A menu offers a list of choices to the user, such as a set of actions or functions.
usage import { MenuTrigger, Menu, Item, Section, Divider, MenuTriggerContext, useMenuTriggerContext } from "@sharegate/orbit-ui";
UsageA menu accepts exactly two children: the element which trigger the opening of the menu and the menu items. A trigger can be any component which accepts a ref
and any other props passed from menu.
DefaultA default menu.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
</ MenuTrigger >
SectionsA menu items can be group by sections.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Section title = " Actions " >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
</ Section >
< Section title = " Others " >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Section >
</ Menu >
</ MenuTrigger >
DividersA menu items can be separated by dividers.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
< Divider />
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
</ MenuTrigger >
Item iconA menu item can have icons .
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " >
< PlaceholderMajorIcon />
< Text > Launch... </ Text >
</ Item >
< Item key = " eject " >
< PlaceholderMajorIcon />
< Text > Eject... </ Text >
</ Item >
< Item key = " land " >
< PlaceholderMajorIcon />
< Text > Land... </ Text >
</ Item >
</ Menu >
</ MenuTrigger >
Item end iconA select item can have non standard end icons can be provided to handle special cases like displaying a list of icons. However, think twice before adding end icons, start icons should be your go to.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " >
< Text > Launch... </ Text >
< IconList slot = " end-icon " >
< UfoMajorIcon />
< TelescopeMajorIcon />
< RocketMajorIcon />
</ IconList >
</ Item >
< Item key = " eject " >
< Text > Eject... </ Text >
< PlaceholderMajorIcon slot = " end-icon " />
</ Item >
< Item key = " land " >
< Text > Land... </ Text >
< IconList slot = " end-icon " >
< UfoMajorIcon />
< TelescopeMajorIcon />
< RocketMajorIcon />
</ IconList >
</ Item >
</ Menu >
</ MenuTrigger >
Item descriptionA menu item can have a single line description.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " >
< Text > Launch... </ Text >
< Text slot = " description " > Launch... </ Text >
</ Item >
< Item key = " eject " >
< Text > Eject... </ Text >
< Text slot = " description " > Eject... </ Text >
</ Item >
< Item key = " land " >
< Text > Land... </ Text >
< Text slot = " description " > Land on Of Course I Still Love You </ Text >
</ Item >
</ Menu >
</ MenuTrigger >
A description can be paired with an icon .
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " >
< PlaceholderMajorIcon />
< Text > Launch... </ Text >
< Text slot = " description " > Launch... </ Text >
</ Item >
< Item key = " eject " >
< PlaceholderMajorIcon />
< Text > Eject... </ Text >
< Text slot = " description " > Eject... </ Text >
</ Item >
< Item key = " land " >
< PlaceholderMajorIcon />
< Text > Land... </ Text >
< Text slot = " description " > Land on Of Course I Still Love You </ Text >
</ Item >
</ Menu >
</ MenuTrigger >
A description can also be paired with an avatar
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " >
< Avatar name = " Sally Ride " />
< Text > Sally Ride </ Text >
< Text slot = " description " > First American woman to go into space </ Text >
</ Item >
< Item key = " eject " >
< Avatar name = " Alan Shepard " />
< Text > Alan Shepard </ Text >
< Text slot = " description " >
American astronaut, naval aviator, test pilot, and businessman
</ Text >
</ Item >
< Item key = " land " >
< Avatar name = " Chris Hadfield " />
< Text > Chris Hadfield </ Text >
< Text slot = " description " > First Canadian Astronaut to walk in space </ Text >
</ Item >
</ Menu >
</ MenuTrigger >
A menu item can have a basic tooltip.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< TooltipTrigger >
< Item key = " land " > Land... </ Item >
< Tooltip > Land on Of Course I Still Love You </ Tooltip >
</ TooltipTrigger >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
</ MenuTrigger >
Disabled itemA menu item can be disabled.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
< Item disabled key = " launch " >
Launch...
</ Item >
< Item key = " eject " > Eject... </ Item >
< Item disabled key = " land " >
Land...
</ Item >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
</ MenuTrigger >
ValidationA menu can display a validation state to communicate to the user whether the current value is valid or invalid. Implement your own validation logic in your app and pass either "valid"
or "invalid"
to the menu via the validationState
prop.
Editable example
< Menu
validationState = " invalid "
defaultSelectedKeys = { [ "land" ] }
selectionMode = " single "
aria-label = " View tasks "
>
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
SelectionA menu supports multiple selection modes. By default, selection is disabled, however this can be changed by settings the selectionMode
property to "single"
or "multiple"
.
When using selection with a <Menu>
component wraped inside a <MenuTrigger>
, you must handled the selected keys in controlled mode with the selectedKeys
property otherwise the selected keys won't be persisted through openings.
Editable example
( ) => {
const [ selectedKeys , setSelectedKeys ] = useState ( [ ] ) ;
const handleSelectionChange = useCallback (
( event , newKeys ) => {
setSelectedKeys ( newKeys ) ;
} ,
[ setSelectedKeys ]
) ;
return (
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu
selectionMode = " multiple "
selectedKeys = { selectedKeys }
onSelectionChange = { handleSelectionChange }
>
< Section title = " Actions " >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
</ Section >
< Section title = " Others " >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Section >
</ Menu >
</ MenuTrigger >
) ;
} ;
Custom triggerA menu trigger can update is appareance based on the isOpen
value by using useMenuTriggerContext
.
Any trigger would work as long as it accepts a ref
and any other props provided by the menu.
Editable example
const CustomTrigger = forwardRef ( ( props , ref ) => {
const { isOpen } = useMenuTriggerContext ( ) ;
return (
< IconButton
{ ... props }
variant = { isOpen ? "primary" : "secondary" }
aria-label = " View tasks "
ref = { ref }
>
< VerticalDotsMajorIcon />
</ IconButton >
) ;
} ) ;
render (
< MenuTrigger >
< CustomTrigger />
< Menu >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
< Divider />
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
</ MenuTrigger >
) ;
Disclosure arrowYou can use a disclosure arrow component to hint that activating the button will display additional content.
Editable example
< MenuTrigger >
< Button variant = " secondary " >
< Text > Trigger </ Text >
< DisclosureArrow slot = " end-icon " />
</ Button >
< Menu >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
</ MenuTrigger >
Dynamic itemsA menu items can be rendered dynamically.
Editable example
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu >
{ [ "Launch" , "Eject" , "Land" , "Help" , "Exit" ] . map ( x => (
< Item key = { x . toLowerCase ( ) } > { x } </ Item >
) ) }
</ Menu >
</ MenuTrigger >
ControlledThe selectedKey
and open
state can be handled in controlled mode.
Editable example
( ) => {
const [ selectedKey , setSelectedKey ] = useState ( [ ] ) ;
const [ isOpen , setIsOpen ] = useState ( false ) ;
const handleOpenChange = useCallback (
( event , newOpen ) => {
setIsOpen ( newOpen ) ;
console . log ( newOpen ) ;
} ,
[ setIsOpen ]
) ;
const handleSelectionChange = useCallback ( ( event , newKeys ) => {
setSelectedKey ( newKeys ) ;
console . log ( newKeys ) ;
} , [ ] ) ;
return (
< MenuTrigger open = { isOpen } onOpenChange = { handleOpenChange } >
< Button variant = " secondary " > Trigger </ Button >
< Menu
selectionMode = " single "
selectedKeys = { selectedKey }
onSelectionChange = { handleSelectionChange }
>
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
< Item key = " help " > Help </ Item >
< Item key = " exit " > Exit </ Item >
</ Menu >
</ MenuTrigger >
) ;
} ;
Opening a modalA ModalTrigger
component won't work with a menu item. Still, it can be done with a custom modal trigger .
Editable example
( ) => {
const [ isOpen , setIsOpen ] = useState ( false ) ;
const handleSelectionChange = useCallback (
( event , keys ) => {
setIsOpen ( true ) ;
} ,
[ setIsOpen ]
) ;
const handleModalClose = useCallback ( ( ) => {
setIsOpen ( false ) ;
} , [ setIsOpen ] ) ;
return (
< >
< MenuTrigger >
< IconButton variant = " secondary " aria-label = " View tasks " >
< VerticalDotsMajorIcon />
</ IconButton >
< Menu onSelectionChange = { handleSelectionChange } >
< Item key = " launch " > Launch... </ Item >
< Item key = " eject " > Eject... </ Item >
< Item key = " land " > Land... </ Item >
</ Menu >
</ MenuTrigger >
< Overlay show = { isOpen } >
< Modal onClose = { handleModalClose } >
< Heading > Apollo 11 movie </ Heading >
< Content >
< Paragraph >
Apollo 11 is a 2019 American documentary film edited, produced and
directed by Todd Douglas Miller. It focuses on the 1969 Apollo 11
mission, the first spaceflight from which men walked on the Moon.
</ Paragraph >
< Paragraph >
The film consists solely of archival footage, including 70 mm film
previously unreleased to the public, and does not feature narration,
interviews or modern recreations. The Saturn V rocket, Apollo crew
consisting of Buzz Aldrin, Neil Armstrong, and Michael Collins, and
Apollo program Earth-based mission operations engineers are prominently
featured in the film.
</ Paragraph >
</ Content >
</ Modal >
</ Overlay >
</ >
) ;
} ;
API
usage import { MenuTrigger } from "@sharegate/orbit-ui";
Name Description Default align The horizontal alignment of the popup relative to the trigger.
- allowFlip Whether or not the popup can flip when it will overflow it's boundary area.
- allowPreventOverflow Whether or not the popup position can change to prevent it from being cut off so that it stays visible within its boundary area.
- children * React children.
string | number | false | true | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal
- closeOnSelect Whether or not the menu should close when an item is selected.
- defaultOpen The initial value of open when in auto controlled mode.
- direction The direction the open will open relative to the trigger.
- onOpenChange Called when the open state change.
(event: SyntheticEvent<Element, Event>, isOpen: boolean) => void
event
React's original event. isOpen
Indicate if the popup is visible.
- open Whether or not to show the popup.
- zIndex The z-index of the menu.
-
usage import { Menu } from "@sharegate/orbit-ui";
Name Description Default autoFocus Whether or not the menu should autofocus on render.
- autoFocusTarget Default focus target when enabling autofocus.
- children * React children.
string | number | false | true | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal
- defaultSelectedKeys The initial value of selectedKeys
when uncontrolled.
string[]
- disabled Whether or not the menu items are disabled.
- fluid Whether or not the listbox take up the width of its container.
false | true | ResponsiveValue<boolean>
- nodes A collection of nodes to render instead of children. It should only be used if you embed a Menu inside another component.
CollectionNode[]
- onSelectionChange Called when the selected keys change.
(event: SyntheticEvent<Element, Event>, keys: string[]) => void
event
React's original event. keys
The keys of the selected items..
- selectedKeys A controlled set of the selected item keys.
string[]
- selectionMode The type of selection that is allowed.
"none"
validationState Whether or not the menu should display as "valid" or "invalid".
-
Item
usage import { Item } from "@sharegate/orbit-ui";
slots "icon", "text", "description", "end-icon"
Name Description Default children React children.
string | number | false | true | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal
- key A unique key to identify the item.
-
Section
usage import { Section } from "@sharegate/orbit-ui";
Name Description Default children * React children.
string | number | false | true | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal
-
Divider
usage import { Divider } from "@sharegate/orbit-ui";
Name Description Default orientation The orientation of the divider.
"horizontal" | "vertical" | ResponsiveValue<"horizontal" | "vertical">
horizontal
usage import { MenuItem } from "@sharegate/orbit-ui";
Name Description Default children * React children.
string | number | false | true | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal
- disabled Whether or not the item is disabled.
- item * Matching collection item.
-
usage import { MenuSection } from "@sharegate/orbit-ui";
Name Description Default children * React children.
string | number | false | true | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal
- title The section name.
-