Skip to content

Docs: Add FAQ about generic Vue components in CSF Next#33687

Merged
valentinpalkovic merged 2 commits into
nextfrom
kasper/docs-csf-next-generic-vue
Feb 2, 2026
Merged

Docs: Add FAQ about generic Vue components in CSF Next#33687
valentinpalkovic merged 2 commits into
nextfrom
kasper/docs-csf-next-generic-vue

Conversation

@kasperpeulen
Copy link
Copy Markdown
Member

@kasperpeulen kasperpeulen commented Jan 28, 2026

Related to #24238

What I did

Added a FAQ entry to the CSF Next documentation explaining how generic Vue components work with CSF Next.

Generic Vue components (using <script lang="ts" setup generic="T">) had type inference issues with traditional CSF3 (the generic type T would default to unknown). With CSF Next, users can simply pass the type parameter directly:

const meta = preview.meta({
  component: GenericList<{ id: number; name: string }>,
});

This documents the solution to issue #24238.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Documentation-only change, no manual testing required.

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make 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/core team 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>

Summary by CodeRabbit

  • Documentation
    • Enhanced Vue TypeScript tips with clearer, structured examples.
    • Added guidance on type checking, editor support, and Vue tooling.
    • Introduced examples for using generics in Vue components.
    • Reorganized documentation with explicit separation of script and template blocks for improved readability.

✏️ Tip: You can customize this high-level summary in your review settings.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Jan 28, 2026

View your CI Pipeline Execution ↗ for commit 686f663

Command Status Duration Result
nx run-many -t compile,check,knip,test,pretty-d... ✅ Succeeded 9m 58s View ↗

☁️ Nx Cloud last updated this comment at 2026-01-29 15:23:02 UTC

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Jan 28, 2026

View your CI Pipeline Execution ↗ for commit 5fde5c6

Command Status Duration Result
nx run-many -t compile,check,knip,test,pretty-d... ✅ Succeeded 6m 10s View ↗

☁️ Nx Cloud last updated this comment at 2026-01-28 11:33:23 UTC

@kasperpeulen kasperpeulen force-pushed the kasper/docs-csf-next-generic-vue branch from 89d031c to 5fde5c6 Compare January 28, 2026 11:25
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 28, 2026

📝 Walkthrough

Walkthrough

The Vue-specific tips section in the TypeScript documentation has been restructured with improved example formatting. Vue 3 SFC examples now feature explicit script setup and template block separation. New guidance on type checking, editor support, Vue tooling, and a CSF Next example for generics in Vue components have been added.

Changes

Cohort / File(s) Summary
TypeScript Documentation
docs/writing-stories/typescript.mdx
Restructured Vue SFC examples with separated <script setup lang="ts"> and <template> blocks; enhanced with guidance on defineProps, defineEmits, type checking, editor support, and a new CSF Next generic component example.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs


Comment @coderabbitai help to get the list of available commands and usage tips.


This setup will add type support for `*.vue` imports to your `*.stories.ts` files, providing the same type safety and autocomplete features.

[CSF Next](../api/csf/csf-next.mdx) adds support for [Generic Vue components](https://vuejs.org/api/sfc-script-setup.html#generics) (using `<script lang="ts" setup generic="T">`). Simply pass the type parameter directly to the component:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea why GitHub is showing 18 changed files instead of just this one. I merged next into this branch, but that shouldn't bork the changes view like this. 🤷‍♂️

In any case, I moved your CSF Next FAQ entry to the Writing stories with TypeScript guide, because it only pertains to TypeScript users.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@code/core/src/telemetry/detect-agent.ts`:
- Around line 16-19: Update the DetectAgentOptions type so stdoutIsTTY is typed
as boolean | undefined (to match process.stdout.isTTY) and modify the detection
logic in the detect-agent routine (the code that reads options.stdoutIsTTY and
applies heuristics) to explicitly handle undefined—either treat undefined as
non-TTY (same behavior as false) or bypass the heuristics path when stdoutIsTTY
=== undefined; ensure references to DetectAgentOptions and any function using
options.stdoutIsTTY are updated accordingly so the undefined case no longer
produces unintended false positives.
- Around line 1-8: KnownAgentName includes 'opencode' but detectExplicitAgent
lacks detection for it; either remove 'opencode' from the KnownAgentName union
or add explicit detection in detectExplicitAgent by checking OpenCode's
environment markers (e.g., OPENCODE_* vars) and returning 'opencode' when
present—update the KnownAgentName type or the detectExplicitAgent function
accordingly (reference KnownAgentName and detectExplicitAgent).

In `@docs/writing-stories/typescript.mdx`:
- Line 73: Update the heading "## Vue specific tips" in
docs/writing-stories/typescript.mdx to use the hyphenated form "Vue-specific" so
it reads "## Vue-specific tips"; locate the heading text and replace the
non-hyphenated word to correct the grammar.
🧹 Nitpick comments (3)
code/lib/cli-storybook/src/codemod/helpers/config-to-csf-factory.test.ts (1)

372-408: Good test coverage for the new empty/side-effect-only preview file scenarios.

The tests properly validate:

  • Single side-effect import
  • Empty file
  • Multiple side-effect imports (with expected Prettier reordering)

Consider adding a test for preview files with only re-exports (e.g., export { withTheme } from './decorators') to verify the default export is added in that case as well. Based on learnings: "In Storybook CSF factories codemod, preview files with only named exports (including re-exports like export { withTheme } from './decorators') still require a default export to be added via export default definePreview({})."

code/core/src/telemetry/detect-agent.test.ts (2)

77-79: Minor: Comment mentions isAgent=false but function returns undefined.

The comment says "returns isAgent=false" but detectAgent returns undefined when no signals are present, not an object with isAgent: false.

📝 Suggested fix
-  it('returns isAgent=false when there are no signals', () => {
+  it('returns undefined when there are no signals', () => {
     expect(detectAgent({ stdoutIsTTY: false, env: {} })).toEqual(undefined);
   });

34-44: Consider adding a standalone test for Claude Code detection.

CLAUDECODE is only tested within the precedence test (lines 20-31). For consistency with other agents (gemini-cli, codex, cursor), consider adding a dedicated standalone test.

📝 Suggested addition
it('detects Claude Code via CLAUDECODE', () => {
  expect(detectAgent({ stdoutIsTTY: true, env: { CLAUDECODE: '1' } })).toEqual({
    name: 'claude-code',
  });
});

Based on learnings: "Cover all branches, conditions, edge cases, error paths, and different input variations in unit tests"

Comment on lines +1 to +8
export type KnownAgentName =
| 'claude-code'
| 'gemini-cli'
| 'cursor'
| 'codex'
| 'opencode'
| 'amp'
| 'unknown';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n code/core/src/telemetry/detect-agent.ts

Repository: storybookjs/storybook

Length of output: 2441


🏁 Script executed:

rg -i 'opencode' code/ --type ts --type tsx --type js --type jsx

Repository: storybookjs/storybook

Length of output: 92


🌐 Web query:

OpenCode CLI environment variables detection

💡 Result:

OpenCode CLI “detects”/uses environment variables in two main ways:

  1. CLI/runtime feature flags (read directly from your shell env)
  • OpenCode reads a set of OPENCODE_* variables at startup to toggle behavior (config paths, autoupdate, pruning, Claude-code file loading, server auth, etc.). (opencode.ai)
  • Notable examples include OPENCODE_CONFIG (custom config file path) and OPENCODE_CONFIG_CONTENT (inline JSON config), plus various feature toggles like OPENCODE_DISABLE_AUTOUPDATE, OPENCODE_DISABLE_CLAUDE_CODE, etc. (opencode.ai)
  1. Config discovery + env-var substitution (env vars referenced from config files)
  • Config discovery precedence (highest → lowest):
    OPENCODE_CONFIGOPENCODE_CONFIG_CONTENTopencode.jsonc/json in project dir → parent dirs → global config (typically under ~/.config/opencode/). (deepwiki.com)
  • Inside config files, OpenCode supports env var interpolation with {env:VARIABLE_NAME}; if the env var is missing, it substitutes an empty string. (opencode.ai)

Sources
[1] (opencode.ai)
[2] (deepwiki.com)
[3] (opencode.ai)

Citations:


opencode is defined in KnownAgentName but never detected.

The type includes 'opencode' (line 6), but detectExplicitAgent has no corresponding detection logic for it. OpenCode CLI uses OPENCODE_* environment variables for configuration, but no standard detection marker is documented. Either add detection for OpenCode (if a detection variable should be supported) or remove it from the type union to keep types aligned with implementation.

🤖 Prompt for AI Agents
In `@code/core/src/telemetry/detect-agent.ts` around lines 1 - 8, KnownAgentName
includes 'opencode' but detectExplicitAgent lacks detection for it; either
remove 'opencode' from the KnownAgentName union or add explicit detection in
detectExplicitAgent by checking OpenCode's environment markers (e.g., OPENCODE_*
vars) and returning 'opencode' when present—update the KnownAgentName type or
the detectExplicitAgent function accordingly (reference KnownAgentName and
detectExplicitAgent).

Comment on lines +16 to +19
type DetectAgentOptions = {
stdoutIsTTY: boolean;
env: NodeJS.ProcessEnv;
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

stdoutIsTTY type should allow undefined to match process.stdout.isTTY.

process.stdout.isTTY is boolean | undefined, but DetectAgentOptions.stdoutIsTTY is typed as boolean. When isTTY is undefined (e.g., piped output), the current logic at line 78 treats it as falsy and applies heuristics, which may cause false positives.

Consider:

  1. Updating the type to boolean | undefined
  2. Explicitly handling undefined in the logic (e.g., treat as non-TTY or skip heuristics)
🔧 Suggested fix
 type DetectAgentOptions = {
-  stdoutIsTTY: boolean;
+  stdoutIsTTY: boolean | undefined;
   env: NodeJS.ProcessEnv;
 };

And optionally be explicit about undefined handling:

-  if (stdoutIsTTY) {
+  // When isTTY is true, skip heuristics (user is likely in an interactive terminal)
+  // When undefined or false, apply heuristics
+  if (stdoutIsTTY === true) {
     return undefined;
   }

Also applies to: 75-80

🤖 Prompt for AI Agents
In `@code/core/src/telemetry/detect-agent.ts` around lines 16 - 19, Update the
DetectAgentOptions type so stdoutIsTTY is typed as boolean | undefined (to match
process.stdout.isTTY) and modify the detection logic in the detect-agent routine
(the code that reads options.stdoutIsTTY and applies heuristics) to explicitly
handle undefined—either treat undefined as non-TTY (same behavior as false) or
bypass the heuristics path when stdoutIsTTY === undefined; ensure references to
DetectAgentOptions and any function using options.stdoutIsTTY are updated
accordingly so the undefined case no longer produces unintended false positives.

## Vue specific tips

Vue has excellent support for TypeScript, and we have done our utmost to take advantage of that in the stories files. For example, consider the following strongly typed Vue 3 single file component (SFC):
## Vue specific tips
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hyphenate “Vue-specific”.

Minor grammar polish for the heading.

✏️ Proposed fix
-## Vue specific tips
+## Vue-specific tips
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Vue specific tips
## Vue-specific tips
🧰 Tools
🪛 LanguageTool

[grammar] ~73-~73: Use a hyphen to join words.
Context: ...*/} ## Vue specific tips Vue has excellent support...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
In `@docs/writing-stories/typescript.mdx` at line 73, Update the heading "## Vue
specific tips" in docs/writing-stories/typescript.mdx to use the hyphenated form
"Vue-specific" so it reads "## Vue-specific tips"; locate the heading text and
replace the non-hyphenated word to correct the grammar.

Copy link
Copy Markdown
Contributor

@kylegach kylegach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving to unblock. Merge if you agree with my change.

@kylegach kylegach added the patch:yes Bugfix & documentation PR that need to be picked to main branch label Jan 28, 2026
kasperpeulen and others added 2 commits January 29, 2026 22:11
Documents that generic Vue components work seamlessly with CSF Next
by passing the type parameter directly to the component.
@kasperpeulen kasperpeulen force-pushed the kasper/docs-csf-next-generic-vue branch from 2028727 to 686f663 Compare January 29, 2026 15:11
@kasperpeulen
Copy link
Copy Markdown
Member Author

Thanks Kyle! Sorry about the mess - fixed the branch (removed the unrelated commits that got mixed in). Ready to merge now.

@valentinpalkovic valentinpalkovic merged commit 72d12b4 into next Feb 2, 2026
124 checks passed
@valentinpalkovic valentinpalkovic deleted the kasper/docs-csf-next-generic-vue branch February 2, 2026 13:14
valentinpalkovic added a commit that referenced this pull request Feb 2, 2026
…ic-vue

Docs: Add FAQ about generic Vue components in CSF Next
(cherry picked from commit 72d12b4)
@github-actions github-actions Bot mentioned this pull request Feb 2, 2026
13 tasks
@github-actions github-actions Bot added the patch:done Patch/release PRs already cherry-picked to main/release branch label Feb 2, 2026
@github-actions github-actions Bot mentioned this pull request Feb 3, 2026
18 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:normal documentation patch:done Patch/release PRs already cherry-picked to main/release branch patch:yes Bugfix & documentation PR that need to be picked to main branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants