{"_id":"@anri1214/dynamic-forms-mui","_rev":"9-98ca1b9c64058d3eaa236e3fff80c260","name":"@anri1214/dynamic-forms-mui","dist-tags":{"latest":"0.1.14"},"versions":{"0.1.7":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.7","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"license":"MIT","_id":"@anri1214/dynamic-forms-mui@0.1.7","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"}],"dist":{"shasum":"68a8746521ba4add8a2f08646f0fe11fec4611fb","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.7.tgz","fileCount":6,"integrity":"sha512-H88vIyoxL8bTVO85dUMv67Dd3leQ622hAB+wS2YSraxPyndYnhX9Ooa8zHn7JoRHe8ldVU91Qd4J58VjPrHd8g==","signatures":[{"sig":"MEUCIQDr4cD0p6/XR0ihuaPCjBvHxHBZMEh/AzIKCVL/OIIJsAIgAebc/+zQ3aRanlFPecKMF+ikGaJNchR58XKWDx6bPAc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123441},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"db7e2a22babcc82d12e7ad35ed0ef2d6201341fe","scripts":{"dev":"vite build --watch","build":"vite build"},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"_npmVersion":"10.8.2","description":"Type-safe declarative form builder for React with MUI","directories":{},"_nodeVersion":"20.20.2","dependencies":{"date-fns":"^4.1.0","@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.7","typescript":"~5.9.3","@types/node":"^24.0.0","@types/react":"^19.1.16","vite-plugin-dts":"^4.0.0","@types/react-dom":"^19.1.9"},"peerDependencies":{"zod":"^4.0.0","react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@base-ui/react":"^1.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","@mui/icons-material":"^7.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dynamic-forms-mui_0.1.7_1778511323368_0.40053510307927964","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.8","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"license":"MIT","_id":"@anri1214/dynamic-forms-mui@0.1.8","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"}],"dist":{"shasum":"becff0313c5b95e3681865037173d0bb4fd49409","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.8.tgz","fileCount":6,"integrity":"sha512-c48bbzIDQEuTOS5T17MIJb0+M5IhO72sDTvXQWprBRRz2YZnFexvvg+0YOWDxKRyHQwOYk9itkuYBIMRrhadDg==","signatures":[{"sig":"MEYCIQDnYxGAffgixfAobPzjJn6lFoHpIDMyk3ZX9UuoFn2x8AIhAJGKbhrt/VJF9g8kubO9x0s4R6+8UW6FJImW3VehFJdh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123467},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"ea4186dab1b7502f571d79c39174f44f3f5a25fe","scripts":{"dev":"vite build --watch","build":"vite build"},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"_npmVersion":"10.8.2","description":"Type-safe declarative form builder for React with MUI","directories":{},"_nodeVersion":"20.20.2","dependencies":{"date-fns":"^4.1.0","@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.7","typescript":"~5.9.3","@types/node":"^24.0.0","@types/react":"^19.1.16","vite-plugin-dts":"^4.0.0","@types/react-dom":"^19.1.9"},"peerDependencies":{"zod":"^4.0.0","react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@base-ui/react":"^1.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","@mui/icons-material":"^7.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dynamic-forms-mui_0.1.8_1778660564680_0.3862775532522038","host":"s3://npm-registry-packages-npm-production"}},"0.1.9":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.9","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"license":"MIT","_id":"@anri1214/dynamic-forms-mui@0.1.9","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"}],"dist":{"shasum":"a0a89729c2311eb792a3cb47fa8a8567ea7e5aaf","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.9.tgz","fileCount":6,"integrity":"sha512-4BUgRFu4xNh3ZvKbiZCizlBCwtZ63+IXmt+DHdfVfmoKcVZo6RM0JVcLjpeUosrZ14WJsfH8jXiyICRXZLOjfQ==","signatures":[{"sig":"MEUCIB46Z6PHH7pYWlpmO1GPA+W615pfqbBXV0RIRBob5NtQAiEAv7TBsTAf7VEvxIKIumpqTv21C8w9C/Z/J/K4AyFrvfk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123494},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"93cf0419b8ee5623789a263a052256de917e320f","scripts":{"dev":"vite build --watch","build":"vite build"},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"_npmVersion":"10.8.2","description":"Type-safe declarative form builder for React with MUI","directories":{},"_nodeVersion":"20.20.2","dependencies":{"date-fns":"^4.1.0","@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.7","typescript":"~5.9.3","@types/node":"^24.0.0","@types/react":"^19.1.16","vite-plugin-dts":"^4.0.0","@types/react-dom":"^19.1.9"},"peerDependencies":{"zod":"^4.0.0","react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@base-ui/react":"^1.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","@mui/icons-material":"^7.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dynamic-forms-mui_0.1.9_1778661620065_0.38074650928862663","host":"s3://npm-registry-packages-npm-production"}},"0.1.10":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.10","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"license":"MIT","_id":"@anri1214/dynamic-forms-mui@0.1.10","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"}],"dist":{"shasum":"97a7cb1f47bc23f9d3aa79017ba2941d91d3cbad","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.10.tgz","fileCount":6,"integrity":"sha512-ovC5B8XKHVV06EZsfSKvyxAhZEh8J+luB1bSsDxb3/NRcq4pfC8E0rBLhPdobBmnUBJss9GtRAjXm77vU1ySTQ==","signatures":[{"sig":"MEUCIQCX6bxu+zsgTON0g1i3mkGiYOaWeVE47xENbMosoOUoFAIgSIGmGZauyPspHs/i2Am/zECtJhkZ8Bc5OBjx1Z9krLI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":124393},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"d9051a2f207d226682ee4038e8e75cf03ca83efe","scripts":{"dev":"vite build --watch","build":"vite build"},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"_npmVersion":"10.9.3","description":"Type-safe declarative form builder for React with MUI","directories":{},"_nodeVersion":"22.20.0","dependencies":{"date-fns":"^4.1.0","@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.7","typescript":"~5.9.3","@types/node":"^24.0.0","@types/react":"^19.1.16","vite-plugin-dts":"^4.0.0","@types/react-dom":"^19.1.9"},"peerDependencies":{"zod":"^4.0.0","react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@base-ui/react":"^1.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","@mui/icons-material":"^7.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dynamic-forms-mui_0.1.10_1779797141712_0.18061116067266392","host":"s3://npm-registry-packages-npm-production"}},"0.1.11":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.11","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"license":"MIT","_id":"@anri1214/dynamic-forms-mui@0.1.11","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"}],"dist":{"shasum":"63604462ca2dcda7fa01a76968c9ecdb314f510f","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.11.tgz","fileCount":6,"integrity":"sha512-WI7Ad7GIJmKlLLRCMrUUs3yRrxz/1bqT5iGrUaqzyKYl/awLJ5jV9F+RxYO/uk21JILjOum3P9pext01ZJHaWw==","signatures":[{"sig":"MEUCIQCdC+3bTTkWwbKXu9c0SEzRZfGxyNLxqvq99NnNmBCsjgIgBrTtdX1yb4CRwcaLTl73p1ZGZrVXXckNOI1sPlC7ai8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":125360},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"36eaed58af188007c52b42c0a00ed93c563bbad1","scripts":{"dev":"vite build --watch","build":"vite build"},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"_npmVersion":"10.8.2","description":"Type-safe declarative form builder for React with MUI","directories":{},"_nodeVersion":"20.20.2","dependencies":{"date-fns":"^4.1.0","@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.7","typescript":"~5.9.3","@types/node":"^24.0.0","@types/react":"^19.1.16","vite-plugin-dts":"^4.0.0","@types/react-dom":"^19.1.9"},"peerDependencies":{"zod":"^4.0.0","react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@base-ui/react":"^1.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","@mui/icons-material":"^7.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dynamic-forms-mui_0.1.11_1785770057772_0.3901964886303999","host":"s3://npm-registry-packages-npm-production"}},"0.1.12":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.12","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"license":"MIT","_id":"@anri1214/dynamic-forms-mui@0.1.12","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"}],"dist":{"shasum":"a665c044e4a01629e7f5e5e00b4f6482631049df","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.12.tgz","fileCount":6,"integrity":"sha512-tV92zHUpONkXoo7ir7J2KspIk8TsmY5Kxxt3tvF09ioG6WukdvBVXb2N4VDC+sFfGQG7oTvi3VG1hTBfDr6N+g==","signatures":[{"sig":"MEQCIAVhXI++2xyTTaP79dXh/xKI1eI8zlQEnkziFUSFkBRjAiAEj+DexE2IotTlv/7sa32L6HJlAxm2odmGjlV3gNA+Xw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":127677},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"b600dd94fb7c38611a59143c133072c43ceb5b99","scripts":{"dev":"vite build --watch","build":"vite build"},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"_npmVersion":"10.8.2","description":"Type-safe declarative form builder for React with MUI","directories":{},"_nodeVersion":"20.20.2","dependencies":{"date-fns":"^4.1.0","@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.7","typescript":"~5.9.3","@types/node":"^24.0.0","@types/react":"^19.1.16","vite-plugin-dts":"^4.0.0","@types/react-dom":"^19.1.9"},"peerDependencies":{"zod":"^4.0.0","react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@base-ui/react":"^1.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","@mui/icons-material":"^7.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dynamic-forms-mui_0.1.12_1787243009832_0.3268634364579419","host":"s3://npm-registry-packages-npm-production"}},"0.1.13":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.13","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"license":"MIT","_id":"@anri1214/dynamic-forms-mui@0.1.13","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"}],"dist":{"shasum":"4f738c2cc1c9493147c9393999b0a5e447c8f850","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.13.tgz","fileCount":6,"integrity":"sha512-pdwb4ioNVkhA0obk8+CjvcTVECIJMSxtxjTAkdLCM9UuZz1PfNbpECty7suKZ3n/mPc2/aSF3nmG52VZX4Yrww==","signatures":[{"sig":"MEUCIQCZRP9DP8DVTQGwumv73QCBogt7Umgn23eo23hmPxB1bwIgNnLqviy6r+CNH9ZSUnHE3cwqQ/7DpuMgw4ejuA94y0s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128188},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"c2293fb5575f4f26a23d09c641c2182e680b3550","scripts":{"dev":"vite build --watch","build":"vite build"},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"_npmVersion":"10.8.2","description":"Type-safe declarative form builder for React with MUI","directories":{},"_nodeVersion":"20.20.2","dependencies":{"date-fns":"^4.1.0","@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.7","typescript":"~5.9.3","@types/node":"^24.0.0","@types/react":"^19.1.16","vite-plugin-dts":"^4.0.0","@types/react-dom":"^19.1.9"},"peerDependencies":{"zod":"^4.0.0","react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@base-ui/react":"^1.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","@mui/icons-material":"^7.0.0","@tanstack/react-query":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dynamic-forms-mui_0.1.13_1787848649663_0.19047878089660775","host":"s3://npm-registry-packages-npm-production"}},"0.1.14":{"name":"@anri1214/dynamic-forms-mui","version":"0.1.14","description":"Type-safe declarative form builder for React with MUI","license":"MIT","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","@mui/material":"^7.0.0","@mui/icons-material":"^7.0.0","@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","react-hook-form":"^7.70.0","zod":"^4.0.0","@tanstack/react-query":"^5.0.0","@base-ui/react":"^1.0.0"},"dependencies":{"@hookform/resolvers":"^5.2.2","@mui/x-date-pickers":"^8.26.0","date-fns":"^4.1.0"},"devDependencies":{"@types/react":"^19.1.16","@types/react-dom":"^19.1.9","typescript":"~5.9.3","vite":"^7.1.7","@types/node":"^24.0.0","vite-plugin-dts":"^4.0.0"},"scripts":{"build":"vite build","dev":"vite build --watch"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_id":"@anri1214/dynamic-forms-mui@0.1.14","gitHead":"729c8b709fdf6cda7442c4c35055e79da9366a5f","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-vvTyh6OTSz3wrBl9U+z5+Qkmzb/THVr6YzHWsbXTOjOX3EKlST2n/S14bs9NcU/CmZPGuyB8EhfRRKEE+NPkow==","shasum":"a1acb4b6d081962a2188efd5c12f5360fa817b48","tarball":"https://registry.npmjs.org/@anri1214/dynamic-forms-mui/-/dynamic-forms-mui-0.1.14.tgz","fileCount":6,"unpackedSize":128621,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAsWmZg1pLK0v0uwuiwK3BbkAtVoMFP4V4zj3U+SqYYSAiBxVsZaWNPaMOaj/eNRE3lnaLcmFp/RT9XjGA/I1lUkZQ=="}]},"_npmUser":{"name":"anri1214","email":"anri1214.k@gmail.com"},"directories":{},"maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"},{"name":"yevhenii.kolomiiets","email":"yevheniikolomiiets@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dynamic-forms-mui_0.1.14_1787907426173_0.40355173833606606"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-11T14:55:23.296Z","modified":"2026-08-28T08:57:06.472Z","0.1.7":"2026-05-11T14:55:23.525Z","0.1.8":"2026-05-13T08:22:44.838Z","0.1.9":"2026-05-13T08:40:20.193Z","0.1.10":"2026-05-26T12:05:41.868Z","0.1.11":"2026-08-03T15:14:17.921Z","0.1.12":"2026-08-20T16:23:29.989Z","0.1.13":"2026-08-27T16:37:29.807Z","0.1.14":"2026-08-28T08:57:06.310Z"},"license":"MIT","keywords":["react","forms","dynamic-forms","mui","material-ui","json-schema","form-builder","react-hook-form","zod","typescript"],"description":"Type-safe declarative form builder for React with MUI","maintainers":[{"name":"anri1214","email":"anri1214.k@gmail.com"},{"name":"yevhenii.kolomiiets","email":"yevheniikolomiiets@gmail.com"}],"readme":"# @anri1214/dynamic-forms-mui\n\nType-safe declarative form builder for React with Material-UI.\n\nDefine your forms with a JSON schema — get fully validated, accessible MUI forms with zero boilerplate.\n\n## Features\n\n- **JSON-driven forms** — describe fields, sections, and validation in a single schema object\n- **15 built-in field types** — text, email, password, textarea, number, select, multiselect, autocomplete, checkbox, switch, radio, date, date-range, file upload\n- **Dynamic validation** — Zod schemas generated at runtime from your config; async validation supported\n- **Conditional visibility** — show/hide fields based on other field values\n- **Dynamic options** — load select/radio/autocomplete options from an API with dependency support\n- **Async search** — autocomplete fields with server-side search via `dependsOnInput`\n- **Customizable section styles** — override spacing and styles per section slot via `sectionSlotProps`\n- **Fully customizable UI** — replace any or all default MUI components via Context\n- **API client injection** — bring your own HTTP client (Axios, fetch, etc.)\n- **Type-safe** — full TypeScript coverage for schemas, fields, and components\n\n## Installation\n\n```bash\nnpm install @anri1214/dynamic-forms-mui\n```\n\n### Peer Dependencies\n\n```bash\nnpm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styled react-hook-form zod @tanstack/react-query @base-ui/react\n```\n\n## Quick Start\n\n### 1. Wrap your app with `DynamicFormsProvider`\n\n```tsx\nimport { DynamicFormsProvider } from '@anri1214/dynamic-forms-mui'\nimport type { ApiClient } from '@anri1214/dynamic-forms-mui'\n\n// Adapt your HTTP client to the ApiClient interface\nconst apiClient: ApiClient = {\n  get: (url, config) => fetch(url).then((r) => r.json()),\n}\n\nfunction App() {\n  return (\n    <DynamicFormsProvider\n      apiClient={apiClient}\n      onError={(msg) => console.error(msg)}\n    >\n      {/* your app */}\n    </DynamicFormsProvider>\n  )\n}\n```\n\n### 2. Define a form schema\n\n```tsx\nimport type { FormSchema } from '@anri1214/dynamic-forms-mui'\n\nconst schema: FormSchema = {\n  sections: [\n    {\n      id: 'contact',\n      title: 'Contact Info',\n      fields: ['name', 'email'],\n    },\n  ],\n  fields: {\n    name: {\n      type: 'text',\n      label: 'Full Name',\n      placeholder: 'John Doe',\n      validation: { required: true, minLength: 2 },\n    },\n    email: {\n      type: 'email',\n      label: 'Email',\n      validation: { required: true },\n    },\n  },\n}\n```\n\n### 3. Render the form\n\n```tsx\nimport { DynamicForm } from '@anri1214/dynamic-forms-mui'\nimport type { LabelMap } from '@anri1214/dynamic-forms-mui'\n\nfunction ContactPage() {\n  const handleSubmit = (data: Record<string, unknown>, labelMap: LabelMap) => {\n    console.log('Form data:', data)\n    console.log('Labels:', labelMap) // { country: { 'US': 'United States', ... }, ... }\n  }\n\n  return (\n    <DynamicForm schema={schema} onSubmit={handleSubmit}>\n      {({ isValid, isSubmitting }) => (\n        <button type=\"submit\" disabled={!isValid || isSubmitting}>\n          Submit\n        </button>\n      )}\n    </DynamicForm>\n  )\n}\n```\n\n## Field Types\n\n| Type | Config Interface | Description |\n|------|-----------------|-------------|\n| `text` | `TextFieldConfig` | Standard text input |\n| `email` | `TextFieldConfig` | Email input with format validation |\n| `password` | `TextFieldConfig` | Password input |\n| `textarea` | `TextFieldConfig` | Multi-line text input |\n| `number` | `NumberFieldConfig` | Numeric input with min/max/step |\n| `select` | `SelectFieldConfig` | Single-value dropdown |\n| `multiselect` | `SelectFieldConfig` | Multi-value dropdown with chips |\n| `autocomplete` | `AutocompleteFieldConfig` | Single-value autocomplete with async search |\n| `checkbox` | `CheckboxFieldConfig` | Boolean checkbox |\n| `switch` | `CheckboxFieldConfig` | Toggle switch |\n| `radio` | `RadioFieldConfig` | Radio button group |\n| `date` | `DateFieldConfig` | Date picker |\n| `dateRange` | `DateFieldConfig` | Date range picker |\n| `file` | `FileFieldConfig` | File upload |\n\n## Validation\n\nValidation rules are defined per-field in the `validation` property:\n\n```ts\nvalidation: {\n  required: true,\n  minLength: 2,\n  maxLength: 100,\n  pattern: '^[a-zA-Z]+$',\n  patternMessage: 'Only letters allowed',\n\n  // Async validation (e.g. check username availability)\n  asyncValidation: {\n    apiUrl: '/api/check-username',\n    debounceMs: 500,\n    message: 'Username is already taken',\n  },\n}\n```\n\n## Conditional Fields\n\nShow or hide fields based on other values:\n\n```ts\nfields: {\n  hasCompany: {\n    type: 'checkbox',\n    label: 'I have a company',\n  },\n  companyName: {\n    type: 'text',\n    label: 'Company Name',\n    showIf: { field: 'hasCompany', operator: 'equals', value: true },\n  },\n}\n```\n\nSupported operators: `equals`, `notEquals`, `in`, `notIn`, `isEmpty`, `isNotEmpty`, `gt`, `gte`, `lt`, `lte`. Conditions can be combined with `and` / `or`.\n\n## Dynamic Options\n\nLoad select/radio/autocomplete options from an API:\n\n```ts\ncountry: {\n  type: 'select',\n  label: 'Country',\n  optionsSource: {\n    apiUrl: '/api/countries',\n    valueKey: 'code',\n    labelKey: 'name',\n  },\n},\ncity: {\n  type: 'select',\n  label: 'City',\n  optionsSource: {\n    apiUrl: '/api/cities',\n    queryParams: [{ key: 'country', dependsOn: 'country' }],\n    valueKey: 'id',\n    labelKey: 'name',\n  },\n},\n```\n\nWhen `country` changes, `city` options reload automatically.\n\n### Async Search (Autocomplete)\n\nUse `dependsOnInput` in `queryParams` to send the user's typed text as a search query:\n\n```ts\ncustomer: {\n  type: 'autocomplete',\n  label: 'Customer',\n  optionsSource: {\n    apiUrl: '/api/customers',\n    queryParams: [{ key: 'search', dependsOnInput: true }],\n    valueKey: 'id',\n    labelKey: 'name',\n  },\n},\n```\n\nThe input is debounced (300ms) before triggering the API call.\n\n### Pre-selected Options (`initialOptions`)\n\nWhen editing a form with pre-existing values, the API options may not have loaded yet. Use `initialOptions` to display the current selection immediately:\n\n```ts\ncompanies: {\n  type: 'multiselect',\n  label: 'Companies',\n  optionsSource: { apiUrl: '/api/companies', valueKey: 'id', labelKey: 'name' },\n  initialOptions: [\n    { value: '1', label: 'Acme Corp' },\n    { value: '2', label: 'Globex' },\n  ],\n},\n```\n\n`initialOptions` are merged with API results — duplicates are deduplicated automatically.\n\n## Customizing UI Components\n\nReplace any default MUI component with your own:\n\n```tsx\nimport { DynamicFormsProvider } from '@anri1214/dynamic-forms-mui'\nimport type { DFTextFieldProps } from '@anri1214/dynamic-forms-mui'\n\nfunction MyTextField(props: DFTextFieldProps) {\n  return <input className=\"my-input\" {...props} />\n}\n\n<DynamicFormsProvider\n  apiClient={apiClient}\n  components={{ TextField: MyTextField }}\n>\n  {/* Only TextField is replaced; the other 9 stay default */}\n</DynamicFormsProvider>\n```\n\n### Overridable Components\n\n`TextField` · `NumberField` · `Select` · `Autocomplete` · `Checkbox` · `Switch` · `RadioGroup` · `DatePicker` · `DateRangePicker` · `FileUpload`\n\n## Section Styling (`sectionSlotProps`)\n\nCustomize spacing and styles for section elements via `sectionSlotProps`. Can be set globally via the provider or per-form (form-level merges on top of provider-level):\n\n```tsx\n// Global defaults for all forms\n<DynamicFormsProvider\n  apiClient={apiClient}\n  sectionSlotProps={{\n    root: { sx: { mb: 2 } },\n    content: { sx: { gap: 1 } },\n  }}\n>\n  {/* Per-form override — merges with provider defaults */}\n  <DynamicForm\n    schema={schema}\n    onSubmit={handleSubmit}\n    sectionSlotProps={{\n      title: { sx: { mb: 1, fontSize: '1rem' } },\n      description: { sx: { mb: 1 } },\n    }}\n  >\n    {({ isValid }) => <button type=\"submit\" disabled={!isValid}>Save</button>}\n  </DynamicForm>\n</DynamicFormsProvider>\n```\n\nAvailable slots: `root` (section wrapper), `title` (section heading), `description` (section description), `content` (fields container). Custom `sx` is merged on top of defaults. When both provider and form define the same slot, `sx` values are merged with form-level taking priority.\n\nSection `title` is optional — omit it from the schema to render sections without a heading.\n\n## Component Size\n\nBy default, all form inputs use MUI's `\"medium\"` size. You can set `size` globally via the provider or per-form:\n\n```tsx\n// All forms render with small inputs\n<DynamicFormsProvider apiClient={apiClient} size=\"small\">\n  {/* ... */}\n</DynamicFormsProvider>\n```\n\nPer-form override (takes priority over the provider):\n\n```tsx\n<DynamicForm schema={schema} onSubmit={handleSubmit} size=\"small\" />\n```\n\nSupported values: `\"small\"` | `\"medium\"` (default).\n\n## Per-Form API Client Override\n\nOverride the global `apiClient` for a specific form:\n\n```tsx\n<DynamicForm\n  schema={schema}\n  onSubmit={handleSubmit}\n  apiClient={differentApiClient}\n/>\n```\n\n## Custom Field Types\n\nRegister custom field components for new field types:\n\n```tsx\nimport { registerFieldComponent } from '@anri1214/dynamic-forms-mui'\n\nregisterFieldComponent('rating', MyRatingField)\n```\n\n## Label Map (`onSubmit` second argument)\n\nThe `onSubmit` callback receives a second argument — `labelMap` of type `LabelMap` — a nested record mapping field names to their loaded option labels:\n\n```ts\ntype LabelMap = Record<string, Record<string | number, string>>\n// { [fieldName]: { [optionValue]: optionLabel } }\n```\n\nThis is useful for multi-step forms where you need to display human-readable labels in a review step without making extra API calls:\n\n```tsx\nconst [formData, setFormData] = useState<Record<string, unknown>>({})\nconst [labels, setLabels] = useState<LabelMap>({})\n\nconst handleSubmit = (data: Record<string, unknown>, labelMap: LabelMap) => {\n  setFormData(data)   // { country: 'US', city: '42' }\n  setLabels(labelMap) // { country: { 'US': 'United States', 'UK': 'United Kingdom', ... }, city: { '42': 'New York', ... } }\n}\n\n// In the review step:\nconst countryLabel = labels.country?.[formData.country as string] // \"United States\"\n```\n\nThe label map includes all currently loaded options for fields with `options`, `optionsSource`, or `initialOptions`. Fields without options (text, number, checkbox, etc.) are not included.\n\n## Exports\n\n### Components\n- `DynamicFormsProvider` — context provider (wrap your app)\n- `DynamicForm` — main form renderer\n- `FormErrorBoundary` — error boundary for forms\n\n### Hooks\n- `useDynamicFormsContext()` — access apiClient, components, notifications\n- `useFieldVisibility(schema)` — get visible field set\n- `useOptionsSource(source, staticOptions, initialOptions?)` — load options from API with async search support\n- `useAsyncValidation(fieldName, config)` — debounced async validation\n\n### Utils\n- `buildZodSchema` — generate Zod schema from FormSchema\n- `evaluateCondition` — evaluate showIf conditions\n- `extractDefaultValues` — extract defaults from schema\n- `registerFieldComponent` — register custom field types\n\n### Types\n- `FormSchema`, `Section`, `FieldConfig`, `FieldType`, `FormMode`, `SectionSlotProps`\n- `AutocompleteFieldConfig`, `SelectFieldConfig`, `TextFieldConfig`, etc.\n- `ApiClient`, `UIComponents`, `NotificationCallbacks`, `ComponentSize`\n- `LabelMap` — nested record of resolved option labels (`Record<fieldName, Record<value, label>>`)\n- `DFTextFieldProps`, `DFAutocompleteProps`, `DFSelectProps`, `DFCheckboxProps`, etc.\n\n## AI Assistant Integration (MCP)\n\nThis library has a companion MCP server — **@anri1214/dynamic-forms-mui-mcp** — that lets AI assistants (Cursor, Claude Code, VS Code Copilot) understand the `FormSchema` structure and help generate correct form configurations.\n\n```bash\nnpx @anri1214/dynamic-forms-mui-mcp\n```\n\nThe MCP server provides:\n- **Schema validation** — validate JSON against the FormSchema spec\n- **Field type docs** — descriptions, props, and examples for all 14 field types\n- **Code generation** — generate FormSchema JSON from natural language\n- **Backend endpoint generation** — produce API endpoints in any language/framework\n- **Version-aware** — serves documentation matching your installed library version\n\nSee [@anri1214/dynamic-forms-mui-mcp README](https://www.npmjs.com/package/@anri1214/dynamic-forms-mui-mcp) for setup instructions.\n\n## License\n\nMIT\n\n","readmeFilename":"README.md"}