Date Picker
Installation
Section titled “Installation”Copy editable source into an initialized application:
pnpm dlx @simurgh-ui/cli add date-pickerFor package consumption, import from the component subpath and load its optional recipe CSS:
import { DatePicker, DatePickerProps,} from '@simurgh-ui/react/date-picker';import '@simurgh-ui/styles/date-picker.css';import { DatePicker } from '@simurgh-ui/vue/date-picker';import '@simurgh-ui/styles/date-picker.css';Angular
Section titled “Angular”import { DatePickerComponent } from '@simurgh-ui/angular/date-picker';import '@simurgh-ui/styles/date-picker.css';Omit the component stylesheet for fully headless styling. CLI-copied components use the local path
written to simurgh.json and the copied application styles instead of these package imports.
Purpose
Section titled “Purpose”Date Picker composes Popover and Calendar into a form-ready single-date control. The trigger shows a localized date while the submitted and emitted value remains YYYY-MM-DD.
Default presentation: styled
Section titled “Default presentation: styled”The optional component stylesheet provides a complete default recipe, including visual hierarchy and interaction states. Consumers can override semantic tokens or omit the recipe.
Basic usage
Section titled “Basic usage”Anatomy
Section titled “Anatomy”The public component parts are listed in API surface below. Use only the parts needed by the example; compound components depend on their documented parent/child nesting.
State model
Section titled “State model”Controlled state remains the application’s source of truth and must be updated from every change event. Uncontrolled state reads its default only when the component mounts. Do not pass both forms of the same state at once.
| Framework | Exact state contract and reset behavior |
|---|---|
| React | Controlled: month + onMonthChange. Uncontrolled: defaultMonth. Reset controlled state by assigning the initial value; reset uncontrolled state by changing a React key.Controlled: value + onValueChange. Uncontrolled: defaultValue. Reset controlled state by assigning the initial value; reset uncontrolled state by changing a React key. |
| Vue | Controlled: v-model (modelValue + update:modelValue). Uncontrolled: defaultValue. Reset the model ref to its initial value; reset uncontrolled state with a changed Vue :key.Controlled: v-model:month (month + update:month). Uncontrolled: defaultMonth. Reset the model ref to its initial value; reset uncontrolled state with a changed Vue :key. |
| Angular | Controlled two-way binding: [(value)] (value + valueChange). Angular exposes no separate default input; initialize and reset the bound class field explicitly.Controlled two-way binding: [(month)] (month + monthChange). Angular exposes no separate default input; initialize and reset the bound class field explicitly. |
React
const initialMonth = '';const [month, setMonth] = useState(initialMonth);const [resetKey, setResetKey] = useState(0);
<DatePicker month={month} onMonthChange={setMonth}>…</DatePicker><button onClick={() => setMonth(initialMonth)}>Reset controlled</button><DatePicker key={resetKey} defaultMonth={initialMonth}>…</DatePicker><button onClick={() => setResetKey((key) => key + 1)}>Reset uncontrolled</button>Vue
<script setup lang="ts">import { ref } from 'vue';const initial = '';const state = ref(initial);const resetKey = ref(0);</script>
<DatePicker v-model="state">…</DatePicker><button @click="state = initial">Reset controlled</button><DatePicker :key="resetKey" :defaultValue="initial">…</DatePicker><button @click="resetKey++">Reset uncontrolled</button>Angular
initial = '';value = this.initial;reset() { this.value = this.initial; }<simurgh-date-picker [(value)]="value">…</simurgh-date-picker><button type="button" (click)="reset()">Reset</button>Use required for native constraint validation and disabled to make the entire control unavailable. Calendar constraints such as min, max, and disabledDates pass through unchanged. Selection closes the popup and returns focus to the trigger.
Examples
Section titled “Examples”<DatePicker defaultValue="2026-08-12" name="appointment" label="Appointment date" onValueChange={setDate}/><DatePicker v-model="date" v-model:month="month" name="appointment" label="Appointment date"/><simurgh-date-picker [(value)]="date" [(month)]="month" name="appointment" label="Appointment date"/>Real-world example: constrained appointment dates
Section titled “Real-world example: constrained appointment dates”Keep constraints in ISO date form and validate again on the server because client constraints can be bypassed. Explain unavailable dates outside the calendar when users need the reason.
const disabledDates = holidays.map((holiday) => holiday.date);<DatePicker value={date} onValueChange={setDate} name="appointment" min="2026-08-14" max="2026-09-30" disabledDates={disabledDates} label="Appointment date" required/>;Vue uses v-model="date" with :disabled-dates="disabledDates"; Angular uses [(value)]="date"
with [disabledDates]="disabledDates". Keep min, max, locale, and first-day settings identical.
Keyboard interactions
Section titled “Keyboard interactions”These keys describe behavior implemented by the adapters. Native Tab, Enter, and Space behavior still applies to descendant links, buttons, and form controls unless the component overrides it.
| Concern / keys | Behavior |
|---|---|
| Focus entry and exit (Tab / Shift+Tab) | Tab reaches the trigger/input, then the open calendar grid. |
| Navigation and activation | Calendar arrows move days; Home/End moves to week edges; Enter or Space selects. |
| Escape | Escape closes the popover when focus is inside it. |
| RTL differences | Calendar Arrow Left/Right movement reverses in RTL. |
| Typeahead | Not supported. |
Accessibility
Section titled “Accessibility”Preserve the documented composition and accessible names when wrapping or restyling this component. See accessibility and RTL guidance for keyboard, focus, labeling, and directionality requirements.
API surface
Section titled “API surface”- React exports:
DatePicker,DatePickerProps - Vue exports:
DatePicker - Angular exports:
DatePickerComponent
Import these public symbols from the component subpath shown in Installation. Framework-specific props, events, slots, directives, methods, defaults, and native-attribute behavior belong in the API tables on this page; use the linked source only to verify the current implementation.
React API reference
An inherited-attributes entry means the component accepts the complete named React native interface, including its event handlers and ARIA and data attributes. Remaining attributes are forwarded to the rendered element unless the component behavior described on this page overrides them.
DatePicker
Section titled “DatePicker”Complete props type: DatePickerProps.
| Prop | Type | Default / requirement |
|---|---|---|
defaultMonth | string | undefined |
defaultValue | string | undefined |
direction | Direction | undefined |
disabled | boolean | undefined |
disabledDates | string[] | undefined |
firstDayOfWeek | number | undefined |
label | string | undefined |
locale | string | undefined |
max | string | undefined |
min | string | undefined |
month | string | undefined |
name | string | undefined |
onMonthChange | (month: string) => void | undefined |
onValueChange | (value: string) => void | undefined |
placeholder | string | undefined |
required | boolean | undefined |
value | string | undefined |
DatePickerProps
Section titled “DatePickerProps”Exported type: CalendarProps & { placeholder?: string; required?: boolean; disabled?: boolean; }.
Vue API reference
Boolean props without explicit defaults use Vue’s false default. Undeclared attributes follow
the fallthrough behavior stated for each component.
DatePicker
Section titled “DatePicker”Vue attribute fallthrough is enabled for the rendered root.
| Prop | Type | Default / requirement |
|---|---|---|
modelValue | string | undefined |
defaultValue | string | '' |
month | string | undefined |
defaultMonth | string | undefined |
locale | string | 'en' |
direction | Direction | 'ltr' |
firstDayOfWeek | number | 0 |
min | string | undefined |
max | string | undefined |
disabledDates | string[] | () => [] |
name | string | undefined |
label | string | 'Date picker calendar' |
placeholder | string | 'Pick a date' |
required | boolean | false |
disabled | boolean | false |
| Event | Payload |
|---|---|
update:modelValue | string |
update:month | string |
Slots: none.
Exposed methods: none.
Angular API reference
Angular
Section titled “Angular”Inputs and outputs use their public template names. Public methods are callable through a template
reference or ViewChild. Native attributes apply to the documented template root or directive host;
they are not automatically forwarded through component hosts.
DatePickerComponent
Section titled “DatePickerComponent”Component selector: simurgh-date-picker. The template’s first native element is div.
| Input | Type | Default / requirement |
|---|---|---|
value | string | '' |
month | string | calendarToday().slice(0, 7) |
locale | string | 'en' |
direction | Direction | 'ltr' |
firstDayOfWeek | number | 0 |
min | string | undefined |
max | string | undefined |
disabledDates | string[] | [] |
name | string | undefined |
label | string | 'Date picker calendar' |
placeholder | string | 'Pick a date' |
required | boolean | false |
disabled | boolean | false |
| Output | Payload |
|---|---|
valueChange | string |
monthChange | string |
Content projection: none.
| Public method |
|---|
choose(value: string): void |
updateMonth(month: string): void |
Composition contract
Section titled “Composition contract”Follow the framework example as a structural contract. Root components own shared state; parts that consume that state must stay under the root (or be attached to projected descendants in Angular). Parts described as conditional are optional until their corresponding interaction or semantic region is used. Do not render a state-consuming part by itself.
| Framework | Required parent/child relationship | Conditional parts | Supporting types |
|---|---|---|---|
| React | DatePicker is standalone and required when using this component. | Content is optional unless the API requires a label or value. | DatePickerProps. |
| Vue | DatePicker is standalone and required when using this component. | Content is optional unless the API requires a label or value. | None. |
| Angular | DatePickerComponent is standalone and required when using this component. | Content is optional unless the API requires a label or value. | None. |
Accessible names, descriptions, and form labels remain required whenever the component’s purpose cannot otherwise be determined, even when the corresponding visual part is optional.
Framework parity and differences
Section titled “Framework parity and differences”The adapters target the same user-visible behavior and accessibility contract. Their public shapes follow each framework’s conventions and are not expected to be symbol-for-symbol identical.
| Concern | Contract |
|---|---|
| Public composition | React exports 2 parts, Vue 1, and Angular 1. These are intentional composition differences; use each framework’s example rather than translating symbol-for-symbol. |
| State and change events | React uses controlled/default props and callbacks for month, value; Vue uses v-model, v-model:month; Angular uses [(value)], [(month)]. |
| Children and content | React uses children; Vue uses the slots listed above; Angular uses the documented content projection selectors. |
| Native attributes | React forwards the named native interface; Vue follows the stated fallthrough rule; Angular attributes apply to the component host unless an input, directive, or documented native root consumes them. |
| Imperative access | React has no forwarded ref; Vue exposes no methods; Angular exposes the listed class methods through a template reference or ViewChild. |
These differences are intentional adapter design. Behavioral or accessibility differences not stated on this page are parity defects rather than supported variations.
Form integration
Section titled “Form integration”Use name="appointmentDate" to serialize the current value under the documented field name. The examples initialize the field, keep its
value application-owned, forward disabled and required, render an accessible error, and read
the browser submission payload. This component has no public invalid prop; announce validation errors next to the labeled control and use native validity where available.
const initial = '2026-08-12';const [value, setValue] = useState(initial);const [errors, setErrors] = useState<Record<string, string>>({});
<form onSubmit={(event) => { event.preventDefault(); const data = new FormData(event.currentTarget); // Submit data.get('appointmentDate').}}> <DatePicker name="appointmentDate" value={value} onValueChange={setValue} required disabled={isDisabled} /> {errors.appointmentDate && <p role="alert">{errors.appointmentDate}</p>} <button type="submit">Submit</button></form><script setup lang="ts">import { reactive, ref } from 'vue';const initial = '2026-08-12';const value = ref(initial);const errors = reactive<Record<string, string>>({});function submit(event: Event) { const data = new FormData(event.currentTarget as HTMLFormElement); // Submit data.get('appointmentDate').}</script>
<form @submit.prevent="submit"> <DatePicker v-model="value" name="appointmentDate" required :disabled="isDisabled"></DatePicker> <p v-if="errors.appointmentDate" role="alert">{{ errors.appointmentDate }}</p> <button type="submit">Submit</button></form>Angular
Section titled “Angular”initial = '2026-08-12';value = this.initial;errors: Record<string, string> = {};submit(form: HTMLFormElement) { const data = new FormData(form); // Submit data.get('appointmentDate').}<form #form (submit)="submit(form); $event.preventDefault()"> <simurgh-date-picker [(value)]="value" name="appointmentDate" required [disabled]="isDisabled"></simurgh-date-picker> <p *ngIf="errors.appointmentDate" role="alert">{{ errors.appointmentDate }}</p> <button type="submit">Submit</button></form>For Angular reactive or template-driven forms, bridge the documented value/valueChange pair
to your form control. The component does not implement ControlValueAccessor; update disabled and
validation state from the Angular form explicitly.
Supported states
Section titled “Supported states”The table distinguishes component behavior from application-owned presentation. “Not supported” means there is no public state contract for that adapter; do not invent one with an undocumented attribute. Keep status and error messages accessible when they are rendered outside the component.
| State | React | Vue | Angular |
|---|---|---|---|
| Loading | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. |
| Empty | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. |
| Invalid | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. |
| Read-only | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. |
| Disabled | Supported with disabled={true} on the documented control or interactive part; its interaction is blocked. Disabled form controls are omitted from submission. | Supported with :disabled="true" on the documented control or interactive part; its interaction is blocked. Disabled form controls are omitted from submission. | Supported with [disabled]="true" on the documented control or interactive part; its interaction is blocked. Disabled form controls are omitted from submission. |
| Error | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. | Not supported by this component API; handle this state in surrounding application UI. |
Styling contract
Styling contract
Section titled “Styling contract”The selectors below are used by the published component recipe or emitted consistently by an adapter. Treat these as the supported styling surface. Element order, anonymous wrappers, and undocumented descendants are implementation details and should not be targeted.
| Surface | Stable hooks |
|---|---|
| Recipe classes | .simurgh-content, .simurgh-item, .simurgh-trigger |
| Stable DOM parts | [data-slot="button"], [data-slot="calendar"], [data-slot="checkbox"], [data-slot="date-picker"], [data-slot="date-picker-content"], [data-slot="date-picker-trigger"], [data-slot="input"], [data-slot="input-otp"], [data-slot="native-select"], [data-slot="pagination-link"], [data-slot="select-trigger"], [data-slot="toggle-group-item"], [data-slot="toolbar-button"] |
| Stable data attributes | [data-density], [data-slot] |
| ARIA/state selectors used by the recipe | [aria-disabled] |
| CSS custom properties consumed | --simurgh-border, --simurgh-control-height, --simurgh-control-padding, --simurgh-foreground, --simurgh-radius, --simurgh-ring, --simurgh-shadow, --simurgh-surface |
Prefer a semantic token override for theme-wide changes. Use the listed class or part selectors for a component-scoped override. When omitting recipe CSS, preserve state attributes and ARIA semantics even if your replacement styles use different selectors.
Customization
Section titled “Customization”Load the optional component stylesheet for the default recipe, override semantic tokens for broad theme changes, or omit the recipe CSS for headless styling. See theming and styling hooks for import order, selectors, dark mode, RTL, and reduced-motion guidance.
Last verified on 2026-08-13 against Simurgh registry 0.1.1.
Related components
Section titled “Related components”- Review the shared accessibility and RTL guidance and theming and styling hooks.
- Use the component chooser and component overview to compare related primitives.
- Inspect the registry manifest and framework source for React, Vue, or Angular.