UNPKG

lightswind

Version:

A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.

47 lines 4.36 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Dock; const jsx_runtime_1 = require("react/jsx-runtime"); const framer_motion_1 = require("framer-motion"); const react_1 = require("react"); function useDockItemSize(mouseX, baseItemSize, magnification, distance, ref, spring) { const mouseDistance = (0, framer_motion_1.useTransform)(mouseX, (val) => { if (typeof val !== "number" || isNaN(val)) return 0; const rect = ref.current?.getBoundingClientRect() ?? { x: 0, width: baseItemSize, }; return val - rect.x - baseItemSize / 2; }); const targetSize = (0, framer_motion_1.useTransform)(mouseDistance, [-distance, 0, distance], [baseItemSize, magnification, baseItemSize]); return (0, framer_motion_1.useSpring)(targetSize, spring); } function DockItem({ icon, label, onClick, mouseX, baseItemSize, magnification, distance, spring, badgeCount, }) { const ref = (0, react_1.useRef)(null); const isHovered = (0, framer_motion_1.useMotionValue)(0); const size = useDockItemSize(mouseX, baseItemSize, magnification, distance, ref, spring); const [showLabel, setShowLabel] = (0, react_1.useState)(false); (0, react_1.useEffect)(() => { const unsubscribe = isHovered.on("change", (value) => setShowLabel(value === 1)); return () => unsubscribe(); }, [isHovered]); return ((0, jsx_runtime_1.jsxs)(framer_motion_1.motion.div, { ref: ref, style: { width: size, height: size }, onHoverStart: () => isHovered.set(1), onHoverEnd: () => isHovered.set(0), onFocus: () => isHovered.set(1), onBlur: () => isHovered.set(0), onClick: onClick, className: "relative inline-flex items-center justify-center rounded-full bg-background shadow-md", tabIndex: 0, role: "button", "aria-haspopup": "true", "aria-label": label, children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center", children: icon }), badgeCount !== undefined && badgeCount > 0 && ((0, jsx_runtime_1.jsx)("span", { className: "absolute -top-2 -right-2 flex items-center justify-center w-5 h-5 text-xs font-bold text-white bg-red-500 rounded-full", children: badgeCount > 99 ? "99+" : badgeCount })), (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { children: showLabel && ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { initial: { opacity: 0, y: 0 }, animate: { opacity: 1, y: -10 }, exit: { opacity: 0, y: 0 }, transition: { duration: 0.2 }, className: "absolute -top-6 left-1/2 w-fit whitespace-pre rounded-md \r\n border border bg-[#060606] px-2 py-0.5 text-xs text-white", style: { x: "-50%" }, role: "tooltip", children: label })) })] })); } function Dock({ items, className = "", spring = { mass: 0.1, stiffness: 150, damping: 12 }, magnification = 70, distance = 200, panelHeight = 64, dockHeight = 256, baseItemSize = 50, }) { const mouseX = (0, framer_motion_1.useMotionValue)(Infinity); const isHovered = (0, framer_motion_1.useMotionValue)(0); const maxHeight = (0, react_1.useMemo)(() => Math.max(dockHeight, magnification + magnification / 2 + 4), [magnification, dockHeight]); const animatedHeight = (0, framer_motion_1.useSpring)((0, framer_motion_1.useTransform)(isHovered, [0, 1], [panelHeight, maxHeight]), spring); return ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { style: { height: animatedHeight }, className: "mx-2 flex max-w-full items-center", children: (0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { onMouseMove: ({ pageX }) => { isHovered.set(1); mouseX.set(pageX); }, onMouseLeave: () => { isHovered.set(0); mouseX.set(Infinity); }, className: `absolute bottom-2 left-1/2 -translate-x-1/2 transform flex items-end gap-4 w-fit rounded-2xl border-2 border px-4 pb-2 ${className}`, style: { height: panelHeight }, role: "toolbar", "aria-label": "Application dock", children: items.map((item, index) => ((0, jsx_runtime_1.jsx)(DockItem, { icon: item.icon, label: item.label, onClick: item.onClick, mouseX: mouseX, baseItemSize: baseItemSize, magnification: magnification, distance: distance, spring: spring, badgeCount: item.badgeCount }, index))) }) })); } //# sourceMappingURL=Dock.js.map