diff --git a/code/frameworks/angular-vite/src/client/decorateStory.test.ts b/code/frameworks/angular-vite/src/client/decorateStory.test.ts index d2ca56f304b3..96d80badc99f 100644 --- a/code/frameworks/angular-vite/src/client/decorateStory.test.ts +++ b/code/frameworks/angular-vite/src/client/decorateStory.test.ts @@ -6,8 +6,7 @@ import { componentWrapperDecorator } from './decorators.ts'; import decorateStory from './decorateStory.ts'; import type { AngularRenderer } from './types.ts'; -// TODO: Fix. Test is infinitely running. -describe.skip('decorateStory', () => { +describe('decorateStory', () => { describe('angular behavior', () => { it('should use componentWrapperDecorator with args', () => { const decorators: DecoratorFunction[] = [ @@ -37,8 +36,11 @@ describe.skip('decorateStory', () => { grandparentInput: 'grandparent input', parentOutput: expect.any(Function), }, - template: - '', + template: ` + +`, userDefinedTemplate: true, }); }); @@ -76,8 +78,11 @@ describe.skip('decorateStory', () => { grandparentInput: 'Grandparent input', sameInput: 'Story input', }, - template: - '', + template: ` + +`, userDefinedTemplate: true, }); }); @@ -207,7 +212,7 @@ describe.skip('decorateStory', () => { }); }); - it('should only keeps args with a control or an action in argTypes', () => { + it('passes every arg to the story, including ones carrying no control', () => { const decorated = decorateStory( (context: StoryContext) => ({ template: `Args available in the story : ${Object.keys(context.args).join()}`, @@ -222,17 +227,17 @@ describe.skip('decorateStory', () => { argTypes: { withControl: { control: { type: 'object' }, name: 'withControl' }, withAction: { action: 'onClick', name: 'withAction' }, - toRemove: { name: 'toRemove' }, + plain: { name: 'plain' }, }, args: { withControl: 'withControl', withAction: () => ({}), - toRemove: 'toRemove', + plain: 'plain', }, }) ) ).toEqual({ - template: 'Args available in the story : withControl,withAction', + template: 'Args available in the story : withControl,withAction,plain', userDefinedTemplate: true, }); }); diff --git a/code/frameworks/angular-vite/src/client/decorateStory.ts b/code/frameworks/angular-vite/src/client/decorateStory.ts index f25c5e6ea8a3..3b65a417056c 100644 --- a/code/frameworks/angular-vite/src/client/decorateStory.ts +++ b/code/frameworks/angular-vite/src/client/decorateStory.ts @@ -2,14 +2,13 @@ import { sanitizeStoryContextUpdate } from 'storybook/preview-api'; import type { DecoratorFunction, LegacyStoryFn, StoryContext } from 'storybook/internal/types'; import { computesTemplateFromComponent } from './renderer/ComputesTemplateFromComponent.ts'; -import { getComponentInputsOutputs } from './renderer/utils/NgComponentAnalyzer.ts'; import type { AngularRenderer } from './types.ts'; export default function decorateStory( mainStoryFn: LegacyStoryFn, decorators: DecoratorFunction[] ): LegacyStoryFn { - const returnDecorators = [cleanArgsDecorator, ...decorators].reduce( + const returnDecorators = decorators.reduce( (previousStoryFn: LegacyStoryFn, decorator) => (context: StoryContext) => { const decoratedStory = decorator((update) => { @@ -50,49 +49,3 @@ const prepareMain = ( function hasNoTemplate(template: string | null | undefined): template is undefined { return template === null || template === undefined; } - -const cleanArgsDecorator: DecoratorFunction = (storyFn, context) => { - if (!context.argTypes || !context.args) { - return storyFn(); - } - - // When no argTypes are defined for the story (e.g. compodoc metadata is - // unavailable, or the class name was renamed by a bundler so the compodoc - // lookup fails) we have no signal to distinguish "real" component inputs - // from other args. Pass them through unchanged rather than stripping every - // arg the user explicitly set. - // - // Server docgen leaves the same gap: it holds the component metadata and - // infers controls where the UI reads them, so nothing here carries a control - // and a public property that is not an @Input would lose the value its story set. - if (Object.keys(context.argTypes).length === 0 || globalThis.FEATURES?.experimentalDocgenServer) { - return storyFn(); - } - - // Without compodoc-derived argTypes the decorator-extracted control/action - // signal disappears for component inputs/outputs, so fall back to Angular's - // own runtime metadata: any arg whose name matches a component @Input/@Output - // (incl. signal inputs/outputs) must be passed through even if its argType is - // missing/incomplete. - const componentIO = context.component - ? getComponentInputsOutputs(context.component) - : { inputs: [], outputs: [] }; - const componentBindings = new Set([ - ...componentIO.inputs.map((i) => i.templateName), - ...componentIO.outputs.map((o) => o.templateName), - ]); - - const argsToClean = context.args; - - context.args = Object.entries(argsToClean).reduce((obj, [key, arg]) => { - const argType = context.argTypes[key]; - - // Keep args declared as component inputs/outputs OR with a control/action. - if (argType?.action || argType?.control || componentBindings.has(key)) { - return { ...obj, [key]: arg }; - } - return obj; - }, {}); - - return storyFn(); -};