Skip to contents

Toolbar

A container for grouping a set of buttons and controls.

import type { JSX } from '@solidjs/web';
import { Toolbar } from 'base-ui-solid/toolbar';
import { ToggleGroup } from 'base-ui-solid/toggle-group';
import { Toggle } from 'base-ui-solid/toggle';
import { Select } from 'base-ui-solid/select';
import styles from './index.module.css';

export default function ExampleToolbar() {
  return (
    <Toolbar.Root class={styles.Toolbar}>
      <ToggleGroup class={styles.Group} aria-label="Alignment">
        <Toolbar.Button
          render={(props) => <Toggle {...props} style={props.style || undefined} />}
          aria-label="Align left"
          value="align-left"
          class={styles.Button}
        >
          Align Left
        </Toolbar.Button>
        <Toolbar.Button
          render={(props) => <Toggle {...props} style={props.style || undefined} />}
          aria-label="Align right"
          value="align-right"
          class={styles.Button}
        >
          Align Right
        </Toolbar.Button>
      </ToggleGroup>
      <Toolbar.Separator class={styles.Separator} />
      <Toolbar.Group class={styles.Group} aria-label="Numerical format">
        <Toolbar.Button class={styles.Button} aria-label="Format as currency">
          $
        </Toolbar.Button>
        <Toolbar.Button class={styles.Button} aria-label="Format as percent">
          %
        </Toolbar.Button>
      </Toolbar.Group>
      <Toolbar.Separator class={styles.Separator} />
      <Select.Root defaultValue="Helvetica">
        <Toolbar.Button
          render={(props) => <Select.Trigger {...props} style={props.style || undefined} />}
          class={styles.Button}
        >
          <Select.Value />
          <Select.Icon>
            <CaretUpDownIcon />
          </Select.Icon>
        </Toolbar.Button>
        <Select.Portal>
          <Select.Positioner class={styles.Positioner} sideOffset={4} alignItemWithTrigger={false}>
            <Select.Popup class={styles.Popup}>
              <Select.Item class={styles.Item} value="Helvetica">
                <Select.ItemIndicator class={styles.ItemIndicator}>
                  <CheckIcon />
                </Select.ItemIndicator>
                <Select.ItemText class={styles.ItemText}>Helvetica</Select.ItemText>
              </Select.Item>
              <Select.Item class={styles.Item} value="Arial">
                <Select.ItemIndicator class={styles.ItemIndicator}>
                  <CheckIcon />
                </Select.ItemIndicator>
                <Select.ItemText class={styles.ItemText}>Arial</Select.ItemText>
              </Select.Item>
            </Select.Popup>
          </Select.Positioner>
        </Select.Portal>
      </Select.Root>
      <Toolbar.Separator class={styles.Separator} />
      <Toolbar.Link class={styles.Link} href="#">
        Edited 51m ago
      </Toolbar.Link>
    </Toolbar.Root>
  );
}

function CaretUpDownIcon(
  props: Omit<JSX.IntrinsicElements['svg'], 'style'> & { style?: JSX.CSSProperties },
) {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="currentColor"
      {...props}
      style={{ display: 'block', ...props.style }}
    >
      <path d="M11 10H5l3 3.5zm0-4H5l3-3.5z" />
    </svg>
  );
}

function CheckIcon(
  props: Omit<JSX.IntrinsicElements['svg'], 'style'> & { style?: JSX.CSSProperties },
) {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      {...props}
      style={{ display: 'block', ...props.style }}
    >
      <path d="m2.5 8.5 4 4 7-9" />
    </svg>
  );
}

Usage guidelines

To ensure that toolbars are accessible and helpful, follow these guidelines:

  • Use inputs sparingly: Left and right arrow keys are used to both move the text insertion cursor in an input, and to navigate among controls in horizontal toolbars. When using an input in a horizontal toolbar, use only one and place it as the last element of the toolbar.

Anatomy

Import the component and assemble its parts:

Anatomy
import { Toolbar } from 'base-ui-solid/toolbar';

<Toolbar.Root>
  <Toolbar.Button />
  <Toolbar.Link />
  <Toolbar.Separator />
  <Toolbar.Group>
    <Toolbar.Button />
    <Toolbar.Button />
  </Toolbar.Group>
  <Toolbar.Input />
