Dock

A dock component that displays a list of items.

Dock - Basic

Loading...

Usage Guide

Install the clsx and tailwind-merge packages:

npm install clsx tw-merge framer-motion

Next, add cn utility:

import { twMerge } from "tailwind-merge";
import { clsx, type ClassValue } from "clsx";

export function cn(...inputs: ClassValue[]) {
    return twMerge(clsx(inputs));
}

Copy and paste the following component source.

"use client";

import React from "react";
import { cn } from "@/lib/utils";
import { motion } from "framer-motion";

export interface DockItemProps {
    icon: React.ReactNode;
    label: string;
    onClick?: () => void;
    className?: string;
}

interface DockProps {
    children: React.ReactNode;
    className?: string;
}

// dock
export function Dock({ children, className }: DockProps) {
    return (
        <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ type: "spring", stiffness: 260, damping: 20 }}
            className={cn("px-4 py-2 flex gap-2 border rounded-2xl shadow-md", className)}
        >
            {children}
        </motion.div>
    );
}

// dock item
export function DockItem({ icon, label, onClick, className, ...props }: DockItemProps) {
    const [isHovered, setIsHovered] = React.useState(false);

    return (
        <motion.div
            className={cn(
                "relative flex items-center justify-center w-12 h-12 rounded-full shadow-md cursor-pointer border dark:bg-neutral-900",
                className
            )}
            onHoverStart={() => setIsHovered(true)}
            onHoverEnd={() => setIsHovered(false)}
            onClick={onClick}
            {...props}
        >
            {icon}
            {isHovered && (
                <motion.div
                    initial={{ opacity: 0, y: 10 }}
                    animate={{ opacity: 1, y: 0 }}
                    className="absolute bottom-full mb-2 px-2 py-1 bg-black/75 text-white dark:bg-white dark:text-black text-xs rounded"
                >
                    {label}
                </motion.div>
            )}
        </motion.div>
    );
}

Props - Dock

PropTypeDescriptionDefault
childrenReactNodeThe content to be rendered inside the component_
classNamestringCustom class to apply to the component._

Props - DockItem

PropTypeDescriptionDefault
iconReactNodeIcon component_
labelstringText to show on tooltip_
classNamestringCustom class to apply to the component._