---
title: DatePicker 日期选择器
description: 基于 React Aria DatePicker，通过 DateField 与 Calendar 组合的可组合日期选择器
links:
  rac: DatePicker
  source: date-picker/date-picker.tsx
  styles: date-picker.css
  storybook: Components/Date and Time/DatePicker
  figma: true
---

## 用法

```tsx
import { DatePicker, DateField, Calendar, Label } from '@heroui/react';
```

<ComponentPreview name="date-picker-basic" />

## 组件结构

`DatePicker` 采用组合优先 API。显式组合 `DateField` 与 `Calendar` 以控制结构与样式。

```tsx
import {Calendar, DateField, DatePicker, Label} from '@heroui/react';

export default () => (
  <DatePicker>
    <Label />
    <DateField.Group>
      <DateField.Input>
        {(segment) => <DateField.Segment segment={segment} />}
      </DateField.Input>
      <DateField.Suffix>
        <DatePicker.Trigger>
          <DatePicker.TriggerIndicator />
        </DatePicker.Trigger>
      </DateField.Suffix>
    </DateField.Group>
    <DatePicker.Popover>
      <Calendar aria-label="Choose date">
        <Calendar.Header>
          <Calendar.YearPickerTrigger>
            <Calendar.YearPickerTriggerHeading />
            <Calendar.YearPickerTriggerIndicator />
          </Calendar.YearPickerTrigger>
          <Calendar.NavButton slot="previous" />
          <Calendar.NavButton slot="next" />
        </Calendar.Header>
        <Calendar.Grid>
          <Calendar.GridHeader>
            {(day) => <Calendar.HeaderCell>{day}</Calendar.HeaderCell>}
          </Calendar.GridHeader>
          <Calendar.GridBody>{(date) => <Calendar.Cell date={date} />}</Calendar.GridBody>
        </Calendar.Grid>
      </Calendar>
    </DatePicker.Popover>
  </DatePicker>
)
```

## 示例

### 禁用

<ComponentPreview name="date-picker-disabled" />

### 受控组件

<ComponentPreview name="date-picker-controlled" />

### 表单校验

<ComponentPreview name="date-picker-with-validation" />

### 格式选项

使用 `granularity`、`hourCycle`、`hideTimeZone`、`shouldForceLeadingZeros` 等 props 控制 DatePicker 值的显示方式。

<ComponentPreview name="date-picker-format-options" />

### 表单示例

<ComponentPreview name="date-picker-form-example" />

### 自定义指示器

未提供 children 时，`DatePicker.TriggerIndicator` 渲染默认 `IconCalendar`。传入 children 可替换。

<ComponentPreview name="date-picker-with-custom-indicator" />

### 渲染函数

<ComponentPreview
  name="date-picker-render-function"
/>

### 国际化日历

默认情况下，DatePicker 使用用户 locale 的日历系统显示日期。可用 `I18nProvider` 包裹并设置 [Unicode 日历 locale 扩展](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar#adding_a_calendar_in_the_locale_string) 覆盖。

以下示例展示印度日历系统：

<ComponentPreview name="date-picker-international-calendar" />

**Note：** 无论显示的 locale 如何，`onChange` 事件始终返回与 `value` 或 `defaultValue` 相同日历系统的日期（未提供 value 时为 Gregorian）。这确保应用逻辑在单一日历系统下一致运行，同时仍可按用户偏好格式显示日期。

完整支持的日历系统及其标识符列表请参阅：
- [React Aria Calendar Implementations](https://react-aria.adobe.com/internationalized/date/Calendar#implementations)
- [React Aria International Calendars](https://react-aria.adobe.com/Calendar#international-calendars)

## 自定义样式

### Tailwind CSS

<ComponentPreview name="date-picker-custom-styles" />

### 全局 CSS

使用 `@layer components` 自定义 DatePicker 基础类。

```css
@layer components {
  .date-picker {
    @apply inline-flex flex-col gap-1;
  }

  .date-picker__trigger {
    @apply inline-flex items-center justify-between;
  }

  .date-picker__trigger-indicator {
    @apply text-muted;
  }

  .date-picker__popover {
    @apply min-w-[var(--trigger-width)] p-0;
  }
}
```

## 样式参考

HeroUI 遵循 [BEM](https://getbem.com/) 命名以便复用自定义。

### CSS 类

DatePicker 在 `packages/styles/components/date-picker.css` 中使用以下类：

- `.date-picker` - 根包裹层
- `.date-picker__trigger` - 打开 popover 的触发器部分
- `.date-picker__trigger-indicator` - 默认/自定义指示器 slot
- `.date-picker__popover` - Popover 内容包裹层

### 交互状态

DatePicker 支持 React Aria data 属性与伪状态：

- **Open**：触发器上 `[data-open="true"]`
- **Disabled**：触发器上 `[data-disabled="true"]` 或 `[aria-disabled="true"]`
- **Focus visible**：触发器上 `:focus-visible` 或 `[data-focus-visible="true"]`
- **Hover**：触发器上 `:hover` 或 `[data-hovered="true"]`

## API 参考

### DatePicker

DatePicker 继承 React Aria [DatePicker](https://react-aria.adobe.com/DatePicker.md) 的所有 props。

| Prop | 类型 | 默认值 | 描述 |
|------|------|---------|-------------|
| `value` | `DateValue \| null` | - | 受控选中日期值 |
| `defaultValue` | `DateValue \| null` | - | 非受控模式下的默认选中值 |
| `onChange` | `(value: DateValue \| null) => void` | - | 选中日期变化时调用 |
| `isOpen` | `boolean` | - | 受控 popover 打开状态 |
| `defaultOpen` | `boolean` | `false` | 初始 popover 打开状态 |
| `onOpenChange` | `(isOpen: boolean) => void` | - | popover 打开状态变化时调用 |
| `isDisabled` | `boolean` | `false` | 禁用日期选择与触发器交互 |
| `isInvalid` | `boolean` | - | 标记字段为无效以显示校验状态 |
| `minValue` | `DateValue` | - | 最小可选日期 |
| `maxValue` | `DateValue` | - | 最大可选日期 |
| `name` | `string` | - | HTML 表单提交时使用的 name |
| `children` | `ReactNode \| (values: DatePickerRenderProps) => ReactNode` | - | 组合内容或 render 函数 |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, DatePickerRenderProps>` | - | 使用自定义 render 函数覆盖默认 DOM 元素 |

### Composition Parts

| Component | Description |
|-----------|-------------|
| `DatePicker.Root` | 根 date picker 容器与状态所有者 |
| `DatePicker.Trigger` | 触发按钮，通常渲染在 `DateField.Suffix` 内 |
| `DatePicker.TriggerIndicator` | 带默认日历图标的指示器 slot |
| `DatePicker.Popover` | `Calendar` 内容的 Popover 包裹层 |

### Related packages
- [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) — 所有日期组件使用的日期类型（`CalendarDate`、`CalendarDateTime`、`ZonedDateTime`）与工具
- [`I18nProvider`](https://react-aria.adobe.com/I18nProvider) — 为子树覆盖 locale
- [`useLocale`](https://react-aria.adobe.com/useLocale) — 读取当前 locale 与布局方向

## 相关组件

<RelatedComponents component="datepicker" />