Wheel Pickerv1.0.0
ستونی که کاربر با انگشت میچرخاند و هرچه وسطِ ستون بایستد انتخاب میشود. برای انتخاب از یک بازهٔ عددیِ طولانی روی موبایل ساخته شده، جایی که فهرست کشویی بلند و لمسناپذیر میشود. حالت موبایلِ Date Picker روی همین سوار است.
این کامپوننت فعلاً برای ۱ فریمورک از ۴ فریمورک آماده است.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
نصب
با CLI اختصاصی digdesign کامپوننت را از رجیستری دیگ نصب کنید؛ وابستگیها و فایلها خودکار اضافه میشوند.
npx digdesign@latest add https://docs.digdesign.ir/r/wheel-picker.jsonpnpm dlx digdesign@latest add https://docs.digdesign.ir/r/wheel-picker.jsonyarn dlx digdesign@latest add https://docs.digdesign.ir/r/wheel-picker.jsonbunx --bun digdesign@latest add https://docs.digdesign.ir/r/wheel-picker.jsonاین کامپوننت هنوز برای Vue پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
این کامپوننت هنوز برای Svelte پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
این کامپوننت هنوز برای Angular پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
استفاده
import {
WheelPicker,
WheelPickerColumn,
type WheelPickerOption,
} from "@/components/ui/wheel-picker"
const [hour, setHour] = React.useState(9)
<WheelPicker>
<WheelPickerColumn options={hours} value={hour} onChange={setHour} aria-label="ساعت" />
</WheelPicker>این کامپوننت هنوز برای Vue پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
این کامپوننت هنوز برای Svelte پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
این کامپوننت هنوز برای Angular پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
ترکیب اجزا
WheelPicker فقط ظرفِ افقی است و ستونها را کنار هم میچیند. تمام رفتار در WheelPickerColumn است و هر ستون value و onChange مستقل خودش را میگیرد؛ یعنی کامپوننت همیشه کنترلشده است و حالت داخلی ندارد.
ظرف عمداً dir="ltr" دارد. ترتیب ستونها در انتخابگرِ زمان و تاریخ یک قرارداد جهانی است (ساعت سمت چپِ دقیقه) و با راستبهچپ شدنِ صفحه نباید برعکس شود. محتوای داخلِ هر ستون همچنان فارسی است.
ارتفاع ستون ثابت است: پنج ردیفِ چهلپیکسلی. عرض را شما میدهید؛ برای ستونی که برچسبِ بلندتری دارد (مثل نام ماه) با className="flex-[1.6]" سهم بیشتری بدهید.
value عدد است، نه رشته. برای برچسب هر چیزی میشود داد (label از نوع ReactNode است)، پس ارقام فارسی و نام ماه هر دو با همین یک ساختار کار میکنند.
دسترسپذیری
- ستون role="listbox" و هر ردیف role="option" با aria-selected دارد، پس صفحهخوان میفهمد کدام گزینه انتخاب شده است.
- روی هر ستون aria-label بگذارید؛ بدون آن، صفحهخوان سه ستونِ کنار هم را از هم تشخیص نمیدهد و فقط «فهرست» میگوید.
- ناوبری با صفحهکلید ندارد: ستون فوکوسپذیر نیست و فلشها کار نمیکنند. این کامپوننت برای لمس ساخته شده، پس روی دسکتاپ بهجایش Select یا Time Field بگذارید که هر دو کاملاً با کیبورد کار میکنند.
- کلیک روی هر ردیف هم آن را وسط میآورد، ولی راه اصلی کشیدن است؛ به همین دلیل هدف لمسی هر ردیف چهل پیکسل ارتفاع دارد.
- محوشدگی بالا و پایین و نوار انتخابِ وسط همه aria-hidden هستند و در درخت دسترسپذیری دیده نمیشوند.
مرجع API
WheelPicker
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| children | React.ReactNode | — | یک یا چند WheelPickerColumn که کنار هم چیده میشوند. |
| className | string | — | روی ظرف افقی مینشیند؛ عرض کل چرخ را از همینجا بدهید. |
WheelPickerColumn
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| options | WheelPickerOption[] | — | فهرست گزینهها، هر کدام { value: number, label: ReactNode }. ترتیبشان همان ترتیب نمایش است. |
| value | number | — | مقدار انتخابشده. اگر در options نباشد، اولین گزینه انتخابشده در نظر گرفته میشود. |
| onChange | (value: number) => void | — | بعد از ایستادنِ اسکرول صدا زده میشود، نه در طول کشیدن؛ پس با هر پیکسل حرکت، state شما بهروز نمیشود. |
| aria-label | string | — | نام ستون برای صفحهخوان. در چرخ چندستونی الزامی است. |
| className | string | — | روی خودِ ستون مینشیند؛ برای سهمِ عرض از flex استفاده کنید. |
این کامپوننت هنوز برای Vue پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
این کامپوننت هنوز برای Svelte پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
این کامپوننت هنوز برای Angular پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک در دست کار است.
نمونهها
انتخاب ساعت
دو ستونِ ساعت و دقیقه کنار هم. ترتیبشان بهخاطر dir="ltr" روی ظرف، در صفحهٔ راستبهچپ هم ثابت میماند.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
تاریخ شمسی
ستون ماه برچسب متنی دارد نه عددی، پس با flex سهم بیشتری از عرض میگیرد تا نام ماه نشکند.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
کنترل از بیرون
چون کامپوننت کاملاً کنترلشده است، تغییر value از بیرون ستون را بیصدا به همان ردیف میبرد بدون اینکه onChange دوباره شلیک شود.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
کدام نمونه برای کدام موقعیت
| نمونه | کجا به کار میآید |
|---|---|
| انتخاب ساعت | رزرو نوبت یا تنظیم یادآور روی موبایل |
| تاریخ شمسی | همان چیزی که Date Picker روی موبایل نشان میدهد |
| کنترل از بیرون | دکمههای میانبر کنار چرخ |
دستورالعمل استفاده
برای بازهٔ عددیِ طولانی روی موبایل
انجام بده
شصت دقیقه یا سیویک روز، جایی که کاربر معمولاً چند قدم آنطرفتر از مقدار فعلی را میخواهد و کشیدن سریعتر از پیمایشِ یک فهرست بلند است.
انجام نده
برای چند گزینهٔ کم و بیترتیب (مثل انتخاب شهر یا وضعیت) مناسب نیست؛ آنجا Select خواناتر است، با کیبورد کار میکند و همهٔ گزینهها را یکجا نشان میدهد.
روی هر ستون aria-label بگذارید
ساعت انتخابشده: ۱۴:۳۰
انجام بده
با aria-label، صفحهخوان «ساعت» و «دقیقه» را جدا اعلام میکند و کاربر میفهمد در کدام ستون است.
انجام نده
بدون برچسب، سه listboxِ بینام کنار هم میمانند و با صفحهخوان قابل استفاده نیستند.