Skip to content

Context menu

The Context menu component opens a menu at the cursor when the user right-clicks its content. It is positioned at the pointer, traps focus while open, supports arrow-key navigation through the menu, and closes on Escape, scroll, or an outside click.

Nest a Menu flyout inside the menu to add submenus. A prediction cone keeps a submenu open while the pointer moves diagonally towards it — and back out to its opener — even when the cursor briefly crosses another item. Set debug-cone to visualise that cone.

Right-click anywhere in this area

Props

debug-cone?: boolean
Visualises the submenu prediction cone for debugging. Draws the safe triangle and the pointer.

disabled?: boolean
Whether the context menu is disabled.

is-persistent?: boolean
When enabled, the context menu stays open after a menu item is clicked instead of closing. Defaults to false; individual items can also opt in via their own is-persistent.

position?: "bottom-left" | "bottom-right" | "top-left" | "…"
The position of the menu relative to the cursor.
Default: bottom-left

Emits

open: [MouseEvent]
Triggered when the menu opens, with the originating event.

close: []
Triggered when the menu closes.

Slots

default
The region that responds to right-clicks.

menu
The menu content. Receives a close function. Place a Menu with items here.

Examples

Basic

A basic context menu.

Right-click here

<template>
    <FluxContextMenu>
        <FluxPane style="padding: 36px; text-align: center">
            Right-click here
        </FluxPane>

        <template #menu>
            <FluxMenu>
                <FluxMenuGroup>
                    <FluxMenuItem
                        label="Cut"
                        type="button"/>

                    <FluxMenuItem
                        label="Copy"
                        type="button"/>

                    <FluxMenuItem
                        label="Paste"
                        type="button"/>
                </FluxMenuGroup>
            </FluxMenu>
        </template>
    </FluxContextMenu>
</template>

<script
    setup
    lang="ts">
    import { FluxContextMenu, FluxMenu, FluxMenuGroup, FluxMenuItem, FluxPane } from '@flux-ui/components';
</script>

With icons

A context menu with icons.

Right-click for actions

<template>
    <FluxContextMenu @open="onOpen">
        <FluxPane style="padding: 36px; text-align: center">
            Right-click for actions
        </FluxPane>

        <template #menu="{close}">
            <FluxMenu>
                <FluxMenuGroup>
                    <FluxMenuItem
                        icon-leading="pen"
                        label="Edit"
                        type="button"
                        @click="close"/>

                    <FluxMenuItem
                        icon-leading="copy"
                        label="Duplicate"
                        type="button"
                        @click="close"/>
                </FluxMenuGroup>

                <FluxSeparator/>

                <FluxMenuGroup>
                    <FluxMenuItem
                        icon-leading="trash"
                        label="Delete"
                        type="button"
                        @click="close"/>
                </FluxMenuGroup>
            </FluxMenu>
        </template>
    </FluxContextMenu>
</template>

<script
    setup
    lang="ts">
    import { FluxContextMenu, FluxMenu, FluxMenuGroup, FluxMenuItem, FluxPane, FluxSeparator } from '@flux-ui/components';

    function onOpen(): void {
        // The menu opened at the cursor.
    }
</script>

Nest a Menu flyout to add a submenu that opens to the side.

Prediction cone
Right-click here

<template>
    <div style="display: flex; flex-flow: column; gap: 15px">
        <div style="display: flex; align-items: center; gap: 9px">
            <FluxToggle
                v-model="showCone"/>

            Prediction cone
        </div>

        <FluxContextMenu :debug-cone="showCone">
            <FluxPane style="padding: 36px; text-align: center">
                Right-click here
            </FluxPane>

            <template #menu="{close}">
                <FluxMenu>
                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="pen"
                            label="Rename"
                            type="button"
                            @click="close"/>

                        <FluxMenuFlyout
                            icon="arrow-up-from-square"
                            label="Share">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        icon-leading="paper-plane"
                                        label="Email"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="copy"
                                        label="Copy link"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>
                    </FluxMenuGroup>

                    <FluxSeparator/>

                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="trash"
                            is-destructive
                            label="Delete"
                            type="button"
                            @click="close"/>
                    </FluxMenuGroup>
                </FluxMenu>
            </template>
        </FluxContextMenu>
    </div>
