#402
Context menu
A dashed button area that opens a Rename, Duplicate, Delete menu at the pointer on right-click, or from the keyboard with Shift+F10 or the ContextMenu key.
Hand this to your AI. It names the exact library parts, timings and accessibility promises of this demo.
Build the "Context menu" pattern (@codeatlasdev/ui demo #402, navigation/menu) in my app.
Call get_demo({ ids: ["#402"] }) first and keep its structure. It needs @codeatlasdev/[email protected].
Use: Context menus on rows, files or canvases: the menu opens where the user pointed and moves when they right-click again.
Keep these library parts, with the props and tokens the demo uses:
- announce, DropdownMenu, DropdownMenuItem, DropdownMenuSeparator from "@codeatlasdev/ui"
Behaviour to keep:
- `let open = $state(false)` and `let point = $state<{ x: number; y: number } | null>(null)`
- The area is a native `<button type="button" class="area" {oncontextmenu} {onkeydown}>` so it is focusable and named by its visible text
- `oncontextmenu` calls `e.preventDefault()`, sets `point = { x: e.clientX, y: e.clientY }` and `open = true`
- `onkeydown` handles `ContextMenu` and Shift+F10 and anchors the menu to the area's top-left
- `<DropdownMenu bind:open anchor={point}>` has no trigger; items Rename, Duplicate and a destructive Delete after `<DropdownMenuSeparator />`
- Each item calls `function pick(action: string)`, which sets `last = action` and calls `announce`; `Last action: {last}` is shown below
Reduced motion: the demo handles it; keep that branch.
Keyboard: operable; keep the focus order and key handling.
Change only the copy and the data. Use the theme tokens (--ca-*), never raw colours. Library parts
- DropdownMenu
@codeatlasdev/ui - DropdownMenuItem
@codeatlasdev/ui - DropdownMenuSeparator
@codeatlasdev/ui
How it is built
- `let open = $state(false)` and `let point = $state<{ x: number; y: number } | null>(null)`
- The area is a native `<button type="button" class="area" {oncontextmenu} {onkeydown}>` so it is focusable and named by its visible text
- `oncontextmenu` calls `e.preventDefault()`, sets `point = { x: e.clientX, y: e.clientY }` and `open = true`
- `onkeydown` handles `ContextMenu` and Shift+F10 and anchors the menu to the area's top-left
- `<DropdownMenu bind:open anchor={point}>` has no trigger; items Rename, Duplicate and a destructive Delete after `<DropdownMenuSeparator />`
- Each item calls `function pick(action: string)`, which sets `last = action` and calls `announce`; `Last action: {last}` is shown below
Related
Loading source.