Skip to main content

Menu

A menu list that provides navigation for pages and functions.

When to Use

  • Navigation menus are the soul of a website, users rely on navigation to jump between pages
  • Generally divided into top navigation and side navigation; top navigation provides global categories and functions, while side navigation provides multi-level structure to organize site architecture
  • Menu can be used alone or combined with Dropdown component

In Kube Design, the Menu component provides flexible menu functionality:

  • Icon Support: Menu items can include icons
  • Group Labels: Use MenuLabel to group menu items
  • Disabled State: Support disabling individual menu items
  • Link Support: Menu items can be used as links
  • Theme Switching: Support light and dark themes

Examples

Basic Usage

Most basic menu usage.

Live Editor
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuItem icon={<Add />}>Create</MenuItem>
        <MenuItem icon={<Stop />}>Stop</MenuItem>
        <MenuItem icon={<Pen />}>Edit</MenuItem>
        <MenuItem icon={<Trash />}>Delete</MenuItem>
      </Menu>
    </Card>
  );
}
Result
Loading...

With Label Groups

Use MenuLabel to group menu items.

Live Editor
function Demo() {
  const { Add, Pen, Stop, Trash, Download, Upload } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuLabel>Edit Operations</MenuLabel>
        <MenuItem icon={<Add />}>Create</MenuItem>
        <MenuItem icon={<Pen />}>Edit</MenuItem>
        <Divider />
        <MenuLabel>File Operations</MenuLabel>
        <MenuItem icon={<Upload />}>Upload</MenuItem>
        <MenuItem icon={<Download />}>Download</MenuItem>
        <Divider />
        <MenuLabel>Dangerous Operations</MenuLabel>
        <MenuItem icon={<Stop />}>Stop</MenuItem>
        <MenuItem icon={<Trash />}>Delete</MenuItem>
      </Menu>
    </Card>
  );
}
Result
Loading...

Disabled Menu Items

Menu items can be set to disabled state.

Live Editor
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuItem icon={<Add />}>Create</MenuItem>
        <MenuItem icon={<Pen />} disabled>
          Edit (Disabled)
        </MenuItem>
        <MenuItem icon={<Stop />}>Stop</MenuItem>
        <MenuItem icon={<Trash />} disabled>
          Delete (Disabled)
        </MenuItem>
      </Menu>
    </Card>
  );
}
Result
Loading...

Click Events

Menu items support click events.

Live Editor
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;
  const [action, setAction] = React.useState('');

  return (
    <Group direction="column" spacing="md">
      {action && <Text>You clicked: {action}</Text>}
      <Card style={{ width: '220px' }}>
        <Menu>
          <MenuItem icon={<Add />} onClick={() => setAction('Create')}>
            Create
          </MenuItem>
          <MenuItem icon={<Pen />} onClick={() => setAction('Edit')}>
            Edit
          </MenuItem>
          <MenuItem icon={<Stop />} onClick={() => setAction('Stop')}>
            Stop
          </MenuItem>
          <MenuItem icon={<Trash />} onClick={() => setAction('Delete')}>
            Delete
          </MenuItem>
        </Menu>
      </Card>
    </Group>
  );
}
Result
Loading...

Menu items can be used as links.

Live Editor
function Demo() {
  const { Home, User, Setting, Logout } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuItem icon={<Home />} as="a" href="#home">
          Home
        </MenuItem>
        <MenuItem icon={<User />} as="a" href="#profile">
          Profile
        </MenuItem>
        <MenuItem icon={<Setting />} as="a" href="#settings">
          Settings
        </MenuItem>
        <Divider />
        <MenuItem icon={<Logout />} as="a" href="#logout">
          Logout
        </MenuItem>
      </Menu>
    </Card>
  );
}
Result
Loading...

Custom Width

Set menu width through the width property.

Live Editor
function Demo() {
  const { Add, Pen, Trash } = KubedIcons;

  return (
    <Group spacing="md">
      <Card style={{ width: '180px' }}>
        <Menu width={180}>
          <MenuLabel>Width 180px</MenuLabel>
          <MenuItem icon={<Add />}>Create</MenuItem>
          <MenuItem icon={<Pen />}>Edit</MenuItem>
          <MenuItem icon={<Trash />}>Delete</MenuItem>
        </Menu>
      </Card>
      <Card style={{ width: '260px' }}>
        <Menu width={260}>
          <MenuLabel>Width 260px</MenuLabel>
          <MenuItem icon={<Add />}>Create Resource</MenuItem>
          <MenuItem icon={<Pen />}>Edit Configuration</MenuItem>
          <MenuItem icon={<Trash />}>Delete Resource</MenuItem>
        </Menu>
      </Card>
    </Group>
  );
}
Result
Loading...

Icon Only

Menu items can display only icons without text.

