Skip to content

DatePicker — API reference

The complete prop / event / slot / imperative-handle surface of @rozie-ui/date-picker.

Props

NameTypeDefaultTwo-way (model)RequiredDescription
valueany''The selected value (two-way r-model). Polymorphic on selectionMode: in single mode an ISO YYYY-MM-DD string ("" = nothing selected); in range mode a { start, end } object of ISO endpoints ("" = an unset endpoint). As the sole model: true prop it drives the Angular ControlValueAccessor, so a DatePicker is a form control ([(ngModel)] / [formControl] bind directly). Selecting a day writes the new value back and emits change. Lit caveat (range mode): the object form must be delivered via a property binding (.value=${obj} / r-model), never a string value="..." attribute — the same rule already in force for disabledDates.
selectionModeString"single"Selection mode: 'single' (the default — value is one ISO YYYY-MM-DD string, fully backward-compatible) or 'range' (value becomes a { start, end } object selected with two clicks plus a live hover preview, direction-agnostic). In range mode a completed selection additionally emits rangeComplete.
minStringnullInclusive lower bound as an ISO YYYY-MM-DD string. Days before it are rendered disabled and cannot be selected or focused. null (the default) imposes no lower bound.
maxStringnullInclusive upper bound as an ISO YYYY-MM-DD string. Days after it are rendered disabled and cannot be selected or focused. null (the default) imposes no upper bound.
disabledDatesArray[]An array of ISO YYYY-MM-DD strings to disable individually (e.g. holidays or already-booked days), in addition to the min/max bounds. Disabled days are non-interactive and marked aria-disabled.
weekStartsOnNumber0The first day of the week as a number, 0 = Sunday through 6 = Saturday. Rotates both the weekday header row and the grid columns (e.g. 1 for a Monday-first calendar).
disabledBooleanfalseDisable the entire control — every day cell and the previous/next month buttons become non-interactive and are marked aria-disabled. Also sets the Angular ControlValueAccessor disabled state.
localeString"en-US"BCP-47 locale tag used by Intl.DateTimeFormat to render the month-year heading and the short weekday header labels (e.g. "fr-FR", "ja-JP"). Falls back to English names in a runtime without Intl.
labelsObject{}Optional overrides for the 10 static English "chrome" strings, keyed by root, previousMonth, nextMonth, changeMonthYear, changeYear, chooseMonth, chooseYear, presets, today, clear (defaults: "Date picker", "Previous month", "Next month", "Change month and year", "Change year", "Choose month", "Choose year", "Date range presets", "Today", "Clear"). Honest split: Intl is a date/number formatter, not a message catalog — it can localize a DATE but cannot translate the phrase "Previous month". The day-cell accessible name, each multi-month panel's own grid caption, the weekday header long names, and the month-year heading text are already Intl-derived from the locale prop and are NOT labels keys; the 10 chrome phrases above are English-static and only labels can translate them. An empty object (the default) yields the English defaults with zero config. Lit caveat: pass via a property binding (.labels=${…}), never a string attribute — the same rule already in force for disabledDates/presetRanges.
presetRangesArray[]Quick-pick presets for range mode — an array of { label, range } where range is a literal { start, end } value or a () => { start, end } thunk (the consumer owns the date math and i18n labels). Renders a default preset rail beneath the grid; the #presets slot overrides it. Lit caveat: pass via a property binding (.presetRanges=${[…]}) — thunks inside the array cannot survive a string attribute, same as disabledDates.
monthYearNavBooleantrueRender the month-year heading as a clickable drill button that navigates days → months → years (and a year label that drills months → years). Capability-on: this is the documented exception to the boolean-default-false rule — the drill navigation is the ergonomic win of this feature, so it defaults to true. Set :month-year-nav="false" to restore the static heading <span> (byte-identical to the pre-navigation output).
numberOfMonthsNumber1How many month grids to render side by side, anchored at the view month and stepping forward (e.g. 2 for a two-up range calendar). 1 (the default) emits exactly the single-month markup with no extra wrapper element.
showFooterBooleanfalseRender a Today / Clear footer row beneath the calendar grid. Today selects (single mode) or navigates to (range mode) the current date; Clear deselects. The #footer slot fully overrides the default row, receiving { today, clear, todayIso }.
disabledDaysOfWeekArray[]An array of weekday indices to disable, Number[] where 0 = Sunday through 6 = Saturday (e.g. [0, 6] disables every weekend). Serializable, so it passes fine as a plain attribute. Threaded through the single gating funnel, so disabled weekdays are non-interactive, non-focusable, and marked aria-disabled — in agreement with day cells, drill enablement, and keyboard focus.
isDateDisabledFunctionnullA consumer predicate (iso: string) => boolean — return true to disable the given ISO YYYY-MM-DD date (e.g. custom holiday / blackout rules beyond disabledDates/min/max). Threaded through the single gating funnel so day cells, drill enablement, and focus all agree. Lit caveat: pass via a property binding (.isDateDisabled=${fn}), never a string attribute — a function cannot survive attribute serialization, the same rule already in force for disabledDates/presetRanges.

