پرش به مطلب اصلی

DatePicker

کامپوننت DatePicker برای انتخاب تاریخ بر پایه‌ی تقویم شمسی (جلالی) استفاده می‌شود. رابط کاربری (تقویم، اعداد روز/ماه/سال) کاملاً شمسی است و مقدار خروجی هم تاریخ شمسی را به‌صورت اصلی نگه می‌دارد — به‌صورت پیش‌فرض معادل میلادی (Date) هم به آن اضافه می‌شود تا مستقیماً قابل‌ذخیره در دیتابیس و مقایسه باشد.

Import​

import { DatePicker } from "fara-ui";

اگر هنوز FaraUI را نصب و راه‌اندازی نکرده‌ای، ابتدا صفحه‌ی شروع به کار را ببین.

Basic Usage​

import { useState } from "react";
import { DatePicker } from "fara-ui";

export function BirthdayPicker() {
const [value, setValue] = useState(null);

return (
<div>
<DatePicker value={value} onChange={setValue} placeholder="تاریخ تولد را انتخاب کنید" />
{value && (
<p>تاریخ شمسی: {`${value.jalali.year}/${value.jalali.month}/${value.jalali.day}`}</p>
)}
</div>
);
}

اگر نمی‌خواهی مقدار را در state کنترل کنی، از defaultValue استفاده کن:

<DatePicker
defaultValue={{
jalali: { year: 1404, month: 1, day: 1 },
}}
onChange={(nextValue) => console.log(nextValue)}
/>

Date Value​

مقدار ورودی/خروجی کامپوننت یک شیء DatePickerValue است:

interface DatePickerValue {
jalali: JalaliDate; // { year, month, day } — همیشه موجود
gregorian?: Date; // با includeGregorian (پیش‌فرض true)
time?: { hour: number; minute: number }; // فقط با showTime
}
  • jalali — تاریخ انتخاب‌شده به شمسی؛ مقدار اصلی کامپوننت.
  • gregorian — معادل میلادی همان تاریخ؛ اگر با سرور یا دیتابیس میلادی کار می‌کنی از همین فیلد استفاده کن بدون تبدیل دستی.
  • time — ساعت و دقیقه‌ی انتخاب‌شده؛ فقط وقتی showTime فعال باشد.

برای مقدار اولیه می‌توانی هر کدام از jalali یا gregorian را بدهی؛ کامپوننت خودش مقدار دیگر را استخراج می‌کند.

Playground​

<DatePicker
value={value}
onChange={setValue}
mode="calendar"
placeholder="انتخاب تاریخ"
/>

توجه: کنترل showTodayButton فقط در mode="calendar" اثر دارد. در mode="scroll" به‌جای دکمه‌ی «امروز»، یک دکمه‌ی «تأیید» ثابت برای بستن پیکر وجود دارد.

Mode​

  • calendar (پیش‌فرض): نمایش شبکه‌ی ماهانه‌ی روزها، همراه با امکان پرش سریع به انتخاب ماه یا سال از هدر تقویم.
  • scroll: ستون‌های اسکرولی برای روز، ماه و سال — شبیه پیکرهای رایج موبایل (مثل iOS).

بازه‌ی سال قابل‌انتخاب در هر دو حالت از ۱۳۰۰ تا ۱۵۰۰ (شمسی) محدود شده است.

Time Selection (showTime)​

با showTime ستون‌ها/لیست‌های ساعت و دقیقه هم به پیکر اضافه می‌شود و مقدار خروجی فیلد time پیدا می‌کند:

<DatePicker value={value} onChange={setValue} showTime />

// value === {
// jalali: { year: 1404, month: 6, day: 10 },
// gregorian: Date,
// time: { hour: 14, minute: 30 },
// }

در هر دو mode با فعال‌بودن showTime، انتخاب تاریخ به‌صورت draft نگه داشته می‌شود و فقط با کلیک روی «تایید» ثبت می‌گردد. مقدار پیش‌فرض ساعت با defaultTime تنظیم می‌شود:

  • "current" (پیش‌فرض) — زمان فعلی سیستم
  • "zero" — 00:00

Restricting the Selectable Range​

  • minDate / maxDate — حد پایین و بالای تاریخ قابل انتخاب؛ به‌صورت Date میلادی یا JalaliDate شمسی. روزهای خارج از محدوده غیرفعال می‌شوند و پیمایش ماه/سال هم محدود می‌شود.
  • disabledDates — تابعی که یک Date میلادی می‌گیرد و اگر true برگرداند، آن روز غیرفعال می‌شود؛ مثلاً تعطیلات.
<DatePicker
minDate={{ year: 1404, month: 1, day: 1 }}
maxDate={new Date("2026-03-21")}
disabledDates={(date) => date.getDay() === 5} // جمعه‌ها
/>

یک مثال کامل برای جلوگیری از انتخاب تاریخ گذشته:

function FutureDatePicker() {
const [date, setDate] = useState(null);

return (
<DatePicker
value={date}
onChange={setDate}
minDate={new Date()}
disabledDates={(day) => day.getDay() === 5}
placeholder="یک روز کاری انتخاب کنید"
/>
);
}

Controlled vs Uncontrolled​

DatePicker هر دو حالت را پشتیبانی می‌کند: با value کنترل‌شده و با defaultValue غیرکنترل‌شده.

Friday Highlight​

جمعه‌ها به‌صورت خودکار (هم عدد روز داخل جدول، هم حرف «ج» در هدر ستون‌ها) با رنگ قرمز نمایش داده می‌شوند تا از بقیه‌ی روزهای هفته متمایز باشند. این رفتار ثابت است و پراپ جداگانه‌ای برای فعال/غیرفعال‌کردنش وجود ندارد.

Utilities​

اگر جایی در برنامه‌ات نیاز به تبدیل شمسی ⇄ میلادی داری، از توابع کمکی استفاده کن:

import { gregorianToJalali, jalaliToGregorian, formatJalali } from "fara-ui/jalali";

const jalali = gregorianToJalali(new Date()); // { year, month, day }
jalaliToGregorian({ year: 1404, month: 6, day: 10 }); // Date
formatJalali(jalali); // مثلاً "1404/06/10"

Accessibility​

  • دکمه‌های پیمایش ماه (قبلی/بعدی) دارای aria-label مناسب هستند.
  • محدودیت شناخته‌شده: در حال حاضر ناوبری با کلیدهای جهت‌دار داخل جدول روزها پشتیبانی نمی‌شود؛ فقط Escape و کلیک بیرون از تقویم آن را می‌بندد.

Data Attributes and Customize CSS​

DatePicker برای استایل‌دهی پایدار، hookهای data-fara-* زیر را ارائه می‌کند:

<div data-fara-date-picker>
<input data-fara-date-picker-input />
</div>

مهم‌ترین hookها:

Attributeکاربرد
data-fara-date-pickerریشه‌ی کامپوننت
data-fara-date-picker-inputفیلد نمایش تاریخ
data-fara-date-picker-panelپنل تقویم؛ در Portal قرار می‌گیرد
data-fara-date-picker-day-cellسلول هر روز
data-fara-date-picker-month-cellسلول ماه در نمای انتخاب ماه
data-fara-date-picker-year-cellسلول سال در نمای انتخاب سال
data-fara-date-picker-confirm-buttonدکمه‌ی تأیید

سلول‌های روز می‌توانند stateهایی مثل data-selected و data-today داشته باشند:

[data-fara-date-picker-day-cell][data-today] {
font-weight: 700;
}

[data-fara-date-picker-day-cell][data-selected] {
background: #7c3aed;
color: white;
}

className روی wrapper اصلی و inputClassName روی input نمایش تاریخ اعمال می‌شود:

<DatePicker
className="report-date-picker"
inputClassName="report-date-input"
onChange={(value) => console.log(value)}
/>
.report-date-picker {
width: 280px;
}

.report-date-input {
border-radius: 12px;
}

چون پنل تقویم با Portal در document.body رندر می‌شود، برای استایل‌دهی خود پنل از data-fara-date-picker-panel استفاده کن، نه selectorهای فرزند wrapper.

SSR Note​

DatePicker با SSR و Next.js سازگار است و در زمان رندر سرور خروجی پنل تولید نمی‌کند. پنل بلافاصله پس از hydration در مرورگر فعال می‌شود و نیازی به dynamic(..., { ssr: false }) نیست.

Props​

PropTypeDefaultDescription
valueDatePickerValue | null-تاریخ انتخاب‌شده (controlled)
defaultValueDatePickerValue | nullnullتاریخ اولیه (uncontrolled)
onChange(value: DatePickerValue) => void-هنگام انتخاب تاریخ صدا زده می‌شود
mode"calendar" | "scroll""calendar"نوع رابط انتخاب تاریخ
showTimebooleanfalseامکان انتخاب ساعت و دقیقه
defaultTime"current" | "zero""current"ساعت اولیه‌ی پیکر وقتی showTime فعال است
showTodayButtonbooleantrueنمایش دکمه‌ی «امروز» (فقط در mode="calendar")
minDateDate | JalaliDate-حد پایین تاریخ قابل انتخاب
maxDateDate | JalaliDate-حد بالای تاریخ قابل انتخاب
disabledDates(date: Date) => boolean-غیرفعال‌کردن تاریخ‌های خاص
includeGregorianbooleantrueافزودن فیلد gregorian به مقدار خروجی
placeholderstring"انتخاب تاریخ"متن راهنما وقتی تاریخی انتخاب نشده
disabledbooleanfalseغیرفعال کردن کل کامپوننت
classNamestring-کلاس CSS اضافی برای سفارشی‌سازی
inputClassNamestring-کلاس CSS اضافی مخصوص فیلد ورودی نمایش تاریخ