From f950973b038b3df29a55a3361da7a8cac7db3c6f Mon Sep 17 00:00:00 2001 From: dev Date: Thu, 25 Jun 2026 00:54:41 +0200 Subject: [PATCH] feat(eidos): calendar month/year via popover+grid; nav controls compose system Button/IconButton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Month/year choosers replace the native ``, + * no nested popover. The `MonthView` / `YearView` parts render the reused + * `MonthGrid` / `YearGrid` when active; the `Heading` advances the view. + */ + view = $state('day'); private lastLoggedValidationKey: string | null = null; private constructor(opts: CalendarOpts) { @@ -347,6 +355,29 @@ export class CalendarProvider { this.setPlaceholder(this.opts.placeholder.current.set({ year }), target); } + // ── Navigation view (day ↔ month ↔ year) ────────────────────────────────── + + setView(view: CalendarView): void { + this.view = view; + } + + /** Heading click: drill UP one level (day → month → year). */ + advanceView(): void { + this.view = this.view === 'day' ? 'month' : 'year'; + } + + /** Month grid select: set the placeholder year+month and drill back DOWN to days. */ + selectMonthView(year: number, month: number, target?: HTMLElement): void { + this.setPlaceholder(this.opts.placeholder.current.set({ year, month }), target); + this.view = 'day'; + } + + /** Year grid select: set the placeholder year and drill back DOWN to months. */ + selectYearView(year: number, target?: HTMLElement): void { + this.setYear(year, target); + this.view = 'month'; + } + private announceNavigation(): void { if (!this.opts.announceNavigation.current) return; this.announcement = this.headingValue; diff --git a/src/uix/soma/components/calendar/exports.ts b/src/uix/soma/components/calendar/exports.ts index cb5a37f3b..c997f8bc5 100644 --- a/src/uix/soma/components/calendar/exports.ts +++ b/src/uix/soma/components/calendar/exports.ts @@ -13,7 +13,13 @@ export { default as HeadCell } from './components/calendar-head-cell.svelte'; export { default as Cell } from './components/calendar-cell.svelte'; export { default as Day } from './components/calendar-day.svelte'; +// The provider class is exported so the eidos view-switch parts +// (Heading button, MonthView, YearView) can read `view` + drive +// `advanceView` / `selectMonthView` / `selectYearView` off the live context. +export { CalendarProvider } from './calendar-provider.svelte'; + export type { + CalendarView, CalendarProps, CalendarHeaderProps, CalendarHeadingProps, diff --git a/src/uix/soma/components/calendar/types.ts b/src/uix/soma/components/calendar/types.ts index 4a18d9c53..de8cac833 100644 --- a/src/uix/soma/components/calendar/types.ts +++ b/src/uix/soma/components/calendar/types.ts @@ -15,6 +15,15 @@ import type { import type { DateValue, DateMatcher, Month, WeekStartsOn, DateOrder } from '$libs/days'; import type { CalendarBoundsValidationStatus } from './helpers'; +// ── Navigation view ────────────────────────────────────────────────────────── + +/** + * The calendar's active navigation view. The day grid switches in-place to a + * month grid then a year grid (Ark/Mantine/MUI pattern) — no native `