Live Editor
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '60px' }}>
      <Menu width={60}>
        <MenuItem icon={<Add />} />
        <MenuItem icon={<Pen />} />
        <MenuItem icon={<Stop />} />
        <MenuItem icon={<Trash />} />
      </Menu>
    </Card>
  );
}
Result
Loading...

Menu used as sidebar navigation.

Live Editor
function Demo() {
  const { Cluster, Project, Pod, Service, ConfigMap } = KubedIcons;
  const [active, setActive] = React.useState('clusters');

  return (
    <Card style={{ width: '240px' }}>
      <Menu width={240}>
        <MenuLabel>Workloads</MenuLabel>
        <MenuItem
          icon={<Pod />}
          onClick={() => setActive('pods')}
          style={{
            backgroundColor: active === 'pods' ? '#e8f4ff' : 'transparent',
          }}
        >
          Pods
        </MenuItem>
        <MenuItem
          icon={<Service />}
          onClick={() => setActive('services')}
          style={{
            backgroundColor: active === 'services' ? '#e8f4ff' : 'transparent',
          }}
        >
          Services
        </MenuItem>
        <Divider />
        <MenuLabel>Configuration</MenuLabel>
        <MenuItem
          icon={<ConfigMap />}
          onClick={() => setActive('configmaps')}
          style={{
            backgroundColor: active === 'configmaps' ? '#e8f4ff' : 'transparent',
          }}
        >
          ConfigMaps
        </MenuItem>
      </Menu>
    </Card>
  );
}
Result
Loading...

Dark Theme

Menu supports dark theme.

Live Editor
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '220px', backgroundColor: '#242e42' }}>
      <Menu themeType="dark">
        <MenuLabel>Menu Title</MenuLabel>
        <MenuItem icon={<Add />}>Create</MenuItem>
        <MenuItem icon={<Pen />}>Edit</MenuItem>
        <MenuItem icon={<Stop />}>Stop</MenuItem>
        <Divider />
        <MenuItem icon={<Trash />}>Delete</MenuItem>
      </Menu>
    </Card>
  );
}
Result
Loading...

Compact Mode

Reduce menu item spacing, suitable for limited space scenarios.

Live Editor
function Demo() {
  const { Add, Pen, Stop, Trash } = KubedIcons;

  return (
    <Card style={{ width: '200px' }}>
      <Menu width={200} style={{ padding: '4px 0' }}>
        <MenuItem icon={<Add />} style={{ padding: '6px 12px' }}>
          Create
        </MenuItem>
        <MenuItem icon={<Pen />} style={{ padding: '6px 12px' }}>
          Edit
        </MenuItem>
        <MenuItem icon={<Stop />} style={{ padding: '6px 12px' }}>
          Stop
        </MenuItem>
        <MenuItem icon={<Trash />} style={{ padding: '6px 12px' }}>
          Delete
        </MenuItem>
      </Menu>
    </Card>
  );
}
Result
Loading...

Combined with Dropdown

Menu is most commonly used with the Dropdown component.

Live Editor
function Demo() {
  const { More, Add, Pen, Stop, Trash } = KubedIcons;

  const menu = (
    <Menu>
      <MenuLabel>Operations</MenuLabel>
      <MenuItem icon={<Add />}>Create</MenuItem>
      <MenuItem icon={<Pen />}>Edit</MenuItem>
      <MenuItem icon={<Stop />}>Stop</MenuItem>
      <Divider />
      <MenuItem icon={<Trash />}>Delete</MenuItem>
    </Menu>
  );

  return (
    <Dropdown content={menu}>
      <Button>
        <More size={16} style={{ marginRight: '4px' }} />
        More Actions
      </Button>
    </Dropdown>
  );
}
Result
Loading...

API

PropertyDescriptionTypeDefault
widthMenu widthnumber210
themeTypeTheme type'light' | 'dark'-
classNameCustom class namestring-
styleCustom stylesCSSProperties-
childrenMenu itemsReactNode-

MenuItem is actually a placeholder component, the actual rendering is done by MenuButton. Here are the available properties:

PropertyDescriptionTypeDefault
iconMenu item iconReactNode-
disabledWhether disabledbooleanfalse
colorMenu item colorstring-
rightSectionRight content area (like shortcuts)ReactNode-
asRender as specified HTML elementany'button'
onClickClick event callback(e: MouseEvent) => void-
classNameCustom class namestring-
styleCustom stylesCSSProperties-
themeTypeTheme type'light' | 'dark'-
childrenMenu item contentReactNode-

MenuLabel is a placeholder component, actually rendered as a Text component.

PropertyDescriptionTypeDefault
childrenLabel contentReactNode-
classNameCustom class namestring-
styleCustom stylesCSSProperties-
themeTypeTheme type'light' | 'dark'-
info

