Indicador de pasos
Muestra dónde está una persona en un flujo que el producto recorre en un orden fijo de pasos (qué paso es el actual, cuáles están completados, cuál tiene un error y cuáles faltan todavía) y le permite pulsar un paso para volver a él.
- Categoría
- Navegación
- Tokens
comp.stepper- Nivel
- Base
- Web
tanrei-stepperclock_loader_40 - SwiftUI
TanreiStepperradio_button_unchecked - Jetpack Compose
TanreiStepperradio_button_unchecked - Flutter
TanreiStepperradio_button_unchecked - React Native
Stepperradio_button_unchecked
Generado a partir de docs/status/status.json, specs/stepper.spec.json
Horizontal, con un paso que tiene un error
El indicador de pasos (stepper) se coloca encima o al lado del contenido de un flujo que tiene una posición: una compra, una configuración inicial, una solicitud en varias partes. Un paso es el actual, los anteriores están completados, uno puede necesitar la atención de la persona y el resto faltan todavía.
Los pasos son hijos <tanrei-stepper-step>, en orden. value indica el paso actual. El indicador nunca mueve value por sí mismo: cuando la persona pulsa un paso, emite select con el valor de ese paso, y tu flujo va allí (o no) y establece value.
SwiftUI, Compose, Flutter y React Native están planificados: los nombres que figuran junto a cada plataforma al principio de esta página son los que les da la especificación, y todavía no se distribuye nada para ellos.
<tanrei-stepper id="checkout" label="Progreso de la compra" value="shipping" pressable="visited"
completed-text="Completado" error-text="Tiene un error" position-text="Paso {position} de {count}">
<tanrei-stepper-step value="account" label="Cuenta"></tanrei-stepper-step>
<tanrei-stepper-step value="shipping" label="Envío" description="Dirección y entrega"></tanrei-stepper-step>
<tanrei-stepper-step value="gift" label="Envoltorio de regalo" description="Opcional"></tanrei-stepper-step>
<tanrei-stepper-step value="payment" label="Pago"></tanrei-stepper-step>
</tanrei-stepper>
<script type="module">
import '@tanrei/web/components/stepper';
const stepper = document.querySelector('#checkout');
// Pulsar un paso es pedir ir allí. El flujo decide y luego mueve value.
stepper.addEventListener('select', (e) => {
if (goTo(e.detail.value)) stepper.value = e.detail.value;
});
</script>import { Stepper, StepperStep } from '@tanrei/react';
<Stepper
label="Progreso de la compra"
value={step}
pressable="visited"
completedText="Completado"
errorText="Tiene un error"
positionText="Paso {position} de {count}"
onSelect={(e) => setStep(e.detail.value)}
>
<StepperStep value="account" label="Cuenta" />
<StepperStep value="shipping" label="Envío" status={shippingError ? 'error' : 'auto'} />
<StepperStep value="payment" label="Pago" />
<StepperStep value="review" label="Revisión" />
</Stepper>Los textos son tuyos: completed-text y error-text son lo que la tecnología de apoyo oye después de la etiqueta de un paso, y position-text es la línea de la forma compacta, con los huecos {position} y {count}. Dalos una sola vez para todos los indicadores de pasos con setWords({ stepCompletedText, stepErrorText, stepPositionText }).
Vertical y compacto
Anatomía
| Parte | Descripción |
|---|---|
1 root | The ordered list of the flow's steps, named by label: one row of equal columns (horizontal), one column (vertical), or, in the compact form, a bar and two lines of text. It has no fill, no edge and no padding of its own. |
2 step | One item of the list: its marker, its label and, where it has one, its description. A step is in exactly one condition — incomplete, current, complete or error — and, while it can be pressed, in the interaction states. |
3 container | The area of a step that carries hover, focus and press while the step can be pressed: its marker and its text, with the container's padding around them. It has no fill at rest. A step that cannot be pressed draws its container but answers nothing. |
4 marker | What begins a step: a filled or ringed circle holding the step's number, the glyph check (complete) or the glyph priority_high (error). Its fill, ring and content say the step's condition; it is decorative, because the step's condition is also said in words. |
5 label | The step's name, in a few words ("Shipping"). It wraps and is never cut. |
6 description · opcional | A short second line under the label ("Optional", "2 items"), in a smaller and quieter style. It wraps and is never cut. |
7 connector | The line from a step's marker to the next step's marker: across the column in the horizontal form, down beside the text in the vertical form. Drawn in the complete color after a complete step, so that the way already gone is one line. Decorative. The last step has none. |
8 bar · opcional | The compact form's row of segments, one per step, filled up to and including the current step. Decorative: the position text says the same in words. |
9 position · opcional | The compact form's position in the product's words ("Step 2 of 5"), above the current step's label. |
10 focus-ring | The indicator shown for keyboard focus, around a pressable step's container. |
Propiedades
| Propiedad | Tipo | Valor predeterminado | Descripción |
|---|---|---|---|
label | string | "" | The accessible name of the stepper ("Checkout progress"), in the product's language. Not drawn. It tells the list of steps from the content it tracks, so it is required. |
value | string | "" | The value of the current step: where the person is. Empty, or a value no step has, makes no step current — before the flow begins, or once it is finished. The stepper never changes it itself: the product moves its flow and sets value. |
layout | horizontal | vertical | compact | "horizontal" | horizontal: the steps side by side in equal columns, above the content they track; where the width it is given cannot hold every step at its least width, the stepper draws the compact form instead (SPR-6). vertical: the steps one under another, beside the content or in a narrow column. compact: the bar and the position in words ("Step 2 of 5") with the current step's label, at any width. |
pressable | none | visited | all | "none" | Which steps the person can press to go to them. none: no step; the stepper only shows where the person is. visited: each step that is complete or has an error and is not current — the steps the person has been to, so that they can go back. all: every step that is not current, for a flow whose steps can be done in any order. A disabled step is never pressable, and the current step never is. The compact form presses nothing. |
completedText | string | "" | The word assistive technology hears after the label of a complete step ("Completed"), in the product's language. Not drawn: the check says it to the eye. The product's: Tanrei has no word for it. Empty reads the product's words. Required while a step is complete. |
errorText | string | "" | The word assistive technology hears after the label of a step with an error ("Has an error"), in the product's language. Not drawn: the glyph says it to the eye. The product's: Tanrei has no word for it. Empty reads the product's words. Required while a step has an error. |
positionText | string | "" | The compact form's position: the whole sentence in the product's language with two places the stepper fills, {position} with the current step's place counted from 1 and {count} with the number of steps ("Step {position} of {count}", "ステップ {position}/{count}"). The product's: Tanrei has no sentence for it. Empty reads the product's words. Required while the compact form is drawn. |
Eventos
| Evento | Descripción |
|---|---|
select | The person pressed a step to go to it, by pointer, touch, Enter, Space or assistive technology; carries the step's value. The stepper does not change value: the product goes to the step (or does not) and sets value. |
Elementos
Los tipos de elemento que el componente repite. Un fixture enumera sus elementos en orden; cada plataforma nombra cada tipo según su propio estilo.
step
One step of the flow: its value, its label, an optional description, its status and whether it can be visited.
| Propiedad | Tipo | Valor predeterminado | Descripción |
|---|---|---|---|
value | string | "" | Identifies the step: the stepper's value names the current step by it, and select carries it. Unique within the stepper; required. |
label | string | "" | The step's name, in a few words ("Shipping"). Drawn, and the start of what assistive technology hears for the step. Required. |
description | string | "" | A short second line under the label ("Optional", "2 items"). Empty draws none. |
status | auto | incomplete | complete | error | "auto" | What the product knows of the step. auto: complete when it comes before the current step and incomplete when it comes after it (or when no step is current) — a flow done in order. incomplete and complete: so, wherever the step stands (a step skipped and left for later; a step done ahead in a flow of any order). error: the step needs the person's attention. The current step is drawn current whatever its status, except error, which it keeps. |
disabled | boolean | false | The step cannot be gone to now (it depends on an earlier choice). Only meaningful while pressable is not none: the step is drawn disabled and is not pressable. Ignored on the current step. |
| Especificación | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| Elemento | tanrei-stepper-step | TanreiStepperStep | TanreiStepperStep | TanreiStepperStep | StepperStep |
value · Propiedad | value | id | value | value | value |
label · Propiedad | label | label | label | label | label |
description · Propiedad | description | description | description | description | description |
status · Propiedad | status | status | status | status | status |
disabled · Propiedad | disabled | disabled | enabled | enabled | disabled |
| Notas | A child element: <tanrei-stepper-step value="shipping" label="Shipping" description="…" status="error" disabled>, as <option> in a <select>. | TanreiStepperStep(id:, label:, description:, status: .auto, disabled:), an Identifiable value. | A data class; enabled is the inverse flag. | A value class; enabled is the inverse flag. | The element type of the steps array: { value, label, description?, status?, disabled? }. |
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 |
|---|---|
SPR-1 | THE stepper SHALL draw each step in exactly one condition: current WHILE value equals the step's value (the first step with that value, SPR-21) and its status is not error; error WHILE its status is error, current or not; complete WHILE its status is complete, or its status is auto and it comes before the current step; incomplete WHILE its status is incomplete, or its status is auto and it comes after the current step or no step is current. WHEN value or a step's status changes THE stepper SHALL draw every step's new condition at once, without a motion of its own beyond the state motion of SPR-17. |
SPR-2 | THE stepper SHALL draw each step's marker as a circle at least comp.stepper.marker.size high and wide, with corners comp.stepper.marker.shape eased by sys.shape.corner-smoothing, filled with the marker color of the step's condition and state (comp.stepper.incomplete.marker.color, comp.stepper.current.marker.color, comp.stepper.complete.marker.color, comp.stepper.error.marker.color at rest) and edged inside its size by a ring comp.stepper.marker.outline.width wide in the marker outline color of the same (comp.stepper.incomplete.marker.outline.color, and so on). An incomplete or current marker SHALL hold the step's number — its place in the flow, counted from 1 — in comp.stepper.marker.label.typescale and the marker content color of its condition, centred, as a left-to-right run whose digits are never reversed; a complete marker SHALL hold the glyph check and an error marker the glyph priority_high instead, in the marker content color of their condition, each in a box comp.stepper.marker.icon.size large through the platform's icon helper with sys.icon.family.selected, sys.icon.fill.selected, the weight comp.stepper.marker.icon.weight and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max, unmirrored in every layout direction; THE stepper SHALL draw no mark of its own. |
SPR-3 | THE stepper SHALL draw each step's label in comp.stepper.label.typescale and the label color of its condition and state, and, WHERE the step has a description, the description comp.stepper.description.gap under the label in comp.stepper.description.typescale and the description color of the same; it SHALL wrap both where their language allows a break and, for a run with no such place that is longer than the line, inside the run, and SHALL NOT cut them, draw an ellipsis or scroll. A change of condition SHALL NOT change the label's text style, so that no step moves when the current step does. |
SPR-4 | WHILE layout is horizontal and the full form is drawn (SPR-6) THE stepper SHALL lay its steps out in one row of columns of equal width, in order, each column a step's container: its marker at the container's start, comp.stepper.container.padding from its edges, and its label and description under the marker, comp.stepper.marker.gap below it, aligned to the start and as wide as the column less its padding; the row SHALL be exactly as wide as the place it stands in and as high as its tallest step, every step's marker on one line. |
SPR-5 | WHILE layout is vertical THE stepper SHALL lay its steps out in one column, in order, each step's container as wide as the stepper: its marker at the container's start, comp.stepper.container.padding from its edges, and its label and description beside the marker, comp.stepper.marker.gap from it, filling the rest of the width; the marker SHALL be centred on the label's first line, and WHERE the marker is taller than that line the stepper SHALL lower the text by half the difference, so that the marker's top is the content's top. |
SPR-6 | WHILE layout is compact, or layout is horizontal and the width the layout gives the stepper is less than the number of steps times comp.stepper.step.min-width, THE stepper SHALL draw the compact form instead of its steps: the bar — one segment per step in a row as wide as the stepper, comp.stepper.bar.gap apart, each comp.stepper.bar.thickness thick with corners comp.stepper.bar.shape, the segments of the current step and every step before it in comp.stepper.bar.filled.color and the others in comp.stepper.bar.color — then, comp.stepper.position.gap under it, the position in comp.stepper.position.typescale and comp.stepper.position.color, and under that the current step's label as SPR-3 draws a current step's, or an error step's where the current step has an error, preceded there by its marker's glyph priority_high at comp.stepper.marker.icon.size in the error label color. It SHALL decide by the width it is given, not by the window's, and SHALL change form at once WHEN that width crosses the threshold, keeping value. WHILE no step is current THE stepper SHALL draw the bar with no segment filled, and neither the position nor a label. |
SPR-7 | THE stepper SHALL fill the position's places as the product's sentence marks them: {position} with the current step's place counted from 1 and {count} with the number of steps, each written as the platform writes a whole number in the language of the element; it SHALL do nothing else to the sentence, and SHALL draw a sentence without {position} as it is written and in debug builds report it. |
SPR-8 | WHILE a step is followed by another step and the full form is drawn THE stepper SHALL draw a connector from that step's marker to the next step's: a straight line comp.stepper.connector.thickness thick, starting comp.stepper.connector.gap after the step's marker and ending comp.stepper.connector.gap before the next step's marker — across the row on the markers' centre line in the horizontal form, down the markers' centre line in the vertical form — in comp.stepper.connector.complete.color WHILE the step is complete and comp.stepper.connector.color otherwise. No container's fill or state layer SHALL cover a connector, and the connector SHALL be hidden from assistive technology. |
SPR-9 | WHILE pressable is visited THE stepper SHALL make pressable each step that is drawn complete or error, is not current and is not disabled; WHILE pressable is all, each step that is not current and is not disabled; WHILE pressable is none, no step; and in the compact form no step, whatever pressable says. A pressable step SHALL be the platform's own button for the whole of its container, in the focus order in the order of the steps; a step that is not pressable SHALL NOT take focus, SHALL NOT answer a pointer, a press or a key, and SHALL draw no interaction state. |
SPR-10 | WHEN the person activates a pressable step by pointer, touch, Enter, Space or assistive technology THE stepper SHALL emit select exactly once with that step's value, and SHALL NOT change value or any step's condition itself: the product goes to the step and sets value, or keeps the person where they are. |
SPR-11 | WHILE pressable is not none and a step's disabled is true and the step is not current THE stepper SHALL draw the step from the disabled tokens of its condition — its label, description, marker content and ring faded as disabled content, its fill kept, SHALL NOT make it pressable, and SHALL expose it as a disabled button, so that a person who reaches it hears that it cannot be gone to now; WHILE pressable is none THE stepper SHALL draw and expose a step whose disabled is true as it draws any other, because nothing is pressed and so nothing is unavailable. WHILE the current step's disabled is true THE stepper SHALL draw it current and in debug builds report it. |
SPR-12 | WHILE a pressable step is hovered, keyboard-focused or pressed THE stepper SHALL render its container, marker, marker outline, marker content, label, description and opacity from the component tokens of its condition in the highest-precedence active state, with precedence pressed over focused over hovered; focus gained by pointer or touch SHALL NOT select the focused state. |
SPR-13 | WHEN a pressable step receives keyboard focus THE stepper SHALL show the focus ring around that step's container without animation — the system's focus indicator, sys.focus.offset from the container, sys.focus.outer-width wide in the focus-ring color, with the inner stroke of sys.focus.inner-width where the system has one; focus gained by pointer or touch SHALL NOT show it. |
SPR-14 | WHEN a pressable step is pressed by pointer, touch, Enter or Space THE stepper SHALL show the pressed state without delay and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner. |
SPR-15 | WHILE pressed THE stepper 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 step 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; marker, label, description, 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.stepper.motion.feedback-duration with comp.stepper.motion.state-easing, fades over comp.stepper.motion.state-duration with comp.stepper.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced. |
SPR-16 | THE stepper SHALL ease its containers' corners, comp.stepper.container.shape, 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. |
SPR-17 | WHEN a step changes between interaction states or between conditions THE stepper SHALL change its colors over comp.stepper.motion.state-duration with comp.stepper.motion.state-easing, and at once where motion is reduced; a glyph or a number that replaces another in a marker SHALL be replaced at once. |
SPR-18 | THE stepper SHALL make every step's container at least sys.target.pointer high and wide for fine pointers and sys.target.touch for touch input — a platform that cannot tell the input type SHALL use sys.target.touch — leaving the room it adds below and after the container's content, so that a pressable step's hit area meets the minimum target without reaching over a neighbouring step's, and so that a pressable and a plain step stand alike. |
SPR-19 | THE stepper SHALL be exposed to assistive technology as an ordered list named by label, of as many items as it has steps, each step one item holding, in this order, its label, the product's word for its condition where it has one — completedText for a complete step, errorText for a step with an error, nothing for an incomplete one — and its description; the current step SHALL be exposed as the current step of the flow (the web's aria-current="step"; the platform's selected trait with its position where it has no current state). Markers, numbers, glyphs, connectors and the bar SHALL be hidden: the list gives each step its place, and the words its condition. WHILE the compact form is drawn THE stepper SHALL instead be exposed as one group named by label holding the position and the current step's label, followed by errorText where the current step has an error, so that what is heard is what is drawn. |
SPR-20 | THE stepper SHALL have no words of its own: it SHALL take completedText, errorText and positionText from the instance's prop and, WHILE that is empty, from the product's words of the same keys; WHILE a word that a drawn step needs was given by nobody THE stepper SHALL expose nothing in its place, still draw the step, and record and report the missing word as the product's words do. |
SPR-21 | WHEN value names no step THE stepper SHALL make no step current; WHEN a step's value is empty or repeats another step's THE stepper SHALL still draw it and treat the first step with a value as the one that value names; WHILE label is empty, a step's label is empty, or the stepper holds fewer than two steps, THE stepper SHALL still render; in debug builds it SHALL report each of these, except an empty value, which names the time before or after the flow. |
SPR-22 | WHILE the text size is enlarged THE stepper SHALL grow each label, description, number and position with it and grow each marker with its number, keeping comp.stepper.marker.size as a minimum and every gap and padding as it is, SHALL wrap and never cut text, and SHALL still choose its form by the width it is given (SPR-6). |
SPR-23 | WHERE the platform draws with a person's own forced colors (the web's forced-colors mode, and a platform's equivalent where it has one) THE stepper SHALL draw every ring, connector, segment, number, glyph and text in the platform's text color — a pressable step's label in the platform's button text color — the current step's marker filled in the platform's highlight color with its number in the highlight text color, and the filled segments of the bar in the highlight color, and SHALL draw the focus ring in the platform's highlight color; nothing it draws relies on a fill alone. |
SPR-24 | THE stepper 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 stepper is shown THE stepper SHALL draw itself for the new direction at once, without a motion of its own, keeping its focus. |
SPR-25 | WHERE the layout direction is right-to-left THE stepper SHALL mirror its layout by logical start and end — the first step at the right of a horizontal row, the markers at the right of a vertical column, the bar filled from the right — and SHALL keep its reading and focus order first step to last; it SHALL NOT mirror a glyph or reverse a number. |
SPR-26 | THE stepper SHALL lay out each label, description and the position as text of its own direction, isolated from the text around it: it takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right name or a number keeps its own order in a right-to-left layout; THE stepper SHALL still place the text and align its lines by the layout direction, not by the text's own. |
SPR-27 | IF the icon set cannot draw a marker's glyph yet (its font is still loading or failed to load) THE stepper SHALL draw nothing in the glyph's place, never the glyph's name as text, keeping the marker's size, fill and ring, and SHALL still expose the step's condition in words; it SHALL show the glyph once the icon set can draw it. |
SPR-28 | WHERE the platform has ARIA attributes (the web), the host carries its list or group role (SPR-19) itself, so what the product writes on it is not moved, but for a name: WHILE label is not empty THE stepper SHALL hold the product's aria-label and aria-labelledby on that host as their data-aria- twins, so that label is its whole name although the platform gives aria-labelledby the precedence, and WHEN label is emptied SHALL give them back as they were written; WHILE label is empty a name the product gives so — aria-label, or aria-labelledby naming an element — SHALL be its name and SHALL NOT be reported as having none in debug builds (SPR-21). WHEN the product removes one, or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaLabelledByElements) to null, THE stepper SHALL take it away. |
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-stepper | TanreiStepper | TanreiStepper | TanreiStepper | Stepper |
label · Propiedad | label | label | contentDescription | semanticLabel | accessibilityLabel |
value · Propiedad | value | current | current | current | value |
layout · Propiedad | layout | layout | layout | layout | layout |
pressable · Propiedad | pressable | pressable | pressable | pressable | pressable |
completedText · Propiedad | completedText | completedText | completedText | completedText | completedText |
errorText · Propiedad | errorText | errorText | errorText | errorText | errorText |
positionText · Propiedad | positionText | positionText | positionText | positionText | positionText |
select · Evento | select | onSelect | onSelect | onSelect | onSelect |
| Notas | <tanrei-stepper label="Checkout" value="payment" layout="horizontal" pressable="visited"> holds <tanrei-stepper-step> children, in order. The stepper is a role="list" named by aria-label, each step host a role="listitem" with aria-current="step" on the current one; a pressable step draws a native <button> in its shadow root around its marker and text, a step that is not pressable the same parts in a <div>. The words for a condition are a visually hidden span after the label. The compact form is drawn in the stepper's own shadow root, where the steps are not displayed, and the host's role becomes group. The switch from horizontal to compact reads the host's width with a ResizeObserver against comp.stepper.step.min-width measured from a probe. select is a CustomEvent with detail.value; value is never set by the element. React: Stepper and StepperStep, generated wrappers. Fixtures fill their stage: 600 wide for a horizontal stepper, 360 for a vertical one, 320 for a compact one. | TanreiStepper(_ label:, steps:, current: ID?, layout:, pressable:, onSelect:). Not SwiftUI's Stepper, which increments a value (the number input's steppers are that). The list is an accessibility container; the current step carries the .isSelected trait and its position as its accessibility value, because iOS has no current-step state. The compact switch reads the proposed width (ViewThatFits). | TanreiStepper(steps, current, onSelect, layout, pressable, contentDescription, modifier). A collectionInfo list with collectionItemInfo per step; the current step is selected = true with its position in stateDescription, because Compose has no current-step semantics. The compact switch reads the incoming constraints (BoxWithConstraints). | TanreiStepper(steps:, current:, onSelect:, layout:, pressable:, semanticLabel:), built with the widgets library, without Material's Stepper. Semantics(container: true, label:) around a list; the current step Semantics(selected: true) with its position in its value. The compact switch reads the incoming constraints (LayoutBuilder). | <Stepper steps={StepperStep[]} value layout pressable onSelect accessibilityLabel />. The list has role="list" where the platform maps it, each step role="listitem"; the current step aria-current on the web target and accessibilityState.selected with its position elsewhere. A pressable step is a Pressable with role="button". The compact switch reads onLayout. |
Tokens
| Token | Alias de | Valor resuelto (claro) |
|---|---|---|
--tanrei-comp-stepper-bar-color | sys.color.outline-variant | |
--tanrei-comp-stepper-bar-filled-color | sys.color.primary | |
--tanrei-comp-stepper-bar-gap | sys.space.space50 | 4px |
--tanrei-comp-stepper-bar-shape | sys.shape.corner.full | 9999px |
--tanrei-comp-stepper-bar-thickness | sys.space.space50 | 4px |
--tanrei-comp-stepper-complete-container-color | — | |
--tanrei-comp-stepper-complete-description-color | sys.color.on-surface-variant | |
--tanrei-comp-stepper-complete-disabled-container-color | — | |
--tanrei-comp-stepper-complete-disabled-description-color | — | |
--tanrei-comp-stepper-complete-disabled-label-color | — | |
--tanrei-comp-stepper-complete-disabled-marker-color | — | |
--tanrei-comp-stepper-complete-disabled-marker-content-color | — | |
--tanrei-comp-stepper-complete-disabled-marker-outline-color | — | |
--tanrei-comp-stepper-complete-disabled-state-layer-color | — | |
--tanrei-comp-stepper-complete-focused-container-color | — | |
--tanrei-comp-stepper-complete-focused-description-color | — | |
--tanrei-comp-stepper-complete-focused-label-color | — | |
--tanrei-comp-stepper-complete-focused-marker-color | — | |
--tanrei-comp-stepper-complete-focused-marker-content-color | — | |
--tanrei-comp-stepper-complete-focused-marker-outline-color | — | |
--tanrei-comp-stepper-complete-focused-state-layer-color | — | |
--tanrei-comp-stepper-complete-hovered-container-color | — | |
--tanrei-comp-stepper-complete-hovered-description-color | — | |
--tanrei-comp-stepper-complete-hovered-label-color | — | |
--tanrei-comp-stepper-complete-hovered-marker-color | — | |
--tanrei-comp-stepper-complete-hovered-marker-content-color | — | |
--tanrei-comp-stepper-complete-hovered-marker-outline-color | — | |
--tanrei-comp-stepper-complete-hovered-state-layer-color | — | |
--tanrei-comp-stepper-complete-label-color | sys.color.on-surface | |
--tanrei-comp-stepper-complete-marker-color | sys.color.secondary-container | |
--tanrei-comp-stepper-complete-marker-content-color | sys.color.on-secondary-container | |
--tanrei-comp-stepper-complete-marker-outline-color | sys.color.secondary-container | |
--tanrei-comp-stepper-complete-pressed-container-color | — | |
--tanrei-comp-stepper-complete-pressed-description-color | — | |
--tanrei-comp-stepper-complete-pressed-label-color | — | |
--tanrei-comp-stepper-complete-pressed-marker-color | — | |
--tanrei-comp-stepper-complete-pressed-marker-content-color | — | |
--tanrei-comp-stepper-complete-pressed-marker-outline-color | — | |
--tanrei-comp-stepper-complete-pressed-state-layer-color | — | |
--tanrei-comp-stepper-complete-state-layer-color | comp.stepper.complete.label.color | |
--tanrei-comp-stepper-connector-color | sys.color.outline-variant | |
--tanrei-comp-stepper-connector-complete-color | sys.color.primary | |
--tanrei-comp-stepper-connector-gap | sys.space.space50 | 4px |
--tanrei-comp-stepper-connector-thickness | sys.border.thick | 2px |
--tanrei-comp-stepper-container-padding | sys.space.space100 | 8px |
--tanrei-comp-stepper-container-shape | sys.shape.corner.small | 6px |
--tanrei-comp-stepper-current-container-color | — | |
--tanrei-comp-stepper-current-description-color | sys.color.on-surface-variant | |
--tanrei-comp-stepper-current-disabled-container-color | — | |
--tanrei-comp-stepper-current-disabled-description-color | — | |
--tanrei-comp-stepper-current-disabled-label-color | — | |
--tanrei-comp-stepper-current-disabled-marker-color | — | |
--tanrei-comp-stepper-current-disabled-marker-content-color | — | |
--tanrei-comp-stepper-current-disabled-marker-outline-color | — | |
--tanrei-comp-stepper-current-disabled-state-layer-color | — | |
--tanrei-comp-stepper-current-focused-container-color | — | |
--tanrei-comp-stepper-current-focused-description-color | — | |
--tanrei-comp-stepper-current-focused-label-color | — | |
--tanrei-comp-stepper-current-focused-marker-color | — | |
--tanrei-comp-stepper-current-focused-marker-content-color | — | |
--tanrei-comp-stepper-current-focused-marker-outline-color | — | |
--tanrei-comp-stepper-current-focused-state-layer-color | — | |
--tanrei-comp-stepper-current-hovered-container-color | — | |
--tanrei-comp-stepper-current-hovered-description-color | — | |
--tanrei-comp-stepper-current-hovered-label-color | — | |
--tanrei-comp-stepper-current-hovered-marker-color | — | |
--tanrei-comp-stepper-current-hovered-marker-content-color | — | |
--tanrei-comp-stepper-current-hovered-marker-outline-color | — | |
--tanrei-comp-stepper-current-hovered-state-layer-color | — | |
--tanrei-comp-stepper-current-label-color | sys.color.on-surface | |
--tanrei-comp-stepper-current-marker-color | sys.color.primary | |
--tanrei-comp-stepper-current-marker-content-color | sys.color.on-primary | |
--tanrei-comp-stepper-current-marker-outline-color | sys.color.primary | |
--tanrei-comp-stepper-current-pressed-container-color | — | |
--tanrei-comp-stepper-current-pressed-description-color | — | |
--tanrei-comp-stepper-current-pressed-label-color | — | |
--tanrei-comp-stepper-current-pressed-marker-color | — | |
--tanrei-comp-stepper-current-pressed-marker-content-color | — | |
--tanrei-comp-stepper-current-pressed-marker-outline-color | — | |
--tanrei-comp-stepper-current-pressed-state-layer-color | — | |
--tanrei-comp-stepper-current-state-layer-color | comp.stepper.current.label.color | |
--tanrei-comp-stepper-description-gap | sys.space.space25 | 2px |
--tanrei-comp-stepper-disabled-container-shape | — | 6px |
--tanrei-comp-stepper-disabled-opacity | — | 1 |
--tanrei-comp-stepper-error-container-color | — | |
--tanrei-comp-stepper-error-description-color | sys.color.error | |
--tanrei-comp-stepper-error-disabled-container-color | — | |
--tanrei-comp-stepper-error-disabled-description-color | — | |
--tanrei-comp-stepper-error-disabled-label-color | — | |
--tanrei-comp-stepper-error-disabled-marker-color | — | |
--tanrei-comp-stepper-error-disabled-marker-content-color | — | |
--tanrei-comp-stepper-error-disabled-marker-outline-color | — | |
--tanrei-comp-stepper-error-disabled-state-layer-color | — | |
--tanrei-comp-stepper-error-focused-container-color | — | |
--tanrei-comp-stepper-error-focused-description-color | — | |
--tanrei-comp-stepper-error-focused-label-color | — | |
--tanrei-comp-stepper-error-focused-marker-color | — | |
--tanrei-comp-stepper-error-focused-marker-content-color | — | |
--tanrei-comp-stepper-error-focused-marker-outline-color | — | |
--tanrei-comp-stepper-error-focused-state-layer-color | — | |
--tanrei-comp-stepper-error-hovered-container-color | — | |
--tanrei-comp-stepper-error-hovered-description-color | — | |
--tanrei-comp-stepper-error-hovered-label-color | — | |
--tanrei-comp-stepper-error-hovered-marker-color | — | |
--tanrei-comp-stepper-error-hovered-marker-content-color | — | |
--tanrei-comp-stepper-error-hovered-marker-outline-color | — | |
--tanrei-comp-stepper-error-hovered-state-layer-color | — | |
--tanrei-comp-stepper-error-label-color | sys.color.error | |
--tanrei-comp-stepper-error-marker-color | — | |
--tanrei-comp-stepper-error-marker-content-color | sys.color.error | |
--tanrei-comp-stepper-error-marker-outline-color | sys.color.error | |
--tanrei-comp-stepper-error-pressed-container-color | — | |
--tanrei-comp-stepper-error-pressed-description-color | — | |
--tanrei-comp-stepper-error-pressed-label-color | — | |
--tanrei-comp-stepper-error-pressed-marker-color | — | |
--tanrei-comp-stepper-error-pressed-marker-content-color | — | |
--tanrei-comp-stepper-error-pressed-marker-outline-color | — | |
--tanrei-comp-stepper-error-pressed-state-layer-color | — | |
--tanrei-comp-stepper-error-state-layer-color | comp.stepper.error.label.color | |
--tanrei-comp-stepper-focused-container-shape | — | 6px |
--tanrei-comp-stepper-focused-opacity | — | 1 |
--tanrei-comp-stepper-hovered-container-shape | — | 6px |
--tanrei-comp-stepper-hovered-opacity | — | 1 |
--tanrei-comp-stepper-incomplete-container-color | — | |
--tanrei-comp-stepper-incomplete-description-color | sys.color.on-surface-variant | |
--tanrei-comp-stepper-incomplete-disabled-container-color | — | |
--tanrei-comp-stepper-incomplete-disabled-description-color | — | |
--tanrei-comp-stepper-incomplete-disabled-label-color | — | |
--tanrei-comp-stepper-incomplete-disabled-marker-color | — | |
--tanrei-comp-stepper-incomplete-disabled-marker-content-color | — | |
--tanrei-comp-stepper-incomplete-disabled-marker-outline-color | — | |
--tanrei-comp-stepper-incomplete-disabled-state-layer-color | — | |
--tanrei-comp-stepper-incomplete-focused-container-color | — | |
--tanrei-comp-stepper-incomplete-focused-description-color | — | |
--tanrei-comp-stepper-incomplete-focused-label-color | — | |
--tanrei-comp-stepper-incomplete-focused-marker-color | — | |
--tanrei-comp-stepper-incomplete-focused-marker-content-color | — | |
--tanrei-comp-stepper-incomplete-focused-marker-outline-color | — | |
--tanrei-comp-stepper-incomplete-focused-state-layer-color | — | |
--tanrei-comp-stepper-incomplete-hovered-container-color | — | |
--tanrei-comp-stepper-incomplete-hovered-description-color | — | |
--tanrei-comp-stepper-incomplete-hovered-label-color | — | |
--tanrei-comp-stepper-incomplete-hovered-marker-color | — | |
--tanrei-comp-stepper-incomplete-hovered-marker-content-color | — | |
--tanrei-comp-stepper-incomplete-hovered-marker-outline-color | — | |
--tanrei-comp-stepper-incomplete-hovered-state-layer-color | — | |
--tanrei-comp-stepper-incomplete-label-color | sys.color.on-surface-variant | |
--tanrei-comp-stepper-incomplete-marker-color | — | |
--tanrei-comp-stepper-incomplete-marker-content-color | sys.color.on-surface-variant | |
--tanrei-comp-stepper-incomplete-marker-outline-color | sys.color.outline | |
--tanrei-comp-stepper-incomplete-pressed-container-color | — | |
--tanrei-comp-stepper-incomplete-pressed-description-color | — | |
--tanrei-comp-stepper-incomplete-pressed-label-color | — | |
--tanrei-comp-stepper-incomplete-pressed-marker-color | — | |
--tanrei-comp-stepper-incomplete-pressed-marker-content-color | — | |
--tanrei-comp-stepper-incomplete-pressed-marker-outline-color | — | |
--tanrei-comp-stepper-incomplete-pressed-state-layer-color | — | |
--tanrei-comp-stepper-incomplete-state-layer-color | comp.stepper.incomplete.label.color | |
--tanrei-comp-stepper-marker-gap | sys.space.space100 | 8px |
--tanrei-comp-stepper-marker-icon-size | sys.icon.extra-small | 16px |
--tanrei-comp-stepper-marker-icon-weight | sys.icon.mark.weight | 500 |
--tanrei-comp-stepper-marker-outline-width | sys.border.thick | 2px |
--tanrei-comp-stepper-marker-shape | sys.shape.corner.full | 9999px |
--tanrei-comp-stepper-marker-size | — | 24px |
--tanrei-comp-stepper-motion-feedback-duration | sys.motion.role.feedback | 450ms |
--tanrei-comp-stepper-motion-state-duration | sys.motion.role.state.large | 250ms |
--tanrei-comp-stepper-motion-state-easing | sys.motion.easing.state | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-stepper-position-color | sys.color.on-surface-variant | |
--tanrei-comp-stepper-position-gap | sys.space.space100 | 8px |
--tanrei-comp-stepper-pressed-container-shape | — | 6px |
--tanrei-comp-stepper-pressed-opacity | — | 1 |
--tanrei-comp-stepper-step-min-width | — | 120px |
--tanrei-comp-stepper-description-typescale | sys.typescale.body-small | 400 13px/1.5385 |
--tanrei-comp-stepper-label-typescale | sys.typescale.label | 500 14px/1.4286 |
--tanrei-comp-stepper-marker-label-typescale | sys.typescale.label-small | 500 12px/1.3333 |
--tanrei-comp-stepper-position-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.
horizontal
label: Checkout value: payment completedText: Completed errorText: Has an error items: 4 horizontal-descriptions
label: Checkout value: shipping completedText: Completed errorText: Has an error items: 4 horizontal-error
label: Checkout value: payment completedText: Completed errorText: Has an error items: 4 current-error
label: Checkout value: payment completedText: Completed errorText: Has an error items: 4 pressable-visited
label: Checkout value: payment pressable: visited completedText: Completed errorText: Has an error items: 4 pressable-disabled
label: Set-up value: profile pressable: all completedText: Completed errorText: Has an error items: 4 finished
label: Checkout completedText: Completed errorText: Has an error items: 3 long-labels
label: Application value: documents completedText: Completed errorText: Has an error items: 3 vertical
label: Set-up value: profile layout: vertical completedText: Completed errorText: Has an error items: 4 vertical-error
label: Set-up value: team layout: vertical pressable: visited completedText: Completed errorText: Has an error items: 4 compact
label: Checkout value: shipping layout: compact completedText: Completed errorText: Has an error positionText: Step {position} of {count} items: 5 compact-error
label: Checkout value: payment layout: compact completedText: Completed errorText: Has an error positionText: Step {position} of {count} items: 4 horizontal-rtl
label: الدفع value: payment completedText: مكتمل errorText: به خطأ direction: rtl items: 4 compact-rtl
label: الدفع value: shipping layout: compact completedText: مكتمل errorText: به خطأ positionText: الخطوة {position} من {count} direction: rtl items: 4 Generado a partir de specs/stepper.spec.json, tokens/comp/stepper.tokens.json, design/tokens/
Usa un indicador de pasos cuando una persona recorre un flujo de tres a siete pasos en un orden que fija el producto, y saber dónde está y cuánto le queda la ayuda a terminar: una compra, un registro en varias partes, una solicitud. Muéstralo encima del contenido del paso (horizontal) o a su lado, en una columna (vertical).
No uses un indicador de pasos:
- para instrucciones que un lector sigue por su cuenta. Eso es Pasos: un procedimiento numerado sin posición, cuyos marcadores son anillos simples y nunca muestran el progreso.
- para un flujo de dos pasos, o uno tan corto que la posición no dice nada. Basta un encabezado que diga para qué sirve esta página.
- para una lista larga de tareas independientes que se hacen en cualquier orden. Eso es una lista de tareas: una fila por tarea con su estado, cada una un enlace.
- en lugar de la navegación propia del flujo. Mantén los botones Atrás y Continuar. El indicador de pasos dice dónde está la persona; no es la forma en que se mueve la mayoría.
| Estado | Qué significa | Cómo se dibuja |
|---|---|---|
| Actual | Donde está la persona. | Un marcador relleno con el número del paso. |
| Completado | Hecho. De forma predeterminada, todos los pasos anteriores al actual. | Un marcador con una marca de verificación. |
| Error | Necesita la atención de la persona, esté donde esté. | Un anillo y un glifo de prioridad, y la etiqueta en el color de error. |
| Incompleto | Falta todavía. De forma predeterminada, todos los pasos posteriores al actual. | Un anillo con el número del paso. |
status en un paso es auto de forma predeterminada: completado antes del paso actual, incompleto después. Establécelo cuando tu flujo sepa más: error para un paso que hay que corregir, complete para un paso hecho fuera de orden, incomplete para un paso que se saltó y todavía hay que hacer. Cada estado se distingue por la forma de su marcador, no solo por el color.
Cuando el flujo termina, deja value vacío y marca todos los pasos como complete.
pressable="visited"permite a la persona pulsar los pasos por los que ya pasó (completados o con un error) para volver a ellos. La mayoría de los flujos quieren esto.pressable="all"le permite pulsar cualquier paso que no sea el actual, para un flujo cuyos pasos pueden hacerse en cualquier orden.pressable="none"(el predeterminado) solo muestra la posición.
Un paso pulsable se ve igual que uno que no lo es hasta que tiene el cursor encima o recibe el foco, como en la mayoría de los sistemas. Si tus usuarios necesitan más pistas, dilo cerca del indicador («Selecciona un paso para cambiarlo»). El paso actual nunca es pulsable. Un paso al que todavía no se puede ir (depende de una elección anterior) es disabled: se dibuja atenuado y se anuncia como no disponible.
Un indicador de pasos horizontal se vuelve compacto por sí solo cuando su ancho no admite todos los pasos con su ancho mínimo: una barra de segmentos rellena hasta el paso actual, la posición con tus textos («Paso 2 de 5») y la etiqueta del paso actual. layout="compact" pide esa forma con cualquier ancho. La forma compacta no se puede pulsar: de eso se encarga el botón Atrás del flujo. layout="vertical", en cambio, mantiene todos los pasos visibles en una columna.
- Nombra los pasos por lo que la persona hace o aporta, en una o dos palabras: Cuenta, Envío, Pago, Revisión.
- Mantén el mismo número de pasos de principio a fin. Si un paso solo aplica a veces, muéstralo y sáltalo, en lugar de añadirlo a mitad de camino.
- Pon el error en el paso donde la persona puede corregirlo, con una descripción breve de lo que está mal.
- No uses el indicador de pasos como la única forma de avanzar.
- No escribas números en las etiquetas. El marcador muestra el número y la lista lo anuncia.
- No uses un indicador de pasos para las secciones de una página ni como pestañas. Para eso están las Pestañas o una tabla de contenido.
- Rol
list- Etiquetado
- An ordered list named by label ("Checkout progress"). Each step is an item read as its label, then its condition in the product's words (completedText, errorText), then its description; the current step is exposed as the current step (aria-current="step"). The list gives each step its place ("3 of 4"), so the number in the marker is not read again. In the compact form the stepper is a group named by label that reads the position and the current step's label, as drawn.
- 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 next or previous pressable step, in the order of the steps; a step that cannot be pressed is not a stop. |
| Enter / Space | Presses the focused step: the stepper emits select with its value, and the product goes there. |
Notas
- The stepper is an ordered list with the current item marked, as in the W3C's tutorial on forms in several steps: a step's place comes from the list, its condition from words the product gives, and the current step from aria-current="step". It is not a landmark: it belongs to the flow's content, and a page has one.
- Condition is never said by color alone (WCAG 1.4.1): the current marker is filled and holds the number, a complete marker holds a check, an error marker a different glyph, an incomplete marker is a ring; each is also said in words to assistive technology.
- Contrast in the default system: the ring of an incomplete step is outline, held to 3:1 on the surface; the current marker's primary fill is held to 3:1, and its number on-primary to 4.5:1 on it; the complete marker's secondary-container fill is not held to 3:1 by itself, and does not need to be, because its check (on-secondary-container, 4.5:1) identifies it. Labels are on-surface or on-surface-variant (4.5:1), the error label error (4.5:1). The connector and the bar are decorative.
- Pressing a step only asks to go there (select): the product decides, and moves value. A step that cannot be pressed is plain text and not a stop; a disabled step of a pressable stepper is a disabled button, so that a person hears it cannot be gone to now.
- The compact form draws no pressable step: a person goes back with the flow's own Back control. What is drawn is what is heard: the position and the current step.
- How a state looks is a value decision of the active design system; the stepper reads the state's tokens and never computes the effect itself.
- Not the steps of a procedure: a set of instructions to read, with no position, is Steps, whose markers are hairline rings with no fill, no glyph and no state.
Generado a partir de specs/stepper.spec.json, tokens/sys/measure.tokens.json
- El indicador de pasos es una lista ordenada con el nombre de su
label. Cada paso es un elemento que se lee como su etiqueta, luego el texto de su estado (completed-text,error-text) y luego su descripción. La lista da a cada paso su lugar («3 de 4»), así que el número del marcador no se vuelve a leer. - El paso actual se expone como el paso actual (
aria-current="step"). - Un paso pulsable es un botón nativo y una parada de tabulación, en el orden de los pasos. Enter y Espacio lo pulsan. Un paso que no se puede pulsar es texto simple y no es una parada. Un paso deshabilitado de un indicador pulsable es un botón deshabilitado.
- Los marcadores, los glifos, los conectores y la barra quedan ocultos para la tecnología de apoyo.
- Los estados se distinguen por la forma además de por el color: un marcador relleno, una marca de verificación, un glifo de prioridad, un anillo.
- En la forma compacta, el indicador es un único grupo con el nombre de su etiqueta, que lee lo que se dibuja: la posición y la etiqueta del paso actual, y el texto de error cuando el paso actual tiene uno.
- Las etiquetas y las descripciones saltan de línea y nunca se cortan. Con tamaños de texto mayores todo crece, y el indicador sigue volviéndose compacto según el ancho del que dispone.
- Con colores forzados, el marcador actual toma el color de resaltado y todo lo demás el color del texto.
- Las compilaciones de depuración notifican una etiqueta que falta, un valor que no nombra ningún paso, un valor de paso vacío o repetido, un paso sin etiqueta, un indicador con menos de dos pasos, un paso actual marcado como deshabilitado, una frase de posición sin
{position}y un texto que falta.
- Da al indicador de pasos un
labelque diga qué flujo sigue («Progreso de la compra»). - Da
completed-text,error-textyposition-texten tu idioma, o una sola vez consetWords(). - Mantén los botones Atrás y Continuar propios del flujo, y mueve el foco al encabezado del nuevo paso cuando el paso cambie, para que quien usa un lector de pantalla oiga dónde está.
- Cuando un paso tiene un error, muestra también el error en sí en el contenido del paso. El indicador de pasos solo dice que el paso necesita atención.