FloatingDock
A fixed top-center navigation dock with tooltips, logo slot, dividers, and keyboard-accessible actions.
Installation
npx vayu-ui-cli@latest add floating-dockUsage
The dock is fixed to the top of the viewport. Hover or focus any item to see its tooltip.
Anatomy
import { FloatingDock } from 'vayu-ui';
<FloatingDock aria-label="Navigation">
<FloatingDock.Container>
<FloatingDock.Logo href="/">Logo</FloatingDock.Logo>
<FloatingDock.Divider />
<FloatingDock.Item icon={Home} label="Home" href="/" />
<FloatingDock.Item icon={Settings} label="Settings" onClick={() => {}} />
</FloatingDock.Container>
</FloatingDock>;- FloatingDock — Root
<nav>element. Fixed to the top-center of the viewport. Provides the accessible navigation landmark. - FloatingDock.Container — Glassmorphism wrapper. Injects the
linkComponentinto children viacloneElement. Handles backdrop blur, border, and shadow styling. - FloatingDock.Logo — Brand logo slot. Renders as a link when
hrefis provided, otherwise as a plain<div>. - FloatingDock.Item — Interactive navigation item. Renders as a
<button>or a link element. Wrapped in aTooltipthat shows on hover/focus. - FloatingDock.Divider — Reuses the
Dividercomponent with vertical orientation. Separates logical groups of items.
Accessibility
- Keyboard Support:
Tab— Move focus to the next interactive item.Shift+Tab— Move focus to the previous interactive item.Enter/Space— Activate the focused item.
- ARIA Attributes:
aria-labelon the root<nav>provides an accessible name for the navigation landmark.aria-labelon eachFloatingDock.Itemdescribes the item's purpose.aria-hidden="true"on decorative icons to prevent screen reader announcements.role="separator"onFloatingDock.Dividermarks it as a visual separator.role="tooltip"on the tooltip element witharia-describedbylinking the item to its tooltip.
- Focus Behavior:
- Focus ring appears on
focus-visibleusingring-focuswith an offset. - Hover animations (
scale,translate) respectprefers-reduced-motionviamotion-safe:.
- Focus ring appears on
Screen reader behavior
When a screen reader user tabs into the floating dock, they hear the navigation landmark announced (e.g., "Main navigation navigation landmark"). As they tab through items, each item is announced by its aria-label (e.g., "Search link" or "Settings button"). The decorative icons are hidden from the assistive technology tree via aria-hidden="true". When hovering or focusing an item, the tooltip text is announced via aria-describedby. Dividers are announced as separators, providing logical grouping cues between dock sections.
Component Folder Structure
FloatingDock/
├── FloatingDock.tsx # Root nav wrapper with fixed positioning
├── FloatingDockContainer.tsx # Glassmorphism layout with cloneElement injection
├── FloatingDockItem.tsx # Interactive navigation item with tooltip
├── FloatingDockLogo.tsx # Brand logo item
├── types.ts # TypeScript type definitions
├── index.ts # Re-exports compound component and types
└── README.md # Component usage referenceProps
FloatingDock (Root)
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Typically FloatingDock.Container. Required. |
aria-label | string | "Floating dock" | Accessible name for the navigation landmark. |
className | string | — | Additional CSS classes. |
FloatingDock.Container
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | FloatingDock.Item, FloatingDock.Logo, and FloatingDock.Divider components. Required. |
linkComponent | ElementType | Link | Custom link component for routing (defaults to Next.js Link). |
className | string | — | Additional CSS classes. |
FloatingDock.Item
| Prop | Type | Default | Description |
|---|---|---|---|
icon | ComponentType | — | Icon component (e.g., Lucide icon). |
label | string | — | Tooltip text and aria-label for the item. Required. |
href | string | — | URL to navigate to — renders as a link. |
onClick | () => void | — | Click handler — renders as a button when href is absent. |
className | string | — | Additional CSS classes. |
FloatingDock.Logo
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Logo content (text or image). Required. |
href | string | — | URL for the logo link. |
className | string | — | Additional CSS classes. |
FloatingDock.Divider
Reuses the Divider component. Relevant props:
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" | Divider direction. |
spacing | DividerSpacing | — | Spacing variant. |
decorative | boolean | false | Whether the divider is purely decorative. |
className | string | — | Additional CSS classes. |