Controls: Fix select controls for optional unions in Flow and nested options#34495
Controls: Fix select controls for optional unions in Flow and nested options#34495MastadoonPrime wants to merge 2 commits intostorybookjs:nextfrom
Conversation
…options Closes storybookjs#12641 This commit addresses two remaining issues with Storybook Controls of type "select": 1. Flow converter: Optional props in Flow add `void` to the union type, causing the enum detection to fail (same bug that was fixed for TypeScript in storybookjs#33200). The fix filters out `void` elements before checking if all remaining elements are literals, allowing optional Flow unions to correctly display as select controls. 2. Options nested inside control: Users commonly write `control: { type: "select", options: [...] }` instead of the correct `control: { type: "select" }, options: [...]`. The normalizeInputType function now extracts options from the control object to the top level when no top-level options are already specified, making both syntaxes work. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughFlow union-to-enum conversion now ignores Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
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.
🧹 Nitpick comments (1)
code/core/src/preview-api/modules/store/csf/normalizeInputTypes.test.ts (1)
127-158: Good test coverage for the new options extraction feature.The tests comprehensively cover both scenarios: extracting nested options when no top-level options exist, and preserving top-level options when both are present.
Minor style note: This new test block uses double quotes (
") while the rest of the file uses single quotes ('). Consider aligning with the existing file style for consistency.,
🧹 Optional: Align quote style with rest of file
-describe("normalizeInputType - options extraction", () => { - it("extracts options from inside control object to top level", () => { +describe('normalizeInputType - options extraction', () => { + it('extracts options from inside control object to top level', () => { expect( normalizeInputType( { - control: { type: "select", options: ["a", "b", "c"] }, + control: { type: 'select', options: ['a', 'b', 'c'] }, }, - "arg" + 'arg' ) ).toEqual({ - name: "arg", - options: ["a", "b", "c"], - control: { type: "select", disable: false }, + name: 'arg', + options: ['a', 'b', 'c'], + control: { type: 'select', disable: false }, }); }); - it("does not override existing top-level options with control.options", () => { + it('does not override existing top-level options with control.options', () => { expect( normalizeInputType( { - options: ["x", "y"], - control: { type: "select", options: ["a", "b", "c"] }, + options: ['x', 'y'], + control: { type: 'select', options: ['a', 'b', 'c'] }, }, - "arg" + 'arg' ) ).toEqual({ - name: "arg", - options: ["x", "y"], - control: { type: "select", options: ["a", "b", "c"], disable: false }, + name: 'arg', + options: ['x', 'y'], + control: { type: 'select', options: ['a', 'b', 'c'], disable: false }, }); }); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@code/core/src/preview-api/modules/store/csf/normalizeInputTypes.test.ts` around lines 127 - 158, The test block in normalizeInputTypes.test.ts uses double quotes instead of the file's single-quote style; update all string literals in this new describe/it block (e.g., the describe title, it titles, the call to normalizeInputType and expected object keys like "arg", "select", and array elements) to use single quotes so the test file's quoting is consistent with the rest of the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@code/core/src/preview-api/modules/store/csf/normalizeInputTypes.test.ts`:
- Around line 127-158: The test block in normalizeInputTypes.test.ts uses double
quotes instead of the file's single-quote style; update all string literals in
this new describe/it block (e.g., the describe title, it titles, the call to
normalizeInputType and expected object keys like "arg", "select", and array
elements) to use single quotes so the test file's quoting is consistent with the
rest of the file.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1bcc81a2-6bab-44ab-9ea4-b44ca1375f82
📒 Files selected for processing (3)
code/core/src/docs-tools/argTypes/convert/flow/convert.tscode/core/src/preview-api/modules/store/csf/normalizeInputTypes.test.tscode/core/src/preview-api/modules/store/csf/normalizeInputTypes.ts
Address CodeRabbit nit: align quote style in normalizeInputType options extraction tests with the rest of the file.
What
Closes #12641
This PR addresses two remaining issues with Storybook Controls of type "select" that were not fully resolved by #33200.
Why
1. Flow converter missing
voidfilteringPR #33200 fixed the TypeScript converter to filter out
undefinedfrom union types before checking if all elements are literals (for enum/select detection). However, the Flow converter has the same bug — optional props in Flow addvoidto the union type, causing the enum detection to fail. This results in optional union props displaying as "object" controls instead of "select" dropdowns.2. Options nested inside control object
Users commonly write
control: { type: "select", options: [...] }instead of the documentedcontrol: { type: "select" }, options: [...]. The Storybook documentation showsoptionsat the argType level, but many users (and even some examples) nest it insidecontrol. Previously this silently failed — the control would render as a select but with no options. NownormalizeInputTypeextractsoptionsfrom the control object to the top level when no top-leveloptionsare already specified.How
Flow converter (
convert/flow/convert.ts)isVoidtype guard to detect Flowvoidtypesvoidelements from union before checking if all remaining elements are literalsnormalizeInputTypes (
normalizeInputTypes.ts)optionspropertyoptionsexists insidecontroland no top-leveloptionsis set, extract it to the top leveloptionsalready exists, leavecontrol.optionsas-is (top-level takes precedence)Tests (
normalizeInputTypes.test.ts)optionsfrom inside control object to top leveloptionswithcontrol.optionsHow to test
Flow optional union fix
Nested options fix
argTypes: { size: { control: { type: "select", options: ["sm", "md", "lg"] } } }argTypes: { size: { control: { type: "select" }, options: ["sm", "md", "lg"] } }still worksChecklist
Summary by CodeRabbit
Bug Fixes
Tests