An accessible React menubar component that provides keyboard navigation, submenus, and customizable styling while maintaining semantic HTML structure and screen reader compatibility.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Components for organizing and displaying menu items with various layouts, including basic items, grouping, labeling, and visual separation.
Basic interactive menu item that can be selected and responds to keyboard and mouse interactions.
/**
* Interactive menu item that can be selected
* @param props - Menu item props
* @returns JSX element representing the menu item
*/
function MenubarItem(props: MenubarItemProps): React.ReactElement;
interface MenubarItemProps extends React.ComponentPropsWithoutRef<'div'> {
/** Whether the item is disabled */
disabled?: boolean;
/** Callback fired when the item is selected */
onSelect?: (event: SelectEvent) => void;
/** Text value for accessibility (used by screen readers) */
textValue?: string;
}Usage Examples:
'use client';
import * as Menubar from "@radix-ui/react-menubar";
// Basic menu item
<Menubar.Item onSelect={() => console.log("New file")}>
New File
</Menubar.Item>
// Disabled menu item
<Menubar.Item disabled>
Recent Files
</Menubar.Item>
// Item with custom text value for accessibility
<Menubar.Item
textValue="Save document"
onSelect={handleSave}
>
Save <span style={{ opacity: 0.6 }}>Ctrl+S</span>
</Menubar.Item>Groups related menu items together, providing semantic organization and optional styling.
/**
* Groups related menu items together
* @param props - Group container props
* @returns JSX element representing the group
*/
function MenubarGroup(props: MenubarGroupProps): React.ReactElement;
interface MenubarGroupProps extends React.ComponentPropsWithoutRef<'div'> {
/** Child menu items to group together */
children?: React.ReactNode;
}Usage Examples:
// Basic grouping
<Menubar.Group>
<Menubar.Item>Cut</Menubar.Item>
<Menubar.Item>Copy</Menubar.Item>
<Menubar.Item>Paste</Menubar.Item>
</Menubar.Group>
// Multiple groups with separators
<Menubar.Content>
<Menubar.Group>
<Menubar.Item>New</Menubar.Item>
<Menubar.Item>Open</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item>Save</Menubar.Item>
<Menubar.Item>Save As</Menubar.Item>
</Menubar.Group>
</Menubar.Content>Non-interactive label for menu sections, providing context and organization without being selectable.
/**
* Non-interactive label for menu sections
* @param props - Label props
* @returns JSX element representing the label
*/
function MenubarLabel(props: MenubarLabelProps): React.ReactElement;
interface MenubarLabelProps extends React.ComponentPropsWithoutRef<'div'> {
/** Label text or content */
children?: React.ReactNode;
}Usage Examples:
// Section label
<Menubar.Content>
<Menubar.Label>File Operations</Menubar.Label>
<Menubar.Item>New</Menubar.Item>
<Menubar.Item>Open</Menubar.Item>
<Menubar.Separator />
<Menubar.Label>Recent Files</Menubar.Label>
<Menubar.Item>document.txt</Menubar.Item>
<Menubar.Item>project.json</Menubar.Item>
</Menubar.Content>
// Styled label
<Menubar.Label className="menu-section-header">
Export Options
</Menubar.Label>Visual separator between groups of menu items, improving organization and visual hierarchy.
/**
* Visual separator between menu item groups
* @param props - Separator props
* @returns JSX element representing the separator
*/
function MenubarSeparator(props: MenubarSeparatorProps): React.ReactElement;
interface MenubarSeparatorProps extends React.ComponentPropsWithoutRef<'div'> {
/** Whether the separator is decorative only (default: false) */
decorative?: boolean;
}Usage Examples:
// Basic separator
<Menubar.Content>
<Menubar.Item>New</Menubar.Item>
<Menubar.Item>Open</Menubar.Item>
<Menubar.Separator />
<Menubar.Item>Exit</Menubar.Item>
</Menubar.Content>
// Decorative separator (screen reader friendly)
<Menubar.Separator decorative />
// Custom styled separator
<Menubar.Separator className="thick-separator" />// Complete menu with grouped items
<Menubar.Content>
<Menubar.Label>File Operations</Menubar.Label>
<Menubar.Group>
<Menubar.Item onSelect={handleNew}>New</Menubar.Item>
<Menubar.Item onSelect={handleOpen}>Open</Menubar.Item>
<Menubar.Item onSelect={handleOpenRecent}>Open Recent</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Label>Save Operations</Menubar.Label>
<Menubar.Group>
<Menubar.Item onSelect={handleSave}>Save</Menubar.Item>
<Menubar.Item onSelect={handleSaveAs}>Save As...</Menubar.Item>
<Menubar.Item onSelect={handleSaveAll}>Save All</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Item onSelect={handleExit}>Exit</Menubar.Item>
</Menubar.Content>// Menu items with keyboard shortcuts
<Menubar.Content>
<Menubar.Item onSelect={handleNew}>
<span>New File</span>
<span className="shortcut">Ctrl+N</span>
</Menubar.Item>
<Menubar.Item onSelect={handleOpen}>
<span>Open</span>
<span className="shortcut">Ctrl+O</span>
</Menubar.Item>
<Menubar.Item onSelect={handleSave}>
<span>Save</span>
<span className="shortcut">Ctrl+S</span>
</Menubar.Item>
</Menubar.Content>// Element reference types
type MenubarItemElement = HTMLDivElement;
type MenubarGroupElement = HTMLDivElement;
type MenubarLabelElement = HTMLDivElement;
type MenubarSeparatorElement = HTMLDivElement;
// Event types
interface SelectEvent {
preventDefault(): void;
target: HTMLElement;
}Install with Tessl CLI
npx tessl i tessl/npm-radix-ui--react-menubar