mcpField
S
syncfusion-react-daterangepicker

syncfusion-react-daterangepicker

github.com/syncfusion开发3168 次安装1 周前更新
代码仓库

关于 syncfusion-react-daterangepicker

面向开发者的 Syncfusion React DateRangePicker 实现指南,涵盖范围选择、校验、格式化、事件、样式及进阶用法。

主要功能

  1. 01日期范围选择与预设
  2. 02范围约束与校验
  3. 03日期及区域格式化
  4. 04事件与命令式方法
  5. 05主题、RTL 与移动模式
  6. 06API 与进阶用法指南

适用场景

  1. 01为报表面板添加日期范围
  2. 02校验预订表单中的日期范围
  3. 03定制本地化日期输入
  4. 04处理选择器事件与状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/syncfusion/react-ui-components-skills --skill syncfusion-react-daterangepicker

安装后在 Claude Code 中输入/syncfusion-react-daterangepicker确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
advanced-patterns.md
api-reference.md
customization-and-styling.md
date-range-formatting.md
date-range-selection.md
events-and-methods.md
getting-started.md

详细介绍

实现 Syncfusion React DateRangePicker 组件

Syncfusion React DateRangePicker 组件提供直观的日期范围选择方式,支持预设范围、日期验证、多种日期格式、键盘导航和针对移动设备优化的全屏模式。

文档导航指南

入门

📄 阅读: references/getting-started.md

  • 通过 npm(@syncfusion/ej2-react-calendars)安装
  • CSS 导入和主题配置
  • 基本的 DateRangePicker 实现
  • 类组件与函数组件设置
  • 组件初始化和结构
  • 运行开发服务器
  • 常见故障排查
日期范围选择

📄 阅读: references/date-range-selection.md

  • 开始日期和结束日期属性
  • 日期范围验证模式
  • 最小和最大日期限制
  • 禁用日期配置
  • 日期范围预设(最近 7 天、最近 30 天等)
  • 值绑定和双向更新
  • 只读和禁用状态
  • 占位符和标签
日期范围格式设置

📄 阅读: references/date-range-formatting.md

  • 日期格式字符串选项(MM/dd/yyyy、dd-MMM-yyyy 等)
  • 显示格式与输入格式
  • 基于区域设置的日期格式
  • 开始日期和结束日期之间的自定义分隔符
  • 浮动标签类型(Never、Always、Auto)
  • 自定义占位文本
  • 用于 DOM 属性的 htmlAttributes
事件和方法

📄 阅读: references/events-and-methods.md

  • 事件处理程序(change、open、close、blur、focus、select)
  • 事件参数结构
  • 方法(show、hide、focusIn、focusOut、reset、destroy)
  • 使用 useRef 进行命令式控制
  • 生命周期事件(created、destroyed)
  • 事件模式和最佳实践
  • 清除值和重置状态
  • DateRangeSelectingEvent 和 ChangedEventArgs
自定义和样式设置

📄 阅读: references/customization-and-styling.md

  • 使用 cssClass 自定义 CSS 类
  • 主题选项(Material、Bootstrap、Fluent、Tailwind、Fabric)
  • 移动设备全屏模式
  • RTL(从右向左)语言支持
  • 自定义预设范围
  • Z-index 管理
  • 宽度和高度配置
  • 无障碍功能和 ARIA 属性
API 参考

📄 阅读: references/api-reference.md

  • 完整的属性列表(35 个以上属性)
  • 所有方法及其签名(8 个方法)
  • 所有事件及其事件参数(12 个事件)
  • 类型定义和接口
  • 默认值和限制
  • 各属性和方法的使用场景
高级模式

📄 阅读: references/advanced-patterns.md

  • 使用日期范围验证提交表单
  • 键盘快捷键和按键导航
  • 处理服务器时区偏移
  • 持久化和 localStorage
  • 多组件集成(开始日期/结束日期绑定)
  • 使用延迟加载优化性能
  • 错误处理和验证模式
  • 复杂日期范围场景(财年、季度)

快速开始

