# 日期范围选择

两个输入框加一个双月日历，选开始和结束两次点击；带「近 7 天 / 近 30 天 / 本月 / 上月」快捷项。窄屏变为单月。

**依赖**：`zhaoui.css` 与 `zhaoui.js`（原生 HTML、CSS、JS，不需要框架或 jQuery）。只用核心包时，还要加 `modular/date.min.js` 和 `modular/date.min.css`；全量版已包含。

## 用法

```html
<div data-zh-daterange data-name-start="from" data-name-end="to" data-start="2026-10-01" data-end="2026-10-07" data-max="2026-12-31" aria-label="统计周期"></div>

<script>
document.querySelector('[data-zh-daterange]').addEventListener('zh:daterange-change', function (e) {
  console.log(e.detail.start, '→', e.detail.end);
});
</script>
```

## 样式类

`zh-dp`、`zh-dp-panel`、`zh-dp-presets`

## 属性

| 属性 | 用在 | 取值 | 说明 |
|---|---|---|---|
| `data-zh-daterange` | <div> | 无 | 声明这是日期范围选择 |
| `data-start / data-end` | 容器 | YYYY-MM-DD | 初始的开始与结束日期 |
| `data-min / data-max` | 容器 | YYYY-MM-DD | 可选范围 |
| `data-presets` | 容器 | false 表示关闭 | 默认显示快捷项 |
| `data-name-start / data-name-end` | 容器 | 字段名 | 分别生成开始、结束两个隐藏 input |
| `data-size` | 容器 | sm \| md（默认）\| lg | 尺寸 |
| `aria-label / data-labelledby / data-label` | 容器 | 字符串 / 标签元素 id / 弹层标题 | 输入框的无障碍名称；data-label 是弹出面板的标题 |
| `data-msg` | 容器 | 一个元素的选择器，如 #status | 可选的状态提示元素：选择、报错时会把文字写进去（读屏可以朗读），元素上可预先写好默认文字 |
| `<label for="容器 id">` | 容器所在页面的 <label> | for 指向容器的 id | label 会成为输入框的无障碍名称，点击 label 会聚焦输入框；容器是空 <div>，label 的 for 指向它的 id 即可 |

## 方法

- `ZhaoUI.dateRangePicker(host, { start, end, min, max, presets, size, label, msg, onChange })`：命令式创建；onChange(start, end)
- `el.zhDateRange.get() / .set(start, end) / .open() / .close()`：get 返回 [Date|null, Date|null]；set 接受字符串或 Date

## 事件

| 事件 | 触发于 | detail | 说明 |
|---|---|---|---|
| `zh:daterange-change` | 容器 | { start, end, dates: [Date\|null, Date\|null] } | 范围确定、键入确认或清除后触发（冒泡）；start / end 是 YYYY-MM-DD 字符串或空串 |

## 无障碍

- 两个输入框在一个 role="group" 里，分别叫「开始日期」「结束日期」
- 第一次点击选开始，第二次选结束；先点了较晚的日期再点较早的，会自动对调
- 悬停时预览范围；已选中的天数会朗读（如「共 7 天」）
- 键入时结束日期早于开始日期会被拒绝并提示；键盘操作与单日期相同
- 窄屏（≤ 767px）时日历只显示一个月
- 需要的宽度：范围选择器至少 17.5rem（约 280px，样式里是 min-width），放进更窄的容器会溢出容器而不是截断日期。筛选栏里请给它留足位置，不要给它或它的父元素设更窄的宽度

## 常见问题

### 日期范围选择是什么？

两个输入框加一个双月日历，选开始和结束两次点击；带「近 7 天 / 近 30 天 / 本月 / 上月」快捷项。窄屏变为单月。

### 怎么使用日期范围选择？

先在页面里引入 zhaoui.css 和 zhaoui.js（放在 </body> 前，不加 defer），再照本页「用法」里的标记书写；需要用代码控制时，用「方法」里列出的接口。

### 日期范围选择有哪些事件？

zh:daterange-change（范围确定、键入确认或清除后触发（冒泡）；start / end 是 YYYY-MM-DD 字符串或空串）。

### 日期范围选择有哪些方法？

ZhaoUI.dateRangePicker(host, { start, end, min, max, presets, size, label, msg, onChange })：命令式创建；onChange(start, end)；el.zhDateRange.get() / .set(start, end) / .open() / .close()：get 返回 [Date|null, Date|null]；set 接受字符串或 Date。

### 日期范围选择支持键盘和读屏吗？

两个输入框在一个 role="group" 里，分别叫「开始日期」「结束日期」；第一次点击选开始，第二次选结束；先点了较晚的日期再点较早的，会自动对调；悬停时预览范围；已选中的天数会朗读（如「共 7 天」）。

### 日期范围选择需要依赖框架吗？

不需要。ZhaoUI 是原生 HTML、CSS 和 JavaScript，不依赖 jQuery、Vue 或 React。
