Skip to content

CSF-Next: Add tags type support for #34819

Merged
valentinpalkovic merged 4 commits into
storybookjs:nextfrom
unional:tags-csf-next
May 22, 2026
Merged

CSF-Next: Add tags type support for #34819
valentinpalkovic merged 4 commits into
storybookjs:nextfrom
unional:tags-csf-next

Conversation

@unional
Copy link
Copy Markdown
Contributor

@unional unional commented May 16, 2026

Closes #34818

What I did

Adds ability to customize tags type for CSF Next.

Note that I add type-plus as dev dependency to test the type.
Could not find a good way to test it otherwise.

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

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

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

  • New Features

    • Enhanced type support for story tags, allowing addons and previews to customize tag types with improved autocomplete and validation.
  • Tests

    • Added compile-time type assertions to verify correct tag typing and compatibility across addon and preview configurations.
  • Chores

    • Added development type utilities to support the new type checks.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Make story-level tags renderer-aware: AddonTypes may declare tags; BaseAnnotations.tags now conditionally derives from TRenderer['tags'] (falling back to Tag[]). Adds type-plus devDependency and tests that assert compile-time tags inference/assignability.

Changes

Renderer-aware tags customization

Layer / File(s) Summary
Tags type system
code/core/src/csf/story.ts
AddonTypes adds `tags?: Tag[]
Tags typing tests and dependency
code/core/package.json, code/core/src/csf/csf-factories.test.ts
Adds type-plus to devDependencies. Vitest imports updated to include expectTypeOf. New test suite verifies tags typing/inference for definePreviewAddon<{ tags: ... }>() and definePreview(...).type<{ tags: ... }>() using testType.canAssign.

🎯 3 (Moderate) | ⏱️ ~20 minutes


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

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Hi @unional

Thank you very much for your contribution!

Could you please complete the testing instructions with 1 or 2 scenarios so we can verify the feature ourselves?

@valentinpalkovic valentinpalkovic moved this from Empathy Queue (prioritized) to On Hold in Core Team Projects May 21, 2026
@valentinpalkovic valentinpalkovic self-assigned this May 21, 2026
@valentinpalkovic valentinpalkovic self-requested a review May 21, 2026 09:12
@unional
Copy link
Copy Markdown
Contributor Author

unional commented May 21, 2026

Could you please complete the testing instructions with 1 or 2 scenarios so we can verify the feature ourselves?

Hi @valentinpalkovic, the change is type related and the scenarios are in the unit tests added. What testing instructions do you need? You should see the autocompletion are working in the tests.

@valentinpalkovic valentinpalkovic moved this from On Hold to In Progress in Core Team Projects May 21, 2026
@valentinpalkovic valentinpalkovic changed the title feat: add tags type support for CSF Next CSF-Next: Add tags type support for May 21, 2026
@valentinpalkovic
Copy link
Copy Markdown
Contributor

Hi @unional,

The build is failing. Could you please take a look?

unional added 2 commits May 21, 2026 16:26
the looser `unknown[]` type doesn't work well with Generic + conditional type logic
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

Fails
🚫 The "#### Manual testing" section must be filled in. Please describe how to test the changes you've made, step by step, so that reviewers can confirm your PR works as intended.

Generated by 🚫 dangerJS against af92c4a

@unional
Copy link
Copy Markdown
Contributor Author

unional commented May 21, 2026

Hi @unional,

The build is failing. Could you please take a look?

fixed by strengthening the type from unknown[] to Tag[]

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: 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/core/src/csf/csf-factories.test.ts`:
- Around line 81-124: Add element-level "literal remainder" assertions to ensure
tags aren't widened to string[]: for both Parameters<typeof
preview.meta>[0]['tags'] and for the tags type on meta.story, extract the
element type (e.g. Elem = ...['tags'][number]), compute Remainder =
Exclude<Elem, string>, and add reciprocal testType.canAssign assertions
asserting 'foo' | 'bar' canAssign Remainder and Remainder canAssign 'foo' |
'bar' to catch widening; update the existing tests around preview.meta and
meta.story accordingly (refer to preview.meta, meta.story, and
testType.canAssign in the file).

