# ListRow

> La fila de lista de iCloud: ícono de 32, título en 17, detalle gris, valor a la derecha, punto de color y chevron; en secciones con su total y con la selección de Drive.

```tsx
import { List, ListRow, ListSection } from "sebs7n-ui/list-row"
```

Sin `"use client"`: sirve en un Server Component.

## Ejemplos

### La lista maestra

Ícono de 32, título en 17, detalle gris debajo y el saldo a la derecha. Tocá una fila: la elegida va en el acento mientras la lista tiene el foco y en gris cuando el foco se va (hacé click afuera).

```tsx
import { List, ListRow } from "sebs7n-ui/list-row"
import { ReceiptIcon } from "lucide-react"
import { useState } from "react"

function Maestra() {
  const [elegido, setElegido] = useState("nube")
  return (
    <List aria-label="Clientes" className="w-full max-w-md">
      {CLIENTES.map((cliente) => (
        <ListRow
          description={cliente.detalle}
          icon={<ReceiptIcon />}
          key={cliente.id}
          onClick={() => setElegido(cliente.id)}
          selected={elegido === cliente.id}
          title={cliente.nombre}
          trailing={cliente.saldo}
        />
      ))}
    </List>
  )
}
```

### El desglose de espacio

La lista de Almacenamiento: secciones de 19/600 con el total a la derecha, el detalle en una columna del medio (`inline`) y el punto de color de la categoría al final.

```tsx
import { FileTextIcon, FolderIcon, ImageIcon } from "lucide-react"
import { List, ListRow, ListSection } from "sebs7n-ui/list-row"

function Desglose() {
  return (
    <List aria-label="Espacio usado" className="w-full max-w-xl">
      <ListSection title="Usado por la cuenta" total="23,6 GB">
        <ListRow description="1.204 comprobantes" dot="amber" icon={<FileTextIcon />} inline title="Facturas" trailing="13,5 GB" />
        <ListRow description="Todos los archivos" dot="purple" icon={<FolderIcon />} inline title="Documentos" trailing="6,1 GB" />
        <ListRow description="Logos y firmas" dot="teal" icon={<ImageIcon />} inline title="Imágenes" trailing="4,0 GB" />
      </ListSection>
    </List>
  )
}
```

### Filas que navegan

Con `render` la fila es un link y el chevron dice que lleva a otra pantalla.

```tsx
import { List, ListRow } from "sebs7n-ui/list-row"

function Navegacion() {
  return (
    <List aria-label="Ajustes de facturación" className="w-full max-w-md">
      <ListRow chevron render={<a href="#datos-fiscales" />} title="Datos fiscales" />
      <ListRow chevron description="2 puntos de venta" render={<a href="#puntos-de-venta" />} title="Puntos de venta" />
      <ListRow chevron render={<a href="#numeracion" />} title="Numeración" trailing="0001-00000124" />
    </List>
  )
}
```

## Props

### List

Hereda las props de `<ul>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

### ListRow

Hereda las props de `<li>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `chevron` | `boolean` | `false` | El › de una fila que navega a otra pantalla. |
| `description` | `React.ReactNode` | — | El detalle: 14 gris debajo del título, o una columna del medio en 17 con `inline`. |
| `dot` | `"brand" \| "gray" \| "red" \| "amber" \| "green" \| "blue" \| "teal" \| "purple" \| "pink"` | — | Punto de 8 del color de la categoría (la paleta de `Badge`). Decorativo. |
| `icon` | `React.ReactNode` | — | Ícono o avatar en una caja de 32. Decorativo. |
| `inline` | `boolean` | `false` | Pone el detalle en una columna del medio, como el desglose de Almacenamiento. |
| `onClick` | `React.MouseEventHandler<HTMLElement>` | — | Hace la fila un `<button>`. |
| `render` | `RenderElement` | — | El elemento interactivo de la fila (`<a>`, `Link`). Recibe el contenido y las clases. |
| `selected` | `boolean` | `false` | La fila elegida: acento con el foco en la lista, gris sin foco; `aria-current` en la fila interactiva. |
| `title` | `React.ReactNode` | — | Primera línea, 17 en texto principal. |
| `trailing` | `React.ReactNode` | — | A la derecha: un importe, un tamaño, una hora. |
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

### ListSection

Hereda las props de `<li>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `title` * | `React.ReactNode` | — | El título del grupo (19/600). Es el nombre accesible de la lista de adentro. |
| `total` | `React.ReactNode` | — | El total a la derecha de la cabecera, en 19/600 con cifras tabulares. |
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

`*` obligatoria.

## Teclado

| Tecla | Qué hace |
|---|---|
| Tab | Recorre las filas interactivas (las que tienen `onClick` o `render`). Las demás no son paradas. |
| Enter | Activa la fila: el botón o el link. |
| Espacio | Activa la fila si es un botón. |

## Accesibilidad

- `List` es un `<ul role="list">` y cada `ListRow` un `<li>`: el lector cuenta los ítems (el `role` explícito es para Safari, que se lo saca a una lista sin viñetas).
- `ListSection` es un `<li>` con su propia lista adentro, **nombrada por el título** (`aria-labelledby`): el lector dice «Usado por la cuenta, lista, 3 ítems».
- Con `onClick` la fila es un `<button>`; con `render` es tu `<a>`. Nunca un `<div>` clickeable.
- `selected` suma `aria-current="true"` en la fila interactiva: el ítem que está abierto en el panel de detalle.
- El ícono, el punto y el chevron son decorativos (`aria-hidden`). El punto de color **no puede ser el único dato**: la categoría tiene que estar en el texto.
- La lista lleva `tabIndex={-1}`, como la `Table`: un click en una fila deja el foco adentro y la elegida sigue en el acento. Sin foco adentro, la elegida es gris.

## Reglas de uso

- **Para una lista, no una tabla.** Si las columnas se comparan entre filas (importe, fecha, estado), es una `Table`. Si cada fila es una cosa con su nombre y un dato, es una `List`.
- **`description` debajo del título** para la lista maestra (Mail, clientes); **`inline`** para un desglose donde el detalle es una columna (Almacenamiento).
- **`chevron` solo en filas que navegan** a otra pantalla. Una fila que abre el detalle al lado (split view) no lleva chevron: lleva `selected`.
- **Color propio adentro de una fila elegida → `selectionSecondaryClassName`.** Funciona igual que en la `Table`.
- Las props de texto se llaman como las de `CardRow` (`title`, `description`, `trailing`): pasar de un widget a una lista es cambiar el componente, no las props.
- Sin caja: la lista vive sobre la página o en un panel. Para listas largas, virtualizá vos y pasale las filas visibles.

## Relacionados

[table](/docs/components/table.md) · [card](/docs/components/card.md) · [split-view](/docs/components/split-view.md)
