Clawscale

Menu

A Menu lists actions. Put it in a popover to build a dropdown. For right-click menus, see Context menu.

Usage#

import { Menu, MenuDivider, MenuItem } from "@clawscale/react";
<Menu>
  <MenuItem icon="play" text="Run pipeline" onClick={runPipeline} />
  <MenuItem icon="duplicate" text="Duplicate" onClick={duplicate} />
</Menu>

Examples#

Basic#

Every MenuItem needs text. Add onClick or href to make it act. disabled turns an item off.

import { Classes, Menu, MenuItem } from "@clawscale/react";

export default function MenuBasic() {
  return (
    <Menu className={Classes.ELEVATION_1}>
      <MenuItem text="Open pipeline" />
      <MenuItem text="Run now" />
      <MenuItem text="Edit schedule" />
      <MenuItem disabled text="Archive" />
    </Menu>
  );
}

Icons and labels#

icon renders before the text. label renders right-aligned text, such as a hotkey or a count. Pass an element with labelElement.

import { Classes, Icon, Menu, MenuItem } from "@clawscale/react";

export default function MenuIcons() {
  return (
    <Menu className={Classes.ELEVATION_1}>
      <MenuItem icon="play" text="Run pipeline" label="⌘R" />
      <MenuItem icon="duplicate" text="Duplicate" label="⌘D" />
      <MenuItem icon="history" text="Run history" label="1,284" />
      <MenuItem icon="code-block" text="Open in notebook" labelElement={<Icon icon="share" />} />
    </Menu>
  );
}

Nest MenuItem elements to build a submenu. It opens on hover to the right and flips left when space runs out.

import { Classes, Menu, MenuItem } from "@clawscale/react";

export default function MenuSubmenus() {
  return (
    <Menu className={Classes.ELEVATION_1}>
      <MenuItem icon="play" text="Run pipeline" />
      <MenuItem icon="export" text="Export results">
        <MenuItem text="CSV" />
        <MenuItem text="Parquet" />
        <MenuItem text="JSON Lines" />
      </MenuItem>
      <MenuItem icon="globe" text="Replicate to">
        <MenuItem text="us-east-1" />
        <MenuItem text="eu-west-1" />
        <MenuItem text="ap-southeast-2" />
      </MenuItem>
    </Menu>
  );
}

Dividers#

MenuDivider separates groups of items. Its optional title labels the group below it.

import { Classes, Menu, MenuDivider, MenuItem } from "@clawscale/react";

export default function MenuDividers() {
  return (
    <Menu className={Classes.ELEVATION_1}>
      <MenuDivider title="Pipelines" />
      <MenuItem icon="flows" text="ingest_orders" label="Hourly" />
      <MenuItem icon="flows" text="refresh_revenue" label="Daily" />
      <MenuDivider title="Datasets" />
      <MenuItem icon="th" text="orders_daily" label="3.4M rows" />
      <MenuItem icon="th" text="revenue_by_region" label="12K rows" />
      <MenuDivider />
      <MenuItem icon="cog" text="Workspace settings" />
    </Menu>
  );
}

Intent#

intent colors an item. Keep danger for destructive actions.

import { Classes, Menu, MenuItem } from "@clawscale/react";

export default function MenuIntent() {
  return (
    <Menu className={Classes.ELEVATION_1}>
      <MenuItem icon="play" intent="primary" text="Run pipeline" />
      <MenuItem icon="tick-circle" intent="success" text="Mark as validated" />
      <MenuItem icon="pause" intent="warning" text="Pause ingestion" />
      <MenuItem icon="trash" intent="danger" text="Delete dataset" />
    </Menu>
  );
}

A Menu does not open or close by itself. Pass it as the content of a PopoverNext. Clicking an item closes the popover, unless the item sets shouldDismissPopover={false}.

import { Button, Menu, MenuDivider, MenuItem, PopoverNext } from "@clawscale/react";

