navigation · conformant
FabMenu
FabMenuFabMenuPropsFabMenuItemFabMenuItemProps
import { useState } from 'react'
import { FabMenu, FabMenuItem, Icon, Surface, Text } from '@language-lit/material3-expressive'
export function FabMenuExample() {
const [open, setOpen] = useState(false)
return (
<Surface
as="section"
aria-labelledby="fab-menu-example-title"
color="surface-container-low"
shape="extra-large"
className="fab-menu-example"
>
<Text as="h2" id="fab-menu-example-title" variant="titleLarge" emphasis="emphasized">
FAB menu
</Text>
<Text as="p" variant="bodyMedium">
Click the trigger to morph it into a close button and reveal a
staggered column of items, closest-to-trigger first.
</Text>
<div className="fab-menu-example__row">
<FabMenu
triggerLabel="Create"
icon={<Icon source="add" />}
closeIcon={<Icon source="close" />}
expanded={open}
onExpandedChange={setOpen}
>
<FabMenuItem icon={<Icon source="edit" />} onClick={() => setOpen(false)}>
Edit
</FabMenuItem>
<FabMenuItem icon={<Icon source="share" />} onClick={() => setOpen(false)}>
Share
</FabMenuItem>
<FabMenuItem icon={<Icon source="delete" />} onClick={() => setOpen(false)}>
Delete
</FabMenuItem>
<FabMenuItem onClick={() => setOpen(false)}>Archive</FabMenuItem>
<FabMenuItem icon={<Icon source="lock" />} disabled>
Restricted
</FabMenuItem>
</FabMenu>
</div>
</Surface>
)
}FabMenu renders a trigger FAB that morphs shape, color, and icon size
when toggled, revealing a staggered column of FabMenuItems above it.
import { FabMenu, FabMenuItem } from '@language-lit/material3-expressive'
import '@language-lit/material3-expressive/styles.css'
<FabMenu
triggerLabel="Create"
icon={<AddIcon />}
closeIcon={<CloseIcon />}
expanded={open}
onExpandedChange={setOpen}
>
<FabMenuItem icon={<EditIcon />} onClick={edit}>
Edit
</FabMenuItem>
<FabMenuItem icon={<ShareIcon />} onClick={share}>
Share
</FabMenuItem>
</FabMenu>Contract
triggerLabel(the trigger's accessible name),icon(shown collapsed), andcloseIcon(shown expanded) are required.expanded/defaultExpanded/onExpandedChangefollow the same controlled/uncontrolled toggle contract asIconButton's ownselected/onSelectedChange.childrenareFabMenuItems (icon,childrenas the label,onClick,disabled). Collapsed items areinert— removed from both the accessibility tree and tab order, but kept in the DOM for the reveal transition.- The trigger exposes
aria-expanded/aria-haspopup="true"/aria-controls.ArrowDown(orTab) from a focused, expanded trigger moves focus to the first item. - Wiring the menu to real navigation/actions is entirely up to
onClickon eachFabMenuItem—FabMenudoes not own routing or any overlay/menu semantics beyond the disclosure pattern above.
Tokens and boundaries
Colors, geometry, and motion timing come entirely from
--m3e-comp-fab-menu-* CSS custom properties, scoped by
Material3Provider. FabMenu injects no runtime styles and uses no
requestAnimationFrame loop — the trigger's collapsed/expanded morph and
each item's staggered reveal are both plain CSS transitions.