{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "table",
  "title": "Table (FRAME/12 Adapter)",
  "description": "FRAME/12 skin for semantic data tables with monospace headers, tabular numerals, and heavy ink rules.",
  "registryDependencies": [
    "https://frame12.dev/r/frame12-styles.json"
  ],
  "files": [
    {
      "path": "ui/table.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\n\nexport type TableDensity = 'comfortable' | 'compact';\n\nconst useIsoLayoutEffect =\n  typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\nconst TableContext = React.createContext<{\n  captionId: string;\n  setActiveCaptionId: (id: string | null) => void;\n} | null>(null);\n\nexport interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {\n  density?: TableDensity;\n  wrapperProps?: React.HTMLAttributes<HTMLDivElement>;\n}\n\nexport function Table({\n  density = 'comfortable',\n  className = '',\n  wrapperProps,\n  children,\n  ...rest\n}: TableProps) {\n  const isCompact = density === 'compact';\n  const rawId = React.useId().replace(/:/g, '');\n  const captionId = `f12-tbl-cap-${rawId}`;\n  const [activeCaptionId, setActiveCaptionId] = React.useState<string | null>(null);\n  const [isOverflowing, setIsOverflowing] = React.useState(false);\n  const wrapRef = React.useRef<HTMLDivElement | null>(null);\n\n  useIsoLayoutEffect(() => {\n    const el = wrapRef.current;\n    if (!el) return;\n    const checkOverflow = () => {\n      const next = el.scrollWidth > el.clientWidth + 1;\n      setIsOverflowing((prev) => (prev === next ? prev : next));\n    };\n    checkOverflow();\n    const ro =\n      typeof ResizeObserver !== 'undefined' ? new ResizeObserver(checkOverflow) : null;\n    if (ro) {\n      ro.observe(el);\n      if (el.firstElementChild) {\n        ro.observe(el.firstElementChild);\n      }\n    }\n    window.addEventListener('resize', checkOverflow);\n    return () => {\n      ro?.disconnect();\n      window.removeEventListener('resize', checkOverflow);\n    };\n  }, [children]);\n\n  const {\n    className: wrapClassName = '',\n    tabIndex: wrapTabIndex,\n    role: wrapRole,\n    'aria-label': wrapAriaLabel,\n    'aria-labelledby': wrapAriaLabelledBy,\n    ...restWrap\n  } = wrapperProps ?? {};\n\n  const resolvedTabIndex = wrapTabIndex !== undefined ? wrapTabIndex : isOverflowing ? 0 : undefined;\n  const resolvedRole = wrapRole !== undefined ? wrapRole : isOverflowing ? 'region' : undefined;\n  const resolvedAriaLabelledBy =\n    wrapAriaLabelledBy ??\n    (isOverflowing && !wrapAriaLabel\n      ? (activeCaptionId ?? rest['aria-labelledby'])\n      : undefined);\n  const resolvedAriaLabel =\n    wrapAriaLabel ??\n    (isOverflowing && !resolvedAriaLabelledBy\n      ? (rest['aria-label'] ?? 'Scrollable data table')\n      : undefined);\n\n  const ctxValue = React.useMemo(\n    () => ({ captionId, setActiveCaptionId }),\n    [captionId],\n  );\n\n  return (\n    <TableContext.Provider value={ctxValue}>\n      <div\n        ref={wrapRef}\n        className={`f12-table-wrap${wrapClassName ? ` ${wrapClassName}` : ''}`}\n        tabIndex={resolvedTabIndex}\n        role={resolvedRole}\n        aria-label={resolvedAriaLabel}\n        aria-labelledby={resolvedAriaLabelledBy}\n        {...restWrap}\n      >\n        <table\n          className={`f12-table${isCompact ? ' f12-table-compact' : ''}${className ? ` ${className}` : ''}`}\n          data-density={isCompact ? 'compact' : undefined}\n          {...rest}\n        >\n          {children}\n        </table>\n      </div>\n    </TableContext.Provider>\n  );\n}\n\nexport function TableHeader({\n  className = '',\n  children,\n  ...rest\n}: React.HTMLAttributes<HTMLTableSectionElement>) {\n  return (\n    <thead className={className} {...rest}>\n      {children}\n    </thead>\n  );\n}\n\nexport function TableBody({\n  className = '',\n  children,\n  ...rest\n}: React.HTMLAttributes<HTMLTableSectionElement>) {\n  return (\n    <tbody className={className} {...rest}>\n      {children}\n    </tbody>\n  );\n}\n\nexport function TableFooter({\n  className = '',\n  children,\n  ...rest\n}: React.HTMLAttributes<HTMLTableSectionElement>) {\n  return (\n    <tfoot className={className} {...rest}>\n      {children}\n    </tfoot>\n  );\n}\n\nexport function TableRow({\n  className = '',\n  children,\n  ...rest\n}: React.HTMLAttributes<HTMLTableRowElement>) {\n  return (\n    <tr className={className} {...rest}>\n      {children}\n    </tr>\n  );\n}\n\nexport function TableHead({\n  scope = 'col',\n  className = '',\n  children,\n  ...rest\n}: React.ThHTMLAttributes<HTMLTableCellElement>) {\n  return (\n    <th scope={scope} className={className} {...rest}>\n      {children}\n    </th>\n  );\n}\n\nexport function TableCell({\n  className = '',\n  children,\n  ...rest\n}: React.TdHTMLAttributes<HTMLTableCellElement>) {\n  return (\n    <td className={className} {...rest}>\n      {children}\n    </td>\n  );\n}\n\nexport function TableCaption({\n  id: userCaptionId,\n  className = '',\n  children,\n  ...rest\n}: React.HTMLAttributes<HTMLTableCaptionElement>) {\n  const ctx = React.useContext(TableContext);\n  const setActiveCaptionId = ctx?.setActiveCaptionId;\n  const resolvedCaptionId = userCaptionId ?? ctx?.captionId;\n  useIsoLayoutEffect(() => {\n    if (!setActiveCaptionId || !resolvedCaptionId) return;\n    setActiveCaptionId(resolvedCaptionId);\n    return () => setActiveCaptionId(null);\n  }, [setActiveCaptionId, resolvedCaptionId]);\n  return (\n    <caption id={resolvedCaptionId} className={className} {...rest}>\n      {children}\n    </caption>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/frame12/table.tsx"
    }
  ],
  "type": "registry:ui"
}