Form field that opens a dual-panel TimeRangePicker in an overlay (auto by default: menu on desktop, bottom drawer on mobile).
Introduction
TimeRangeField is a form control that opens a TimeRangePicker—a pair of side-by-side TimePanel columns—in an overlay (auto by default: menu on desktop, bottom drawer on mobile): a label, a trigger input that is read-only by default, and helper or error text, all wrapped in FormField chrome.
The value is a TimeRangeValue tuple ([start, end]) of wall-clock times. Reach for TimeField when only a single time is needed, or DateTimeRangeField when both dates and times are required.
Import
import { TimeRangeField } from "@bridge-ui/vue/Components/TimeRangeField";import { TimeRangeField } from "@bridge-ui/react/Components/TimeRangeField";Basic usage
Provide a label and placeholder. Bind the value 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. The trigger input is read-only by default; clicking or focusing it opens the picker menu.
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 trigger.
- readonly — keeps the value visible and focusable but not editable; the menu does not open.
The input is read-only by default (picker only). Set editable to unlock typing. The field does not parse or commit typed text — handle that in your own component if needed.
Use description for helper text below the field. When error and errorMessage are both set, the description is hidden unless showDescriptionOnError.
Ampm
Set ampm to use a 12-hour clock with a dedicated AM/PM column on each panel of the picker.
Interval
Use interval to control the minute step between selectable options (default 1), applied to both start and end panels.
Show seconds
Set showSeconds to add a seconds column to both 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.
Show footer
Set showFooter to render Cancel / Apply actions on the nested picker. 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.
Standalone TimeRangePicker
TimeRangePicker is the inline dual-panel picker TimeRangeField opens in an overlay (auto by default: menu on desktop, bottom drawer on mobile). Use it directly for toolbars, inline forms, or any layout where a floating menu is not desired. Start and end always sit in a row with a vertical divider; titles sit above the panels (customize with startTitle and endTitle). Pass error to apply the error color palette to tiles. Pass fill to stretch to the container width. 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). When unset, fill defaults to true for drawer overlays (false for menu / modal). Drawer overlays scroll horizontally when dual time columns overflow, with bridge-scroll-fade-x on the inner scroller. See Scroll utilities. 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.
Related components
TimeField, DateTimeRangeField, TextField
Accessibility
For the field to be accessible, the trigger must be linked to its label and helper or error text:
- 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".
- The trigger is read-only by default; the picker menu opens on click or focus and closes on Escape.
Provide a stable controlId when rendering client-only so labels associate correctly on first paint.
Anatomy
TimeRangeField composes FormField around a trigger input that is read-only by default, opening a TimeRangePicker inside an overlay (auto by default: menu on desktop, bottom drawer on mobile):
FormField (root)
├── Header — label, optional corner text, required indicator
├── Container — variant shell (outline, filled, …)
│ ├── Input — trigger showing the formatted range (read-only unless editable)
│ └── End adornment — clock icon (default) or custom endIcon
├── Menu — opens on trigger click, focus, or Escape to close
│ └── TimeRangePicker
│ ├── Titles — startTitle and endTitle above the panels
│ ├── TimePanel — start time (hour / minute / AM·PM columns)
│ ├── Divider — vertical
│ └── TimePanel — end time (hour / minute / AM·PM columns)
└── Footer — description (helper text) or error messageAPI
| Prop | Type | Default | Description |
|---|---|---|---|
| default-value | TimeRangeValue | null | — | Initial value for uncontrolled usage (without v-model). |
| v-model | TimeRangeValue | null | — | Two-way binding for the selected range. |
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultValue | TimeRangeValue | null | — | Initial value for uncontrolled usage. |
| onChange | (value: TimeRangeValue | null) => void | — | Called when the range changes. |
| value | TimeRangeValue | null | — | Selected range. Use with onChange for controlled state. |
TimeRangeField-specific
| Prop | Type | Default | Description |
|---|---|---|---|
| ampm | boolean | false | Uses a 12-hour clock with an AM/PM column. |
| clearable | boolean | false | Whether the value can be cleared. |
| disableTimes | Date[] | — | Times that cannot be selected. |
| editable | boolean | false | Unlocks the input. Does not parse or commit typed text. |
| fill | boolean | — | Fills the overlay width. Unset: true for drawer, false for menu / modal. |
| interval | number | 1 | Minute step between options. |
| maxTime | Date | — | Latest selectable time. |
| minTime | Date | — | Earliest selectable time. |
| overlay | FieldOverlayMode | "auto" | Overlay shell: menu, modal, drawer, or auto. |
| placeholder | string | — | Native attribute forwarded to the trigger input. |
| showFooter | boolean | false (true for modal/drawer when unset) | Shows Cancel / Apply on the nested picker. |
| showSeconds | boolean | false | Shows seconds in the panel and formatted value. |
| timeZone | string | global.timeZone | IANA time zone for the UI wall clock. The value Date is a UTC instant. |
Events
| Event | Payload | Description |
|---|---|---|
| @apply | — | Emitted when Apply is pressed (showFooter). |
| @cancel | — | Emitted when Cancel is pressed (showFooter). |
| @change | TimeRangeValue | null | Emitted when the range changes. |
| @close | — | Emitted when the menu closes. |
| @open | — | Emitted when the menu opens. |
| Prop | Payload | Description |
|---|---|---|
| onApply | — | Called when Apply is pressed (showFooter). |
| onCancel | — | Called when Cancel is pressed (showFooter). |
| onChange | (value: TimeRangeValue | null) | Called when the range changes. |
| onClose | — | Called when the menu closes. |
| onOpen | — | Called when the menu opens. |
Inherited from FormField
| Prop | Type | Default | Description |
|---|---|---|---|
| classes | TimeRangeFieldClasses | — | Class overrides for field / input regions. |
| color | FormFieldColor | "primary" | Color applied to the field control and the nested picker. |
| controlId | string | — | Associates labels and helper text with the control. Auto-generated when omitted. |
| corner | string | — | Secondary label text at the inline end of the header row. |
| customProps | TimeRangeFieldCustomProps | — | Props for each part, plus menu, modal, drawer (forwarded to the overlay shell) and timeRangePicker (forwarded to the nested TimeRangePicker). |
| description | string | — | Helper text below the control. Hidden when error and an error message are set, unless showDescriptionOnError. |
| disabled | boolean | false | Whether the control is disabled. |
| endIcon | IconSource | "clock" | Icon at the inline end. |
| error | boolean | false | Applies invalid styling. Hides description when an error message is shown, unless showDescriptionOnError. |
| errorIcon | IconSource | "alert" | Icon shown when invalid and showErrorIcon is enabled. |
| errorMessage | string | — | Error message below the control. |
| hideErrorMessage | boolean | false | Does not reserve the error row. That row is also omitted while a description is shown. |
| label | string | — | Primary label text above the control. |
| readonly | boolean | false | Whether the control is read-only. |
| required | boolean | false | Shows a red asterisk on the label. |
| rounded | FormFieldRounded | "md" | Border radius of the field control and the nested picker. |
| showDescriptionOnError | boolean | false | Keeps the description visible while the field is invalid. |
| showErrorIcon | boolean | true | Shows an error icon when invalid. |
| size | FormFieldSize | "md" | Typography and control sizing. |
| slots | TimeRangeFieldSlots | — | React slots. Vue: #label, #corner, default, #description, #errorMessage, #start, #end, #footer. |
| startIcon | IconSource | — | Icon at the inline start. |
| variant | FormFieldVariant | "outline" | Visual variant of the field shell. |