Date Picker
Installation
npx @mielui/svelte add date-pickeryarn dlx @mielui/svelte add date-pickerbunx @mielui/svelte add date-pickerUsage
Compose Label, Input, Trigger and Content around Calendar. Input renders localized editable segments and a hidden native validation control. Add name to include the date in form data. The field and calendar share the same DateValue.
<script lang="ts">
import type { DateValue } from '@internationalized/date';
import * as DatePicker from '@mielui/svelte/components/date-picker';
let value = $state<DateValue | undefined>();
</script>
<DatePicker.Root bind:value>
<DatePicker.Label>Publish date</DatePicker.Label>
<DatePicker.Input name="publishDate" />
<DatePicker.Trigger />
<DatePicker.Content align="end">
<DatePicker.Calendar />
</DatePicker.Content>
</DatePicker.Root>Use CalendarDate from @internationalized/date for date-only values, or parseDate for ISO date strings. Bind placeholder to control the visible month. An explicit locale and placeholder keep server and client formatting predictable. Avoid converting a date-only selection through a UTC JavaScript Date to store it; value.toString() preserves its calendar date.
Examples
Helper text
A line under the field tells people they can type the date or pick it.
Type a date or choose one from the calendar.
Localized input
locale sets the field order, weekday names and month names. Pass labels to translate the trigger and panel names, and set weekStartsOn when the first day must not follow the locale.
Disabled
disabled turns off the field and the trigger. readonly keeps the calendar navigable but blocks changes to the value.
Forms and reset
A named Input submits its ISO date value. Required and invalid fields block submission; focus moves to the visible date segments. Disabled fields are omitted. Reset restores the initial selection. Input also accepts form to associate it with an external form.
Composition and accessibility
Calendar exposes a children snippet with months and weekdays. Keep the default Month, or compose Grid, GridHead, GridBody, GridRow, HeadCell, Cell and Day to restyle individual regions. Month also accepts a day(date) snippet. Header, Heading, PrevButton, NextButton, MonthSelect and YearSelect can be omitted, reordered or replaced with another documented composition.
Styled parts forward native attributes and expose bind:element for their underlying element. On Root, bind:element refers to the element that wraps its parts. Arrow keys move between days, Page Up and Page Down change the visible month, and Enter or Space selects. Focus and selection are distinct. Disabled dates cannot be selected; readonly calendars remain navigable. The today indicator and unavailable strike-through provide cues beyond color.
Input exposes a children snippet with segments for custom field composition. Render each Segment with its part to preserve keyboard editing. Put name on Input for ISO-value form submission, and required or validation callbacks on Root. Use errorMessageId to connect your error message. Popup focus returns to the trigger when dismissed; motion respects reduced-motion preferences.
Labels
Built-in text is English. Pass a DatePickerLabels object to labels on Root to translate or reword the trigger name, the panel name and the validation message. Every key is optional, and an omitted key keeps its English default.
<script lang="ts">
import * as DatePicker from '@mielui/svelte/components/date-picker';
import type { DatePickerLabels } from '@mielui/svelte/components/date-picker';
const labels: DatePickerLabels = {
trigger: 'Choisir une date',
content: 'Calendrier',
invalid: 'Saisissez une date valide.'
};
</script>
<DatePicker.Root locale="fr-FR" {labels}>
<DatePicker.Label>Date du rendez-vous</DatePicker.Label>
<DatePicker.Input name="appointment" />
<DatePicker.Trigger />
<DatePicker.Content align="end">
<DatePicker.Calendar />
</DatePicker.Content>
</DatePicker.Root>Calendar options
Root passes the calendar's options through to the panel. isDateDisabled removes a date from play: it cannot be focused or picked. isDateUnavailable is softer. An unavailable date is struck through and can still be focused, so keyboard users can read why it is off limits, and picking it marks the value invalid.
numberOfMonths shows more than one month and pagedNavigation makes the arrows jump by that many. weekdayFormat, fixedWeeks and disableDaysOutsideMonth shape the grid the same way they do on Calendar, and monthFormat and yearFormat name the months and years.
preventDeselect keeps a date selected when it is clicked again. onValueChange runs with each new date, and onPlaceholderChange runs when the visible month changes. initialFocus puts keyboard focus on a day as soon as the panel opens.
Opening and closing
Bind open on Root to control the panel, and use onOpenChange to hear about each change. onOpenChangeComplete runs after the open or close animation has finished. The panel closes once a date is picked. Set closeOnDateSelect={false} to keep it open, which helps when people compare a few dates before deciding.
Trigger opens the panel on click. openOnHover opens it when the pointer rests on the button, with openDelay and closeDelay in milliseconds for how long to wait.
The calendar is closed and stays open after you pick a date.
Validation and the typed field
validate receives the date and returns an error message, or a list of them, when your own rule rejects it. onInvalid then runs with the reason and that message, which is where you show the error. Built-in limits such as minValue report through the same callback.
The typed field has its own options on Root. granularity decides which segments it shows, from day down to second, hourCycle picks a 12 or 24 hour clock, and hideTimeZone drops the zone name. readonlySegments locks the segments you list while the rest stay editable.
Panel position and dismissal
Content positions the calendar panel. side picks the edge of the field it opens from and flips when there is no room, sideOffset is the gap in pixels, and alignOffset nudges it along that edge. avoidCollisions, collisionBoundary and collisionPadding control how it stays inside the viewport or another container. sticky keeps it in view while the field scrolls, hideWhenDetached hides it once the field scrolls away, and customAnchor positions it against a different element. strategy switches between absolute and fixed positioning, updatePositionStrategy set to always re-measures every frame for a field that moves, and arrowPadding and dir cover arrows and right-to-left text.
The same part owns dismissal and focus. interactOutsideBehavior and escapeKeydownBehavior take close, ignore, or one of the two defer values that ask a parent layer first. onInteractOutside, onFocusOutside and onEscapeKeydown run for each event and can call preventDefault() to keep the panel open. trapFocus, preventScroll and preventOverflowTextSelection decide whether Tab, page scrolling and text selection can leave the panel, and onOpenAutoFocus and onCloseAutoFocus let you redirect focus when it opens and closes. surface picks solid or glass, and portal={false} renders the panel in place.
When you compose the calendar yourself, every part except Root and Month accepts child, a snippet that receives the part's props so you can render your own element with them, and style for inline styles. Month takes showHeading to print the month name above its grid, which Root turns on by itself when it shows more than one month.
Root, Input, Trigger, Calendar and Content also accept style.
API reference
DatePicker.Root
childrenSnippet<[]>Content rendered inside.
placeholderBindableDateValueThe placeholder value of the date field. This determines the format and what date the field starts at when it is empty.
disabledbooleanIf true, the date field will be disabled and users will not be able to interact with it. This also disables the hidden input element if the date field is used in a form.
Default
falsevalueBindableDateValueThe value of the date picker.
readonlybooleanIf true, the date field will be readonly, and users will not be able to edit the values of any of the individual segments.
Default
falserequiredbooleanWhether or not the hidden input of the date field requires a value to be submitted.
Default
falseonValueChangeOnChangeFn<DateValue | undefined>A callback function called when the value changes.
onPlaceholderChangeOnChangeFn<DateValue>A callback function called when the placeholder value changes.
preventDeselectbooleanWhether or not users can deselect a date once selected without selecting another date.
minValueDateValueThe minimum acceptable date. When provided, the date field will be marked as invalid if the user enters a date before this date.
maxValueDateValueThe maximum acceptable date. When provided, the date field will be marked as invalid if the user enters a date after this date.
pagedNavigationbooleanApplicable only when
numberOfMonthsis greater than 1.weekStartsOnWeekStartsOnThe day of the week to start the calendar on, which must be a number between 0 and 6, where 0 is Sunday and 6 is Saturday.
weekdayFormat"long" | "narrow" | "short"How the string representation of the weekdays provided via the
weekdaysstate store should be formatted.Default
'short'isDateDisabledDateMatcherA function that returns true if the given date is disabled, which makes the date unable to be selected in the calendar.
isDateUnavailableDateMatcherA function that returns true if the given date is unavailable, where if selected, the date field will be marked as invalid.
fixedWeeksbooleanDisplay 6 weeks per month, regardless the month's number of weeks. This is useful for displaying a consistent calendar, where the size of the calendar doesn't change month to month.
Default
truenumberOfMonthsnumberDetermines the number of months to display on the calendar simultaneously. For navigation between months, refer to the
pagedNavigationprop.calendarLabelstringThis label is exclusively used for accessibility, remaining hidden from the page. It's read by screen readers when the calendar is opened. The current month and year are automatically appended to the label, so you only need to provide the base label.
localestringThe locale to use for formatting the date field.
Default
'en-US'initialFocusbooleanWhether to focus a date when the picker is first opened.
disableDaysOutsideMonthbooleanWhether to disable the selection of days outside the current month. By default, days outside the current month are rendered to fill the calendar grid, but they are not selectable. Setting this prop to
truewill disable this behavior.Default
truemonthFormat"numeric" | "long" | "short" | "narrow" | "2-digit" | ((month: number) => string)The format of the month names in the calendar.
yearFormat"numeric" | "2-digit" | ((year: number) => string)The format of the year names in the calendar.
openBindablebooleanThe open state of the date picker popover.
Default
falseonOpenChangeOnChangeFn<boolean>A callback function called when the open state changes.
onOpenChangeCompleteOnChangeFn<boolean>A callback function called when the open state changes complete.
validateDateValidatorA function that returns a string or array of strings as validation errors if the date is invalid, or nothing if the date is valid
onInvalidDateOnInvalidA callback fired when the date field's value is invalid. Use this to display an error message to the user.
readonlySegments("month" | "year" | "day" | "hour" | "minute" | "second" | "dayPeriod")[]An array of segment names that should be readonly. If provided, only the segments not in this array will be editable.
hourCycle12 | 24The format to use for displaying the time in the input. If using a 12 hour clock, ensure you also include the
dayPeriodsegment in your input to ensure the user can select AM/PM.granularityGranularityThe granularity of the date field. This determines which segments will be includes in the segments array used to build the date field.
hideTimeZonebooleanWhether or not to hide the timeZoneName segment from the date field.
closeOnDateSelectbooleanWhether to close the popover when a date is selected.
errorMessageIdstringThe
idof the element which contains the error messages for the date field when the date is invalid.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
nulllabelsDatePickerLabelsOverrides the built-in text and accessible names. Every key is optional and English is the fallback.
DatePicker.Cell
childrenSnippet<[CalendarCellSnippetProps]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
dateRequiredCalendarDate | CalendarDateTime | ZonedDateTimeThe date value of the cell.
monthRequiredCalendarDate | CalendarDateTime | ZonedDateTimeThe month DateValue that this cell is being rendered in.
childSnippet<[CalendarCellSnippetProps & { props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Day
childrenSnippet<[CalendarDaySnippetProps]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[CalendarDaySnippetProps & { props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Grid
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.GridBody
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.GridHead
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.GridRow
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.HeadCell
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Header
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Heading
childrenSnippet<[CalendarHeadingSnippetProps]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[CalendarHeadingSnippetProps & { props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Month
classstringClasses added to the element.
monthRequired{ value: DateValue; weeks: DateValue[][]; dates: DateValue[]; }Month data from the Root snippet.
weekdaysRequiredstring[]Weekday names from the Root snippet.
localestringBCP 47 locale used for names and number formats.
Default
'en-US'showHeadingbooleanShows the month name above the grid, for layouts with several months.
Default
falsedaySnippet<[date: DateValue]>Custom content for each day cell.
DatePicker.MonthSelect
childrenSnippet<[CalendarMonthSelectSnippetProps]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[CalendarMonthSelectSnippetProps & { props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.monthFormat"numeric" | "long" | "short" | "narrow" | "2-digit" | ((month: number) => string)How the month names should be formatted in the select options.
monthsnumber[]An array of month numbers (1-12) to display in the select. This allows for flexible month selection, such as showing only specific months or seasons.
elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.NextButton
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.PrevButton
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.YearSelect
childrenSnippet<[CalendarYearSelectSnippetProps]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[CalendarYearSelectSnippetProps & { props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.yearFormat"numeric" | "2-digit" | ((year: number) => string)How the year should be formatted in the select options.
yearsnumber[]An array of years to display in the select. This allows for complete control over which years appear, such as showing only years with data or excluding certain periods.
elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Calendar
childrenSnippet<[CalendarRootSnippetProps]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Content
childrenSnippet<[]>Content rendered inside.
dirDirectionThe text direction of the content.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
align"center" | "end" | "start"The preferred alignment of the anchor to render against when open. This may change when collisions occur.
Default
'start'onInteractOutsideInteractOutsideEventHandlerCallback fired when an outside interaction event completes, which is either a
pointerup,mouseup, ortouchendevent, depending on the user's input device.interactOutsideBehaviorInteractOutsideBehaviorTypeInteract outside behavior type.
close: Closes the element immediately.defer-otherwise-close: Delegates the action to the parent element. If no parent is found, it closes the element.defer-otherwise-ignore: Delegates the action to the parent element. If no parent is found, nothing is done.ignore: Prevents the element from closing and also blocks the parent element from closing in response to an outside interaction.onFocusOutside((event: FocusEvent) => void)Callback fired when focus leaves the dismissible layer.
preventScrollbooleanWhether to prevent scrolling the body when the content is open. Whether to prevent body scrolling when the content is open.
onEscapeKeydown((e: KeyboardEvent) => void)Callback fired when escape is pressed.
escapeKeydownBehaviorEscapeBehaviorTypeEscape behavior type.
close: Closes the element immediately.defer-otherwise-close: Delegates the action to its parent component that has an escape keydown handler. If no parent is found, it closes the element.defer-otherwise-ignore: Delegates the action to the parent element. If no parent is found, nothing is done.ignore: Prevents the element from closing and also blocks the parent element from closing in response to an escape key press.side"bottom" | "left" | "right" | "top"The preferred side of the anchor to render against when open. Will be reversed when collisions occur.
sideOffsetnumberThe distance in pixels from the anchor to the floating element.
Default
6alignOffsetnumberAn offset in pixels from the "start" or "end" alignment options.
arrowPaddingnumberThis describes the padding between the arrow and the edges of the floating element. If your floating element has border-radius, this will prevent it from overflowing the corners.
avoidCollisionsbooleanWhen
true, overrides thesideandalignoptions to prevent collisions with the boundary edges.collisionBoundaryArrayable<Boundary>A boundary element or array of elements to check for collisions against.
collisionPaddingnumber | Partial<Record<"left" | "right" | "top" | "bottom", number>>The amount in pixels of virtual padding around the viewport edges to check for overflow which will cause a collision.
Default
8sticky"partial" | "always"Keeps the panel in view while its anchor scrolls.
partialkeeps part of it visible andalwayskeeps all of it.hideWhenDetachedbooleanHides the panel when the trigger scrolls out of view.
updatePositionStrategy"optimized" | "always""optimized" will only update the position when necessary, while "always" will update the position on each animation frame, which is useful if the floating content is following something like a mouse cursor.
strategy"absolute" | "fixed"The positioning strategy to use for the floating element.
customAnchorstring | HTMLElement | Measurable | nullUse an element other than the trigger to anchor the content to. If provided, the content will be anchored to the provided element instead of the trigger.
preventOverflowTextSelectionbooleanPassing
truewill prevent the overflow of text selection outside the element, provided the element is the top layer.onOpenAutoFocusEventCallbackEvent handler called when auto-focusing on open. Can be prevented.
onCloseAutoFocusEventCallbackEvent handler called when auto-focusing on close. Can be prevented.
trapFocusbooleanWhether focus is trapped within the focus scope.
elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
nullsurface"solid" | "glass"Surface treatment. Omit it to inherit
--mielui-surfacefrom the theme.portalbooleanMoves the panel to the end of the document so ancestors cannot clip it. Set false to render it in place.
Default
true
DatePicker.Input
childrenSnippet<[DateFieldInputSnippetProps]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
formstringId of the form the hidden input belongs to.
namestringThe name to use for the hidden input element of the date field, which is used to submit the ISO string value of the date field to a server. If not provided, the hidden input element will not be rendered.
elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Label
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Segment
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
partRequired"day" | "dayPeriod" | "hour" | "literal" | "minute" | "month" | "second" | "timeZoneName" | "year"Which part of the date this segment edits.
stylestring | StyleProperties | nullInline styles for the element.
childSnippet<[{ props: Record<string, unknown>; }]>Renders your own element in place of the default one. Spread the given
propsonto it.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
DatePicker.Trigger
childrenSnippet<[]>Content rendered inside.
idstringId of the element.
stylestring | StyleProperties | nullInline styles for the element.
openOnHoverbooleanWhether the popover should open when the trigger is hovered.
openDelaynumberHow long to wait before opening the popover on hover (ms). Only applies when
openOnHoveristrue.closeDelaynumberHow long to wait before closing the popover after hover ends (ms). Only applies when
openOnHoveristrue.elementBindableHTMLElement | nullBindable reference to the DOM element.
Default
null
pnpm dlx @mielui/svelte add date-picker