Saltar al contenido
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
Primeros pasosWebReactSwiftUIJetpack ComposeFlutterReact NativePreajustesTu propio sistema de diseñoUsar Tanrei con agentes de IAMarcaTokens de diseñoSistemas de diseño y personalizaciónTheme StudioColorTipografíaIconosFormaElevaciónMovimientoEstados de interacciónComportamientoDiseño de páginaAccesibilidadTextosTokens de colorTokens de la escala tipográficaTokens de formaTokens de elevaciónTokens de movimientoTokens de estadoTokens de espacio y de medidaComponentesBotónBotón de acción principalBotón segmentadoGrupo de botonesBotón con menúBarra de herramientasBotón de copiarCasilla de verificaciónBotón de opciónInterruptorChipMenúControl deslizanteCampo de control deslizanteCalendarioDateTimePickerGrupo de camposGrupo de botones de opciónGrupo de casillas de verificaciónSelectCampo de selecciónBarra de menúsSubida de archivosSelector de archivos AvanzadoZona de soltar archivosEntrada de texto AvanzadoCampo de textoCampo de chipsCampoCuadro combinado AvanzadoCampo de cuadro combinadoEntrada numérica AvanzadoCampo numéricoEntrada de color AvanzadoCampo de colorEntrada de código de un solo uso AvanzadoCampo de código de un solo usoEntrada de texto incrustada AvanzadoCuadro de redacción de chatTarjetaDivisorCapa modal AvanzadoDiálogoListaFila de listaHoja inferiorHoja lateralCarruselBloque de códigoTablaPopoverPasosAcordeónLista de descripcionesFiguraEstructura de la aplicaciónCabecera de páginaVista de árbolLínea de tiempoVista previa de imágenesTirador de tamañoMarco redimensionableÁrea de desplazamientoInsigniaIndicador de progresoMedidorContador animadoIndicador de cargaSnackbarTooltipAtajo de tecladoTagCódigo en líneaCalloutAvatarEstado vacíoGrupo de tagsEsqueletoElemento de archivoMuestraTexto en marquesinaPestañasVista de pestañasBarra de la aplicaciónBarra de navegaciónPanel de navegaciónBúsquedaEnlacePaginaciónEnlaces anterior y siguienteIndicador de pasosRuta de navegaciónTabla de contenidoTarjeta de enlaceMenú FABEstadoCómo se construye TanreiCómo contribuirLicencia y atribución
InicioComponentesControl deslizante

Control deslizante

Permite elegir un valor, o un intervalo de valores, arrastrando un tirador a lo largo de una pista, de forma continua o por pasos.

content_copyVer en Markdown
Categoría
Selección
Tokens
comp.slider
Nivel
Base
Se usa en
Slider field

Descripción general

Web
tanrei-slider
schedule
SwiftUI
TanreiSlider
schedule
Jetpack Compose
TanreiSlider
schedule
Flutter
TanreiSlider
schedule
React Native
Slider
schedule

Generado a partir de docs/status/status.json, specs/slider.spec.json

Continuo, por pasos con puntos de parada y un intervalo

Área de pruebas

Cada control fija una propiedad del componente en vivo, y el código cambia con él. La dirección de la página guarda lo que fijes, así que un enlace la abre tal como la dejaste. El código es para la web. Para las demás plataformas, consulta «Correspondencia de nombres por plataforma».

Uso

Un control deslizante elige un valor entre min y max (0 y 100 de forma predeterminada). Con range tiene dos tiradores y elige el tramo que va de startValue a value. Con step en 0 es continuo; por encima de 0, los valores se ajustan a min más múltiplos enteros de step.

El control deslizante no dibuja ninguna etiqueta. label le da nombre para la tecnología de apoyo, y una etiqueta visible es un texto tuyo junto al control, con las mismas palabras. Un intervalo necesita además startLabel para su tirador de inicio.

Dos eventos informan de un cambio. input se emite con cada cambio mientras la persona arrastra, y change se emite una vez cuando el cambio ha terminado: acabó la pulsación, o se pulsó una tecla o se hizo un ajuste desde una tecnología de apoyo. Un valor que defines tú no emite ninguno de los dos. Cada plataforma los nombra a su manera: onValueChange y onValueChangeFinished en Compose, onChanged y onChangeEnd en Flutter, onValueChange y onSlidingComplete en React Native y, en SwiftUI, el binding y onCommit.

La revisión que dio al control deslizante su tirador redondo, y el examen posterior que hizo más grueso su anillo, solo cambiaron su aspecto, así que todos los ejemplos siguientes están al día. La web dibuja el aspecto actual. SwiftUI, Compose, Flutter y React Native van rezagados: todavía dibujan el aspecto anterior, un tirador redondo y macizo con las pistas cortadas en su borde y un solo tamaño de punto de parada para todos los tamaños, hasta que se pongan al día.

<!-- El control deslizante no dibuja ninguna etiqueta: pon tu etiqueta visible a su lado, con las mismas palabras. -->
<tanrei-slider name="volume" label="Volumen" value="40" value-indicator="active"></tanrei-slider>

<!-- Por pasos, con un punto en cada paso. -->
<tanrei-slider label="Brillo" value="30" step="10" stops></tanrei-slider>

<!-- Un intervalo envía start-value y después value, con el mismo nombre. -->
<tanrei-slider name="price" range min="0" max="500" step="10" start-value="100" value="300"
  label="Precio máximo" start-label="Precio mínimo"></tanrei-slider>

<script type="module">
  import '@tanrei/web/components/slider';
  const volume = document.querySelector('[name="volume"]');
  // El elemento define su propio valor antes de emitir input y change.
  volume.addEventListener('input', () => preview(volume.value));
  volume.addEventListener('change', () => save(volume.value));
</script>
import { Slider } from '@tanrei/react';

<Slider
  label="Volumen"
  value={volume}
  valueIndicator="active"
  onInput={(e) => setVolume(e.currentTarget.value)}
  onChange={(e) => save(e.detail.value)}
/>

<Slider
  range
  min={0}
  max={500}
  step={10}
  startValue={minPrice}
  value={maxPrice}
  label="Precio máximo"
  startLabel="Precio mínimo"
  onInput={(e) => setPrices(e.currentTarget.startValue, e.currentTarget.value)}
/>
import Tanrei

// Cada cambio escribe en el binding; onCommit se ejecuta cuando un cambio ha terminado.
TanreiSlider("Volumen", value: $volume, in: 0...100, onCommit: save)

TanreiSlider("Brillo", value: $brightness, in: 0...100, step: 10)

// Un intervalo es el inicializador cuyo binding es un ClosedRange: lowerBound es el tirador de inicio.
TanreiSlider("Precio máximo", startLabel: "Precio mínimo", value: $prices, in: 0...500, step: 10)
import io.github.chnotchy.tanrei.components.TanreiSlider