</Toolbar.Root>;

Examples

Using with Menu

All Base UI popup components that provide a Trigger component can be integrated with a toolbar by passing the trigger to <Toolbar.Button> with the render prop:

Using popups with toolbar
return (
  <Toolbar.Root>
    <Menu.Root>
      <Toolbar.Button render={(props) => <Menu.Trigger {...props} />}  />
      <Menu.Portal>
        {/* prettier-ignore */}
        {/* Compose the rest of the menu */}
      </Menu.Portal>
    </Menu.Root>
  </Toolbar.Root>;
)

This applies to <AlertDialog>, <Dialog>, <Menu>, <Popover>, and <Select>.

Using with Tooltip

Unlike other popups, the toolbar item should be passed to the render prop of <Tooltip.Trigger>:

Using popups with toolbar
return (
  <Toolbar.Root>
    <Tooltip.Root>
      <Tooltip.Trigger render={(props) => <Toolbar.Button {...props} />}  />
      <Tooltip.Portal>
        {/* prettier-ignore */}
        {/* Compose the rest of the tooltip */}
      </Tooltip.Portal>
    </Tooltip.Root>
  </Toolbar.Root>;
)

Using with NumberField

To use a NumberField in the toolbar, pass <NumberField.Input> to <Toolbar.Input> using the render prop:

Using NumberField with toolbar
return (
  <Toolbar.Root>
    <NumberField.Root>
      <NumberField.Group>
        <NumberField.Decrement />
        <Toolbar.Input render={(props) => <NumberField.Input {...props} />}  />
        <NumberField.Increment />
      </NumberField.Group>
    </NumberField.Root>
  </Toolbar.Root>;
)

API reference

Root

A container for grouping a set of controls, such as buttons, toggle groups, or menus. Renders a <div> element.

Prop
Type
Default
loopFocusbooleantrue
If true, using keyboard navigation will wrap focus to the other end of the toolbar once the end is reached.boolean
disabledboolean—
-boolean
orientationToolbar.Root.Orientation'horizontal'
The orientation of the toolbar.Toolbar.Root.Orientation
classfunction—
CSS class applied to the element, or a function that returns a class based on the component’s state.JSX.ClassValue | ((state) => JSX.ClassValue)
stylefunction—
Style applied to the element, or a function that returns a style object based on the component’s state.JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)
renderfunction—
Replace the default element with a tag name, component, or render function.keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)

Data attributes

Name
Type
Default
data-orientationUnion—
Indicates the orientation of the toolbar.'horizontal' | 'vertical'
data-disabled-—
Present when the toolbar is disabled.-
Attribute
Description
data-orientation
Indicates the orientation of the toolbar.
data-disabled
Present when the toolbar is disabled.
Root.State
type ToolbarRootState = {
  /** Whether the component is disabled. */
  disabled: boolean;
  /** The component orientation. */
  orientation: Toolbar.Root.Orientation;
};
Root.Orientation
type ToolbarRootOrientation = 'horizontal' | 'vertical';
Root.ItemMetadata
type ToolbarRootItemMetadata = { disabled: boolean; focusableWhenDisabled: boolean };

Button

A button that can be used as-is or as a trigger for other components. Renders a <button> element.

Prop
Type
Default
focusableWhenDisabledbooleantrue
When true the item remains focusable when disabled.boolean
nativeButtonbooleantrue
Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).boolean
disabledbooleanfalse
When true the item is disabled.boolean
classfunction—
CSS class applied to the element, or a function that returns a class based on the component’s state.JSX.ClassValue | ((state) => JSX.ClassValue)
stylefunction—
Style applied to the element, or a function that returns a style object based on the component’s state.JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)
renderfunction—
Replace the default element with a tag name, component, or render function.keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)

Data attributes

Name
Type
Default
data-orientationUnion—
Indicates the orientation of the toolbar.'horizontal' | 'vertical'
data-disabled-—
Present when the button is disabled.-
data-focusable-—
Present when the button remains focusable when disabled.-
Attribute
Description
data-orientation
Indicates the orientation of the toolbar.
data-disabled
Present when the button is disabled.
data-focusable
Present when the button remains focusable when disabled.
Button.State
type ToolbarButtonState = {
  /** Whether the component is disabled. */
  disabled: boolean;
  /** Whether the component remains focusable when disabled. */
  focusable: boolean;
  /** The component orientation. */
  orientation: Toolbar.Root.Orientation;
};

