An interactive dock component inspired by macOS dock with animation capabilities..
1"use client"
2
3import { useEffect, useState } from "react"
4import {
5 BlocksIcon,
6 CircleIcon,
7 HexagonIcon,
8 OctagonIcon,
9 PentagonIcon,
10 SquareIcon,
11 TriangleIcon,
12} from "lucide-react"
13
14import {
15 Dock,
16 DockCard,
17 DockCardInner,
18 DockDivider,
19} from "@/components/ui/dock"
20
21function useIsMobile() {
22 const [isMobile, setIsMobile] = useState(false)
23
24 useEffect(() => {
25 const userAgent = navigator.userAgent
26 const isSmall = window.matchMedia("(max-width: 768px)").matches
27 const isMobile = Boolean(
28 /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.exec(
29 userAgent
30 )
31 )
32
33 const isDev = process.env.NODE_ENV !== "production"
34 if (isDev) setIsMobile(isSmall || isMobile)
35
36 setIsMobile(isSmall && isMobile)
37 }, [])
38
39 return isMobile
40}
41
42// Main component to display the dock with cards
43let gradients = [
44 "https://products.ls.graphics/mesh-gradients/images/03.-Snowy-Mint_1-p-130x130q80.jpeg",
45 "https://products.ls.graphics/mesh-gradients/images/04.-Hopbush_1-p-130x130q80.jpeg",
46 "https://products.ls.graphics/mesh-gradients/images/06.-Wisteria-p-130x130q80.jpeg",
47 "https://products.ls.graphics/mesh-gradients/images/09.-Light-Sky-Blue-p-130x130q80.jpeg",
48 "https://products.ls.graphics/mesh-gradients/images/12.-Tumbleweed-p-130x130q80.jpeg",
49 "https://products.ls.graphics/mesh-gradients/images/15.-Perfume_1-p-130x130q80.jpeg",
50 null,
51 "https://products.ls.graphics/mesh-gradients/images/36.-Pale-Chestnut-p-130x130q80.jpeg",
52]
53
54function DockAnimation() {
55 let openIcons = [
56 <CircleIcon className="h-8 w-8 fill-black stroke-black rounded-full" />,
57 <TriangleIcon className="h-8 w-8 fill-black stroke-black rounded-full" />,
58 <SquareIcon className="h-8 w-8 fill-black stroke-black rounded-full" />,
59 <PentagonIcon className="h-8 w-8 fill-black stroke-black rounded-full" />,
60 <HexagonIcon className="h-8 w-8 fill-black stroke-black rounded-full" />,
61 <OctagonIcon className="h-8 w-8 fill-black stroke-black rounded-full" />,
62 null, // skip
63 <BlocksIcon className="h-8 w-8 fill-black stroke-black rounded-full" />,
64 ]
65
66 const isMobile = useIsMobile()
67
68 const responsiveOpenIcons = isMobile
69 ? openIcons.slice(3, openIcons.length)
70 : openIcons
71 const responsiveGradients = isMobile
72 ? gradients.slice(3, gradients.length)
73 : gradients
74
75 return (
76 <div className=" flex items-center justify-center">
77 <Dock>
78 {responsiveGradients.map((src, index) =>
79 src ? (
80 <DockCard key={src} id={`${index}`}>
81 <DockCardInner src={src} id={`${index}`}>
82 {responsiveOpenIcons[index]}
83 </DockCardInner>
84 </DockCard>
85 ) : (
86 <DockDivider key={index} />
87 )
88 )}
89 </Dock>
90 </div>
91 )
92}
93
94export DockAnimation