{"_id":"@00rez/form-runner","_rev":"7-e9f3ad8ef11b1027867fc24a61ad75c5","name":"@00rez/form-runner","dist-tags":{"latest":"1.0.6"},"versions":{"1.0.0":{"name":"@00rez/form-runner","version":"1.0.0","_id":"@00rez/form-runner@1.0.0","maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"dist":{"shasum":"954d5e5e045d6ac0b2351da084e77bb7d43890b9","tarball":"https://registry.npmjs.org/@00rez/form-runner/-/form-runner-1.0.0.tgz","fileCount":46,"integrity":"sha512-hUlVoYMCWjRGkq9bquIIYVrsix6z7URPHD543tU95uQPKymrrr79vAxaqRrwcX0Iq1GBnx8uQiBXSJDgGSoO4g==","signatures":[{"sig":"MEQCIFS8+NPvJV8czwhExicauqJERh8F2kby7Z2Yw7bImze1AiAW9CmvS500FU1EvryTER0FbYVPA8SPGL2Si2im3vtwiA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":210228},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.es.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.umd.js"},"./styles.css":"./dist/style.css"},"gitHead":"f497f6be1d1f4d1df79a24facaf2354601217774","scripts":{"lint":"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"tsc && vite build","test:ui":"vitest --ui","test:coverage":"vitest --coverage"},"_npmUser":{"name":"00rez","email":"alh17885@gmail.com"},"_npmVersion":"10.9.0","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@rjsf/core":"^6.1.2","@rjsf/utils":"^6.1.2","@rjsf/shadcn":"^6.1.2","lucide-react":"^0.554.0","markdown-to-jsx":"^7.4.7","@rjsf/validator-ajv8":"^6.1.2"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.1","jsdom":"^27.2.0","vitest":"^4.0.13","postcss":"^8.5.6","playwright":"^1.57.0","typescript":"^5.9.3","@types/node":"^22.5.4","tailwindcss":"^3.4.18","@types/react":"^18.3.5","autoprefixer":"^10.4.22","vite-plugin-dts":"^4.0.3","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@testing-library/user-event":"^14.5.2"},"peerDependencies":{"react":"^18.3.1","react-dom":"^18.3.1"},"_npmOperationalInternal":{"tmp":"tmp/form-runner_1.0.0_1767266732629_0.9310169396070125","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@00rez/form-runner","version":"1.0.1","_id":"@00rez/form-runner@1.0.1","maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"dist":{"shasum":"204336907778dba300cafbaa620afa837e6d881e","tarball":"https://registry.npmjs.org/@00rez/form-runner/-/form-runner-1.0.1.tgz","fileCount":47,"integrity":"sha512-l1etWAjE8aYsqoO1JnmbmbKcPyfmt1FTRLDd8fb9H/aoim2gyAqpqe23cNHbpxCkBIErkiM0EV4pwP2M04gqdg==","signatures":[{"sig":"MEYCIQCbcYF2xhgsBord1SKbAxCCTdOjE7tAf3BORpKZZF9U8AIhAMQH7E6xc3Rol2/zNto+lVisvYu9yGq+Q8RME4FWwUjm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":225532},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.es.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.umd.js"},"./styles.css":"./dist/style.css"},"gitHead":"2fe69f7cbcb614a844daf716bbb786c24bb144c1","scripts":{"lint":"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"tsc && vite build","test:ui":"vitest --ui","test:coverage":"vitest --coverage"},"_npmUser":{"name":"00rez","email":"alh17885@gmail.com"},"_npmVersion":"10.9.0","description":"A powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@rjsf/core":"^6.1.2","@rjsf/utils":"^6.1.2","@rjsf/shadcn":"^6.1.2","lucide-react":"^0.554.0","markdown-to-jsx":"^7.4.7","@rjsf/validator-ajv8":"^6.1.2"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.1","jsdom":"^27.2.0","vitest":"^4.0.13","postcss":"^8.5.6","playwright":"^1.57.0","typescript":"^5.9.3","@types/node":"^22.5.4","tailwindcss":"^3.4.18","@types/react":"^18.3.5","autoprefixer":"^10.4.22","vite-plugin-dts":"^4.0.3","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@testing-library/user-event":"^14.5.2"},"peerDependencies":{"react":"^18.3.1","react-dom":"^18.3.1"},"_npmOperationalInternal":{"tmp":"tmp/form-runner_1.0.1_1767268075431_0.44686162764835613","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@00rez/form-runner","version":"1.0.2","license":"MIT","_id":"@00rez/form-runner@1.0.2","maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"dist":{"shasum":"4aab583516f434aab4ae604e7d41a191ccd76409","tarball":"https://registry.npmjs.org/@00rez/form-runner/-/form-runner-1.0.2.tgz","fileCount":47,"integrity":"sha512-UZu7dK3DUSytWua5dOSAfNdZUZ08SM2vYrlkN+RuS8fXdY3IbPFo1K/8xJ/iBp02NkR4OTt3bmRFcc1sZW1dYg==","signatures":[{"sig":"MEQCIFxQVHuMIeOMXvHQn3k3zGVT2zXIbD53AQZMaPK2mwzlAiBttrGL1ctPky8bWnZmb47p1V9vksCaSQpNpDAZYRfDRQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":225554},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.es.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.umd.js"},"./styles.css":"./dist/style.css"},"gitHead":"cbb5078d144547a5ce6183ed9d85db94f5671992","scripts":{"lint":"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"tsc && vite build","test:ui":"vitest --ui","test:coverage":"vitest --coverage"},"_npmUser":{"name":"00rez","email":"alh17885@gmail.com"},"_npmVersion":"10.9.0","description":"A powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@rjsf/core":"^6.1.2","@rjsf/utils":"^6.1.2","@rjsf/shadcn":"^6.1.2","lucide-react":"^0.554.0","markdown-to-jsx":"^7.4.7","@rjsf/validator-ajv8":"^6.1.2"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.1","jsdom":"^27.2.0","vitest":"^4.0.13","postcss":"^8.5.6","playwright":"^1.57.0","typescript":"^5.9.3","@types/node":"^22.5.4","tailwindcss":"^3.4.18","@types/react":"^18.3.5","autoprefixer":"^10.4.22","vite-plugin-dts":"^4.0.3","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@testing-library/user-event":"^14.5.2"},"peerDependencies":{"react":"^18.3.1","react-dom":"^18.3.1"},"_npmOperationalInternal":{"tmp":"tmp/form-runner_1.0.2_1767269606056_0.04364573967291441","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@00rez/form-runner","version":"1.0.3","license":"MIT","_id":"@00rez/form-runner@1.0.3","maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"dist":{"shasum":"8032c319b4cd81972460bdc345560ecc23bea98d","tarball":"https://registry.npmjs.org/@00rez/form-runner/-/form-runner-1.0.3.tgz","fileCount":47,"integrity":"sha512-Z2LRg2V9JphceJmxSG33Nyd8XFeoluKNu5C+MiesNLKCQasYzzam5k35rmNOFebqVt2pm4zxI/tB+6UnW7ROHw==","signatures":[{"sig":"MEYCIQCDxUFEpo9I6KrpScHd1Ai8NE45UywGMGnrTMwx4lgRywIhALkl+o2FxPMjfOoWJQS3OMugIprelytajaN2HrWxeKd4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":225729},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.es.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.umd.js"},"./form-runner.css":"./dist/form-runner.css"},"gitHead":"79cf9df5c338b7fc254c7565d532739b56aae797","scripts":{"lint":"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"tsc && vite build","test:ui":"vitest --ui","test:coverage":"vitest --coverage"},"_npmUser":{"name":"00rez","email":"alh17885@gmail.com"},"_npmVersion":"10.9.0","description":"A powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@rjsf/core":"^6.1.2","@rjsf/utils":"^6.1.2","@rjsf/shadcn":"^6.1.2","lucide-react":"^0.554.0","markdown-to-jsx":"^7.4.7","@rjsf/validator-ajv8":"^6.1.2"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.1","jsdom":"^27.2.0","vitest":"^4.0.13","postcss":"^8.5.6","playwright":"^1.57.0","typescript":"^5.9.3","@types/node":"^22.5.4","tailwindcss":"^3.4.18","@types/react":"^18.3.5","autoprefixer":"^10.4.22","vite-plugin-dts":"^4.0.3","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@testing-library/user-event":"^14.5.2"},"peerDependencies":{"react":"^18.3.1","react-dom":"^18.3.1"},"_npmOperationalInternal":{"tmp":"tmp/form-runner_1.0.3_1767280869086_0.5192158357984129","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@00rez/form-runner","version":"1.0.4","license":"MIT","_id":"@00rez/form-runner@1.0.4","maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"dist":{"shasum":"2be57f549341f65d6eaa002b1c72a472fa131eab","tarball":"https://registry.npmjs.org/@00rez/form-runner/-/form-runner-1.0.4.tgz","fileCount":47,"integrity":"sha512-tSFoL36+QxacZcYDiuM39GwShYXSXUAP7apuKiABGBWu2BPj2QxNphhNERI4u6sPikUeFwwMN7GsVCIiB/FpeA==","signatures":[{"sig":"MEUCIFvYVRzGvm3I+IzCG+UuimgMIYdKbNXO+MkPIBguiTMKAiEAzxrTBtnbz0xUbNz1g0YmxrAzLkjU+PNGOSBkj59Pn1E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":225734},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.es.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.umd.js"},"./form-runner.css":"./dist/form-runner.css"},"gitHead":"9c65eb1825fa3ed11723efb12dc4b18a164e0cdb","scripts":{"lint":"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"tsc && vite build","test:ui":"vitest --ui","test:coverage":"vitest --coverage"},"_npmUser":{"name":"00rez","email":"alh17885@gmail.com"},"_npmVersion":"10.9.0","description":"A powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@rjsf/core":"^6.1.2","@rjsf/utils":"^6.1.2","@rjsf/shadcn":"^6.1.2","lucide-react":"^0.554.0","markdown-to-jsx":"^7.4.7","@rjsf/validator-ajv8":"^6.1.2"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.1","jsdom":"^27.2.0","vitest":"^4.0.13","postcss":"^8.5.6","playwright":"^1.57.0","typescript":"^5.9.3","@types/node":"^22.5.4","tailwindcss":"^3.4.18","@types/react":"^18.3.5","autoprefixer":"^10.4.22","vite-plugin-dts":"^4.0.3","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@testing-library/user-event":"^14.5.2"},"peerDependencies":{"react":"^18.3.1","react-dom":"^18.3.1"},"_npmOperationalInternal":{"tmp":"tmp/form-runner_1.0.4_1767294891528_0.6658691917291704","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@00rez/form-runner","version":"1.0.5","license":"MIT","_id":"@00rez/form-runner@1.0.5","maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"dist":{"shasum":"80bd6dd4a40f6a7242e4b45ede77f7f800c0563f","tarball":"https://registry.npmjs.org/@00rez/form-runner/-/form-runner-1.0.5.tgz","fileCount":47,"integrity":"sha512-HS5bJxQfw42yI25la1++uuOMvFkACPNvkYW/u87rc+ZQh3TrXFkRofgmaHp24HW6zNH70tALhoVm79/6wFAJCA==","signatures":[{"sig":"MEUCIF/uuvlEGoty1fer7NR8ShRqCrbVUTJ6EdCr+h/RBsZ5AiEA9tmMB3a6kQgdpK3cgW3uSD3fsyTRu0mZcSinaVTTlzQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":225629},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.es.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.umd.js"},"./form-runner.css":"./dist/form-runner.css"},"gitHead":"566ad46e670dc7203dab6fb2fce51d6822c3d032","scripts":{"lint":"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"tsc && vite build","test:ui":"vitest --ui","test:coverage":"vitest --coverage"},"_npmUser":{"name":"00rez","email":"alh17885@gmail.com"},"_npmVersion":"10.9.0","description":"A powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@rjsf/core":"^6.1.2","@rjsf/utils":"^6.1.2","@rjsf/shadcn":"^6.1.2","lucide-react":"^0.554.0","markdown-to-jsx":"^7.4.7","@rjsf/validator-ajv8":"^6.1.2"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.1","jsdom":"^27.2.0","vitest":"^4.0.13","postcss":"^8.5.6","playwright":"^1.57.0","typescript":"^5.9.3","@types/node":"^22.5.4","tailwindcss":"^3.4.18","@types/react":"^18.3.5","autoprefixer":"^10.4.22","vite-plugin-dts":"^4.0.3","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@testing-library/user-event":"^14.5.2"},"peerDependencies":{"react":"^18.3.1","react-dom":"^18.3.1"},"_npmOperationalInternal":{"tmp":"tmp/form-runner_1.0.5_1767513449200_0.9519408768212654","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@00rez/form-runner","version":"1.0.6","license":"MIT","type":"module","main":"./dist/index.umd.js","module":"./dist/index.es.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.umd.js"},"./form-runner.css":"./dist/form-runner.css"},"scripts":{"build":"tsc && vite build","lint":"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0","test":"vitest","test:ui":"vitest --ui","test:coverage":"vitest --coverage"},"peerDependencies":{"react":"^18.3.1","react-dom":"^18.3.1"},"dependencies":{"@rjsf/core":"^6.1.2","@rjsf/shadcn":"^6.1.2","@rjsf/utils":"^6.1.2","@rjsf/validator-ajv8":"^6.1.2","lucide-react":"^0.554.0","markdown-to-jsx":"^7.4.7"},"devDependencies":{"@testing-library/jest-dom":"^6.9.1","@testing-library/react":"^16.3.0","@testing-library/user-event":"^14.5.2","@types/node":"^22.5.4","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.7.0","autoprefixer":"^10.4.22","jsdom":"^27.2.0","playwright":"^1.57.0","postcss":"^8.5.6","tailwindcss":"^3.4.18","typescript":"^5.9.3","vite":"^6.4.1","vite-plugin-dts":"^4.0.3","vitest":"^4.0.13"},"_id":"@00rez/form-runner@1.0.6","gitHead":"085672b589e760dcb9ebc1320ef8619ff738cb50","description":"A powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional","_nodeVersion":"22.12.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-WuKZf92tugPuHRtx8KtG2XucCRq7ylZFZpe+8x3IMvjag9Ex7jmZbUWElNMb5hfF8yIbrBnMdZ8LE2MBIo8C/w==","shasum":"0e2cc124d4bab483d2235e0c85b433d292ae79cd","tarball":"https://registry.npmjs.org/@00rez/form-runner/-/form-runner-1.0.6.tgz","fileCount":47,"unpackedSize":227663,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCfigQRzR13CXnmhX8n4C1cnqoZ3dhmm4q74t9RNI+SVwIhANWg14IPbLYHuiUWGpo4XQwn7Peo5zu888StBC0Moev/"}]},"_npmUser":{"name":"00rez","email":"alh17885@gmail.com"},"directories":{},"maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/form-runner_1.0.6_1768681735434_0.7847056938520276"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-01T11:25:32.522Z","modified":"2026-01-17T20:28:55.701Z","1.0.0":"2026-01-01T11:25:32.765Z","1.0.1":"2026-01-01T11:47:55.611Z","1.0.2":"2026-01-01T12:13:26.243Z","1.0.3":"2026-01-01T15:21:09.237Z","1.0.4":"2026-01-01T19:14:51.705Z","1.0.5":"2026-01-04T07:57:29.361Z","1.0.6":"2026-01-17T20:28:55.594Z"},"license":"MIT","description":"A powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional","maintainers":[{"name":"00rez","email":"alh17885@gmail.com"}],"readme":"# @00rez/form-runner\n\nA powerful, reusable React form rendering library built on [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/). Render complex forms from JSON Schema with advanced features like dynamic options, event callbacks, conditional logic, and custom widgets.\n\n## Installation\n\n```bash\nnpm install @00rez/form-runner react react-dom @rjsf/core @rjsf/utils @rjsf/validator-ajv8\n```\n\n## Quick Start\n\n```tsx\nimport { Form } from '@00rez/form-runner';\nimport { createValidator } from '@rjsf/validator-ajv8';\n\nconst schema = {\n  type: 'object',\n  properties: {\n    firstName: { type: 'string', title: 'First Name' },\n    email: { type: 'string', format: 'email', title: 'Email' },\n  },\n  required: ['firstName', 'email'],\n};\n\nconst uiSchema = {\n  firstName: { 'ui:placeholder': 'Enter your first name' },\n  email: { 'ui:widget': 'email' },\n};\n\nconst validator = createValidator();\n\nexport default function App() {\n  const [formData, setFormData] = React.useState({});\n\n  return (\n    <Form\n      schema={schema}\n      uiSchema={uiSchema}\n      formData={formData}\n      validator={validator}\n      onChange={(e) => setFormData(e.formData)}\n      onSubmit={(e) => console.log('Submitted:', e.formData)}\n    />\n  );\n}\n```\n\n## Core Components\n\n### Form\n\nThe main form rendering component. Wraps RJSF with custom widgets, templates, and theme.\n\n**Props:**\n\n```typescript\ninterface FormProps {\n  id?: string;                          // Unique form ID (auto-normalized)\n  schema: RJSFSchema;                   // JSON Schema defining form structure & validation\n  uiSchema: UiSchema;                   // UI Schema controlling presentation\n  formData: object;                     // Current form data\n  validator: ValidatorType;             // JSON Schema validator (use @rjsf/validator-ajv8)\n  onChange?: (data: IChangeEvent, id?: string) => void;  // Called when form data changes\n  onSubmit?: (data: unknown) => void;   // Called when form is submitted\n  omitExtraData?: boolean;              // Remove properties not in schema\n  liveOmit?: boolean;                   // Remove extra data on change (not just submit)\n  transformErrors?: ErrorTransformer | ((errors: RJSFValidationError[]) => RJSFValidationError[]);\n  callbackRegistry?: EventCallbackRegistry;  // Registry for event callbacks\n  formContext?: Record<string, unknown>; // Additional context passed to widgets\n  children?: React.ReactNode;           // Custom buttons or elements\n  theme?: ThemeProps;                   // Allow for custom theme override\n}\n```\n\n**Example:**\n\n```tsx\n<Form\n  id=\"contactForm\"\n  schema={schema}\n  uiSchema={uiSchema}\n  formData={data}\n  validator={validator}\n  onChange={(e) => setData(e.formData)}\n  onSubmit={(e) => handleSubmit(e.formData)}\n  callbackRegistry={myCallbacks}\n/>\n```\n\n## Built-in Widgets\n\nThe form-runner includes custom widgets for enhanced UX:\n\n| Widget | Usage | Description |\n|--------|-------|-------------|\n| `TextArea` | Text with longer content | Multi-line text input |\n| `Email` | Email fields | Email validation |\n| `Password` | Password fields | Masked input |\n| `Toggle` | Boolean fields | Toggle switch component |\n| `Checkbox` | Single boolean | Standard checkbox |\n| `Checkboxes` | Multiple selections | Multi-select checkboxes |\n| `Radio` | Single from multiple | Radio button group |\n| `Select` | Dropdown selection | Standard select dropdown |\n| `Autocomplete` | Searchable dropdown | Type-ahead autocomplete |\n| `Date` | Date input | Date picker |\n| `DateTime` | Date + time input | Combined date/time picker |\n| `Time` | Time input | Time picker |\n| `DateRange` | Date range selection | Two-date range picker |\n| `DateTimeRange` | Date/time range | Combined range picker |\n| `MaskedInput` | Formatted input | Phone, SSN, etc. |\n\n**Using widgets in UI Schema:**\n\n```tsx\nconst uiSchema = {\n  email: { 'ui:widget': 'email' },\n  password: { 'ui:widget': 'password' },\n  comments: { 'ui:widget': 'textarea' },\n  birthDate: { 'ui:widget': 'date' },\n  agreedToTerms: { 'ui:widget': 'toggle' },\n  phone: {\n    'ui:widget': 'maskedInput',\n    'ui:options': {\n      mask: '(999) 999-9999',\n    },\n  },\n};\n```\n\n## Advanced Features\n\n### 1. Dynamic Options (Autocomplete/Select)\n\nFetch options dynamically from an API based on form data. Supports caching, debouncing, and variable interpolation.\n\n**In UI Schema:**\n\n```tsx\nconst uiSchema = {\n  country: { 'ui:widget': 'select' },\n  city: {\n    'ui:widget': 'select',\n    'ui:options': {\n      apiConfig: {\n        url: '/api/cities?country={{country}}',  // Interpolate form data\n        method: 'GET',\n        resultPath: 'data',           // Path to options array in response\n        labelKey: 'name',             // Property to display\n        valueKey: 'id',               // Property to use as value\n        triggerOnLoad: false,         // Fetch on component load\n        triggerOnInteraction: true,   // Fetch on user interaction\n        cache: true,                  // Cache results\n        debounce: 300,                // Debounce delay in ms\n      },\n    },\n  },\n};\n```\n\n**Hook Usage:**\n\n```tsx\nimport { useDynamicOptions } from '@00rez/form-runner';\n\nfunction MyComponent() {\n  const [options, setOptions] = React.useState([]);\n  const { options: dynamicOptions } = useDynamicOptions(\n    apiConfig,\n    options,\n    formData\n  );\n  return <select>{/* render options */}</select>;\n}\n```\n\n### 2. Event Callbacks\n\nTrigger custom logic on field events: `onLoad`, `onFocus`, `onChange`, `onBlur`.\n\n**Define a callback registry:**\n\n```tsx\nconst callbackRegistry = {\n  async fetchUserData(context) {\n    const { fieldId, currentValue, formData } = context;\n    const response = await fetch(`/api/users/${currentValue}`);\n    return response.json();\n  },\n  \n  formatPhoneNumber(context) {\n    const { currentValue } = context;\n    return currentValue.replace(/(\\d{3})(\\d{3})(\\d{4})/, '($1) $2-$3');\n  },\n};\n```\n\n**In UI Schema:**\n\n```tsx\nconst uiSchema = {\n  userId: {\n    'ui:options': {\n      eventConfig: {\n        onChange: 'fetchUserData',    // Call by name from registry\n        onBlur: (context) => {        // Or use inline function\n          console.log('User left field:', context.fieldId);\n        },\n      },\n    },\n  },\n  phone: {\n    'ui:options': {\n      eventConfig: {\n        onChange: 'formatPhoneNumber',\n      },\n    },\n  },\n};\n```\n\n**Hook Usage:**\n\n```tsx\nimport { useFieldEvents } from '@00rez/form-runner';\n\nfunction MyField() {\n  const { triggerEvent } = useFieldEvents(\n    'fieldId',\n    'fieldName',\n    currentValue,\n    formData,\n    schema,\n    eventConfig,\n    callbackRegistry\n  );\n\n  return (\n    <input\n      onChange={async (e) => {\n        const result = await triggerEvent('onChange', e.target.value);\n        // Use result...\n      }}\n    />\n  );\n}\n```\n\n**Context Object Available to Callbacks:**\n\n```typescript\ninterface FieldEventContext {\n  fieldId: string;           // Unique field identifier\n  fieldName: string;         // Field name/path\n  currentValue: any;         // Current field value\n  formData: any;             // Entire form data\n  schema: RJSFSchema;        // Field's JSON Schema\n  formContext?: any;         // Custom context passed to form\n}\n```\n\n### 3. Conditional Logic\n\nShow, hide, or require fields based on conditions using JSON Schema `if/then/else`.\n\n**In FormBuilderElement (builder format):**\n\n```tsx\nconst element = {\n  id: 'fieldB',\n  logic: {\n    field: 'fieldA',\n    operator: 'eq',\n    value: 'yes',\n    action: 'show',  // 'show', 'hide', or 'require'\n  },\n};\n```\n\n**Supported Operators:**\n- `eq` - equals\n- `neq` - not equals\n- `gt` - greater than\n- `lt` - less than\n- `gte` - greater than or equal\n- `lte` - less than or equal\n- `contains` - string contains\n\nThe logic is compiled into the JSON Schema's `allOf` with `if/then/else` blocks.\n\n### 4. Custom Error Transformation\n\nTransform validation errors for better UX or to filter out specific errors.\n\n```tsx\nimport { transformErrors } from '@00rez/form-runner';\n\nconst customTransformer = (errors) => {\n  return errors\n    .filter(err => err.property !== 'dynamicField')  // Hide certain fields\n    .map(err => ({\n      ...err,\n      message: `Custom: ${err.message}`,\n    }));\n};\n\n<Form\n  {...props}\n  transformErrors={customTransformer}\n/>\n```\n\n## Types & Interfaces\n\n### FormBuilderElement\n\nInternal representation for form structure (used by form builder):\n\n```typescript\ninterface FormBuilderElement {\n  id: string;                    // Unique identifier\n  label: string;                 // Display label\n  description?: string;          // Help text\n  placeholder?: string;          // Input placeholder\n  required?: boolean;            // Required field\n  icon: IconName;                // Icon identifier\n  category: 'input' | 'layout';  // Element category\n  isContainer?: boolean;         // Can contain children (layouts)\n  elements?: FormBuilderElement[]; // Nested children\n  schema: RJSFSchema;            // JSON Schema\n  uiSchema: UiSchema;            // UI Schema\n  logic?: LogicCondition;        // Conditional visibility\n}\n```\n\n### LogicCondition\n\n```typescript\ninterface LogicCondition {\n  field: string;                // Reference field ID\n  operator: 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'contains';\n  value: any;                   // Value to compare\n  action: 'show' | 'hide' | 'require'; // Action to take\n}\n```\n\n### ApiConfig\n\n```typescript\ninterface ApiConfig {\n  url: string;                    // API endpoint (supports {{variable}} interpolation)\n  method: 'GET' | 'POST';         // HTTP method\n  headers?: Record<string, string>; // Custom headers\n  body?: string;                  // Request body template\n  resultPath?: string;            // Path to options in response (e.g., 'data.items')\n  labelKey?: string;              // Property name for display label\n  valueKey?: string;              // Property name for value\n  triggerOnLoad?: boolean;        // Fetch when component loads\n  triggerOnInteraction?: boolean; // Fetch on user interaction\n  cache?: boolean;                // Cache results\n  debounce?: number;              // Debounce delay (ms)\n}\n```\n\n### FieldEventConfig\n\n```typescript\ninterface FieldEventConfig {\n  onLoad?: string | FieldEventCallback;   // Called when field mounts\n  onFocus?: string | FieldEventCallback;  // Called on focus\n  onChange?: string | FieldEventCallback; // Called on value change\n  onBlur?: string | FieldEventCallback;   // Called on blur\n}\n\ntype FieldEventCallback = (context: FieldEventContext) => Promise<any> | any;\n```\n\n### EventCallbackRegistry\n\n```typescript\ninterface EventCallbackRegistry {\n  [callbackName: string]: FieldEventCallback;\n}\n```\n\n## Utility Functions\n\n### normalizeId\n\nSanitize field IDs by removing special characters:\n\n```tsx\nimport { normalizeId } from '@00rez/form-runner';\n\nconst id = normalizeId('My Field!@#$%'); // 'MyField'\n```\n\n### transformErrors\n\nPre-built error transformer for common use cases:\n\n```tsx\nimport { transformErrors } from '@00rez/form-runner';\n\nconst errors = transformErrors(rawErrors, schema, uiSchema);\n```\n\n### Interpolation Utilities\n\nThe library provides utilities for dynamic text interpolation with support for multiple interpolation styles:\n\n#### interpolate\n\nThe original interpolation function supporting `{{key}}` patterns for language dictionaries and `[[key]]` patterns for global data:\n\n```tsx\nimport { interpolate } from '@00rez/form-runner';\n\n// Replace {{key}} with language data and [[key]] with global data\nconst result = interpolate(\n  { label: 'Hello {{name}}', value: '[[globalVar]]' },\n  { name: 'John' },           // Language/data dictionary\n  { globalVar: 'Global!' }    // Global data (optional)\n);\n// Result: { label: 'Hello John', value: 'Global!' }\n```\n\n#### interpolateWithI18next\n\nA string-focused function with i18next-compatible format. Supports `{{variable}}` patterns with fallback to global data:\n\n```tsx\nimport { interpolateWithI18next } from '@00rez/form-runner';\n\nconst result = interpolateWithI18next(\n  'Hello {{name}}, you have {{count}} messages',\n  { name: 'John', count: 5 },\n  { count: 10 }  // Fallback global data (optional)\n);\n// Result: 'Hello John, you have 5 messages'\n```\n\n**Features:**\n- Supports nested object access with dot notation: `{{user.profile.name}}`\n- Returns numeric values as strings\n- Falls back to `globalData` if value not found in primary values\n- Returns unmatched patterns unchanged\n\n#### interpolateObjectWithI18next\n\nRecursively interpolates all strings in objects and arrays using i18next format:\n\n```tsx\nimport { interpolateObjectWithI18next } from '@00rez/form-runner';\n\nconst schema = {\n  title: 'Welcome {{userName}}',\n  properties: {\n    message: { type: 'string', title: 'Message: {{itemCount}} items' },\n  },\n};\n\nconst result = interpolateObjectWithI18next(\n  schema,\n  { userName: 'Alice', itemCount: 42 }\n);\n// Result: { title: 'Welcome Alice', properties: { message: { ... title: 'Message: 42 items' } } }\n```\n\n**Use cases:**\n- Interpolating entire form schemas\n- Dynamic form configuration with i18next\n- Maintaining structure while replacing text values\n\n## Custom Validation\n\nUse the validator's composition to add custom keywords:\n\n```tsx\nimport { createValidator } from '@rjsf/validator-ajv8';\n\nconst validator = createValidator();\n\n// Add custom validation keyword\nvalidator.ajv.addKeyword({\n  keyword: 'customKeyword',\n  compile: (value) => {\n    return (data) => value ? data > 10 : true;\n  },\n});\n```\n\n## Styling\n\nThe component uses **Tailwind CSS** for styling. Ensure Tailwind is installed and configured in your project:\n\n```bash\nnpm install -D tailwindcss postcss autoprefixer\nnpx tailwindcss init -p\n```\n\nInclude styles in your app:\n\n```tsx\nimport '@00rez/form-runner/form-runner.css';\n```\n\n## Examples\n\n### Complete Form with All Features\n\n```tsx\nimport React, { useState } from 'react';\nimport { Form, EventCallbackRegistry } from '@00rez/form-runner';\nimport { createValidator } from '@rjsf/validator-ajv8';\n\nconst schema = {\n  type: 'object',\n  properties: {\n    country: {\n      type: 'string',\n      title: 'Country',\n      enum: ['US', 'Canada', 'UK'],\n    },\n    city: {\n      type: 'string',\n      title: 'City',\n    },\n    productType: {\n      type: 'string',\n      title: 'Product Type',\n    },\n    message: {\n      type: 'string',\n      title: 'Additional Info',\n    },\n    agreeToTerms: {\n      type: 'boolean',\n      title: 'I agree to terms',\n    },\n  },\n  required: ['country', 'city'],\n};\n\nconst uiSchema = {\n  country: {\n    'ui:widget': 'select',\n  },\n  city: {\n    'ui:widget': 'select',\n    'ui:options': {\n      apiConfig: {\n        url: '/api/cities?country={{country}}',\n        resultPath: 'cities',\n        labelKey: 'name',\n        valueKey: 'id',\n        cache: true,\n        debounce: 300,\n      },\n    },\n  },\n  productType: {\n    'ui:widget': 'select',\n    'ui:options': {\n      apiConfig: {\n        url: '/api/products?city={{city}}',\n        resultPath: 'products',\n        labelKey: 'name',\n        valueKey: 'id',\n      },\n      eventConfig: {\n        onChange: 'logSelection',\n      },\n    },\n  },\n  message: {\n    'ui:widget': 'textarea',\n  },\n  agreeToTerms: {\n    'ui:widget': 'toggle',\n  },\n};\n\nconst callbackRegistry: EventCallbackRegistry = {\n  async logSelection(context) {\n    console.log('Selected:', context.currentValue);\n  },\n};\n\nexport default function App() {\n  const [data, setData] = useState({});\n  const [submitted, setSubmitted] = useState(null);\n  const validator = createValidator();\n\n  return (\n    <div className=\"p-8 max-w-2xl mx-auto\">\n      <h1 className=\"text-2xl font-bold mb-6\">My Form</h1>\n      {submitted ? (\n        <div className=\"p-4 bg-green-50 border border-green-200 rounded\">\n          <p className=\"font-semibold\">Submitted successfully!</p>\n          <pre className=\"mt-2 text-sm\">{JSON.stringify(submitted, null, 2)}</pre>\n          <button\n            onClick={() => setSubmitted(null)}\n            className=\"mt-4 px-4 py-2 bg-blue-600 text-white rounded\"\n          >\n            Edit\n          </button>\n        </div>\n      ) : (\n        <Form\n          schema={schema}\n          uiSchema={uiSchema}\n          formData={data}\n          validator={validator}\n          onChange={(e) => setData(e.formData)}\n          onSubmit={(e) => setSubmitted(e.formData)}\n          callbackRegistry={callbackRegistry}\n        />\n      )}\n    </div>\n  );\n}\n```\n\n## Troubleshooting\n\n### Form doesn't render\n\n- Ensure `schema`, `uiSchema`, and `validator` are provided\n- Check browser console for validation errors\n- Verify schema is valid JSON Schema format\n\n### Dynamic options not loading\n\n- Check network tab for API requests\n- Verify URL interpolation with correct field names: `{{fieldName}}`\n- Ensure `resultPath` matches your API response structure\n- Check `labelKey` and `valueKey` match actual data properties\n\n### Callbacks not firing\n\n- Register callbacks in `callbackRegistry` by exact name\n- Check `eventConfig` has correct callback name or function\n- Verify field has focus/change event listeners\n- Check browser console for callback execution\n\n### Styling issues\n\n- Ensure Tailwind CSS is properly configured\n- Import styles: `import '@00rez/form-runner/styles.css'`\n- Check conflicting CSS specificity\n\n## Contributing\n\nn/a\n\n## License\n\nMIT\n","readmeFilename":"README.md"}