From 9eb3f424839dee492f784720a0931261ad7e2db5 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:35:51 +0100 Subject: [PATCH] feat(calendar): add week number display to DateStrip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add optional calendar week (KW) display setting for the DateStrip component. Week numbers appear above the first day of each week without affecting spacing. - Add dateStripShowWeekNumbers setting to settings store - Implement week number label in DateStrip with responsive styling - Add toggle to DateStripContextMenu for easy access - Respects weekStartsOn setting for correct week start detection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../lib/components/calendar/DateStrip.svelte | 41 +++++++++++++++++++ .../calendar/DateStripContextMenu.svelte | 8 ++++ .../web/src/lib/stores/settings.svelte.ts | 5 +++ 3 files changed, 54 insertions(+) diff --git a/apps/calendar/apps/web/src/lib/components/calendar/DateStrip.svelte b/apps/calendar/apps/web/src/lib/components/calendar/DateStrip.svelte index dbe73adf1..13e9783bd 100644 --- a/apps/calendar/apps/web/src/lib/components/calendar/DateStrip.svelte +++ b/apps/calendar/apps/web/src/lib/components/calendar/DateStrip.svelte @@ -11,6 +11,8 @@ subDays, startOfDay, isWithinInterval, + getWeek, + startOfWeek, } from 'date-fns'; import { de } from 'date-fns/locale'; import { onMount, tick } from 'svelte'; @@ -72,6 +74,17 @@ return { significant: false, emoji: '' }; } + // Check if a date is the first day of the week (respects weekStartsOn setting) + function isFirstDayOfWeek(date: Date): boolean { + const weekStart = startOfWeek(date, { weekStartsOn: settingsStore.weekStartsOn }); + return isSameDay(date, weekStart); + } + + // Get week number for a date + function getWeekNumber(date: Date): number { + return getWeek(date, { weekStartsOn: settingsStore.weekStartsOn }); + } + // Reactive view range - needed to trigger re-renders let viewRange = $derived(viewStore.viewRange); let currentDate = $derived(viewStore.currentDate); @@ -262,6 +275,7 @@ {@const isFirstOfMonth = day.getDate() === 1} {@const moonPhase = isSignificantMoonPhase(day)} {@const eventCount = getEventCount(day)} + {@const showWeekNumber = settingsStore.dateStripShowWeekNumbers && isFirstDayOfWeek(day)} {#if isFirstOfMonth}
handleDayClick(day)} class:is-today={dayIsToday} > + {#if showWeekNumber} + KW {getWeekNumber(day)} + {/if} {#if moonPhase.significant && settingsStore.dateStripShowMoonPhases} {moonPhase.emoji} {/if} @@ -468,6 +485,20 @@ line-height: 1; } + .week-number-label { + position: absolute; + top: -14px; + left: 50%; + transform: translateX(-50%); + font-size: 0.5625rem; + font-weight: 600; + color: hsl(var(--color-muted-foreground)); + white-space: nowrap; + pointer-events: none; + text-transform: uppercase; + letter-spacing: 0.02em; + } + .event-dots { display: flex; gap: 2px; @@ -602,6 +633,11 @@ top: -14px; } + .week-number-label { + top: -12px; + font-size: 0.5rem; + } + .day-number { font-size: 1rem; } @@ -648,6 +684,11 @@ top: -12px; } + .date-strip-wrapper.compact .week-number-label { + top: -10px; + font-size: 0.5rem; + } + .date-strip-wrapper.compact .month-divider { height: 28px; } diff --git a/apps/calendar/apps/web/src/lib/components/calendar/DateStripContextMenu.svelte b/apps/calendar/apps/web/src/lib/components/calendar/DateStripContextMenu.svelte index c9639d066..158aa9116 100644 --- a/apps/calendar/apps/web/src/lib/components/calendar/DateStripContextMenu.svelte +++ b/apps/calendar/apps/web/src/lib/components/calendar/DateStripContextMenu.svelte @@ -35,6 +35,14 @@ checked: settingsStore.dateStripShowWeekday, action: () => toggleSetting('dateStripShowWeekday'), }, + { + id: 'week-numbers', + label: 'Kalenderwochen', + icon: Calendar, + toggle: true, + checked: settingsStore.dateStripShowWeekNumbers, + action: () => toggleSetting('dateStripShowWeekNumbers'), + }, { id: 'divider-1', label: '', diff --git a/apps/calendar/apps/web/src/lib/stores/settings.svelte.ts b/apps/calendar/apps/web/src/lib/stores/settings.svelte.ts index 61911cadd..b303435ca 100644 --- a/apps/calendar/apps/web/src/lib/stores/settings.svelte.ts +++ b/apps/calendar/apps/web/src/lib/stores/settings.svelte.ts @@ -33,6 +33,7 @@ export interface CalendarAppSettings { dateStripHighlightWeekends: boolean; // Visually highlight weekend days dateStripShowMonthDividers: boolean; // Show vertical dividers between months dateStripCompact: boolean; // Use compact/smaller DateStrip + dateStripShowWeekNumbers: boolean; // Show week numbers at start of week // UI settings sidebarCollapsed: boolean; @@ -59,6 +60,7 @@ const DEFAULT_SETTINGS: CalendarAppSettings = { dateStripHighlightWeekends: true, dateStripShowMonthDividers: true, dateStripCompact: false, + dateStripShowWeekNumbers: false, // UI defaults sidebarCollapsed: false, defaultEventDuration: 60, @@ -177,6 +179,9 @@ export const settingsStore = { get dateStripCompact() { return settings.dateStripCompact; }, + get dateStripShowWeekNumbers() { + return settings.dateStripShowWeekNumbers; + }, get defaultEventDuration() { return settings.defaultEventDuration; },