# Calendar A month-grid date picker with optional month-picking mode and `Temporal.PlainDate` binding. ## Usage Use standalone. ```svelte ``` ## Anatomy The `class` attribute values represent part names, and `conditional` indicates elements that are rendered conditionally. Other attributes represent their corresponding props. While `picking`, `children` renders inside `middle` and wins over the embedded `MonthPicker`. ```svelte
{weekday}
{#if children}{children}{:else}{/if} while picking
{bottom}
``` - Left and right buttons page `display`; the label button toggles `picking`. - While picking, `children` renders in the middle slot and wins over the embedded `MonthPicker`. - The `bottom` snippet receives a control object (`setToday`, `clear`), the `picking` state, and the variant. - Enabled day clicks and Enter or Space select one `Temporal.PlainDate`. - Day cells expose `data-today`, `data-selected`, `data-outside`, `data-disabled`, and `data-weekday`. - The weekday header row and each week row both use the `aux` part; only the header row and its column headers carry `data-header`, which separates header-only from day-only styling. - Arrow keys, Home, End, PageUp, PageDown, and Shift+PageUp/PageDown update roving focus. ## Props | Name | Type | Default | Description | |---|---|---|---| | `value` | `Temporal.PlainDate` | - | Bindable selected date | | `display` | `Temporal.PlainYearMonth` | - | Bindable shown year-month for calendar paging | | `picking` | `boolean` | `false` | Bindable state that shows the embedded `MonthPicker` instead of the day grid | | `min` | `Temporal.PlainDate` | - | Lower date bound; dates before it are disabled | | `max` | `Temporal.PlainDate` | - | Upper date bound; dates after it are disabled | | `isDisabled` | `(d: Temporal.PlainDate) => boolean` | - | Custom predicate that disables matching dates | | `outsideDays` | `boolean` | `false` | Show outside-month days in the grid | | `fixedWeeks` | `boolean` | `false` | Render a fixed six-week grid | | `firstDayOfWeek` | `number` | `0` | First weekday, where `0` = Sunday | | `locale` | `string` | - | Locale for weekday and heading labels | | `label` | `Snippet` | - | Heading snippet | | `left` | `Snippet` | - | Previous-button snippet | | `right` | `Snippet` | - | Next-button snippet | | `weekday` | `Snippet` | - | Weekday label snippet | | `day` | `Snippet` | - | Day cell snippet | | `bottom` | `Snippet` | - | Bottom-area snippet; receives a control object (`setToday`, `clear`), the `picking` state, and the variant | | `children` | `Snippet` | - | Overrides the middle slot while picking; wins over `monthPicker` | | `monthPicker` | `MonthPickerProps` | - | Nested config bag spread into the embedded `MonthPicker`; `Calendar` owns the displayed month, bounds, and variant | | `transition` | `TransitionProp` | - | Optional transition function and params for switching between the day grid and month picker | | `pageTransition` | `TransitionProp` | - | Optional transition that slides the day grid when `display` pages | | `styling` | `SVSClass` | - | Styling override | | `variant` | `SVSVariant` | `NEUTRAL` | Variant passed to navigation and container parts | ## Styling To learn more, see [Styling](/docs/styling). ### Variant Management Selected days render with `active`, disabled days render with `inactive`, and other day cells use `neutral`. Navigation and container parts receive the supplied `variant`. ### Default Class Name `svs-calendar` ## Behavior - Left/right buttons page `display`; the label toggles the picking slot. - While picking, `children` renders in the middle slot and wins over the embedded `MonthPicker`. - The `bottom` snippet receives a control object (`setToday`, `clear`), the `picking` state, and the variant. - Enabled day clicks and Enter/Space select a single `Temporal.PlainDate`. - Day cells expose `data-today`, `data-selected`, `data-outside`, `data-disabled`, and `data-weekday`. - Arrow, Home/End, PageUp/PageDown, and Shift+PageUp/PageDown update roving focus. - The grid re-keys when `display` changes; optional `pageTransition` applies to the day-grid page change. ## Accessibility ### Keyboard Interactions | Key | Description | | --- | --- | | `ArrowLeft` / `ArrowRight` | Moves focus one day backward or forward | | `ArrowUp` / `ArrowDown` | Moves focus one week backward or forward | | `Home` / `End` | Moves focus to the start or end of the focused week | | `PageUp` / `PageDown` | Moves focus one month backward or forward | | `Shift` + `PageUp` / `Shift` + `PageDown` | Moves focus one year backward or forward | | `Enter` / `Space` | Selects the focused day | Clicking an enabled day also selects it. ### ARIA Roles and Attributes The component applies these automatically: - Root (`whole`): `role="group"` and `aria-label` generated from the current displayed month. - Caption button (`label`): `aria-expanded` for the month/year picker state. - Grid (`main`): `role="grid"` and `aria-labelledby` pointing to the caption button; it contains weekday and week rows. - Weekday row (`aux`): `role="row"` containing column headers. - Weekday header: `role="columnheader"` with an `aria-label` for the full weekday name. - Day cell: `role="gridcell"`, roving `tabindex`, `aria-selected`, `aria-disabled`, `aria-current="date"` on today, and a per-date `aria-label`. The root already has a built-in accessible name such as the current month. Provide clear custom `label`, `left`, `right`, and day snippets if you replace the default visible text. ## Exports ### Types ```ts interface CalendarProps { value?: Temporal.PlainDate; // bindable; selected date display?: Temporal.PlainYearMonth; // bindable; shown month picking?: boolean; // bindable (false) min?: Temporal.PlainDate; max?: Temporal.PlainDate; isDisabled?: (d: Temporal.PlainDate) => boolean; outsideDays?: boolean; // (false) fixedWeeks?: boolean; // (false) firstDayOfWeek?: number; // (0=Sun) locale?: string; label?: Snippet<[Temporal.PlainYearMonth, string, boolean]>; left?: Snippet<[string]>; right?: Snippet<[string]>; weekday?: Snippet<[number, string]>; day?: Snippet<[DayCtx]>; bottom?: Snippet<[CalendarCtl, boolean, string]>; children?: Snippet; monthPicker?: Omit; transition?: TransitionProp; pageTransition?: TransitionProp; styling?: SVSClass; variant?: SVSVariant; // (VARIANT.NEUTRAL) } type CalendarReqdProps = never; type CalendarBindProps = "value" | "display" | "picking"; type DayCtx = { date: Temporal.PlainDate; variant: string; weekday: number; today: boolean; selected: boolean; outside: boolean; disabled: boolean; }; type CalendarCtl = { setToday: () => void; clear: () => void; }; type TransitionProp = { fn?: (node: HTMLElement, params: any, options: { direction: "in" | "out" | "both" }) => import("svelte/transition").TransitionConfig; params?: unknown; }; ``` ### Others No additional exports are available. ## Examples The example code uses Tailwind CSS along with `SVSClass`. ### Basic **Code** ```svelte src=CalendarBasic.svelte
{#snippet left()}{"<"}{/snippet} {#snippet right()}{">"}{/snippet}
Selected: {value?.toString() ?? "Pick a day"}
{#snippet left()}{/snippet} ``` ### With Interactive Variant **Code** ```svelte src=CalendarPract.svelte
{#snippet label(ym)} {ym.toString()} {/snippet} {#snippet left()}{"<"}{/snippet} {#snippet right()}{">"}{/snippet} {#snippet bottom(ctl)} {/snippet}
Selected: {value?.toString() ?? "Pick a day"}
{#snippet left()}{/snippet} ```