Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actions don't show up in panel when using argTypesRegex #15012

Closed
Tracked by #23869
jonathanhuang13 opened this issue May 22, 2021 · 20 comments
Closed
Tracked by #23869

Actions don't show up in panel when using argTypesRegex #15012

jonathanhuang13 opened this issue May 22, 2021 · 20 comments

Comments

@jonathanhuang13
Copy link

jonathanhuang13 commented May 22, 2021

Describe the bug
Actions don't show up in the actions panel when using argTypesRegex parameter in preview.js or in the component.

Reproduction
Here is the reproduction: https://github.com/jonathanhuang13/storybook-repro

npm install
npm run storybook

There are two stories to see:

  • The Works story works with manually specifying the argTypes
  • The Buggy story doesn't work and it uses the argTypesRegex parameter

System

Environment Info:

  System:
    OS: macOS 11.3.1
    CPU: (8) x64 Apple M1
  Binaries:
    Node: 14.16.1 - ~/.asdf/installs/nodejs/14.16.1/bin/node
    npm: 6.14.12 - ~/.asdf/installs/nodejs/14.16.1/bin/npm
  Browsers:
    Chrome: 90.0.4430.212
    Safari: 14.1
  npmPackages:
    @storybook/addon-actions: ^6.2.9 => 6.2.9
    @storybook/addon-essentials: ^6.2.9 => 6.2.9
    @storybook/addon-links: ^6.2.9 => 6.2.9
    @storybook/react: ^6.2.9 => 6.2.9

Additional context
This additional context is from the original repo, not the reproduced repo. I have a component that takes a required prop onClickFoo. With the following story, I can see actions in the action panel when I click the appropriate button:

// Working

import React from 'react';
import { Story, Meta } from '@storybook/react';

import Editor, { EditorProps } from 'components/editor';

export default {
  title: 'Editor',
  component: Editor,
  argTypes: {
    onClickFoo: { action: 'changed' }, // Specifying argTypes by hand works
  },
} as Meta;

const Template: Story<EditorProps> = (args) => (
  <div className="h-60">
    <Editor {...args} />
  </div>
);

export const Base = Template.bind({});
Base.args = {
  prop1: 'prop1',
};

However, using argTypesRegex does not work on the component level. I do see the console log in the console though:

// Does not work
import React from 'react';
import { Story, Meta } from '@storybook/react';

import Editor, { EditorProps } from 'components/editor';

export default {
  title: 'Editor',
  component: Editor,
  parameters: { actions: { argTypesRegex: '^on.*' } }, // Specifying parameters does not work
} as Meta;

const Template: Story<EditorProps> = (args) => (
  <div className="h-60">
    <Editor {...args} />
  </div>
);

export const Base = Template.bind({});
Base.args = {
  prop1: 'prop1',
  onClickFoo: () => console.log('Hello world'), // Removing this causes error in storybook that 'onClickFoo' doesn't exist
};

Additionally, putting the argTypesRegex in preview.js doesn't work either:

// .storybook/preview.js

export const parameters = {
  actions: { argTypesRegex: '^on[A-Z].*' },
}
// Story

import React from 'react';
import { Story, Meta } from '@storybook/react';

import Editor, { EditorProps } from 'components/editor';

export default {
  title: 'Editor',
  component: Editor,
} as Meta;

const Template: Story<EditorProps> = (args) => (
  <div className="h-60">
    <Editor {...args} />
  </div>
);

export const Base = Template.bind({});
Base.args = {
  prop1: 'prop1',
  onClickFoo: () => console.log('Hello world'),
};
@yannbf
Copy link
Member

yannbf commented May 30, 2021

Hey @jonathanhuang13, I believe the problem is how you are typing your component. I personally have never seen such way of typing, I commonly see this:

- const TestComponent: (props: Props) => JSX.Element = (props) => {
+ const TestComponent = (props: Props): JSX.Element => {
  return (
    <div onClick={props.onClickFoo}>Hello World</div>
  );
};

If you do like that, and just remove the args altogether, it will work as intended:

const Template: Story<Props> = (args) => <TestComponent {...args} />;

export const Base = Template.bind({});
- Base.args = {
-   onClickFoo: () => console.log('Hello'), // Still buggy after commented out
- };

Actions will automatically detect properties based on the actions argTypesRegex and if there is no value being passed, it will fill the handler with an action, which will appear in the panel. If you are passing a value via args, it won't display any actions in the panel but rather call the callback you're passing.

@jonathanhuang13
Copy link
Author

@yannbf Thanks for taking a look at this. I've confirmed that how you've typed it works. It's strange how the other way of typing a component causes issues. I'll go ahead and close this though. Thanks!

@luxalpa
Copy link

luxalpa commented Feb 16, 2022

I would like this to be reopened if possible.
I can confirm that this is a bug. Typing it with Pick<ComponentProps<SomeComponent>, "onChange"> does not work, putting onChange in directly does. Apparently the Typescript support is a bit broken.

@swallowtail62
Copy link

I can confirm that this is a bug. Typing it with Pick<ComponentProps, "onChange"> does not work, putting onChange in directly does. Apparently the Typescript support is a bit broken.

I had the same problem.
It seems to happen when picking from a third party types.

type GoodComponentProps = { onClick: VoidFunction };  // OK
type GoodComponentProps2 = Pick<GoodComponentProps, 'onClick'>;  // OK


// e.g.
import { ButtonProps as MUIButtonProps } from '@mui/material/Button';

type BadComponentProps = Pick<MUIButtonProps, 'onClick'>;  // NG: Not work

@coler-j
Copy link

coler-j commented Nov 7, 2022

This does still seem to be an issue

@tcolinpa
Copy link

same issue here with third party types

@RickCardoso
Copy link
Contributor

RickCardoso commented Jan 19, 2023

Same here with union types

I have a modal component with

export type ModalProps = {
  ...

  /**
   * Callback called when a dismissed action is taken
   * @default undefined
   */
  onClose?: () => void;
}

and other modal components that use this one, their types are similar to this:

export type DialogProps = Omit<ModalProps, 'children' | 'actionRequired' | 'message'>;

On the Modal stories, the argTypesRegex works perfectly, on the Dialog or any other modal, it doesn't.

@jonathanhuang13 , can we reopen this?

@CallumHoward
Copy link

Also not working for me in React when the underlying component is typed like

export const Button = forwardRef<HTMLButtonElement, Props>(({children, ...props}, ref) => {
  // ...
  return (
    <BaseButton {...props} ref={ref}>
      {children}
    </BaseButton>
  );
})

@yannbf
Copy link
Member

yannbf commented Apr 23, 2023

@kasperpeulen could you check the aforementioned use cases? thanks <3

@kasperpeulen kasperpeulen reopened this May 1, 2023
@kasperpeulen kasperpeulen self-assigned this May 1, 2023
@legarsjules
Copy link

any news on this ?

@kasperpeulen
Copy link
Contributor

Shall we prioritize this? @shilman @vanessayuenn

@kasperpeulen kasperpeulen added this to the 7.x action args milestone Jul 28, 2023
@tocoteron
Copy link

Any news?

@yashsway
Copy link

yashsway commented Nov 2, 2023

I have a component configured like below where I have the same issue. Note the actions: { argTypesRegex: "^on.*" } setting in the default export in the story.js file doesn't wire up the prop onChange in the component to the actions tab in storybook. Weirdly it only happens for a component configured like this... where there is a context wrapped version of the component that I'm actually trying to use in Storybook.

export interface ComponentAProps = {
   ... // excluded for brevity
   onChange?: (newValue: string) => void;
}

const ComponentA = () => {
  const { ... } = useComponentAContext();
}

const ComponentAWithContext = (props: ComponentAProps) => <ComponentAContextProvider>
<ComponentA /></ComponentAContextProvider>;

export default ComponentAWithContext;
import ComponentA from "./ComponentA"; // should import the context wrapped default export

const Template = (args) => {
  // debugging - you can see here that Storybook isn't passing an `onChange` handler of it's own because of `argTypesRegex`. If it worked, you'll see it here.
  console.log(args);

  return <ComponentA {...args} />;
};

export const Basic = Template.bind({});

export default {
  title: "ComponentA",
  component: ComponentA,
  parameters: {
    componentSubtitle:
      "A neat subtitle",
    viewMode: "story",
    actions: { argTypesRegex: "^on.*" },
  },
};

I'm using Storybook (@storybook:react@6.5.16).

I've done some digging online and I found that making the following change to the default export is the only thing that worked (see https://storybook.js.org/docs/6.5/react/essentials/actions#action-args)

const Template = (args) => {
  // debugging - shows an `onChange` that Storybook passed in called `actionHandler`. So actions work!
  console.log(args);

  return <ComponentA {...args} />;
};

export default {
  title: "ComponentA",
  component: ComponentA,
  parameters: {
    componentSubtitle:
      "A neat subtitle",
    viewMode: "story",
    // doesn't wire up to the `onChange` prop sadly
    actions: { argTypesRegex: "^on.*" },
  },
 // explicitly specifying argTypes works!
 argTypes: {
    onChange: {
      action: "changed",
    },
  },
};

@eddiemonge
Copy link
Contributor

Doesn't work when doing a component like this either:

import MenuOpenIcon from '@mui/icons-material/MenuOpen';
import IconButton from '@mui/material/IconButton';

export default function MenuButton({ onClick }: { onClick(): void}) {
  return (
    <IconButton color="inherit" edge="start" onClick={onClick}>
      <MenuOpenIcon />
    </IconButton>
  )
}

@yannbf
Copy link
Member

yannbf commented Dec 1, 2023

cc @kasperpeulen

@vanessayuenn vanessayuenn removed this from the 7.x action args milestone Jan 9, 2024
@vanessayuenn vanessayuenn added this to the 8.0-beta milestone Jan 9, 2024
@valentinpalkovic
Copy link
Contributor

I can't reproduce it in the latest Storybook 8.0 alpha (8.0.0-alpha.11). I will close this.

@eddiemonge
Copy link
Contributor

@valentinpalkovic ok but what about in SB7?

@rikusen0335
Copy link

8.0, still can't achieve this

main.ts

export default {
  parameters: {
    actions: { argTypesRegex: '^on.*' },
  },
} satisfies Preview

Button.stories.tsx

import { Meta, StoryObj } from '@storybook/react'

import { Button } from '.'

export default {
  component: Button,
  title: 'atoms/Button'
} satisfies Meta<typeof Button>

type Story = StoryObj<typeof Button>

export const Default: Story = {
  args: {
    variant: 'primary',
    text: 'text'
  }
}

@yannbf
Copy link
Member

yannbf commented Mar 19, 2024

@rikusen0335 would you mind sharing the code of your Button component as well? Or even better, set it up here? https://storybook.new/

@rikusen0335
Copy link

@yannbf Will try to make reproduction on playground!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

No branches or pull requests