</template>

<script
    lang="ts"
    setup>
    import { FluxContextMenu, FluxMenu, FluxMenuFlyout, FluxMenuGroup, FluxMenuItem, FluxPane, FluxSeparator, FluxToggle } from '@flux-ui/components';
    import { ref } from 'vue';

    const showCone = ref(false);
</script>

Menu flyouts nest arbitrarily deep. The prediction cone guides the pointer into a submenu and back out to its opener across every level.

Prediction cone
Right-click this file

<template>
    <div style="display: flex; flex-flow: column; gap: 15px">
        <div style="display: flex; align-items: center; gap: 9px">
            <FluxToggle
                v-model="showCone"/>

            Prediction cone
        </div>

        <FluxContextMenu :debug-cone="showCone">
            <FluxPane style="padding: 36px; text-align: center">
                Right-click this file
            </FluxPane>

            <template #menu="{close}">
                <FluxMenu>
                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="arrow-up-right-from-square"
                            label="Open"
                            type="button"
                            @click="close"/>

                        <FluxMenuFlyout
                            icon="folder-tree"
                            label="Move to">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuFlyout
                                        icon="folder"
                                        label="Documents">
                                        <FluxMenu>
                                            <FluxMenuGroup>
                                                <FluxMenuFlyout
                                                    icon="folder"
                                                    label="Work">
                                                    <FluxMenu>
                                                        <FluxMenuGroup>
                                                            <FluxMenuItem
                                                                icon-leading="folder"
                                                                label="2025"
                                                                type="button"
                                                                @click="close"/>

                                                            <FluxMenuItem
                                                                icon-leading="folder"
                                                                label="2026"
                                                                type="button"
                                                                @click="close"/>
                                                        </FluxMenuGroup>
                                                    </FluxMenu>
                                                </FluxMenuFlyout>

                                                <FluxMenuItem
                                                    icon-leading="folder"
                                                    label="Personal"
                                                    type="button"
                                                    @click="close"/>

                                                <FluxMenuItem
                                                    icon-leading="folder"
                                                    label="Invoices"
                                                    type="button"
                                                    @click="close"/>
                                            </FluxMenuGroup>
                                        </FluxMenu>
                                    </FluxMenuFlyout>

                                    <FluxMenuFlyout
                                        icon="folder"
                                        label="Pictures">
                                        <FluxMenu>
                                            <FluxMenuGroup>
                                                <FluxMenuItem
                                                    icon-leading="folder"
                                                    label="Camera Roll"
                                                    type="button"
                                                    @click="close"/>

                                                <FluxMenuItem
                                                    icon-leading="folder"
                                                    label="Screenshots"
                                                    type="button"
                                                    @click="close"/>
                                            </FluxMenuGroup>
                                        </FluxMenu>
                                    </FluxMenuFlyout>

                                    <FluxMenuItem
                                        icon-leading="folder"
                                        label="Desktop"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>
                    </FluxMenuGroup>

                    <FluxSeparator/>

                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="trash"
                            is-destructive
                            label="Delete"
                            type="button"
                            @click="close"/>
                    </FluxMenuGroup>
                </FluxMenu>
            </template>
        </FluxContextMenu>
    </div>
</template>

<script
    lang="ts"
    setup>
    import { FluxContextMenu, FluxMenu, FluxMenuFlyout, FluxMenuGroup, FluxMenuItem, FluxPane, FluxSeparator, FluxToggle } from '@flux-ui/components';
    import { ref } from 'vue';

    const showCone = ref(false);
</script>

Nested formatting

A spreadsheet-style menu mixing several openers with two and three levels of nesting.

Prediction cone
Right-click this cell

