DateInput
DateInput lets the user type or pick a date from a calendar popover. Use it for scheduling, deadlines, booking dates, or any form field that needs a specific calendar date.
Installation
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
Requires React 19+, base CSS and a Theme provider. See Setup.
Date Input
DateInput lets the user type or pick a date from a calendar popover. Use it for scheduling, deadlines, booking dates, or any form field that needs a specific calendar date.
| Prop | Type | Default | Description |
|---|---|---|---|
| label * | string | Label text. | |
| isLabelHidden | boolean | false | Visually hide the label. |
| description | string | Helper text displayed below the label. | |
| isOptional | boolean | false | Show an "(optional)" indicator next to the label. |
| isRequired | boolean | false | Mark the field as required. |
| isDisabled | boolean | false | Disable the input and calendar. |
| disabledMessage | string | Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled DateInput in Tooltip. Disabled controls swallow the hover events an external Tooltip needs. | |
| value | ISODateString | Selected date in YYYY-MM-DD format. | |
| onChange | (value: ISODateString | undefined) => void | Callback invoked when the selected date changes. | |
| changeAction | (value: ISODateString | undefined) => void | Promise<void> | Async action fired after onChange. Drives optimistic UI updates via useTransition. | |
| isLoading | boolean | false | Whether the input is in a loading state. Disables interaction and shows a spinner. |
| min | ISODateString | Minimum selectable date (YYYY-MM-DD). | |
| max | ISODateString | Maximum selectable date (YYYY-MM-DD). | |
| dateConstraints | ReadonlyArray<(date: Date) => boolean> | Array of custom constraint functions that disable specific dates. | |
| placeholder | string | 'Select a date' | Placeholder text shown in the text input. |
| size | 'sm' | 'md' | 'lg' | 'md' | Size of the input control. |
| status | {type: 'warning' | 'error' | 'success', message?: string} | Status indicator object for error, warning, or success states with a message. | |
| statusVariant | 'attached' | 'detached' | 'tooltip' | 'attached' | How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing; tooltip hides the message box and surfaces it in a tooltip on the status icon. |
| labelTooltip | string | Tooltip text displayed via an info icon at the end of the label. | |
| hasClear | boolean | false | Shows a clear (×) button when a date value is set. Clicking it clears the value and returns focus to the input. |
| numberOfMonths | 1 | 2 | 1 | Number of months displayed simultaneously in the calendar popover. |
| weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 0 | First day of week in Astryx calendar surfaces. A number (0 = Sunday to 6 = Saturday) or a three-letter day name; native pickers remain browser/OS-owned. |
| format | 'date' | 'date_long' | 'date_weekday' | 'system_date' | ((value: ISODateString) => string) | 'date_long' | How the committed date value is displayed. Named values are reused from Timestamp's format vocabulary: 'date' shows 'Mar 21, 2026', 'date_long' shows 'March 21, 2026', 'date_weekday' shows 'Wed, Mar 21, 2026', 'system_date' shows '2026-03-21'. A function receives the ISO value and returns a custom string. Applies only to the committed value, never to text being typed. |
| presentation | 'popover' | 'bottom-sheet' | 'native' | 'adaptive-bottom-sheet' | 'adaptive-native' | 'adaptive-native' | Which surface draws the date picker. 'adaptive-native' (the default) uses Astryx's calendar popover on a fine pointer and the browser/OS picker (input type=date) on a coarse pointer, keeping Astryx fallbacks where a native control cannot express the value; 'native' always uses the browser/OS picker with no fallback; 'adaptive-bottom-sheet' uses the popover on a fine pointer and Astryx's bottom-sheet picker on a coarse pointer; 'popover' and 'bottom-sheet' force that Astryx surface on every pointer. Every value opens a picker; a typed-only field is TimeInput's alone. Use a non-native presentation for a field that needs weekStartsOn, numberOfMonths or dateConstraints, none of which a native picker can express. |
| nativePicker | 'touch' | 'always' | 'never' | 'touch' | Deprecated: use presentation ('touch' = 'adaptive-native', 'always' = 'native', 'never' = 'adaptive-bottom-sheet'). Still works exactly as released; presentation wins when both are set. |
| width | SizeValue | Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned. | |
| containerXstyle | StyleXStyles | StyleX styles for the Field box around the label, control, and status. containerClassName and containerStyle take a class name and inline styles for the same box. No effect (development warning) where no Field box renders: inside InputGroup (style the group) and in a horizontal-labels FormLayout. | |
| containerClassName | string | Class name for the Field box. Same targeting as containerXstyle. | |
| containerStyle | CSSProperties | Inline styles for the Field box. Same targeting as containerXstyle. | |
| controlXstyle | StyleXStyles | StyleX styles for the visual control box: the bordered element that holds the text, icons, and end controls, never the native input. controlClassName and controlStyle take a class name and inline styles for the same box. Replaces root xstyle, className, and style, which this component does not accept. | |
| controlClassName | string | Class name for the visual control box. Same targeting as controlXstyle. | |
| controlStyle | CSSProperties | Inline styles for the visual control box. Same targeting as controlXstyle. |
Usage guidance
- Base props such as ref, id, data-, aria-, and DOM event handlers go to the date input, the element that is focused and announced. A DOM handler runs after DateInput's own handler for the same event and still receives events it handled (including ones it called preventDefault on), so it cannot cancel built-in behavior.
- Provide clear labels and descriptions so users understand what date is expected.
- Use min, max, and dateConstraints to restrict selectable dates to valid ranges.
- Use hasClear when the date is optional so the user can reset it.
- Show a loading state with changeAction when the date triggers a server-side save.
- Use DateInput inside InputGroup when adding a short static prefix or suffix, such as a due-date hint.
- Avoid: Use a DateInput for free-form text that does not represent a calendar date.
- Avoid: Hide the label without surrounding context that makes the field purpose obvious.
- Avoid: Rely on the calendar alone; the text input lets users type dates directly, which is faster for known dates.
- Avoid: Wrap a disabled DateInput in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.
Theming API
{
"targets": [
{
"className": "astryx-date-input",
"visualProps": [
"size",
"status"
],
"states": [
"disabled"
]
},
{
"className": "astryx-date-input-toggle-icon",
"states": [
"state"
]
}
]
}
Anatomy
- Label: Text above the input describing what date is expected.
- Text input: A field where the user can type a date directly. Parses common formats like MM/DD/YYYY.
- Calendar icon: A button that opens the calendar popover for visual date picking.
- Calendar popover: A month grid that appears when the icon is clicked or the input is focused.
- Clear button: A × button that resets the date value. Shown when hasClear is true and a date is set.
- Status message: An error, warning, or success message below the input.
Examples
- Date Input: A date input field with a calendar popover. Type a date or click the calendar icon to pick one.
- DateInput — Clearable: Date input with a clear button that resets the value. Use when the date field is optional and the user may need to undo their selection.
- DateInput — Min/Max Constraints: Date input constrained to a min/max window. Use when only certain dates are valid, like booking availability or a fiscal quarter.
- DateInput — Formats: The format prop reuses Timestamp's format vocabulary to control how the committed value is displayed: date, date_long (default), date_weekday, and system_date, or a function for a fully custom string. Formatting applies only to the committed value, never to text the user is actively typing.
- DateInput — Description: Date input with helper text below the label explaining what the field expects. Use when the purpose of the date is not obvious from the label alone.
- DateInput — Validation: Date input in all three status states: error, warning, and success. Use to surface validation issues, caution the user, or confirm a valid selection.