{
  "$schema": "https://pdfx.akashpise.dev/schema/registry-item.json",
  "name": "form",
  "type": "registry:ui",
  "title": "Form",
  "description": "Form layout with labeled fields in single, two-column, or three-column layouts",
  "files": [
    {
      "path": "components/pdfx/form/pdfx-form.tsx",
      "content": "import { Text as PDFText, View } from '@react-pdf/renderer';\nimport type { Style } from '@react-pdf/types';\nimport { usePdfxTheme, useSafeMemo } from '../lib/pdfx-theme-context';\nimport { createFormStyles } from './pdfx-form.styles';\nimport type { FormLayout, PdfFormField, PdfFormGroup, PdfFormProps } from './pdfx-form.types';\n\nfunction renderFieldAbove(\n  field: PdfFormField,\n  idx: number,\n  styles: ReturnType<typeof createFormStyles>\n) {\n  const areaHeight = field.height ?? 18;\n  const areaStyle: Style[] = [styles.fieldArea, { minHeight: areaHeight }];\n\n  return (\n    <View key={`${field.label}-${idx}`} style={styles.fieldAbove}>\n      <PDFText style={styles.labelAbove}>{field.label}</PDFText>\n      <View style={areaStyle}>\n        {field.hint ? <PDFText style={styles.hint}>{field.hint}</PDFText> : null}\n      </View>\n    </View>\n  );\n}\n\nfunction renderFieldLeft(\n  field: PdfFormField,\n  idx: number,\n  styles: ReturnType<typeof createFormStyles>\n) {\n  const areaHeight = field.height ?? 18;\n  const areaStyle: Style[] = [styles.fieldArea, styles.fieldLeftArea, { minHeight: areaHeight }];\n\n  return (\n    <View key={`${field.label}-${idx}`} style={styles.fieldLeft}>\n      <PDFText style={styles.labelLeft}>{field.label}</PDFText>\n      <View style={areaStyle}>\n        {field.hint ? <PDFText style={styles.hint}>{field.hint}</PDFText> : null}\n      </View>\n    </View>\n  );\n}\n\nfunction renderGroup(\n  group: PdfFormGroup,\n  gi: number,\n  styles: ReturnType<typeof createFormStyles>,\n  labelPosition: 'above' | 'left'\n) {\n  const layout: FormLayout = group.layout ?? 'single';\n  const cols = layout === 'three-column' ? 3 : layout === 'two-column' ? 2 : 1;\n\n  const renderField = (field: PdfFormField, idx: number) =>\n    labelPosition === 'left'\n      ? renderFieldLeft(field, idx, styles)\n      : renderFieldAbove(field, idx, styles);\n\n  if (cols === 1) {\n    return (\n      <View key={`group-${gi}`} style={styles.group}>\n        {group.title ? <PDFText style={styles.groupTitle}>{group.title}</PDFText> : null}\n        {group.fields.map(renderField)}\n      </View>\n    );\n  }\n\n  const chunkSize = Math.ceil(group.fields.length / cols);\n  const chunks: PdfFormField[][] = [];\n  for (let i = 0; i < group.fields.length; i += chunkSize) {\n    chunks.push(group.fields.slice(i, i + chunkSize));\n  }\n  while (chunks.length < cols) {\n    chunks.push([]);\n  }\n\n  return (\n    <View key={`group-${gi}`} style={styles.group}>\n      {group.title ? <PDFText style={styles.groupTitle}>{group.title}</PDFText> : null}\n      <View style={styles.columnsRow}>\n        {chunks.map((chunk, ci) => (\n          <View key={`col-${gi}-${chunk[0]?.label ?? ci}`} style={styles.column}>\n            {chunk.map(renderField)}\n          </View>\n        ))}\n      </View>\n    </View>\n  );\n}\n\nexport function PdfForm({\n  title,\n  subtitle,\n  groups,\n  variant = 'underline',\n  labelPosition = 'above',\n  noWrap = false,\n  style,\n}: PdfFormProps) {\n  const theme = usePdfxTheme();\n  const styles = useSafeMemo(() => createFormStyles(theme, variant), [theme, variant]);\n\n  const rootStyles: Style[] = [styles.root];\n  if (style) rootStyles.push(style);\n\n  const inner = (\n    <View style={rootStyles}>\n      {title ? <PDFText style={styles.formTitle}>{title}</PDFText> : null}\n      {subtitle ? <PDFText style={styles.formSubtitle}>{subtitle}</PDFText> : null}\n      {title || subtitle ? <View style={styles.formDivider} /> : null}\n      {groups.map((group, gi) => renderGroup(group, gi, styles, labelPosition))}\n    </View>\n  );\n\n  return noWrap ? <View wrap={false}>{inner}</View> : inner;\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/pdfx/form/pdfx-form.styles.ts",
      "content": "import { StyleSheet } from '@react-pdf/renderer';\nimport { usePdfxTheme } from '../lib/pdfx-theme-context';\ntype PdfxTheme = ReturnType<typeof usePdfxTheme>;\nimport type { PdfFormVariant } from './pdfx-form.types';\n\n/** Style factory for fillable form layouts, derived from the active theme. */\nexport function createFormStyles(t: PdfxTheme, variant: PdfFormVariant = 'underline') {\n  const { spacing, borderRadius, fontWeights, typography } = t.primitives;\n  const borderColor = t.colors.border;\n  const hairline = 0.75; // lighter than spacing[0.5]=2pt — more refined\n  const rule = 1; // group title rule\n\n  const fieldAreaByVariant: Record<PdfFormVariant, object> = {\n    underline: {\n      borderBottomWidth: 1,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n    },\n    box: {\n      borderWidth: hairline,\n      borderColor: borderColor,\n      borderStyle: 'solid',\n      borderRadius: borderRadius.sm,\n    },\n    outlined: {\n      borderWidth: hairline,\n      borderColor: t.colors.foreground,\n      borderStyle: 'solid',\n      borderRadius: borderRadius.md,\n    },\n    ghost: {\n      backgroundColor: t.colors.muted,\n      borderRadius: borderRadius.sm,\n    },\n  };\n\n  const hasPadding = variant === 'box' || variant === 'outlined' || variant === 'ghost';\n\n  return StyleSheet.create({\n    root: {\n      width: '100%',\n      marginBottom: t.spacing.componentGap,\n    },\n\n    formTitle: {\n      fontFamily: t.typography.heading.fontFamily,\n      fontSize: typography.xl,\n      lineHeight: t.typography.heading.lineHeight,\n      color: t.colors.foreground,\n      fontWeight: fontWeights.bold,\n      marginBottom: spacing[1],\n    },\n    formSubtitle: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: typography.sm,\n      lineHeight: t.typography.body.lineHeight,\n      color: t.colors.mutedForeground,\n      marginBottom: spacing[3],\n    },\n    formDivider: {\n      borderBottomWidth: rule,\n      borderBottomColor: borderColor,\n      borderBottomStyle: 'solid',\n      marginBottom: spacing[4],\n    },\n\n    group: {\n      marginBottom: spacing[5],\n    },\n    groupTitle: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: typography.xs,\n      lineHeight: 1.2,\n      color: t.colors.mutedForeground,\n      fontWeight: fontWeights.semibold,\n      textTransform: 'uppercase',\n      letterSpacing: 0.8,\n      marginBottom: spacing[3],\n    },\n\n    columnsRow: {\n      flexDirection: 'row',\n      gap: spacing[4],\n    },\n    column: {\n      flex: 1,\n    },\n\n    fieldAbove: {\n      marginBottom: spacing[3],\n      width: '100%',\n    },\n    labelAbove: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: typography.xs,\n      lineHeight: 1.2,\n      color: t.colors.mutedForeground,\n      fontWeight: fontWeights.medium,\n      textTransform: 'uppercase',\n      letterSpacing: 0.5,\n      marginBottom: spacing[1],\n    },\n\n    fieldLeft: {\n      flexDirection: 'row',\n      alignItems: 'flex-end',\n      marginBottom: spacing[3],\n      gap: spacing[2],\n    },\n    labelLeft: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: t.typography.body.fontSize,\n      lineHeight: t.typography.body.lineHeight,\n      color: t.colors.mutedForeground,\n      fontWeight: fontWeights.medium,\n      width: 80,\n      paddingBottom: hasPadding ? spacing[1] : 0,\n    },\n    fieldLeftArea: {\n      flex: 1,\n    },\n\n    fieldArea: {\n      width: '100%' as const,\n      ...fieldAreaByVariant[variant],\n    },\n\n    hint: {\n      fontFamily: t.typography.body.fontFamily,\n      fontSize: typography.xs,\n      color: t.colors.mutedForeground,\n      opacity: 0.14,\n      paddingTop: hasPadding ? spacing[1] : spacing[0.5],\n      paddingBottom: hasPadding ? spacing[1] : 0,\n      paddingHorizontal: hasPadding ? spacing[2] : 0,\n    },\n  });\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/pdfx/form/pdfx-form.types.ts",
      "content": "import type { Style } from '@react-pdf/types';\n\n/** Visual style variant for the fillable form. */\nexport type PdfFormVariant = 'underline' | 'box' | 'outlined' | 'ghost';\n\n/** Column layout for a form section. */\nexport type FormLayout = 'single' | 'two-column' | 'three-column';\n\n/** Label position relative to the field. */\nexport type FormLabelPosition = 'above' | 'left';\n\n/**\n * A single fillable field definition.\n * Props - `label` | `hint` | `height` | `width`\n * @see {@link PdfFormField}\n */\nexport interface PdfFormField {\n  label: string;\n  hint?: string;\n  /**\n   * Height of the blank field area in points.\n   * @default 18\n   */\n  height?: number;\n  width?: number | string;\n}\n\n/**\n * A logical group of fields with an optional section title.\n * Props - `title` | `fields` | `layout`\n * @see {@link PdfFormGroup}\n */\nexport interface PdfFormGroup {\n  title?: string;\n  fields: PdfFormField[];\n  /**\n   * @default 'single'\n   */\n  layout?: FormLayout;\n}\n\n/**\n * Fillable PDF form with grouped fields, layout variants, and label positioning options.\n * Props - `title` | `subtitle` | `groups` | `variant` | `labelPosition` | `noWrap` | `style`\n * @see {@link PdfFormProps}\n */\nexport interface PdfFormProps {\n  title?: string;\n  subtitle?: string;\n  groups: PdfFormGroup[];\n  /**\n   * @default 'underline'\n   */\n  variant?: PdfFormVariant;\n  /**\n   * @default 'above'\n   */\n  labelPosition?: FormLabelPosition;\n  noWrap?: boolean;\n  style?: Style;\n}\n",
      "type": "registry:component"
    }
  ],
  "dependencies": [
    "@react-pdf/renderer"
  ],
  "registryDependencies": [
    "theme"
  ]
}