storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.24k stars 9.26k forks source link

[Bug]: Cannot pass callback function as Input to Angular component using Storybook #25724

Open vneogi199 opened 8 months ago

vneogi199 commented 8 months ago

Describe the bug

I am attempting to pass a callback function as an Input to Angular component from a Story. This argument is not being passed through, Inputs of non-function types are being passed without any issue though. Tried with latest stable and alpha releases (Angular 17.1)

My story:

export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
    myFn: () => console.log('running'),
  },
  render: (args) => {
    console.log('Bug here => ', args, args.myFn); // args: {"primary": true,"label": "Button"}, args.myFn: undefined
    return {
      props: {
        ...args,
      },
      template: `<storybook-button ${argsToTemplate(args)}></storybook-button>`,
    };
  },
};

To Reproduce

https://github.com/vneogi199/storybook-input-callback-repro/blob/main/projects/my-lib/src/stories/button.stories.ts#L23-L38

System

System:
    OS: macOS 14.2.1
    CPU: (8) arm64 Apple M1
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.6.0 - /opt/homebrew/bin/node
    Yarn: 1.22.21 - /opt/homebrew/bin/yarn
    npm: 10.2.4 - /opt/homebrew/bin/npm <----- active
    pnpm: 8.14.1 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 120.0.6099.234
    Safari: 17.2.1
  npmPackages:
    @storybook/addon-docs: ^8.0.0-alpha.13 => 8.0.0-alpha.13 
    @storybook/addon-essentials: ^8.0.0-alpha.13 => 8.0.0-alpha.13 
    @storybook/addon-interactions: ^8.0.0-alpha.13 => 8.0.0-alpha.13 
    @storybook/addon-links: ^8.0.0-alpha.13 => 8.0.0-alpha.13 
    @storybook/angular: ^8.0.0-alpha.13 => 8.0.0-alpha.13 
    @storybook/blocks: ^8.0.0-alpha.13 => 8.0.0-alpha.13 
    @storybook/test: ^8.0.0-alpha.13 => 8.0.0-alpha.13 
    storybook: ^8.0.0-alpha.13 => 8.0.0-alpha.13

Additional context

No response

Marklb commented 8 months ago

I would consider that a complex arg, so you would need to set in on the props object in your render function or use a mapper. https://storybook.js.org/docs/writing-stories/args#mapping-to-complex-arg-values

Args get serialized to a string, when passed to the manager then deserialized from a string before it is passed through the story decorators. Even if Storybook serialized what it can to recreate it on deserialization, any referenced would be broken, so it is best to use a mapper on anything that can't be serialized, if possible. Setting the property on props in the render function is also fine, but it mostly looses the ability to be known by any decorators and addons, since it is not known until the story is about to render.

vneogi199 commented 8 months ago

@Marklb Thanks for the reply.

Looks like it is because of the filtering of args we are doing here: https://github.com/storybookjs/storybook/blob/c1fc85f671691ca8865b91dceb9686356ef76fa8/code/frameworks/angular/src/client/decorateStory.ts#L60-L68 So every argType needs to have an action or a control.

I got it working by adding:

argTypes: {
    myFn: {
      control: { type: 'function' },
    },
},
Complete story ```js export const Primary: Story = { args: { primary: true, label: 'Button', myFn: () => console.log('running'), }, argTypes: { myFn: { control: { type: 'function' }, }, }, render: (args) => { console.log('Bug solved here => ', args, args.myFn); return { props: { ...args, }, template: ``, }; }, }; ```
manbearwiz commented 5 months ago

I was using this workaround but the type changes in 8.0.9 don't allow it https://github.com/storybookjs/storybook/pull/26824

q1a0mu commented 5 months ago

I was using this workaround but the type changes in 8.0.9 don't allow it #26824

@manbearwiz I'm also using version 8.0.9, have you found a new workaround?

manbearwiz commented 5 months ago

I'm just sticking with 8.0.8 for now