'use client'; import * as React from 'react'; import { Tabs as TabsPrimitive } from 'radix-ui'; import { type HTMLMotionProps, type Transition, motion } from 'motion/react'; import { cn } from '@workspace/ui/lib/utils'; import { MotionHighlight, MotionHighlightItem, } from '@/registry/effects/motion-highlight'; type TabsProps = React.ComponentProps; function Tabs({ className, ...props }: TabsProps) { return ( ); } type TabsListProps = React.ComponentProps & { activeClassName?: string; transition?: Transition; }; function TabsList({ ref, children, className, activeClassName, transition = { type: 'spring', stiffness: 200, damping: 25, }, ...props }: TabsListProps) { const localRef = React.useRef(null); React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement); const [activeValue, setActiveValue] = React.useState( undefined, ); const getActiveValue = React.useCallback(() => { if (!localRef.current) return; const activeTab = localRef.current.querySelector( '[data-state="active"]', ); if (!activeTab) return; setActiveValue(activeTab.getAttribute('data-value') ?? undefined); }, []); React.useEffect(() => { getActiveValue(); const observer = new MutationObserver(getActiveValue); if (localRef.current) { observer.observe(localRef.current, { attributes: true, childList: true, subtree: true, }); } return () => { observer.disconnect(); }; }, [getActiveValue]); return ( {children} ); } type TabsTriggerProps = React.ComponentProps; function TabsTrigger({ className, value, ...props }: TabsTriggerProps) { return ( ); } type TabsContentProps = React.ComponentProps & HTMLMotionProps<'div'> & { transition?: Transition; }; function TabsContent({ className, children, transition = { duration: 0.5, ease: 'easeInOut', }, ...props }: TabsContentProps) { return ( {children} ); } type TabsContentsProps = HTMLMotionProps<'div'> & { children: React.ReactNode; className?: string; transition?: Transition; }; function TabsContents({ children, className, transition = { type: 'spring', stiffness: 200, damping: 25 }, ...props }: TabsContentsProps) { const containerRef = React.useRef(null); const [height, setHeight] = React.useState(0); React.useEffect(() => { if (!containerRef.current) return; const resizeObserver = new ResizeObserver((entries) => { const newHeight = entries?.[0]?.contentRect.height; if (!newHeight) return; requestAnimationFrame(() => { setHeight(newHeight); }); }); resizeObserver.observe(containerRef.current); return () => { resizeObserver.disconnect(); }; }, [children]); React.useLayoutEffect(() => { if (containerRef.current) { const initialHeight = containerRef.current.getBoundingClientRect().height; setHeight(initialHeight); } }, [children]); return (
{children}
); } export { Tabs, TabsList, TabsTrigger, TabsContent, TabsContents, type TabsProps, type TabsListProps, type TabsTriggerProps, type TabsContentProps, type TabsContentsProps, };