{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "table", "title": "Table", "description": "Animated table with proximity-based row hover highlighting and fluid border transitions. Includes TableHeader, TableBody, TableRow, TableHead, and TableCell sub-components.", "dependencies": [ "framer-motion" ], "registryDependencies": [ "https://zeron-ui.vercel.app/r/surfaces.json", "utils", "https://zeron-ui.vercel.app/r/springs.json", "https://zeron-ui.vercel.app/r/use-proximity-hover.json" ], "files": [ { "path": "src/components/ui/table.tsx", "content": "\"use client\";\n\nimport {\n useRef,\n useEffect,\n useMemo,\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type HTMLAttributes,\n type TdHTMLAttributes,\n type ThHTMLAttributes,\n} from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { cn } from \"@/lib/utils\";\nimport { spring } from \"@/lib/springs\";\nimport { useProximityHover } from \"@/hooks/use-proximity-hover\";\n\n// ── Context ──────────────────────────────────────────────\n\ninterface TableContextValue {\n registerItem: (index: number, element: HTMLElement | null) => void;\n activeIndex: number | null;\n}\n\nconst TableContext = createContext(null);\n\n// ── Table ────────────────────────────────────────────────\n\ninterface TableProps extends HTMLAttributes {\n children: ReactNode;\n}\n\nconst Table = forwardRef(\n ({ children, className, ...props }, ref) => {\n const containerRef = useRef(null);\n\n const {\n activeIndex,\n itemRects,\n sessionRef,\n handlers,\n registerItem,\n measureItems,\n } = useProximityHover(containerRef);\n\n useEffect(() => {\n measureItems();\n }, [measureItems, children]);\n\n const activeRect = activeIndex !== null ? itemRects[activeIndex] : null;\n\n const contextValue = useMemo(\n () => ({ registerItem, activeIndex }),\n [registerItem, activeIndex]\n );\n\n return (\n \n \n {/* Hover background */}\n \n {activeRect && (\n \n )}\n \n\n \n {children}\n \n \n \n );\n }\n);\n\nTable.displayName = \"Table\";\n\n// ── TableHeader ──────────────────────────────────────────\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\n\nTableHeader.displayName = \"TableHeader\";\n\n// ── TableBody ────────────────────────────────────────────\n\nconst TableBody = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\n\nTableBody.displayName = \"TableBody\";\n\n// ── TableRow ─────────────────────────────────────────────\n\ninterface TableRowProps extends HTMLAttributes {\n index?: number;\n}\n\nconst TableRow = forwardRef(\n ({ index, className, style, ...props }, ref) => {\n const internalRef = useRef(null);\n const ctx = useContext(TableContext);\n\n useEffect(() => {\n if (index === undefined || !ctx) return;\n ctx.registerItem(index, internalRef.current);\n return () => ctx.registerItem(index, null);\n }, [index, ctx]);\n\n const isBodyRow = index !== undefined;\n const activeIdx = ctx?.activeIndex ?? null;\n const hideBorder = activeIdx !== null && (\n (isBodyRow && (index === activeIdx || index === activeIdx - 1)) ||\n (!isBodyRow && activeIdx === 0)\n );\n\n return (\n {\n (internalRef as React.MutableRefObject).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject).current = node;\n }}\n data-proximity-index={index}\n className={cn(\n \"group/row relative z-content border-b transition-[border-color] duration-fast\",\n hideBorder ? \"border-border\" : \"border-border\",\n isBodyRow && activeIdx === index && \"is-active\",\n className,\n isBodyRow ? \"font-normal\" : \"font-medium\"\n )}\n style={style}\n {...props}\n />\n );\n }\n);\n\nTableRow.displayName = \"TableRow\";\n\n// ── TableHead ────────────────────────────────────────────\n\nconst TableHead = forwardRef<\n HTMLTableCellElement,\n ThHTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\n\nTableHead.displayName = \"TableHead\";\n\n// ── TableCell ────────────────────────────────────────────\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\n\nTableCell.displayName = \"TableCell\";\n\n// ── Exports ──────────────────────────────────────────────\n\nexport { Table, TableHeader, TableBody, TableRow, TableHead, TableCell };\n", "type": "registry:ui", "target": "components/ui/table.tsx" } ], "type": "registry:ui" }