VayuUI

FloatingDock

A fixed top-center navigation dock with tooltips, logo slot, dividers, and keyboard-accessible actions.

Installation

npx vayu-ui init #one time only
npx vayu-ui add floatingdock
npx vayu-ui add -t floatingdock #with test case needs

Usage

The dock is fixed to the top of the viewport. Hover or focus any item to see its tooltip.

<FloatingDock aria-label="Main navigation">
  <FloatingDock.Container>
    <FloatingDock.Logo href="/">App</FloatingDock.Logo>
    <FloatingDock.Divider />
    <FloatingDock.Item icon={Home} label="Home" href="/" />
    <FloatingDock.Item icon={Search} label="Search" onClick={() => handleClick('Search')} />
    <FloatingDock.Item icon={Mail} label="Messages" onClick={() => handleClick('Messages')} />
    <FloatingDock.Item
      icon={Bell}
      label="Notifications"
      onClick={() => handleClick('Notifications')}
    />
    <FloatingDock.Divider />
    <FloatingDock.Item icon={User} label="Profile" onClick={() => handleClick('Profile')} />
    <FloatingDock.Item
      icon={Settings}
      label="Settings"
      onClick={() => handleClick('Settings')}
    />
  </FloatingDock.Container>
</FloatingDock>

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 linkComponent into children via cloneElement. Handles backdrop blur, border, and shadow styling.
  • FloatingDock.Logo — Brand logo slot. Renders as a link when href is provided, otherwise as a plain <div>.
  • FloatingDock.Item — Interactive navigation item. Renders as a <button> or a link element. Wrapped in a Tooltip that shows on hover/focus.
  • FloatingDock.Divider — Reuses the Divider component 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-label on the root <nav> provides an accessible name for the navigation landmark.
    • aria-label on each FloatingDock.Item describes the item's purpose.
    • aria-hidden="true" on decorative icons to prevent screen reader announcements.
    • role="separator" on FloatingDock.Divider marks it as a visual separator.
    • role="tooltip" on the tooltip element with aria-describedby linking the item to its tooltip.
  • Focus Behavior:
    • Focus ring appears on focus-visible using ring-focus with an offset.
    • Hover animations (scale, translate) respect prefers-reduced-motion via motion-safe:.

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 reference

Props

FloatingDock (Root)

PropTypeDefaultDescription
childrenReactNodeTypically FloatingDock.Container. Required.
aria-labelstring"Floating dock"Accessible name for the navigation landmark.
classNamestringAdditional CSS classes.

FloatingDock.Container

PropTypeDefaultDescription
childrenReactNodeFloatingDock.Item, FloatingDock.Logo, and FloatingDock.Divider components. Required.
linkComponentElementTypeLinkCustom link component for routing (defaults to Next.js Link).
classNamestringAdditional CSS classes.

FloatingDock.Item

PropTypeDefaultDescription
iconComponentTypeIcon component (e.g., Lucide icon).
labelstringTooltip text and aria-label for the item. Required.
hrefstringURL to navigate to — renders as a link.
onClick() => voidClick handler — renders as a button when href is absent.
classNamestringAdditional CSS classes.
PropTypeDefaultDescription
childrenReactNodeLogo content (text or image). Required.
hrefstringURL for the logo link.
classNamestringAdditional CSS classes.

FloatingDock.Divider

Reuses the Divider component. Relevant props:

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Divider direction.
spacingDividerSpacingSpacing variant.
decorativebooleanfalseWhether the divider is purely decorative.
classNamestringAdditional CSS classes.

On this page