Skip to content

feat(add): write v0 examples into a project from the registry - #27

Draft
johnleider wants to merge 1 commit into
mainfrom
feat/add-registry
Draft

feat(add): write v0 examples into a project from the registry#27
johnleider wants to merge 1 commit into
mainfrom
feat/add-registry

Conversation

@johnleider

Copy link
Copy Markdown
Member

Makes npx vuetify add dialog work: it resolves a name against the v0 registry and copies a runnable, styled example into the project.

Depends on vuetifyjs/0#721, which publishes the registry. Until that merges, drive this with --registry <origin>.

It copies the example, not the primitive

v0 is a published package — pnpm add @vuetify/v0 already gets you Dialog, so ejecting the primitive's source would fork a consumer off the upgrade path for nothing. v0 is also headless, so a bare import renders nothing at all. The file a user cannot get today is the one that actually shows something, so that is what gets written.

The styling preflight is the part that matters

Examples style themselves with semantic utilities — bg-primary, text-on-surface, border-divider. Those need two independent layers present:

  1. createThemePlugin, which emits the --v0-* custom properties
  2. an UnoCSS or Tailwind config mapping them onto utility classes

Copy the markup without them and the result looks broken, and it reads as v0's fault. So add detects both, offers the patch, and warns when the theme plugin is missing. A project scaffolded by create-vuetify0 already has both, so this is a no-op there.

The UnoCSS config is edited through magicast rather than appended to — appending leaves the file syntactically invalid, which the first end-to-end run caught. Colors the project already defines are preserved. A Tailwind stylesheet takes an appended @theme inline block, which is valid CSS. With neither engine present, both snippets are printed rather than guessing at one.

Surface

vuetify add dialog
vuetify add combobox --example user-picker
vuetify add tabs --dir src/ui
vuetify add create-data-table --yes

vuetify add with no argument lists integrations and registry items together, so neither is hidden behind knowing its name. add eslint and the add mcp deprecation are unchanged.

Names resolve exactly first, then by stripping the create/use prefix (add popover finds usePopover), then loosely. Ambiguity prompts.

Non-interactive behavior

--yes never blocks and never destroys:

  • picks the canonical example when a feature has several
  • exits 1 on an ambiguous name rather than guessing which feature was meant
  • skips existing files instead of clobbering them; --overwrite is the explicit opt-in

Verified

Driven end-to-end against a locally served registry (93 items) across scratch projects:

  • UnoCSS project — config patched via magicast, output re-parsed to confirm valid TS, pre-existing brand color preserved
  • Tailwind project — @theme inline appended to src/style.css
  • neither — both snippets printed, nothing written blindly
  • theme plugin present — warning correctly suppressed
  • multi-file example — all 3 files written co-located, relative imports intact
  • nested example — mirrored to create-data-table/basic/, no collision
  • re-run — styling patch is idempotent
  • exit codes: unknown 1, ambiguous 1, success 0; no hangs under --yes
  • pnpm lint:fix and pnpm build clean

Note

New i18n strings are English-only. enableFallback covers ru in the meantime — happy to hold for translations if you would rather they land together.

`vuetify add` only handled integrations. It now also resolves a name against
the v0 registry, so `vuetify add dialog` copies a runnable, styled example in
instead of leaving the user to find it in the docs and paste it by hand.

It copies the example, not the primitive's source. v0 is a published package,
so ejecting `Dialog` itself would fork a consumer off the upgrade path for no
gain; the file they cannot get today is the one that actually renders.

The styling preflight is the part that makes this work at all. Examples style
themselves with semantic utilities (`bg-primary`, `text-on-surface`), which
need two layers: `createThemePlugin` to emit the `--v0-*` custom properties,
and an UnoCSS or Tailwind config to map them. Copying the markup without them
produces something that looks broken and reads as v0's fault, so `add` detects
both, offers the patch, and warns when the theme plugin is absent. The UnoCSS
config is edited through magicast — appending the block would leave the file
syntactically invalid — and existing colors are preserved.

Non-interactive runs stay unblocked and non-destructive: `--yes` picks the
canonical example, refuses to guess between ambiguous names, and skips
existing files rather than clobbering them, leaving `--overwrite` as the
explicit opt-in.

New strings are English-only; `enableFallback` covers ru until translated.
@johnleider johnleider added the enhancement New feature or request label Jul 27, 2026
@johnleider johnleider self-assigned this Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant