fix(date-picker): don't mark the same day in every month as selected

The day cell class used `selectedDay === day`, ignoring the currently
viewed month/year. After picking e.g. April 15, flipping to May still
painted May 15 as the selected day; committing with Done would shift
the task's date to whatever month the user happened to be viewing.

Track selectedYear/selectedMonth alongside selectedDay, update them
only on actual day click, and construct the committed ISO from the
selection (not the view). The pre-existing isSelected() helper is now
wired into the cell template.
This commit is contained in:
Claude 2026-04-17 16:17:36 +00:00
parent 8a81f05492
commit a0e2bb214b
No known key found for this signature in database

View file

@ -50,23 +50,28 @@
function selectDay(day: number) { function selectDay(day: number) {
selectedDay = day; selectedDay = day;
selectedYear = viewYear;
selectedMonth = viewMonth;
} }
function isToday(day: number): boolean { function isToday(day: number): boolean {
return `${viewYear}-${viewMonth + 1}-${day}` === todayStr; return `${viewYear}-${viewMonth + 1}-${day}` === todayStr;
} }
let selectedYear = $state(existing ? existing.getFullYear() : now.getFullYear());
let selectedMonth = $state(existing ? existing.getMonth() : now.getMonth());
function isSelected(day: number): boolean { function isSelected(day: number): boolean {
return selectedDay === day && (!value || (() => { return selectedDay === day && selectedYear === viewYear && selectedMonth === viewMonth;
const v = new Date(value);
return v.getFullYear() === viewYear && v.getMonth() === viewMonth;
})());
} }
function done() { function done() {
const h = includeTime ? selectedHour : 0; const h = includeTime ? selectedHour : 0;
const m = includeTime ? selectedMinute : 0; const m = includeTime ? selectedMinute : 0;
const iso = new Date(viewYear, viewMonth, selectedDay, h, m).toISOString(); // Commit based on the last-selected year/month, not the currently-viewed
// ones — users can navigate months after selecting a day without
// accidentally shifting the chosen date to the viewed month.
const iso = new Date(selectedYear, selectedMonth, selectedDay, h, m).toISOString();
onchange(iso, includeTime); onchange(iso, includeTime);
dismiss(); dismiss();
} }
@ -129,9 +134,9 @@
<button <button
onclick={() => selectDay(day)} onclick={() => selectDay(day)}
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-sm transition-colors class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-sm transition-colors
{selectedDay === day ? 'bg-primary text-white' : ''} {isSelected(day) ? 'bg-primary text-white' : ''}
{isToday(day) && selectedDay !== day ? 'font-bold text-primary' : ''} {isToday(day) && !isSelected(day) ? 'font-bold text-primary' : ''}
{selectedDay !== day && !isToday(day) ? 'hover:bg-black/5 dark:hover:bg-white/10' : ''}" {!isSelected(day) && !isToday(day) ? 'hover:bg-black/5 dark:hover:bg-white/10' : ''}"
> >
{day} {day}
</button> </button>