import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
import '@syncfusion/ej2-base/styles/material3.css';
import '@syncfusion/ej2-buttons/styles/material3.css';
import '@syncfusion/ej2-lists/styles/material3.css';
import '@syncfusion/ej2-inputs/styles/material3.css';
import '@syncfusion/ej2-popups/styles/material3.css';
import '@syncfusion/ej2-calendars/styles/material3.css';

function App() {
  const [selectedRange, setSelectedRange] = React.useState<[Date, Date] | null>(null);

  const handleDateRangeChange = (e: any) => {
    setSelectedRange([e.startDate, e.endDate]);
  };

  return (
    <div style={{ padding: '20px' }}>
      <h2>Select Date Range</h2>
      <DateRangePickerComponent
        id="daterangepicker"
        placeholder="Select a range"
        change={handleDateRangeChange}
      />
      {selectedRange && (
        <p>
          Selected: {selectedRange[0]?.toLocaleDateString()} - {selectedRange[1]?.toLocaleDateString()}
        </p>
      )}
    </div>
  );
}

export default App;

常见模式

模式 1:带预设选项的日期范围
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';

function ReportingDashboard() {
  const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);

  const getDateRangePresets = () => {
    const today = new Date();
    const yesterday = new Date(today);
    yesterday.setDate(today.getDate() - 1);
    
    const last7Days = new Date(today);
    last7Days.setDate(today.getDate() - 7);
    
    const last30Days = new Date(today);
    last30Days.setDate(today.getDate() - 30);
    
    const thisMonth = new Date(today.getFullYear(), today.getMonth(), 1);
    const lastMonth = new Date(today.getFullYear(), today.getMonth(), 0);

    return [
      { text: 'Today', value: [today, today] },
      { text: 'Yesterday', value: [yesterday, yesterday] },
      { text: 'Last 7 Days', value: [last7Days, today] },
      { text: 'Last 30 Days', value: [last30Days, today] },
      { text: 'This Month', value: [thisMonth, today] },
      { text: 'Last Month', value: [new Date(today.getFullYear(), today.getMonth() - 1, 1), lastMonth] },
    ];
  };

  const handlePresetClick = (start: Date, end: Date) => {
    setDateRange([start, end]);
  };

  return (
    <div style={{ padding: '20px' }}>
      <h3>Analytics Report</h3>
      <DateRangePickerComponent
        id="daterangepicker"
        placeholder="Select report date range"
        startDate={dateRange?.[0]}
        endDate={dateRange?.[1]}
        change={(e: any) => setDateRange([e.startDate, e.endDate])}
      />
      
      <div style={{ marginTop: '15px' }}>
        {getDateRangePresets().map((preset) => (
          <button
            key={preset.text}
            onClick={() => handlePresetClick(preset.value[0], preset.value[1])}
            style={{ marginRight: '10px', padding: '5px 10px' }}
          >
            {preset.text}
          </button>
        ))}
      </div>
    </div>
  );
}

export default ReportingDashboard;
模式 2:带验证的日期范围
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import * as React from 'react';

function BookingForm() {
  const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);
  const [validationError, setValidationError] = React.useState<string>('');

  const minDate = new Date();
  const maxDate = new Date();
  maxDate.setDate(maxDate.getDate() + 90); // 90 days from now

  const handleDateRangeChange = (e: any) => {
    setValidationError('');
    
    if (!e.startDate || !e.endDate) {
      return;
    }

    const start = new Date(e.startDate);
    const end = new Date(e.endDate);

    // Validation checks
    if (start > end) {
      setValidationError('Start date must be before end date');
      return;
    }

    const daysDifference = (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24);
    if (daysDifference > 30) {
      setValidationError('Date range cannot exceed 30 days');
      return;
    }

    setDateRange([start, end]);
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (dateRange && !validationError) {
      console.log('Booking dates:', {
        checkIn: dateRange[0].toLocaleDateString(),
        checkOut: dateRange[1].toLocaleDateString(),
      });
    }
  };

  return (
    <form onSubmit={handleSubmit} style={{ padding: '20px', maxWidth: '500px' }}>
      <h3>Book Your Stay</h3>
      
      <label style={{ display: 'block', marginBottom: '8px' }}>
        Select Check-in and Check-out Dates (Max 30 days)
      </label>
      
      <DateRangePickerComponent
        id="daterangepicker"
        placeholder="Select check-in and check-out"
        min={minDate}
        max={maxDate}
        startDate={dateRange?.[0]}
        endDate={dateRange?.[1]}
        change={handleDateRangeChange}
        style={{ width: '100%', marginBottom: '8px' }}
      />

      {validationError && (
        <div style={{ color: 'red', marginBottom: '10px', fontSize: '14px' }}>
          ⚠️ {validationError}
        </div>
      )}

      <ButtonComponent 
        type="submit" 
        isPrimary={true} 
        disabled={!dateRange || !!validationError}
      >
        Book Now
      </ButtonComponent>
    </form>
  );
}