// Elevación de estado: mueve value desde onValueChange.
TanreiSlider(
    value = volume,
    onValueChange = { volume = it },
    contentDescription = "Volumen",
    onValueChangeFinished = ::save, // lleva el valor, a diferencia del de foundation
)

// step es un tamaño, no el número de pasos de Material.
TanreiSlider(value = brightness, onValueChange = { brightness = it }, step = 10f, contentDescription = "Brillo")

// Un intervalo es la sobrecarga cuyo valor es un ClosedFloatingPointRange.
TanreiSlider(
    value = prices,
    onValueChange = { prices = it },
    valueRange = 0f..500f,
    step = 10f,
    contentDescription = "Precio máximo",
    startContentDescription = "Precio mínimo",
)
import 'package:tanrei/tanrei.dart';

TanreiSlider(
  value: volume,
  onChanged: (double value) => setState(() => volume = value), // null lo deshabilita
  onChangeEnd: save,
  semanticLabel: 'Volumen',
);

// step es un tamaño, no las divisiones de Material.
TanreiSlider(value: brightness, step: 10, onChanged: (double value) => setState(() => brightness = value), semanticLabel: 'Brillo');

TanreiSlider.range(
  start: minPrice,
  end: maxPrice,
  max: 500,
  step: 10,
  onChanged: (double start, double end) => setState(() {
    minPrice = start;
    maxPrice = end;
  }),
  semanticLabel: 'Precio máximo',
  startSemanticLabel: 'Precio mínimo',
);
import { Slider } from '@tanrei/react-native';

<Slider value={volume} onValueChange={setVolume} onSlidingComplete={save} accessibilityLabel="Volumen" />

<Slider value={brightness} step={10} stops onValueChange={setBrightness} accessibilityLabel="Brillo" />

// Un intervalo: ambos callbacks reciben (value, startValue).
<Slider
  range
  minimumValue={0}
  maximumValue={500}
  step={10}
  startValue={minPrice}
  value={maxPrice}
  onValueChange={(value, startValue) => setPrices(startValue, value)}
  accessibilityLabel="Precio máximo"
  startAccessibilityLabel="Precio mínimo"
/>

Especificaciones

Tamaños, centrado, indicador de valor, vertical y deshabilitado

En el sistema predeterminado, el tirador es un anillo: un círculo de 20 relleno con el color de la superficie, dentro de un contorno del color de la pista activa. El contorno mide 3 de ancho y se dibuja por dentro del borde del círculo, así que no cambia el tamaño del tirador: deja un disco de 14 del color de la superficie, y un contorno más ancho dejaría uno más pequeño. La pista y la pista activa pasan por debajo del tirador y se encuentran en su centro, de modo que la pista activa se lee como una sola línea que termina en el anillo. El tirador mide 20 en todos los tamaños, sobre pistas de 4, 6 y 8.

Los puntos de parada, y el punto que marca el final del recorrido, tienen la mitad del grosor de la pista: 2, 3 y 4 en small, medium y large. El indicador de valor se sitúa un poco por encima de la parte superior del anillo, centrado en él. Deshabilitado, el anillo conserva su relleno, y su contorno se atenúa junto con la pista activa.

Un sistema de diseño puede dibujar el tirador a su manera con los mismos tokens. Con un contorno de 0, el tirador es una forma maciza y, con una separación entre las pistas y el tirador, las pistas se detienen antes de llegar a él y se redondean ahí. m3-like dibuja así la barra vertical de Material.

Anatomía

Anatomía

Dibujado sobre el fixture continuous, tal como lo dibuja el paquete web.
Parte Descripción
1 track The line the handle travels along: the whole range from min to max. Drawn in the track color where it is not active.
2 active-track The part of the track from the origin to the value, or between the two handles of a range, drawn over the track.
3 handle The part the person drags, one per value: in Tanrei a circle (its width along the track equals its height across it) with a fill and an outline of its own, a narrow upright bar where a system says so.
4 handle-outline · opcional The ring drawn over the handle's fill, inside its edge, so the handle keeps its size however wide the ring is: a wider ring leaves a smaller disc of fill. None where its width is 0.
5 container The round state layer centered on a handle, moving with it. It carries hover, focus and press and is invisible at rest.
6 stop-indicator · opcional A dot on the track's midline, half the track's thickness across in Tanrei: at an end of the handle's travel that lies on the track, and at every step while stops is true.
7 value-indicator · opcional A small label beside a handle that shows its value while the handle is pressed or focused, or always.
8 focus-ring Gap-then-ring indicator around the handle that has keyboard focus.

Medidas

Medidas

Longitud Token Valor (px)
handle height tanrei.comp.slider.handle.height.small 20
container size tanrei.comp.slider.container.size 40
Dibujado sobre el fixture continuous, tal como lo dibuja el paquete web.

Propiedades

