Date Range Picker
Two segmented date inputs for a start and an end, a trigger that opens a popover, and a single ordered NaviusDateRange value.
Range:
<NaviusDateRangePicker @bind-Value="_range">
<NaviusDateRangePickerControl class="inline-flex items-center gap-2 rounded-md border px-3 py-2">
<NaviusDateRangePickerInput Part="start" />
<NaviusDateRangePickerSeparator>to</NaviusDateRangePickerSeparator>
<NaviusDateRangePickerInput Part="end" />
<NaviusDateRangePickerTrigger aria-label="Open calendar"><CalendarIcon /></NaviusDateRangePickerTrigger>
</NaviusDateRangePickerControl>
<NaviusDateRangePickerContent class="z-50 rounded-md border bg-popover p-4 shadow-md">
@* a range-mode calendar from the styled layer *@
</NaviusDateRangePickerContent>
</NaviusDateRangePicker>
@code { private NaviusDateRange _range = NaviusDateRange.Empty; }Features
- The endpoints are embedded Date Inputs bound to the start / end side of the shared range, reusing the whole segment brain.
- The value is a
NaviusDateRange(a nullableStartandEnd), so a range can be partially entered; both endpoints submit ISO underStartName/EndName. - The trigger opens a Popover; the range calendar grid itself is delegated to the styled layer (a range-mode calendar), so the brain owns the value, inputs, popover and form submission, not a second calendar engine.
- Controlled via
@bind-Value/@bind-Open, uncontrolled viaDefaultValue/DefaultOpen.
Installation
Install the brain, or copy just this primitive in with the CLI.
navius add date-range-pickerAnatomy
Import the parts and assemble them. The root renders no DOM of its own; it cascades state through the wrapped popover.
@using Navius.Primitives.Components.DateRangePicker
@using Navius.Primitives.Common
<NaviusDateRangePicker>
<NaviusDateRangePickerControl>
<NaviusDateRangePickerInput Part="start" />
<NaviusDateRangePickerSeparator />
<NaviusDateRangePickerInput Part="end" />
<NaviusDateRangePickerTrigger />
</NaviusDateRangePickerControl>
<NaviusDateRangePickerContent>
@* range calendar *@
</NaviusDateRangePickerContent>
</NaviusDateRangePicker>API Reference
Root
NaviusDateRangePicker. Owns the NaviusDateRange value and open state and cascades them. Renders no DOM (wraps a Popover). Value and Open are two-way bindable.
| Prop | Type | Default |
|---|---|---|
| Value | NaviusDateRange | Empty |
| ValueChanged | EventCallback<NaviusDateRange> | - |
| DefaultValue | NaviusDateRange | Empty |
| Open | bool | false |
| OpenChanged | EventCallback<bool> | - |
| DefaultOpen | bool | false |
| MinValue | DateOnly? | - |
| MaxValue | DateOnly? | - |
| Granularity | string | "day" |
| Disabled | bool | false |
| ReadOnly | bool | false |
| Required | bool | false |
| Invalid | bool | false |
| StartName | string? | - |
| EndName | string? | - |
| ChildContent | RenderFragment? | - |
Control
NaviusDateRangePickerControl. The labelled group wrapping the endpoints, separator and trigger; hosts the two hidden bubble inputs. Renders a div with role=group.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-date-range-picker] | Present on the group |
| [data-disabled] | Present when disabled |
| [data-readonly] | Present when read-only |
| [data-invalid] | Present when invalid |
| [data-required] | Present when required |
Input
NaviusDateRangePickerInput. One endpoint: an embedded Date Input bound to the start or end side (Part). Renders the Date Input group.
| Prop | Type | Default |
|---|---|---|
| Part | string | "start" |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-date-range-picker-input] | Present on the endpoint input |
| [data-part] | "start" | "end" |
Separator
NaviusDateRangePickerSeparator. The visual 'to' between the endpoints, hidden from assistive tech. Renders an aria-hidden span.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Trigger
NaviusDateRangePickerTrigger. The calendar button that opens the popup. Delegates to the Popover trigger. Renders a button.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-date-range-picker-trigger] | Present on the trigger button |
| [data-popup-open] | Present while the popup is open (from the Popover trigger) |
Content
NaviusDateRangePickerContent. Portals and anchors the popup (Popover Portal > Positioner > Popup) and hosts the range calendar. The Popup is role=dialog. Renders the popover popup.
| Prop | Type | Default |
|---|---|---|
| Side | string | "bottom" |
| Align | string | "start" |
| SideOffset | double | 4 |
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-date-range-picker-popup] | Present on the popup (role=dialog) |
| [data-open] / [data-closed] | Open/closed lifecycle, from the Popover engine |
| [data-starting-style] / [data-ending-style] | Enter/exit animation hooks, from the Popover engine |
Accessibility
The control is a role="group" carrying aria-invalid; each endpoint keeps its spinbutton segments (see Date Input). The trigger carries aria-haspopup="dialog" + aria-expanded; the popup is role="dialog". The separator is aria-hidden.