Files
temetro/.agents/skills/coss/references/primitives/menu.md
T
Khalid Abdi 929bec8f31 feat: AI-added records save with placeholders + "Added by AI" provenance
Stop blocking AI imports/proposals on missing non-critical fields. Records
the chat agent drafts now save with safe placeholders, auto-generated file
numbers, and a source="ai" marker that surfaces an "Added by AI" badge so a
clinician can review/edit them later.

Backend:
- add `source` (manual|ai) column to patients/appointments/prescriptions
  (migration 0014) + canonical types, services, validation schemas
- relax patient/appointment validation: empty file number allowed, demographic
  + type/provider/initials fall back to placeholders (initials derived from name)
- patients.generateFileNumber() auto-assigns an MRN when one is missing
- proposeAppointment accepts a name when no file number resolves; AI commits +
  /api/ai/import stamp source="ai"

Frontend:
- `source` on Appointment/Patient/Prescription types; AI commits send source="ai"
- reusable <AiBadge> shown on the Patients table/detail and prescriptions list

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 19:27:17 +03:00

3.0 KiB

coss Menu

When to use

  • Contextual action lists and dropdown commands.
  • Mixed item types (regular, checkbox, radio, nested submenu).

When NOT to use

  • If the user needs to search/filter actions -> use Command instead.
  • If the content is rich informational (not actions) -> use Popover instead.
  • If the overlay is a full modal flow -> use Dialog instead.

Install

npx shadcn@latest add @coss/menu

Manual deps and theme var from docs:

npm install @base-ui/react

Also include the destructive foreground CSS variable snippet from the coss menu docs when doing manual setup.

Canonical imports

import {
  Menu,
  MenuCheckboxItem,
  MenuGroup,
  MenuGroupLabel,
  MenuItem,
  MenuPopup,
  MenuRadioGroup,
  MenuRadioItem,
  MenuSeparator,
  MenuShortcut,
  MenuSub,
  MenuSubPopup,
  MenuSubTrigger,
  MenuTrigger,
} from "@/components/ui/menu"

Minimal pattern

<Menu>
  <MenuTrigger>Open</MenuTrigger>
  <MenuPopup>
    <MenuItem>Profile</MenuItem>
    <MenuSeparator />
    <MenuCheckboxItem>Shuffle</MenuCheckboxItem>
  </MenuPopup>
</Menu>

Use popup positioning props like align / sideOffset only when a layout needs explicit tuning.

Patterns from coss particles

  • Portal forwarding: optional portalProps on MenuPopup → Base UI Menu.Portal (keepMounted, container, …). See portal-props.md.
  • Use MenuTrigger render={<Button ... />} as the default trigger composition.
  • Use openOnHover on MenuTrigger only for explicit hover-driven UX.
  • Use MenuItem render={<Link ... />} for navigational entries.
  • Use MenuItem closeOnClick for action menus where selection should always dismiss the popup.
  • Use MenuCheckboxItem variant="switch" for toggle-style preferences.
  • Use MenuRadioGroup + MenuRadioItem with a defaultValue when enforcing single-choice selection.
  • Use MenuShortcut to display keyboard hints in dense command menus.
  • Use variant="destructive" on dangerous actions.
  • For responsive action menus, keep desktop on Menu and switch mobile to DrawerMenu / DrawerMenuTrigger / DrawerMenuItem patterns.
  • In DrawerMenu flows, wrap actionable rows with DrawerClose render={<DrawerMenuItem />} when selection should dismiss the drawer.

Common pitfalls

  • Forgetting MenuGroup around grouped structures.
  • Missing submenu pair (MenuSubTrigger + MenuSubPopup) for nested actions.
  • Mixing navigation and action items without clear close behavior (closeOnClick) and semantics.

Useful particle references

  • full-featured menu (groups, checkbox/radio, submenus, destructive): p-menu-1
  • hover-activated trigger pattern: p-menu-2
  • checkbox item pattern: p-menu-3
  • radio group pattern: p-menu-4
  • link/navigation items via render: p-menu-5
  • grouped sections with labels + separators: p-menu-6
  • nested submenu pattern: p-menu-7
  • force close on click actions: p-menu-8
  • switch-style checkbox items: p-menu-9
  • cross-component example: p-dialog-2 (menu opening dialog)
  • responsive menu/drawer variant: p-drawer-13