# Sidebar

> La navegación lateral de un panel: header, grupos, ítems con ícono y contador, footer y modo colapsado.

```tsx
import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, … } from "sebs7n-ui/sidebar"
```

## Ejemplos

### Completo

El estado de colapsado lo guarda la app: acá vive en un `useState`, en una app real en una cookie.

```tsx
import { Badge } from "sebs7n-ui/badge"
import { DropdownMenuItem } from "sebs7n-ui/dropdown-menu"
import { FileTextIcon, LogOutIcon, SettingsIcon, UsersIcon } from "lucide-react"
import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarItem, SidebarItemBadge, SidebarSearch } from "sebs7n-ui/sidebar"
import { Switch } from "sebs7n-ui/switch"
import { UserMenu } from "sebs7n-ui/user-menu"
import { useState } from "react"

function Completo() {
  const [colapsado, setColapsado] = useState(false)
  return (
    <div className="flex flex-col gap-4">
      <label className="flex items-center gap-2 text-copy-13 text-gray-900">
        <Switch checked={colapsado} onCheckedChange={setColapsado} size="sm" />
        Colapsado
      </label>
      <div className="h-[26rem] overflow-hidden rounded-xl border border-gray-400">
        <Sidebar className="h-full" collapsed={colapsado}>
          <SidebarHeader>
            <div className="flex h-8 items-center gap-2 px-1">
              <div className="size-6 shrink-0 rounded-md bg-gray-1000" />
              <span className="text-label-14 font-medium group-data-collapsed/sidebar:hidden">Acme</span>
              <Badge className="group-data-collapsed/sidebar:hidden" size="sm">
                Admin
              </Badge>
            </div>
            <SidebarSearch shortcut="⌘K" />
          </SidebarHeader>
          <SidebarContent>
            <SidebarGroup>
              <SidebarGroupLabel>Operación</SidebarGroupLabel>
              <SidebarItem active icon={<FileTextIcon />}>
                Facturas
              </SidebarItem>
              <SidebarItem icon={<UsersIcon />}>
                Clientes
                <SidebarItemBadge label="3 pendientes">3</SidebarItemBadge>
              </SidebarItem>
            </SidebarGroup>
            <SidebarGroup>
              <SidebarGroupLabel>Configuración</SidebarGroupLabel>
              <SidebarItem icon={<SettingsIcon />}>Ajustes</SidebarItem>
            </SidebarGroup>
          </SidebarContent>
          <SidebarFooter>
            <UserMenu
              signOut={
                <DropdownMenuItem>
                  <LogOutIcon />
                  Cerrar sesión
                </DropdownMenuItem>
              }
              user={{ name: "Ana Pérez", email: "ana@acme.com" }}
            />
          </SidebarFooter>
        </Sidebar>
      </div>
    </div>
  )
}
```

## Props

### Sidebar

Hereda las props de `<aside>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `collapsed` | `boolean` | `false` | Solo íconos, 64px. El ancho cambia sin animación: animarlo hace saltar todo el contenido. |
| `className` | `string` | — | — |

### SidebarContent

Hereda las props de `<nav>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `aria-label` | `string` | `"Navegación principal"` | Defines a string value that labels the current element. |
| `className` | `string` | — | — |

### SidebarFooter

Hereda las props de `<div>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `className` | `string` | — | — |

### SidebarGroup

Hereda las props de `<div>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `className` | `string` | — | — |

### SidebarGroupLabel

Hereda las props de `<div>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `id` | `string` | — | — |
| `className` | `string` | — | — |

### SidebarHeader

Hereda las props de `<div>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `className` | `string` | — | — |

### SidebarItem

Hereda las props de `<a>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `active` | `boolean` | `false` | Marca la sección actual: pone aria-current="page" y data-active. |
| `icon` | `React.ReactNode` | — | — |
| `render` | `React.ReactElement \| ComponentRenderFn<RenderFunctionProps, State>` | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| `tooltip` | `React.ReactNode` | — | Texto del tooltip cuando el sidebar está colapsado. Por defecto, el label si es texto. |
| `className` | `string` | — | — |

### SidebarItemBadge

Hereda las props de `<span>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `label` | `string` | — | Texto para el lector de pantalla con contexto ("3 pendientes"). Por defecto, el número visible. |
| `className` | `string` | — | — |

### SidebarSearch

Hereda las props de `<button>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `aria-keyshortcuts` | `string` | `KEYSHORTCUTS[String(shortcut)]` | Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element. |
| `placeholder` | `string` | `"Buscar…"` | Texto del botón (y su nombre accesible). |
| `shortcut` | `React.ReactNode` | — | Solo muestra el `Kbd` y lo anuncia. Escuchar la tecla es trabajo de la app. |
| `className` | `string` | — | — |

## Teclado

| Tecla | Qué hace |
|---|---|
| Tab | Recorre los ítems en orden. |
| Enter | Navega. |
| ⌘B / Ctrl+B | Colapsa y expande — **lo registra la app**, no el paquete. |

## Accesibilidad

- `SidebarContent` es un `<nav>` con `aria-label="Navegación principal"` por defecto.
- `SidebarItem active` pone `aria-current="page"`.
- `SidebarItemBadge` acepta `label` para que el contador se lea con contexto: «Clientes, 3 pendientes».
- `SidebarSearch shortcut` emite `aria-keyshortcuts`, pero **no registra el atajo**: eso es de la app.
- Colapsado, cada ítem muestra su label en un tooltip y conserva el nombre accesible.

## Reglas de uso

- **El paquete no guarda el estado de colapsado.** Guardalo en una cookie y pasá `defaultCollapsed` desde el layout: así el server ya renderiza el ancho correcto y no hay salto.
- `SidebarItem` es un `<a>`: con Next, `render={<Link href />}`.
- Lo que sea texto del header se oculta con `group-data-collapsed/sidebar:hidden`.
- Grupos de 3 a 7 ítems con `SidebarGroupLabel`. Si hay más de ~20 ítems en total, hace falta una paleta de comandos.

## Relacionados

[app-shell](/docs/components/app-shell.md) · [user-menu](/docs/components/user-menu.md) · [navigation-menu](/docs/components/navigation-menu.md)
