Skip to content

Controls: Resolve select control inference for optional unions exceeding 28 elements#35354

Open
Ranit-dev2004 wants to merge 1 commit into
storybookjs:nextfrom
Ranit-dev2004:patch-control-inference
Open

Controls: Resolve select control inference for optional unions exceeding 28 elements#35354
Ranit-dev2004 wants to merge 1 commit into
storybookjs:nextfrom
Ranit-dev2004:patch-control-inference

Conversation

@Ranit-dev2004

@Ranit-dev2004 Ranit-dev2004 commented Jul 2, 2026

Copy link
Copy Markdown

Closes #12641

What I did

Fixes an issue where large optional TypeScript union types that exceed docgen token limits fallback to broad type definitions, causing Storybook to fall back to a raw text or object control instead of mapping to an interactive select dropdown.

Changes

  • Updated the default fallback switch case within inferControls.ts.
  • Implemented an isUnionList verification helper to safely capture the inner array elements from the fallback token payload.
  • Mapped valid options dynamically into a functional select control with a fallback value filtering mechanism.

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

  1. Pull down this branch and launch a standard template sandbox environment.
  2. Inject a TypeScript property containing an optional union type with a large number of literal choices (exceeding 28 elements) into an existing component template (e.g., TsTypes).
  3. Open the sandboxed Storybook UI dashboard.
  4. Verify that the control correctly renders as a functional dropdown selector matching all available variants.

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

  • Declare whether manual QA will be needed for this PR during the next release, through qa:needed or qa:skip

  • 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.

Summary by CodeRabbit

  • New Features

    • Dropdown controls now appear for union-like values, even when explicit options aren’t provided.
    • When available, the UI uses the provided option list; otherwise, it derives selectable values from the type information.
  • Bug Fixes

    • Improved fallback behavior so fields without selectable values continue to use a standard object control.
    • Removed unsupported empty values from derived dropdown options for cleaner selection lists.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor
Fails
🚫

PR is not labeled with one of: ["cleanup","BREAKING CHANGE","feature request","bug","documentation","maintenance","build","dependencies"]

🚫

PR is not labeled with one of: ["ci:normal","ci:merged","ci:daily","ci:docs"]

🚫

PR is not labeled with one of: ["qa:needed","qa:skip","qa:success"]

Generated by 🚫 dangerJS against 863d68a

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The inferControl function's default case in inferControls.ts was updated to derive select control options from either explicit options or a filtered array of string/number values from (type as any).value, falling back to object control otherwise.

Changes

Infer Controls Update

Layer / File(s) Summary
Select control option derivation
code/core/src/preview-api/modules/store/inferControls.ts
The default case now distinguishes explicit options from derived union value lists, populating select control options accordingly, or falling back to object control when neither is present.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Estimated code review effort: 1 (Trivial) | ~5 minutes


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.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
code/core/src/preview-api/modules/store/inferControls.ts (1)

68-82: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider typing the fallback token instead of any.

(type as any).value bypasses type safety, whereas the enum case above uses type as SBEnumType. A narrower local type (or extending SBEnumType) for the fallback token would preserve type checking for valueList.

🤖 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/preview-api/modules/store/inferControls.ts` around lines 68 -
82, The fallback branch in inferControls currently uses (type as any).value,
which bypasses type safety and should be narrowed. Update the default case to
use a typed local shape or extend SBEnumType for the fallback token so valueList
is checked properly, and keep the existing select/options logic intact while
removing the any cast.
🤖 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.

Nitpick comments:
In `@code/core/src/preview-api/modules/store/inferControls.ts`:
- Around line 68-82: The fallback branch in inferControls currently uses (type
as any).value, which bypasses type safety and should be narrowed. Update the
default case to use a typed local shape or extend SBEnumType for the fallback
token so valueList is checked properly, and keep the existing select/options
logic intact while removing the any cast.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: efc015d8-6b9c-4854-845e-cb8b1fece631

📥 Commits

Reviewing files that changed from the base of the PR and between 15dcad5 and 863d68a.

📒 Files selected for processing (1)
  • code/core/src/preview-api/modules/store/inferControls.ts

@Ranit-dev2004 Ranit-dev2004 changed the title fix: resolve select control inference for optional unions exceeding 2… Controls: Resolve select control inference for optional unions exceeding 28 elements Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Problem with storybook-controls of type "select"

1 participant