Dropdown
Componente de menú desplegable para mostrar acciones y opciones.
Importar
Sección titulada «Importar»import { Dropdown } from 'asterui'Ejemplos
Sección titulada «Ejemplos»Dropdown Básico
Menú desplegable simple con elementos usando patrón compuesto.
import { Dropdown, Button } from 'asterui'
function App() {
return (
<Dropdown>
<Dropdown.Trigger>
<Button color="primary">Actions</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Edit</Dropdown.Item>
<Dropdown.Item>Duplicate</Dropdown.Item>
<Dropdown.Item>Delete</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
)
}
export default App Basado en Datos (prop menu)
Define elementos del menú a través de la prop menu en lugar de componentes compuestos.
import { Dropdown, Button } from 'asterui'
import { PencilIcon, DocumentDuplicateIcon, TrashIcon } from '@aster-ui/icons'
function App() {
const menuItems = [
{ key: 'edit', label: 'Edit', icon: <PencilIcon size="sm" /> },
{ key: 'duplicate', label: 'Duplicate', icon: <DocumentDuplicateIcon size="sm" /> },
{ type: 'divider' as const },
{ key: 'delete', label: 'Delete', danger: true, icon: <TrashIcon size="sm" /> },
]
return (
<Dropdown menu={{ items: menuItems }}>
<Dropdown.Trigger>
<Button color="primary">Data-Driven</Button>
</Dropdown.Trigger>
</Dropdown>
)
}
export default App Ubicación
El menú desplegable puede posicionarse en diferentes direcciones.
import { Dropdown, Button, Space } from 'asterui'
function App() {
return (
<Space direction="horizontal" size="sm" wrap>
<Dropdown placement="top">
<Dropdown.Trigger>
<Button>Top</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
<Dropdown.Item>Option 3</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown placement="bottom">
<Dropdown.Trigger>
<Button>Bottom</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
<Dropdown.Item>Option 3</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown placement="left">
<Dropdown.Trigger>
<Button>Left</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
<Dropdown.Item>Option 3</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown placement="right">
<Dropdown.Trigger>
<Button>Right</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
<Dropdown.Item>Option 3</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Space>
)
}
export default App Modos de Activación
Controla cómo se abre el desplegable: clic, hover o ambos.
import { Dropdown, Button, Space } from 'asterui'
function App() {
return (
<Space direction="horizontal" size="sm" wrap>
<Dropdown trigger={['click']}>
<Dropdown.Trigger>
<Button>Click</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown trigger={['hover']}>
<Dropdown.Trigger>
<Button>Hover</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Space>
)
}
export default App Con Iconos
Elementos del menú con iconos para mejor contexto visual.
import { Dropdown, Button } from 'asterui'
import { PencilIcon, DocumentDuplicateIcon, TrashIcon } from '@aster-ui/icons'
function App() {
return (
<Dropdown>
<Dropdown.Trigger>
<Button color="primary">Options</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item icon={<PencilIcon size="sm" />}>Edit</Dropdown.Item>
<Dropdown.Item icon={<DocumentDuplicateIcon size="sm" />}>Duplicate</Dropdown.Item>
<Dropdown.Item icon={<TrashIcon size="sm" />}>Delete</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
)
}
export default App Con Divisor
Separa secciones del menú con divisores.
import { Dropdown, Button } from 'asterui'
function App() {
return (
<Dropdown>
<Dropdown.Trigger>
<Button>Account</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Profile</Dropdown.Item>
<Dropdown.Item>Settings</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item>Help</Dropdown.Item>
<Dropdown.Item danger>Sign out</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
)
}
export default App Estados de Elementos
Los elementos pueden estar activos, deshabilitados o con estilo de peligro.
import { Dropdown, Button } from 'asterui'
function App() {
return (
<Dropdown>
<Dropdown.Trigger>
<Button>States</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item active>Active Item</Dropdown.Item>
<Dropdown.Item>Normal Item</Dropdown.Item>
<Dropdown.Item disabled>Disabled Item</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item danger>Delete Account</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
)
}
export default App Alineación
Alinea el menú desplegable al inicio, centro o final.
import { Dropdown, Button, Space } from 'asterui'
function App() {
return (
<Space direction="horizontal" size="sm" wrap>
<Dropdown placement="bottomLeft">
<Dropdown.Trigger>
<Button>Bottom Left</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown placement="bottom">
<Dropdown.Trigger>
<Button>Bottom Center</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown placement="bottomRight">
<Dropdown.Trigger>
<Button>Bottom Right</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item>Option 1</Dropdown.Item>
<Dropdown.Item>Option 2</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Space>
)
}
export default App Menú Contextual
Abre el desplegable con clic derecho usando el activador contextMenu.
import { Dropdown, Typography } from 'asterui'
import { PencilIcon, DocumentDuplicateIcon, TrashIcon } from '@aster-ui/icons'
function App() {
return (
<Dropdown trigger={['contextMenu']}>
<Dropdown.Trigger>
<div className="p-8 border-2 border-dashed border-base-300 rounded-lg text-center cursor-context-menu">
<Typography.Text type="secondary">Right-click here</Typography.Text>
</div>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item icon={<PencilIcon size="sm" />}>Edit</Dropdown.Item>
<Dropdown.Item icon={<DocumentDuplicateIcon size="sm" />}>Copy</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item icon={<TrashIcon size="sm" />} danger>Delete</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
)
}
export default App Con Submenú
Submenús anidados para opciones jerárquicas.
import { Dropdown, Button } from 'asterui'
import { PencilIcon, FolderIcon, Cog6ToothIcon } from '@aster-ui/icons'
function App() {
return (
<Dropdown>
<Dropdown.Trigger>
<Button>With Submenu</Button>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item icon={<PencilIcon size="sm" />}>Edit</Dropdown.Item>
<Dropdown.SubMenu title="More Options" icon={<FolderIcon size="sm" />}>
<Dropdown.Item>Option A</Dropdown.Item>
<Dropdown.Item>Option B</Dropdown.Item>
<Dropdown.Item>Option C</Dropdown.Item>
</Dropdown.SubMenu>
<Dropdown.SubMenu title="Settings" icon={<Cog6ToothIcon size="sm" />}>
<Dropdown.Item>Preferences</Dropdown.Item>
<Dropdown.Item>Account</Dropdown.Item>
</Dropdown.SubMenu>
<Dropdown.Divider />
<Dropdown.Item danger>Delete</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
)
}
export default App Botón Compacto con Dropdown
Combina un botón con un menú desplegable usando Join para una apariencia de botón dividido compacto. El botón se trata automáticamente como activador sin necesitar el wrapper Dropdown.Trigger. Se abre al pasar el cursor automáticamente.
import { Dropdown, Button, Join } from 'asterui'
import { UserIcon } from '@aster-ui/icons'
function App() {
const menuItems = [
{ key: 'profile', label: 'Profile' },
{ key: 'settings', label: 'Settings' },
{ type: 'divider' as const },
{ key: 'logout', label: 'Sign out', danger: true },
]
return (
<Join>
<Button color="primary">Actions</Button>
<Dropdown menu={{ items: menuItems }} placement="bottomRight">
<Button color="primary" icon={<UserIcon />} />
</Dropdown>
</Join>
)
}
export default App Dropdown de Icono Compacto
Botón desplegable solo con icono unido a otro botón usando la API simplificada (no necesita wrapper Dropdown.Trigger). Se abre al pasar el cursor para acceso rápido.
import { Dropdown, Button, Join } from 'asterui'
import { EllipsisVerticalIcon } from '@aster-ui/icons'
function App() {
return (
<Join>
<Button>Save</Button>
<Dropdown placement="bottomRight">
<Button icon={<EllipsisVerticalIcon />} />
<Dropdown.Menu>
<Dropdown.Item>Save and Close</Dropdown.Item>
<Dropdown.Item>Save as Draft</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item>Discard</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Join>
)
}
export default App Dropdown
Sección titulada «Dropdown»| Propiedad | Descripción | Tipo | Predeterminado |
|---|---|---|---|
children | Elemento activador y contenido del desplegable (patrón compuesto) | React.ReactNode | - |
menu | Configuración del menú (patrón basado en datos) | { items: DropdownMenuItemType[], onClick?: (info: { key: string; keyPath: string[] }) => void } | - |
trigger | Modo(s) de activación para el desplegable | ('click' | 'hover' | 'contextMenu')[] | ['hover'] |
placement | Ubicación del menú desplegable | 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight' | 'left' | 'right' | 'bottomLeft' |
open | Estado abierto controlado | boolean | - |
onOpenChange | Callback cuando cambia el estado abierto | (open: boolean, info?: { source }) => void | - |
disabled | Deshabilitar el desplegable | boolean | false |
arrow | Mostrar flecha apuntando al activador | boolean | { pointAtCenter?: boolean } | false |
autoAdjustOverflow | Ajustar automáticamente la ubicación del desplegable cuando está fuera de la pantalla | boolean | true |
mouseEnterDelay | Retraso antes de mostrar al pasar el ratón (segundos) | number | 0.15 |
mouseLeaveDelay | Retraso antes de ocultar al salir el ratón (segundos) | number | 0.1 |
destroyOnHidden | Destruir desplegable cuando esté oculto | boolean | false |
popupRender | Personalizar contenido del popup | (menu: ReactNode) => ReactNode | - |
data-testid | Prefijo de ID de prueba para elementos hijos | string | - |
className | Clases CSS adicionales | string | - |
Dropdown.Item
Sección titulada «Dropdown.Item»| Propiedad | Descripción | Tipo | Predeterminado |
|---|---|---|---|
key | Clave única para el elemento (prop key de React) | string | - |
children | Contenido del elemento | React.ReactNode | - |
label | Etiqueta del elemento (alternativa a children) | React.ReactNode | - |
icon | Icono a mostrar antes de la etiqueta | React.ReactNode | - |
onClick | Manejador de clic | () => void | - |
active | Estado activo/seleccionado | boolean | false |
disabled | Deshabilitar el elemento | boolean | false |
danger | Estilo de peligro/destructivo | boolean | false |
className | Clases CSS adicionales | string | - |
Dropdown.SubMenu
Sección titulada «Dropdown.SubMenu»| Propiedad | Descripción | Tipo | Predeterminado |
|---|---|---|---|
key | Clave única para el submenú (prop key de React) | string | - |
children | Elementos del submenú | React.ReactNode | - |
title | Título/etiqueta del submenú | React.ReactNode | - |
icon | Icono a mostrar antes del título | React.ReactNode | - |
disabled | Deshabilitar el submenú | boolean | false |
Accesibilidad
Sección titulada «Accesibilidad»- Navegación por teclado con las teclas
Enter,EspacioyEscape - Teclas de flecha para navegar por los elementos del menú
- Atributos ARIA adecuados para lectores de pantalla
- Gestión del foco al abrir y cerrar el menú
- Comportamiento de clic fuera para cerrar