Form field that opens a dual-month DateRangePicker calendar in an overlay (auto by default: menu on desktop, bottom drawer on mobile).
Introduction
DateRangeField is a complete form control: a label, an input that displays the selected range, and a dual-month calendar that opens in an overlay (auto by default: menu on desktop, bottom drawer on mobile). It wraps FormField chrome around a native <input> and an inline DateRangePicker, so you get consistent layout, validation styling, and range selection without assembling those pieces yourself.
For a single date instead of a range, use DateField, which can also select a range via its range prop when you prefer a single-calendar UI.
Import
import { DateRangeField } from "@bridge-ui/vue/Components/DateRangeField";import { DateRangeField } from "@bridge-ui/react/Components/DateRangeField";Basic usage
Provide a label and placeholder. Bind the value with value/onChange in React or v-model in Vue—the value is a two-item tuple [start, end] | null. For uncontrolled usage with an initial value, use defaultValue in React or default-value in Vue. Clicking the field opens a menu with two calendars; selecting a start and end day commits the value and closes the 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 input.
- readonly — keeps the value visible and focusable but not editable; the calendar 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.
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
Constrain the selectable range with minDate and maxDate. Days outside the bounds are disabled on both calendar panels.
Show footer
Set showFooter to add Cancel / Apply actions to 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.
Orientation
Set orientation to vertical to stack the two calendar panels instead of showing them side by side—useful in narrow layouts. Default is horizontal. In both layouts, year sits on the left and nav on the right; month selectors sit inward from the header midpoint when horizontal, and the start month stays in the header (end month over the bottom panel) when vertical.
Granularity
Month and year pick the same Date model and commit the first day of that unit. The field formats without a day. defaultView follows granularity and is clamped so it cannot go deeper. hideMonths is ignored when granularity is month; hideYears is ignored when granularity is year. DateRangePicker and CalendarRange take the same prop.
<DateRangeField label="Period" granularity="month" />
<DateRangePicker granularity="year" />DateRangePicker
DateRangePicker is the inline dual-month calendar that DateRangeField opens in an overlay (auto by default: menu on desktop, bottom drawer on mobile). Use it directly when you need an always-visible range calendar without the FormField shell or menu behavior—for example, in a sidebar or a custom popover. Internally, it renders CalendarRange: year on the left, nav on the right, and month selectors inward from the header midpoint. granularity locks both panels to day, month, or year.
It supports the same value/onChange (React) or v-model (Vue), granularity, minDate/maxDate, orientation, and showFooter props as DateRangeField, plus standalone-only props like color, disabled, error (error color palette on tiles), and fill (fills the container width; default false). The same footer slot replaces Cancel / Apply: apply() commits (and closes an overlay), cancel() discards.
import { DateRangePicker } from "@bridge-ui/vue/Components/DateRangePicker";import { DateRangePicker } from "@bridge-ui/react/Components/DateRangePicker";CalendarRange
CalendarRange is the underlying dual-month calendar used by DateRangePicker (and, in turn, DateRangeField). Use it directly when you need finer control—such as a controlled viewDate, granularity, hover-preview handling via previewDate/onPreviewDateChange, or custom aside content per panel—without the picker’s Cancel / Apply chrome. Pass error to apply the error color palette to tiles. Pass fill to stretch to the container width. Year sits on the left and nav on the right; month selectors sit inward from the header midpoint. Month and year views follow the start calendar. defaultView matches granularity and is clamped so it cannot go deeper.
import { CalendarRange } from "@bridge-ui/react/Components/CalendarRange";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 calendars 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
DateRangePicker, DateField, Select
Accessibility
For the field to be accessible, the input must be linked to its label and helper or error text:
- The label is associated with the input via htmlFor / id, using controlId (auto-generated when omitted).
- description and errorMessage are linked through aria-describedby on the input.
- When error is true, the input receives aria-invalid="true".
- Calendar navigation follows standard keyboard interaction for grid widgets (arrow keys to move between days, Enter/Space to select) across both panels.
Provide a stable controlId when rendering client-only so labels associate correctly on first paint.
Anatomy
DateRangeField composes FormField around a native <input> and opens a DateRangePicker in 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 — formatted range (read-only unless editable)
└── Footer — description (helper text) or error message
Menu (opened on click)
└── DateRangePicker — year and nav at the edges, month selectors inward from the midpoint, two calendar panels
(horizontal or vertical), optionally with Cancel / Apply footerAPI
| Prop | Type | Default | Description |
|---|---|---|---|
| default-value | DateRangeValue | null | — | Initial value for uncontrolled usage (without v-model). |
| v-model | DateRangeValue | null | — | Two-way binding for the selected range. |
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultValue | DateRangeValue | null | — | Initial value for uncontrolled usage. |
| onChange | (value: DateRangeValue | null) => void | — | Called when the range changes. |
| value | DateRangeValue | null | — | Selected range. Use with onChange for controlled state. |
DateRangeField-specific
| Prop | Type | Default | Description |
|---|---|---|---|
| classes | DateRangeFieldClasses | — | Classes for field / input regions. |
| clearable | boolean | false | Whether the value can be cleared. |
| customProps | DateRangeFieldCustomProps | — | Extra props for internal parts (input, menu, modal, drawer, dateRangePicker, …). |
| defaultView | CalendarView | matches granularity | Initial calendar panel. Clamped so it is not deeper than granularity. |
| disableDates | Date[] | — | Dates that cannot be selected. |
| disableMonths | number[] | — | Month indexes that cannot be selected. |
| disableYears | number[] | — | Years 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. |
| granularity | "day" | "month" | "year" | "day" | Deepest selectable panel. Month and year commit as a Date. |
| hideMonths | boolean | false | Hides the month selectors and month panel. Ignored when granularity is "month". |
| hideOutsideDays | boolean | false | Hides days that fall outside the displayed month on both panels. |
| hideWeekdays | boolean | false | Hides weekday labels on both date panels. |
| hideYears | boolean | false | Hides the year selector and year panel. Ignored when granularity is "year". |
| maxDate | Date | — | Latest selectable date. |
| minDate | Date | — | Earliest selectable date. |
| orientation | "horizontal" | "vertical" | "horizontal" | Dual calendar layout forwarded to the picker. |
| overlay | FieldOverlayMode | "auto" | Overlay shell: menu, modal, drawer, or auto. |
| showFooter | boolean | false (true for modal/drawer when unset) | Shows Cancel / Apply on the nested picker. |
| slots | DateRangeFieldSlots | — | Named slots (FormField slots + calendar day + footer). |
| startOfWeek | StartOfWeek | 0 | First day of the week. |
| 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 | value: DateRangeValue | null | Emitted when the range changes (alternative to v-model). |
| @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: DateRangeValue | 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 | FormFieldClasses | — | Class overrides per part. |
| color | FormFieldColor | "primary" | Color applied to the field control. |
| 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 | FormFieldCustomProps | — | Props for each part. label accepts Label props (without children); error label colors come from Label. |
| 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. |
| end | string | — | Inline-end text inside the field (suffix). |
| endIcon | IconSource | — | 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 calendar menu panel. |
| 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 | FormFieldSlots | — | React slots. Vue: #label, #corner, default, #description, #errorMessage, #start, #end. |
| start | string | — | Inline-start text inside the field (prefix). |
| startIcon | IconSource | — | Icon at the inline start. |
| variant | FormFieldVariant | "outline" | Visual variant of the field shell. |