Aller au contenu

Dropdown

Composant de menu déroulant pour afficher des actions et des options.

import { Dropdown } from 'asterui'

Dropdown de base

Menu déroulant simple avec éléments utilisant le modèle composé.

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

Piloté par les données (prop menu)

Définir les éléments de menu via la prop menu au lieu des composants composés.

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

Placement

Le menu déroulant peut être positionné dans différentes directions.

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

Modes de déclenchement

Contrôler comment le menu déroulant s'ouvre : clic, survol ou les deux.

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

Avec icônes

Éléments de menu avec icônes pour un meilleur contexte visuel.

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

Avec séparateur

Séparer les sections de menu avec des séparateurs.

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

États des éléments

Les éléments peuvent être actifs, désactivés ou stylisés comme dangereux.

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

Alignement

Aligner le menu déroulant au début, au centre ou à la fin.

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

Menu contextuel

Ouvrir le menu déroulant au clic droit en utilisant le déclencheur 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

Avec sous-menu

Sous-menus imbriqués pour des options hiérarchiques.

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

Bouton compact avec menu déroulant

Combiner un bouton avec un menu déroulant en utilisant Join pour un aspect compact de bouton divisé. Le bouton est automatiquement traité comme déclencheur sans nécessiter le wrapper Dropdown.Trigger. S'ouvre au survol automatiquement.

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

Menu déroulant icône compacte

Bouton déroulant avec icône uniquement joint à un autre bouton utilisant l'API simplifiée (aucun wrapper Dropdown.Trigger nécessaire). S'ouvre au survol pour un accès rapide.

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
PropriétéDescriptionTypeDéfaut
childrenÉlément déclencheur et contenu du menu déroulant (modèle composé)React.ReactNode-
menuConfiguration du menu (modèle piloté par les données){ items: DropdownMenuItemType[], onClick?: (info: { key: string; keyPath: string[] }) => void }-
triggerMode(s) de déclenchement du menu déroulant('click' | 'hover' | 'contextMenu')[]['hover']
placementPlacement du menu déroulant'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight' | 'left' | 'right''bottomLeft'
openÉtat d’ouverture contrôléboolean-
onOpenChangeRappel lors du changement d’état d’ouverture(open: boolean, info?: { source }) => void-
disabledDésactiver le menu déroulantbooleanfalse
arrowAfficher la flèche pointant vers le déclencheurboolean | { pointAtCenter?: boolean }false
autoAdjustOverflowAjuster automatiquement le placement du menu déroulant lorsqu’il est hors de l’écranbooleantrue
mouseEnterDelayDélai avant l’affichage au survol (secondes)number0.15
mouseLeaveDelayDélai avant le masquage au survol (secondes)number0.1
destroyOnHiddenDétruire le menu déroulant lorsque masquébooleanfalse
popupRenderPersonnaliser le contenu du popup(menu: ReactNode) => ReactNode-
data-testidPréfixe d’ID de test pour les éléments enfantsstring-
classNameClasses CSS supplémentairesstring-
PropriétéDescriptionTypeDéfaut
keyClé unique pour l’élément (prop key React)string-
childrenContenu de l’élémentReact.ReactNode-
labelÉtiquette de l’élément (alternative aux enfants)React.ReactNode-
iconIcône à afficher avant l’étiquetteReact.ReactNode-
onClickGestionnaire de clic() => void-
activeÉtat actif/sélectionnébooleanfalse
disabledDésactiver l’élémentbooleanfalse
dangerStyle dangereux/destructifbooleanfalse
classNameClasses CSS supplémentairesstring-
PropriétéDescriptionTypeDéfaut
keyClé unique pour le sous-menu (prop key React)string-
childrenÉléments du sous-menuReact.ReactNode-
titleTitre/étiquette du sous-menuReact.ReactNode-
iconIcône à afficher avant le titreReact.ReactNode-
disabledDésactiver le sous-menubooleanfalse
  • Navigation au clavier avec les touches Entrée, Espace et Échap
  • Touches fléchées pour naviguer entre les éléments du menu
  • Attributs ARIA appropriés pour les lecteurs d’écran
  • Gestion du focus lors de l’ouverture et de la fermeture du menu
  • Fermeture au clic à l’extérieur