{
  "$schema": "https://pdfx.akashpise.dev/schema/registry-item.json",
  "name": "table",
  "type": "registry:ui",
  "title": "Table",
  "description": "Composable table with Table, TableRow, TableCell",
  "files": [
    {
      "path": "components/pdfx/table/pdfx-table.tsx",
      "content": "import { Text as PDFText, View } from '@react-pdf/renderer';\nimport type { Style } from '@react-pdf/types';\nimport { Children, type ReactElement, type ReactNode, cloneElement, isValidElement } from 'react';\nimport { usePdfxTheme, useSafeMemo } from '../lib/pdfx-theme-context';\nimport { createTableStyles } from './pdfx-table.styles';\nimport type {\n  TableCellProps,\n  TableProps,\n  TableRowProps,\n  TableSectionProps,\n  TableVariant,\n} from './pdfx-table.types';\n\nfunction processTableChildren(\n  children: ReactNode,\n  variant: TableVariant,\n  zebraStripe: boolean\n): ReactNode {\n  let bodyRowIndex = 0;\n\n  return Children.map(children, (child) => {\n    if (!isValidElement(child)) return child;\n\n    if (child.type === TableHeader || child.type === TableBody || child.type === TableFooter) {\n      const isBody = child.type === TableBody;\n      const sectionChild = child as ReactElement<TableSectionProps>;\n      const sectionChildren = Children.map(sectionChild.props.children, (rowChild) => {\n        if (isValidElement(rowChild) && rowChild.type === TableRow) {\n          const rowProps: Partial<TableRowProps> = { variant };\n\n          if (isBody && zebraStripe) {\n            const isStripe = bodyRowIndex % 2 === 1;\n            bodyRowIndex++;\n            if (isStripe) {\n              rowProps.stripe = true;\n            }\n          }\n\n          return cloneElement(rowChild as ReactElement<TableRowProps>, rowProps);\n        }\n        return rowChild;\n      });\n\n      return cloneElement(child, {}, sectionChildren);\n    }\n\n    if (child.type === TableRow) {\n      return cloneElement(child as ReactElement<TableRowProps>, { variant });\n    }\n\n    return child;\n  });\n}\n\nexport function TableHeader({ children, style }: TableSectionProps) {\n  return (\n    <View minPresenceAhead={60} style={style}>\n      {children}\n    </View>\n  );\n}\n\nexport function TableBody({ children, style }: TableSectionProps) {\n  return <View style={style}>{children}</View>;\n}\n\nexport function TableFooter({ children, style }: TableSectionProps) {\n  return <View style={style}>{children}</View>;\n}\n\nexport function Table({\n  children,\n  style,\n  variant = 'line',\n  zebraStripe = false,\n  noWrap = false,\n}: TableProps) {\n  const theme = usePdfxTheme();\n  const styles = useSafeMemo(() => createTableStyles(theme), [theme]);\n  const tableStyles: Style[] = [styles.table];\n  const effectiveZebra = variant === 'striped' ? true : zebraStripe;\n\n  tableStyles.push(\n    {\n      grid: styles.tableGrid,\n      line: styles.tableLine,\n      minimal: styles.tableMinimal,\n      striped: styles.tableStriped,\n      compact: styles.tableCompact,\n      bordered: styles.tableBordered,\n      'primary-header': styles.tablePrimaryHeader,\n    }[variant]\n  );\n\n  const styleArray = style ? [...tableStyles, style] : tableStyles;\n  const processedChildren = processTableChildren(children, variant, effectiveZebra);\n\n  const inner = <View style={styleArray}>{processedChildren}</View>;\n  return noWrap ? <View wrap={false}>{inner}</View> : inner;\n}\n\nexport function TableRow({\n  header,\n  footer,\n  stripe,\n  children,\n  style,\n  variant = 'line',\n}: TableRowProps) {\n  const theme = usePdfxTheme();\n  const styles = useSafeMemo(() => createTableStyles(theme), [theme]);\n  const rowStyles: Style[] = [styles.row];\n\n  rowStyles.push(\n    {\n      grid: styles.rowGrid,\n      line: styles.rowLine,\n      minimal: styles.rowMinimal,\n      striped: styles.rowStriped,\n      compact: styles.rowCompact,\n      bordered: styles.rowBordered,\n      'primary-header': styles.rowPrimaryHeader,\n    }[variant]\n  );\n\n  if (header) {\n    rowStyles.push(\n      {\n        grid: styles.rowHeaderGrid,\n        line: styles.rowHeaderLine,\n        minimal: styles.rowHeaderMinimal,\n        striped: styles.rowHeaderStriped,\n        compact: styles.rowHeaderCompact,\n        bordered: styles.rowHeaderBordered,\n        'primary-header': styles.rowHeaderPrimaryHeader,\n      }[variant]\n    );\n  }\n\n  if (footer) {\n    if (variant === 'striped') rowStyles.push(styles.rowFooterStriped);\n    else rowStyles.push(styles.rowFooter);\n  }\n\n  if (stripe && !header && !footer) {\n    rowStyles.push(styles.rowStripe);\n  }\n\n  const styleArray = style ? [...rowStyles, style] : rowStyles;\n  const childArray = Children.toArray(children);\n  const processedChildren = childArray.map((child, i) => {\n    if (isValidElement(child) && child.type === TableCell) {\n      return cloneElement(child as ReactElement<TableCellProps>, {\n        variant,\n        header,\n        footer,\n        _last: i === childArray.length - 1,\n      });\n    }\n    return child;\n  });\n\n  return (\n    <View wrap={false} style={styleArray}>\n      {processedChildren}\n    </View>\n  );\n}\n\nexport function TableCell({\n  header,\n  footer,\n  align,\n  width,\n  children,\n  style,\n  variant = 'line',\n  _last,\n}: TableCellProps) {\n  const theme = usePdfxTheme();\n  const styles = useSafeMemo(() => createTableStyles(theme), [theme]);\n  const cellStyles: Style[] =\n    width !== undefined ? [styles.cellFixed, { width } as Style] : [styles.cell];\n\n  const cellVariantStyle = (\n    {\n      minimal: styles.cellMinimal,\n      striped: styles.cellStriped,\n      compact: styles.cellCompact,\n      bordered: styles.cellBordered,\n      'primary-header': styles.cellPrimaryHeader,\n    } as Partial<Record<TableVariant, Style>>\n  )[variant];\n  if (cellVariantStyle) cellStyles.push(cellVariantStyle);\n\n  if (variant === 'grid' && !_last) {\n    cellStyles.push(styles.cellGridBorder);\n  } else if (variant === 'bordered' && !_last) {\n    cellStyles.push(styles.cellBorderedBorder);\n  }\n\n  if (align) {\n    cellStyles.push({ textAlign: align } as Style);\n  }\n\n  const styleArray = style ? [...cellStyles, style] : cellStyles;\n\n  let textStyle: Style = styles.cellText;\n  if (header) {\n    textStyle = {\n      grid: styles.cellTextHeaderGrid,\n      line: styles.cellTextHeaderLine,\n      minimal: styles.cellTextHeaderMinimal,\n      striped: styles.cellTextHeaderStriped,\n      compact: styles.cellTextHeaderCompact,\n      bordered: styles.cellTextHeaderBordered,\n      'primary-header': styles.cellTextHeaderPrimaryHeader,\n    }[variant];\n  } else if (footer) {\n    textStyle = styles.cellTextFooter;\n  } else if (variant === 'compact') {\n    textStyle = styles.cellTextCompact;\n  }\n\n  const content =\n    typeof children === 'string' ? (\n      <PDFText style={[textStyle, align ? { textAlign: align } : {}, { margin: 0, padding: 0 }]}>\n        {children}\n      </PDFText>\n    ) : (\n      children\n    );\n\n  return <View style={styleArray}>{content}</View>;\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/pdfx/table/pdfx-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 all table styles derived from the active theme.\n * @param t - The resolved PdfxTheme instance.\n */\nexport function createTableStyles(t: PdfxTheme) {\n  const { spacing, borderRadius, fontWeights, typography } = t.primitives;\n  const borderColor = t.colors.border;\n\n  const hairline = 0.5;\n  const rule = 1;\n  const thick = 1.5;\n\n  const cellPadV = spacing[2] - 2;\n  const cellPadH = spacing[2] + 2;\n  const cellPadVCompact = spacing[0.5];\n  const cellPadHCompact = spacing[2];\n\n  const rowDivider = {\n    borderBottomWidth: hairline,\n    borderBottomColor: borderColor,\n    borderBottomStyle: 'solid' as const,\n  };\n\n  return StyleSheet.create({\n    table: {\n      display: 'flex',\n      flexDirection: 'column',\n      width: '100%',\n      marginBottom: t.spacing.componentGap,\n    },\n\n    tableGrid: {\n      borderWidth: thick,\n      borderColor: borderColor,\n      borderStyle: 'solid',\n      borderTopLeftRadius: borderRadius.md,\n      borderTopRightRadius: borderRadius.md,\n      borderBottomLeftRadius: borderRadius.md,\n      borderBottomRightRadius: borderRadius.md,\n      overflow: 'hidden' as const,\n    },\n\n    tableLine: {\n      borderBottomWidth: hairline,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n\n    tableMinimal: {\n      paddingVertical: spacing[2],\n    },\n\n    tableStriped: {\n      borderTopWidth: hairline,\n      borderTopColor: borderColor,\n      borderTopStyle: 'solid',\n      borderBottomWidth: hairline,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n\n    tableCompact: {\n      borderBottomWidth: hairline,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n\n    tableBordered: {\n      borderWidth: rule,\n      borderColor: borderColor,\n      borderStyle: 'solid',\n      borderTopLeftRadius: borderRadius.sm,\n      borderTopRightRadius: borderRadius.sm,\n      borderBottomLeftRadius: borderRadius.sm,\n      borderBottomRightRadius: borderRadius.sm,\n      overflow: 'hidden' as const,\n    },\n\n    tablePrimaryHeader: {\n      borderBottomWidth: hairline,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n\n    row: {\n      flexDirection: 'row',\n      display: 'flex',\n    },\n\n    rowGrid: rowDivider,\n    rowLine: rowDivider,\n    rowMinimal: rowDivider,\n    rowStriped: {},\n    rowCompact: rowDivider,\n    rowBordered: rowDivider,\n    rowPrimaryHeader: rowDivider,\n\n    rowHeaderGrid: {\n      backgroundColor: t.colors.muted,\n      borderBottomWidth: rule,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n    rowHeaderLine: {\n      borderBottomWidth: rule,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n    rowHeaderMinimal: {\n      borderBottomWidth: rule,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n    rowHeaderStriped: {\n      backgroundColor: t.colors.muted,\n      borderBottomWidth: rule,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n    rowHeaderCompact: {\n      backgroundColor: t.colors.muted,\n      borderBottomWidth: rule,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n    rowHeaderBordered: {\n      backgroundColor: t.colors.muted,\n      borderBottomWidth: hairline,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n    rowHeaderPrimaryHeader: {\n      backgroundColor: t.colors.primary,\n    },\n\n    rowFooter: {\n      borderTopWidth: rule,\n      borderTopColor: borderColor,\n      borderTopStyle: 'solid',\n    },\n    rowFooterStriped: {\n      borderTopWidth: rule,\n      borderTopColor: borderColor,\n      borderTopStyle: 'solid',\n      backgroundColor: t.colors.muted,\n    },\n\n    rowStripe: {\n      backgroundColor: t.colors.muted,\n    },\n\n    cell: {\n      flex: 1,\n      paddingVertical: cellPadV,\n      paddingHorizontal: cellPadH,\n      justifyContent: 'center',\n    },\n    cellFixed: {\n      flexGrow: 0,\n      flexShrink: 0,\n      paddingVertical: cellPadV,\n      paddingHorizontal: cellPadH,\n      justifyContent: 'center',\n    },\n\n    cellMinimal: {\n      paddingVertical: spacing[1] + 1,\n      paddingHorizontal: spacing[2] - 2,\n    },\n    cellStriped: {\n      paddingVertical: cellPadV,\n      paddingHorizontal: cellPadH,\n    },\n    cellCompact: {\n      paddingVertical: cellPadVCompact,\n      paddingHorizontal: cellPadHCompact,\n    },\n    cellBordered: {\n      paddingVertical: cellPadV,\n      paddingHorizontal: cellPadH,\n    },\n    cellPrimaryHeader: {\n      paddingVertical: cellPadV,\n      paddingHorizontal: cellPadH,\n    },\n\n    cellGridBorder: {\n      borderRightWidth: hairline,\n      borderRightColor: borderColor,\n      borderRightStyle: 'solid',\n    },\n    cellBorderedBorder: {\n      borderRightWidth: hairline,\n      borderRightColor: borderColor,\n      borderRightStyle: 'solid',\n    },\n\n    cellText: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n    },\n\n    cellTextHeaderGrid: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.semibold,\n    },\n    cellTextHeaderLine: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.semibold,\n    },\n    cellTextHeaderMinimal: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: 1.2,\n      color: t.colors.mutedForeground,\n      fontWeight: fontWeights.medium,\n    },\n    cellTextHeaderStriped: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.semibold,\n    },\n    cellTextHeaderCompact: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: typography.xs,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.semibold,\n      textTransform: 'uppercase',\n      letterSpacing: 0.6,\n    },\n    cellTextHeaderBordered: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.bold,\n    },\n    cellTextHeaderPrimaryHeader: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: typography.xs,\n      lineHeight: 1.2,\n      color: t.colors.primaryForeground,\n      fontWeight: fontWeights.semibold,\n      textTransform: 'uppercase',\n      letterSpacing: 0.6,\n    },\n\n    cellTextFooter: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.semibold,\n    },\n\n    cellTextCompact: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: typography.xs,\n      lineHeight: 1.2,\n      color: t.colors.foreground,\n    },\n  });\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/pdfx/table/pdfx-table.types.ts",
      "content": "import type { Style } from '@react-pdf/types';\nimport type React from 'react';\n\n/** Table visual style variant. */\nexport type TableVariant =\n  | 'line'\n  | 'grid'\n  | 'minimal'\n  | 'striped'\n  | 'compact'\n  | 'bordered'\n  | 'primary-header';\n\n/**\n * Table container with visual style variants and optional zebra striping.\n * Props - `variant` | `zebraStripe` | `noWrap` | `children` | `style`\n * @see {@link TableProps}\n */\nexport interface TableProps {\n  /** Custom styles to merge with component defaults */\n  style?: Style;\n  /** Content to render */\n  children: React.ReactNode;\n  /**\n   * @default 'line'\n   */\n  variant?: TableVariant;\n  /**\n   * @default false\n   */\n  zebraStripe?: boolean;\n  /**\n   * @default false\n   */\n  noWrap?: boolean;\n}\n\nexport interface TableSectionProps {\n  /** Custom styles to merge with component defaults */\n  style?: Style;\n  /** Content to render */\n  children: React.ReactNode;\n}\n\n/**\n * Table row with optional header, footer, and stripe states.\n * Props - `header` | `footer` | `stripe` | `variant` | `children` | `style`\n * @see {@link TableRowProps}\n */\nexport interface TableRowProps {\n  /** Custom styles to merge with component defaults */\n  style?: Style;\n  /** Content to render */\n  children: React.ReactNode;\n  header?: boolean;\n  footer?: boolean;\n  stripe?: boolean;\n  variant?: TableVariant;\n}\n\n/**\n * Table cell with alignment, fixed width, and header or footer text styling.\n * Props - `header` | `footer` | `align` | `width` | `variant` | `_last` | `children` | `style`\n * @see {@link TableCellProps}\n */\nexport interface TableCellProps {\n  /** Custom styles to merge with component defaults */\n  style?: Style;\n  /** Content to render */\n  children: React.ReactNode;\n  header?: boolean;\n  footer?: boolean;\n  align?: 'left' | 'center' | 'right';\n  width?: string | number;\n  variant?: TableVariant;\n  _last?: boolean;\n}\n",
      "type": "registry:component"
    }
  ],
  "dependencies": [
    "@react-pdf/renderer"
  ],
  "registryDependencies": [
    "theme"
  ]
}