Let the calendar jump to any month or year, in both directions
Clicking the month or year label only ever stepped forward (`month + 1`, `year + 1`), so the only way back was the prev-month arrow, one month at a time. Jumping back a year was impossible. Both labels are now selects, so any month or year is one click away in either direction. Selects rather than +/- steppers because the app already uses them elsewhere, and because stepping in a second direction would still not give the "quickly jump" part of the original intent. Year options are bounded to 2026-2055, the calendar cache range: outside it the backend raises UncachedYearError and returns 422, so offering those years would hand the user an error instead of a calendar. The prev/next month arrows are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RXMhc9nT6sNz1SL4j8dznL
This commit is contained in:
@@ -137,12 +137,14 @@ export function Calendar(): ReactNode {
|
||||
setCurrentMonth(new Date(year, month + 1, 1))
|
||||
}
|
||||
|
||||
const handleMonthClick = () => {
|
||||
setCurrentMonth(new Date(year, month + 1, 1))
|
||||
const handleMonthChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const newMonth = Number(e.target.value)
|
||||
setCurrentMonth(new Date(year, newMonth, 1))
|
||||
}
|
||||
|
||||
const handleYearClick = () => {
|
||||
setCurrentMonth(new Date(year + 1, month, 1))
|
||||
const handleYearChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const newYear = Number(e.target.value)
|
||||
setCurrentMonth(new Date(newYear, month, 1))
|
||||
}
|
||||
|
||||
// §3.6 — an explicit mode toggle (rather than a modifier-click or context
|
||||
@@ -299,26 +301,34 @@ export function Calendar(): ReactNode {
|
||||
←
|
||||
</button>
|
||||
<h2 className="calendar__title">
|
||||
<button
|
||||
onClick={handleMonthClick}
|
||||
className="calendar__month-button"
|
||||
aria-label={t('calendar.advanceMonthAria', {
|
||||
month: currentMonth.toLocaleDateString(locale === 'sv' ? 'sv-SE' : 'en-US', { month: 'long' }),
|
||||
})}
|
||||
<select
|
||||
value={month}
|
||||
onChange={handleMonthChange}
|
||||
className="calendar__month-select"
|
||||
aria-label={t('calendar.selectMonthAria')}
|
||||
>
|
||||
{currentMonth.toLocaleDateString(locale === 'sv' ? 'sv-SE' : 'en-US', {
|
||||
month: 'long',
|
||||
})}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleYearClick}
|
||||
className="calendar__year-button"
|
||||
aria-label={t('calendar.advanceYearAria', {
|
||||
year: currentMonth.getFullYear(),
|
||||
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((m) => {
|
||||
const date = new Date(year, m, 1)
|
||||
const monthName = date.toLocaleDateString(locale === 'sv' ? 'sv-SE' : 'en-US', { month: 'long' })
|
||||
return (
|
||||
<option key={m} value={m}>
|
||||
{monthName}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
<select
|
||||
value={year}
|
||||
onChange={handleYearChange}
|
||||
className="calendar__year-select"
|
||||
aria-label={t('calendar.selectYearAria')}
|
||||
>
|
||||
{currentMonth.getFullYear()}
|
||||
</button>
|
||||
{Array.from({ length: 2055 - 2026 + 1 }, (_, i) => 2026 + i).map((y) => (
|
||||
<option key={y} value={y}>
|
||||
{y}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</h2>
|
||||
<button onClick={handleNextMonth} aria-label={t('calendar.nextMonthAria')}>
|
||||
→
|
||||
|
||||
Reference in New Issue
Block a user