DockPro
A floating tool dock with a gliding label, a springy selection, and trays that grow out of it.
Live · keyboard ready


- 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.
The full library index for assistants is at /llms.txt.