In `@code/core/src/csf/story.ts`:
- Line 417: The conditional type for tags loses addon-provided tuple/element
types because AddonTypes.tags is optional, so TRenderer['tags'] can be
undefined; update the type expression that references TRenderer['tags'] so it
first removes undefined (e.g. via NonNullable or Exclude) before testing extends
string[] — i.e., change the check using TRenderer['tags'] to use
NonNullable<TRenderer['tags']> (or Exclude<TRenderer['tags'], undefined>) so
that the conditional preserves renderer/custom tuple types instead of always
falling back to plain string[]; locate the occurrence that reads like "tags?:
(TRenderer['tags'] extends string[] ? TRenderer['tags'] : string[]) | undefined"
and replace the conditional accordingly.
🪄 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: 2753e743-e25e-46d7-998b-27edc1ba38b0

📥 Commits

Reviewing files that changed from the base of the PR and between 799ab6c and 97cc282.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • code/core/package.json
  • code/core/src/csf/csf-factories.test.ts
  • code/core/src/csf/story.ts

Comment thread code/core/src/csf/csf-factories.test.ts
Comment thread code/core/src/csf/story.ts Outdated
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.

♻️ Duplicate comments (1)
code/core/src/csf/story.ts (1)

417-417: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Conditional type still doesn't preserve custom tags (duplicate issue)

This issue was flagged in a previous review and remains unresolved. Since AddonTypes.tags is optional, TRenderer['tags'] includes undefined, causing TRenderer['tags'] extends Tag[] to always be false and fall back to Tag[], which defeats the purpose of this PR.

The suggested fix from the previous review is correct, with a minor adjustment to use Tag[] instead of string[] for consistency with line 188:

Suggested fix
-  tags?: (TRenderer['tags'] extends Tag[] ? TRenderer['tags'] : Tag[]) | undefined;
+  tags?: NonNullable<TRenderer['tags']> extends Tag[]
+    ? NonNullable<TRenderer['tags']>
+    : Tag[];
🤖 Prompt for 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.

In `@code/core/src/csf/story.ts` at line 417, The conditional for the tags
property fails because TRenderer['tags'] is optional (includes undefined);
replace the check with a NonNullable-based conditional so undefined is stripped
before the extends test and the custom tag type is preserved. Concretely, update
the declaration using NonNullable<TRenderer['tags']> in the conditional (e.g.
tags?: (NonNullable<TRenderer['tags']> extends Tag[] ?
NonNullable<TRenderer['tags']> : Tag[]) | undefined) so TRenderer custom tag
types are retained while still falling back to Tag[].
🤖 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.

Duplicate comments:
In `@code/core/src/csf/story.ts`:
- Line 417: The conditional for the tags property fails because
TRenderer['tags'] is optional (includes undefined); replace the check with a
NonNullable-based conditional so undefined is stripped before the extends test
and the custom tag type is preserved. Concretely, update the declaration using
NonNullable<TRenderer['tags']> in the conditional (e.g. tags?:
(NonNullable<TRenderer['tags']> extends Tag[] ? NonNullable<TRenderer['tags']> :
Tag[]) | undefined) so TRenderer custom tag types are retained while still
falling back to Tag[].

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8370fae1-4c0f-4514-b31c-03cb5500a221

📥 Commits

Reviewing files that changed from the base of the PR and between 97cc282 and 2d677ed.

📒 Files selected for processing (1)
  • code/core/src/csf/story.ts

@valentinpalkovic valentinpalkovic merged commit e174cbe into storybookjs:next May 22, 2026
132 of 133 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Core Team Projects May 22, 2026
@unional unional deleted the tags-csf-next branch May 22, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants