{
  "$schema": "https://pdfx.akashpise.dev/schema/registry-item.json",
  "name": "data-table",
  "type": "registry:ui",
  "title": "DataTable",
  "description": "Convenience API: columns + data array. Uses Table/TableRow/TableCell internally.",
  "files": [
    {
      "path": "components/pdfx/data-table/pdfx-data-table.tsx",
      "content": "import { Text as PDFText } from '@react-pdf/renderer';\nimport type { Style } from '@react-pdf/types';\nimport { Fragment } from 'react';\nimport { usePdfxTheme, useSafeMemo } from '../lib/pdfx-theme-context';\nimport { Table, TableBody, TableCell, TableFooter, TableHeader, TableRow } from '../table/pdfx-table';\nimport { createCompactStyles, formatValue } from './pdfx-data-table.styles';\nimport type { DataTableProps } from './pdfx-data-table.types';\n\nexport function DataTable<T extends Record<string, unknown>>({\n  columns,\n  data,\n  variant = 'grid',\n  footer,\n  stripe = false,\n  size = 'default',\n  noWrap = false,\n  style,\n}: DataTableProps<T>) {\n  const theme = usePdfxTheme();\n  const compact = useSafeMemo(() => createCompactStyles(theme), [theme]);\n  const isCompact = size === 'compact';\n\n  return (\n    <Table variant={variant} zebraStripe={stripe} noWrap={noWrap} style={style}>\n      <TableHeader>\n        <TableRow header>\n          {columns.map((col) => (\n            <TableCell\n              key={col.key}\n              header\n              align={col.align ?? 'left'}\n              width={col.width}\n              style={isCompact ? compact.cell : undefined}\n            >\n              {isCompact ? (\n                <PDFText\n                  style={[compact.headerText, col.align ? ({ textAlign: col.align } as Style) : {}]}\n                >\n                  {col.header}\n                </PDFText>\n              ) : (\n                col.header\n              )}\n            </TableCell>\n          ))}\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        {data.map((row, i) => (\n          // biome-ignore lint/suspicious/noArrayIndexKey: DataTable has no row id; order is stable for static data\n          <Fragment key={i}>\n            <TableRow>\n              {columns.map((col) => {\n                const value = row[col.key];\n                const rendered = col.render ? col.render(value, row) : null;\n                const text = rendered === null ? formatValue(value) : null;\n                return (\n                  <TableCell\n                    key={col.key}\n                    align={col.align ?? 'left'}\n                    width={col.width}\n                    style={isCompact ? compact.cell : undefined}\n                  >\n                    {isCompact ? (\n                      rendered !== null ? (\n                        rendered\n                      ) : (\n                        <PDFText\n                          style={[\n                            compact.text,\n                            col.align ? ({ textAlign: col.align } as Style) : {},\n                          ]}\n                        >\n                          {text}\n                        </PDFText>\n                      )\n                    ) : rendered !== null ? (\n                      rendered\n                    ) : (\n                      text\n                    )}\n                  </TableCell>\n                );\n              })}\n            </TableRow>\n          </Fragment>\n        ))}\n      </TableBody>\n      {footer && (\n        <TableFooter>\n          <TableRow footer>\n            {columns.map((col) => {\n              const value = col.key in footer ? footer[col.key] : '';\n              const rendered = col.renderFooter ? col.renderFooter(value) : null;\n              const text = rendered === null ? formatValue(value) : null;\n              return (\n                <TableCell\n                  key={col.key}\n                  footer={!!value}\n                  align={col.align ?? 'left'}\n                  width={col.width}\n                  style={isCompact ? compact.cell : undefined}\n                >\n                  {isCompact ? (\n                    rendered !== null ? (\n                      rendered\n                    ) : (\n                      <PDFText\n                        style={[\n                          value ? compact.footerText : compact.text,\n                          col.align ? ({ textAlign: col.align } as Style) : {},\n                        ]}\n                      >\n                        {text}\n                      </PDFText>\n                    )\n                  ) : rendered !== null ? (\n                    rendered\n                  ) : (\n                    text\n                  )}\n                </TableCell>\n              );\n            })}\n          </TableRow>\n        </TableFooter>\n      )}\n    </Table>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/pdfx/data-table/pdfx-data-table.styles.ts",
      "content": "import { StyleSheet } from '@react-pdf/renderer';\nimport { usePdfxTheme } from '../lib/pdfx-theme-context';\ntype PdfxTheme = ReturnType<typeof usePdfxTheme>;\n\n/**\n * Creates compact-mode cell and text styles for the DataTable component.\n * Used when `size=\"compact\"` to render denser rows with smaller font sizes.\n * @param t - The resolved PdfxTheme instance.\n */\nexport function createCompactStyles(t: PdfxTheme) {\n  const { spacing, fontWeights, lineHeights } = t.primitives;\n  return StyleSheet.create({\n    cell: {\n      paddingVertical: spacing[0.5],\n      paddingHorizontal: spacing[2],\n    },\n    text: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.primitives.typography.xs,\n      lineHeight: lineHeights.normal,\n      color: t.colors.foreground,\n    },\n    headerText: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.primitives.typography.xs,\n      lineHeight: lineHeights.normal,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.semibold,\n    },\n    footerText: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.primitives.typography.xs,\n      lineHeight: lineHeights.normal,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.semibold,\n    },\n  });\n}\n\n/**\n * Converts an arbitrary cell value to a display string.\n * Returns an empty string for null/undefined values.\n * @param value - The raw cell value to format.\n */\nexport function formatValue(value: unknown): string {\n  if (value === null || value === undefined) return '';\n  if (typeof value === 'number') return String(value);\n  return String(value);\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/pdfx/data-table/pdfx-data-table.types.ts",
      "content": "import type React from 'react';\nimport type { TableVariant } from '../table/pdfx-table.types';\nimport type { Style } from '@react-pdf/types';\n\n/** DataTable row density size. */\nexport type DataTableSize = 'default' | 'compact';\n\n/**\n * Column definition for a DataTable.\n * Props - `key` | `header` | `align` | `width` | `render` | `renderFooter`\n * @see {@link DataTableColumn}\n */\nexport interface DataTableColumn<T = Record<string, unknown>> {\n  key: keyof T & string;\n  header: string;\n  align?: 'left' | 'center' | 'right';\n  width?: string | number;\n  /**\n   * Custom cell renderer. Must return @react-pdf/renderer elements (Text, View,\n   * Image, etc.) — NOT HTML DOM elements. TypeScript accepts ReactNode but DOM\n   * nodes will crash at runtime in the PDF renderer.\n   */\n  render?: (value: unknown, row: T) => React.ReactNode;\n  /**\n   * Custom footer cell renderer. Same constraint: return @react-pdf/renderer\n   * elements only — no HTML/DOM nodes.\n   */\n  renderFooter?: (value: unknown) => React.ReactNode;\n}\n\n/**\n * Data table for PDF rendering with column definitions, footer support, and stripe options.\n * Props - `columns` | `data` | `variant` | `footer` | `stripe` | `size` | `noWrap` | `style`\n * @see {@link DataTableProps}\n */\nexport interface DataTableProps<T = Record<string, unknown>> {\n  /** Custom styles to merge with component defaults */\n  style?: Style;\n  columns: DataTableColumn<T>[];\n  data: T[];\n  /**\n   * @default 'grid'\n   */\n  variant?: TableVariant;\n  footer?: Partial<Record<keyof T & string, string | number>>;\n  stripe?: boolean;\n  /**\n   * @default 'default'\n   */\n  size?: DataTableSize;\n  noWrap?: boolean;\n}\n",
      "type": "registry:component"
    }
  ],
  "dependencies": [
    "@react-pdf/renderer"
  ],
  "registryDependencies": [
    "theme",
    "table"
  ]
}