{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "radix-tabs", "type": "registry:ui", "title": "Radix Tabs", "description": "A set of layered sections of content—known as tab panels—that are displayed one at a time.", "dependencies": [ "motion", "radix-ui" ], "registryDependencies": [ "https://animate-ui.com/r/motion-highlight" ], "files": [ { "path": "registry/radix/tabs/index.tsx", "content": "'use client';\n\nimport * as React from 'react';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { type HTMLMotionProps, type Transition, motion } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport {\n MotionHighlight,\n MotionHighlightItem,\n} from '@/components/animate-ui/effects/motion-highlight';\n\ntype TabsProps = React.ComponentProps;\n\nfunction Tabs({ className, ...props }: TabsProps) {\n return (\n \n );\n}\n\ntype TabsListProps = React.ComponentProps & {\n activeClassName?: string;\n transition?: Transition;\n};\n\nfunction TabsList({\n ref,\n children,\n className,\n activeClassName,\n transition = {\n type: 'spring',\n stiffness: 200,\n damping: 25,\n },\n ...props\n}: TabsListProps) {\n const localRef = React.useRef(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);\n\n const [activeValue, setActiveValue] = React.useState(\n undefined,\n );\n\n const getActiveValue = React.useCallback(() => {\n if (!localRef.current) return;\n const activeTab = localRef.current.querySelector(\n '[data-state=\"active\"]',\n );\n if (!activeTab) return;\n setActiveValue(activeTab.getAttribute('data-value') ?? undefined);\n }, []);\n\n React.useEffect(() => {\n getActiveValue();\n\n const observer = new MutationObserver(getActiveValue);\n\n if (localRef.current) {\n observer.observe(localRef.current, {\n attributes: true,\n childList: true,\n subtree: true,\n });\n }\n\n return () => {\n observer.disconnect();\n };\n }, [getActiveValue]);\n\n return (\n \n \n {children}\n \n \n );\n}\n\ntype TabsTriggerProps = React.ComponentProps;\n\nfunction TabsTrigger({ className, value, ...props }: TabsTriggerProps) {\n return (\n \n \n \n );\n}\n\ntype TabsContentProps = React.ComponentProps &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction TabsContent({\n className,\n children,\n transition = {\n duration: 0.5,\n ease: 'easeInOut',\n },\n ...props\n}: TabsContentProps) {\n return (\n \n \n {children}\n \n \n );\n}\n\ntype TabsContentsProps = HTMLMotionProps<'div'> & {\n children: React.ReactNode;\n className?: string;\n transition?: Transition;\n};\n\nfunction TabsContents({\n children,\n className,\n transition = { type: 'spring', stiffness: 200, damping: 25 },\n ...props\n}: TabsContentsProps) {\n const containerRef = React.useRef(null);\n\n const [height, setHeight] = React.useState(0);\n\n React.useEffect(() => {\n if (!containerRef.current) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n const newHeight = entries?.[0]?.contentRect.height;\n if (!newHeight) return;\n requestAnimationFrame(() => {\n setHeight(newHeight);\n });\n });\n\n resizeObserver.observe(containerRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [children]);\n\n React.useLayoutEffect(() => {\n if (containerRef.current) {\n const initialHeight = containerRef.current.getBoundingClientRect().height;\n setHeight(initialHeight);\n }\n }, [children]);\n\n return (\n \n
{children}
\n \n );\n}\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n TabsContents,\n type TabsProps,\n type TabsListProps,\n type TabsTriggerProps,\n type TabsContentProps,\n type TabsContentsProps,\n};\n", "type": "registry:ui", "target": "components/animate-ui/radix/tabs.tsx" } ] }