منتقي التاريخ (Date Picker)
حقل للتاريخ يفتح تقويمًا تحته. عنصره المُشغِّل هو نفسه في حقل الاختيار، فيصطف الاثنان في النموذج: الأحجام الأربعة نفسها، والتسمية والنص المساعد وحلقة التركيز. يحمل يومًا واحدًا أو مدة، ويعرضها بصيغة 20 يناير 2026 في الصفحة العربية، وبصيغة Jan 20, 2026 في الإنجليزية.
التثبيت
npx @smicolon/fasla-ui@latest add date-pickerقبل إضافة أي مكوّن، شغّل الأمر init مرة واحدة في مشروعك. التفاصيل في صفحة التثبيت.
معاينة
الأحجام
أربعة أحجام: ارتفاع الحجم xs هو 28px، والحجم sm هو 32px، والحجم md هو 36px، والحجم lg هو 40px، وهي ارتفاعات حقل الاختيار نفسها. ويتغير الارتفاع والمسافة بين الأيقونة والنص فقط، أما الحشو فهو 12px وأيقونة التقويم 16px في كل الأحجام.
الحالات
التركيز حالة حقيقية، لا خاصية: انتقل إلى الحقل بمفتاح Tab أو افتحه. يرسم العنصر المُشغِّل حلقة التركيز عند التركيز من لوحة المفاتيح، وطوال بقاء التقويم مفتوحًا. وتُظهر الخاصية disabled الحقل كله باهتًا بنصف شفافيته، مع التسمية والنص المساعد.
المدة
تحمل القيمة mode="range" يومًا للبداية ويومًا للنهاية، بينهما شرطة. يبقى التقويم مفتوحًا بعد الضغطة الأولى، ويُغلق بعد اختيار الطرفين. واضبط الخاصية numberOfMonths على 2 ليُفتح بشهرين.
بجوار حقل الاختيار
تعمل التسمية والملاحظة في نهاية سطرها والنص المساعد كما في حقل الاختيار، والعنصر المُشغِّل هو عنصره نفسه، فيصطف منتقي التاريخ وحقل الاختيار جنبًا إلى جنب في كل الأحجام.
اختياري
حيث نوصل طلبك.
التقويم
يُفتح التقويم تحت العنصر المُشغِّل بمسافة 4px، محاذيًا لحافته في البداية، وينتقل فوقه حين لا يتسع له المكان تحته. وينتقل التركيز إلى اليوم المختار، وإلا فإلى اليوم الحالي، فتعمل مفاتيح الأسهم فورًا. ويُغلق التقويم باختيار يوم أو بمفتاح Escape، ويعود التركيز إلى العنصر المُشغِّل.
في نموذج
امنح الحقل الخاصية name فيُرسل مع نموذجه: اليوم بصيغة 2026-01-20، والمدة بصيغة 2026-01-20/2026-02-09. ومرّر خصائص التقويم عبر calendarProps، مثل قائمتي الشهر والسنة لتاريخ الميلاد.
إتاحة الوصول (accessibility)
- العنصر المُشغِّل عنصر
buttonيفتح نافذة بالدورdialog. واسمه التسمية والقيمة معًا، فيقرأ قارئ الشاشة الاثنين، ويقرأ النص المساعد معهما. - يفتح مفتاح Enter أو مفتاح المسافة التقويم وينقل التركيز إلى اليوم المختار. ثم تعمل مفاتيح التقويم نفسها: الأسهم، ومفتاح Page Up، ومفتاح Page Down، ومفتاح Home، ومفتاح End. ويغلق مفتاح Escape التقويم ويعيد التركيز إلى العنصر المُشغِّل.
- تسمّي الخاصية
labelالعنصر المُشغِّل. وإذا لم تضع تسمية، فأضف السمةaria-label. والضغط على التسمية ينقل التركيز إلى العنصر المُشغِّل دون أن يفتح التقويم. - يتبع الاتجاه السمة
dirفي الصفحة، ولا توجد له خاصية. ويأخذ التقويم اتجاه الصفحة ولغتها وخطها من العنصر المُشغِّل، مع أنه يُعرض في نهاية العنصرbody.
الخصائص (props)
DatePicker
| الخاصية | النوع | الافتراضي | الوصف |
|---|---|---|---|
mode | "single" | "range" | "single" | يوم واحد، أو مدة من يوم إلى آخر. |
value | Date | DateRange | null | لا يوجد | اليوم المختار، أو المدة مع القيمة mode="range". وتُستخدم مع onValueChange. |
defaultValue | Date | DateRange | null | لا يوجد | القيمة المختارة عند العرض الأول. |
onValueChange | (value) => void | لا يوجد | تُستدعى باليوم الجديد، أو بالمدة عند اختيار كل طرف. |
placeholder | ReactNode | لا يوجد | نص يظهر قبل اختيار تاريخ. والافتراضي «اختر تاريخًا» في الصفحة العربية، وما يقابله بالإنجليزية في غيرها. |
size | "xs" | "sm" | "md" | "lg" | "md" | ارتفاع الحقل: 28 أو 32 أو 36 أو 40px. |
numberOfMonths | number | 1 | عدد الأشهر المتجاورة في التقويم. |
calendarProps | CalendarProps | لا يوجد | خصائص أخرى للتقويم: الأيام الموقوفة، والشهر المعروض، وقائمتا الشهر والسنة، والخاصية radius. |
label | ReactNode | لا يوجد | تسمية الحقل، ترتبط بالعنصر المُشغِّل تلقائيًا. |
aria-label | string | لا يوجد | الاسم الذي يقرؤه قارئ الشاشة للعنصر المُشغِّل حين لا توجد تسمية ظاهرة. |
aria-labelledby | string | لا يوجد | معرّف عنصر يسمّي العنصر المُشغِّل بدل الخاصية label. |
labelEnd | ReactNode | لا يوجد | ملاحظة قصيرة في نهاية سطر التسمية، مثل «اختياري». |
description | ReactNode | لا يوجد | نص مساعد تحت الحقل، يقرؤه قارئ الشاشة مع الحقل. |
descriptionEnd | ReactNode | لا يوجد | ملاحظة في نهاية سطر النص المساعد. |
disabled | boolean | false | يعطّل الحقل ويُظهر المجموعة كلها باهتة. |
name | string | لا يوجد | الاسم الذي تُرسل به القيمة مع النموذج. |
form | string | لا يوجد | معرّف النموذج الذي تُرسل معه القيمة، حين يكون الحقل خارجه. |
id | string | لا يوجد | معرّف العنصر المُشغِّل. |
open | boolean | لا يوجد | يفتح التقويم أو يغلقه حين تتحكم به. |
defaultOpen | boolean | false | يفتح التقويم عند العرض الأول. |
onOpenChange | (open) => void | لا يوجد | تُستدعى عند فتح التقويم أو إغلاقه. |
collisionAvoidance | { side, align, fallbackAxisSide } | لا يوجد | كيف يتجنب التقويم حافة النافذة. ينتقل تلقائيًا فوق العنصر المُشغِّل حين لا يتسع له المكان تحته. |
container | HTMLElement | لا يوجد | مكان عرض التقويم، والافتراضي العنصر body. |
className | string | لا يوجد | أصناف CSS إضافية لمجموعة الحقل. |
الاستخدام
يوم واحد
import { DatePicker } from "@/components/ui/date-picker"
export function DeliveryDate() {
return (
<DatePicker
name="delivery"
label="تاريخ التوصيل"
description="نوصل الطلبات بين 9 صباحًا و5 مساءً."
calendarProps={{ disabled: { before: new Date() } }}
/>
)
}مدة
"use client"
import * as React from "react"
import { DatePicker, type DateRange } from "@/components/ui/date-picker"
export function StayDates() {
const [stay, setStay] = React.useState<DateRange | null>(null)
return (
<DatePicker
mode="range"
numberOfMonths={2}
label="مدة الإقامة"
value={stay}
onValueChange={setStay}
/>
)
}في نموذج
import { Button } from "@/components/ui/button"
import { DatePicker } from "@/components/ui/date-picker"
export function BirthDateForm() {
return (
<form action="/profile" className="flex flex-col items-start gap-8">
<DatePicker
name="dob"
label="تاريخ الميلاد"
description="نستخدم تاريخ ميلادك لحساب عمرك."
calendarProps={{
captionLayout: "dropdown",
startMonth: new Date(1926, 0),
endMonth: new Date(),
}}
/>
<Button type="submit">إرسال</Button>
</form>
)
}