mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-04 15:11:10 +08:00
174 lines
5.9 KiB
Markdown
174 lines
5.9 KiB
Markdown
# Storybook Addon Actions
|
|
|
|
Storybook Addon Actions can be used to display data received by event handlers in [Storybook](https://storybook.js.org).
|
|
|
|
[Framework Support](https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md)
|
|
|
|

|
|
|
|
## Getting Started
|
|
|
|
Install:
|
|
|
|
```sh
|
|
npm i -D @storybook/addon-actions
|
|
```
|
|
|
|
Then, add following content to `.storybook/main.js`
|
|
|
|
```js
|
|
module.exports = {
|
|
addons: ['@storybook/addon-actions'],
|
|
};
|
|
```
|
|
|
|
## Actions args
|
|
|
|
Starting in SB6.0, we recommend using the `actions` story parameter to specify actions. There are two relevant options `actions.args` and `actions.argTypesRegex` which the actions addon uses to inject actions into your story functions as Storybook Args.
|
|
|
|
The following example uses the `actions.args` array to generate actions that are passed into the story (when `passArgsFirst` is set to `true`):
|
|
|
|
```js
|
|
import Button from './button';
|
|
|
|
export default {
|
|
title: 'Button',
|
|
parameters: { actions: { args: ['onClick'] } },
|
|
};
|
|
|
|
export const defaultView = ({ onClick }) => <Button onClick={onClick}>Hello World!</Button>;
|
|
```
|
|
|
|
Alternatively, suppose you have a naming convention, like `onX` for event handlers. The following configuration automatically creates actions for each `onX` argType (which you can either specify manually or generate automatically using [Storybook Docs](https://www.npmjs.com/package/@storybook/addon-docs).
|
|
|
|
```js
|
|
import Button from './button';
|
|
|
|
export default {
|
|
title: 'Button',
|
|
component: Button,
|
|
parameters: { actions: { argTypesRegex: '^on.*' } },
|
|
};
|
|
|
|
export const defaultView = ({ onClick }) => <Button onClick={onClick}>Hello World!</Button>;
|
|
```
|
|
|
|
## Manually-specified actions
|
|
|
|
Import the `action` function and use it to create actions handlers. When creating action handlers, provide a **name** to make it easier to identify.
|
|
|
|
> _Note: Make sure NOT to use reserved words as function names. [issues#29](https://github.com/storybookjs/storybook-addon-actions/issues/29#issuecomment-288274794)_
|
|
|
|
```js
|
|
import { action } from '@storybook/addon-actions';
|
|
import Button from './button';
|
|
|
|
export default {
|
|
title: 'Button',
|
|
component: Button,
|
|
};
|
|
|
|
export const defaultView = () => <Button onClick={action('button-click')}>Hello World!</Button>;
|
|
```
|
|
|
|
## Multiple actions
|
|
|
|
If your story requires multiple actions, it may be convenient to use `actions` to create many at once:
|
|
|
|
```js
|
|
import { actions } from '@storybook/addon-actions';
|
|
import Button from './button';
|
|
|
|
export default {
|
|
title: 'Button',
|
|
component: Button,
|
|
};
|
|
|
|
// This will lead to { onClick: action('onClick'), ... }
|
|
const eventsFromNames = actions('onClick', 'onMouseOver');
|
|
|
|
// This will lead to { onClick: action('clicked'), ... }
|
|
const eventsFromObject = actions({ onClick: 'clicked', onMouseOver: 'hovered' });
|
|
|
|
export const first = () => <Button {...eventsFromNames}>Hello World!</Button>;
|
|
|
|
export const second = () => <Button {...eventsFromObject}>Hello World!</Button>;
|
|
```
|
|
|
|
## Action Decorators
|
|
|
|
If you wish to process action data before sending them over to the logger, you can do it with action decorators.
|
|
|
|
`decorate` takes an array of decorator functions. Each decorator function is passed an array of arguments, and should return a new arguments array to use. `decorate` returns a object with two functions: `action` and `actions`, that act like the above, except they log the modified arguments instead of the original arguments.
|
|
|
|
```js
|
|
import { decorate } from '@storybook/addon-actions';
|
|
import Button from './button';
|
|
|
|
export default {
|
|
title: 'Button',
|
|
component: Button,
|
|
};
|
|
|
|
const firstArg = decorate([args => args.slice(0, 1)]);
|
|
|
|
export const first = () => <Button onClick={firstArg.action('button-click')}>Hello World!</Button>;
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Arguments which are passed to the action call will have to be serialized while be "transferred"
|
|
over the channel.
|
|
|
|
This is not very optimal and can cause lag when large objects are being logged, for this reason it is possible
|
|
to configure a maximum depth.
|
|
|
|
The action logger, by default, will log all actions fired during the lifetime of the story. After a while
|
|
this can make the storybook laggy. As a workaround, you can configure an upper limit to how many actions should
|
|
be logged.
|
|
|
|
To apply the configuration globally use the `configureActions` function in your `preview.js` file.
|
|
|
|
```js
|
|
import { configureActions } from '@storybook/addon-actions';
|
|
|
|
configureActions({
|
|
depth: 100,
|
|
// Limit the number of items logged into the actions panel
|
|
limit: 20,
|
|
});
|
|
```
|
|
|
|
To apply the configuration per action use:
|
|
|
|
```js
|
|
action('my-action', {
|
|
depth: 5,
|
|
});
|
|
```
|
|
|
|
### Available Options
|
|
|
|
| Name | Type | Description | Default |
|
|
| -------------------- | ------- | ----------------------------------------------------------------------------------- | ------- |
|
|
| `depth` | Number | Configures the transferred depth of any logged objects. | `10` |
|
|
| `clearOnStoryChange` | Boolean | Flag whether to clear the action logger when switching away from the current story. | `true` |
|
|
| `limit` | Number | Limits the number of items logged in the action logger | `50` |
|
|
|
|
## withActions decorator
|
|
|
|
You can define action handles in a declarative way using `withActions` decorators. It accepts the same arguments as [`actions`](#multiple-actions)
|
|
Keys have `'<eventName> <selector>'` format, e.g. `'click .btn'`. Selector is optional. This can be used with any framework but is especially useful for `@storybook/html`.
|
|
|
|
```js
|
|
import { withActions } from '@storybook/addon-actions';
|
|
import Button from './button';
|
|
|
|
export default {
|
|
title: 'Button',
|
|
decorators: [withActions('mouseover', 'click .btn')],
|
|
};
|
|
|
|
export const first = () => <Button className="btn">Hello World!</Button>;
|
|
```
|