{"_id":"@eidhachem/forms-nuxt-ui","_rev":"2-f70e6635c9d0ebd4a6951b8b400ade1e","name":"@eidhachem/forms-nuxt-ui","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@eidhachem/forms-nuxt-ui","version":"0.1.0","keywords":["vue","nuxt","nuxt-ui","forms","adapter","typescript"],"license":"UNLICENSED","_id":"@eidhachem/forms-nuxt-ui@0.1.0","maintainers":[{"name":"eidhachem","email":"eidhachem1@gmail.com"}],"dist":{"shasum":"e7f3cf2d4f8a2fa92420109348d461a7a1d8dfd6","tarball":"https://registry.npmjs.org/@eidhachem/forms-nuxt-ui/-/forms-nuxt-ui-0.1.0.tgz","fileCount":7,"integrity":"sha512-uu6AYZEz4sCiPaEZAkvcov0u64Bn5vaGd+TvCmf7fLECdmwCF2Y+5hFhk7fJ+9UTCQqTnNqPgYF0hRfLLDHo8A==","signatures":[{"sig":"MEQCIDiPdLFyAZcWQUqp4PK56hhq468zhA9RMgjyrGbrDtKLAiAPSOVSTmm0lDtAo9ajmBO1k8TAGv8mvdJpxiaPSyJB4w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47823},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"443c15dda2a1f68028259f819ac30d30f4fb218d","scripts":{"dev":"vite build --watch","test":"vitest run","build":"vite build","clean":"rimraf dist","typecheck":"vue-tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"eidhachem","email":"eidhachem1@gmail.com"},"_npmVersion":"10.8.2","description":"Official @eidhachem/forms UI adapter for Nuxt UI: maps built-in field types to Nuxt UI components.","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","dependencies":{"@eidhachem/forms":"workspace:^"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.13","vite":"^5.4.11","rimraf":"^6.0.1","vue-tsc":"^2.1.10","typescript":"^5.7.2","vite-plugin-dts":"^4.3.0"},"peerDependencies":{"vue":"^3.4.0","@nuxt/ui":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/forms-nuxt-ui_0.1.0_1787302880666_0.5999402421408351","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@eidhachem/forms-nuxt-ui","version":"0.1.1","description":"Official @eidhachem/forms UI adapter for Nuxt UI: maps built-in field types to Nuxt UI components.","type":"module","license":"UNLICENSED","engines":{"node":">=20"},"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"},"./package.json":"./package.json"},"scripts":{"build":"vite build","dev":"vite build --watch","typecheck":"vue-tsc --noEmit -p tsconfig.json","test":"vitest run","clean":"rimraf dist"},"dependencies":{"@eidhachem/forms":"^0.1.1"},"peerDependencies":{"@nuxt/ui":"^4.0.0","vue":"^3.4.0"},"devDependencies":{"rimraf":"^6.0.1","typescript":"^5.7.2","vite":"^5.4.11","vite-plugin-dts":"^4.3.0","vue":"^3.5.13","vue-tsc":"^2.1.10"},"publishConfig":{"access":"public"},"keywords":["vue","nuxt","nuxt-ui","forms","adapter","typescript"],"_id":"@eidhachem/forms-nuxt-ui@0.1.1","gitHead":"443c15dda2a1f68028259f819ac30d30f4fb218d","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-wFCFa6/jvS0QEx07d2gT/2Ea3u65D8wFYfAMtPz4TFxlDr9x01XbjHdJrKmCfwWY8zY5Qz3/5hPmkHlUhuLFLA==","shasum":"8ef13afeb11710c4753c704b811fc8bd54c38481","tarball":"https://registry.npmjs.org/@eidhachem/forms-nuxt-ui/-/forms-nuxt-ui-0.1.1.tgz","fileCount":7,"unpackedSize":47818,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGw52NhK8W5OCMIB+qheptp3SJ24KXWhDY2UhVbdH+fFAiEAlOqv69tfZ4u8Hnx5umuV2TOMlr0Nn8lD29mrvpVSZwU="}]},"_npmUser":{"name":"eidhachem","email":"eidhachem1@gmail.com"},"directories":{},"maintainers":[{"name":"eidhachem","email":"eidhachem1@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/forms-nuxt-ui_0.1.1_1787320677922_0.9136404307496577"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-21T09:01:20.381Z","modified":"2026-08-21T13:57:58.256Z","0.1.0":"2026-08-21T09:01:20.822Z","0.1.1":"2026-08-21T13:57:58.069Z"},"license":"UNLICENSED","keywords":["vue","nuxt","nuxt-ui","forms","adapter","typescript"],"description":"Official @eidhachem/forms UI adapter for Nuxt UI: maps built-in field types to Nuxt UI components.","maintainers":[{"name":"eidhachem","email":"eidhachem1@gmail.com"}],"readme":"# @sowlutions/forms-nuxt-ui\n\n> **Status:** Phase 13 complete. `createNuxtUiAdapter()` maps 22 of\n> `@sowlutions/forms`'s built-in field types onto real Nuxt UI v4 components.\n> See [ADR-018](../../docs/architecture/decisions/ADR-018-nuxt-ui-adapter.md)\n> for the full per-type breakdown, and for why this package never imports\n> from `@nuxt/ui` itself — you hand it your own already-resolved component\n> references (one small one-time setup step, below).\n\n## Setup\n\nNuxt UI v4's components internally rely on Nuxt-build-time-only virtual\nmodules (`#build/ui/*`, `#imports`), so they can only be imported from code\nthat a running Nuxt build actually compiles — never from this package's own\nahead-of-time build. Instead, pull your already-resolved component\nreferences from Nuxt's `#components` virtual module (the same mechanism\nNuxt's own auto-imports are built on) and hand them to\n`createNuxtUiAdapter()` once, in a plugin:\n\n```ts\n// app/plugins/forms-nuxt-ui.ts\nimport {\n  UFormField,\n  UInput,\n  UTextarea,\n  UInputNumber,\n  USlider,\n  USelectMenu,\n  URadioGroup,\n  UCheckbox,\n  UCheckboxGroup,\n  USwitch,\n  UInputTags,\n  UColorPicker,\n  UInputRating,\n  UPinInput,\n  UFileUpload,\n} from '#components';\nimport { createNuxtUiAdapter } from '@sowlutions/forms-nuxt-ui';\nimport { registerAdapter, setDefaultAdapter } from '@sowlutions/forms';\n\nexport default defineNuxtPlugin(() => {\n  registerAdapter(\n    createNuxtUiAdapter({\n      UFormField,\n      UInput,\n      UTextarea,\n      UInputNumber,\n      USlider,\n      USelectMenu,\n      URadioGroup,\n      UCheckbox,\n      UCheckboxGroup,\n      USwitch,\n      UInputTags,\n      UColorPicker,\n      UInputRating,\n      UPinInput,\n      UFileUpload,\n    }),\n  );\n  setDefaultAdapter('nuxt-ui');\n});\n```\n\nFrom then on, `FormRenderer`/`FieldRenderer` (or your own headless markup)\nrender every mapped field type through the real Nuxt UI component — no\nfurther wiring per form or per field.\n\n## Supported field types\n\n`text`, `password`, `email`, `tel`, `url`, `search`, `textarea`, `number`,\n`currency`, `percentage`, `range`, `select`, `multiselect`, `autocomplete`,\n`combobox`, `radio`, `checkbox`, `checkbox-group`, `switch`, `tags`,\n`color`, `rating`, `otp`, `file`, `image`, `file-list`, `image-list`.\n\nDeliberately unmapped — `supports()` returns `false` and\n`resolveFieldComponentOrThrow` throws a clear error rather than rendering\nsilently-wrong UI (rule 11): `phone` (no native Nuxt UI component);\n`date`/`datetime`/`time`/`month`/`week`/`date-range` (Nuxt UI's date/time\ninputs take `@internationalized/date` value objects, not a plain JS value —\nsee ADR-018 for why this adapter doesn't attempt that conversion\ngenerically); `heading`/`description`/`divider`/`section`/`group`/`tabs`/\n`accordion` (structural, not value-bound fields); `custom` (bypasses\nadapter resolution entirely, ADR-013 §3).\n\n`select`/`multiselect`/`autocomplete`/`combobox` submit just the selected\noption's `value` (not the whole `{ label, value }` object) — this needs\n`valueKey: 'value'` on Nuxt UI's `USelectMenu`, since (unlike\n`radio`/`checkbox-group`) it doesn't default to that itself; set for you\nalready. `otp` submits a single string — `UPinInput`'s own `modelValue` is\nalways a per-digit array, converted both ways. Neither needs anything\nextra from you; see ADR-025 if you're curious why they needed fixing.\n\n## Passing per-field config (options, accept, formatOptions, ...)\n\nTwo channels reach the real Nuxt UI component, both forwarded through\n(`FormAdapter.resolveComponent` only ever sees the field type string):\n`field.props` (a loose bag, works for anything), and the field's own typed\nper-type config (`SelectionFieldConfig.options`, `CurrencyFieldConfig.currency`,\n`FileFieldConfig.accept`, ... — `packages/core/src/types/field.ts`'s\n`FieldTypeConfigMap`) — declared as ordinary top-level `FieldSchema`\nproperties, not nested under `props`. `props` always wins on a key\ncollision (see ADR-023), so it's also how to override the typed config for\none render without touching the schema. Both forms work:\n\n```ts\n{ name: 'country', type: 'select', options: [{ label: 'USA', value: 'us' }] }\n{ name: 'country', type: 'select', props: { options: [{ label: 'USA', value: 'us' }] } } // equivalent\n\n{ name: 'price', type: 'currency', currency: 'USD' }\n{ name: 'avatar', type: 'image', props: { accept: '.png,.jpg' } } // overrides the 'image/*' default\n```\n\n`options` is renamed to Nuxt UI's own `items` prop internally — `@sowlutions/forms`'\n`SelectOption` shape (`label`/`value`/`disabled`/`description`) already\nmatches Nuxt UI's default item shape. One exception: a `MaybeReactive`\ncallback or `AsyncOptionsConfig` `options` (Phase 6 dynamic forms,\n`useFieldOptions()`) is *not* merged automatically — only a plain, already-\nresolved array is; resolve it via `useFieldOptions()` yourself and pass the\nresult through `field.props.options`.\n\nSee the repository root [README](../../README.md) and\n[docs/architecture](../../docs/architecture) for the full architecture and\nroadmap.\n","readmeFilename":"README.md"}