شريط تمرير
قيمة واحدة أو نطاق من قيمتين. مفاتيح الأسهم والضغط على المسار يصلان إلى النتيجة نفسها التي يصل إليها السحب.
client - الحجم لم يُقَس بعد
شريط تمرير
client - الحجم لم يُقَس بعدقيمة واحدة أو نطاق من قيمتين. مفاتيح الأسهم والضغط على المسار يصلان إلى النتيجة نفسها التي يصل إليها السحب.
جرّبه
size
invalid
fullWidth
showValue
min
max
step
largeStep
minStepsBetweenValues
الشيفرة
slider.tsx
import { Slider } from 'topclassui/slider'
<div className="grid justify-items-start gap-2">
<span id="slider-playground-label" className="text-sm text-body">Volume</span>
<Slider aria-labelledby="slider-playground-label" defaultValue={60} />
</div>حقل نطاق مخفي يحمل القيمة، فيُرسل الشريط مع نموذجه؛ ويتحرك المقبض بعد ترطيب الصفحة.
كل الحالات، بدون تمرير الفأرة
4 حالاتأو استورده من الحزمة
topclassui/slider
import { Slider } from 'topclassui/slider'ثبّت مرة واحدة:npm i topclassui@beta zod
أمثلة
- لرقم يُختار بالإحساس ضمن حدود معروفة. أما الرقم الدقيق فمكانه NumberField.
minوmaxوstepقيمها 0 و100 و1، ومحصورة بين سالب وموجب 1e15؛ وlargeStepلا يقل عنstep، فيتحرك Page Up دائمًا.minStepsBetweenValuesيبقي مقبضي النطاق متباعدين؛ فلا يتقاطعان أبدًا.showValueيكتب القيمة بعد المسار، بلغة المزوّد وأرقامه. والقيمة الطويلة تنتقل إلى أسفل المسار.- العرض هو عرض Input بنفس
size؛ وfullWidthيملأ الحاوية. للشريط قيمة دائمًا، لذا يُقبلrequiredثم يُهمل.
basic
Volume
basic.tsx
import { Slider } from 'topclassui/slider'
/** Outside a Field: the slider is named by the visible text above it. Drag the thumb, press the track, or use the arrows. */
export default function Demo() {
return (
<div className="grid justify-items-start gap-2">
<span id="slider-basic-label" className="text-sm text-body">Volume</span>
<Slider aria-labelledby="slider-basic-label" defaultValue={60} step={5} />
</div>
)
}
range
Price
range.tsx
import { Slider } from 'topclassui/slider'
/** A pair gives two thumbs, named Minimum and Maximum, that cannot cross. The form receives the name twice. */
export default function Demo() {
return (
<div className="grid justify-items-start gap-2">
<span id="slider-range-label" className="text-sm text-body">Price</span>
<Slider aria-labelledby="slider-range-label" name="price" defaultValue={[20, 80]} step={5} />
</div>
)
}
show-value
show-value.tsx
import { Slider } from 'topclassui/slider'
/** showValue writes the value after the track, in the provider's digits; format shapes it, here as dollars. */
export default function Demo() {
return (
<div className="grid justify-items-start gap-4">
<Slider aria-label="Brightness" defaultValue={40} showValue />
<Slider
aria-label="Budget"
defaultValue={[200, 800]}
min={0}
max={1000}
step={50}
format={{ style: 'currency', currency: 'USD', maximumFractionDigits: 0 }}
showValue
/>
</div>
)
}
form
form.tsx
import { Button } from 'topclassui/button'
import { Slider } from 'topclassui/slider'
/** The slider carries the name and the default: it sends volume=60, before any script runs and after. */
export default function Demo() {
return (
<form className="grid justify-items-start gap-3">
<span id="slider-form-label" className="text-sm text-body">Volume</span>
<Slider aria-labelledby="slider-form-label" name="volume" defaultValue={60} step={5} />
<Button type="submit">Save</Button>
</form>
)
}
sizes
sizes.tsx
import { Slider } from 'topclassui/slider'
/** The five sizes. Each is as wide as an Input of its size, and each thumb stays 24 px, and 44 px under a finger. */
export default function Demo() {
return (
<div className="grid justify-items-start gap-4">
<Slider size="xs" aria-label="Extra small" defaultValue={20} />
<Slider size="sm" aria-label="Small" defaultValue={40} />
<Slider size="md" aria-label="Medium" defaultValue={50} />
<Slider size="lg" aria-label="Large" defaultValue={60} />
<Slider size="xl" aria-label="Extra large" defaultValue={80} />
</div>
)
}
بالعربية، من اليمين إلى اليسار
مستوى الصوتنطاق السعر
rtl.tsx
import { TopClassProvider } from 'topclassui/provider'
import { Slider } from 'topclassui/slider'
/** Arabic, inside TopClassProvider as the root layout would mount it. The track runs from right to left: 30 sits 30%
* in from the right, ArrowLeft raises the value, and the two thumbs of the range are named in Arabic. */
export default function Demo() {
return (
<TopClassProvider direction="rtl" locale="ar">
<div dir="rtl" lang="ar" className="grid justify-items-start gap-3">
<span id="slider-rtl-volume" className="text-sm text-body">مستوى الصوت</span>
<Slider aria-labelledby="slider-rtl-volume" name="volume" defaultValue={30} showValue />
<span id="slider-rtl-price" className="text-sm text-body">نطاق السعر</span>
<Slider aria-labelledby="slider-rtl-price" name="price" defaultValue={[20, 80]} />
</div>
</TopClassProvider>
)
}
الخصائص
لوحة المفاتيح وإمكانية الوصول
- سمِّه بـ
aria-labelأوaria-labelledby: ما يأخذ التركيز هو حقل نطاق داخل المقبض. ويُسمّى مقبضا النطاق «الحد الأدنى» و«الحد الأقصى». - لكل سحب طريق بلوحة المفاتيح (WCAG 2.5.7). والمقبض هو الهدف: 24px، و44px تحت مؤشر لمس.
invalidيضبط aria-invalid على المجموعة وعلى كل حقل نطاق؛ ويتحوّل الملء والمقبض والخط حول المسار إلى لون الخطر.
من اليمين إلى اليسار
تحت TopClassProvider باتجاه من اليمين إلى اليسار يبدأ المسار من اليمين: ArrowLeft يضيف خطوة، والقيمة 30 تقع على بعد 30% من اليمين.
الخادم والمتصفح
مكوّن متصفح: يُعرض على الخادم ثم يُرطَّب في المتصفح.
الملفات: index.tsx, client.tsx.
على الشارة: client - الحجم لم يُقَس بعد.