Skip to main content

Menu

Menus are used to display a list of items using a dropdown components. Embeded with headless UI, they support a11y features such as keyboard navigation and screen reader support.

Menu Example

// @heroicons/react v2
import { Menu } from '@fluid-design/fluid-ui';
import {
ArrowRightOnRectangleIcon,
BellIcon,
CogIcon,
UserIcon,
} from '@heroicons/react/24/outline';
function Example() {
return (
<Menu
label='Settings'
color='gray'
weight='clear'
iconStart={CogIcon}
iconEndPosition='between'
menuPositionY='bottom'
header='Hi, User'
className='absolute right-4 top-4'
menus={[
{
label: 'Profile',
iconStart: UserIcon,
},
{
role: 'separator',
},
{
label: 'Notifications',
iconStart: BellIcon,
role: 'info',
},
]}
/>
);
}

Basic Example

Basic Example

// @heroicons/react v2
import { Menu } from '@fluid-design/fluid-ui';
import { BellIcon, CogIcon, UserIcon } from '@heroicons/react/24/outline';
function Example() {
return (
<Menu
label='Settings'
color='gray'
weight='outline'
iconStart={CogIcon}
iconEndPosition='between'
menuPositionY='bottom'
header='Hi, User'
menus={[
{
label: 'Profile',
iconStart: UserIcon,
onClick: () => null,
},
{
role: 'separator',
},
{
label: 'Notifications',
role: 'info',
iconStart: BellIcon,
onClick: () => null,
},
]}
/>
);
}

Use as component

Menu can also be used as a component to render custom content. And instead of using the menus prop, you can use the <Menu.Item /> component to render the menu items. This is useful when you want to render a custom menu.


import { Menu } from '@fluid-design/fluid-ui';
import { Fragment } from 'react';
function Example() {
const avatarImage =
'https://images.unsplash.com/photo-1626544827763-d516dce335e2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=80&q=80';
return (
<Menu
className='inline-block'
color='indigo'
iconEnd={ChevronRightIcon}
iconEndPosition='between'
label='Options'
menuClassName='w-40'
menuPositionX='end'
menuPositionY='center'
weight='light'
>
<Fragment>
<div className='flex flex-col items-center justify-center gap-2 px-3.5 py-2'>
<img
alt='avatar'
className='h-12 w-12 rounded-full'
src={avatarImage}
/>
<p>Custom Menu</p>
</div>
<Menu.Item
className='justify-between'
isLoading={isEditing}
role='info'
loadingOptions={{
animation: 'pulse',
}}
>
<span>Edit</span>
<PencilIcon className='h-4 w-4' />
</Menu.Item>
<Menu.Item
className='justify-between'
disabled={true}
role='destructive'
>
<span>Delete</span>
<TrashIcon className='h-4 w-4' />
</Menu.Item>
</Fragment>
</Menu>
);
}

Rendering additional content

You can add custom content to the <Menu /> component by passing a children prop. However, according to A11y standars and Headless UI, it is recommended to use the <Popover /> component instead.

Component API

PropDefaultDescription
badgeundefinedstring | number

Badge to be rendered on the right side of the button.

badgeClassNameundefinedstring

Class name to be applied to the badge.

headerundefinedJSX.Element | string;

Header to be rendered on the top of the menu.

classNameundefinedstring

Class name to be applied to the menu.

menuClassNameundefinedstring

Class name to be applied to the menu list.

buttonClassNameundefinedstring

Class name to be applied to the button.

menuButtonClassNameundefinedstring

Class name to be applied to the menu button.

menuPositionX'start''start' | 'center' | 'end'

Position of the menu on the X axis.

menuPositionY'bottom''top' | 'center' | 'bottom'

Position of the menu on the Y axis.

horizontalfalseboolean

Whether the menu should be rendered horizontally.

menusundefinedMenuItems[]

Array of menu items to be rendered. Use this prop if you want to render the menu items as a list. Otherwise, use the children prop as it will have no effect.

srundefinedstring

Screen reader text.

PropDefaultDescription
labelundefinedstring

Label of the menu item.

roleundefined"separator" | "destructive" | "default" | "info" | "success" | "warning" | "primary"

Role of the menu item.

iconStartundefinedJSX.Element

Icon to be rendered on the left side of the menu item.

iconEndundefinedJSX.Element

Icon to be rendered on the right side of the menu item.

Menu button uses Button component as a base. You can pass all the props that Button component accepts.

PropDefaultDescription
labelundefinedstring

Label of the button.

labelClassNameundefinedstring

Class name to be applied to the label.

iconundefinedJSX.Element

Icon to be rendered on the left side of the button.

iconClassNameundefinedstring

Class name to be applied to the icon.

iconStartundefinedJSX.Element

Icon to be rendered on the left side of the button.

iconStartClassNameundefinedstring

Class name to be applied to the icon start.

iconEndundefinedJSX.Element

Icon to be rendered on the right side of the button.

iconEndClassNameundefinedstring

Class name to be applied to the icon end.

iconStartPosition'flex''flex' | 'between'

Position of the icon start. 'between' will create a gap between the icon and the label

iconEndPosition'flex''flex' | 'between'

Position of the icon end. 'between' will create a gap between the icon and the label