DateRangePicker
کامپوننت DateRangePicker برای انتخاب یک بازهی تاریخ بر پایهی تقویم شمسی (جلالی) استفاده میشود؛ مثل فیلتر بازهی زمانی در گزارشها یا تعیین تاریخ ورود و خروج. پنل آن دو ماه کنار هم نمایش میدهد و بازهی در حال انتخاب را بهصورت زنده highlight میکند.
Import
import { DateRangePicker } from "fara-ui";
اگر هنوز FaraUI را نصب و راهاندازی نکردهای، ابتدا صفحهی شروع به کار را ببین.
Basic Usage
import { useState } from "react";
import { DateRangePicker } from "fara-ui";
export function ReportRangePicker() {
const [range, setRange] = useState(null);
return (
<div>
<DateRangePicker
value={range}
onChange={setRange}
placeholder="بازهی گزارش را انتخاب کنید"
/>
{range && (
<p>
از {range.start.year}/{range.start.month}/{range.start.day}
{" تا "}
{range.end.year}/{range.end.month}/{range.end.day}
</p>
)}
</div>
);
}
برای مقدار اولیهی غیرکنترلشده از defaultValue استفاده کن:
<DateRangePicker
defaultValue={{
start: { year: 1404, month: 1, day: 1 },
end: { year: 1404, month: 1, day: 7 },
}}
onChange={(nextRange) => console.log(nextRange)}
/>
Playground
<DateRangePicker
value={range}
onChange={setRange}
placeholder="انتخاب بازهی تاریخ"
/>
Range Selection
- کلیک اول، تاریخ شروع بازه را انتخاب میکند.
- با حرکت ماوس روی روزها، بازهی در حال انتخاب بهصورت زنده پیشنمایش میشود.
- کلیک دوم، تاریخ پایان را مشخص میکند. اگر تاریخ پایان قبل از شروع انتخاب شود، بهصورت خودکار جابهجا میشوند تا ترتیب درست بماند.
مقادیر پنل فقط با کلیک روی «تأیید» در onChange ثبت میشوند؛ بستن پنل (کلیک بیرون یا Escape) بدون تأیید، مقدار قبلی را حفظ میکند. اگر فقط تاریخ شروع انتخاب و تأیید شود، بازهی تکروزه (start == end) ثبت میشود.
Range Value
مقدار ورودی/خروجی کامپوننت یک شیء با تاریخهای شمسی است و بهصورت پیشفرض معادل میلادی آن هم برگردانده میشود:
interface DateRangeValue {
start: JalaliDate; // { year, month, day } شمسی
end: JalaliDate;
startGregorian?: Date; // با includeGregorian (پیشفرض true)
endGregorian?: Date;
}
اگر فقط معادل میلادی را نیاز داری، includeGregorian را روشن بگذار و از startGregorian/endGregorian استفاده کن؛ برای بهروزرسانی state لازم نیست خودت تبدیل انجام بدهی.
Restricting the Selectable Range
minDate/maxDate— حد پایین و بالای بازهی قابل انتخاب؛ هر دو یا هر کدام بهصورتDateمیلادی یاJalaliDateشمسی. روزهای خارج از محدوده غیرفعال میشوند و پیمایش ماه هم محدود میشود.disabledDates— تابعی که یکDateمیلادی میگیرد و اگرtrueبرگرداند، آن روز غیرفعال میشود؛ مثلاً تعطیلات.
<DateRangePicker
minDate={new Date("2025-03-21")}
disabledDates={(date) => date.getDay() === 5} // جمعهها
/>
بازهی سال قابلپیمایش از ۱۳۰۰ تا ۱۵۰۰ (شمسی) محدود شده است.
مثال کامل برای فیلتر گزارش:
function SalesReportFilter() {
const [range, setRange] = useState(null);
function loadReport() {
if (!range?.startGregorian || !range.endGregorian) return;
const params = new URLSearchParams({
from: range.startGregorian.toISOString(),
to: range.endGregorian.toISOString(),
});
console.log(`/api/reports/sales?${params}`);
}
return (
<div>
<DateRangePicker
value={range}
onChange={setRange}
minDate={new Date("2025-03-21")}
disabledDates={(date) => date.getDay() === 5}
/>
<button type="button" disabled={!range} onClick={loadReport}>
دریافت گزارش
</button>
</div>
);
}
Controlled vs Uncontrolled
DateRangePicker هر دو حالت را پشتیبانی میکند: با value کنترلشده و با defaultValue غیرکنترلشده.
Accessibility
- دکمههای پیمایش ماه (قبلی/بعدی) دارای
aria-labelمناسب هستند. - پنل با کلیک بیرون از کامپوننت یا کلید
Escapeبسته میشود.
Data Attributes and Customize CSS
DateRangePicker hookهای پایدار زیر را در DOM تولید میکند:
| Attribute | کاربرد |
|---|---|
data-fara-date-range-picker | ریشهی کامپوننت |
data-fara-date-range-picker-input | فیلد نمایش بازه |
data-fara-date-range-picker-panel | پنل انتخاب؛ در Portal قرار میگیرد |
data-fara-date-range-picker-day-cell | سلول هر روز |
data-fara-date-range-picker-month-column | ستون هر ماه |
data-fara-date-range-picker-footer-button | دکمههای پایین پنل |
سلولهای روز stateهایی مثل data-selected, data-in-range و data-today دارند:
[data-fara-date-range-picker-day-cell][data-in-range] {
background: #ede9fe;
}
[data-fara-date-range-picker-day-cell][data-selected] {
background: #7c3aed;
color: white;
}
className روی wrapper اصلی و inputClassName روی input اعمال میشود:
<DateRangePicker
className="booking-range"
inputClassName="booking-range-input"
value={range}
onChange={setRange}
/>
.booking-range {
width: 320px;
}
.booking-range-input {
border-radius: 12px;
}
پنل با Portal داخل
document.bodyرندر میشود؛ برای استایل پنل از hook مربوط بهdata-fara-date-range-picker-panelاستفاده کن.
SSR Note
DateRangePicker با SSR و Next.js سازگار است و در زمان رندر سرور خروجی پنل تولید نمیکند. پنل پس از hydration در مرورگر فعال میشود و نیازی به dynamic(..., { ssr: false }) نیست.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | DateRangeValue | null | - | بازهی انتخابشده (controlled) |
defaultValue | DateRangeValue | null | null | بازهی اولیه (uncontrolled) |
onChange | (value: DateRangeValue) => void | - | با کلیک روی «تأیید» صدا زده میشود |
minDate | Date | JalaliDate | - | حد پایین بازهی قابل انتخاب |
maxDate | Date | JalaliDate | - | حد بالای بازهی قابل انتخاب |
disabledDates | (date: Date) => boolean | - | غیرفعالکردن روزهای خاص |
includeGregorian | boolean | true | افزودن معادل میلادی به مقدار خروجی |
placeholder | string | "انتخاب بازهی تاریخ" | متن راهنما وقتی بازهای انتخاب نشده |
disabled | boolean | false | غیرفعال کردن کل کامپوننت |
className | string | - | کلاس CSS اضافی برای سفارشیسازی |
inputClassName | string | - | کلاس CSS اضافی مخصوص فیلد ورودی نمایش بازه |