A row of icon buttons that grow toward the pointer, like an app launcher. Every item is a real button or link with a visible label (a tooltip) that is also its accessible name. Magnification is off on touch and for reduced motion.
Optional, and kept apart.
Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.
import { CalendarIcon, ChartIcon, Dock, DockItem, HomeIcon, InboxIcon, SearchIcon, SettingsIcon } from "@rdloom/react";
// Move the pointer along the dock: the icons grow toward it and their neighbours move aside.
export default function DockBasicExample() {
return (
<div className="flex w-full justify-center py-12">
<Dock label="Applications">
<DockItem label="Home"><HomeIcon className="size-5" /></DockItem>
<DockItem label="Search"><SearchIcon className="size-5" /></DockItem>
<DockItem label="Inbox"><InboxIcon className="size-5" /></DockItem>
<DockItem label="Calendar"><CalendarIcon className="size-5" /></DockItem>
<DockItem label="Reports"><ChartIcon className="size-5" /></DockItem>
<DockItem label="Settings"><SettingsIcon className="size-5" /></DockItem>
</Dock>
</div>
);
}Installation
npx rdloom add dockCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.
It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/dock.jsonWorks, but without upgrade tracking, and you import the motion CSS yourself.
Usage
import { CalendarIcon, ChartIcon, Dock, DockItem, HomeIcon, InboxIcon, SearchIcon, SettingsIcon } from "@rdloom/react";
<div className="flex w-full justify-center py-12">
<Dock label="Applications">
<DockItem label="Home"><HomeIcon className="size-5" /></DockItem>
<DockItem label="Search"><SearchIcon className="size-5" /></DockItem>
<DockItem label="Inbox"><InboxIcon className="size-5" /></DockItem>
<DockItem label="Calendar"><CalendarIcon className="size-5" /></DockItem>
<DockItem label="Reports"><ChartIcon className="size-5" /></DockItem>
<DockItem label="Settings"><SettingsIcon className="size-5" /></DockItem>
</Dock>
</div>Vertical
import { CalendarIcon, ChartIcon, Dock, DockItem, UsersIcon } from "@rdloom/react";
export default function DockVerticalExample() {
return (
<div className="flex w-full justify-center py-4">
<Dock label="Workspace tools" orientation="vertical">
<DockItem label="Calendar"><CalendarIcon className="size-5" /></DockItem>
<DockItem label="Reports"><ChartIcon className="size-5" /></DockItem>
<DockItem label="Team"><UsersIcon className="size-5" /></DockItem>
</Dock>
</div>
);
}Links
import { Dock, DockItem, FileIcon, GlobeIcon, HomeIcon } from "@rdloom/react";
export default function DockLinksExample() {
return (
<div className="flex w-full justify-center py-6">
<Dock label="Quick links" magnification={1.4}>
<DockItem label="Home page" href="#home"><HomeIcon className="size-5" /></DockItem>
<DockItem label="Documents" href="#documents"><FileIcon className="size-5" /></DockItem>
<DockItem label="Website" href="#website"><GlobeIcon className="size-5" /></DockItem>
</Dock>
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
childrenrequiredDockItem elements. | node | none |
labelrequiredAccessible name of the toolbar, for example Applications. | string | none |
orientationLayout direction and which arrow keys move focus. | "horizontal" | "vertical" | "horizontal" |
magnificationScale of the item directly under the pointer. 1 turns magnification off. | number | 1.6 |
distancePixels from the pointer within which items grow. | number | 120 |
isPausedTurns magnification off. Items still enlarge slightly on focus. | boolean | false |
Accessibility
Role toolbar, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
- Tab moves into the dock on one item and out again (roving focus)
- Left and Right arrows (Up and Down when vertical) move between items, swapped in right-to-left layouts
- Home and End jump to the first and last item
- Enter or Space activates the focused item
Screen readers announce
- Announced as a toolbar with its label; each item as a button or link with its label
What your code must do
- Each item is a real button (or a link when it has an href) named by its label
- The label also shows as a tooltip on hover and keyboard focus
- Focus enlarges the focused item too, so keyboard users get the same feedback
- Magnification does not run on touch, for prefers-reduced-motion, in a .rdm-still container or when isPaused is set
- Scaling is visual only: layout does not shift and hit areas stay at least 24px
- Forced colors: items keep a visible border and focus ring
Guidelines
Use it when
- A small set of app-level shortcuts or tools
Avoid it when
- Primary site navigation: use NavigationMenu
- More than about ten items
Don't
- Icon items without a label
- Hiding essential actions only in the dock
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-surface-raised--rd-color-border-default--rd-color-text-default--rd-color-focus-ring--rd-radius-overlay--rd-radius-control--rd-elevation-raised