[Feature Request]: Track `passedArgs` separately from `initialArgs` in `StoryContext` so code snippets in docs pages show only the props user specified.
#23,317 opened on 2023年7月5日
説明
Is your feature request related to a problem? Please describe
This feature request is related to #22930.
Currently additional args from the ArgEnhancers in addons (e.g., @storybook/addon-actions and @storybook/addon-interactions) are merged into StoryContext.initialArgs, which initially only contains user-specified args. This unfortunately causes <Source /> in a docs page to have additional props that have been added, not by the user but by addons, show up.
Describe the solution you'd like
I think this could be improved by tracking the args that the user has explicitly specified in their stories, say passedArgs, separate from the merged initialArgs in StoryContext. And then use this information when producing code snippets in docs pages.
Concretely, the solution I'd like would be something like the following:
Add passedArgs to StoryContextForEnhancers type found in @storybook/csf:
type StoryContextForEnhancers<TRenderer extends Renderer = Renderer, TArgs = Args> = StoryIdentifier & {
component?: (TRenderer & {
T: any;
})['component'];
subcomponents?: Record<string, (TRenderer & {
T: any;
})['component']>;
parameters: Parameters;
initialArgs: TArgs;
passedArgs?: TArgs; // this
argTypes: StrictArgTypes<TArgs>;
};
Add passedArgs to contextForEnhancers in preparePartialAnnotations found at code/lib/preview-api/src/modules/store/csf/prepareStory.ts
// Pull out args[X] into initialArgs for argTypes enhancers
const passedArgs: Args = {
...projectAnnotations.args,
...componentAnnotations.args,
...storyAnnotations?.args,
} as Args;
const contextForEnhancers: StoryContextForEnhancers<TRenderer> = {
componentId: componentAnnotations.id,
title: componentAnnotations.title,
kind: componentAnnotations.title, // Back compat
id: storyAnnotations?.id || componentAnnotations.id,
// if there's no story name, we create a fake one since enhancers expect a name
name: storyAnnotations?.name || '__meta',
story: storyAnnotations?.name || '__meta', // Back compat
component: componentAnnotations.component,
subcomponents: componentAnnotations.subcomponents,
tags,
parameters,
initialArgs: passedArgs,
passedArgs, // this
argTypes: passedArgTypes,
};
Pass context.passedArgs to produce a source string.
// code/renderers/react/src/docs/jsxDecorator.tsx
// Inside `jsxDecorator` function
...
// Exclude decorators from source code snippet by default
const storyJsx = context?.parameters.docs?.source?.excludeDecorators
? (context.originalStoryFn as ArgsStoryFn<ReactRenderer>)(context.passedArgs, context) // `context.passedArgs` instead of `context.args`
: storyFn({ args: context.passedArgs }); // `context.passedArgs` instead of `context.args`
const sourceJsx = mdxToJsx(storyJsx);
const rendered = renderJsx(sourceJsx, options);
if (rendered) {
jsx = rendered;
}
...
When I tested this locally, the docs page doesn't show any unspecified props in code snippets, and in story pages, @storybook/addon-actions still works correctly.
Now, I've probably missed a lot of things, so I need some reviews / comments on the proposed fix from the core team!
Thanks.
Describe alternatives you've considered
No response
Are you able to assist to bring the feature to reality?
yes, I can
Additional context
No response