Menus and filters
Every dropdown in the product is the same menu. Filters sit at the right of a toolbar and show their current value.
All menus use the dropdown menu: a white panel, a light blue row on hover, and a blue tick on the selected item. Do not build a menu from scratch.
Filters
A filter button names what it filters and shows the current value. The list opens aligned to the button's right edge when the button sits at the right of the toolbar.
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="secondaryGhost" size="md" />}>
<Funnel size={16} />
<span>Status</span>
<span style={{ fontWeight: 500 }}>{current.label}</span>
<CaretDown size={14} />
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{STATUSES.map((s) => (
<DropdownMenuItem key={s.id} onClick={() => setStatus(s.id)}>
<span className="flex-1">{s.label}</span>
<span>{s.count}</span>
{s.id === status && <Check size={16} weight="bold" />}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>- Lead the toolbar with the scope (whose items, or which list), then filters on the right.
- Show counts in filter options when they help people choose.
- Keep a filter's value when people leave and come back to the page.
Actions menus
Group a row's secondary actions in one menu. Put destructive actions last, after a separator, with the destructive variant.
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="secondaryGhost" label="Page actions" icon={CaretDown} iconPosition="suffix" />} />
<DropdownMenuContent>
<DropdownMenuItem>Rename</DropdownMenuItem>
<DropdownMenuItem>Duplicate</DropdownMenuItem>
<DropdownMenuItem>Save as template</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive"><Trash size={16} /> Delete page</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Rules
- Use the Petavue Button as the trigger, through
render. Icon, label, value and caret share one colour. - Menu items are 14px. A second line, when needed, is 12px secondary text.
- Fewer than three options, or options people should compare side by side, belong in a radio group or a segmented control, not a menu.