import type { Granularity, HourCycle } from '../utils/date-segments.js'; import type { DateInput } from '../utils/date-value.js'; import type { FormValidityHandle } from '../utils/formControl.js'; import type { PrimitivePropsWithRef } from '../utils/primitive.js'; import type { SegmentedLabelProps } from '../utils/segmentedField.js'; /** Props for the {@link DateField} segmented date entry root. */ export interface DateFieldProps extends Omit, 'defaultValue' | 'onChange' | 'dir'>, SegmentedLabelProps { /** * Current date for controlled usage — `null` while any segment is untyped; takes a `Date` or ISO-8601 string, read as local time. * @default undefined — uncontrolled, tracks its own value internally. */ value?: DateInput | null | undefined; /** * Initial date, used only when the field is uncontrolled; takes the same `Date`-or-ISO-string forms `value` does. * @default undefined — every segment starts on its placeholder. */ defaultValue?: DateInput | null | undefined; /** * Fires with the new `Date` once every segment is filled, and with `null` as soon as one is cleared — never with a half-typed date. * @default undefined — no-op if omitted. */ onValueChange?: ((value: Date | null) => void) | undefined; /** * How far down the field is editable — `'day'` is date-only, anything past it appends hour/minute (and, at `'second'`, seconds), the `datetime-local` equivalent. * @default 'day' */ granularity?: Granularity | undefined; /** * Forces 12-hour (with an AM/PM segment) or 24-hour time segments for display only — the submitted value is always 24 hour. * @default undefined — whatever the locale resolves to. */ hourCycle?: HourCycle | undefined; /** * BCP-47 locale deciding segment order, the literals between segments and the * AM/PM names — `en-US` orders month/day/year, `de-DE` orders day.month.year. * @default undefined — the runtime's default locale. */ locale?: string | undefined; /** * Earliest accepted date — a value before it marks the field `aria-invalid`/`data-invalid` and fails constraint validation with `rangeUnderflow`; takes a `Date` or ISO-8601 string. * @default undefined — no minimum; any year from 1 to 9999. */ minDate?: DateInput | undefined; /** * Latest accepted date — a value after it fails constraint validation with `rangeOverflow`; takes a `Date` or ISO-8601 string. * @default undefined — no maximum; any year from 1 to 9999. */ maxDate?: DateInput | undefined; /** * Disables the field and drops every segment out of the tab order. * @default false */ disabled?: boolean | undefined; /** * Segments stay focusable and readable but refuse every edit. * @default false */ readOnly?: boolean | undefined; /** * Predicate marking dates as unavailable, receiving the typed `Date` — an unavailable date marks the field `aria-invalid`/`data-invalid` without changing what it submits. * @default undefined — every date is available. */ isDateUnavailable?: ((date: Date) => boolean) | undefined; /** * Whether a one-digit month, day or hour renders zero-padded (`05/09/2026` vs `5/9/2026`); turned off, year still keeps four digits and minute/second keep two. * @default true */ shouldForceLeadingZeros?: boolean | undefined; /** * Marks the field invalid, exposed as `aria-invalid`/`data-invalid`. * @default false */ invalid?: boolean | undefined; /** * Marks the field required — an incomplete field is `valueMissing`. * @default false */ required?: boolean | undefined; /** * Form field name — with it the date submits as `YYYY-MM-DD` (or `YYYY-MM-DDTHH:mm[:ss]` past `day` granularity), without it the field submits nothing. * @default undefined */ name?: string | undefined; /** * Id of the `
` this field submits into when rendered outside it — e.g. inside a Dialog's portal — forwarded to the hidden input and used to route form reset. * @default undefined — the field belongs to its nearest ancestor ``, if any. */ form?: string | undefined; /** * Writing direction, which decides whether ArrowLeft moves to the previous or * the next segment. * @default undefined — read off the nearest `[dir]` ancestor or `document.dir`. */ dir?: 'ltr' | 'rtl' | undefined; } /** * What {@link DateField}'s forwarded ref carries — the root `
` plus the two constraint-validation methods, answering off the hidden input's `YYYY-MM-DD` wire value; type your ref as `React.useRef(null)` to call them. */ export type DateFieldHandle = HTMLDivElement & FormValidityHandle;