<div class="docs-content" data-render>
# dp-context-menu

A custom right-click (and long-press on touch) context menu. A single instance is created by
`Application.js` and reachable as `app.contextMenu`.

Source: `static/js/components/AppContextMenu.js`.

## Methods

| Method | Description |
|---|---|
| `attach(host, builder)` | Bind to an element. `builder(event)` returns the item array to show, or an empty array to suppress. Handles desktop right-click and a 500ms touch long-press. |
| `open(x, y, items)` | Open the menu at viewport coordinates with the given items. |
| `close()` | Hide the menu. |

Each item: `{ label, onSelect, icon?, danger?, disabled?, separator? }`. Use `{ separator: true }`
for a divider. The menu repositions to stay within the viewport and auto-closes on selection,
outside click, scroll, resize, or Escape.

## Usage

```html
&lt;dp-context-menu&gt;&lt;/dp-context-menu&gt;
```

```javascript
app.contextMenu.attach(myElement, (event) => [
    { label: "Open", onSelect: () => open() },
    { separator: true },
    { label: "Delete", danger: true, onSelect: () => remove() },
]);
```
</div>

<div class="component-demo">
    <div class="component-demo-title">Live example - right-click (or long-press) the box</div>
    <div class="component-demo-stage">
        <div id="ctx-target" class="card docs-demo-ctx-target">
            Right-click here
        </div>
        <span id="ctx-result" class="text-muted"></span>
    </div>
    <dp-context-menu id="ctx-menu"></dp-context-menu>
</div>
<script type="module">
    import "{{ static_url('/static/js/components/AppContextMenu.js') }}";
    const menu = document.getElementById("ctx-menu");
    const target = document.getElementById("ctx-target");
    const result = document.getElementById("ctx-result");
    menu.attach(target, () => [
        { label: "Open", icon: "\u{1F4C2}", onSelect: () => { result.textContent = "Open selected"; } },
        { label: "Rename", icon: "\u{270F}", onSelect: () => { result.textContent = "Rename selected"; } },
        { separator: true },
        { label: "Delete", icon: "\u{1F5D1}", danger: true, onSelect: () => { result.textContent = "Delete selected"; } },
    ]);
</script>
