Context Menu

A Context Menu Component in UI, often referred to as a right-click menu or context menu, is a user interface element that appears when a user interacts with a specific part of a graphical user interface, typically by right-clicking on an element. This menu provides contextual options relevant to the selected item or area, allowing users to perform specific actions or access additional functionality.

Example

Right click here

"use client";
import * as ContextMenu from "@lora-ui/context-menu";
import React from "react";
export default function Base() {
const contextRef = React.useRef(null);
function onValueChange(value) {
console.log(value);
}
return (
<>
<div
className="flex w-full justify-center py-48 text-base font-medium text-[#101828] dark:text-[#f5f5f6]"
ref={contextRef}
>
<p>Right click here</p>
</div>
<ContextMenu.Root
contextAreaRef={contextRef}
onValueChange={onValueChange}
>
<ContextMenu.Content className="border-box w-[300px] rounded-lg border border-[#eaecf0] bg-[#ffffff] py-1 dark:border-[#1f242f] dark:bg-[#0c111d]">
<ContextMenu.Root>
<ContextMenu.Trigger className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none">
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Fruits
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.6151 7.15788C10.7954 7.3502 10.7954 7.64949 10.6151 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</div>
</ContextMenu.Trigger>
<ContextMenu.Content className="border-box w-[300px] rounded-lg border border-[#eaecf0] bg-[#ffffff] py-1 dark:border-[#1f242f] dark:bg-[#0c111d]">
<ContextMenu.Item
value="Apple"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Apple
</div>
</ContextMenu.Item>
<ContextMenu.Item
value="Banana"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Banana
</div>
</ContextMenu.Item>
<ContextMenu.Item
value="Orange"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Orange
</div>
</ContextMenu.Item>
<ContextMenu.Root>
<ContextMenu.Trigger className="group block w-[300px] px-[6px] py-[1px] focus:outline-none">
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Melon
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.6151 7.15788C10.7954 7.3502 10.7954 7.64949 10.6151 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</div>
</ContextMenu.Trigger>
<ContextMenu.Content className="border-box w-[300px] rounded-lg border border-[#eaecf0] bg-[#ffffff] py-1 dark:border-[#1f242f] dark:bg-[#0c111d]">
<ContextMenu.Item
value="Cantaloupe"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Cantaloupe
</div>
</ContextMenu.Item>
<ContextMenu.Item
value="Watermelon"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Watermelon
</div>
</ContextMenu.Item>
<ContextMenu.Item
value="Honeydew"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Honeydew
</div>
</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu.Root>
</ContextMenu.Content>
</ContextMenu.Root>
<ContextMenu.Root>
<ContextMenu.Trigger className="group block w-full px-[6px] py-[1px] focus:outline-none">
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Countries
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.6151 7.15788C10.7954 7.3502 10.7954 7.64949 10.6151 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</div>
</ContextMenu.Trigger>
<ContextMenu.Content className="border-box w-[300px] rounded-lg border border-[#eaecf0] bg-[#ffffff] py-1 dark:border-[#1f242f] dark:bg-[#0c111d]">
<ContextMenu.Item
value="United States"
isDisabled
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
United States
</div>
</ContextMenu.Item>
<ContextMenu.Item
value="Canada"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Canada
</div>
</ContextMenu.Item>
<ContextMenu.Item
value="Australia"
className="group block w-full rounded-md px-[6px] py-[1px] focus:outline-none"
>
<div className="flex items-center justify-between py-[10px] pl-2 pr-[10px] text-base font-medium text-[#101828] hover:bg-[#f9fafb] group-focus:rounded-md group-focus:bg-[#f9fafb] group-disabled:pointer-events-none group-disabled:text-[--app-text-disabled] dark:text-[#f5f5f6] dark:hover:bg-[#1f242f] dark:group-focus:bg-[#1f242f]">
Australia
</div>
</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu.Root>
</ContextMenu.Content>
</ContextMenu.Root>
</>
);
}

Installation

Install the component from your command line.

npm install @lora-ui/context-menu

API Reference

Root

PropTypeDefaultExplanation
contextAreaRefReact.RefObjectRef object for click area
onValueChangeFunction(value: string) => {}Callback fn for selected value

Trigger

PropTypeDefaultExplanation

Content

PropTypeDefaultExplanation

Item

PropTypeDefaultExplanation
valueStringSupport typeahead when value provided
isDisabledBooleanfalse

Keyboard

CommandDescription
Space
Activates the focused item.
Enter
Activates the focused item.
Escape
Closes the context menu.
ArrowRight
Open submenu and focus the first menuitem in submenu.
ArrowLeft
Close submenu and focus on the parent menuitem of submenu.
ArrowDown
Moves focus to the next item.
ArrowUp
Moves focus to the previous item.
A-Z
and
a-z
Focus a menuitem that starts with the typed characters.

Other

All relevant ARIA attributes are automatically managed.