Ir al contenido

Dropdown

Componente de menú desplegable para mostrar acciones y opciones.

import { Dropdown } from 'asterui'

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
PropiedadDescripciónTipoPredeterminado
childrenElemento activador y contenido del desplegable (patrón compuesto)React.ReactNode-
menuConfiguración del menú (patrón basado en datos){ items: DropdownMenuItemType[], onClick?: (info: { key: string; keyPath: string[] }) => void }-
triggerModo(s) de activación para el desplegable('click' | 'hover' | 'contextMenu')[]['hover']
placementUbicación del menú desplegable'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight' | 'left' | 'right''bottomLeft'
openEstado abierto controladoboolean-
onOpenChangeCallback cuando cambia el estado abierto(open: boolean, info?: { source }) => void-
disabledDeshabilitar el desplegablebooleanfalse
arrowMostrar flecha apuntando al activadorboolean | { pointAtCenter?: boolean }false
autoAdjustOverflowAjustar automáticamente la ubicación del desplegable cuando está fuera de la pantallabooleantrue
mouseEnterDelayRetraso antes de mostrar al pasar el ratón (segundos)number0.15
mouseLeaveDelayRetraso antes de ocultar al salir el ratón (segundos)number0.1
destroyOnHiddenDestruir desplegable cuando esté ocultobooleanfalse
popupRenderPersonalizar contenido del popup(menu: ReactNode) => ReactNode-
data-testidPrefijo de ID de prueba para elementos hijosstring-
classNameClases CSS adicionalesstring-
PropiedadDescripciónTipoPredeterminado
keyClave única para el elemento (prop key de React)string-
childrenContenido del elementoReact.ReactNode-
labelEtiqueta del elemento (alternativa a children)React.ReactNode-
iconIcono a mostrar antes de la etiquetaReact.ReactNode-
onClickManejador de clic() => void-
activeEstado activo/seleccionadobooleanfalse
disabledDeshabilitar el elementobooleanfalse
dangerEstilo de peligro/destructivobooleanfalse
classNameClases CSS adicionalesstring-
PropiedadDescripciónTipoPredeterminado
keyClave única para el submenú (prop key de React)string-
childrenElementos del submenúReact.ReactNode-
titleTítulo/etiqueta del submenúReact.ReactNode-
iconIcono a mostrar antes del títuloReact.ReactNode-
disabledDeshabilitar el submenúbooleanfalse
  • Navegación por teclado con las teclas Enter, Espacio y Escape
  • 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