Toolbar
Groups related controls in one tab stop, with arrow keys to move focus.
toolbar-basic-demo.tsx
"use client";import { ToggleButton } from "@/components/vip-ui/toggle-button";import { ToggleButtonGroup } from "@/components/vip-ui/toggle-button-group";import { Toolbar } from "@/components/vip-ui/toolbar";export function ToolbarBasicDemo() { return ( <Toolbar aria-label="Text alignment"> <ToggleButtonGroup aria-label="Alignment" selectionMode="single" defaultSelectedKeys={["left"]} disallowEmptySelection > <ToggleButton id="left" variant="segmented"> Left </ToggleButton> <ToggleButton id="center" variant="segmented"> Center </ToggleButton> <ToggleButton id="right" variant="segmented"> Right </ToggleButton> </ToggleButtonGroup> </Toolbar> );}Show more
Installation
CLI
Manual
The CLI adds the files, packages, theme variables, and Tailwind plugin that this component uses. Before you run it, set up your project.
npm
yarn
pnpm
bun
pnpm dlx shadcn@latest add https://vip-ui.dev/r/vip-toolbar.jsonFormatting toolbar
Make something worth reading.
toolbar-demo.tsx
"use client";import { TextBIcon, TextItalicIcon, TextUnderlineIcon,} from "@phosphor-icons/react";import { useState } from "react";import { Button } from "@/components/vip-ui/button";import { Separator } from "@/components/vip-ui/separator";import { ToggleButton } from "@/components/vip-ui/toggle-button";import { ToggleButtonGroup } from "@/components/vip-ui/toggle-button-group";import { Toolbar } from "@/components/vip-ui/toolbar";export function ToolbarDemo() { const [styles, setStyles] = useState(new Set(["bold"])); return ( <div className="grid w-full max-w-sm justify-items-start gap-3"> <Toolbar size="sm" aria-label="Text formatting"> <ToggleButtonGroup aria-label="Text style" selectionMode="multiple" selectedKeys={styles} onSelectionChange={(keys) => setStyles(new Set([...keys].map(String))) } > <ToggleButton id="bold" variant="segmented" iconOnly aria-label="Bold" > <TextBIcon aria-hidden="true" /> </ToggleButton> <ToggleButton id="italic" variant="segmented" iconOnly aria-label="Italic" > <TextItalicIcon aria-hidden="true" /> </ToggleButton> <ToggleButton id="underline" variant="segmented" iconOnly aria-label="Underline" > <TextUnderlineIcon aria-hidden="true" /> </ToggleButton> </ToggleButtonGroup> <Separator orientation="vertical" className="h-6 self-center" /> <Button variant="ghost" isDisabled={styles.size === 0} onPress={() => setStyles(new Set())} > Clear </Button> </Toolbar> <p className="w-full rounded-lg border border-border/70 bg-card px-4 py-3 text-sm leading-6 shadow-[var(--shadow-card)]" style={{ fontWeight: styles.has("bold") ? 700 : 400, fontStyle: styles.has("italic") ? "italic" : "normal", textDecoration: styles.has("underline") ? "underline" : "none", }} > Make something worth reading. </p> </div> );}Show more
Vertical toolbar
The up and down arrow keys move focus.
toolbar-vertical-demo.tsx
"use client";import { ToggleButton } from "@/components/vip-ui/toggle-button";import { ToggleButtonGroup } from "@/components/vip-ui/toggle-button-group";import { Toolbar } from "@/components/vip-ui/toolbar";export function ToolbarVerticalDemo() { return ( <Toolbar orientation="vertical" aria-label="Block type"> <ToggleButtonGroup aria-label="Block" selectionMode="single" defaultSelectedKeys={["body"]} disallowEmptySelection > <ToggleButton id="body" variant="segmented"> Body </ToggleButton> <ToggleButton id="heading" variant="segmented"> Heading </ToggleButton> <ToggleButton id="quote" variant="segmented"> Quote </ToggleButton> </ToggleButtonGroup> </Toolbar> );}Show more
Sizes
Popovers that open from the toolbar keep the default size.
toolbar-sizes-demo.tsx
"use client";import { ArrowClockwiseIcon, ArrowCounterClockwiseIcon, LinkSimpleIcon, TextBIcon, TextItalicIcon,} from "@phosphor-icons/react";import { Button } from "@/components/vip-ui/button";import { Separator } from "@/components/vip-ui/separator";import type { Size } from "@/components/vip-ui/size";import { ToggleButton } from "@/components/vip-ui/toggle-button";import { ToggleButtonGroup } from "@/components/vip-ui/toggle-button-group";import { Toolbar } from "@/components/vip-ui/toolbar";export function ToolbarSizesDemo() { return ( <div className="flex flex-col items-start gap-3"> <CommentToolbar size="xs" /> <CommentToolbar size="sm" /> <CommentToolbar size="md" /> </div> );}function CommentToolbar({ size }: { size: Size }) { return ( <Toolbar size={size} aria-label="Comment editor"> <Button variant="ghost" iconOnly aria-label="Undo"> <ArrowCounterClockwiseIcon aria-hidden="true" /> </Button> <Button variant="ghost" iconOnly aria-label="Redo"> <ArrowClockwiseIcon aria-hidden="true" /> </Button> <Separator orientation="vertical" className="h-5 self-center" /> <ToggleButtonGroup aria-label="Text style" selectionMode="multiple"> <ToggleButton id="bold" variant="segmented" iconOnly aria-label="Bold"> <TextBIcon aria-hidden="true" /> </ToggleButton> <ToggleButton id="italic" variant="segmented" iconOnly aria-label="Italic" > <TextItalicIcon aria-hidden="true" /> </ToggleButton> </ToggleButtonGroup> <Separator orientation="vertical" className="h-5 self-center" /> <Button variant="ghost"> <LinkSimpleIcon aria-hidden="true" /> Link </Button> </Toolbar> );}Show more
API reference
vip/ui adds or changes the props below. For all other props, see React Aria Toolbar (opens in a new tab).
- size: "xs" | "sm" | "md" | "lg" | "xl"
- Sets the size of each button, toggle, and toggle group in the toolbar. Popovers and dialogs that open from the toolbar keep the default size.