A link component. Renders an <a> element.

Prop
Type
Default
classfunction—
CSS class applied to the element, or a function that returns a class based on the component’s state.JSX.ClassValue | ((state) => JSX.ClassValue)
stylefunction—
Style applied to the element, or a function that returns a style object based on the component’s state.JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)
renderfunction—
Replace the default element with a tag name, component, or render function.keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)

Data attributes

Name
Type
Default
data-orientationUnion—
Indicates the orientation of the toolbar.'horizontal' | 'vertical'
Attribute
Description
data-orientation
Indicates the orientation of the toolbar.
Link.State
type ToolbarLinkState = {
  /** The component orientation. */
  orientation: Toolbar.Root.Orientation;
};

Input

A native input element that integrates with Toolbar keyboard navigation. Renders an <input> element.

Prop
Type
Default
defaultValueUnion—
-string | number | string[]
focusableWhenDisabledbooleantrue
When true the item remains focusable when disabled.boolean
disabledbooleanfalse
When true the item is disabled.boolean
classfunction—
CSS class applied to the element, or a function that returns a class based on the component’s state.JSX.ClassValue | ((state) => JSX.ClassValue)
stylefunction—
Style applied to the element, or a function that returns a style object based on the component’s state.JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)
renderfunction—
Replace the default element with a tag name, component, or render function.keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)

Data attributes

Name
Type
Default
data-orientationUnion—
Indicates the orientation of the toolbar.'horizontal' | 'vertical'
data-disabled-—
Present when the input is disabled.-
data-focusable-—
Present when the input remains focusable when disabled.-
Attribute
Description
data-orientation
Indicates the orientation of the toolbar.
data-disabled
Present when the input is disabled.
data-focusable
Present when the input remains focusable when disabled.
Input.State
type ToolbarInputState = {
  /** Whether the component is disabled. */
  disabled: boolean;
  /** Whether the component remains focusable when disabled. */
  focusable: boolean;
  /** The component orientation. */
  orientation: Toolbar.Root.Orientation;
};

Group

Groups several toolbar items or toggles. Renders a <div> element.

Prop
Type
Default
disabledbooleanfalse
When true all toolbar items in the group are disabled.boolean
classfunction—
CSS class applied to the element, or a function that returns a class based on the component’s state.JSX.ClassValue | ((state) => JSX.ClassValue)
stylefunction—
Style applied to the element, or a function that returns a style object based on the component’s state.JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)
renderfunction—
Replace the default element with a tag name, component, or render function.keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)

Data attributes

Name
Type
Default
data-orientationUnion—
Indicates the orientation of the toolbar.'horizontal' | 'vertical'
data-disabled-—
Present when the group is disabled.-
Attribute
Description
data-orientation
Indicates the orientation of the toolbar.
data-disabled
Present when the group is disabled.
Group.State
type ToolbarGroupState = {
  /** Whether the component is disabled. */
  disabled: boolean;
  /** The component orientation. */
  orientation: Toolbar.Root.Orientation;
};

Separator

A separator element accessible to screen readers. Renders a <div> element.

Prop
Type
Default
orientationOrientation—
The orientation of the separator. Defaults to the opposite of the toolbar’s orientation, so a horizontal toolbar renders vertical separators.Orientation
classfunction—
CSS class applied to the element, or a function that returns a class based on the component’s state.JSX.ClassValue | ((state) => JSX.ClassValue)
stylefunction—
Style applied to the element, or a function that returns a style object based on the component’s state.JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)
renderfunction—
Replace the default element with a tag name, component, or render function.keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)

Data attributes

Name
Type
Default
data-orientationUnion—
Indicates the orientation of the separator, which is perpendicular to the toolbar.'horizontal' | 'vertical'
Attribute
Description
data-orientation
Indicates the orientation of the separator, which is perpendicular to the toolbar.
Separator.State
type ToolbarSeparatorState = {
  /** The orientation of the separator. */
  orientation: Orientation;
};