DockPro

A floating tool dock with a gliding label, a springy selection, and trays that grow out of it.

Live · keyboard ready
Lake Louise under a clear sky
Lake Louise, sunrise
Cliffs above the Pacific at dusk
Ocean Beach, dusk
  • A floating tool or mode switcher, such as the tools of a canvas or whiteboard editor.
  • Toolbars where related tools share one slot and open a tray, like shape variants.
  • Tool sets people may reorder by drag or Alt with the arrow keys.
  • Use segmented-control for two to four inline options.
  • Use action-button for one-off actions that do not stay selected.
  • Use liquid-tab-bar for switching between app sections rather than tools.

Installation

Pro source and install commands unlock with a Pro plan.

example.tsx
import { Dock } from "@/registry/components/dock/dock";import { Hand, MousePointer2, Pencil, Square, Circle } from "lucide-react"; export function CanvasTools() {  const [tool, setTool] = useState("select");  const [items, setItems] = useState([    { id: "select", label: "Select", icon: <MousePointer2 />, shortcut: "V" },    { id: "hand", label: "Hand", icon: <Hand />, shortcut: "H" },    { id: "shapes", label: "Shapes", icon: <Square />, items: [      { id: "rect", label: "Rectangle", icon: <Square />, shortcut: "R" },      { id: "ellipse", label: "Ellipse", icon: <Circle />, shortcut: "O" },    ] },    { id: "pen", label: "Pen", icon: <Pencil />, shortcut: "P" },  ]);  return <Dock items={items} value={tool} onValueChange={setTool} onItemsChange={next => setItems(next)} />;}

Dock

A floating command dock for the tools or modes someone switches between all day. A label glides between items, a selection springs to the chosen one, and groups grow a tray out of the dock surface.

PropTypeDefaultDescription
itemsRequired{ id: string; label: string; icon: ReactNode; shortcut?: string; badge?: number; items?: DockItem[] }[]–Items in order. shortcut is a display-only key hint, badge a rolling count that leaves at 0, and items turns the entry into a group with a tray.
valuestring | nullnullId of the selected item or group member.
onValueChange(id: string) => void–Called when an item or group member is chosen.
onItemsChange(items: DockItem[], change: { type: "move"; id: string; index: number }) => void–Enables drag to reorder and Alt with the arrow keys. Receives the next list and what moved.
labelstring"Tools"Accessible name of the toolbar.
classNamestring–Extra class on the root.
ArrowLeftorArrowRight
Moves focus along the dock, wrapping; in an open tray, moves between members.
HomeorEnd
Focuses the first or last item.
EnterorSpace
Chooses an item. On a group, selects the member it shows and opens or closes its tray. In a tray, chooses the member, closes the tray, and returns focus to the group.
ArrowUp
On a group, opens its tray and focuses the chosen member.
ArrowDown
In a tray, closes it and returns focus to the group.
Tab
In a tray, closes it and moves on.
Alt+ArrowLeftorArrowRight
Moves the focused item when onItemsChange is set.
Escape
Closes the open tray and returns focus to its group.
  • Items sit in a horizontal toolbar with a roving tabindex; plain items use aria-pressed for selection.
  • Groups use aria-haspopup, aria-expanded, and aria-controls pointing at the tray, which is a labelled group that stays inert while closed.
  • Accessible names include the shortcut hint and badge count, such as "Pen, P". A group reads as its label and shown member, such as "Shapes: Ellipse, O", plus "selected" when it holds the value.
  • The floating label is aria-hidden. It shows on mouse hover and on keyboard focus, not on touch.
  • A pointer down outside the dock closes an open tray.
  • The label glides between items after a short first hover delay and stays warm so the next one follows at once; the selection springs between items with a shared layoutId.
  • Opening a group grows a tab of the same material out of the dock with members staggering in; dragged items lift and neighbours reflow on a layout spring.
  • Reduced motion makes the label, tray, and selection jump and keeps short fades.
  • The dock sizes to its items at a fixed 44px slot and caps at max-width 100%; it does not shrink items, so keep the count small on phones.
  • The tray and label rise above the dock on purpose, so leave room over it in the layout.
  • Labels only appear for mouse hover and keyboard focus; touch shows no label, so pick icons that read on their own.
  • Item slots use touch-action pan-y, so a vertical swipe over the dock still scrolls the page while sideways drags reorder when onItemsChange is set.
  • Selection is one shared layoutId element and drag uses Reorder, so only the moved items reflow.
  • A single ResizeObserver measures the bar. The tray mounts when a group first opens and then stays mounted, inert, for the last opened group.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Choose it for a floating tool or mode switcher, such as the tools of a canvas editor. Use segmented-control for two to four inline options and action-button for one-off toolbar actions.
  • Control value and handle shortcut keys on the page; the dock only displays them. Use items on an entry to group related tools under one slot.
  • Pass onItemsChange only if people may reorder the dock.
/components/dock/markdown

The full library index for assistants is at /llms.txt.