Date and time range picker field with dual calendars, bounds, and AM/PM support.
Introduction
DateTimeRangeField is a complete form control for picking a start and end date-time as a single pair. It wraps FormField chrome around an overlay-based DateTimeRangePicker (auto by default: menu on desktop, bottom drawer on mobile; dual calendars, each with its own time panel), so you get consistent layout, validation styling, and a formatted range display without assembling those pieces yourself.
Use DateTimeRangeField when users pick a window with both a date and a time on each end—bookings, shifts, or event windows. For a single date-time, use DateTimeField. For a date-only range, use the dedicated DateRangeField component.
Import
import { DateTimeRangeField } from "@bridge-ui/vue/Components/DateTimeRangeField";import { DateTimeRangeField } from "@bridge-ui/react/Components/DateTimeRangeField";Basic usage
Provide a label and placeholder. Bind the value—a DateRangeValue tuple of [start, end] date-times—with value/onChange in React or v-model in Vue. For uncontrolled usage with an initial value, use defaultValue in React or default-value in Vue.
Form props
Standard form attributes are supported through inherited FormField props:
- required — shows a red asterisk on the label. Pair with the native required attribute when validating with HTML forms.
- disabled — prevents interaction and applies disabled styling to the field shell and input.
- readonly — keeps the value visible and focusable but not editable, and does not open the picker.
Use description for helper text below the field. When error is set, the description is hidden and errorMessage is shown instead.
AM/PM
Set ampm to display and edit both time panels with a 12-hour clock and an AM/PM column, instead of the default 24-hour format.
Interval
Control the minute step between selectable time options with interval (default 1). For example, interval={15} only offers times on the quarter hour, for both ends of the range.
Show seconds
Set showSeconds to add a seconds column to both time panels and include seconds in the formatted value.
Variants
Control the field shell appearance with the variant prop. Available variants: outline (default), filled, notched, stacked, and underlined.
Sizes
Control the field size with the size prop. Available sizes: 2xs, xs, sm, md (default), lg, xl, and 2xl.
Bounds
Restrict selectable dates with minDate / maxDate, and selectable times with minTime / maxTime. The bounds apply to both ends of the range.
Days limited to Aug 1–28, 2026, and times to 9 AM–6 PM.
Days limited to Aug 1–28, 2026, and times to 9 AM–6 PM.
Show footer
Set showFooter to render Cancel / Apply actions on the nested picker. The selection is a draft until Apply is pressed; Cancel discards it and closes. When unset, showFooter defaults to true for modal / drawer overlays (false for menu). A custom footer slot replaces Cancel / Apply: call apply() to commit and close, or cancel() to discard and close.
Selection is a draft until Apply is pressed.
Selection is a draft until Apply is pressed.
Orientation
Use orientation to control the dual calendar layout inside the picker: "horizontal" (default) places the two Calendar + Time pairs side by side; "vertical" stacks them.
Standalone DateTimeRangePicker
Use DateTimeRangePicker directly—combining CalendarRange with a time panel beside each month—when you need the dual calendars and times inline, without FormField chrome or a menu trigger.
DateTimeRangePicker accepts the same ampm, interval, showSeconds, minDate/maxDate, minTime/maxTime, orientation, and showFooter props as DateTimeRangeField, plus standalone-only color and rounded props for the calendars and time tiles. The same footer slot replaces Cancel / Apply: apply() commits (and closes an overlay), cancel() discards.
Overlay
Use the overlay prop to choose the picker shell: auto (default), menu, modal, or drawer. auto uses menu on desktop and a bottom drawer on mobile. When unset, showFooter defaults to true for modal / drawer overlays (false for menu). Apply commits and closes; Cancel discards and closes.
Validation
Set error and errorMessage to show invalid styling and an error message below the field. Use required to show a red asterisk on the label.
Pick a valid date-time range.
Pick a valid date-time range.
Related components
Accessibility
For the field to be accessible, the trigger input must be linked to its label and helper or error text, and both calendars and time panels must be reachable by keyboard:
- The label is associated with the trigger via htmlFor / id, using controlId (auto-generated when omitted).
- description and errorMessage are linked through aria-describedby on the trigger.
- When error is true, the trigger receives aria-invalid="true".
- Each calendar panel follows WAI-ARIA grid conventions for date navigation; time panels are keyboard-navigable and expose AM/PM as a toggle when ampm is set.
Provide a stable controlId when rendering client-only so labels associate correctly on first paint.
Anatomy
DateTimeRangeField composes FormField around a trigger input and an overlay-based dual picker (auto by default: menu on desktop, bottom drawer on mobile):
FormField (root)
├── Header — label, optional corner text, required indicator
├── Container — variant shell (outline, filled, …)
│ └── Trigger — formatted start → end range input, opens the picker menu
├── Menu — DateTimeRangePicker (two Calendar + TimePanel pairs), optional Cancel / Apply footer
└── Footer — description (helper text) or error messageAPI
| Prop | Type | Default | Description |
|---|---|---|---|
| v-model | DateRangeValue | null | — | Two-way binding for the date-time range value. |
| default-value | DateRangeValue | null | — | Initial value for uncontrolled usage (without v-model). |
| Prop | Type | Default | Description |
|---|---|---|---|
| value | DateRangeValue | null | — | Controlled range value. Use with onChange. |
| defaultValue | DateRangeValue | null | — | Initial value for uncontrolled usage. |
| onChange | (value: DateRangeValue | null) => void | — | Called when the value changes. |
DateTimeRangeField-specific
| Prop | Type | Default | Description |
|---|---|---|---|
| ampm | boolean | false | Uses a 12-hour clock with an AM/PM column. |
| clearable | boolean | true | Whether the value can be cleared. |
| showSeconds | boolean | false | Shows seconds in the panel and formatted value. |
| disableDates | Date[] | — | Dates that cannot be selected. |
| disableMonths | number[] | — | Month indexes that cannot be selected. |
| disableTimes | Date[] | — | Times that cannot be selected. |
| disableYears | number[] | — | Years that cannot be selected. |
| hideMonths | boolean | false | Hides month navigation / panel. |
| hideOutsideDays | boolean | false | Hides days that fall outside the displayed month. |
| hideWeekdays | boolean | false | Hides weekday labels. |
| hideYears | boolean | false | Hides year navigation / panel. |
| interval | number | 1 | Minute step between time options. |
| maxDate | Date | — | Latest selectable date. |
| maxTime | Date | — | Latest selectable time. |
| minDate | Date | — | Earliest selectable date. |
| minTime | Date | — | Earliest selectable time. |
| overlay | FieldOverlayMode | "auto" | Overlay shell: menu, modal, drawer, or auto. |
| orientation | "horizontal" | "vertical" | "horizontal" | Dual calendar layout forwarded to the picker. |
| showFooter | boolean | false (true for modal/drawer when unset) | Shows Cancel / Apply on the nested picker. |
| startOfWeek | StartOfWeek | 0 | First day of the week. |
| timeZone | string | — | IANA time zone. |
Inherited from FormField
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Primary label text above the control. |
| description | string | — | Helper text below the control (hidden when invalid). |
| corner | string | — | Secondary label text at the inline end of the header row. |
| required | boolean | false | Shows a red asterisk on the label. |
| disabled | boolean | false | Whether the control is disabled. |
| readonly | boolean | false | Whether the control is read-only (does not open the picker). |
| error | boolean | false | Applies invalid styling and hides description. |
| errorMessage | string | — | Error message below the control. |
| showErrorIcon | boolean | true | Shows an error icon when invalid. |
| hideErrorMessage | boolean | false | Does not reserve space for error messages. |
| variant | FormFieldVariant | "outline" | Visual variant of the field shell. |
| color | FormFieldColor | "primary" | Color applied to the field control. |
| size | FormFieldSize | "md" | Typography and control sizing. |
| rounded | FormFieldRounded | "md" | Border radius of the field control. |
| start | string | — | Inline-start text inside the field (prefix). |
| end | string | — | Inline-end text inside the field (suffix). |
| startIcon | IconSource | — | Icon at the inline start. |
| endIcon | IconSource | — | Icon at the inline end. |
| errorIcon | IconSource | "alert" | Icon shown when invalid and showErrorIcon is enabled. |
| controlId | string | — | Associates labels and helper text with the control. Auto-generated when omitted. |
| classes | DateTimeRangeFieldClasses | — | Classes for field / input regions. |
| customProps | DateTimeRangeFieldCustomProps | — | Props for each part, including the nested dateTimeRangePicker. label accepts Label props (without children). |
| slots | DateTimeRangeFieldSlots | — | Named slots (FormField slots plus calendar day + footer). |
Events
| Event | Payload | Description |
|---|---|---|
| v-on:apply | — | Emitted when Apply is pressed (showFooter). |
| v-on:cancel | — | Emitted when Cancel is pressed (showFooter). |
| v-on:change | DateRangeValue | null | Emitted when the range changes. |
| v-on:close | — | Emitted when the menu closes. |
| v-on:open | — | Emitted when the menu opens. |
| Prop | Payload | Description |
|---|---|---|
| onApply | — | Called when Apply is pressed (showFooter). |
| onCancel | — | Called when Cancel is pressed (showFooter). |
| onChange | DateRangeValue | null | Called when the range changes. |
| onClose | — | Called when the menu closes. |
| onOpen | — | Called when the menu opens. |