{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "table", "title": "Table", "description": "A data table where row separators are hand-drawn rough lines instead of CSS borders.", "dependencies": [ "roughjs" ], "registryDependencies": [ "https://www.bydefaulthuman.fun/r/use-rough.json", "utils", "https://www.bydefaulthuman.fun/r/crumble-theme.json", "https://www.bydefaulthuman.fun/r/rough-lib.json" ], "files": [ { "path": "registry/new-york/ui/table.tsx", "content": "\"use client\";\n\nimport {\n useCallback,\n useContext,\n useEffect,\n useRef,\n type HTMLAttributes,\n type TdHTMLAttributes,\n type ThHTMLAttributes,\n} from \"react\";\nimport { createContext } from \"react\";\nimport { useRough } from \"@/hooks/use-rough\";\nimport { cn } from \"@/lib/utils\";\nimport {\n CrumbleContext,\n resolveRoughVars,\n type CrumbleColorProps,\n type CrumbleTheme,\n} from \"@/lib/rough\";\n\ninterface TableContextValue {\n rowIndex: number;\n theme: CrumbleTheme;\n}\n\nconst TableContext = createContext({\n rowIndex: 0,\n theme: \"pencil\",\n});\n\nexport interface TableProps\n extends HTMLAttributes,\n CrumbleColorProps {\n theme?: CrumbleTheme;\n}\n\nexport function Table({\n children,\n className,\n fill,\n stroke,\n strokeMuted,\n theme: themeProp,\n ...props\n}: TableProps) {\n const { theme: contextTheme } = useContext(CrumbleContext);\n const theme = themeProp ?? contextTheme;\n const roughStyle = resolveRoughVars({ stroke, strokeMuted, fill });\n return (\n \n \n \n {children}\n \n
\n \n );\n}\n\nexport function TableHeader({\n children,\n className,\n ...props\n}: HTMLAttributes) {\n return (\n \n {children}\n \n );\n}\n\nexport function TableBody({\n children,\n className,\n ...props\n}: HTMLAttributes) {\n return (\n \n {children}\n \n );\n}\n\nexport interface TableRowProps extends HTMLAttributes {\n index?: number;\n}\n\nexport function TableRow({\n children,\n className,\n index = 0,\n ...props\n}: TableRowProps) {\n const { theme } = useContext(TableContext);\n const rowRef = useRef(null);\n const externalSvgRef = useRef(null);\n const { drawLine, svgRef } = useRough({\n stableId: `table-row-${index}`,\n svgRef: externalSvgRef,\n theme,\n variant: \"border\",\n });\n\n const draw = useCallback(() => {\n const row = rowRef.current;\n const svg = svgRef.current;\n if (!row || !svg) return;\n\n const w = row.offsetWidth;\n svg.replaceChildren();\n svg.setAttribute(\"width\", String(w));\n svg.setAttribute(\"height\", \"6\");\n svg.setAttribute(\"viewBox\", `0 0 ${w} 6`);\n\n const line = drawLine(0, 3, w, 3, {\n stroke: \"var(--cr-stroke-muted)\",\n strokeWidth: theme === \"crayon\" ? 1.5 : 0.8,\n });\n if (line) svg.appendChild(line);\n }, [drawLine, svgRef, theme]);\n\n useEffect(() => {\n const id = requestAnimationFrame(() => draw());\n return () => cancelAnimationFrame(id);\n }, [draw]);\n\n useEffect(() => {\n const row = rowRef.current;\n if (!row) return;\n const ro = new ResizeObserver(() => draw());\n ro.observe(row);\n return () => ro.disconnect();\n }, [draw]);\n\n return (\n \n \n {children}\n \n \n \n \n \n );\n}\n\nexport function TableHead({\n children,\n className,\n ...props\n}: ThHTMLAttributes) {\n return (\n \n {children}\n \n );\n}\n\nexport function TableCell({\n children,\n className,\n ...props\n}: TdHTMLAttributes) {\n return (\n \n {children}\n \n );\n}\n\nexport function TableCaption({\n children,\n className,\n ...props\n}: HTMLAttributes) {\n return (\n \n {children}\n \n );\n}\n", "type": "registry:ui", "target": "components/crumble/ui/table.tsx" } ], "type": "registry:ui" }