Admin
Estado: EstableControl segmentado
Para los filtros del admin (Todos / Alumnos / Maestros / Admins) y cualquier grupo corto de opciones excluyentes. La pastilla viaja con resorte hasta la opción activa. Enlaces para filtros del servidor, radios nativos para un valor de formulario o del cliente, o pestañas ARIA para paneles.
- Admin
- Resorte
- Turbo
- Teclado
12 clases en los próximos 7 días · la siguiente, Reformer 7:00
148 clases este mes · 91% de asistencia
12 clases en los próximos 7 días · la siguiente, Reformer 7:00
148 clases este mes · 91% de asistencia
app/views/… (la demo de arriba)
<div class="@container flex w-full max-w-md flex-col items-center gap-5">
<%# Filtros del servidor: enlaces con aria-current. En tu app: href: people_path(role: "client"),
sin turbo: false (aquí evita que la demo recargue la página). %>
<%= render Ui::SegmentedControlComponent.new(label: "Filtrar por rol", selected: "all") do |seg| %>
<% seg.with_option(label: "Todos", value: "all", count: 47, href: "#segmented-todos", data: { turbo: false }) %>
<% seg.with_option(label: "Alumnos", value: "student", count: 38, href: "#segmented-alumnos", data: { turbo: false }) %>
<% seg.with_option(label: "Maestros", value: "teacher", count: 6, href: "#segmented-maestros", data: { turbo: false }) %>
<% seg.with_option(label: "Admins", value: "admin", count: 3, href: "#segmented-admins", data: { turbo: false }) %>
<% end %>
<%# Un valor para un formulario: radios nativos que se mandan con name:. %>
<%= render Ui::SegmentedControlComponent.new(label: "Periodo", name: "range", selected: "week", shape: :pill, variant: :solid) do |seg| %>
<% seg.with_option(label: "Hoy", value: "today") %>
<% seg.with_option(label: "Semana", value: "week") %>
<% seg.with_option(label: "Mes", value: "month") %>
<% seg.with_option(label: "Año", value: "year") %>
<% end %>
<%# Paneles de la misma vista: patrón ARIA tabs. %>
<div class="hidden w-full flex-col items-center gap-3 @sm:flex">
<%= render Ui::SegmentedControlComponent.new(label: "Clases", mode: :tabs, selected: "proximas", size: :md) do |seg| %>
<% seg.with_option(label: "Próximas", value: "proximas", count: 12, controls: "segmented-panel-proximas") %>
<% seg.with_option(label: "Pasadas", value: "pasadas", controls: "segmented-panel-pasadas") %>
<% end %>
<p id="segmented-panel-proximas" role="tabpanel" class="text-xs text-faint">12 clases en los próximos 7 días · la siguiente, Reformer 7:00</p>
<p id="segmented-panel-pasadas" role="tabpanel" class="text-xs text-faint" hidden>148 clases este mes · 91% de asistencia</p>
</div>
</div>Qué hace
- Pastilla con el resorte "morph" (posición y ancho por separado); sigue a la opción si cambia el ancho.
- En enlaces la pastilla se adelanta al clic mientras Turbo trae la página filtrada.
- Si no cabe, se desplaza sola hasta la activa y desvanece la orilla que tiene más.
- Dispara segmented-control:change con { value, index } en los tres modos.
- Sin JS la opción activa se marca sola con el mismo fondo.
Props
| Nombre | Tipo | Default | Descripción |
|---|---|---|---|
| label | String | — | Nombre accesible del grupo. |
| with_option(label:, value:, count:, href:, controls:) | slot | — | Una opción con su conteo; href la vuelve enlace, controls apunta a su panel (modo tabs). |
| selected | String | la primera | El value de la opción activa (p. ej. params[:role]). |
| mode | :links | :radio | :tabs | :links con href, si no :radio | Quién decide: el servidor, un formulario/el cliente o paneles de la vista. |
| name | String | nil | Modo radio: el nombre con el que se manda el valor. |
| form / attribute | FormBuilder / Symbol | nil | Modo radio: name y selected salen del modelo. |
| size / shape / variant | :sm|:md · :segment|:pill · :soft|:solid | :sm · :segment · :soft | Alto, forma (sigue el dial de redondez) y si la pastilla es una capa elevada o el acento lleno. tone: :subtle|:solid es el nombre anterior de variant:. |
| full_width | Boolean | false | Las opciones se reparten el ancho. |
Accesibilidad
- Enlaces: <nav> con aria-current=page; Tab entre opciones y ←/→ como atajo.
- Radio: radiogroup con <input type=radio> nativos; las flechas cambian la selección.
- Tabs: role=tablist/tab, aria-selected, aria-controls, tabindex itinerante, ←/→, Inicio y Fin.