# DateRangeInput

- Page: https://jiguang132.com/resources/astryx/docs/date-range-input
- Resource: Astryx (https://jiguang132.com/resources/astryx.md)
- All guides: https://jiguang132.com/resources/astryx/docs.md

DateRangeInput lets users select a start and end date from a dual-month calendar popover. Use it for filtering data by time period, report generation, analytics dashboards, and booking flows.

## Installation

```bash
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
```

Requires React 19+, base CSS and a Theme provider. See [Setup](/resources/astryx/docs/getting-started).

## Date Range Input

DateRangeInput lets users select a start and end date from a dual-month calendar popover. Use it for filtering data by time period, report generation, analytics dashboards, and booking flows.

| Prop | Type | Default | Description |
|---|---|---|---|
| label * | string |  | Label text. |
| isLabelHidden | boolean | false | Visually hide the label. |
| description | string |  | Helper text displayed below the label. |
| isOptional | boolean | false | Show an "(optional)" indicator. |
| isRequired | boolean | false | Mark the field as required. |
| isDisabled | boolean | false | Disable the trigger and picker. |
| disabledMessage | string |  | Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled DateRangeInput in Tooltip. Disabled controls swallow the hover events an external Tooltip needs. |
| value * | DateRange \| null |  | Selected date range or null. Import the `DateRange` type from `@astryxdesign/core/DateRangeInput`; it is `{start: ISODateString, end: ISODateString}`. Do NOT redeclare your own DateRange type; use the exported one so TypeScript structurally matches. |
| onChange * | (value: DateRange \| null) => void |  | Callback when the range changes. Called with null on clear. |
| changeAction | (value: DateRange \| null) => void \| Promise<void> |  | Async action fired after onChange. Drives optimistic UI updates via useTransition. |
| isLoading | boolean | false | Whether the input is in a loading state. Disables interaction and shows a spinner. |
| min | ISODateString |  | Minimum selectable date. `ISODateString` is a template literal type (`\`${number}${number}${number}${number}-${number}${number}-${number}${number}\``). Pass a string literal like `"2026-01-28"`, not a runtime string variable. Import it from `@astryxdesign/core/Calendar` or use `as ISODateString` if computing the value dynamically. |
| max | ISODateString |  | Maximum selectable date. Same template literal type as `min`: use a YYYY-MM-DD string literal or cast with `as ISODateString`. |
| dateConstraints | Array<(date: Date) => boolean> |  | Custom constraint functions to disable specific dates. |
| maxRangeSpan | number |  | Maximum days a selected range may span, counting both endpoints (`7` = a 7-day window, start + 6). Once a start is picked, days beyond this distance are disabled so the range cannot stretch past the cap. Rolling window relative to the start; for fixed calendar bounds use `min`/`max`. Constrains selection only; it never rewrites a `value` already wider than the cap (flag that with `status`). |
| minRangeSpan | number |  | Minimum days a selected range must span, counting both endpoints (`2` forbids a single-day range). Once a start is picked, days closer than this are disabled. Clicking the start again commits a one-day range when allowed, or cancels the in-progress selection when the minimum is longer. Defaults to 1 (same-day start and end allowed). |
| presets | Array<DateRangePreset> |  | Preset ranges shown as quick-select options beside the calendar. A preset is disabled when either endpoint violates min, max, or dateConstraints, or when its span violates minRangeSpan or maxRangeSpan. |
| hasClear | boolean | true | Shows a clear button when a range is selected. |
| placeholder | string | 'Select date range' | Placeholder text when no range is selected. |
| size | 'sm' \| 'md' \| 'lg' | 'md' | Size of the trigger. |
| status | {type: 'warning' \| 'error' \| 'success', message?: string} |  | Status indicator for error, warning, or success states. |
| statusVariant | 'attached' \| 'detached' \| 'tooltip' | 'attached' | How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing; tooltip hides the message box and surfaces it in a tooltip on the status icon. |
| labelTooltip | string |  | Tooltip text via info icon at label end. |
| numberOfMonths | 1 \| 2 | 2 | Number of months in the calendar. |
| weekStartsOn | 0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 'sun' \| 'mon' \| 'tue' \| 'wed' \| 'thu' \| 'fri' \| 'sat' | 0 | First day of week in the calendar. A number (0 = Sunday to 6 = Saturday) or a three-letter day name. |
| width | SizeValue |  | Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned. |
| containerXstyle | StyleXStyles |  | StyleX styles for the Field box around the label, control, and status. containerClassName and containerStyle take a class name and inline styles for the same box. No effect (development warning) where no Field box renders: inside InputGroup (style the group) and in a horizontal-labels FormLayout. |
| controlXstyle | StyleXStyles |  | StyleX styles for the visual control box: the bordered element that holds the text, icons, and end controls, never the native input. controlClassName and controlStyle take a class name and inline styles for the same box. Replaces root xstyle, className, and style, which this component does not accept. |

### Usage guidance

- Base props such as ref, id, data-*, aria-*, and DOM event handlers go to the range trigger, the element that is focused and announced. A DOM handler runs after DateRangeInput's own handler for the same event and still receives events it handled (including ones it called preventDefault on), so it cannot cancel built-in behavior.
- Use presets for common ranges like "Last 7 days" to speed up selection.
- Use min/max to constrain selectable dates to valid ranges.
- Keep hasClear enabled (default) so users can reset the filter.
- Provide clear labels and descriptions so users understand what the range controls.
- Avoid: Use DateRangeInput when only a single date is needed; use DateInput instead.
- Avoid: Hide the label without surrounding context that makes the purpose obvious.
- Avoid: Wrap a disabled DateRangeInput in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.

### Theming API

```json
{
  "targets": [
    {
      "className": "astryx-date-range-input",
      "visualProps": [
        "size",
        "status"
      ],
      "states": [
        "disabled"
      ]
    },
    {
      "className": "astryx-date-range-input-toggle-icon",
      "states": [
        "state"
      ]
    },
    {
      "className": "astryx-date-range-input-presets"
    },
    {
      "className": "astryx-date-range-input-preset",
      "states": [
        "selected",
        "disabled"
      ]
    }
  ]
}
```

### Anatomy

- **Label**: Text above the trigger describing what date range is expected.
- **Field surface**: Bordered control containing the calendar toggle, range trigger, and end affordances.
- **Trigger button**: A button showing the formatted range or placeholder. Clicking opens the popover.
- **Calendar icon**: A trailing icon that also opens the popover.
- **Calendar popover**: A dual-month calendar grid with range selection and hover preview.
- **Preset sidebar**: A list of preset range options beside the calendar.
- **Preset button**: A quick-select action for one preset range, reflecting current and disabled states.
- **Clear button**: A × button that resets the range to null.
- **Status message**: An error, warning, or success message below the trigger.


## Examples

- Date Range Input: A date range picker with a button trigger and dual-month calendar popover with preset ranges.
- DateRangeInput — With Presets: Date range picker with quick-select presets for common periods. Use for analytics dashboards, report filters, or any context where users frequently select standard time windows.
- DateRangeInput — Validation: Date range input in all three status states: error, warning, and success. Use to surface booking conflicts, flag high-demand periods, or confirm an available range.

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
