{"_id":"@bugenzi/formpdf-editor","name":"@bugenzi/formpdf-editor","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@bugenzi/formpdf-editor","version":"0.1.0","description":"Embeddable PDF form field editor for React with JSON and AcroForm export","type":"module","license":"MIT","repository":{"type":"git","url":"git+https://github.com/bugenzi/formbase.git","directory":"packages/pdf-form-editor"},"homepage":"https://github.com/bugenzi/formbase#readme","publishConfig":{"access":"public"},"keywords":["pdf","form","editor","react","acroform","pdf-lib","form-fields","signature","pdf-editor","coordinate-engine"],"sideEffects":["**/*.css"],"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/index.css","./engine":{"types":"./dist/engine/index.d.ts","import":"./dist/engine/index.js","require":"./dist/engine/index.cjs"}},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","prepublishOnly":"tsup"},"peerDependencies":{"react":">=18","react-dom":">=18"},"dependencies":{"@types/pdfmake":"^0.3.2","file-saver":"^2.0.5","immer":"^10.1.1","interactjs":"^1.10.27","nanoid":"^5.1.7","pdf-lib":"^1.17.1","pdfjs-dist":"^4.10.38","pdfmake":"^0.3.7","zustand":"^5.0.0"},"devDependencies":{"@types/file-saver":"^2.0.7","@types/react":"^18.3.0","@types/react-dom":"^18.3.7","tsup":"^8.3.0","typescript":"^5.6.0","vitest":"^4.1.0"},"_id":"@bugenzi/formpdf-editor@0.1.0","gitHead":"f2d2a1d040ab00d60a359b275230d1de37a45b3e","bugs":{"url":"https://github.com/bugenzi/formbase/issues"},"_nodeVersion":"22.13.1","_npmVersion":"11.1.0","dist":{"integrity":"sha512-h6K/xYHiXyd1V3VyAVYbpCR2H8CLvha2Vf917jwBffQ9eyx69rHUk95fiXlpjJwui6oV6ctzP/VOEugYFyTqWA==","shasum":"add89a225f3252960afca623e977c8428b894d75","tarball":"https://registry.npmjs.org/@bugenzi/formpdf-editor/-/formpdf-editor-0.1.0.tgz","fileCount":17,"unpackedSize":560512,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDE+7sdYxP5MH05wD2vUN7QIa4ARdVU/1QlY1pdy8fhTwIgXbo5hTy7qXH45hTMg1DoqU6TzKFxzsJ/S22uuOZ1wI0="}]},"_npmUser":{"name":"bugenzi","email":"amarbugarin@outlook.com"},"directories":{},"maintainers":[{"name":"bugenzi","email":"amarbugarin@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/formpdf-editor_0.1.0_1776707385388_0.1392498710383403"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-20T17:49:45.231Z","0.1.0":"2026-04-20T17:49:45.553Z","modified":"2026-04-20T17:49:45.758Z"},"maintainers":[{"name":"bugenzi","email":"amarbugarin@outlook.com"}],"description":"Embeddable PDF form field editor for React with JSON and AcroForm export","homepage":"https://github.com/bugenzi/formbase#readme","keywords":["pdf","form","editor","react","acroform","pdf-lib","form-fields","signature","pdf-editor","coordinate-engine"],"repository":{"type":"git","url":"git+https://github.com/bugenzi/formbase.git","directory":"packages/pdf-form-editor"},"bugs":{"url":"https://github.com/bugenzi/formbase/issues"},"license":"MIT","readme":"# @bugenzi/formpdf-editor\n\nEmbeddable PDF form editor for React. Place fields on any PDF, export JSON schemas or AcroForm-ready PDFs, and keep coordinates in PDF-native space.\n\n## Install\n\n```bash\nnpm install @bugenzi/formpdf-editor\n# or\npnpm add @bugenzi/formpdf-editor\n```\n\n## Quick start\n\n```tsx\nimport { PdfFormEditor } from '@bugenzi/formpdf-editor'\nimport '@bugenzi/formpdf-editor/styles.css'\n\nfunction App() {\n  return (\n    <PdfFormEditor\n      pdfUrl=\"/contract.pdf\"\n      onSave={(bytes) => upload(bytes)}\n    />\n  )\n}\n```\n\nThat is the zero-config path. You do **not** need an AI proxy to use the editor, export schemas, or export fillable PDFs.\n\n## What ships today\n\n- **6 field types** — text, signature, initials, date, checkbox, dropdown\n- **PDF-native coordinates** — fields stored in PDF points (72pt/inch), with Y-flip handled transparently\n- **AcroForm export** — export PDFs with real form fields via pdf-lib\n- **JSON schema export/import** — round-trip field definitions\n- **Undo/redo** — immer patch-based history\n- **Keyboard shortcuts** — T/S/I/D/C/L to add fields, Ctrl+Z undo, Delete to remove\n- **Drag & resize** — interact.js with alignment guides\n- **Composable API** — use the full editor or import individual pieces\n- **Error boundary and toasts** — built-in recovery and feedback\n\n## Planned or optional\n\n- **AI-assisted detection** — the hooks exist, but you need your own server-side proxy to use it\n- **Headless fill SDK** — planned, not published yet\n\n## Recommended adoption path\n\n1. Start with `PdfFormEditor`\n2. Export a JSON schema or fillable PDF\n3. Move to the composable API only if you need a custom layout\n4. Add AI experimentation later, behind your own proxy, if it fits your product\n\n## Export programmatically\n\n```tsx\nimport { useFormExport } from '@bugenzi/formpdf-editor'\n\nfunction SaveButton({ originalFile }) {\n  const { exportJSON, exportToPdf, downloadJson, downloadPdf } = useFormExport()\n\n  const schema = exportJSON()\n  const pdfBytes = await exportToPdf(originalFile)\n\n  return null\n}\n```\n\n## Schema import\n\n```tsx\nimport { useSchemaImport } from '@bugenzi/formpdf-editor'\n\nfunction LoadButton() {\n  const { importSchema, importFile } = useSchemaImport()\n\n  const result = await importFile(jsonFile)\n  console.log(`Imported ${result.imported} fields`)\n\n  importSchema(schemaObject, { clearExisting: true })\n}\n```\n\n## Props\n\n```ts\ninterface PdfFormEditorProps {\n  pdfUrl?: string\n  pdfFile?: File\n  aiProxyUrl?: string\n  onExport?: (schema) => void\n  onSave?: (pdfBytes: Uint8Array) => void\n}\n```\n\n`aiProxyUrl` is optional. It is only relevant if you are wiring up AI-assisted detection yourself.\n\n## Composable API\n\nUse individual pieces for custom layouts:\n\n```tsx\nimport {\n  EditorProvider,\n  PdfCanvas,\n  FieldLayer,\n  PropsPanel,\n  FieldPalette,\n  Toolbar,\n  useFieldStore,\n  useFormExport,\n  useSchemaImport,\n} from '@bugenzi/formpdf-editor'\nimport '@bugenzi/formpdf-editor/styles.css'\n\nfunction CustomEditor({ file, zoom }) {\n  return (\n    <EditorProvider>\n      <YourToolbar />\n      <PdfCanvas pdfFile={file} scale={zoom}>\n        {(pageIdx) => <FieldLayer pageIdx={pageIdx} />}\n      </PdfCanvas>\n      <PropsPanel />\n    </EditorProvider>\n  )\n}\n```\n\n## Coordinate system\n\nFields are stored in **PDF User Space** (bottom-left origin, points). `CoordEngine` handles the transforms:\n\n```text\nPDF Points (bottom-left) → CoordEngine → Screen Pixels (top-left)\nscreenY = (pageHeightPt - ptY - ptH) * scaleY\n```\n\nThis means:\n- exported coordinates remain correct regardless of zoom level\n- AcroForm fields land where they appear on screen\n- there is no drift between edit mode and export\n\n## AI proxy contract\n\nIf you choose to wire up `aiProxyUrl`, the endpoint must handle two request shapes.\n\n**Field detection**\n\n```json\nPOST { \"imageBase64\": \"<jpeg>\", \"pageIndex\": 0 }\n→ { \"fields\": [{ \"type\": \"text\", \"label\": \"Name\", \"x\": 0.1, \"y\": 0.2, \"w\": 0.3, \"h\": 0.03, \"required\": true }] }\n```\n\nCoordinates are 0-1 relative, top-left origin.\n\n**Chat**\n\n```json\nPOST { \"message\": \"What fields does this form need?\" }\n→ { \"reply\": \"Based on the document...\" }\n```\n\n## CSS\n\nThe stylesheet must be imported separately:\n\n```ts\nimport '@bugenzi/formpdf-editor/styles.css'\n```\n\nUses CSS variables for theming. All classes are prefixed with `pfe-` or `form-field`.\n\n## Requirements\n\n- React 18+\n- Modern browser (Chrome, Firefox, Safari, Edge)\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-3406d076139f451756f838e3acba16cc"}