import { default as React } from 'react'; import { DateRange, DayPickerProps, Locale, Matcher, OnSelectHandler } from 'react-day-picker'; import { Breakpoint, BreakpointSupport } from '../../../helpers'; import { ModalContentProps } from '../../overlays/modal/modal-content/modal-content'; import { MultiValueFieldProps } from '../multi-value-field/multi-value-field'; import { TextFieldForwardRef, TextFieldProps } from '../textfield/textfield'; export type DateFieldModal = boolean | Exclude; export type DateFieldMode = 'single' | 'multiple' | 'range'; export type CalendarView = 'days' | 'months' | 'years'; export type DateFieldCalendarTrigger = 'input' | 'button'; type DateTextFieldProps = Omit; type DateMultiValueFieldProps = Omit; /** * Subset of DateField props that can be overridden per breakpoint via the * `BreakpointSupport` API (e.g. ``). */ type DateFieldBreakpointProps = { /** * Whether the calendar popover is interactive. * @default true */ enableCalendar?: boolean; /** * What opens the calendar — only the icon (`'button'`) or anywhere in the input (`'input'`). * @default button */ calendarTrigger?: DateFieldCalendarTrigger; /** * Swap the custom calendar for the browser's native ``. * Only applies to `mode='single'`. * @default false */ useNativePicker?: boolean; /** * Number of months shown side-by-side. In the **popover** on mobile (`< md`) values > 1 are * clamped to 1 — a multi-month popover gets unscrollable on a phone viewport. In a **modal** the * count is kept: the months wrap to a vertical stack and the modal body scrolls. */ numberOfMonths?: number; }; export interface DateFieldProps extends BreakpointSupport, Omit { /** * Unique identifier for the date field. */ id: string; /** * Field label. Required for accessibility. */ label: string; /** * Determines the selection mode of the calendar. * - `'single'` (default) – only one date can be selected. The `selected` prop should be a `Date` object or `undefined`. * - `'multiple'` – multiple individual dates can be selected. The `selected` prop should be an array of `Date` objects. * - `'range'` – a continuous date range can be selected. The `selected` prop should be an object with `from` and optional `to` properties, both being `Date` objects. * * @default single */ mode?: DateFieldMode; /** * The currently selected date(s). The expected type depends on the `mode`: * - For `mode="single"`, this should be a `Date` object or `undefined`. * - For `mode="multiple"`, this should be an array of `Date` objects. * - For `mode="range"`, this should be an object with a `from` property (a `Date` object) and an optional `to` property (also a `Date` object). */ selected?: Date | Date[] | DateRange | undefined; /** * Callback fired when the user selects a date or date range. The exact parameters depend on the `mode`: * - For `mode="single"`, the callback receives the selected `Date` object (or `undefined` if cleared). * - For `mode="multiple"`, the callback receives an array of selected `Date` objects. * - For `mode="range"`, the callback receives an object with `from` and optional `to` properties, both being `Date` objects (or `undefined` if cleared). */ onSelect?: OnSelectHandler; /** * Disable specific dates. Accepts the same matchers as React DayPicker's `disabled` prop. * * @deprecated Use `disabledMatchers` instead — same shape, semantics, and merging * behaviour. The current overload re-uses the form-control `disabled` name for a * matcher prop, which is inconsistent with `DateTimeField`'s boolean `disabled` * and confusing for consumers migrating between the two siblings. `disabledMatchers` * stays additive for now; this overload will be replaced by `disabled?: boolean` * in a future major. */ disabled?: Matcher | Matcher[]; /** * Disable specific dates via react-day-picker matchers. Mirrors the * `disabledMatchers` prop on `DateTimeField` so the API is consistent across * the date-field family. Merges with the (deprecated) `disabled` overload — * if both are supplied, the union of both matcher sets is applied. */ disabledMatchers?: Matcher | Matcher[]; /** * Input placeholder text when no date is selected. */ placeholder?: string; /** * Additional class name(s) to apply to the component container. */ className?: string; /** * Custom date formatting function. Receives the selected date(s) and should return a string for display in the input field. * If not provided, a default formatter will be used that formats dates as "dd.MM.yyyy" in the "et-EE" locale. */ formatDate?: (date: Date | Date[] | DateRange | undefined) => string; /** * Show days from adjacent months in the calendar view. Default is `true`. * * @default true */ showOutsideDays?: boolean; /** * Custom date parsing function for user input. Receives the input string and should return a `Date`, an array of `Date`s, a `DateRange`, or `undefined` if the input is invalid or cleared. * If not provided, the component will not allow manual input and will rely solely on the calendar picker for date selection. */ parseDate?: (value: string) => Date | Date[] | DateRange | undefined; /** * Initial month to display when the calendar is opened. If not provided, defaults to the month of the currently selected date or the current month if no date is selected. */ initialMonth?: Date; /** * When `true`, the date field is marked as required, and the calendar will enforce that a date is selected before allowing the user to close it. Default is `false`. * * @default false */ required?: boolean; /** * How the month/year selector in the calendar header is rendered. * Forwarded to the internal `Calendar` / `CalendarHeader`. * - `'dropdown'` (default) — each picker is a `