{"_id":"@aidanbell/schema-form","_rev":"3-5d8af794e99ffcec7ecb71c0febb6597","name":"@aidanbell/schema-form","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@aidanbell/schema-form","version":"0.1.0","license":"MIT","_id":"@aidanbell/schema-form@0.1.0","maintainers":[{"name":"aidanbell","email":"aidanbell0182@gmail.com"}],"dist":{"shasum":"4e2e0686157dd13fd1ac332ccd230240c3b6623f","tarball":"https://registry.npmjs.org/@aidanbell/schema-form/-/schema-form-0.1.0.tgz","fileCount":9,"integrity":"sha512-1rQ6aoj7bRQpxusUbmvDDo4IVukT88spcQ263tm9zKIpWWDL9lcKv6CnWU1dXyUXUGYuVVxmbeJfqHNCTe1wAA==","signatures":[{"sig":"MEUCIQDUh5ROz7Gm6OcZmoUYXfT+xrtSUXcNOLwOT+NzCm3ieAIgfWK3TtR5l3kBys5TQD9WtOy9716hK5B/SOJGNkN9ZA4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110634},"main":"./dist/index.cjs","type":"module","_from":"file:aidanbell-schema-form-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run --config ../../vitest.config.ts","build":"tsup","typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"aidanbell","email":"aidanbell0182@gmail.com"},"_resolved":"/private/var/folders/xh/wc6pbw7x425c8xbl8smtt5j00000gn/T/69244b9187843dbedad76adbc7835132/aidanbell-schema-form-0.1.0.tgz","_integrity":"sha512-1rQ6aoj7bRQpxusUbmvDDo4IVukT88spcQ263tm9zKIpWWDL9lcKv6CnWU1dXyUXUGYuVVxmbeJfqHNCTe1wAA==","_npmVersion":"10.8.2","description":"Headless schema-driven forms: parse, Valibot validation, and useSchemaForm","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.6","react":"^19.2.8","valibot":"^1.4.2","happy-dom":"^20.11.2","react-dom":"^19.2.8","typescript":"^5.7.3","@types/react":"^19.2.18","react-hook-form":"^7.85.0","@types/react-dom":"^19.2.4","@hookform/resolvers":"^5.7.1","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.2.0","valibot":"^1.4.2","react-dom":">=18.2.0","react-hook-form":"^7.50.0","@hookform/resolvers":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/schema-form_0.1.0_1787147431933_0.05698062226387157","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aidanbell/schema-form","version":"0.1.1","license":"MIT","_id":"@aidanbell/schema-form@0.1.1","maintainers":[{"name":"aidanbell","email":"aidanbell0182@gmail.com"}],"dist":{"shasum":"5287c86b339aa12a7a1ccb103620834b2787a408","tarball":"https://registry.npmjs.org/@aidanbell/schema-form/-/schema-form-0.1.1.tgz","fileCount":9,"integrity":"sha512-HwJDykESwasGyS2UGK30o2ymVAcpvJOk8114yGDxhbEY6xpBvoPin0rFmrMcqLXPZYzENoTfN1Sqb+Ps9yd6/g==","signatures":[{"sig":"MEQCIDtaPGx1svT65FomGXT2zRQdjVfTbzszdhSD2+1FIDcxAiBHnU5gUVoKntS+f1nkxy1Kb8TcYaALhyOQk3HC7knXhg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":116746},"main":"./dist/index.cjs","type":"module","_from":"file:aidanbell-schema-form-0.1.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run --config ../../vitest.config.ts","build":"tsup","typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"aidanbell","email":"aidanbell0182@gmail.com"},"_resolved":"/private/var/folders/xh/wc6pbw7x425c8xbl8smtt5j00000gn/T/790ac36b3d13798e80927e6c96ece796/aidanbell-schema-form-0.1.1.tgz","_integrity":"sha512-HwJDykESwasGyS2UGK30o2ymVAcpvJOk8114yGDxhbEY6xpBvoPin0rFmrMcqLXPZYzENoTfN1Sqb+Ps9yd6/g==","_npmVersion":"10.8.2","description":"Headless schema-driven forms: parse, Valibot validation, and useSchemaForm","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.6","react":"^19.2.8","valibot":"^1.4.2","happy-dom":"^20.11.2","react-dom":"^19.2.8","typescript":"^5.7.3","@types/react":"^19.2.18","react-hook-form":"^7.85.0","@types/react-dom":"^19.2.4","@hookform/resolvers":"^5.7.1","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.2.0","valibot":"^1.4.2","react-dom":">=18.2.0","react-hook-form":"^7.50.0","@hookform/resolvers":">=3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/schema-form_0.1.1_1787163189119_0.7109460971075359","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aidanbell/schema-form","version":"0.2.0","description":"Headless schema-driven forms: parse, Valibot validation, and useSchemaForm","license":"MIT","type":"module","sideEffects":false,"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":{"@hookform/resolvers":">=5.0.1","react":">=18.2.0","react-dom":">=18.2.0","react-hook-form":"^7.50.0","valibot":"^1.4.2"},"devDependencies":{"@hookform/resolvers":"^5.7.1","@testing-library/react":"^16.3.2","@types/react":"^19.2.18","@types/react-dom":"^19.2.4","happy-dom":"^20.11.2","react":"^19.2.8","react-dom":"^19.2.8","react-hook-form":"^7.85.0","tsup":"^8.3.6","typescript":"^5.7.3","valibot":"^1.4.2"},"publishConfig":{"access":"public"},"dependencies":{"@standard-schema/spec":"^1.1.0"},"scripts":{"build":"tsup","typecheck":"tsc --noEmit -p tsconfig.json","test":"vitest run --config ../../vitest.config.ts"},"_id":"@aidanbell/schema-form@0.2.0","_integrity":"sha512-h1ZZ4inZoXDRKExzWREA4Qul136cY8dyL5UMlwnQh9QJmvBvrgFGLfU8SSFryIhbhKX4WM2GI6NXexlXNBlHPA==","_resolved":"/private/var/folders/xh/wc6pbw7x425c8xbl8smtt5j00000gn/T/f6e66c52771af9f3ad9aa632047b1e77/aidanbell-schema-form-0.2.0.tgz","_from":"file:aidanbell-schema-form-0.2.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-h1ZZ4inZoXDRKExzWREA4Qul136cY8dyL5UMlwnQh9QJmvBvrgFGLfU8SSFryIhbhKX4WM2GI6NXexlXNBlHPA==","shasum":"21abf97a439a565a1e97b740e2ac8f11cac01f25","tarball":"https://registry.npmjs.org/@aidanbell/schema-form/-/schema-form-0.2.0.tgz","fileCount":9,"unpackedSize":118941,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD8y5Uk6bxH9cUMFUj0d+UXBsOFIHjgu641P56dvD1RQQIge801vJWMjxFsq+m0Bt8xpCoGxJ1nDUPHRKdoWPr8DT4="}]},"_npmUser":{"name":"aidanbell","email":"aidanbell0182@gmail.com"},"directories":{},"maintainers":[{"name":"aidanbell","email":"aidanbell0182@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/schema-form_0.2.0_1787685228323_0.1306979142495528"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-19T13:50:31.751Z","modified":"2026-08-25T19:13:48.701Z","0.1.0":"2026-08-19T13:50:32.067Z","0.1.1":"2026-08-19T18:13:09.275Z","0.2.0":"2026-08-25T19:13:48.553Z"},"license":"MIT","description":"Headless schema-driven forms: parse, Valibot validation, and useSchemaForm","maintainers":[{"name":"aidanbell","email":"aidanbell0182@gmail.com"}],"readme":"# `@aidanbell/schema-form`\n\n> **Experimental `0.1.x`** — API may change before 1.0.\n\nHeadless schema-driven forms for React: parse a JSON field definition, build a [Valibot](https://valibot.dev) validator, and wire [React Hook Form](https://react-hook-form.com) via `useSchemaForm`.\n\nBring your own UI — this package does not render inputs.\n\n## Install\n\n```bash\npnpm add @aidanbell/schema-form valibot react react-dom react-hook-form @hookform/resolvers\n```\n\n**Peers:** `react` / `react-dom` ≥18.2, `valibot` ^1.4.2, `react-hook-form` ^7.50, `@hookform/resolvers` ≥5.0.1.\n\nBuilt validation schemas implement [Standard Schema v1](https://standardschema.dev), so `validationSchema` from `useSchemaForm` (or `buildFormValidationSchema`) can be passed to any Standard Schema-aware consumer — not just React Hook Form.\n\n## Quickstart\n\n```tsx\nimport {\n  parseFormDefinition,\n  useSchemaForm,\n} from \"@aidanbell/schema-form\";\n\nconst parsed = parseFormDefinition({\n  schemaVersion: 1,\n  title: \"Invite\",\n  fields: [\n    { name: \"email\", type: \"email\", label: \"Email\", required: true },\n    { name: \"age\", type: \"number\", label: \"Age\" },\n  ],\n});\n\nif (!parsed.success) {\n  throw new Error(parsed.error);\n}\n\nexport function InviteForm() {\n  const { fields, form, handleSubmit } = useSchemaForm({\n    definition: parsed.data,\n    onSubmit: (values) => {\n      console.log(values);\n    },\n  });\n\n  return (\n    <form onSubmit={handleSubmit}>\n      {fields.map((field) => (\n        <label key={field.name}>\n          {field.label ?? field.name}\n          <input {...form.register(field.name)} />\n          {form.formState.errors[field.name] && (\n            <span>{String(form.formState.errors[field.name]?.message)}</span>\n          )}\n        </label>\n      ))}\n      <button type=\"submit\">Submit</button>\n    </form>\n  );\n}\n```\n\n## API\n\n| Export | Role |\n|--------|------|\n| `parseFormDefinition` | Validate a form definition (object or JSON string). Never throws; returns `ParseResult`. |\n| `formatParseError` | Format parse issues into a readable string. |\n| `buildFormValidationSchema` | Build a Valibot object schema from `FieldDefinition[]`. |\n| `getDefaultValues` | Derive RHF-friendly defaults (`defaultValue` or type fallbacks). |\n| `useSchemaForm` | Headless hook: Valibot resolver + defaults + optional `onSubmit`. |\n\n**Types:** `FormDefinition`, `FieldDefinition`, `FieldType`, `ParseResult`, `ParseIssue`, `UseSchemaFormOptions`, `UseSchemaFormResult`, `FormValidationSchema`.\n\nFull field contract: see [`SCHEMA.md`](../../SCHEMA.md) in the monorepo.\n\n## Empty-value semantics\n\n- Optional text-like fields (`string`, `email`, `password`, `textarea`, `select`, `radio`) use `''` when empty.\n- Optional `number` fields use `undefined` when empty (never coerced to `0`).\n- `boolean` defaults to `false`; a required boolean must be `true`.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}