Repository navigation
Vue3: Support TypeScript enum props in vue-component-meta docgen - #35684
Conversation
vue-component-meta stringifies a TS enum member to its qualified name
("Severity.Info"), which says nothing about what gets passed to the
component. #35565 therefore had to keep enums out of Controls entirely:
an enum sbType would have made a select inject the literal string
"Severity.Info" instead of 'info'.
vuejs/language-tools#6131, released in vue-component-meta 3.3.9, adds a
"literal" schema node carrying the runtime value next to the member name.
Consume it: TS enums now resolve to an enum sbType of their runtime values,
with control.labels mapping each value back to the member name it is
written as. Picking "Severity.Info" in the dropdown passes 'info'; numeric
enums pass 0 and 1. table.type.summary keeps the enum name either way.
The dotted-string guard stays, narrowed to what it actually catches now:
unresolved qualified type names like "typeof Config.alpha", which
stringify with a dot but stand for no value.
The labels are only useful if they survive next to the control type inferControls picks. Assert the merged result directly, so the radio/select treatment a TS enum shares with a literal union cannot silently break.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 3 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (4)
WalkthroughThe Vue 3 docgen integration now uses ChangesVue enum extraction
Sequence Diagram(s)sequenceDiagram
participant VueComponentMeta
participant ExtractArgTypes
participant InferControls
VueComponentMeta->>ExtractArgTypes: provide literal enum schemas
ExtractArgTypes->>ExtractArgTypes: map enum labels to runtime values
ExtractArgTypes->>InferControls: provide enum options and labels
InferControls-->>ExtractArgTypes: return inferred controls
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
code/renderers/vue3/src/extractArgTypes.ts (1)
341-346: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove non-maintenance references from comments.
Keep the local behavior rationale only.
code/renderers/vue3/src/extractArgTypes.ts#L341-L346: remove the external pull-request reference.code/lib/docgen-harness/src/vue3/__testfixtures__/props-ts-enum/TsEnumProps.vue#L2-L4: remove thecm-argtypes.snapshotcross-file reference.As per coding guidelines: “Comments should explain maintenance rationale, not investigation history; do not include internal ticket or acceptance codes, provenance claims, or cross-file line references.”
Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@code/renderers/vue3/src/extractArgTypes.ts`:
- Line 347: Remove the duplicate LiteralSchema type declaration in the module,
retaining a single Extract<PropertyMetaSchema, { kind: 'literal' }> alias for
all existing usages.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7dce3da8-f2ac-444a-91ba-ea92110ab8b8
⛔ Files ignored due to path filters (2)
code/renderers/vue3/src/__snapshots__/extractArgTypes.test.ts.snapis excluded by!**/*.snapyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (10)
code/frameworks/vue3-vite/package.jsoncode/frameworks/vue3-vite/src/plugins/vue-component-meta.tscode/lib/docgen-harness/README.mdcode/lib/docgen-harness/package.jsoncode/lib/docgen-harness/src/vue3/__testfixtures__/props-ts-enum/TsEnumProps.vuecode/lib/docgen-harness/src/vue3/__testfixtures__/props-ts-enum/cm-argtypes.snapshotcode/lib/docgen-harness/src/vue3/vue3-component-meta-baselines.test.tscode/renderers/vue3/src/docs/tests-meta-components/meta-components.tscode/renderers/vue3/src/extractArgTypes.test.tscode/renderers/vue3/src/extractArgTypes.ts
… engine The story renders under both docgen engines and shows the difference directly: vue-component-meta gives severity/level a labelled option set, vue-docgen-api falls back to a JSON editor. It also carries the numeric enum and a plain literal union, so a regression in either shows up next to its unaffected neighbour. Both describe blocks in extractArgTypes.test.ts were named "(vue-docgen-api)" while the first one drives vue-component-meta fixtures. Sharing a name put their snapshots in one namespace, and since both spell "should extract props for component", the two engines' props snapshots were told apart only by a trailing 1/2 - so reordering or renaming a test would silently swap which engine each snapshot belonged to.
Package BenchmarksCommit: The following packages have significant changes to their size or dependencies:
|
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 73 | 73 | 0 |
| Self size | 21.39 MB | 21.39 MB | 🚨 +426 B 🚨 |
| Dependency size | 36.75 MB | 31.22 MB | 🎉 -5.53 MB 🎉 |
| Bundle Size Analyzer | Link | Link |
@storybook/angular-vite
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 36 | 36 | 0 |
| Self size | 33.41 MB | 33.41 MB | 🎉 -42 B 🎉 |
| Dependency size | 21.34 MB | 15.81 MB | 🎉 -5.53 MB 🎉 |
| Bundle Size Analyzer | Link | Link |
@storybook/cli
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 205 | 205 | 0 |
| Self size | 827 KB | 827 KB | 0 B |
| Dependency size | 91.60 MB | 86.07 MB | 🎉 -5.53 MB 🎉 |
| Bundle Size Analyzer | Link | Link |
@storybook/codemod
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 198 | 198 | 0 |
| Self size | 32 KB | 32 KB | 🎉 -36 B 🎉 |
| Dependency size | 90.08 MB | 84.55 MB | 🎉 -5.53 MB 🎉 |
| Bundle Size Analyzer | Link | Link |
create-storybook
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 74 | 74 | 0 |
| Self size | 1.09 MB | 1.09 MB | 🚨 +66 B 🚨 |
| Dependency size | 58.14 MB | 52.60 MB | 🎉 -5.53 MB 🎉 |
| Bundle Size Analyzer | node | node |
LogDetails |
What I did
Closes the TS-enum gap that #35565 had to leave open.
vue-component-metastringifies a TypeScript enum member to its qualified name (Severity.Info), which says nothing about the value the component actually receives. That is why #35565, when it enabledschema: true, had to explicitly keep TS enums out of Controls (86a1ea5): anenumsbType would have rendered a dropdown that injects the literal string"Severity.Info"instead of'info'.vuejs/language-tools#6131 - merged and released in
vue-component-meta@3.3.9- adds aliteralschema node that carries the runtime value alongside the member name:This PR bumps to
^3.3.9and consumes it.Before / after
The dropdown shows
Severity.Infoand passes'info'. Numeric enums (enum Level { Low, High }) pass0and1under the labelsLevel.Low/Level.High.table.type.summarykeeps the enum name in both cases, so the docs table is unchanged.Notes on the implementation
control.typeis deliberately not set.inferControlsalready picksradiovsselectby option count, andcombineParametersmerges it with thelabelsset here. TS enums therefore behave exactly like plain literal unions instead of being force-fed aselect.Severity | 'custom'resolves to['info', 'warning', 'error', 'custom'], with labels only on the enum members.typeof Config.alpha | typeof Config.beta) - those carry no value and must not become selectable. TS enum members no longer reach that branch.removeNestedSchemasin the vite plugin gained an explicit terminal case forliteralnodes (they have nothing nested, and the previousdelete schema.schemano longer type-checks against the widenedPropertyMetaSchema).MyEnumfixture inmeta-components.tswas a hand-maintained capture of checker output still in the pre-3.3.9 shape; it is updated so the mock matches what the dependency now produces.Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Unit tests in
code/renderers/vue3/src/extractArgTypes.test.tscover string enums, numeric enums, mixed enum/literal unions, the qualified-name guard, and theoptions+control.labelsoutput. The docgen harness (#35574) re-recordsprops-ts-enumand shows the change as a reviewed baseline diff - it is the only fixture that moves, and the harness comparator certifies it as an improvement rather than a regression.Manual testing
yarn task sandbox --template vue3-vite/default-ts --start-from autodocgen: 'vue-component-meta'in the framework optionsDocumentation
MIGRATION.MD
Checklist for Maintainers
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsqa:neededorqa:skipbug🤖 Generated with Claude Code
https://claude.ai/code/session_015gvCXfY6v5hGRDVNL11JXS