<template>
    <div style="display: flex; flex-flow: column; gap: 15px">
        <div style="display: flex; align-items: center; gap: 9px">
            <FluxToggle
                v-model="showCone"/>

            Prediction cone
        </div>

        <FluxContextMenu :debug-cone="showCone">
            <FluxPane style="padding: 36px; text-align: center">
                Right-click this cell
            </FluxPane>

            <template #menu="{close}">
                <FluxMenu>
                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="scissors"
                            label="Cut"
                            type="button"
                            @click="close"/>

                        <FluxMenuItem
                            icon-leading="copy"
                            label="Copy"
                            type="button"
                            @click="close"/>

                        <FluxMenuItem
                            icon-leading="paste"
                            label="Paste"
                            type="button"
                            @click="close"/>
                    </FluxMenuGroup>

                    <FluxSeparator/>

                    <FluxMenuGroup>
                        <FluxMenuFlyout
                            icon="plus"
                            label="Insert">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        icon-leading="arrow-up"
                                        label="Row above"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="arrow-down"
                                        label="Row below"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>

                                <FluxSeparator/>

                                <FluxMenuGroup>
                                    <FluxMenuFlyout
                                        icon="table-cells"
                                        label="Cells">
                                        <FluxMenu>
                                            <FluxMenuGroup>
                                                <FluxMenuItem
                                                    icon-leading="arrow-right"
                                                    label="Shift right"
                                                    type="button"
                                                    @click="close"/>

                                                <FluxMenuItem
                                                    icon-leading="arrow-down"
                                                    label="Shift down"
                                                    type="button"
                                                    @click="close"/>
                                            </FluxMenuGroup>
                                        </FluxMenu>
                                    </FluxMenuFlyout>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>

                        <FluxMenuFlyout
                            icon="font"
                            label="Format">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuFlyout
                                        icon="hashtag"
                                        label="Number">
                                        <FluxMenu>
                                            <FluxMenuGroup>
                                                <FluxMenuItem
                                                    label="Currency"
                                                    type="button"
                                                    @click="close"/>

                                                <FluxMenuItem
                                                    label="Percent"
                                                    type="button"
                                                    @click="close"/>

                                                <FluxMenuItem
                                                    label="Date"
                                                    type="button"
                                                    @click="close"/>
                                            </FluxMenuGroup>
                                        </FluxMenu>
                                    </FluxMenuFlyout>

                                    <FluxMenuFlyout
                                        icon="text-height"
                                        label="Text">
                                        <FluxMenu>
                                            <FluxMenuGroup>
                                                <FluxMenuItem
                                                    icon-leading="bold"
                                                    label="Bold"
                                                    type="button"
                                                    @click="close"/>

                                                <FluxMenuItem
                                                    icon-leading="italic"
                                                    label="Italic"
                                                    type="button"
                                                    @click="close"/>
                                            </FluxMenuGroup>

                                            <FluxSeparator/>

                                            <FluxMenuGroup>
                                                <FluxMenuFlyout
                                                    icon="palette"
                                                    label="Color">
                                                    <FluxMenu>
                                                        <FluxMenuGroup>
                                                            <FluxMenuItem
                                                                icon-leading="circle"
                                                                label="Red"
                                                                type="button"
                                                                @click="close"/>

                                                            <FluxMenuItem
                                                                icon-leading="circle"
                                                                label="Green"
                                                                type="button"
                                                                @click="close"/>

                                                            <FluxMenuItem
                                                                icon-leading="circle"
                                                                label="Blue"
                                                                type="button"
                                                                @click="close"/>
                                                        </FluxMenuGroup>
                                                    </FluxMenu>
                                                </FluxMenuFlyout>
                                            </FluxMenuGroup>
                                        </FluxMenu>
                                    </FluxMenuFlyout>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>
                    </FluxMenuGroup>

                    <FluxSeparator/>

                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="trash"
                            is-destructive
                            label="Delete row"
                            type="button"
                            @click="close"/>
                    </FluxMenuGroup>
                </FluxMenu>
            </template>
        </FluxContextMenu>
    </div>
</template>

<script
    lang="ts"
    setup>
    import { FluxContextMenu, FluxMenu, FluxMenuFlyout, FluxMenuGroup, FluxMenuItem, FluxPane, FluxSeparator, FluxToggle } from '@flux-ui/components';
    import { ref } from 'vue';

    const showCone = ref(false);
</script>

Real-world

A Finder-style menu with several submenu openers stacked under each other.

Prediction cone
Right-click this item

<template>
    <div style="display: flex; flex-flow: column; gap: 15px">
        <div style="display: flex; align-items: center; gap: 9px">
            <FluxToggle
                v-model="showCone"/>

            Prediction cone
        </div>

        <FluxContextMenu :debug-cone="showCone">
            <FluxPane style="padding: 36px; text-align: center">
                Right-click this item
            </FluxPane>

            <template #menu="{close}">
                <FluxMenu>
                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="arrow-up-right-from-square"
                            label="Open"
                            type="button"
                            @click="close"/>

                        <FluxMenuFlyout
                            icon="image"
                            label="Open With">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        icon-leading="eye"
                                        label="Preview"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="image"
                                        label="Photos"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>

                                <FluxSeparator/>

                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        label="App Store…"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>

                        <FluxMenuItem
                            icon-leading="trash"
                            is-destructive
                            label="Move to Trash"
                            type="button"
                            @click="close"/>
                    </FluxMenuGroup>

                    <FluxSeparator/>

                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="circle-info"
                            label="Get Info"
                            type="button"
                            @click="close"/>

                        <FluxMenuItem
                            icon-leading="pen"
                            label="Rename"
                            type="button"
                            @click="close"/>

                        <FluxMenuItem
                            icon-leading="clone"
                            label="Duplicate"
                            type="button"
                            @click="close"/>

                        <FluxMenuItem
                            icon-leading="eye"
                            label="Quick Look"
                            type="button"
                            @click="close"/>
                    </FluxMenuGroup>

                    <FluxSeparator/>

                    <FluxMenuGroup>
                        <FluxMenuItem
                            icon-leading="copy"
                            label="Copy"
                            type="button"
                            @click="close"/>

                        <FluxMenuFlyout
                            icon="arrow-up-from-square"
                            label="Share">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        icon-leading="paper-plane"
                                        label="Mail"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="copy"
                                        label="Copy Link"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>

                        <FluxMenuFlyout
                            icon="bolt"
                            label="Quick Actions">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        icon-leading="rotate-left"
                                        label="Rotate Left"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="pen"
                                        label="Markup"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="image"
                                        label="Convert Image"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>
                    </FluxMenuGroup>

                    <FluxSeparator/>

                    <FluxMenuGroup>
                        <FluxMenuFlyout
                            icon="palette"
                            label="Tags">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        icon-leading="circle"
                                        label="Red"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="circle"
                                        label="Orange"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        icon-leading="circle"
                                        label="Green"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>

                        <FluxMenuFlyout
                            icon="gear"
                            label="Services">
                            <FluxMenu>
                                <FluxMenuGroup>
                                    <FluxMenuItem
                                        label="Show in Enclosing Folder"
                                        type="button"
                                        @click="close"/>

                                    <FluxMenuItem
                                        label="New Terminal at Folder"
                                        type="button"
                                        @click="close"/>
                                </FluxMenuGroup>
                            </FluxMenu>
                        </FluxMenuFlyout>
                    </FluxMenuGroup>
                </FluxMenu>
            </template>
        </FluxContextMenu>
    </div>
</template>

<script
    lang="ts"
    setup>
    import { FluxContextMenu, FluxMenu, FluxMenuFlyout, FluxMenuGroup, FluxMenuItem, FluxPane, FluxSeparator, FluxToggle } from '@flux-ui/components';
    import { ref } from 'vue';

    const showCone = ref(false);
</script>

With color picker

Embed a full component with a Menu pane. The picker stays interactive while the menu is open.

Right-click here

<template>
    <FluxContextMenu>
        <FluxPane style="padding: 36px; text-align: center">
            Right-click here
        </FluxPane>

        <template #menu>
            <FluxMenu>
                <FluxMenuGroup>
                    <FluxMenuSubHeader label="Highlight"/>

                    <FluxMenuPane>
                        <FluxColorPicker v-model="color"/>
                    </FluxMenuPane>
                </FluxMenuGroup>
            </FluxMenu>
        </template>
    </FluxContextMenu>
</template>

<script
    setup
    lang="ts">
    import { FluxColorPicker, FluxContextMenu, FluxMenu, FluxMenuGroup, FluxMenuPane, FluxMenuSubHeader, FluxPane } from '@flux-ui/components';
    import { ref } from 'vue';

    const color = ref('#ef4444');
</script>

Used components