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;
},