Navegación
List Index
El índice A–Z de Contactos: una tira de letras junto a una lista agrupada, cada una un link a su sección, las vacías apagadas y, con el dedo, se desliza.
import { ListIndex } from "sebs7n-ui/list-index"Ejemplos
Clientes de la A a la Z
Una lista agrupada por inicial con la tira de letras al costado: cada letra es un link a su sección y las que no tienen clientes se ven apagadas. En un teléfono, apoyá el dedo en la tira y deslizalo.
import { List, ListRow, ListSection } from "sebs7n-ui/list-row"
import { ListIndex } from "sebs7n-ui/list-index"
function Clientes() {
return (
<div className="relative h-[660px] w-full max-w-md overflow-hidden rounded-surface border border-separator">
<div className="h-full overflow-y-auto scroll-smooth pe-8 motion-reduce:scroll-auto">
<List aria-label="Clientes">
{SECTIONS.map(([letter, names]) => (
<ListSection className="scroll-mt-2" id={`customer-${letter}`} key={letter} title={letter}>
{names.map((name) => (
<ListRow key={name} title={name} />
))}
</ListSection>
))}
</List>
</div>
<ListIndex
available={SECTIONS.map(([letter]) => letter)}
className="absolute inset-y-2 end-1"
getHref={(letter) => `#customer-${letter}`}
/>
</div>
)
}Props
Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».
ListIndex
Hereda las props de <nav>.
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
available* | readonly string[] | — | Las letras que tienen sección. Las demás se ven apagadas y no son links. |
getHref | (letter: string) => string | defaultHref | El destino de cada letra. Por defecto #A, #B…: la sección lleva ese id. Deslizar, mover solo la caja y pasar el foco con Enter necesitan un #… a un id de la página; con otro destino, la letra es un link común. |
labels | Partial<NonNullable<Labels["listIndex"]>> | — | Textos: label (el nombre del nav, «Índice alfabético»). El que viene por defecto es listIndexLabels: un provider sin el grupo listIndex (es opcional) cae a ese texto en español. |
letters | readonly string[] | ALPHABET | Todas las letras de la tira, en orden. Por defecto, A–Z. |
onPointerCancel | PointerEventHandler<T> | — | Se suma al de la tira, que termina el deslizamiento igual. |
onPointerDown | PointerEventHandler<T> | — | Corre antes de empezar a deslizar: con event.preventDefault() la tira no se desliza. |
onPointerMove | PointerEventHandler<T> | — | Corre antes de mover el deslizamiento: con event.preventDefault() ese movimiento no cambia de letra. |
onPointerUp | PointerEventHandler<T> | — | Se suma al de la tira, que termina el deslizamiento igual. |
className | string | — | Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana. |
Teclado
- Tab
- Recorre las letras que tienen sección; las apagadas no son paradas.
- Enter
- Sigue el link: la lista va a la sección de esa letra y el foco pasa a la sección (Tab sigue desde ahí).
Accesibilidad
- Es un
<nav>llamado «Índice alfabético» (labels.listIndex.label) con una<ol>de links: el lector lo ofrece en su lista de regiones y dice cuántas letras hay. - Las letras sin sección son
role="link"+aria-disabled="true"sinhref: se leen «atenuado» en vez de desaparecer, y no son paradas de Tab. - Cada letra ocupa 24 de ancho y el alto se reparte: en una tira de 624 o más, cada una llega a 24×24 (WCAG 2.5.8). Más corta, dale alto al contenedor o acortá
letters. - Deslizar es un atajo del dedo: lo mismo se logra tocando cada letra, o scrolleando la lista.
Reglas de uso
- Para listas largas ordenadas por nombre (clientes, proveedores) que ya están agrupadas por inicial: cada
ListSectionllevaidcon su letra (id="A"), o el que devuelvagetHref. availableson las letras que tienen sección;letterscambia la tira (sumá#oÑsi tu lista las usa).- Ponela al costado de la lista que scrollea, pegada con
stickyoabsolutey con el alto de la lista. La tira no scrollea: se reparte el alto que le den. - Si la lista scrollea en su propia caja (
overflow-yauto,scrolluoverlay), una letra mueve solo esa caja hasta la sección (respetascroll-margin-topyscroll-smooth): la página no salta. Si la sección está en la página, es el ancla de siempre. - Con el dedo (
pointer: coarse) se desliza: la lista sigue a la letra que está bajo el dedo sin sumar entradas al historial. - Solo por subpath (
sebs7n-ui/list-index).