Context Menu

A menu that opens where you right-click.

Right click here

Installation

uvx django_shadcn@latest add context_menu

Usage

Right click here
<c-context-menu>
    <c-context-menu.trigger class="...">Right click here</c-context-menu.trigger>
    <c-context-menu.content class="w-48">
        <c-context-menu.item>Profile</c-context-menu.item>
        <c-context-menu.item>Billing</c-context-menu.item>
        <c-context-menu.item>Settings</c-context-menu.item>
    </c-context-menu.content>
</c-context-menu>

The trigger swallows the browser's own menu and records where you clicked; the content is positioned there with fixed, so it opens under the cursor rather than under the element.

Examples

Labels, checkboxes and radios

Right click here
<c-context-menu.label>Appearance</c-context-menu.label>
<c-context-menu.checkbox-item checked="true">Status bar</c-context-menu.checkbox-item>

<c-context-menu.radio-group value="bottom">
    <c-context-menu.radio-item value="top">Top</c-context-menu.radio-item>
    <c-context-menu.radio-item value="bottom">Bottom</c-context-menu.radio-item>
</c-context-menu.radio-group>

Submenu

Right click here
<c-context-menu.sub>
    <c-context-menu.sub-trigger>Share</c-context-menu.sub-trigger>
    <c-context-menu.sub-content class="w-40">
        <c-context-menu.item>Copy link</c-context-menu.item>
        <c-context-menu.item>Email</c-context-menu.item>
    </c-context-menu.sub-content>
</c-context-menu.sub>

Inset items

Right click here
<c-context-menu.item inset="true">Rename</c-context-menu.item>

inset lines an item up with the ones that carry a checkbox or radio mark.

Notes

Radix opens the submenu on hover with a safe triangle, so moving diagonally towards it does not close it. Here the submenu opens on mouseenter and closes on mouseleave — cutting a corner too sharply closes it.

The menu closes when the page scrolls. It is placed at viewport coordinates, so leaving it open through a scroll would drag it away from what you right-clicked. Radix does the same thing for the same reason.

Upstream caps the menu height and scrolls it internally. That is dropped here: the overflow would clip the submenu, which Radix escapes by rendering it in a portal. A very long menu grows instead of scrolling.

There is no roving focus: the menu answers to the pointer and to Escape, not to the arrow keys. Same limitation as the tooltip on positioning — the content is placed at the cursor without measuring whether it fits, so a right-click near the bottom edge opens a menu that runs past it.