Events

EventPayloadDescription
change{ value }Fired whenever the selected value changes — selecting a day, dropping a range anchor, or a programmatic clear(). In single mode value is the new ISO YYYY-MM-DD string (or ""); in range mode it is the current { start, end } object (the anchor-only { start, end: "" } write fires change too). Not fired when the picked value equals the current selection.
rangeComplete{ value }Range mode only. Fires once when the second endpoint lands or a preset is applied — i.e. when a full range is committed. value is the ordered { start, end } object (min/max already applied, so start <= end regardless of click direction). Does not fire on the anchor-only first click.

The two-way model also fires the framework-native update event (onValueChange / update:value / bind:value / (valueChange) / value-change) carrying the new value (ISO string in single mode, { start, end } object in range mode) directly.

Per-target rangeComplete consumer-prop casing

rangeComplete is a camelCase source event, and each framework derives the consumer-facing prop name its own way. Bind the exact name for your target — the Svelte one is lowercase, and a PascalCase binding there silently never fires. Lit is the exception: it does NOT preserve the source casing — the compiler kebab-cases multi-word emit names at dispatch, so the DOM event name is range-complete, not rangeComplete (quick 260811-nre; previously documented here as case-preserved, which was true before that fix and is no longer):

TargetConsumer binding
React / SolidonRangeComplete={...}
Vue@rangeComplete="..." (emit('rangeComplete'))
Angular(rangeComplete)="..." output
LitaddEventListener('range-complete', ...)CustomEvent("range-complete"), kebab-cased at dispatch (NOT rangeComplete)
Svelteonrangecomplete={...} — ⚠ LOWERCASE (NOT onRangeComplete)

Slots

Every slot is optional — omit any of them to get the default token-themed markup for that region.

SlotScope paramsDescription
header{ label, prev, next, disabled, openMonths, openYears, closeDrill, viewMode }Replace the default month-nav header. label is the localized "Month YYYY" heading, prev/next step the displayed month, disabled mirrors the disabled prop. openMonths()/openYears() drill down into the months/years panel (mirroring the default heading button's click), closeDrill() returns to the days view (guarded — a no-op while the whole control is disabled), and viewMode is the current 'days' | 'months' | 'years' panel, so a custom header can render its own drill-aware chrome without touching the default panels below it. All four are additive — the first four params keep their names, order and semantics from before this addition.
footer{ today, clear, todayIso }Replace the default Today / Clear row. today() selects today (single mode) or navigates the view to today (range mode); clear() deselects; todayIso is today's ISO YYYY-MM-DD string. The default row is gated by showFooter — but an explicit #footer slot renders whenever provided, regardless of showFooter.
presets{ presets, apply }Range mode only. Replace the default quick-pick preset rail. presets is the resolved presetRanges array ({ label, range }[]), and apply(range) commits a preset's range (firing change + rangeComplete). Omit the slot to get the default token-themed rail.

On React the scoped slots are render-prop callbacks (header/footer/presets render-props) — the one documented cross-framework slot divergence.

Caveats

The polymorphic object value (range mode) and the function-form presetRanges entries are non-string values, so they must be delivered as properties, never string attributes. On Vue, React, Svelte, Angular, and Solid this happens automatically through the framework's binding syntax. On Lit you must use a property binding — .value=${obj} / r-model and .presetRanges=${[...]} — never value="..." (a string attribute would stringify the object to '[object Object]' and never reach the component). This is the identical rule already in force for disabledDates (an array prop), not a new constraint class.

Imperative handle

Grab a handle via the framework-native ref mechanism (useRefDatePickerHandle, Vue/Svelte/Angular template refs, Solid ref callback, or the Lit custom element itself):

MethodDescription
focus()Move keyboard focus into the grid — onto the selected day (if visible), else today (if visible), else the first enabled day of the displayed month(s). Multi-month aware.
goToToday()Swing the displayed month to today (no selection change).
clear()Deselect the current selection, emitting change. Writes "" in single mode and { start: "", end: "" } in range mode. A no-op (no change fired) when nothing is currently selected.

Theming

Every visual value is a --rozie-datepicker-* CSS custom property. Import a ready-made design-system bridge or set the tokens yourself at any ancestor scope:

ts
import '@rozie-ui/date-picker-react/themes/shadcn.css';   // or material.css, bootstrap.css, base.css

The complete token table and the design-system bridges live on the dedicated theming page.

Pre-1.0 — APIs may change between minor versions.