export default BookingForm;
模式 4:事件处理和状态管理
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';

function EventTrackingExample() {
  const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);
  const [eventLog, setEventLog] = React.useState<string[]>([]);

  const handleSelect = (e: any) => {
    setEventLog(prev => [
      ...prev, 
      `Selected: ${e.startDate?.toLocaleDateString()} to ${e.endDate?.toLocaleDateString()}`
    ]);
  };

  const handleChange = (e: any) => {
    setDateRange([e.startDate, e.endDate]);
    setEventLog(prev => [...prev, `Changed: ${new Date().toLocaleTimeString()}`]);
  };

  const handleOpen = (e: any) => {
    setEventLog(prev => [...prev, `Popup opened at ${new Date().toLocaleTimeString()}`]);
  };

  const handleClose = (e: any) => {
    setEventLog(prev => [...prev, `Popup closed at ${new Date().toLocaleTimeString()}`]);
  };

  const clearLog = () => {
    setEventLog([]);
  };

  return (
    <div style={{ padding: '20px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>
      <div>
        <h3>DateRangePicker</h3>
        <DateRangePickerComponent
          id="daterangepicker"
          placeholder="Select date range"
          select={handleSelect}
          change={handleChange}
          open={handleOpen}
          close={handleClose}
        />
      </div>

      <div style={{ padding: '10px', border: '1px solid #ccc', borderRadius: '4px' }}>
        <h3>Event Log</h3>
        <button 
          onClick={clearLog}
          style={{ 
            padding: '5px 10px', 
            marginBottom: '10px',
            backgroundColor: '#f0f0f0',
            border: '1px solid #ccc',
            cursor: 'pointer'
          }}
        >
          Clear Log
        </button>
        <ul style={{ maxHeight: '300px', overflowY: 'auto', margin: 0, paddingLeft: '20px' }}>
          {eventLog.map((event, idx) => (
            <li key={idx} style={{ marginBottom: '5px', fontSize: '12px' }}>
              {event}
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default EventTrackingExample;
模式 5:自定义日期范围格式
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';

function DateFormatDemo() {
  const [formatType, setFormatType] = React.useState<'short' | 'long' | 'custom'>('short');
  const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);

  const getFormat = () => {
    switch (formatType) {
      case 'short':
        return 'M/d/yyyy';
      case 'long':
        return 'MMMM d, yyyy';
      case 'custom':
        return 'dd-MMM-yy';
      default:
        return 'M/d/yyyy';
    }
  };

  return (
    <div style={{ padding: '20px' }}>
      <h3>Date Range Format Options</h3>
      
      <div style={{ marginBottom: '15px' }}>
        <label style={{ marginRight: '10px' }}>Format Type:</label>
        {(['short', 'long', 'custom'] as const).map((format) => (
          <label key={format} style={{ marginRight: '15px' }}>
            <input
              type="radio"
              name="format"
              value={format}
              checked={formatType === format}
              onChange={(e) => setFormatType(e.target.value as any)}
            />
            {format.charAt(0).toUpperCase() + format.slice(1)}
          </label>
        ))}
      </div>

      <div style={{ marginBottom: '10px', padding: '10px', backgroundColor: '#f5f5f5' }}>
        <strong>Format String:</strong> {getFormat()}
      </div>

      <DateRangePickerComponent
        id="daterangepicker"
        placeholder="Select date range"
        format={getFormat()}
        startDate={dateRange?.[0]}
        endDate={dateRange?.[1]}
        change={(e: any) => setDateRange([e.startDate, e.endDate])}
      />

      {dateRange && (
        <div style={{ marginTop: '15px', padding: '10px', backgroundColor: '#e8f5e9' }}>
          <p>
            <strong>Formatted Output:</strong> {dateRange[0].toLocaleDateString('en-US')} - {dateRange[1].toLocaleDateString('en-US')}
          </p>
        </div>
      )}
    </div>
  );
}

export default DateFormatDemo;

关键属性参考

  • 属性:startDate:类型:Date — 默认值:null — 范围的初始开始日期。
  • 属性:endDate:类型:Date — 默认值:null — 范围的初始结束日期。
  • 属性:min:类型:Date — 默认值:new Date(1900, 0, 1) — 可选择的最小日期。
  • 属性:max:类型:Date — 默认值:new Date(2099, 11, 31) — 可选择的最大日期。
  • 属性:value:类型:Date[] | DateRange — 默认值:null — 获取或设置开始日期和结束日期。
  • 属性:format:类型:string | RangeFormatObject — 默认值:null — 日期显示和输入格式。
  • 属性:placeholder:类型:string — 默认值:null — 输入占位文本。
  • 属性:enabled:类型:boolean — 默认值:true — 启用或禁用组件(使用 enabled,而非 disabled)。
  • 属性:readonly:类型:boolean — 默认值:false — 只读状态;禁止编辑。
  • 属性:allowEdit:类型:boolean — 默认值:true — 允许手动编辑输入文本。
  • 属性:cssClass:类型:string — 默认值:'' — 为根元素添加自定义 CSS 类。
  • 属性:floatLabelType:类型:FloatLabelType | string — 默认值:Never — 浮动标签行为(Never、Always、Auto)。
  • 属性:separator:类型:string — 默认值:'-' — 输入中开始日期和结束日期之间的分隔符。
  • 属性:locale:类型:string — 默认值:'en-US' — 用于格式化和本地化的区域设置。
  • 属性:inputFormats:类型:string[] | RangeFormatObject[] — 默认值:null — 可接受的输入解析格式。
  • 属性:keyConfigs:类型:object — 默认值:null — 自定义键盘快捷键映射。
  • 属性:firstDayOfWeek:类型:number — 默认值:null — 日历中每周的第一天。
  • 属性:dayHeaderFormat:类型:DayHeaderFormats — 默认值:Short — 标题中星期名称的格式。
  • 属性:start:类型:CalendarView — 默认值:Month — 弹出窗口打开时的初始日历视图。
  • 属性:depth:类型:CalendarView — 默认值:Month — 日历导航的最大深度。
  • 属性:weekNumber:类型:boolean — 默认值:false — 在日历行中显示周数。
  • 属性:weekRule:类型:WeekRule — 默认值:FirstDay — 定义一年中第一周的规则。
  • 属性:minDays:类型:number — 默认值:null — 所选范围允许的最小天数。
  • 属性:maxDays:类型:number — 默认值:null — 所选范围允许的最大天数。
  • 属性:strictMode:类型:boolean — 默认值:false — 为 true 时,只能输入有效范围。
  • 属性:showClearButton:类型:boolean — 默认值:true — 切换清除按钮的显示状态。
  • 属性:fullScreenMode:类型:boolean — 默认值:false — 在移动设备上使用全屏弹出窗口。
  • 属性:htmlAttributes:类型:{ [key: string]: string } — 默认值:{} — 应用于组件元素的其他 HTML 属性。
  • 属性:serverTimezoneOffset:类型:number — 默认值:null — 处理初始值时使用的服务器时区偏移量(分钟)。
  • 属性:width:类型:number | string — 默认值:'' — 组件输入框的宽度。
  • 属性:zIndex:类型:number — 默认值:1000 — 弹出元素的 z-index。

相关技能


后续步骤:

评论

支持 Markdown