fix(app): support CSF v3 stories in composeEnhancers (#602)#632
Open
darioabc wants to merge 1 commit into
Open
fix(app): support CSF v3 stories in composeEnhancers (#602)#632darioabc wants to merge 1 commit into
darioabc wants to merge 1 commit into
Conversation
Storybook's Component Story Format v3 (the default since Storybook 7,
2023) describes a story as a plain object — { args?, render?, ... } —
rather than a React function component with property attachments. Ladle
previously passed module[storyName] (the object) directly as 'component'
to ArgsProvider, whose React.createElement(component, props) threw
'Element type is invalid: expected a string ... but got: object'.
Resolve the named export to a real component before passing it down:
- typeof storyExport === 'function': CSF v2, use directly
- typeof storyExport === 'object' with render fn: wrap renderFn
- typeof storyExport === 'object' with meta.component: render
meta.component with merged args (covers args-only / empty /
decorators-only)
- else: defensive fallback renderer
CSF v2 stories are unchanged. Args/argTypes spread reads from
storyExport symmetrically for both shapes.
Closes tajo#602.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #602.
Background
Storybook's Component Story Format v3 (the default since Storybook 7, 2023) defines a story as a plain object:
Ladle today only handles CSF v2, where the named export is a
React.FCwith.args/.argTypes/.decoratorsattached as function properties. With CSF v3 stories,composeEnhancerspasses the plain object toArgsProvider, which doesReact.createElement(component, props)— and React 19 (and 17/18 alike) throwsElement type is invalid: expected a string … or a class/function … but got: object.Verified the failure in a 312-story production codebase — every story errored under Ladle 5.1.1 + React 19. The fix has been running locally via
patch-packageagainst an 841-story production sweep with 0 ArgsProvider errors and 0 navigation errors before this PR was filed.Change
packages/ladle/lib/app/src/compose-enhancers.tsx: whenmodule[storyName]is an object, resolve a real component before passing it toArgsProvider:storyExport.renderis a function, wrap it as(props) => render(props)socreateElementreceives a function..component, rendermeta.componentwith the merged args (covers CSF v3 args-only and empty stories).CSF v2 stories (named-export-is-a-function) are unchanged — the
typeof storyExport === "function"branch keeps the existing path.Args / argTypes spread now walks
storyExport.args/storyExport.argTypes(instead of relying onmodule[storyName].args); the new spread is symmetric for both shapes.Test plan
pnpm typecheck,pnpm lint, unit tests underpackages/ladle, all e2e fixtures).e2e/csf3package with Playwright spec covering four CSF v3 shapes:meta.component)renderFn)meta.component)e2e/decoratorscontinue to work (decorator chain, args, params, mock-date).Out of scope
Story<P>typing (currentlyextends React.FC<P>) to accept the object form. The runtime fix is sufficient for codebases that importStoryObjfrom@storybook/react; a follow-up PR can broaden Ladle's own type to match Storybook'sStoryObj<…>.TSSatisfiesExpressionparser unwrap for named-identifier default exports (separate PR).