Toolbar
A semantic, flexible command bar for related actions.
Toolbar is a semantic command surface for actions that belong together: document controls, editor tools, filters, view switches, or panel commands. It provides structure around existing Mosmox UI buttons without taking ownership of the business logic.
The component is exported with compound subcomponents: Toolbar.Item, Toolbar.Menu, Toolbar.Group, Toolbar.Separator, and Toolbar.Spacer. Toolbar actions are command buttons, not selectable navigation tabs: clicking an item invokes its handler but does not leave it selected.
Installation
import { Toolbar, ConfigProvider } from '@mosmox/ui';Basic usage
<Toolbar aria-label="Document toolbar">
<Toolbar.Group aria-label="File commands">
<Toolbar.Item onClick={createDocument}>New</Toolbar.Item>
<Toolbar.Item onClick={saveDocument}>Save</Toolbar.Item>
</Toolbar.Group>
<Toolbar.Separator />
<Toolbar.Group aria-label="Editing commands">
<Toolbar.Item onClick={undo}>Undo</Toolbar.Item>
<Toolbar.Item onClick={redo}>Redo</Toolbar.Item>
</Toolbar.Group>
<Toolbar.Spacer />
<Toolbar.Item onClick={openSettings}>Settings</Toolbar.Item>
</Toolbar>Toolbar.Item supports the ButtonProps API, including icons, loading state, keyboard shortcuts, and standard button events. It is a command button rather than a link. Toolbar.Group gives related commands their own accessible group, Toolbar.Separator communicates a boundary, and Toolbar.Spacer pushes trailing actions to the opposite edge.
Toolbar itself renders role="toolbar". It can be horizontal or vertical, compact or comfortable, fixed/sticky, full-width, wrapped, disabled as a whole, or displayed as a multi-column/multi-row grid.
Tooltips on toolbar actions
Add tooltip to any Toolbar.Item or Toolbar.Menu to reuse the standard dark Tooltip on hover and keyboard focus. The optional placement, size, and color can be customized without changing the action itself:
<Toolbar variant="primary" aria-label="Quick actions">
<Toolbar.Item iconLeft={<Plus />} tooltip="Create a new item">
Create
</Toolbar.Item>
<Toolbar.Item
aria-label="Search"
iconLeft={<Search />}
iconOnly
tooltip="Search"
tooltipPlacement="bottom"
tooltipSize="sm"
>
Search
</Toolbar.Item>
</Toolbar>The tooltip is shown for both pointer hover and focus, so icon-only actions should still provide an accessible aria-label.
Variants and layout modes
The available variants are surface, bordered, floating, plain, primary, secondary, light, outline, dashed, text, link, danger, and success. The color variants use the same palette as Button. Use orientation="vertical" for a tool rail or command stack, fullWidth to fill its container, and wrap when actions may move onto multiple lines.
Color variants style the Toolbar surface. For example, primary creates a primary-color bar while its commands remain transparent actions inside the bar:
<Toolbar variant="primary" iconOnly aria-label="Primary actions">
<Toolbar.Item aria-label="Create" iconLeft={<Plus />} />
<Toolbar.Item aria-label="Settings" iconLeft={<Settings />} />
<Toolbar.Item aria-label="Search" iconLeft={<Search />} />
</Toolbar>
<Toolbar variant="primary" aria-label="Primary labeled actions">
<Toolbar.Item iconLeft={<Plus />}>Create</Toolbar.Item>
<Toolbar.Item iconLeft={<Settings />}>Settings</Toolbar.Item>
</Toolbar>
<Toolbar variant="secondary" aria-label="Secondary actions">
<Toolbar.Item iconLeft={<Plus />}>Create</Toolbar.Item>
<Toolbar.Item iconLeft={<Settings />}>Settings</Toolbar.Item>
</Toolbar>
<Toolbar variant="light" aria-label="Light actions">
<Toolbar.Item iconLeft={<Plus />}>Create</Toolbar.Item>
<Toolbar.Item iconLeft={<Settings />}>Settings</Toolbar.Item>
</Toolbar><Toolbar variant="bordered" fullWidth wrap aria-label="Editor tools">
<Toolbar.Group aria-label="Formatting">
<Toolbar.Item onClick={toggleBold}>Bold</Toolbar.Item>
<Toolbar.Item onClick={toggleItalic}>Italic</Toolbar.Item>
</Toolbar.Group>
<Toolbar.Spacer />
<Toolbar.Item>Share</Toolbar.Item>
</Toolbar>
<Toolbar orientation="vertical" variant="surface" aria-label="Navigation tools">
<Toolbar.Item onClick={openDashboard}>Dashboard</Toolbar.Item>
<Toolbar.Item>Reports</Toolbar.Item>
<Toolbar.Item>Settings</Toolbar.Item>
</Toolbar>sticky applies sticky positioning to the toolbar so it can remain visible while its content scrolls. The component does not impose a top offset; set one in CSS when it sits below another fixed header.
floating and the floating visual variant are separate concepts: the floating prop changes positioning to fixed, while variant="floating" applies the floating surface styling. They can be used independently or together.
Toolbar menus
Toolbar.Menu is a Toolbar trigger backed by the existing Menu component. It renders a down-arrow trigger and opens the menu below it. Menu entries, selection callbacks, size, variant, width, and max height are passed to Menu.
Menus can also be placed inside a floating, colorized Toolbar:
<Toolbar floating draggable title="Primary menu" initialPosition={{ top: 96, left: 24 }} variant="primary">
<Toolbar.Menu
label="Actions"
entries={[{ key: 'create', label: 'Create', onClick: createItem }]}
/>
</Toolbar><Toolbar aria-label="Document actions" variant="bordered">
<Toolbar.Menu
label="Insert"
menuVariant="default"
entries={[
{ key: 'file', label: 'File', onClick: insertFile },
{ key: 'folder', label: 'Folder', onClick: insertFolder },
]}
onMenuSelect={handleMenuSelect}
/>
<Toolbar.Menu
label="View"
menuSize="sm"
menuVariant="compact"
entries={[
{ key: 'preview', label: 'Preview', onClick: openPreview },
{ key: 'details', label: 'Details', onClick: openDetails },
]}
/>
</Toolbar>Floating and draggable toolbars
Set floating to render the toolbar above the page content with fixed positioning. Add draggable to show a drag handle and let users move it with pointer or touch input. title gives the floating toolbar a named header. initialPosition defines its starting viewport coordinates; both values can be numbers (pixels) or CSS position strings. Dragging starts from the header or empty toolbar area so buttons remain clickable.
Set collapsible to show a chevron that collapses the toolbar to its header. Use defaultCollapsed for an uncontrolled initial state, or collapsed with onCollapsedChange for controlled state.
columns and rows turn the toolbar into a grid. iconOnly passes icon-only behavior to every Toolbar.Item; provide an icon to each item and keep its accessible name with aria-label.
<Toolbar
aria-label="Quick actions"
columns={2}
collapsible
draggable
floating
iconOnly
initialPosition={{ top: 96, left: 24 }}
rows={2}
title="Quick actions"
variant="floating"
>
<Toolbar.Item aria-label="Create" iconLeft={<Plus />}>Create</Toolbar.Item>
<Toolbar.Item aria-label="Save" iconLeft={<Save />}>Save</Toolbar.Item>
<Toolbar.Item aria-label="Settings" iconLeft={<Settings />}>Settings</Toolbar.Item>
<Toolbar.Item aria-label="Close" iconLeft={<X />}>Close</Toolbar.Item>
</Toolbar>When collapsible is enabled, the collapse control is rendered in the floating header. The header is available only for a floating toolbar and is shown when title, draggable, or collapsible is supplied. A controlled toolbar uses collapsed with onCollapsedChange; an uncontrolled toolbar uses defaultCollapsed.
Keyboard and accessibility
The root renders with role="toolbar" and aria-orientation. Give it an accessible name with aria-label; visible labels can be supplied through a Toolbar.Group label in surrounding UI. With rovingFocus enabled (the default), Left/Right arrows move through horizontal actions, Up/Down arrows move through vertical actions, and Home/End jump to the edges. Disabled actions are skipped.
<Toolbar aria-label="Editor tools" rovingFocus>
<Toolbar.Item onClick={toggleBold}>Bold</Toolbar.Item>
<Toolbar.Item>Italic</Toolbar.Item>
<Toolbar.Item>Underline</Toolbar.Item>
</Toolbar>Set rovingFocus={false} when a custom keyboard manager owns focus or when every action should remain in the normal tab order.
State, density, and configuration
Toolbar items are command buttons: clicking an item invokes its handler and does not leave the item selected. Set disabled on the toolbar to disable all items, or disable individual items when only one command is unavailable. density accepts compact and comfortable; size accepts default or sm (small).
<ConfigProvider components={{ toolbar: { variant: 'bordered', density: 'compact', size: 'sm' } }}>
<Toolbar aria-label="Configured toolbar">
<Toolbar.Item>Configured</Toolbar.Item>
<Toolbar.Item onClick={runConfiguredCommand}>Provider defaults</Toolbar.Item>
</Toolbar>
</ConfigProvider>Instance props override the provider defaults. The toolbar uses shared color, border, shadow, and radius tokens and adapts to the active theme.
API reference
Toolbar props
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | horizontal | vertical | horizontal | Direction and arrow-key behavior. |
variant | surface | bordered | floating | plain | primary | secondary | light | outline | dashed | text | link | danger | success | surface | Visual treatment and color palette. Color variants match Button. |
size | sm | default | default | Default or small toolbar density. |
density | compact | comfortable | comfortable | Toolbar spacing and minimum height. |
fullWidth | boolean | false | Fills the available width. |
floating | boolean | false | Uses fixed positioning above page content. |
draggable | boolean | false | Enables pointer/touch dragging for a floating toolbar. Requires floating. |
initialPosition | { top: number | string; left: number | string } | { top: 24, left: 24 } in floating mode | Initial viewport position. |
columns | number | — | Number of equal grid columns. |
rows | number | — | Number of grid rows. |
iconOnly | boolean | false | Makes every toolbar item icon-only while preserving accessible text. |
title | ReactNode | — | Header title shown for a floating toolbar. |
collapsible | boolean | false | Shows a control that collapses the toolbar to its header. |
defaultCollapsed | boolean | false | Initial collapsed state in uncontrolled mode. |
collapsed | boolean | — | Controlled collapsed state. |
onCollapsedChange | (collapsed: boolean) => void | — | Called when the collapse state changes. |
wrap | boolean | false | Allows items to wrap. |
sticky | boolean | false | Uses sticky positioning. |
disabled | boolean | false | Disables all toolbar items. |
rovingFocus | boolean | true | Enables arrow-key focus management. |
aria-label | string | Toolbar | Accessible name. |
children | ReactNode | — | Toolbar groups, items, menus, separators, and spacers. |
className | string | — | Additional class on the root toolbar element. |
style | CSSProperties | — | Inline styles. In floating mode, left and top are managed from initialPosition and dragging. |
Toolbar.Item
Supports the Button props; size can override the inherited toolbar size. Toolbar items do not expose a persistent selected state or aria-pressed; use onClick to execute the command. Native button attributes such as type, name, value, form, aria-*, and keyboard/mouse event handlers are also accepted.
| Button prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Visible label. |
iconLeft, iconRight | ReactNode | — | Leading or trailing icon. |
iconOnly | boolean | inherited from Toolbar | Hides the visible label while preserving the accessible name. |
variant | ButtonVariant | text | Button treatment; the toolbar surface may set foreground colors for dark variants. |
size | 'sm' | 'default' | inherited from Toolbar | Item size override. |
loading | boolean | false | Shows the Button loading state. |
loadingMode | 'inline' | 'replace' | inline | Loading presentation. |
loadingLabel | string | Loading | Accessible loading label. |
progress | number | — | Shows Button progress. |
circle | boolean | false | Circular button styling. |
fullWidth | boolean | false | Fills the available item width. |
disableHover | boolean | false | Disables Button hover styling. |
hoverScale | boolean | true | Controls item hover scaling; the toolbar enables it by default. |
className | string | — | Additional class on the item Button. |
| Tooltip prop | Type | Default | Description |
|---|---|---|---|
tooltip | ReactNode | — | Content displayed in the standard Tooltip on hover or focus. |
tooltipOpenDelay | number | 0 | Delay before opening the tooltip in milliseconds. |
tooltipCloseDelay | number | 80 | Delay before closing the tooltip in milliseconds. |
tooltipPlacement | TooltipPlacement | top | Tooltip position, for example top, bottom, left, or right. |
tooltipSize | sm | default | lg | default | Tooltip size. |
tooltipVariant | dark | light | primary | dark | Tooltip color variant. |
Toolbar.Menu
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Trigger label. A down-arrow is added automatically. |
entries | MenuEntry[] | — | Entries passed to the existing Menu component. |
menuSize | sm | default | lg | default | Menu density. |
menuVariant | default | compact | filled | default | Menu visual style. |
menuWidth | number | string | 240 | Menu width. |
menuMaxHeight | number | string | — | Optional menu max height. |
menuAriaLabel | string | derived from label | Accessible menu name. |
onMenuSelect | (key: string) => void | — | Called when a menu entry is selected; the menu then closes. |
Toolbar.Menu also accepts the standard button and tooltip props supported by Toolbar.Item, including disabled, iconLeft, className, onClick, and tooltip.
The popover is positioned below the trigger. An outside pointer click closes it, and selecting a Menu entry invokes onMenuSelect and closes the popover. Toolbar.Menu controls only the open state of its own menu; the selected value belongs to the supplied Menu entries and application state.
Toolbar.Group
| Prop | Type | Description |
|---|---|---|
children | ReactNode | Related toolbar items. |
aria-label | string | Accessible name for the group. |
className | string | Custom class name. |
Toolbar.Separator
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | horizontal | Direction of the decorative separator. It is not interactive or focusable. |
className | string | — | Additional class on the separator. |
Toolbar.Spacer
Toolbar.Spacer has no props. It is a decorative flex spacer that pushes following actions to the opposite edge in a horizontal toolbar. In a vertical toolbar it creates flexible vertical space.
ToolbarTooltipProps
These props are available on Toolbar.Item and Toolbar.Menu:
| Prop | Type | Default | Description |
|---|---|---|---|
tooltip | ReactNode | — | Content displayed by the standard Tooltip on hover and focus. |
tooltipOpenDelay | number | 0 | Opening delay in milliseconds. |
tooltipCloseDelay | number | 80 | Closing delay in milliseconds. |
tooltipPlacement | TooltipPlacement | top | top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, or left-end. |
tooltipSize | 'sm' | 'default' | 'lg' | default | Tooltip size. |
tooltipVariant | 'dark' | 'light' | 'primary' | dark | Tooltip color variant. |
ConfigProvider API
Toolbar defaults can be configured globally. Instance props override these values:
| Config prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | horizontal | Default layout direction. |
variant | ToolbarVariant | surface | Default surface and color treatment. |
size | 'sm' | 'default' | default | Default toolbar and item size. |
density | 'compact' | 'comfortable' | comfortable | Default toolbar spacing and minimum height. |
<ConfigProvider components={{
toolbar: {
orientation: 'vertical',
variant: 'light',
size: 'sm',
density: 'compact',
},
}}>
<Toolbar aria-label="Tool rail">
<Toolbar.Item aria-label="Search" iconLeft={<Search />} iconOnly />
<Toolbar.Item aria-label="Settings" iconLeft={<Settings />} iconOnly />
</Toolbar>
</ConfigProvider>All toolbar colors, borders, radius values, shadows, focus states, and typography use the active ConfigProvider theme tokens.