The Dock component creates a macOS-style dock with smooth spring animations and interactive item scaling. Each dock item features dynamic tooltips with rotation and translation effects based on mouse movement.
Installation
npm install @craftdotui/components
import { Dock , DockItem } from "@craftdotui/components" ;
Basic Dock
With Click Handlers
Custom Styling
import { Dock , DockItem } from "@craftdotui/components" ;
import { Home , Search , Bell , User } from "lucide-react" ;
export default function Example () {
return (
< Dock >
< DockItem icon = { < Home /> } label = "Home" />
< DockItem icon = { < Search /> } label = "Search" />
< DockItem icon = { < Bell /> } label = "Notifications" />
< DockItem icon = { < User /> } label = "Profile" />
</ Dock >
);
}
Components
The container component that wraps all dock items.
The dock items to display.
Additional CSS classes for custom styling.
DockItem
Individual items within the dock.
The icon to display in the dock item.
The label shown in the tooltip on hover.
Optional click handler function.
Additional CSS classes for the dock item.
Animation Details
Dock Container Animation
initial = {{ opacity : 0 }}
animate = {{ opacity : 1 }}
transition = {{ type : "spring" , stiffness : 260 , damping : 20 }}
DockItem Spring Configuration
const springConfig = {
stiffness: 200 ,
damping: 10
};
Hover Effects
Scale on Hover : Items scale to 1.2x with spring physics
Tap Scale : Items scale to 0.9x on click
Rotation : Tooltip rotates ±25° based on mouse position
Translation : Tooltip shifts ±10px horizontally
whileHover = {{
scale : 1.2 ,
transition : { type : "spring" , stiffness : 300 , damping : 20 },
}}
whileTap = {{ scale : 0.9 }}
Tooltip Animation
initial = {{ opacity : 0 , y : 10 , scale : 0.8 }}
animate = {{ opacity : 1 , y : 0 , scale : 1 }}
exit = {{ opacity : 0 , y : 10 , scale : 0.8 }}
The tooltip dynamically rotates and translates based on horizontal mouse movement within each dock item.
Examples
Social Media Dock
import { Dock , DockItem } from "@craftdotui/components" ;
import { Facebook , Twitter , Instagram , Linkedin , Youtube } from "lucide-react" ;
export default function SocialDock () {
return (
< Dock className = "fixed bottom-8 left-1/2 -translate-x-1/2" >
< DockItem
icon = { < Facebook className = "w-6 h-6 text-blue-600" /> }
label = "Facebook"
onClick = { () => window . open ( "https://facebook.com" ) }
/>
< DockItem
icon = { < Twitter className = "w-6 h-6 text-sky-500" /> }
label = "Twitter"
onClick = { () => window . open ( "https://twitter.com" ) }
/>
< DockItem
icon = { < Instagram className = "w-6 h-6 text-pink-600" /> }
label = "Instagram"
onClick = { () => window . open ( "https://instagram.com" ) }
/>
< DockItem
icon = { < Linkedin className = "w-6 h-6 text-blue-700" /> }
label = "LinkedIn"
onClick = { () => window . open ( "https://linkedin.com" ) }
/>
< DockItem
icon = { < Youtube className = "w-6 h-6 text-red-600" /> }
label = "YouTube"
onClick = { () => window . open ( "https://youtube.com" ) }
/>
</ Dock >
);
}
App Launcher
import { Dock , DockItem } from "@craftdotui/components" ;
import { Code , Terminal , Database , Cloud , Package } from "lucide-react" ;
export default function AppLauncher () {
const apps = [
{ icon: Code , label: "VS Code" , action: "code" },
{ icon: Terminal , label: "Terminal" , action: "terminal" },
{ icon: Database , label: "Database" , action: "db" },
{ icon: Cloud , label: "Cloud" , action: "cloud" },
{ icon: Package , label: "Packages" , action: "npm" },
];
return (
< Dock className = "gap-6" >
{ apps . map (( app ) => (
< DockItem
key = { app . action }
icon = { < app.icon className = "w-6 h-6" /> }
label = { app . label }
onClick = { () => launchApp ( app . action ) }
/>
)) }
</ Dock >
);
}
Position the dock using fixed positioning (e.g., fixed bottom-4 left-1/2 -translate-x-1/2) for a persistent navigation bar.
Best Practices
Keep dock items between 4-8 for optimal usability
Use consistent icon sizes (typically 20-24px)
Provide clear, concise labels
Use semantic icon choices that match their function
Consider adding visual separators for grouped actions
Accessibility
Fully keyboard accessible
ARIA labels inherited from icon components
Supports screen readers
Respects reduced motion preferences