Form field for choosing a calendar date, datetime, or range through locale-ordered segmented entry, a calendar surface, and expression-based presets, with all values carried as zoneless ISO-8601 strings.
Install @wyrd-company/react or the Flutter package and use it directly —
your DESIGN.md does the styling.
catalog/contracts/date-time-picker.ymlsource of truth · verbatim
$schema: https://thewyrdingway.dev/schemas/component-contract.schema.ymlcontractVersion: 0.1.0identity:name: DateTimePickertag: wyrd-date-time-pickerpackage: wyrd.component.date-time-pickertitle: Date Time Pickersummary: Form field for choosing a calendar date, datetime, or range through locale-ordered segmented entry, a calendar surface, and expression-based presets, with all values carried as zoneless ISO-8601 strings.relationships:related-to: - behavior-date-time-picker - l10n-formatting-runtimeclassification:category: form-fieldcomposition: multi-slotinteractive: truetarget-strategy:react: requiredflutter: requiredsurface:properties: - name: valuetype:kind: stringrequired: falsecontrolled: trueserializable: truesummary: Controlled zoneless ISO-8601 value; a point in single mode ("2026-07-09", "2026-07-09T14:30") or an interval in range mode ("2026-07-01/2026-07-31"). Precision follows granularity. - name: default-valuetype:kind: stringrequired: falseserializable: truesummary: Initial uncontrolled ISO-8601 point or interval. - name: selection-modetype:kind: enumvalues: - single - rangerequired: falsedefault: singleserializable: truesummary: Whether the value is a single point or a start/end interval selected in two steps. - name: granularitytype:kind: enumvalues: - year - month - day - hour - minuterequired: falsedefault: dayserializable: truesummary: Value precision and deepest calendar surface; year and month terminate at their drill level, hour and minute add time columns. - name: displaytype:kind: enumvalues: - popover - inline - modalrequired: falsedefault: popoverreflects: trueserializable: truesummary: Calendar presentation; inline embeds the calendar surface permanently open, modal presents a mobile-friendly overlay. - name: is-opentype:kind: booleanrequired: falsedefault: falsecontrolled: truereflects: trueserializable: truesummary: Controlled calendar visibility for popover and modal display; ignored by inline display. - name: default-opentype:kind: booleanrequired: falsedefault: falseserializable: truesummary: Initial uncontrolled calendar visibility for popover and modal display. - name: is-disabledtype:kind: booleanrequired: falsedefault: falsereflects: trueserializable: truesummary: Prevents opening the calendar, editing segments, and changing the value. - name: mintype:kind: stringrequired: falseserializable: truesummary: Earliest selectable ISO-8601 value, inclusive, at the active granularity. - name: maxtype:kind: stringrequired: falseserializable: truesummary: Latest selectable ISO-8601 value, inclusive, at the active granularity. - name: blackout-datestype:kind: arrayitem:kind: stringrequired: falsedefault: []serializable: truesummary: ISO-8601 dates rendered disabled and unselectable; shown, never hidden. - name: blackout-weekdaystype:kind: arrayitem:kind: integerminimum: 1maximum: 7required: falsedefault: []serializable: truesummary: ISO weekday numbers (1 = Monday) rendered disabled and unselectable in every visible week. - name: max-spantype:kind: stringrequired: falseserializable: truesummary: Maximum range length as an ISO-8601 duration (for example P30D); days beyond the span disable while a range start is pending. - name: minute-steptype:kind: integerminimum: 1maximum: 30required: falsedefault: 1serializable: truesummary: Minute column increment at minute granularity. - name: visible-monthstype:kind: integerminimum: 1maximum: 3required: falsedefault: 1serializable: truesummary: Number of consecutive month panes shown by the calendar surface. - name: reference-datetype:kind: stringrequired: falseserializable: truesummary: ISO-8601 anchor for the today marker and preset expression resolution; hosts default it to the current date at the seam, and the runtime never reads a clock. - name: presetstype:kind: arrayitem:kind: objectfields:template:kind: stringn:kind: integerrequired: falsedefault: []serializable: truesummary: Ordered relative-date expressions (template plus optional count) resolved and labeled by the shared runtime against reference-date; selecting one commits its resolved value. - name: fiscal-year-start-monthtype:kind: integerminimum: 1maximum: 12required: falsedefault: 1serializable: truesummary: First month of the fiscal year consumed by quarter and year preset templates. - name: day-metadatatype:kind: arrayitem:kind: objectfields:date:kind: stringweight:kind: numberlabel:kind: stringrequired: falsedefault: []serializable: truesummary: Per-day metadata; weight (0-1) drives built-in density shading and label augments the day's accessible name.slots: - name: labelrequired: truecardinality: exactly-oneaccepts: - textsummary: Visible label and accessible-name source. - name: descriptionrequired: falsecardinality: zero-or-oneaccepts: - textsummary: Help text associated with the field. - name: day-cellrequired: falsecardinality: zero-or-oneaccepts: - componentsummary: Consumer renderer for day cells receiving day context; replaces the built-in cell content while selection and disabled semantics stay component-owned.events: - name: value-changepayload:value:kind: stringaction:kind: action-refbubbles: truecomposed: truecancelable: falsesummary: Canonical value-change event carrying the ISO-8601 point or interval. - name: open-changepayload:is-open:kind: booleanreason:kind: enumvalues: - trigger - keyboard - dismiss - select - programmaticbubbles: truecomposed: truecancelable: falsesummary: Canonical calendar visibility event for popover and modal display.states: - name: closedsource: behavior-runtimesummary: Calendar surface is not visible. - name: opensource: behavior-runtimesummary: Calendar surface is visible; always active under inline display. - name: range-start-pendingsource: behavior-runtimesummary: Range mode has a committed start awaiting an end selection. - name: focusedsource: behavior-runtimesummary: Segments, trigger, or calendar own focus. - name: blurredsource: behavior-runtimesummary: Focus is outside the field. - name: disabledsource: propertysummary: Disabled state derived from is-disabled. - name: filledsource: propertysummary: State when value or default-value holds a point or interval.parts: - name: rootsummary: Field root and popup positioning owner.slots: - label - description - name: labelsummary: Label text.slots: - label - name: controlsummary: Segmented input composing the value from locale-ordered segments. - name: segmentsummary: Repeated editable segment for one date or time field. - name: triggersummary: Button that opens and closes the calendar surface. - name: popupsummary: Popover or modal calendar surface. - name: calendar-headersummary: Localized heading with previous and next navigation at the active drill level. - name: gridsummary: Day, month, or year grid with locale-derived week layout. - name: daysummary: Repeated day gridcell.slots: - day-cell - name: time-panelsummary: Hour and minute columns synchronized with the date selection. - name: preset-groupsummary: Ordered preset shortcut panel. - name: presetsummary: Repeated preset shortcut with its runtime-resolved label. - name: descriptionsummary: Description text.slots: - descriptiontokens:root:gap: spacing.xslabel:color: color.on-surfacefont: typography.label-mdcontrol:background: color.surfaceforeground: color.on-surfaceplaceholder: color.on-surface-variantborder-color: color.outlineborder-color-focus: color.primaryborder-width: 1pxradius: rounded.smpadding-x: spacing.mdpadding-y: spacing.smfont: typography.body-mdsegment:background-focus: color.primaryforeground-focus: color.on-primaryradius: rounded.smpadding-x: spacing.xstrigger:background: color.primaryforeground: color.on-primaryradius: rounded.smpadding-x: spacing.mdpadding-y: spacing.smfont: typography.label-mdpopup:background: color.surface-containerforeground: color.on-surfaceborder-color: color.outlineradius: rounded.mdshadow: shadow.mdpadding: spacing.mdgap: spacing.smcalendar-header:foreground: color.on-surfacefont: typography.label-mdgap: spacing.smgrid:gap: spacing.xsday:foreground: color.on-surfaceforeground-disabled: color.on-surface-variantbackground-selected: color.primaryforeground-selected: color.on-primarybackground-in-range: color.surface-containerforeground-in-range: color.on-surfacebackground-today: color.surface-containerdensity-tint: color.primaryradius: rounded.smpadding-x: spacing.smpadding-y: spacing.xstime-panel:background: color.surface-containerforeground: color.on-surfacebackground-selected: color.primaryforeground-selected: color.on-primarygap: spacing.xsfont: typography.body-mdpreset-group:gap: spacing.xspadding: spacing.smpreset:background: color.surface-containerforeground: color.on-surfacebackground-selected: color.primaryforeground-selected: color.on-primaryradius: rounded.smpadding-x: spacing.smpadding-y: spacing.xsfont: typography.label-mdmessages: - key: date-time-picker.labeldescription: Default visible label shown when the label slot is not supplied. - key: date-time-picker.placeholderdescription: Placeholder shown while no value is selected. - key: date-time-picker.open-calendardescription: Accessible label for the calendar trigger. - key: date-time-picker.selected-datedescription: Announces a selected date.params:when: date - key: date-time-picker.selected-timedescription: Announces a selected time.params:when: date - key: date-time-picker.selected-datetimedescription: Announces a selected date and time.params:when: date - key: date-time-picker.selected-rangedescription: Announces a selected range with its start and end.params:start: dateend: date - key: date-time-picker.month-headingdescription: Calendar heading at day granularity.params:when: date - key: date-time-picker.previous-monthdescription: Accessible label for moving to the previous month. - key: date-time-picker.next-monthdescription: Accessible label for moving to the next month. - key: date-time-picker.previous-yeardescription: Accessible label for moving to the previous year at month and year drill levels. - key: date-time-picker.next-yeardescription: Accessible label for moving to the next year at month and year drill levels. - key: date-time-picker.day-labeldescription: Accessible label for one day in the grid.params:when: date - key: date-time-picker.weekday.mondaydescription: Abbreviated Monday column heading. - key: date-time-picker.weekday.tuesdaydescription: Abbreviated Tuesday column heading. - key: date-time-picker.weekday.wednesdaydescription: Abbreviated Wednesday column heading. - key: date-time-picker.weekday.thursdaydescription: Abbreviated Thursday column heading. - key: date-time-picker.weekday.fridaydescription: Abbreviated Friday column heading. - key: date-time-picker.weekday.saturdaydescription: Abbreviated Saturday column heading. - key: date-time-picker.weekday.sundaydescription: Abbreviated Sunday column heading. - key: date-time-picker.today-markerdescription: Label for the reference-date marker. - key: date-time-picker.range-start-promptdescription: Instruction announced when range mode awaits a start selection. - key: date-time-picker.range-end-promptdescription: Instruction announced while a range start is pending an end selection. - key: date-time-picker.out-of-rangedescription: Explanation for days disabled by the min and max bounds.params:earliest: datelatest: date - key: date-time-picker.blackoutdescription: Explanation for days disabled by blackout rules.params:when: date - key: date-time-picker.max-span-exceededdescription: Explanation for days disabled because the range would exceed max-span.params:days: plural - key: date-time-picker.time-headingdescription: Heading for the time columns at hour and minute granularity. - key: date-time-picker.segment-yeardescription: Accessible name for the year segment. - key: date-time-picker.segment-monthdescription: Accessible name for the month segment. - key: date-time-picker.segment-daydescription: Accessible name for the day segment. - key: date-time-picker.segment-hourdescription: Accessible name for the hour segment. - key: date-time-picker.segment-minutedescription: Accessible name for the minute segment. - key: date-time-picker.preset.todaydescription: Label for the today preset template. - key: date-time-picker.preset.yesterdaydescription: Label for the yesterday preset template. - key: date-time-picker.preset.tomorrowdescription: Label for the tomorrow preset template. - key: date-time-picker.preset.last-n-daysdescription: Label for the trailing-days preset template.params:n: plural - key: date-time-picker.preset.next-n-daysdescription: Label for the leading-days preset template.params:n: plural - key: date-time-picker.preset.this-weekdescription: Label for the current-week preset template. - key: date-time-picker.preset.this-monthdescription: Label for the current-month preset template. - key: date-time-picker.preset.this-quarterdescription: Label for the current-quarter preset template, fiscal-aware. - key: date-time-picker.preset.this-yeardescription: Label for the current-year preset template, fiscal-aware. - key: date-time-picker.preset.month-to-datedescription: Label for the month-to-date preset template. - key: date-time-picker.preset.quarter-to-datedescription: Label for the quarter-to-date preset template, fiscal-aware. - key: date-time-picker.preset.year-to-datedescription: Label for the year-to-date preset template, fiscal-aware.obligations:accessibility:role: composite grid popupname: Label slot provides the accessible name for the segmented control.description: Description slot is programmatically associated with the control; segment, grid, and time-column semantics are documented-manual with axe coverage for role, name, and disabled exposure.keyboard: - Left and Right arrows move focus between segments; typed digits fill the focused segment and auto-advance. - Up and Down arrows increment and decrement the focused segment within its valid range. - Enter and Space on the trigger open the calendar surface. - Arrow keys move focus by day in the grid; PageUp and PageDown move by month; Shift plus PageUp and PageDown move by year. - Home and End move focus to the start or end of the locale-derived week. - Enter selects the focused day, committing the point in single mode or the pending start and then end in range mode. - Arrow keys in the time columns move by minute-step and synchronize with the selected date. - Escape closes popover and modal surfaces without changing the value.semantics: - Each segment exposes spinbutton semantics with its localized name, current value, and valid range. - Trigger exposes expanded state while the calendar surface is visible. - Grid and gridcell roles expose focused, selected, in-range, and disabled states. - Days disabled by bounds, blackouts, or max-span remain visible and expose a localized explanation. - Preset shortcuts expose their runtime-resolved localized labels. - Values are zoneless; no timezone is announced or implied.behavior:model: behavior-runtimeruntimeBlueprint: behavior/date-time-pickerinteractions: - Opening and closing the calendar follows the behavior runtime trace with reasons; inline display pins the machine open. - Single mode commits a point on day (or time-column) selection and closes popover and modal surfaces with a select reason. - Range mode commits a start into range-start-pending, previews the hovered span target-locally, and commits the interval on end selection. - Preset activation resolves its expression through the shared runtime and commits the resolved value through the normal selection path. - Granularity drill (year to month to day) and time-column synchronization follow the machine's drill state. - Segment editing, grid focus traversal, hover preview, and popup positioning remain target-local.hostEffects: - Dispatch value-change and open-change events. - Move focus between segments, trigger, grid, and time columns per target platform conventions. - Format all date-bearing and time-bearing text through the localization seam. - Query the runtime for locale segment order, preset resolution, and preset labels. - Keep popup positioning synchronized with the control under popover display.conditions: - rtl - locale - reduced-motion - cvd-deuteranopia - density-compact - text-expansion - safe-area - keyboard-insetsdui:status: partialserializableProperties: - value - default-value - selection-mode - granularity - display - is-open - default-open - is-disabled - min - max - blackout-dates - blackout-weekdays - max-span - minute-step - visible-months - reference-date - presets - fiscal-year-start-month - day-metadataserializableSlots: - label - descriptioneventBindings: - value-change - open-changenotes: Values, constraints, presets, and day metadata serialize as plain data; the day-cell renderer slot, calendar rendering, locale-derived layout, focus movement, and keyboard navigation remain target-local.examples: - name: emptystate: closedproperties:reference-date: "2026-07-09"slots:label: Datedescription: Pick the due date. - name: selectedstate: closedproperties:default-value: "2026-07-09"min: "2026-07-01"max: "2026-07-31"reference-date: "2026-07-09"slots:label: Date - name: open-rangestate: openproperties:selection-mode: rangedefault-value: "2026-07-01/2026-07-07"default-open: truevisible-months: 2max-span: P30Dreference-date: "2026-07-09"presets: - template: today - template: last-n-daysn: 7 - template: last-n-daysn: 30 - template: this-quarterslots:label: Reporting period - name: datetimestate: openproperties:granularity: minutedefault-value: "2026-07-09T14:30"default-open: trueminute-step: 15reference-date: "2026-07-09"slots:label: Appointment - name: inline-dashboardstate: openproperties:display: inlineselection-mode: rangedefault-value: "2026-07-01/2026-07-07"reference-date: "2026-07-09"day-metadata: - date: "2026-07-02"weight: 0.8label: High activity - date: "2026-07-04"weight: 0.3label: Low activitypresets: - template: last-n-daysn: 7 - template: month-to-dateslots:label: Activity window - name: disabledstate: disabledproperties:value: "2026-07-09"is-disabled: truereference-date: "2026-07-09"slots:label: Date
01
Examples
Generated from the contract's examples block.
Previews are the published @wyrd-company/react component, themed by the
brand's role tokens — flip the site's light/dark toggle and they follow.
emptystate: closed
Usage
import { WyrdDateTimePicker } from"@wyrd-company/react";
<WyrdDateTimePicker referenceDate="2026-07-09" label="Date" description="Pick the due date." />
// events: onValueChange, onOpenChange
import'package:wyrd_flutter/wyrd_flutter.dart';
WyrdDateTimePicker(
referenceDate: '2026-07-09',
label: Text('Date'),
description: Text('Pick the due date.'),
)
// events: onChanged, onOpenChanged
Controlled zoneless ISO-8601 value; a point in single mode ("2026-07-09", "2026-07-09T14:30") or an interval in range mode ("2026-07-01/2026-07-31"). Precision follows granularity.
default-value
string
undefined
Initial uncontrolled ISO-8601 point or interval.
selection-mode
single | range
single
Whether the value is a single point or a start/end interval selected in two steps.
granularity
year | month | day | hour | minute
day
Value precision and deepest calendar surface; year and month terminate at their drill level, hour and minute add time columns.
display
popover | inline | modal
popover
Calendar presentation; inline embeds the calendar surface permanently open, modal presents a mobile-friendly overlay.
is-open
boolean
false
Controlled calendar visibility for popover and modal display; ignored by inline display.
default-open
boolean
false
Initial uncontrolled calendar visibility for popover and modal display.
is-disabled
boolean
false
Prevents opening the calendar, editing segments, and changing the value.
min
string
undefined
Earliest selectable ISO-8601 value, inclusive, at the active granularity.
max
string
undefined
Latest selectable ISO-8601 value, inclusive, at the active granularity.
blackout-dates
array
ISO-8601 dates rendered disabled and unselectable; shown, never hidden.
blackout-weekdays
array
ISO weekday numbers (1 = Monday) rendered disabled and unselectable in every visible week.
max-span
string
undefined
Maximum range length as an ISO-8601 duration (for example P30D); days beyond the span disable while a range start is pending.
minute-step
integer
1
Minute column increment at minute granularity.
visible-months
integer
1
Number of consecutive month panes shown by the calendar surface.
reference-date
string
undefined
ISO-8601 anchor for the today marker and preset expression resolution; hosts default it to the current date at the seam, and the runtime never reads a clock.
presets
array
Ordered relative-date expressions (template plus optional count) resolved and labeled by the shared runtime against reference-date; selecting one commits its resolved value.
fiscal-year-start-month
integer
1
First month of the fiscal year consumed by quarter and year preset templates.
day-metadata
array
Per-day metadata; weight (0-1) drives built-in density shading and label augments the day's accessible name.
03
Slots & events
Slot
Cardinality
Accepts
Summary
label
exactly-one
text
Visible label and accessible-name source.
description
zero-or-one
text
Help text associated with the field.
day-cell
zero-or-one
component
Consumer renderer for day cells receiving day context; replaces the built-in cell content while selection and disabled semantics stay component-owned.
Event
Payload
Summary
value-change
value, action
Canonical value-change event carrying the ISO-8601 point or interval.
open-change
is-open, reason
Canonical calendar visibility event for popover and modal display.
04
Tokens
The contract's token bindings. Open the shared contextual sidebar from any example;
primary swatches reflect the color you pick there. Error swatches show the active
preset's values; editing any knob switches to custom and resets error to TWW · Ink.
Binding
Token
root.gap
spacing.xs
label.color
color.on-surface
label.font
typography.label-md
control.background
color.surface
control.foreground
color.on-surface
control.placeholder
color.on-surface-variant
control.border-color
color.outline
control.border-color-focus
color.primary
control.border-width
1px
control.radius
rounded.sm
control.padding-x
spacing.md
control.padding-y
spacing.sm
control.font
typography.body-md
segment.background-focus
color.primary
segment.foreground-focus
color.on-primary
segment.radius
rounded.sm
segment.padding-x
spacing.xs
trigger.background
color.primary
trigger.foreground
color.on-primary
trigger.radius
rounded.sm
trigger.padding-x
spacing.md
trigger.padding-y
spacing.sm
trigger.font
typography.label-md
popup.background
color.surface-container
popup.foreground
color.on-surface
popup.border-color
color.outline
popup.radius
rounded.md
popup.shadow
shadow.md
popup.padding
spacing.md
popup.gap
spacing.sm
calendar-header.foreground
color.on-surface
calendar-header.font
typography.label-md
calendar-header.gap
spacing.sm
grid.gap
spacing.xs
day.foreground
color.on-surface
day.foreground-disabled
color.on-surface-variant
day.background-selected
color.primary
day.foreground-selected
color.on-primary
day.background-in-range
color.surface-container
day.foreground-in-range
color.on-surface
day.background-today
color.surface-container
day.density-tint
color.primary
day.radius
rounded.sm
day.padding-x
spacing.sm
day.padding-y
spacing.xs
time-panel.background
color.surface-container
time-panel.foreground
color.on-surface
time-panel.background-selected
color.primary
time-panel.foreground-selected
color.on-primary
time-panel.gap
spacing.xs
time-panel.font
typography.body-md
preset-group.gap
spacing.xs
preset-group.padding
spacing.sm
preset.background
color.surface-container
preset.foreground
color.on-surface
preset.background-selected
color.primary
preset.foreground-selected
color.on-primary
preset.radius
rounded.sm
preset.padding-x
spacing.sm
preset.padding-y
spacing.xs
preset.font
typography.label-md
05
States
State
Source
Summary
closed
behavior-runtime
Calendar surface is not visible.
open
behavior-runtime
Calendar surface is visible; always active under inline display.
range-start-pending
behavior-runtime
Range mode has a committed start awaiting an end selection.
focused
behavior-runtime
Segments, trigger, or calendar own focus.
blurred
behavior-runtime
Focus is outside the field.
disabled
property
Disabled state derived from is-disabled.
filled
property
State when value or default-value holds a point or interval.
06
Accessibility
From the contract's accessibility obligations. Role composite grid popup; Label slot provides the accessible name for the segmented control.
Left and Right arrows move focus between segments; typed digits fill the focused segment and auto-advance.
Up and Down arrows increment and decrement the focused segment within its valid range.
Enter and Space on the trigger open the calendar surface.
Arrow keys move focus by day in the grid; PageUp and PageDown move by month; Shift plus PageUp and PageDown move by year.
Home and End move focus to the start or end of the locale-derived week.
Enter selects the focused day, committing the point in single mode or the pending start and then end in range mode.
Arrow keys in the time columns move by minute-step and synchronize with the selected date.
Escape closes popover and modal surfaces without changing the value.
Each segment exposes spinbutton semantics with its localized name, current value, and valid range.
Trigger exposes expanded state while the calendar surface is visible.
Grid and gridcell roles expose focused, selected, in-range, and disabled states.
Days disabled by bounds, blackouts, or max-span remain visible and expose a localized explanation.
Preset shortcuts expose their runtime-resolved localized labels.
Values are zoneless; no timezone is announced or implied.