SuperAPI AI 工具集

date-range

前端与建站

查看项目

更新于 10-16 05:38

技能介绍

用途

Date Range 组件用于让用户选择开始日期和结束日期,定义一个连续的时间段。它扩展了 Date Picker 模式,引入范围可视化(高亮两个选中日期之间的天数)以及范围专属校验(结束日期必须晚于开始日期、最小/最大范围长度)。

主要能力

  • 双输入对:两个独立日期字段,带联动校验。
  • 单日历面板或双面板 UI:用户选择时进行可视化范围高亮。
  • 范围校验:开始日期、最小/最大范围强制约束,并对两个选中日期进行无障碍播报。

使用方式

实现工作流:

  1. 在复制示例前,先确认该模式与问题及约束匹配。
  2. 从 references/pattern.md 中的结构与示例入手,然后选择最小可行的变体。
  3. 在叠加视觉打磨之前,先应用无障碍、性能和交互防护措施。
  4. 使用测试指南验证键盘、屏幕阅读器、响应式及失败场景下的行为。

键盘交互模式:

按键 操作
Tab 在开始输入框、结束输入框和日历触发器之间移动
Enter / Space 在输入框或触发器上打开选择器;确认悬停日期
Arrow Right 将焦点移到日历中的下一天
Arrow Left 将焦点移到前一天
Arrow Down 将焦点移到下周同一天
Arrow Up 将焦点移到上周同一天
Page Up 导航到上一个月

性能防护指标:

  • 选择器打开时间:双面板日历 < 150ms
  • 悬停预览:悬停期间每帧 < 16ms
  • 范围提交(选择结束日期):更新 UI < 50ms
  • 预设范围选择:应用日期 < 30ms
  • 内存占用:双面板日期范围选择器 < 30KB

适用场景

  • 酒店/旅行预订——入住和退房日期选择。
  • 活动时长——活动或营销活动的开始和结束日期。
  • 报告周期——分析仪表盘的日期筛选(“最近 7 天”、自定义范围)。
  • 租赁和预订系统——租车、设备租赁周期。
  • 请假与休假申请——带最小/最大天数的假期日期选择。

限制与应避免的场景

  • 单日期选择——使用 Date Picker。
  • 开放式筛选——“仅起始日期”或“仅结束日期”——使用两个独立的日期输入。
  • 超长日期范围——跨多年的范围更适合用月份/年份选择器。
  • 开始和结束可为同一天时——需在 UX 文案中明确说明。

常见错误

开始日期变化时重置结束日期

问题:当用户调整开始日期(例如从 3 月 12 日改为 3 月 15 日)时,自动清空结束日期会让只想把范围平移几天的用户感到沮丧。

修复方法:如果新的开始日期早于现有结束日期,保留结束日期。仅当新的开始日期晚于结束日期时才清空。

function onStartDateChange(newStart) {
  if (endDate && newStart < endDate) {
    // Keep end date — range is still valid
  } else {
    setEndDate(null); // Only clear if invalid
  }
  setStartDate(newStart);
}

没有进行中的视觉反馈

问题:用户点击开始日期后,日历看起来没有变化——没有提示系统正在等待选择结束日期。

修复方法:显示说明文字,并对潜在范围进行悬停预览。

calendar.addEventListener('mouseover', (e) => {
  if (selectingEndDate && e.target.matches('.calendar__day-btn')) {
    const hoverDate = getDateFromCell(e.target);
    if (hoverDate > startDate) {
      highlightRange(startDate, hoverDate, 'preview');
    }
  }
});

忽略最小/最大范围约束

问题:租赁和预订系统通常有最短入住要求。如果不在视觉上强制(通过禁用开始日期最小范围内的单元格),用户就能选择无效范围。

修复方法:选择开始日期后,禁用最小范围内的所有单元格。

function getDisabledDatesForEndSelection(startDate, minDays) {
  const disabled = [];
  for (let i = 1; i < minDays; i++) {
    const d = new Date(startDate);
    d.setDate(d.getDate() + i);
    disabled.push(d);
  }
  return disabled;
}

相关模式

  • https://uxpatterns.dev/patterns/forms/date-input
  • https://uxpatterns.dev/patterns/forms/date-picker
  • https://uxpatterns.dev/patterns/forms/selection-input

完整实现细节、示例和测试说明,请参见 references/pattern.md。

模式页面:https://uxpatterns.dev/patterns/forms/date-range