vaiperui

componentes / menu

Menu

Botón de menú desplegable con navegación por flechas, búsqueda al escribir, íconos, separadores e ítems peligrosos.

Cómo usar

La lista es `role="menu"` con botones `menuitem`. Flechas, Home y End mueven entre ítems (los deshabilitados se saltan), escribir una letra salta a una coincidencia, Enter/Espacio selecciona, Esc cierra y devuelve el foco al disparador. `onSelect` corre al hacer clic y con teclado; llama `event.preventDefault()` ahí para mantener el menú abierto. Se compone con `MenuItem`, `MenuLabel` y `MenuSeparator`.

preview
Menu.tsx
import { Button, Menu, MenuItem, MenuLabel, MenuSeparator } from "vaiperui";
<Menu trigger={<Button variant="outlined">Acciones</Button>} label="Acciones">
<MenuLabel>Proyecto</MenuLabel>
<MenuItem icon="✎" onSelect={() => rename()}>Renombrar</MenuItem>
<MenuItem disabled>Archivar</MenuItem>
<MenuSeparator />
<MenuItem destructive icon="✕">Eliminar</MenuItem>
</Menu>

Alineación

preview
start
center
end
alineacion.tsx
<Menu align="start" trigger={<Button>start</Button>}>...</Menu>
<Menu align="center" trigger={<Button>center</Button>}>...</Menu>
<Menu align="end" trigger={<Button>end</Button>}>...</Menu>

Props

PropValoresPredeterminadoDescripción
triggerReactElementningunoBotón que abre el menú (necesita ref, foco y onClick)
labelstringningunoNombre accesible del menú
side / aligntop | right | bottom | left / start | center | endbottom / startLado del disparador y alineación
open / defaultOpen / onOpenChangeboolean / boolean / (open) => voidningunoEstado abierto controlado o no controlado
sizesm | md | lgmdTamaño del texto de los ítems
radius / animationnone | sm | md | lg | full / none | smooth | fast | bouncelg / fastRedondeo y velocidad de la transición de entrada
MenuItemonSelect, icon, destructive, disabledningunoÍtem; `onSelect` corre con clic/teclado y el menú se cierra salvo que se impida

Accesibilidad

  • La lista es `role="menu"` nombrada por `label`; cada `MenuItem` es un `button` con `role="menuitem"`.
  • El disparador recibe `aria-haspopup="menu"`, `aria-expanded` y, mientras está abierto, `aria-controls`.
  • Al abrir, el foco va al primer ítem habilitado; los ítems deshabilitados se saltan con las flechas.
  • La navegación con flechas es circular, y escribir letras en menos de 500ms salta al siguiente ítem cuyo texto empieza con ellas.
  • Seleccionar un ítem cierra el menú y devuelve el foco al disparador, salvo que `onSelect` llame a `event.preventDefault()`.
  • `MenuSeparator` es `role="separator"`, `MenuLabel` es `role="presentation"` y los íconos de los ítems son `aria-hidden`.

Teclado

TeclaAcción
ArrowDownEn el disparador cerrado, abre el menú; dentro, va al siguiente ítem
ArrowUpVa al ítem anterior
Home / EndVa al primer / último ítem
A-ZBúsqueda al escribir: salta al ítem cuyo texto empieza con las letras escritas
Enter / SpaceActiva el ítem enfocado
EscCierra el menú y enfoca el disparador
TabCierra el menú y deja que el foco siga

Ten en cuenta

  • Los ítems deben ser acciones simples; no es una barra de menú y no hay ítems marcables (`menuitemcheckbox`/`menuitemradio`) ni submenús.
  • Pasa `label` para que el menú tenga nombre accesible; el disparador necesita texto visible o su propio `aria-label`.