About menu composition:

  • Menu is the menu container, containing MenuItem, MenuLabel and Divider
  • MenuItem is a placeholder component, actually rendered by MenuButton
  • MenuLabel is a placeholder component, actually rendered as Text component for group labels
  • Divider is a separator used to divide different menu groups
  • Menu component internally filters and only renders MenuItem, MenuLabel and Divider type children

About themes:

  • Uses light theme by default
  • Set themeType="dark" for dark theme
  • Dark theme is suitable for dark backgrounds
  • themeType is passed from Menu to MenuItem and MenuLabel

About menu item types:

  • Default as="button", renders as button element
  • Set as="a" to render as link, needs href property
  • Can use other HTML elements like div, span, etc.
  • as property is implemented through MenuButton component's styled-components

About width:

  • Menu's width property controls the entire menu width
  • All menu items inherit this width
  • Default width is 210px

About rightSection:

  • rightSection can be used to display shortcuts, badges, icons, etc.
  • Content is displayed on the right side of menu item
  • Commonly used to display keyboard shortcuts (like ⌘K) or status indicators

Usage Recommendations

Number of Menu Items

Keep menu items at a moderate number:

// Recommended: 5-8 menu items
<Menu>
<MenuItem>Option 1</MenuItem>
<MenuItem>Option 2</MenuItem>
<MenuItem>Option 3</MenuItem>
<MenuItem>Option 4</MenuItem>
<MenuItem>Option 5</MenuItem>
</Menu>

// If too many items, consider using groups
<Menu>
<MenuLabel>Group 1</MenuLabel>
<MenuItem>Option 1-1</MenuItem>
<MenuItem>Option 1-2</MenuItem>
<Divider />
<MenuLabel>Group 2</MenuLabel>
<MenuItem>Option 2-1</MenuItem>
<MenuItem>Option 2-2</MenuItem>
</Menu>

Use Icons to Enhance Recognition

Add icons to menu items:

import { Add, Pen, Trash } from '@kubed/icons';

<Menu>
<MenuItem icon={<Add />}>Create</MenuItem>
<MenuItem icon={<Pen />}>Edit</MenuItem>
<MenuItem icon={<Trash />}>Delete</MenuItem>
</Menu>;

Organize Menu with Groups

Use MenuLabel and Divider to organize menu:

<Menu>
<MenuLabel>Basic Operations</MenuLabel>
<MenuItem>Create</MenuItem>
<MenuItem>Edit</MenuItem>
<Divider />
<MenuLabel>Dangerous Operations</MenuLabel>
<MenuItem>Delete</MenuItem>
</Menu>

Dangerous Operations Placement

Place dangerous operations at the bottom of menu:

<Menu>
<MenuItem>View</MenuItem>
<MenuItem>Edit</MenuItem>
<MenuItem>Copy</MenuItem>
<Divider />
<MenuItem icon={<Trash />}>Delete</MenuItem>
</Menu>

Disable Rather Than Hide

Disable unavailable menu items instead of hiding them:

<Menu>
<MenuItem>Start</MenuItem>
<MenuItem disabled>Stop (Pod not running)</MenuItem>
<MenuItem>Restart</MenuItem>
</Menu>

As Navigation Menu

When used as sidebar navigation, highlight current selected item:

const [active, setActive] = useState('pods');

<Menu>
<MenuItem
icon={<Pod />}
onClick={() => setActive('pods')}
style={{
backgroundColor: active === 'pods' ? '#e8f4ff' : 'transparent',
fontWeight: active === 'pods' ? 600 : 400,
}}
>
Pods
</MenuItem>
<MenuItem
icon={<Service />}
onClick={() => setActive('services')}
style={{
backgroundColor: active === 'services' ? '#e8f4ff' : 'transparent',
fontWeight: active === 'services' ? 600 : 400,
}}
>
Services
</MenuItem>
</Menu>;

Specify href property when using links:

<Menu>
<MenuItem as="a" href="/home">
Home
</MenuItem>
<MenuItem as="a" href="/profile">
Profile
</MenuItem>
<MenuItem as="a" href="/settings">
Settings
</MenuItem>
</Menu>

Combined with Dropdown

Menu is commonly used with Dropdown:

<Dropdown content={<Menu>...</Menu>}>
<Button>Actions</Button>
</Dropdown>

Theme Selection

Choose appropriate theme based on background:

// Light background: use default theme
<Card>
<Menu>...</Menu>
</Card>

// Dark background: use dark theme
<Card style={{ backgroundColor: '#242e42' }}>
<Menu themeType="dark">...</Menu>
</Card>

Set appropriate width based on content:

// Short text: smaller width
<Menu width={180}>
<MenuItem>Create</MenuItem>
<MenuItem>Edit</MenuItem>
</Menu>

// Long text: larger width
<Menu width={260}>
<MenuItem>Create Kubernetes Resource</MenuItem>
<MenuItem>Edit YAML Configuration</MenuItem>
</Menu>