The MenuItem component represents an actionable item within a menu or list. It supports icons, custom content slots, and various states like selected and highlighted.
Basic Usage
import { MenuItem } from 'reshaped';
function App() {
return (
<MenuItem onClick={() => console.log('Clicked')}>
Menu Item
</MenuItem>
);
}
With Icons
Add an icon to the start of the menu item:
import { MenuItem } from 'reshaped';
import IconHome from '@/icons/Home';
import IconSettings from '@/icons/Settings';
import IconUser from '@/icons/User';
<MenuItem icon={IconHome} onClick={() => navigate('/')}>
Home
</MenuItem>
<MenuItem icon={IconUser} onClick={() => navigate('/profile')}>
Profile
</MenuItem>
<MenuItem icon={IconSettings} onClick={() => navigate('/settings')}>
Settings
</MenuItem>
MenuItem supports three size options:
<MenuItem size="small">Small Item</MenuItem>
<MenuItem size="medium">Medium Item</MenuItem>
<MenuItem size="large">Large Item</MenuItem>
MenuItem can be displayed in multiple colors:
<MenuItem color="neutral">Neutral Item</MenuItem>
<MenuItem color="primary">Primary Item</MenuItem>
<MenuItem color="critical">Delete Item</MenuItem>
Selected State
Highlight a menu item as selected:
<MenuItem selected>
Selected Item
</MenuItem>
Highlighted State
Highlight a menu item (e.g., for keyboard navigation):
<MenuItem highlighted>
Highlighted Item
</MenuItem>
Disabled State
Disable user interaction:
<MenuItem disabled>
Disabled Item
</MenuItem>
Custom Slots
Use start and end slots for custom content:
import { MenuItem, Badge, Switch } from 'reshaped';
<MenuItem
startSlot={<Avatar src="/avatar.jpg" size="small" />}
endSlot={<Badge>New</Badge>}
>
User Profile
</MenuItem>
<MenuItem
endSlot={<Switch checked />}
>
Enable notifications
</MenuItem>
Navigation
Use MenuItem for navigation:
<MenuItem href="/dashboard">
Dashboard
</MenuItem>
Rounded Corners
Apply rounded corners to the menu item:
<MenuItem roundedCorners>
Rounded Item
</MenuItem>
Align menu items within a container:
import { MenuItem } from 'reshaped';
function App() {
return (
<MenuItem.Aligner side="inline">
<MenuItem>Aligned Item</MenuItem>
</MenuItem.Aligner>
);
}
import { MenuItem, View } from 'reshaped';
import IconEdit from '@/icons/Edit';
import IconCopy from '@/icons/Copy';
import IconTrash from '@/icons/Trash';
function ContextMenu() {
return (
<View gap={1} padding={2} backgroundColor="elevated">
<MenuItem icon={IconEdit} onClick={handleEdit}>
Edit
</MenuItem>
<MenuItem icon={IconCopy} onClick={handleCopy}>
Duplicate
</MenuItem>
<MenuItem icon={IconTrash} color="critical" onClick={handleDelete}>
Delete
</MenuItem>
</View>
);
}
import { MenuItem, View } from 'reshaped';
import IconHome from '@/icons/Home';
import IconUser from '@/icons/User';
import IconSettings from '@/icons/Settings';
function NavigationMenu({ activePath }) {
return (
<View gap={1}>
<MenuItem
icon={IconHome}
href="/"
selected={activePath === '/'}
>
Home
</MenuItem>
<MenuItem
icon={IconUser}
href="/profile"
selected={activePath === '/profile'}
>
Profile
</MenuItem>
<MenuItem
icon={IconSettings}
href="/settings"
selected={activePath === '/settings'}
>
Settings
</MenuItem>
</View>
);
}
Keyboard Navigation
function KeyboardMenu() {
const [highlightedIndex, setHighlightedIndex] = useState(0);
const items = ['Item 1', 'Item 2', 'Item 3'];
return (
<View gap={1}>
{items.map((item, index) => (
<MenuItem
key={index}
highlighted={highlightedIndex === index}
onClick={() => handleSelect(item)}
>
{item}
</MenuItem>
))}
</View>
);
}
color
'neutral' | 'critical' | 'primary'
default:"primary"
Component color based on color tokens
size
'small' | 'medium' | 'large'
default:"medium"
Component size (responsive)
SVG component for the icon at the start position
Node for inserting custom content at the start side of the component
Node for inserting custom content at the end side of the component
Highlight the component as selected
Highlight the component as hovered or focused (e.g., for keyboard navigation)
Round the corners of the component (responsive)
URL to navigate to when clicked
onClick
(event: React.MouseEvent) => void
Callback when the item is clicked
Stop event propagation when clicked
Override the root element type
Custom render function for advanced use cases
Additional CSS class name
Additional HTML attributes
side
'start' | 'end' | 'inline'
default:"inline"
Side to align the menu item to
children
React.ReactElement
required
MenuItem element to align
Additional CSS class name
Additional HTML attributes