Repository navigation
Vue: Generate Story snippets from docgen payload - #35815
Conversation
Package BenchmarksCommit: The following packages have significant changes to their size or dependencies:
|
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 94 | 94 | 0 |
| Self size | 31 KB | 31 KB | 🚨 +24 B 🚨 |
| Dependency size | 18.44 MB | 18.45 MB | 🚨 +17 KB 🚨 |
| Bundle Size Analyzer | Link | Link |
@storybook/vue3
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 90 | 90 | 0 |
| Self size | 102 KB | 118 KB | 🚨 +16 KB 🚨 |
| Dependency size | 18.10 MB | 18.10 MB | 0 B |
| Bundle Size Analyzer | Link | Link |
aacb032 to
4597db7
Compare
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThis PR adds static Vue SFC snippet generation for story arguments. It classifies props, slots, events, and models, integrates docgen metadata, supports fixture-tree testing, and adds parity validation with expected omissions. ChangesVue story-doc generation
Sequence Diagram(s)sequenceDiagram
participant StoryFile
participant buildStoryDocs
participant classifyArgs
participant renderSfcSnippet
StoryFile->>buildStoryDocs: provide story metadata and args
buildStoryDocs->>classifyArgs: classify args with docgen metadata
classifyArgs-->>buildStoryDocs: return classified args or warnings
buildStoryDocs->>renderSfcSnippet: render classified args
renderSfcSnippet-->>buildStoryDocs: return Vue SFC snippet
Possibly related PRs
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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/lib/docgen-harness/src/vue3/__testfixtures__/props-basic-types/story-docs.payload.snapshot`:
- Line 27: Update the PropsBasicTypes Vue fixture to hoist the Symbol value into
the script as a token constant, then bind the component’s token prop with
:token="token" instead of calling Symbol directly in the template; leave the
other bindings unchanged.
In
`@code/lib/docgen-harness/src/vue3/__testfixtures__/props-ts-enum/story-docs.payload.snapshot`:
- Line 12: Update renderSfcSnippet() to include the story-local Severity import
in the generated SFC script, or replace the emitted severity value with a
self-contained equivalent so Severity.Warning is resolvable; then regenerate the
props-ts-enum story-docs payload snapshot.
In `@code/lib/docgen-harness/src/vue3/story-docs/build-story-docs.test.ts`:
- Around line 1-11: Replace host filesystem access with memfs in
build-story-docs.test.ts, mocking node:fs and node:fs/promises, then reset and
seed vol in beforeEach with the required fixtures. In snippet-parity.test.ts,
mock node:fs with memfs and configure filesystem spies using vi.mock(..., { spy:
true }) and vi.mocked().
In `@code/renderers/vue3/src/story-docs/classify-args.ts`:
- Around line 102-110: Update the classification logic around unwrapValue and
hasSpreadValue to recursively inspect nested object and array values for
Identifier expressions, not only when the top-level value is an Identifier.
Return the existing unsupported-args error for the referenced identifier before
invoking the SFC renderer, while preserving current handling for top-level
identifiers and spread values.
In `@code/renderers/vue3/src/story-docs/render-sfc.ts`:
- Around line 127-128: Update the StringLiteral handling in render-sfc.ts to
HTML-escape slot text before inserting it into generated template content. Also
update the attribute-value generation around lines 163-170 to encode values
before wrapping them with the attribute delimiter, preserving literal characters
such as quotes and markup safely in both contexts.
- Around line 84-87: Update the hoisted-binding logic in render-sfc.ts at lines
84-87 and 102-107 to generate unique valid TypeScript identifier names instead
of using raw CSF arg or model names. Apply the same allocator to object/array
prop bindings and model refs, ensuring generated names avoid collisions with
imported bindings such as Vue’s ref and are used consistently in declarations
and template attributes.
🪄 Autofix
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 Plus
Run ID: e51aa200-6b71-448f-92e9-495ae0519a9a
📒 Files selected for processing (44)
code/lib/docgen-harness/src/vue3/__testfixtures__/cross-file-composed-utility/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/cross-file-extended-interface/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/cross-file-imported-interface/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/cross-file-props-spread/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/cross-file-runtime-props/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/cross-file-union-alias/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/define-expose/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/define-props-destructured/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/define-props-runtime-array/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/define-props-runtime-object/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/define-slots-with-props/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/events-jsdoc/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/jsdoc-tags/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/prop-slot-name-collision/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/props-basic-types/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/props-generic/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/props-ts-enum/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/props-union-enum/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/recursive-type/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/runtime-multi-constructor/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/runtime-proptype-cast/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/slots-template-only/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/slots/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/snippet-parity-summary.mdcode/lib/docgen-harness/src/vue3/__testfixtures__/type-intersection-whole/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/type-intersection/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/v-model/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/args-formatting/ArgsFormattingButton.vuecode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/args-formatting/input.stories.tscode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/args-formatting/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/as-cast/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/basic/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/csf4/CsfFourButton.vuecode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/csf4/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/import-override/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/prop-slot-collision/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/slots/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/unsupported-args/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/v-model/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/build-story-docs.test.tscode/lib/docgen-harness/src/vue3/story-docs/snippet-parity.test.tscode/renderers/vue3/src/story-docs/build-story-docs.tscode/renderers/vue3/src/story-docs/classify-args.tscode/renderers/vue3/src/story-docs/render-sfc.ts
0c85123 to
700f063
Compare
valentinpalkovic
left a comment
There was a problem hiding this comment.
Thermo-nuclear code quality review
Note
This review was produced with the thermo-nuclear code quality review skill and is AI-assisted. Every claim below was verified by running the code, not by reading it alone. Take the prioritisation with a grain of salt and push back where I got it wrong.
What I ran: both suites on this branch (renderer: 3 files / 5 tests pass, docgen-harness: 2 files / 73 tests pass), plus probes against classifyArgs + renderSfcSnippet and against generateSourceCode, to capture real output for the comparisons below.
Verdict: the feature is worth having and the fixture/snapshot discipline is genuinely strong. My concern is structural, and I would like to resolve it before this lands.
- This stands up a second implementation of Vue's SFC snippet grammar next to the one in
src/docs/sourceDecorator.ts. The two already disagree in seven observable ways, and the parity harness cannot see any of them, becausecompareSnippetdiffs represented names only and scores a candidate-only name as an improvement. - The "what is statically renderable" decision is split across
classify-args.tsandrender-sfc.ts, and they contradict each other. Bare identifiers are rejected; the same identifier as a callee, a member expression or insidenewis inlined into a template that never defines it. - That split produces a user-visible bug on a completely ordinary story:
args: { a: undefined }errors the whole story instead of dropping the arg. - There are three different failure policies for "cannot render this arg" (silent drop, silent whole-story skip, hard error), while
StoryDoc.warningalready models the correct middle ground and is unused. commands.extractDocgenis the wrong door oncore/docgenand re-runs the full provider chain per story file.
Severity is marked on each comment: HIGH / MIDDLE / LOW / NIT. Happy to pair on the shared-printer extraction if that helps get it over the finish line.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/lib/docgen-harness/src/compare/expect-current-or-better.ts`:
- Around line 35-40: Update the comparison flow around compareSnippet and the
stale declaration check so violations other than lost-representation, especially
unparsable-candidate, are reported first. Return or throw the candidate-parsing
violation before evaluating declaredOmissions against omitted, while preserving
the existing stale-declaration handling for lost-representation results.
In
`@code/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/args-formatting/story-docs.payload.snapshot`:
- Around line 11-21: Escape the nested double quotes in the snapshot’s outer
quoted snippet value, specifically the lang="ts" attribute in the SFC script
tag, then regenerate the args-formatting story-docs snapshot so the payload
remains parseable.
🪄 Autofix
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 Plus
Run ID: 901b7198-cda2-4a1d-9811-5a464841a605
📒 Files selected for processing (17)
code/lib/docgen-harness/src/compare/expect-current-or-better.tscode/lib/docgen-harness/src/vue3/__testfixtures__/props-basic-types/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/props-ts-enum/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/v-model/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/args-formatting/input.stories.tscode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/args-formatting/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/csf1-legacy/input.stories.tscode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/csf1-legacy/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/v-model/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/snippet-parity.test.tscode/renderers/vue3/src/story-docs/build-story-docs.tscode/renderers/vue3/src/story-docs/classify-args.test.tscode/renderers/vue3/src/story-docs/classify-args.tscode/renderers/vue3/src/story-docs/classify-value.test.tscode/renderers/vue3/src/story-docs/classify-value.tscode/renderers/vue3/src/story-docs/render-sfc.test.tscode/renderers/vue3/src/story-docs/render-sfc.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- code/lib/docgen-harness/src/vue3/testfixtures/v-model/story-docs.payload.snapshot
- code/lib/docgen-harness/src/vue3/testfixtures/props-basic-types/story-docs.payload.snapshot
- code/lib/docgen-harness/src/vue3/story-docs/testfixtures/v-model/story-docs.payload.snapshot
- code/renderers/vue3/src/story-docs/render-sfc.ts
- code/lib/docgen-harness/src/vue3/testfixtures/props-ts-enum/story-docs.payload.snapshot
- code/lib/docgen-harness/src/vue3/story-docs/snippet-parity.test.ts
- code/renderers/vue3/src/story-docs/build-story-docs.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/event-listener/input.stories.ts`:
- Line 19: Replace the raw console.log in the onSubmit handler of the
event-listener fixture with a typed no-op handler that preserves the listener
coverage without producing output, then regenerate or update the corresponding
story-docs.payload.snapshot to reflect the fixture change.
In `@code/renderers/vue3/src/story-docs/classify-args.ts`:
- Around line 97-105: Update the function classification flow around declared
events and props to inspect function bodies for non-local references, including
captured values and spreads, before assigning the hoist plan. Only hoist
self-contained functions; route unresolved functions through the existing
unresolved-argument omission and warning path, preserving current event/prop
classification for valid functions.
🪄 Autofix
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 Plus
Run ID: f67fc72d-814a-41e7-b6f9-6155ae521d87
📒 Files selected for processing (12)
code/lib/docgen-harness/src/vue3/__testfixtures__/events-jsdoc/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/props-basic-types/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/__testfixtures__/snippet-parity-summary.mdcode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/event-listener/EventListenerForm.vuecode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/event-listener/input.stories.tscode/lib/docgen-harness/src/vue3/story-docs/__testfixtures__/event-listener/story-docs.payload.snapshotcode/lib/docgen-harness/src/vue3/story-docs/build-story-docs.test.tscode/renderers/vue3/src/story-docs/build-story-docs.tscode/renderers/vue3/src/story-docs/classify-args.test.tscode/renderers/vue3/src/story-docs/classify-args.tscode/renderers/vue3/src/story-docs/render-sfc.test.tscode/renderers/vue3/src/story-docs/render-sfc.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- code/lib/docgen-harness/src/vue3/testfixtures/props-basic-types/story-docs.payload.snapshot
- code/lib/docgen-harness/src/vue3/testfixtures/snippet-parity-summary.md
- code/renderers/vue3/src/story-docs/render-sfc.ts
- code/lib/docgen-harness/src/vue3/story-docs/build-story-docs.test.ts
- code/renderers/vue3/src/story-docs/build-story-docs.ts
- code/renderers/vue3/src/story-docs/render-sfc.test.ts
0252797 to
9515c68
Compare
955558b to
87c931f
Compare
87c931f to
de74833
Compare
de74833 to
014c4a0
Compare
Closes #
What I did
This PR makes the Vue renderer synthesizes the snippet statically from the story's args plus fresh docgen, for the cases where the args can be read from the AST.
Each merged arg (meta.args ← story.args) is classified against the docgen payload and rendered into an SFC:
Stories whose args can't be statically read (an identifier reference, a spread) get an error instead of a snippet.
Different examples are available in the fixtures.
Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
Caution
This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!
Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
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.tsDeclare whether manual QA will be needed for this PR during the next release, through
qa:neededorqa:skipMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/coreteam here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>