# Context Menu Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Add a custom right-click context menu to the Oxyde chat app that replaces the browser default and offers context-aware copy actions on room names, message authors, and message bodies. **Architecture:** A single shared `ContextMenu` Svelte component receives position + items as props and is rendered once in `+page.svelte`. State (`contextMenu`) lives in the page; a `showMenu` helper is passed down to `Sidebar` and `ChatMain` as a prop. Each trigger calls `showMenu` with the right items. **Tech Stack:** Svelte 5 runes (`$state`, `$props`), `navigator.clipboard`, CSS custom properties already defined in `+page.svelte`. --- ## File Map | File | Change | |---|---| | `src/lib/types.ts` | Add `ContextMenuItem` interface | | `src/lib/components/ContextMenu.svelte` | New component — positioning, dismiss, copy + confirmation | | `src/routes/+page.svelte` | Add `contextMenu` state, `showMenu` helper, render ``, pass prop to children | | `src/lib/components/Sidebar.svelte` | Add `onShowMenu` prop, wire `oncontextmenu` on `.room-item` buttons | | `src/lib/components/ChatMain.svelte` | Add `onShowMenu` prop, wire `oncontextmenu` on `.msg` div and `.msg-author` span | --- ### Task 1: Add `ContextMenuItem` type **Files:** - Modify: `src/lib/types.ts` - [ ] **Step 1: Add the interface** Open `src/lib/types.ts`. Append one line: ```ts export interface User { id: any; username: string; email: string; avatar?: string; created: string; } export interface Room { id: any; name: string; created: string; } export interface Message { id: any; room: any; author: any; author_username?: string; body: string; created: string; } export interface LiveEvent { action: 'Create' | 'Update' | 'Delete'; data: Message; } export interface ContextMenuItem { label: string; action: () => void; } ``` - [ ] **Step 2: Verify TypeScript accepts it** Run: `cd /home/qdust41/Oxyde && npx tsc --noEmit 2>&1 | head -20` Expected: no errors (or only pre-existing errors unrelated to this file) - [ ] **Step 3: Commit** ```bash git add src/lib/types.ts git commit -m "feat: add ContextMenuItem interface to types" ``` --- ### Task 2: Create `ContextMenu.svelte` component **Files:** - Create: `src/lib/components/ContextMenu.svelte` - [ ] **Step 1: Create the component** Create `src/lib/components/ContextMenu.svelte` with the following content: ```svelte ``` - [ ] **Step 2: Verify no TypeScript errors** Run: `cd /home/qdust41/Oxyde && npx tsc --noEmit 2>&1 | head -20` Expected: no new errors - [ ] **Step 3: Commit** ```bash git add src/lib/components/ContextMenu.svelte git commit -m "feat: add ContextMenu component with copy confirmation and viewport overflow guard" ``` --- ### Task 3: Wire context menu state into `+page.svelte` **Files:** - Modify: `src/routes/+page.svelte` The page needs: 1. `contextMenu` state (nullable position + items object) 2. `showMenu` helper called by children 3. `` rendered inside the `{:else}` (app) block 4. `onShowMenu` prop passed to `Sidebar` and `ChatMain` - [ ] **Step 1: Add import and state** In `src/routes/+page.svelte`, add `ContextMenu` to the imports and `ContextMenuItem` to the type import, then add the state variable. Edit the ` ``` - [ ] **Step 2: Wire `oncontextmenu` on `.room-item` buttons** In the template, replace the `.room-item` button: ```svelte