export default function MenuDropdown() {
  return (
    <PopoverNext
      placement="bottom-start"
      content={
        <Menu>
          <MenuItem icon="th" text="Table" />
          <MenuItem icon="timeline-line-chart" text="Line chart" />
          <MenuItem icon="heat-grid" text="Heatmap" />
          <MenuDivider />
          <MenuItem icon="code" text="SQL editor" />
        </Menu>
      }
    >
      <Button alignText="start" icon="applications" endIcon="caret-down" text="Open with" />
    </PopoverNext>
  );
}

Interactive playground#

Props
First item
Open dropdown
View source on GitHub

Props interface#

Menu renders a <ul> and accepts its HTML attributes.

interface MenuProps extends Props, React.HTMLAttributes<HTMLUListElement>@clawscale/react
PropsDescription
children
React.ReactNode
Menu items.
className
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
largedeprecated
boolean = false
Whether the menu items in this menu should use a large appearance.
use size="large" instead.
size
Size = "medium"
The size of the items in this menu.
smalldeprecated
boolean = false
Whether the menu items in this menu should use a small appearance.
use size="small" instead.
ulRef
React.Ref<HTMLUListElement>
Ref handler that receives the HTML <ul> element backing this component.

MenuItem renders an <li> that wraps an <a>. HTML attributes go to the <a>. The ref goes to the <li>.

interface MenuItemProps extends ActionProps<HTMLAnchorElement>, React.AnchorHTMLAttributes<HTMLAnchorElement>, React.RefAttributes<HTMLLIElement>@clawscale/react

Note that the HTML attributes supported by this component are spread to the nested <a> element, while the ref is attached to the root <li> element. This is an unfortunate quirk in the API which we keep around for backwards-compatibility.

PropsDescription
active
boolean
Whether this item should appear _active_, often useful to indicate keyboard focus. Note that this is distinct from _selected_ appearance, which has its own prop.
children
React.ReactNode
Children of this component will be rendered in a _submenu_ that appears in a popover when hovering or clicking on this item.
className
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
disabled
boolean
Whether this menu item is non-interactive. Enabling this prop will ignore href, tabIndex, and mouse event handlers (in particular click, down, enter, leave).
htmlTitle
string
HTML title to be passed to the <Text> component
icon
IconName | MaybeElement
Name of a Blueprint UI icon (or an icon element) to render before the text.
Inherited from ActionProps
intent
Intent
Visual intent color to apply to element.
Inherited from IntentProps
label
string
Right-aligned label text content, useful for displaying hotkeys.
labelClassName
string
A space-delimited list of class names to pass along to the right-aligned label wrapper element.
labelElement
React.ReactNode
Right-aligned label content, useful for displaying hotkeys.
multiline
boolean = false
Whether the text should be allowed to wrap to multiple lines. If false, text will be truncated with an ellipsis when it reaches max-width.
onClick
(event: React.MouseEvent<T>) => void
Click event handler.
Inherited from ActionProps
onFocus
(event: React.FocusEvent<T>) => void
Focus event handler.
Inherited from ActionProps
popoverProps
Partial<Omit<PopoverProps, "content" | "minimal">>
Props to spread to the submenu popover. Note that content and minimal cannot be changed and usePortal defaults to false so all submenus will live in the same container.
roleStructure
"menuitem" | "listoption" | "listitem" | "none" = "menuitem"
Changes the ARIA role property structure of this MenuItem to accomodate for various different roles of the parent Menu ul element.
selected
boolean = undefined
Whether this item should appear selected - roleStructure must be "listoption" for this to be applied. Defining this will set the aria-selected attribute and apply a small tick icon if true, and empty space for a small tick icon if false or undefined.
shouldDismissPopover
boolean = true
Whether an enabled item without a submenu should automatically close its parent popover when clicked.
submenuProps
Partial<MenuProps>
Props to spread to the child Menu component if this item has a submenu.
tagName
keyof React.JSX.IntrinsicElements = "a"
Name of the HTML tag that wraps the MenuItem.
textrequired
React.ReactNode
Item text, required for usability.
textClassName
string
A space-delimited list of class names to pass along to the text wrapper element.
interface MenuDividerProps extends Props@clawscale/react
PropsDescription
children
never
This component does not support children.
className
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
title
React.ReactNode
Optional header title.
titleId
string
Optional id prop for the header title.