Components
Menu - New!
Menu is an ecosystem of components that provide a structured and accessible way to create menus.
Prebuilt Toggle Elements
The menuToggleElement
prop determines what element or component triggers your menu to open and close. Seeds provides several toggle components to cover a variety of use cases, from simple buttons to accessible listbox triggers and custom input fields.
Below are the available toggle components, their use cases, and example usage.
Accessibility:
All prebuilt toggle components are designed for accessibility out of the box. When building a custom toggle, be sure to follow accessibility guidelines and use the provided context hooks.
MenuToggleButton
The MenuToggleButton is a button designed to trigger the opening and closing of menus. Its props are interchangeable with .
Use case:
The default and most common toggle for menus. Use this for standard dropdowns, action menus, and most menu scenarios where a button is appropriate.
MenuToggleButton
accepts all the same props as .
Name | Type | Default | Description | Required? |
---|---|---|---|---|
external | boolean | If the button is being used as an anchor, this prop will cause the link to open in a new tab. | ||
size | | "large" | "small" | "default" | "default" | ||
appearance | | "primary" | "secondary" | "pill" | "destructive" | "unstyled" | "placeholder" | "unstyled" | What the button looks like. | |
active | boolean | false | Set the button to display in its active state | |
disabled | boolean | Disables user action and applies a disabled style on the button | ||
children | React.ReactNode | |||
href | string | Setting this prop will cause the component to be rendered as an anchor element instead of a button element | ||
download | string | If the component is rendered as an anchor to a file, this prop sets the name of the file to be downloaded | ||
innerRef | React.Ref<HTMLButtonElement> | Used to get a reference to the underlying button | ||
onClick | React.MouseEventHandler<HTMLButtonElement> | Action to perform when the button is clicked | ||
title | string | |||
qa | object | {} | ||
as | TypeStyledComponentsCommonProps["as"] | |||
ariaLabel | string | Label used to describe the button if the button does not have text within it |
This example shows how to use MenuToggleButton
as a menu trigger.
Example:
import { MenuToggleButton } from '@sproutsocial/seeds-react-menu'
<Box display="flex" justifyContent="center" alignItems="center" height="100%"><ActionMenumenuToggleElement={<MenuToggleButton appearance="primary">I'm a MenuToggleButton</MenuToggleButton>}><MenuContent><MenuItem id="item-one">Item 1</MenuItem><MenuItem id="item-two">Item 2</MenuItem><MenuItem id="item-three">Item 3</MenuItem></MenuContent></ActionMenu></Box>
View MenuToggleButton in Storybook
ListboxToggleButton
ListboxToggleButton extends MenuToggleButton and is styled to look like a select dropdown.
It accepts all the same props as MenuToggleButton, with an additional invalid
prop for error state styling.
Use case:
Use when you want your menu trigger to look and behave like a native select dropdown.
Name | Type | Default | Description | Required? |
---|---|---|---|---|
invalid | boolean |
This example demonstrates ListboxToggleButton
styled as a select dropdown trigger.
Example:
import { ListboxToggleButton } from '@sproutsocial/seeds-react-menu'
<Box display="flex" justifyContent="center" alignItems="center" height="100%"><SingleSelectMenumenuToggleElement={<ListboxToggleButton>Open Listbox</ListboxToggleButton>}><MenuContent><MenuItem id="item-one">Item 1</MenuItem><MenuItem id="item-two">Item 2</MenuItem><MenuItem id="item-three">Item 3</MenuItem></MenuContent></SingleSelectMenu></Box>
MenuLabel + ListboxToggleButton
MenuLabel extends the component, but manages association with the menu toggle automatically—so you should not provide an htmlFor
prop. It is used to improve the accessibility of a menu by providing a text label for the menu's toggle element.
Use case:
Use MenuLabel to provide an accessible, visible label for your menu toggle, especially in form-like menus.
Name | Type | Default | Description | Required? |
---|---|---|---|---|
children | React.ReactNode | |||
required | boolean | false | Whether making a selection in the associated menu is required. | |
htmlFor | never | ID of the associated form element. This prop is never valid to pass into MenuLabel
because MenuLabel passes its own htmlFor prop to the underlying Label component. |
This example shows how to pair MenuLabel
with ListboxToggleButton
for an accessible labeled menu trigger.
Example:
import { MenuLabel, ListboxToggleButton, SingleSelectMenu, MenuContent, MenuItem } from '@sproutsocial/seeds-react-menu'
<Box display="flex" justifyContent="center" alignItems="center" height="100%"><SingleSelectMenumenuToggleElement={<><MenuLabel mr={300}>Choose an option:</MenuLabel><ListboxToggleButton>Open Listbox</ListboxToggleButton></>}><MenuContent><MenuItem id="item-one">Item 1</MenuItem><MenuItem id="item-two">Item 2</MenuItem><MenuItem id="item-three">Item 3</MenuItem></MenuContent></SingleSelectMenu></Box>
AutocompleteInput as Toggle
AutocompleteInput extends the component, but its event listeners (such as onKeyDown
, onChange
, etc.) are adapted for compatibility with Downshift’s combobox pattern. This ensures seamless integration with menu state and accessibility features when used as a menu toggle.
Use case:
For searchable menus, use an AutocompleteInput inside a as your toggle. This pattern is common for single-select autocomplete menus.
This example demonstrates using AutocompleteInput
inside a form field as a searchable menu toggle.
Example:
import { Autocomplete, AutocompleteInput, FormField, MenuLabel, MenuContent, MenuItem } from '@sproutsocial/seeds-react-menu'
<Box display="flex" justifyContent="center" alignItems="center" height="100%"><AutocompletemenuToggleElement={<FormField label={<MenuLabel>Search books</MenuLabel>}>{props => <AutocompleteInput {...props} />}</FormField>}><MenuContent><MenuItem id="book-1">Book One</MenuItem><MenuItem id="book-2">Book Two</MenuItem><MenuItem id="book-3">Book Three</MenuItem></MenuContent></Autocomplete></Box>
AutocompleteTokenInput as Toggle
AutocompleteTokenInput extends the component, adapting its event listeners for compatibility with Downshift’s combobox pattern and supporting rendering multiple selected items as tokens.
Use case:
For multi-select autocomplete menus, use an AutocompleteTokenInput inside a as your toggle. This allows users to select multiple items and see them as tokens.
Name | Type | Default | Description | Required? |
---|---|---|---|---|
getTokenProps | (itemId: string) => Partial<TypeTokenSpec> | A function that can be passed to override the default token props | ||
MenuContext | | MenuToggleContext | MenuContentContext | createContext<TypeMenuToggleContext>(defaultMenuContext) | Specify the menu context to use. MenuToggleContext is the default.
This prop is only needed for specialized use cases. |
This example shows AutocompleteTokenInput
used as a multi-select autocomplete menu toggle, displaying selected items as tokens.
Example:
import { Autocomplete, AutocompleteTokenInput, FormField, MenuLabel, MenuContent, MenuItem } from '@sproutsocial/seeds-react-menu'
<Box display="flex" justifyContent="center" alignItems="center" height="100%"><AutocompletemultiSelectmenuToggleElement={<FormField label={<MenuLabel>Search and select books</MenuLabel>} width="250px">{props => <AutocompleteTokenInput {...props} />}</FormField>}><MenuContent><MenuItem id="book-1">Book One</MenuItem><MenuItem id="book-2">Book Two</MenuItem><MenuItem id="book-3">Book Three</MenuItem></MenuContent></Autocomplete></Box>
Using Custom Toggle Elements
You can create your own custom toggle element by using the useMenuToggleContext
and calling getToggleButtonProps
. This is useful if you want to use a non-standard element as your menu trigger.
Note:
For the best experience, we recommend using our prebuilt toggle components above.
The following is an advanced pattern intended for custom use cases where you need to build your own toggle element and handle menu state directly. When building a custom toggle, be sure to follow accessibility guidelines and use the provided context hooks to ensure your menu remains accessible.
This example demonstrates creating a custom menu toggle using useMenuToggleContext
and getToggleButtonProps
.
Example:
import { useMenuToggleContext } from '@sproutsocial/seeds-react-menu'
() => {// A custom toggle button using getToggleProps from MenuToggleContextconst CustomToggle = () => {const { getToggleButtonProps, isOpen, isListbox, ref, ariaProps } = useMenuToggleContext();return (<Button{...getToggleButtonProps?.({// adds the ref from the Popout componentref,// specifies the prop used on the Button component for the refrefKey: "innerRef",// adds the aria tags coming from the Popout component...ariaProps,// adds the correct role if this is an ActionMenu...(isListbox ? {} : { role: "button", "aria-haspopup": "menu" }),})}style={{padding: "8px 16px",background: isOpen ? "#e0f7fa" : "#fff",border: "2px solid #00bcd4",borderRadius: 4,cursor: "pointer",fontWeight: "bold"}}>{isOpen ? "Close" : "Open"} Custom Menu</Button>);};return (<Box display="flex" justifyContent="center" alignItems="center" height="100%"><ActionMenu menuToggleElement={<CustomToggle />}><MenuContent><MenuItem id="item-one">Item 1</MenuItem><MenuItem id="item-two">Item 2</MenuItem><MenuItem id="item-three">Item 3</MenuItem></MenuContent></ActionMenu></Box>);}