Forme DS

Composants

DropdownMenu nouveau

Un menu d'actions data-driven : tu décris le bouton déclencheur via button et la liste d'actions via items. Sections, séparateurs, sous-menus, items destructifs et descriptions sont tous exprimés en données.

Nouveau dans le DS 2.0. Plus de menus contextuels bricolés à la main : la structure (sections, divider, sous-menus items, variante destructive) est déclarée en données, et Astryx gère l'ouverture, le focus clavier APG et la fermeture.
import { DropdownMenu } from "@forme-ch/ui/controls";
import { PencilSimpleIcon, CopyIcon, TrashIcon } from "@forme-ch/ui/icons";

<DropdownMenu
  button={{ label: "Actions", variant: "secondary" }}
  hasChevron
  items={[
    { label: "Éditer", icon: <PencilSimpleIcon />, onClick: edit },
    { label: "Dupliquer", icon: <CopyIcon />, onClick: duplicate },
    { type: "divider" },
    { label: "Supprimer", icon: <TrashIcon />, variant: "destructive", onClick: remove },
  ]}
/>

Sections et descriptions

Regroupe les actions par section ; un item peut porter une description.

<DropdownMenu
  button={{ label: "Facture", variant: "primary", icon: <PencilSimpleIcon /> }}
  hasChevron
  menuWidth={240}
  items={[
    { type: "section", title: "Édition", items: [ { label: "Modifier", onClick: edit } ] },
    { type: "section", title: "Cycle de vie", items: [
      { label: "Archiver", description: "Sort de la liste active", onClick: archive },
      { label: "Supprimer", variant: "destructive", onClick: remove },
    ] },
  ]}
/>

Ouverture contrôlée

Pilote l'état avec isMenuOpen et onOpenChange (ici via useState).

const [open, setOpen] = useState(false);

<DropdownMenu
  button={{ label: "Menu contrôlé", variant: "secondary" }}
  hasChevron
  isMenuOpen={open}
  onOpenChange={setOpen}
  items={[{ label: "Option A", onClick: a }, { label: "Option B", onClick: b }]}
/>

Props

PropTypeDéfautDescription
button * DropdownTriggerProps — Config du bouton déclencheur : { label*, variant?, size?, icon?, iconOnly?, isDisabled? }. iconOnly → isIconOnly côté Astryx.
items * DropdownMenuOption[] — Items data-driven : { label, icon?, onClick?, isDisabled?, description?, variant?, endContent?, items? }, ou { type: 'divider' }, ou une section { type: 'section', title?, items }.
hasChevron boolean false Affiche un chevron ▾ à droite du label du déclencheur.
placement Placement — above · below · start · end.
alignment Alignment — start · center · end.
menuWidth number | string — Largeur imposée du panneau du menu.
isMenuOpen boolean — Ouverture contrôlée.
onOpenChange (open: boolean) => void — Notifie l'ouverture / fermeture.
className string — Classe CSS additionnelle.
style CSSProperties — Styles inline.

Accessibilité

Le focus clavier suit le pattern APG des menus : ouverture au clic, navigation par flèches, fermeture sur Échap et sur clic hors zone — géré nativement par Astryx. Un item iconOnly sur le déclencheur utilise le label comme nom accessible. Les items destructifs sont signalés visuellement et par leur libellé, pas par la seule couleur.

Do & Don't

✓ À faire

Grouper les actions liées en section. Isoler l'action destructive après un divider, en variant: "destructive".

✕ À éviter

Empiler dix actions sans hiérarchie. Reconstruire un menu maison avec position: absolute et gestion clavier ad hoc.