Przejdź do treści

Slider

Stabilny

Wybiera wartość lub zakres wartości przez przeciąganie wzdłuż toru — sprawdza się najlepiej, gdy przybliżone położenie liczy się bardziej niż dokładna liczba.

Anatomia

  1. 1TorPełny zakres wartości w neutralnym odcieniu.
  2. 2ZakresWybrana część zakresu, wypełniona kolorem marki — od początku toru albo między dwoma uchwytami.
  3. 3UchwytElement, który się przeciąga. To on przyjmuje fokus i ma obszar klikalny 32 px; dodaj drugi uchwyt, aby wybierać zakres.

Instalacja

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/slider.json

Użycie

import { Slider } from "@/components/ui/slider"
<Slider defaultValue={50} aria-label="Volume" />

Przekaż liczbę, aby uzyskać jeden uchwyt, albo tablicę, aby uzyskać zakres — po jednym uchwycie na każdą wartość. Wypełniona część toru i obramowanie uchwytu mają kolor marki.

Przykłady

Z etykietą i wartością

Pokazuj bieżącą wartość obok etykiety zawsze, gdy liczba ma znaczenie. Nazwij suwak przez aria-labelledby wskazujące widoczną etykietę; nazwa trafia do uchwytu, bo to na nim faktycznie ustawia się fokus czytnika ekranu.

80%

Zakres

Wartość w postaci tablicy renderuje dwa uchwyty. minStepsBetweenValues nie pozwala im na siebie nachodzić, a getAriaLabel nadaje każdemu uchwytowi własną nazwę — Cena minimalnaCena maksymalna — żeby nie były odczytywane jako dwa identyczne suwaki.

240 USD760 USD

Kroki

step przyciąga wartość do wielokrotności kroku. Przy kilku dyskretnych wartościach narysuj pod torem etykiety podziałki i opisz wartość słowami przez getAriaValueText — 3 repliki mówią więcej niż samo 3.

3 × 1 vCPU

Pionowy

orientation="vertical" pasuje do kontrolek, które kojarzą się z wysokością — poziomów, korektorów, powiększenia. Wysokość suwaka nadaj przez jego kontener.

60 Hz
230 Hz
910 Hz
3,6 kHz
14 kHz

Wyłączony

Wyłączony suwak nadal pokazuje wartość, choć jest półprzezroczysty, i nie reaguje na interakcję. Jeśli powód nie jest oczywisty, wyjaśnij go obok.

Wytyczne

Kiedy używać

  • Gdy względne położenie liczy się bardziej niż precyzja: głośność, krycie, powiększenie, przedział cenowy.
  • Gdy ludziom pomaga widok wartości na tle całego zakresu.

Kiedy nie używać

  • Gdy liczy się dokładna liczba — użyj komponentu Inputtype="number" albo połącz z nim suwak.
  • Przy bardzo dużych zakresach, w których jeden piksel obejmuje wiele wartości — użyj pola liczbowego.
  • Przy kilku nazwanych opcjach — użyj komponentu Radio Group lub Toggle Group.

Pokazuj wartość

Suwak bez widocznej wartości każe ludziom zgadywać. Pokaż wartość obok etykiety, sformatuj ją ($240, 80%) propem format albo własną funkcją formatującą i aktualizuj ją na żywo podczas przeciągania.

Krycie80%
Dobrze.Bieżąca wartość jest widoczna i sformatowana.
Krycie
Źle.Bez widocznej wartości ludzie mogą tylko szacować, co wybrali.

Zatwierdzaj raz, nie zasypuj żądaniami

onValueChange wywołuje się bez przerwy podczas przeciągania — używaj go do aktualizowania widoku. Do zapisu lub pobierania danych po zakończeniu przeciągania użyj onValueCommitted, żeby jedna zmiana nie wysłała pięćdziesięciu żądań.

Dostępność

Każdy uchwyt zawiera natywny <input type="range">, więc suwak od razu działa z czytnikami ekranu, sterowaniem głosowym i funkcjami formularzy w przeglądarce.

KlawiszDziałanie
Tab
Przenosi fokus na następny uchwyt. Każdy uchwyt zakresu ma własne miejsce w kolejności tabulacji.
Zwiększa wartość o jeden krok.
Zmniejsza wartość o jeden krok.
PageUpShift
Zwiększa wartość o duży krok (domyślnie 10).
PageDownShift
Zmniejsza wartość o duży krok.
HomeEnd
Ustawia wartość minimalną lub maksymalną.
  • Nadaj nazwę. Użyj aria-labelledby wskazującego widoczną etykietę albo aria-label. prfct przekazuje nazwę do uchwytów; w zakresie nazwij każdy uchwyt przez getAriaLabel.
  • Opisz wartość. format kształtuje zarówno widoczną, jak i odczytywaną wartość; getAriaValueText nadpisuje to, co jest odczytywane, gdy słowa wyrażają wartość lepiej niż liczby.
  • Krawędzie. Uchwyt ma obramowanie 2 px w kolorze marki, które zapewnia mu kontrast co najmniej 3:1 na każdej powierzchni (WCAG 1.4.11). Tor nie jest potrzebny do rozpoznania kontrolki, więc może pozostać stonowany.
  • Rozmiar celu. Uchwyty mają 16 px, a ich przezroczysty obszar klikalny — 32 × 32 px; po najechaniu i podczas przeciągania lekko się powiększają.

Dokumentacja API

Slider

Renderuje <div role="group"> z torem i jednym uchwytem na każdą wartość. Przyjmuje wszystkie propsy Slider.Root z Base UI.

PropTypDomyślnie
value

Wartość albo wartości zakresu. W trybie kontrolowanym używaj razem z onValueChange.

number | number[]Brak wartości domyślnej
defaultValue

Wartość początkowa w trybie niekontrolowanym. Tablica tworzy zakres.

number | number[]Brak wartości domyślnej
onValueChange

Wywoływana bez przerwy, gdy wartość się zmienia.

(value, details) => voidBrak wartości domyślnej
onValueCommitted

Wywoływana raz, gdy kończy się przeciąganie lub naciśnięcie klawisza — używaj jej do zapisu.

(value, details) => voidBrak wartości domyślnej
min

Najmniejsza wartość.

number0
max

Największa wartość.

number100
step

Krok — wartości są przyciągane do jego wielokrotności.

number1
largeStep

Duży krok — dla klawiszy Page Up/Down i Shift+strzałka.

number10
minStepsBetweenValues

Minimalna odległość między uchwytami zakresu, w krokach.

number0
orientation

Kierunek toru.

"horizontal" | "vertical""horizontal"
format

Formatuje wartość dla technologii wspomagających i Slider.Value.

Intl.NumberFormatOptionsBrak wartości domyślnej
aria-label

Dostępna nazwa przekazywana do uchwytów.

stringBrak wartości domyślnej
aria-labelledby

Id widocznej etykiety, przekazywany do uchwytów.

stringBrak wartości domyślnej
getAriaLabel

Nadaje osobną nazwę każdemu uchwytowi zakresu.

(index: number) => stringBrak wartości domyślnej
getAriaValueText

Własny tekst, który czytnik ekranu odczytuje jako wartość.

(formatted, value, index) => stringBrak wartości domyślnej
thumbCollisionBehavior

Co się dzieje, gdy uchwyty zakresu się spotkają.

"push" | "swap" | "none""push"
name

Wysyła wartość z formularzem.

stringBrak wartości domyślnej
disabled

Ignoruje interakcję i przygasza suwak.

booleanfalse