Propiedad Tipo Valor predeterminado Descripción
size small | medium | large "small" The track's weight and the stop dots' size (and, where a system says so, the handle's height). Small is the everyday slider; medium and large give a prominent control (a volume or brightness slider) more weight. The hit area always meets the minimum target. A design system may add values.
orientation horizontal | vertical "horizontal" Horizontal runs from the inline start (min) to the inline end (max); vertical runs from the bottom (min) to the top (max).
value number 0 The value of the only handle, or of a range's end handle.
startValue number 0 The value of a range's start handle. Ignored while range is false.
range boolean false Draws two handles, choosing the range from startValue to value (a price filter).
min number 0 The lowest value, at the track's start.
max number 100 The highest value, at the track's end.
step number 0 0 is continuous. Above 0 the slider is discrete: its values are min plus whole multiples of step, up to max.
origin number null Where the active track starts. Null starts it at min. A value inside the range makes a centered slider (a balance control) whose active track grows toward either side. Ignored while range is true.
stops boolean false Draws a stop dot at every value a discrete slider can take. Meant for a few steps; ignored while step is 0.
valueIndicator none | active | always "none" Whether a handle shows its value beside it: never, while it is pressed or has keyboard focus, or all the time.
disabled boolean false Prevents interaction and removes the handles from the focus order.
label string "" Names the slider (a range's end handle) for assistive technology. Never drawn: a visible label is the product's text next to the slider, in the same words. Required.
startLabel string "" Names a range's start handle ("Minimum price"). Required while range is true.
valueText string "" The value as words ("40 %", "3 stars"), spoken and shown by the value indicator in place of the number. For a range, the end handle's.
startValueText string "" The start handle's valueText, for a range.

Eventos

Evento Descripción
input The person changed a value; carries value and, for a range, startValue. Emitted for every change during a drag, not when the product sets a value.
change The person finished changing a value (the press ended, or a key or assistive-technology adjustment was made); carries value and, for a range, startValue. Always after the input it follows.

Estados

Comportamiento

Requisitos en formato EARS. Cada implementación de plataforma se prueba contra estos identificadores. El texto de los requisitos se muestra tal como está en la especificación, en inglés.

ID Requisito
SLD-1 THE slider SHALL keep value (and, while range is true, startValue) between min and max; WHILE step is greater than 0 it SHALL take only min plus whole multiples of step that do not exceed max, snapping to the nearest, and WHILE step is 0 any value between min and max.
SLD-2 WHEN the person presses the slider by pointer or touch — the track, a handle, or the space around them — THE slider SHALL move the handle nearer the press (for a range whose handles meet, the one that can move toward the press) to the value under it and, WHILE the press moves, SHALL make the handle follow it along the track, clamped to the handle's range and snapped to step; it SHALL emit input once for each value change and, WHEN the press ends with a value other than the one it started with, change once after the last input. On touch the handle SHALL move once the press has travelled along the track by the platform's touch slop, or when a press that did not move ends; a press that first travels across the track by the slop SHALL be left to an enclosing scroll view and SHALL change nothing.
SLD-3 WHILE a handle has keyboard focus THE slider SHALL increase its value by one keyboard step with Right Arrow or Up Arrow and decrease it with Left Arrow or Down Arrow (Right and Left swapped in a right-to-left horizontal slider), by ten keyboard steps with Page Up and Page Down, and set it to the lowest and highest value it can take with Home and End; the keyboard step is step, or one hundredth of max − min while step is 0. Each key press that changes the value SHALL emit input and then change once; a key press that changes nothing SHALL emit nothing.
SLD-4 WHEN assistive technology increments or decrements a handle (a vertical swipe on an adjustable element, the platform's increment and decrement actions) THE slider SHALL change its value by one keyboard step, and WHEN it sets a value directly where the platform allows that THE slider SHALL clamp and snap it; either SHALL emit input and then change once.
SLD-5 WHILE range is true THE slider SHALL draw a start handle at startValue and an end handle at value, SHALL stop each handle at the other's value so that the two may meet but never cross, and SHALL make each handle its own Tab stop, the start handle first, and its own element for assistive technology.
SLD-6 WHILE range is false THE slider SHALL draw the active track between origin (min while origin is null, and origin clamped to the range) and value, on whichever side of origin value lies; WHILE range is true it SHALL draw the active track between startValue and value.
SLD-7 THE slider SHALL be as long along its axis as its layout gives it and, across it, as thick as the larger of comp.slider.container.size and comp.slider.handle.height.small for size small (and so on for each size); it SHALL extend its hit area across its axis to sys.target.touch for touch input and sys.target.pointer for fine pointers without changing that size (a platform that cannot tell the input type SHALL use sys.target.touch), the whole slider being the hit area, and a handle drawn smaller than the target SHALL NOT make the hit area smaller. It SHALL draw the track comp.slider.track.thickness.small thick for size small (and so on), centered across the axis and inset from each end of the slider by half of comp.slider.container.size, so that a handle and its state layer stay inside the slider at min and max; a handle's center SHALL travel between the two points half the track's thickness in from the track's ends, concentric with its rounded ends.
SLD-8 THE slider SHALL draw the track in comp.slider.standard.track.color and the active track over it in comp.slider.standard.active-track.color. WHILE comp.slider.track.gap is 0 the track and the active track SHALL run under each handle and meet at its center, so that nothing lies between the active track and the handle; WHILE it is above 0 they SHALL stop that far from each side of each handle, measured from the handle's edge. The pieces SHALL be rounded by comp.slider.track.shape.small for size small (and so on), clamped to half the thickness, at the track's two ends and, WHILE comp.slider.track.gap is above 0, beside a handle; they SHALL be square where two pieces meet (under a handle while the gap is 0, and at an origin inside the travel). It SHALL draw each handle centered on the track's midline, comp.slider.standard.handle.width along the axis and comp.slider.handle.height.small across it for size small (and so on), rounded by comp.slider.handle.shape clamped to half its smaller side, painted as SLD-24 says, above the tracks — each part from the tokens of the state SLD-11 names.
SLD-9 THE slider SHALL draw a dot of comp.slider.stop-indicator.size.small for size small (and so on) centered on the track's midline at each end of the handles' travel that lies on the track rather than on the active track, and WHILE stops is true and step is greater than 0 also at every value the slider can take; a dot SHALL be drawn in comp.slider.standard.stop-indicator.color where it lies on the track and in comp.slider.standard.active-stop-indicator.color where it lies on the active track, SHALL NOT be drawn where a handle or its track gap covers it, and a size of 0 SHALL draw none.
SLD-10 THE slider SHALL draw each handle's container, a shape of comp.slider.container.size on each side with corners comp.slider.container.shape, centered on the handle and moving with it, filled with comp.slider.standard.container.color from the handle's state, behind the handle and above the tracks; it may extend beyond the track without affecting layout, and a size of 0 SHALL draw none.
SLD-11 WHILE a handle is hovered, keyboard-focused or pressed THE slider SHALL render that handle and its container from the component tokens of that handle's highest-precedence active state, with precedence pressed over focused over hovered, and the tracks, stop dots and opacity from the highest-precedence state of any of its handles; a handle is hovered while a fine pointer is over the slider and that handle is the one a press there would move; focus gained by pointer or touch SHALL NOT select the focused state. WHEN the colors change between states THE slider SHALL animate them over comp.slider.motion.state-duration with comp.slider.motion.state-easing, and at once where motion is reduced.
SLD-12 WHEN a handle receives keyboard focus THE slider SHALL show the focus ring around that handle without animation; focus gained by pointer or touch SHALL NOT show it.
SLD-13 WHEN the slider is pressed by pointer or touch THE slider SHALL show the pressed state of the handle the press moves without delay, SHALL keep it for as long as the press lasts, and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner.
SLD-14 WHILE pressed THE slider SHALL answer as sys.behavior.pressed-feedback names: overlay applies the pressed tokens to the whole container at once; ripple grows the pressed state layer from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole control and draws no state layer; none draws no answer to the press. Under ripple and dim only the container color stays with the state under the press; handle, tracks, stop dots, opacity and shape still come from the pressed tokens. Under none every part stays with the state under the press. The ripple grows over comp.slider.motion.feedback-duration with comp.slider.motion.state-easing, fades over comp.slider.motion.state-duration with comp.slider.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced. The slider's point of contact is the pressed handle's center, because the handle moves to the press.
SLD-15 THE slider SHALL ease its container, handle and track corners by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0) and show its keyboard focus as sys.behavior.focus-style names (ring or glow); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
SLD-16 WHEN a value changes by a key, by assistive technology, by a press on the track that did not drag, or because the product set it, THE slider SHALL move the handle and the active track to it over comp.slider.motion.value-duration with comp.slider.motion.value-easing; WHILE a press drags a handle, the handle SHALL follow the press without delay; WHERE motion is reduced every change SHALL be shown at once. WHEN the product sets value or startValue THE slider SHALL NOT emit input or change.
SLD-17 WHILE valueIndicator is always, or valueIndicator is active and a handle is pressed or has keyboard focus, THE slider SHALL draw that handle's value indicator comp.slider.value-indicator.offset beyond the handle's outer edge across the axis — above the handle in a horizontal slider, at its inline start in a vertical one; for a round handle beyond the top of its circle, outline included, which lies half of comp.slider.handle.height.small from the track's midline for size small (and so on) — with its center on the handle's center along the axis, shifted along the axis only as far as it must to stay inside the window: the handle's value text on one line in comp.slider.value-indicator.label.typescale and comp.slider.value-indicator.label.color, centered in a container of comp.slider.value-indicator.container.color at least comp.slider.value-indicator.container.height high and as wide as the text plus comp.slider.value-indicator.container.padding-inline on each side but never narrower than it is high, rounded by comp.slider.value-indicator.container.shape. The value indicator SHALL be drawn above neighbouring content and above the handle and its container, without affecting layout or being clipped by the slider, SHALL take no focus and no input (a read overlay), SHALL be hidden from assistive technology, and SHALL fade in and out over comp.slider.motion.state-duration with comp.slider.motion.state-easing, at once where motion is reduced.
SLD-18 THE slider SHALL give each handle a value text: valueText for the only handle and a range's end handle, startValueText for a range's start handle; or, while that is empty, what the product's own function writes for that handle's value, WHERE the product gave the slider such a function in the platform's idiom; or, with neither, the value formatted as a number in the platform's locale with as many fraction digits as the keyboard step has, at most two; the value indicator SHALL show it and assistive technology SHALL read it as the handle's value. THE slider SHALL ask the function again at every change of a value and WHEN the function itself changes, SHALL take an empty answer as no answer, and SHALL announce nothing for a change of the words alone.
SLD-19 THE slider SHALL expose each handle as a slider (the adjustable trait on Apple platforms) named by label, or by startLabel for a range's start handle, with its value, its value text, the lowest and highest value it can take (for a range, bounded by the other handle), its orientation and its disabled state; the tracks, stop dots, container and value indicator SHALL be hidden from assistive technology. WHILE a handle's label (label, or startLabel for a range's start handle) is not empty THE slider SHALL expose it as that handle's accessible name, over a name the product gives the slider on the element (aria-label or aria-labelledby). WHILE label is empty and the product gives the slider a name of its own on the element — aria-label, or aria-labelledby naming an element — THE slider SHALL expose that name on each handle whose own label is empty. WHILE label is empty and the product gives it none, or range is true and startLabel is empty, THE slider SHALL still render, and in debug builds report that a handle has no accessible name: one name of the product's does not tell a range's two handles apart.
SLD-20 WHILE disabled is true THE slider SHALL NOT change a value or emit input or change, SHALL NOT be focusable, SHALL show no value indicator, SHALL expose the disabled state to assistive technology, and SHALL render its container, handles, tracks, stop dots and opacity from the disabled component tokens.
SLD-21 WHILE orientation is vertical THE slider SHALL run its track from the bottom (min) to the top (max), be as tall as its layout gives it, and lay out every part SLD-7 to SLD-17 name turned a quarter turn; WHEN the layout direction is right-to-left THE slider SHALL run a horizontal track from the right (min) to the left (max), mirroring the active track, the stop dots and the arrow keys (SLD-3), and SHALL NOT mirror a vertical slider. WHILE a value indicator is drawn in a right-to-left layout THE slider SHALL keep it centred on its handle and shift it along the axis only as far as it must to stay inside the window, away from whichever edge of the window it would cross, as in left-to-right (SLD-17): the shift is physical and is not mirrored.
SLD-22 IF value, startValue or origin lies outside min and max, or off a step, THE slider SHALL draw and expose it clamped and snapped without emitting input or change; IF startValue is greater than value while range is true THE slider SHALL draw both handles at value; IF max is not greater than min THE slider SHALL draw its handles at the track's start and take no input; IF step is below 0 THE slider SHALL treat it as 0. In debug builds it SHALL report each of these.
SLD-23 WHEN size names a value that the active design system does not have, or orientation or valueIndicator a value the component does not define, THE slider SHALL render with the default value (small, horizontal, none), and in debug builds report the unknown value.
SLD-24 THE slider SHALL fill the whole shape of each handle with comp.slider.standard.handle.color and draw the handle's outline over the fill, comp.slider.handle-outline.width wide inside the handle's edge, in comp.slider.standard.handle-outline.color, so that the outline never changes the handle's width or height and a width of 0 draws none; it SHALL raise the handle by comp.slider.standard.handle.elevation. The parts under a handle (the tracks where they meet, a stop dot, the container) SHALL show through it only as far as its fill is translucent.
SLD-25 THE slider SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the slider is shown THE slider SHALL draw itself for the new direction at once, without a motion of its own, keeping its values and its focus, each value indicator placed again by the new direction.
SLD-26 THE slider SHALL lay out a handle's value text in its value indicator as text of its own direction, isolated from the text around it: each takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word, a number with its sign or unit, a telephone number and an address keep their own order in a right-to-left layout and reorder nothing beside them; THE slider SHALL still place the indicator and align its lines by the layout direction, not by the text's own.
SLD-27 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE slider SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on the element that carries its role (every handle carries them) — an id reference by the elements it names in the host's tree or a tree around it, an error message as part of the description while the slider is invalid — except those the slider owns (aria-disabled), which it SHALL move and not expose. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE slider SHALL take it off that element. WHEN the product sets an aria- attribute the slider owns THE slider SHALL report it in debug builds.

Correspondencia de nombres por plataforma

Paridad no significa API idénticas. Cada plataforma expresa el mismo contrato con su propio estilo.

Especificación Web SwiftUI Jetpack Compose Flutter React Native
Componente tanrei-slider TanreiSlider TanreiSlider TanreiSlider Slider
size · Propiedad size size size size size
orientation · Propiedad orientation orientation orientation orientation orientation
value · Propiedad value value value value value
startValue · Propiedad startValue value value start startValue
range · Propiedad range value value range range
min · Propiedad min bounds valueRange min minimumValue
max · Propiedad max bounds valueRange max maximumValue
step · Propiedad step step step step step
origin · Propiedad origin origin origin origin origin
stops · Propiedad stops showsStops showStops showStops stops
valueIndicator · Propiedad valueIndicator valueIndicator valueIndicator valueIndicator valueIndicator
disabled · Propiedad disabled disabled enabled onChanged disabled
label · Propiedad label label contentDescription semanticLabel accessibilityLabel
startLabel · Propiedad startLabel startLabel startContentDescription startSemanticLabel startAccessibilityLabel
valueText · Propiedad valueText valueText stateDescription semanticValue valueText
startValueText · Propiedad startValueText startValueText startStateDescription startSemanticValue startValueText
input · Evento input value onValueChange onChanged onValueChange
change · Evento change onCommit onValueChangeFinished onChangeEnd onSlidingComplete
Notas Attributes are kebab-case (start-value, value-indicator, start-label, value-text, start-value-text). Each handle is an element with role="slider" and its aria-value attributes, aria-orientation and aria-label in the shadow root (not ElementInternals, which axe cannot see). Not <input type="range">: it has one handle, no gap, no stop dots, and its parts cannot be styled alike in every engine. The handle's outline is its box's border with box-sizing: border-box, over its background (the fill), so it keeps its width and height (SLD-24); while track.gap is 0 the two pieces of the tracks meet at the handle's center under it (SLD-8). Form-associated: it takes name and submits value (a range submits startValue, then value, under the same name), and it sets its own value and startValue before firing input and change, as a native control does. Snapshot harness: the stages of SLD-7. The product's function for a value's words (SLD-18) is formatValue, a property and never an attribute: ((value: number) => string) | null, null by default; it is asked for each handle at every change of a value and when the property itself is set. Slider idiom: TanreiSlider(_ label:, value: Binding<Double>, in bounds: ClosedRange<Double> = 0...100, step:); a range is the initializer whose value is a Binding<ClosedRange<Double>> (lower bound startValue, upper bound value) and which also takes startLabel. Every change writes the binding, which is the input event. onCommit is Tanrei's own parameter, called when a change is finished (SLD-2, SLD-3, SLD-4), as the text field's is; SwiftUI's onEditingChanged reports a drag's start and end, not a change. SwiftUI's own Slider is not used: its track and handle cannot take the tokens. Each handle is an adjustable element (.accessibilityAdjustableAction, .accessibilityValue); disabled follows .disabled(_:). Lagging: ships an earlier form of the slider — a solid round handle, tracks cut at the handle's edge (square there while track.gap is 0), one stop-dot size for every size. It does not draw yet: the handle's fill and outline (SLD-24), the tracks meeting under the handle while track.gap is 0 (SLD-8), the stop dot per size (SLD-9) and the value indicator's placement over a round handle (SLD-17). Not built on this platform yet: the product's function for a value's words (SLD-18) is a format: ((Double) -> String)? = nil parameter. Not built on this platform yet: the stage color a fixture's surface names, which the continuous-on-container-highest fixture draws on. Compose idiom (as Slider and RangeSlider): TanreiSlider(value: Float, onValueChange, modifier, enabled, valueRange: ClosedFloatingPointRange<Float> = 0f..100f, step: Float = 0f, onValueChangeFinished, …); a range is the overload whose value is a ClosedFloatingPointRange<Float> (start and end) and which also takes startContentDescription and startStateDescription. step is a size, not Material's count of steps. State hoisting: the caller moves value from onValueChange. enabled is the inverse flag. Each handle has Compose's slider semantics (progressBarRangeInfo and setProgress), with stateDescription as its value text. Lagging: ships an earlier form of the slider — a solid round handle with its shape clipped out of the tracks, one stop-dot size for every size. It does not draw yet: the handle's fill and outline (SLD-24), the tracks meeting under the handle while track.gap is 0 (SLD-8), the stop dot per size (SLD-9) and the value indicator's placement over a round handle (SLD-17). Not built on this platform yet: the product's function for a value's words (SLD-18) is a format: ((Float) -> String)? = null parameter. Not built on this platform yet: the stage color a fixture's surface names, which the continuous-on-container-highest fixture draws on. Flutter idiom (as Slider): TanreiSlider(value:, onChanged:, onChangeEnd:, min: 0, max: 100, step: 0, …), with step a size rather than Material's divisions; a range is the named constructor TanreiSlider.range(start:, end:, onChanged: (start, end) {…}, …), since Flutter's RangeValues belongs to Material. A null onChanged disables it. orientation is Flutter's Axis. Each handle is a Semantics(slider: true, value:, increasedValue:, decreasedValue:, onIncrease:, onDecrease:) node; the widgets library draws everything else. Lagging: ships an earlier form of the slider — a solid round handle, tracks cut at the handle's edge and rounded there (a notch between the round end and the handle), one stop-dot size for every size. It does not draw yet: the handle's fill and outline (SLD-24), the tracks meeting under the handle while track.gap is 0 (SLD-8), the stop dot per size (SLD-9) and the value indicator's placement over a round handle (SLD-17). Not built on this platform yet: the product's function for a value's words (SLD-18) is format: String Function(double)?. Not built on this platform yet: the stage color a fixture's surface names, which the continuous-on-container-highest fixture draws on. Controlled, in the community slider's idiom (value, minimumValue, maximumValue, step, onValueChange, onSlidingComplete), without depending on it: React Native has no slider in its core. A range adds range and startValue, and both callbacks receive (value, startValue). Each handle is a view with accessibilityRole="adjustable", accessibilityValue ({ min, max, now, text }) and the increment and decrement accessibility actions; the drag is a the touch responder props (onStartShouldSetResponder and the rest) that yields to an enclosing ScrollView as SLD-2 says. The arrow keys work where a hardware keyboard is attached, as the tabs row's do. Lagging: ships an earlier form of the slider — a solid round handle, tracks cut at the handle's edge and rounded there (a notch between the round end and the handle), one stop-dot size for every size. It does not draw yet: the handle's fill and outline (SLD-24), the tracks meeting under the handle while track.gap is 0 (SLD-8), the stop dot per size (SLD-9) and the value indicator's placement over a round handle (SLD-17). Not built on this platform yet: the product's function for a value's words (SLD-18) is a formatValue prop, (value: number) => string. Not built on this platform yet: the stage color a fixture's surface names, which the continuous-on-container-highest fixture draws on.

Tokens

Token Alias de Valor resuelto (claro)
--tanrei-comp-slider-container-shape sys.shape.corner.full 9999px
--tanrei-comp-slider-container-size — 40px
--tanrei-comp-slider-disabled-opacity — 1
--tanrei-comp-slider-focused-opacity — 1
--tanrei-comp-slider-handle-outline-width — 3px
--tanrei-comp-slider-handle-height-large — 20px
--tanrei-comp-slider-handle-height-medium — 20px
--tanrei-comp-slider-handle-height-small — 20px
--tanrei-comp-slider-handle-shape sys.shape.corner.full 9999px
--tanrei-comp-slider-hovered-opacity — 1
--tanrei-comp-slider-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-slider-motion-state-duration sys.motion.role.state.compact 200ms
--tanrei-comp-slider-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-slider-motion-value-duration sys.motion.role.selection.travel 250ms
--tanrei-comp-slider-motion-value-easing sys.motion.easing.spatial cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-slider-pressed-opacity — 1
--tanrei-comp-slider-standard-active-stop-indicator-color sys.color.on-primary #ffffff
--tanrei-comp-slider-standard-active-track-color sys.color.primary #1b1b1b
--tanrei-comp-slider-standard-container-color — #000000 · 0%
--tanrei-comp-slider-standard-disabled-active-stop-indicator-color — #ffffff
--tanrei-comp-slider-standard-disabled-active-track-color — #1b1b1b · 38%
--tanrei-comp-slider-standard-disabled-container-color — #000000 · 0%
--tanrei-comp-slider-standard-disabled-handle-outline-color — #1b1b1b · 38%
--tanrei-comp-slider-standard-disabled-handle-color — #ffffff
--tanrei-comp-slider-standard-disabled-handle-elevation —
--tanrei-comp-slider-standard-disabled-handle-width — 20px
--tanrei-comp-slider-standard-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-slider-standard-disabled-stop-indicator-color — #1b1b1b · 38%
--tanrei-comp-slider-standard-disabled-track-color — #1b1b1b · 12%
--tanrei-comp-slider-standard-focused-active-stop-indicator-color — #ffffff
--tanrei-comp-slider-standard-focused-active-track-color — #1b1b1b
--tanrei-comp-slider-standard-focused-container-color — #1b1b1b · 10%
--tanrei-comp-slider-standard-focused-handle-outline-color — #1b1b1b
--tanrei-comp-slider-standard-focused-handle-color — #ffffff
--tanrei-comp-slider-standard-focused-handle-elevation —
--tanrei-comp-slider-standard-focused-handle-width — 20px
--tanrei-comp-slider-standard-focused-state-layer-color — #1b1b1b
--tanrei-comp-slider-standard-focused-stop-indicator-color — #4b4b4b
--tanrei-comp-slider-standard-focused-track-color — #eeeeee
--tanrei-comp-slider-standard-handle-outline-color sys.color.primary #1b1b1b
--tanrei-comp-slider-standard-handle-color sys.color.surface #ffffff
--tanrei-comp-slider-standard-handle-elevation sys.elevation.level0
--tanrei-comp-slider-standard-handle-width — 20px
--tanrei-comp-slider-standard-hovered-active-stop-indicator-color — #ffffff
--tanrei-comp-slider-standard-hovered-active-track-color — #1b1b1b
--tanrei-comp-slider-standard-hovered-container-color — #1b1b1b · 8%
--tanrei-comp-slider-standard-hovered-handle-outline-color — #1b1b1b
--tanrei-comp-slider-standard-hovered-handle-color — #ffffff
--tanrei-comp-slider-standard-hovered-handle-elevation —
--tanrei-comp-slider-standard-hovered-handle-width — 20px
--tanrei-comp-slider-standard-hovered-state-layer-color — #1b1b1b
--tanrei-comp-slider-standard-hovered-stop-indicator-color — #4b4b4b
--tanrei-comp-slider-standard-hovered-track-color — #eeeeee
--tanrei-comp-slider-standard-pressed-active-stop-indicator-color — #ffffff
--tanrei-comp-slider-standard-pressed-active-track-color — #1b1b1b
--tanrei-comp-slider-standard-pressed-container-color — #1b1b1b · 10%
--tanrei-comp-slider-standard-pressed-handle-outline-color — #1b1b1b
--tanrei-comp-slider-standard-pressed-handle-color — #ffffff
--tanrei-comp-slider-standard-pressed-handle-elevation —
--tanrei-comp-slider-standard-pressed-handle-width — 20px
--tanrei-comp-slider-standard-pressed-state-layer-color — #1b1b1b
--tanrei-comp-slider-standard-pressed-stop-indicator-color — #4b4b4b
--tanrei-comp-slider-standard-pressed-track-color — #eeeeee
--tanrei-comp-slider-standard-state-layer-color comp.slider.standard.handle-outline.color #1b1b1b
--tanrei-comp-slider-standard-stop-indicator-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-slider-standard-track-color sys.color.surface-variant #eeeeee
--tanrei-comp-slider-stop-indicator-size-large — 4px
--tanrei-comp-slider-stop-indicator-size-medium — 3px
--tanrei-comp-slider-stop-indicator-size-small — 2px
--tanrei-comp-slider-track-gap sys.space.space0 0px
--tanrei-comp-slider-track-shape-large sys.shape.corner.full 9999px
--tanrei-comp-slider-track-shape-medium sys.shape.corner.full 9999px
--tanrei-comp-slider-track-shape-small sys.shape.corner.full 9999px
--tanrei-comp-slider-track-thickness-large — 8px
--tanrei-comp-slider-track-thickness-medium — 6px
--tanrei-comp-slider-track-thickness-small — 4px
--tanrei-comp-slider-value-indicator-container-color sys.color.inverse-surface #1f1f1f
--tanrei-comp-slider-value-indicator-container-height — 24px
--tanrei-comp-slider-value-indicator-container-padding-inline sys.space.space100 8px
--tanrei-comp-slider-value-indicator-container-shape sys.shape.corner.small 6px
--tanrei-comp-slider-value-indicator-label-color sys.color.inverse-on-surface #f1f1f1
--tanrei-comp-slider-value-indicator-offset sys.space.space100 8px
--tanrei-comp-slider-value-indicator-label-typescale sys.typescale.label-small 500 12px/1.3333

Fixtures

Representaciones canónicas. Todas las plataformas capturan cada fixture con el mismo identificador para poder comparar los resultados.

Generado a partir de specs/slider.spec.json, tokens/comp/slider.tokens.json, design/tokens/

Pautas

Cuándo usarlo

Usa un control deslizante cuando las personas eligen un valor a ojo y ven su efecto mientras lo mueven: el volumen, el brillo, la exposición de una foto, el radio de búsqueda de un mapa. Un control deslizante de intervalo va bien para un filtro con un límite inferior y otro superior, como un precio.

Cuando el número exacto importa más que su posición, como un importe o una cantidad, usa un campo de texto, o pon uno junto al control deslizante para que la persona pueda hacer cualquiera de las dos cosas. Cuando solo hay unas pocas opciones con nombre, como Bajo, Medio y Alto, los botones de opción nombran cada una, o un botón segmentado donde el sistema lo incluya.

Continuo o por pasos

  • Continuo (step en 0) admite cualquier valor entre min y max. Úsalo cuando los valores intermedios tengan sentido y el efecto se vea al instante.
  • Por pasos (step por encima de 0) se ajusta a min más múltiplos enteros de step. Úsalo cuando solo tengan sentido las unidades enteras: estrellas, un tamaño de fuente en puntos, un porcentaje de diez en diez.
  • stops dibuja un punto en cada valor que puede tomar un control deslizante por pasos. Actívalo cuando haya pocos pasos, para que las personas puedan contarlos. Con muchos pasos, los puntos abarrotan la pista, así que déjalos desactivados.

Las teclas de flecha mueven un paso, o una centésima del intervalo en un control deslizante continuo. Re Pág y Av Pág mueven diez.

Un intervalo

range dibuja dos tiradores, de startValue a value. Los tiradores pueden encontrarse, pero nunca cruzarse. Cada uno es su propia parada de tabulación y su propio control para un lector de pantalla, que oye el intervalo que el tirador todavía puede alcanzar. Da nombre a los dos tiradores: startLabel («Precio mínimo») y label («Precio máximo»).

Un control deslizante centrado

origin define dónde empieza la pista activa. Si se deja vacío, empieza en min. Un valor dentro del intervalo, como 0 en un control de balance de -50 a 50, hace que la pista activa crezca desde ahí hacia cualquiera de los dos lados. Los extremos de la pista conservan sus puntos de parada, así que los dos límites siguen a la vista.

El indicador de valor

valueIndicator muestra el valor del tirador en una pequeña etiqueta junto a él.

Valor Muestra el valor Úsalo para
none (predeterminado) Nunca Controles deslizantes cuyo efecto se ve en otro lugar de la pantalla: volumen, brillo
active Mientras el tirador está pulsado o tiene el foco del teclado Valores que las personas necesitan leer mientras los definen, donde un dedo tapa el tirador
always Todo el tiempo Un valor que debe seguir siendo legible, cuando no hay sitio para un texto tuyo junto al control deslizante

El indicador se sitúa encima del tirador de un control deslizante horizontal y en el inicio en línea de uno vertical. Muestra valueText cuando lo proporcionas y, si no, el número en la configuración regional de la plataforma, con tantos decimales como tenga el paso del teclado, hasta dos. Es solo una vista del valor: no recibe el foco ni ninguna entrada, y un lector de pantalla lee el valor del tirador.

Texto del valor

Define valueText con las palabras que expresan el valor actual cuando el número a secas no quedaría claro: «40%», «3 estrellas», «$300». Sustituye al número tanto en el indicador de valor como en lo que dice un lector de pantalla. En un intervalo, startValueText hace lo mismo para el tirador de inicio. Actualízalo cada vez que cambie el valor.

Unas palabras escritas una sola vez dejan de ser ciertas tras el primer arrastre. Por eso el control deslizante acepta también una función que convierte un valor en sus palabras y que se da una sola vez: se la pide para cada tirador en cada cambio, y valueText y startValueText siguen teniendo prioridad donde los definas. En la web es formatValue, una propiedad y nunca un atributo. Las demás plataformas todavía no la han implementado.

const dollars = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
document.querySelector('[name="price"]').formatValue = (value) => dollars.format(value);

Se usa en el campo de control deslizante: un campo y un control deslizante como un solo componente, con estas palabras dibujadas al final de la fila de la etiqueta. Úsalo siempre que el control deslizante necesite una etiqueta dibujada, ayuda o un error.

Tamaño y orientación

small es el control deslizante de uso diario. medium y large dan una pista más gruesa a un control destacado, como un control deslizante de volumen o de brillo en una pantalla multimedia. Todos los tamaños cumplen el objetivo mínimo.

Un control deslizante vertical va de abajo (min) a arriba (max) en cualquier dirección del diseño. Uno horizontal va desde el inicio en línea, así que en un diseño de derecha a izquierda min queda a la derecha.

Recomendado

  • Pon una etiqueta visible tuya junto al control deslizante, con las mismas palabras que label.
  • Muestra el efecto del valor mientras la persona arrastra, y guárdalo en change, no en cada input.
  • Elige min, max y step de modo que todos los valores que el control deslizante puede tomar sean valores que alguien querría.
  • Da una unidad a valueText cuando el número por sí solo no diga qué cuenta.

Evita

  • No uses un control deslizante para un valor que haya que definir con precisión, como una fecha o una suma de dinero.
  • No uses un control deslizante para un ajuste que solo está activado o desactivado. Usa un interruptor.
  • No muestres puntos de parada en un control deslizante con muchos pasos.
  • No pongas un control deslizante dentro de una barra de herramientas. Necesita las teclas de flecha con las que la barra de herramientas mueve el foco.

Accesibilidad

Rol
slider
Etiquetado
label names the slider, or a range's end handle; startLabel names a range's start handle. Neither is drawn: a visible label is the product's text beside the slider, in the same words. valueText replaces the spoken number ("40 %", "3 stars"). The tracks, stop dots, state layer and value indicator are decorative.
Objetivo mínimo
El área de pulsación cumple el tamaño mínimo de objetivo aunque el tamaño visual sea menor. minimum 32px · pointer 44px · spacing 8px · touch 48px

Teclado

Teclas Acción
Tab / Shift+Tab Moves focus to the handle, and for a range to the start handle, then the end handle.
Right Arrow / Up Arrow Increases the focused handle's value by one keyboard step (Right Arrow decreases it in a right-to-left horizontal slider).
Left Arrow / Down Arrow Decreases the value by one keyboard step (Left Arrow increases it in a right-to-left horizontal slider).
Page Up / Page Down Increases or decreases the value by ten keyboard steps.
Home / End Sets the value to the lowest or highest the handle can take.

Notas

  • Each handle is one slider for assistive technology: role slider with aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext and aria-orientation on the web; the adjustable trait with an accessibility value on Apple platforms (a vertical swipe increments and decrements); a range with a current value and the set-progress action on Android; a slider semantics node with increase and decrease actions in Flutter; role adjustable with accessibilityValue and increment and decrement actions in React Native.
  • A range is two sliders, the WAI-ARIA multi-thumb pattern: each handle's lowest and highest value is bounded by the other handle, so a screen reader announces the range each can still reach.
  • The value is read from the handle and the active track. The handle must be told apart from each thing it lies on — the track, the active track and the surface behind the slider — by its outline (comp.slider.standard.handle-outline.color, where comp.slider.handle-outline.width is above 0) or by its fill (comp.slider.standard.handle.color), at 3:1 or more; comp.slider.standard.active-track.color must stay at least 3:1 against the track and the surface. In the default system the outline carries it against the track and the surface, and the fill against the active track. A faint track keeps its end visible by the stop dot at the end of the travel (SLD-9).
  • The handle may be drawn smaller than the minimum target (20 against 48 in the default system): the whole slider takes the press across its axis at the target's size (SLD-7), so every handle keeps its whole target, a range's two handles included, and no target is reported larger than the area that takes the press.
  • Text size does not change the slider: it has no text of its own except the value indicator, which grows with the text.
  • How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.

Generado a partir de specs/slider.spec.json, tokens/sys/measure.tokens.json

De qué se encarga el componente

  • Cada tirador es un control deslizante para la tecnología de apoyo, que recibe su nombre de label (o de startLabel en el tirador de inicio de un intervalo), con su valor, su texto de valor, el valor más bajo y el más alto que puede tomar, su orientación y su estado deshabilitado. En las plataformas de Apple es un elemento ajustable: un deslizamiento vertical lo mueve un paso.
  • Un intervalo son dos controles deslizantes, el patrón de varios tiradores de WAI-ARIA. Los límites de cada tirador están acotados por el otro tirador, de modo que un lector de pantalla anuncia el intervalo que todavía puede alcanzar.
  • Las pistas, los puntos de parada, la capa de estado y el indicador de valor quedan ocultos para la tecnología de apoyo.
  • Cada tirador es una parada de tabulación, el de inicio primero. Las teclas de flecha mueven un paso, Re Pág y Av Pág diez pasos, e Inicio y Fin llevan al valor más bajo y al más alto. En un control deslizante horizontal de derecha a izquierda, Flecha derecha y Flecha izquierda se intercambian.
  • Las acciones de incrementar y reducir de un lector de pantalla mueven un paso; definir un valor directamente, donde la plataforma lo permite, se limita al intervalo y se ajusta al paso.
  • Una pulsación en cualquier punto del control deslizante lleva ahí el tirador más cercano, y un arrastre lo sigue. En pantallas táctiles, una pulsación que primero se mueve en perpendicular a la pista se deja a la vista de desplazamiento que lo rodea, de modo que el control deslizante no captura un desplazamiento.
  • Todo el control deslizante es el área de pulsación, y alcanza el objetivo mínimo en perpendicular a la pista. El tirador se dibuja más pequeño que el objetivo, pero eso no reduce el área de pulsación, así que cada tirador de un intervalo conserva también el objetivo entero.
  • Muestra el indicador de foco alrededor del tirador con foco, solo para el foco del teclado.
  • En el sistema predeterminado, el tirador se distingue de todo aquello sobre lo que se apoya con 3:1 o más: por su contorno frente a la pista y a la página, y por su relleno frente a la pista activa. La pista activa mantiene 3:1 frente a la pista y a la página, y el final de una pista tenue sigue a la vista gracias a su punto de parada.
  • Un control deslizante deshabilitado no puede recibir el foco, no muestra ningún indicador de valor y se expone como deshabilitado.
  • El tamaño del texto solo cambia el indicador de valor, que crece con el texto.
  • Las compilaciones de depuración notifican la falta de label o de startLabel; un valor, un valor de inicio o un origen fuera del intervalo o fuera de un paso; un valor de inicio por encima del valor; un max que no es mayor que min; un paso negativo, y un tamaño, una orientación o un ajuste del indicador de valor desconocidos.

Carencias conocidas por plataforma:

  • En la web, cada tirador tiene el rol slider en el shadow root, no a través de ElementInternals, porque axe-core no puede ver la semántica definida de ese modo. No es un <input type="range">, que tiene un solo tirador y partes a las que no hay dos motores que den estilo de la misma forma.
  • Web: la tecnología de apoyo ajusta un slider de ARIA mediante las teclas de flecha que le envía el navegador, así que no se puede definir un valor directamente.
  • Web: el indicador de valor no está en la capa superior (top layer). Un ancestro con overflow: hidden lo recorta, y un hermano posicionado posterior con un z-index por encima de 1 lo tapa.
  • SwiftUI no puede exponer el valor más bajo y el más alto de un tirador ni su orientación, y en macOS un tirador no es un control deslizante para la tecnología de apoyo.
  • SwiftUI no puede distinguir un toque de un puntero: en iOS toda pulsación es un toque, también la del puntero de un iPad, y en macOS toda pulsación es de un puntero. Antes de iOS 18, el arrastre de un toque es un gesto de SwiftUI, del que una vista de desplazamiento que rodee el control deslizante quizá no pueda hacerse cargo.
  • SwiftUI: el indicador de valor se mantiene dentro del control deslizante en lugar de dentro de la ventana, y una vista dibujada después del control deslizante puede taparlo.
  • SwiftUI: las teclas se prueban como reglas, todavía no con un teclado real, porque el simulador no da foco del teclado durante la automatización.
  • La semántica del control deslizante de Compose no tiene orientación, así que la orientación de un tirador no se expone.
  • Flutter no expone el valor más bajo ni el más alto ni la orientación de un tirador, ni tiene una acción para definir un valor directamente.
  • Flutter siempre escribe el número con un . como separador decimal, en todas las configuraciones regionales. Define valueText donde eso importe.
  • Flutter: el área de pulsación crece en perpendicular a la pista solo donde el padre del control deslizante es más grande que él. Un padre con el tamaño exacto del control deslizante la recorta.
  • React Native no tiene una acción para definir un valor directamente ni una propiedad de orientación, así que no se expone ninguna de las dos cosas.
  • En React Native, las teclas de flecha solo funcionan donde hay un teclado físico conectado, como en la fila de pestañas.
  • React Native trata toda pulsación como un toque: una pulsación de ratón o de lápiz espera a haberse movido o a haber terminado antes de mover el tirador.
  • React Native dibuja el indicador de valor dentro del control deslizante, no en la capa de superposición, así que se queda dentro del control deslizante en lugar de dentro de la ventana, y una vista dibujada después del control deslizante puede taparlo.
  • React Native: el diseño, el arrastre y cómo cede ante una vista de desplazamiento, y los tiradores ajustables todavía no se han comprobado en un dispositivo.
  • SwiftUI, Compose, Flutter y React Native todavía dibujan el aspecto anterior: un tirador macizo, un solo tamaño de punto de parada para todos los tamaños y las pistas cortadas en el tirador en lugar de encontrarse debajo de él. Donde cortan, terminan la pista de forma distinta: recta en SwiftUI, redondeada con una muesca en Flutter y React Native, y cortada con la forma del tirador en Compose.
  • Con cupertino, el tirador blanco sobre una página blanca mide 1.0:1 en los esquemas claros, por debajo del 3:1 que necesita una parte que muestra el valor. No tiene contorno, tal como lo dibuja Apple, y se distingue por su sombra y por la pista activa teñida que tiene al lado; ninguna invariante comprueba un tirador frente a la página. El 1.0:1 es una medición que se conserva a título informativo: los criterios de accesibilidad de Tanrei no se aplican a un preajuste de imitación. Con cupertino, el control deslizante tampoco dibuja puntos de parada, ni siquiera en los extremos de la pista.
  • Con m3-like, el control deslizante dibuja la barra vertical de Material, a partir de las medidas publicadas por Material. Todavía no se han comprobado frente a la referencia de fidelidad. Con m3-expressive-like, el glifo que Material dibuja dentro de una pista gruesa no tiene sitio (laguna de imitación slider-inset-icon): pon tu icono junto al control deslizante.

Qué debes hacer tú

  • Da a cada control deslizante un label, y a un intervalo también un startLabel, en el idioma de tu producto. Muestra las mismas palabras como etiqueta visible a su lado.
  • Define valueText cuando el número por sí solo no quede claro, y mantenlo sincronizado con el valor.
  • Muestra el resultado de un cambio en algún lugar donde las personas puedan verlo, y diles con texto si un cambio no se pudo aplicar. El control deslizante solo anuncia su propio valor.
  • Con cupertino, donde el tirador es blanco y la pista no tiene puntos en los extremos, mantén el control deslizante fuera de una superficie blanca lisa siempre que puedas.
  • Sobre una superficie con el tono de contenedor más alto, como una tarjeta rellena, la pista inactiva cuesta verla: tiene casi el mismo tono. Donde un control deslizante esté sobre una, apunta comp.slider.standard.track.color a un rol más fuerte en una capa. El tirador y la pista activa siguen mostrando el valor.
  • En la web, da al control deslizante un name para enviar su valor con un formulario.