JGuang

日期范围

DateRangeInput · Astryx

交互预览
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

日期范围 · DateRangeInput

选择起止日期并展示范围状态。

安装与前置条件

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

需要 React 19+,按顺序导入基础 CSS 和主题,并设置 Theme Provider。参见开始使用。

示例与使用方式

  • 日期范围 · 综合展示 1:首先体验这个示例,再查看代码理解组件的组合方式。
  • 日期范围 · 交互示例 2:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 日期范围 · 输入校验 3:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。

API 与上游详细参考

优先使用 0.7.1 官方中文说明;上游尚未提供中文的条目保留英文。属性名、类型及默认值保持原生 API,不把示例状态名称当成组件属性。

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.

属性类型默认值说明
label *stringLabel text.
isLabelHiddenbooleanfalseVisually hide the label.
descriptionstringHelper text displayed below the label.
isOptionalbooleanfalseShow an "(optional)" indicator.
isRequiredbooleanfalseMark the field as required.
isDisabledbooleanfalseDisable the trigger and picker.
disabledMessagestringExplains 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 | nullSelected 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) => voidCallback 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.
isLoadingbooleanfalseWhether the input is in a loading state. Disables interaction and shows a spinner.
minISODateStringMinimum 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/Calendaror useas ISODateString` if computing the value dynamically.
maxISODateStringMaximum selectable date. Same template literal type as min: use a YYYY-MM-DD string literal or cast with as ISODateString.
dateConstraintsArray<(date: Date) => boolean>Custom constraint functions to disable specific dates.
maxRangeSpannumberMaximum 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).
minRangeSpannumberMinimum 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).
presetsArray<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.
hasClearbooleantrueShows a clear button when a range is selected.
placeholderstring'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.
labelTooltipstringTooltip text via info icon at label end.
numberOfMonths1 | 22Number of months in the calendar.
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'0First day of week in the calendar. A number (0 = Sunday to 6 = Saturday) or a three-letter day name.
widthSizeValueWidth of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.
containerXstyleStyleXStylesStyleX 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.
controlXstyleStyleXStylesStyleX 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.

使用建议

  • 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.
  • 避免:Use DateRangeInput when only a single date is needed; use DateInput instead.
  • 避免:Hide the label without surrounding context that makes the purpose obvious.
  • 避免: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.

主题 API

{
  "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"
      ]
    }
  ]
}

组件结构

  • 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.