Wheel Pickerv1.0.0

ستونی که کاربر با انگشت می‌چرخاند و هرچه وسطِ ستون بایستد انتخاب می‌شود. برای انتخاب از یک بازهٔ عددیِ طولانی روی موبایل ساخته شده، جایی که فهرست کشویی بلند و لمس‌ناپذیر می‌شود. حالت موبایلِ Date Picker روی همین سوار است.

ری‌اکت ۱۹ و Next.js با پیاده‌سازی دسترس‌پذیری داخلی دیگویو ۳ با Composition API — هنوز برای این کامپوننت پورت نشدهSvelte ۵ با runes — هنوز برای این کامپوننت پورت نشدهانگولار با signals و دایرکتیوهای standalone — هنوز برای این کامپوننت پورت نشده

این کامپوننت فعلاً برای ۱ فریم‌ورک از ۴ فریم‌ورک آماده است.

۰۰
۰۱
۰۲
۰۳
۰۴
۰۵
۰۶
۰۷
۰۸
۰۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
۱۸
۱۹
۲۰
۲۱
۲۲
۲۳

این نمونه هنوز برای Vue پورت نشده است؛ آنچه می‌بینید نسخهٔ ری‌اکت است.

این نمونه هنوز برای Svelte پورت نشده است؛ آنچه می‌بینید نسخهٔ ری‌اکت است.

این نمونه هنوز برای Angular پورت نشده است؛ آنچه می‌بینید نسخهٔ ری‌اکت است.

نصب

با CLI اختصاصی digdesign کامپوننت را از رجیستری دیگ نصب کنید؛ وابستگی‌ها و فایل‌ها خودکار اضافه می‌شوند.

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/wheel-picker.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/wheel-picker.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/wheel-picker.json
bunx --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

ویژگینوعپیش‌فرضتوضیح
childrenReact.ReactNode—یک یا چند WheelPickerColumn که کنار هم چیده می‌شوند.
classNamestring—روی ظرف افقی می‌نشیند؛ عرض کل چرخ را از همین‌جا بدهید.

WheelPickerColumn

ویژگینوعپیش‌فرضتوضیح
optionsWheelPickerOption[]—فهرست گزینه‌ها، هر کدام { value: number, label: ReactNode }. ترتیبشان همان ترتیب نمایش است.
valuenumber—مقدار انتخاب‌شده. اگر در options نباشد، اولین گزینه انتخاب‌شده در نظر گرفته می‌شود.
onChange(value: number) => void—بعد از ایستادنِ اسکرول صدا زده می‌شود، نه در طول کشیدن؛ پس با هر پیکسل حرکت، state شما به‌روز نمی‌شود.
aria-labelstring—نام ستون برای صفحه‌خوان. در چرخ چندستونی الزامی است.
classNamestring—روی خودِ ستون می‌نشیند؛ برای سهمِ عرض از flex استفاده کنید.

این کامپوننت هنوز برای Vue پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک در دست کار است.

این کامپوننت هنوز برای Svelte پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک در دست کار است.

این کامپوننت هنوز برای Angular پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک در دست کار است.