feat(storybook): from addon-knobs to controls (#6068)

This commit is contained in:
Katerina Skroumpelou 2021-06-25 18:17:48 +03:00 committed by GitHub
parent ea0c6a33f0
commit e13b423ddb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 914 additions and 496 deletions

View File

@ -80,37 +80,43 @@ nx run project-name-e2e:e2e
The url that Cypress points to should look like this:
`'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'`
`'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'`
- `buttoncomponent` is a lowercase version of the `Title` in the `*.stories.ts` file.
- `primary` is the name of an individual story.
- `knob-style=default` sets the `style` knob to a value of `default`.
- `style=default` sets the `style` arg to a value of `default`.
Changing knobs in the url query parameters allows your Cypress tests to test different configurations of your component.
Changing args in the url query parameters allows your Cypress tests to test different configurations of your component. You can [read the documentation](https://storybook.js.org/docs/angular/writing-stories/args#setting-args-through-the-url) for more information.
### Example Files
**\*.component.stories.ts file**
```typescript
import { text, number } from '@storybook/addon-knobs';
import { moduleMetadata, Story, Meta } from '@storybook/angular';
import { ButtonComponent } from './button.component';
export default {
title: 'ButtonComponent',
};
export const primary = () => ({
moduleMetadata: {
imports: [],
},
component: ButtonComponent,
props: {
text: text('text', 'Click me!'),
padding: number('padding', 0),
style: text('style', 'default'),
},
decorators: [
moduleMetadata({
imports: [],
}),
],
} as Meta<ButtonComponent>;
const Template: Story<ButtonComponent> = (args: ButtonComponent) => ({
component: ButtonComponent,
props: args,
});
export const Primary = Template.bind({});
Primary.args = {
text: 'Click me!',
padding: 0,
style: 'default',
};
```
**Cypress \*.spec.ts file**
@ -119,7 +125,7 @@ export const primary = () => ({
describe('shared-ui', () => {
beforeEach(() =>
cy.visit(
'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'
'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'
)
);
@ -138,16 +144,14 @@ To register an [addon](https://storybook.js.org/addons/) for all storybook insta
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js` use the `addDecorator` function.
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js`, you can export an array called `decorators`.
```typescript
import { configure, addDecorator } from '@storybook/angular';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
**-- OR --**
@ -159,22 +163,40 @@ To register an [addon](https://storybook.js.org/addons/) for a single storybook
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in `preview.js` use the `addDecorator` function.
2. If a decorator is required, in `preview.js` you can export an array called `decorators`.
```typescript
import { configure, addDecorator } from '@storybook/angular';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
### More Information
For more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/basics/introduction/).
## From knobs to controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. More can be found [on the official Storybook docs](https://storybook.js.org/docs/react/writing-stories/args).
From **Nx v12.5** and on, the `@nrwl/storybook` package will be using `@storybook/addon-controls` instead of `@storybook/addon-knobs` to generate stories.
### For new Nx workspaces
- Generators will generate your Storybook configuration files and your Stories using Controls/args instead of knobs
- The `storybook-configuration` generator will install the [`@storybook/addon-essentials`](https://storybook.js.org/docs/riot/essentials/introduction) package, part of which is `@storybook/addon-controls`. This includes some more "essential" Storybook features (eg. `docs`). You can [disable features you do not need](https://storybook.js.org/docs/riot/essentials/introduction#disabling-addons) anytime in your `main.js`.
- Cypress e2e tests will be generated, [using the args URL](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) to set args in the controls.
### For existing Nx workspaces
- If you `nx migrate` to the latest version, your `package.json` will be updated to include the `@storybook/addon-essentials` package. The `@storybook/addon-essentials` addon will be added in your `addons` array in your root `main.js` file. You will need to run `npm/yarn install` to have it installed.
- If you install manually the latest version of `@nrwl/storybook`, `@nrwl/workspace` and `@nrwl/angular` or `@nrwl/react`, you will need to manually do `yarn add -D @storybook/addon-essentials`. You will also need to add the addon manually in your `addons` array in your root `main.js` file.
- All the stories you generate from that moment on will be using controls/args
- Your existing stories will not be touched and will still work
## Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
@ -290,11 +312,11 @@ If you have not changed the content of the files which the `storybook-configurat
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-knobs/register'],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should only have the `@storybook/addon-knobs/register` addon, which we already put in the array. You can now delete the `addons.js` file.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
@ -323,10 +345,10 @@ After you add any addons in the `main.js` file, you can safely delete the `addon
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```typescript
import { addDecorator } from '<%= uiFramework %>';
import { withKnobs } from '@storybook/addon-knobs';
import { addDecorator } from '@storybook/angular';
import { YourDecorator } from '@storybook/<something>';
addDecorator(withKnobs);
addDecorator(YourDecorator);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
@ -372,13 +394,3 @@ Your folder structure should now look like this:
├── README.md
└── etc...
```
### Storybook v6 args and controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. Feel free to use the new args way of defining stories. More can be found
[on the official Storybook docs](https://storybook.js.org/docs/angular/writing-stories/args).
> **Note:** Nx does not yet automatically generate stories that use the args syntax. The main reason is that args don't
> yet support being loaded via the iframe URL which is used in Nx to setup your Storybook based e2e tests. Once support
> is present in Storybook v6, we will provide a way to generate args & controls based stories. More on the progress [here](https://github.com/storybookjs/storybook/issues/12291).

View File

@ -71,28 +71,35 @@ nx run project-name-e2e:e2e
The url that Cypress points to should look like this:
`'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'`
`'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'`
- `buttoncomponent` is a lowercase version of the `Title` in the `*.stories.ts` file.
- `primary` is the name of an individual story.
- `knob-style=default` sets the `style` knob to a value of `default`.
- `style=default` sets the `style` arg to a value of `default`.
Changing knobs in the url query parameters allows your Cypress tests to test different configurations of your component.
Changing args in the url query parameters allows your Cypress tests to test different configurations of your component. You can [read the documentation](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) for more information.
### Example Files
**\*.stories.tsx file**
```typescript
import React from 'react';
import { text, number } from '@storybook/addon-knobs';
import { Button } from './button';
import { Story, Meta } from '@storybook/react';
import { Button, ButtonProps } from './button';
export default { title: 'Button' };
export default {
component: Button,
title: 'Button',
} as Meta;
export const primary = () => (
<Button padding={number('Padding', 0)} text={text('Text', 'Click me')} />
);
const Template: Story<ButtonProps> = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
text: 'Click me!',
padding: 0,
style: 'default',
};
```
**Cypress \*.spec.ts file**
@ -101,7 +108,7 @@ export const primary = () => (
describe('shared-ui', () => {
beforeEach(() =>
cy.visit(
'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'
'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'
)
);
@ -120,16 +127,14 @@ To register an [addon](https://storybook.js.org/addons/) for all storybook insta
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js` use the `addDecorator` function.
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js`, you can export an array called `decorators`.
```typescript
import { configure, addDecorator } from '@storybook/react';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
**-- OR --**
@ -141,22 +146,40 @@ To register an [addon](https://storybook.js.org/addons/) for a single storybook
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in `preview.js` use the `addDecorator` function.
2. If a decorator is required, in `preview.js` you can export an array called `decorators`.
```typescript
import { configure, addDecorator } from '@storybook/react';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
### More Information
For more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/basics/introduction/).
## From knobs to controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. More can be found [on the official Storybook docs](https://storybook.js.org/docs/react/writing-stories/args).
From **Nx v12.5** and on, the `@nrwl/storybook` package will be using `@storybook/addon-controls` instead of `@storybook/addon-knobs` to generate stories.
### For new Nx workspaces
- Generators will generate your Storybook configuration files and your Stories using Controls/args instead of knobs
- The `storybook-configuration` generator will install the [`@storybook/addon-essentials`](https://storybook.js.org/docs/riot/essentials/introduction) package, part of which is `@storybook/addon-controls`. This includes some more "essential" Storybook features (eg. `docs`). You can [disable features you do not need](https://storybook.js.org/docs/riot/essentials/introduction#disabling-addons) anytime in your `main.js`.
- Cypress e2e tests will be generated, [using the args URL](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) to set args in the controls.
### For existing Nx workspaces
- If you `nx migrate` to the latest version, your `package.json` will be updated to include the `@storybook/addon-essentials` package. The `@storybook/addon-essentials` addon will be added in your `addons` array in your root `main.js` file. You will need to run `npm/yarn install` to have it installed.
- If you install manually the latest version of `@nrwl/storybook`, `@nrwl/workspace` and `@nrwl/angular` or `@nrwl/react`, you will need to manually do `yarn add -D @storybook/addon-essentials`. You will also need to add the addon manually in your `addons` array in your root `main.js` file.
- All the stories you generate from that moment on will be using controls/args
- Your existing stories will not be touched and will still work
## Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
@ -270,11 +293,11 @@ If you have not changed the content of the files which the `storybook-configurat
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-knobs/register'],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should only have the `@storybook/addon-knobs/register` addon, which we already put in the array. You can now delete the `addons.js` file.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
@ -303,10 +326,9 @@ After you add any addons in the `main.js` file, you can safely delete the `addon
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```typescript
import { addDecorator } from '<%= uiFramework %>';
import { withKnobs } from '@storybook/addon-knobs';
import { addDecorator } from '@storybook/react';
addDecorator(withKnobs);
addDecorator(<YourDecorator>);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
@ -352,13 +374,3 @@ Your folder structure should now look like this:
├── README.md
└── etc...
```
### Storybook v6 args and controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. Feel free to use the new args way of defining stories. More can be found
[on the official Storybook docs](https://storybook.js.org/docs/react/writing-stories/args).
> **Note:** Nx does not yet automatically generate stories that use the args syntax. The main reason is that args don't
> yet support being loaded via the iframe URL which is used in Nx to setup your Storybook based e2e tests. Once support
> is present in Storybook v6, we will provide a way to generate args & controls based stories. More on the progress [here](https://github.com/storybookjs/storybook/issues/12291).

View File

@ -35,8 +35,8 @@ describe('Storybook schematics', () => {
`
module.exports = {
stories: [],
addons: ['@storybook/addon-knobs'],
};
addons: ['@storybook/addon-essentials'],
};
console.log('hi there');
`
@ -99,22 +99,22 @@ describe('Storybook schematics', () => {
writeFileSync(
tmpProjPath(`libs/${myReactLib}/src/lib/button.stories.tsx`),
`
import React from 'react';
import { Button, ButtonStyle } from './button';
import { text, number } from '@storybook/addon-knobs';
export default { title: 'Button' };
export const primary = () => (
<Button
padding={number('Padding', 0)}
style={text('Style', 'default') as ButtonStyle}
text={text('Text', 'Click me')}
// padding='0'
// style='default'
// text='Click me'
/>
);
import { Story, Meta } from '@storybook/react';
import { Button, ButtonProps } from './button';
export default {
component: Button,
title: 'Button',
} as Meta;
const Template: Story<ButtonProps> = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
text: 'Click me',
padding: 0,
style: 'default',
};
`
);
@ -133,14 +133,14 @@ describe('Storybook schematics', () => {
describe('${myAngularLib}', () => {
it('should render the component', () => {
cy.visit('/iframe.html?id=testbuttoncomponent--primary&knob-buttonType=button&knob-style=default&knob-age&knob-isDisabled=false');
cy.visit('/iframe.html?id=testbuttoncomponent--primary&args=buttonType:button;style:default;age;isDisabled:false');
cy.get('proj-test-button').should('exist');
cy.get('button').should('not.be.disabled');
cy.get('button').should('have.class', 'default');
cy.contains('You are 0 years old.');
});
it('should adjust the knobs', () => {
cy.visit('/iframe.html?id=testbuttoncomponent--primary&knob-buttonType=button&knob-style=primary&knob-age=10&knob-isDisabled=true');
it('should adjust the controls', () => {
cy.visit('/iframe.html?id=testbuttoncomponent--primary&args=buttonType:button;style:primary;age:10;isDisabled:true');
cy.get('button').should('be.disabled');
cy.get('button').should('have.class', 'primary');
cy.contains('You are 10 years old.');
@ -165,14 +165,14 @@ describe('Storybook schematics', () => {
describe('react-ui', () => {
it('should render the component', () => {
cy.visit(
'/iframe.html?id=button--primary&knob-Style=default&knob-Padding&knob-Text=Click%20me'
'/iframe.html?id=button--primary&args=style:default;padding;text:Click%20me'
);
cy.get('button').should('exist');
cy.get('button').should('have.class', 'default');
});
it('should adjust the knobs', () => {
it('should adjust the controls', () => {
cy.visit(
'/iframe.html?id=button--primary&knob-Style=primary&knob-Padding=10&knob-Text=Other'
'/iframe.html?id=button--primary&args=style:primary;padding:10;text:Other'
);
cy.get('button').should('have.class', 'primary');
});
@ -240,21 +240,28 @@ describe('Storybook schematics', () => {
`libs/${angularStorybookLib}/src/lib/myteststory.stories.ts`
),
`
import { moduleMetadata, Story, Meta } from '@storybook/angular';
import { MyTestCmpComponent } from '@${proj}/${anotherTestLib}';
export default {
title: 'My Test Cmp',
component: MyTestCmpComponent,
};
decorators: [
moduleMetadata({
imports: [],
})
],
} as Meta<MyTestCmpComponent>;
let x = 'hi';
export const primary = () => ({
moduleMetadata: {
imports: [],
},
props: {},
const Template: Story<MyTestCmpComponent> = (args: MyTestCmpComponent) => ({
component: MyTestCmpComponent,
props: args,
});
export const Primary = Template.bind({});
Primary.args = {
}
`
);
@ -289,7 +296,7 @@ export function createTestUILib(libName: string): void {
styleUrls: ['./test-button.component.css']
})
export class TestButtonComponent implements OnInit {
@Input('buttonType') type = 'button';
@Input('buttonType') buttonType = 'button';
@Input() style: ButtonStyle = 'default';
@Input() age!: number;
@Input() isDisabled = false;

View File

@ -80,37 +80,43 @@ nx run project-name-e2e:e2e
The url that Cypress points to should look like this:
`'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'`
`'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'`
- `buttoncomponent` is a lowercase version of the `Title` in the `*.stories.ts` file.
- `primary` is the name of an individual story.
- `knob-style=default` sets the `style` knob to a value of `default`.
- `style=default` sets the `style` arg to a value of `default`.
Changing knobs in the url query parameters allows your Cypress tests to test different configurations of your component.
Changing args in the url query parameters allows your Cypress tests to test different configurations of your component. You can [read the documentation](https://storybook.js.org/docs/angular/writing-stories/args#setting-args-through-the-url) for more information.
### Example Files
**\*.component.stories.ts file**
```typescript
import { text, number } from '@storybook/addon-knobs';
import { moduleMetadata, Story, Meta } from '@storybook/angular';
import { ButtonComponent } from './button.component';
export default {
title: 'ButtonComponent',
};
export const primary = () => ({
moduleMetadata: {
imports: [],
},
component: ButtonComponent,
props: {
text: text('text', 'Click me!'),
padding: number('padding', 0),
style: text('style', 'default'),
},
decorators: [
moduleMetadata({
imports: [],
}),
],
} as Meta<ButtonComponent>;
const Template: Story<ButtonComponent> = (args: ButtonComponent) => ({
component: ButtonComponent,
props: args,
});
export const Primary = Template.bind({});
Primary.args = {
text: 'Click me!',
padding: 0,
style: 'default',
};
```
**Cypress \*.spec.ts file**
@ -119,7 +125,7 @@ export const primary = () => ({
describe('shared-ui', () => {
beforeEach(() =>
cy.visit(
'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'
'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'
)
);
@ -134,20 +140,18 @@ describe('shared-ui', () => {
To register an [addon](https://storybook.js.org/addons/) for all storybook instances in your workspace:
1. In `/.storybook/main.js`, in the `addons` array of the `module.exports` object, add the new addon:
```
```typescript
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js` use the `addDecorator` function.
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js`, you can export an array called `decorators`.
```
import { configure, addDecorator } from '@storybook/angular';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
```typescript
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
**-- OR --**
@ -155,26 +159,44 @@ To register an [addon](https://storybook.js.org/addons/) for all storybook insta
To register an [addon](https://storybook.js.org/addons/) for a single storybook instance, go to that project's `.storybook` folder:
1. In `main.js`, in the `addons` array of the `module.exports` object, add the new addon:
```
```typescript
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in `preview.js` use the `addDecorator` function.
2. If a decorator is required, in `preview.js` you can export an array called `decorators`.
```
import { configure, addDecorator } from '@storybook/angular';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
```typescript
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
### More Information
For more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/basics/introduction/).
## From knobs to controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. More can be found [on the official Storybook docs](https://storybook.js.org/docs/react/writing-stories/args).
From **Nx v12.5** and on, the `@nrwl/storybook` package will be using `@storybook/addon-controls` instead of `@storybook/addon-knobs` to generate stories.
### For new Nx workspaces
- Generators will generate your Storybook configuration files and your Stories using Controls/args instead of knobs
- The `storybook-configuration` generator will install the [`@storybook/addon-essentials`](https://storybook.js.org/docs/riot/essentials/introduction) package, part of which is `@storybook/addon-controls`. This includes some more "essential" Storybook features (eg. `docs`). You can [disable features you do not need](https://storybook.js.org/docs/riot/essentials/introduction#disabling-addons) anytime in your `main.js`.
- Cypress e2e tests will be generated, [using the args URL](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) to set args in the controls.
### For existing Nx workspaces
- If you `nx migrate` to the latest version, your `package.json` will be updated to include the `@storybook/addon-essentials` package. The `@storybook/addon-essentials` addon will be added in your `addons` array in your root `main.js` file. You will need to run `npm/yarn install` to have it installed.
- If you install manually the latest version of `@nrwl/storybook`, `@nrwl/workspace` and `@nrwl/angular` or `@nrwl/react`, you will need to manually do `yarn add -D @storybook/addon-essentials`. You will also need to add the addon manually in your `addons` array in your root `main.js` file.
- All the stories you generate from that moment on will be using controls/args
- Your existing stories will not be touched and will still work
## Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
@ -215,7 +237,7 @@ The `@nrwl/angular:storybook-migrate-defaults-5-to-6` generator will not exactly
That way, you can have working Storybook instances for all your projects just by running
```
```bash
nx g @nrwl/angular:storybook-migrate-defaults-5-to-6
```
@ -271,7 +293,7 @@ Check your `package.json` file for all `@storybook` packages. Install the latest
For example:
```
```bash
yarn add --dev @storybook/angular@latest
```
@ -287,14 +309,14 @@ If you have not changed the content of the files which the `storybook-configurat
- In the root `./storybook` directory, create a new file named `main.js` with the following content:
```
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-knobs/register'],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should only have the `@storybook/addon-knobs/register` addon, which we already put in the array. You can now delete the `addons.js` file.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
@ -302,7 +324,7 @@ module.exports = {
- In the library `./storybook` directory, create a new file named `main.js` with the following content:
```
```typescript
const lib_main_module = require('../../.storybook/main');
lib_main_module.stories.push('../src/lib/**/*.stories.mdx');
@ -314,7 +336,7 @@ Please take extra care making sure that the path to the root `./storybook` direc
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:
```
```typescript
lib_main_module.addons.push('<YOUR_ADDON_HERE>');
```
@ -322,35 +344,35 @@ After you add any addons in the `main.js` file, you can safely delete the `addon
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```
import { addDecorator } from '<%= uiFramework %>';
import { withKnobs } from '@storybook/addon-knobs';
```typescript
import { addDecorator } from '@storybook/angular';
import { YourDecorator } from '@storybook/<something>';
addDecorator(withKnobs);
addDecorator(YourDecorator);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
```
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
}
});
```typescript
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
});
```
#### Check final folder structure
Your folder structure should now look like this:
```
```treeview
<workspace name>/
├── .storybook/
│ ├── main.js

View File

@ -71,28 +71,35 @@ nx run project-name-e2e:e2e
The url that Cypress points to should look like this:
`'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'`
`'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'`
- `buttoncomponent` is a lowercase version of the `Title` in the `*.stories.ts` file.
- `primary` is the name of an individual story.
- `knob-style=default` sets the `style` knob to a value of `default`.
- `style=default` sets the `style` arg to a value of `default`.
Changing knobs in the url query parameters allows your Cypress tests to test different configurations of your component.
Changing args in the url query parameters allows your Cypress tests to test different configurations of your component. You can [read the documentation](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) for more information.
### Example Files
**\*.stories.tsx file**
```typescript
import React from 'react';
import { text, number } from '@storybook/addon-knobs';
import { Button } from './button';
import { Story, Meta } from '@storybook/react';
import { Button, ButtonProps } from './button';
export default { title: 'Button' };
export default {
component: Button,
title: 'Button',
} as Meta;
export const primary = () => (
<Button padding={number('Padding', 0)} text={text('Text', 'Click me')} />
);
const Template: Story<ButtonProps> = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
text: 'Click me!',
padding: 0,
style: 'default',
};
```
**Cypress \*.spec.ts file**
@ -101,7 +108,7 @@ export const primary = () => (
describe('shared-ui', () => {
beforeEach(() =>
cy.visit(
'/iframe.html?id=buttoncomponent--primary&knob-text=Click me!&knob-padding&knob-style=default'
'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'
)
);
@ -116,20 +123,18 @@ describe('shared-ui', () => {
To register an [addon](https://storybook.js.org/addons/) for all storybook instances in your workspace:
1. In `/.storybook/main.js`, in the `addons` array of the `module.exports` object, add the new addon:
```
```typescript
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js` use the `addDecorator` function.
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js`, you can export an array called `decorators`.
```
import { configure, addDecorator } from '@storybook/react';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
```typescript
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
**-- OR --**
@ -137,26 +142,44 @@ To register an [addon](https://storybook.js.org/addons/) for all storybook insta
To register an [addon](https://storybook.js.org/addons/) for a single storybook instance, go to that project's `.storybook` folder:
1. In `main.js`, in the `addons` array of the `module.exports` object, add the new addon:
```
```typescript
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-knobs/register'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in `preview.js` use the `addDecorator` function.
2. If a decorator is required, in `preview.js` you can export an array called `decorators`.
```
import { configure, addDecorator } from '@storybook/react';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);
```typescript
import someDecorator from 'some-storybook-addon';
export const decorators = [someDecorator];
```
### More Information
For more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/basics/introduction/).
## From knobs to controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. More can be found [on the official Storybook docs](https://storybook.js.org/docs/react/writing-stories/args).
From **Nx v12.5** and on, the `@nrwl/storybook` package will be using `@storybook/addon-controls` instead of `@storybook/addon-knobs` to generate stories.
### For new Nx workspaces
- Generators will generate your Storybook configuration files and your Stories using Controls/args instead of knobs
- The `storybook-configuration` generator will install the [`@storybook/addon-essentials`](https://storybook.js.org/docs/riot/essentials/introduction) package, part of which is `@storybook/addon-controls`. This includes some more "essential" Storybook features (eg. `docs`). You can [disable features you do not need](https://storybook.js.org/docs/riot/essentials/introduction#disabling-addons) anytime in your `main.js`.
- Cypress e2e tests will be generated, [using the args URL](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) to set args in the controls.
### For existing Nx workspaces
- If you `nx migrate` to the latest version, your `package.json` will be updated to include the `@storybook/addon-essentials` package. The `@storybook/addon-essentials` addon will be added in your `addons` array in your root `main.js` file. You will need to run `npm/yarn install` to have it installed.
- If you install manually the latest version of `@nrwl/storybook`, `@nrwl/workspace` and `@nrwl/angular` or `@nrwl/react`, you will need to manually do `yarn add -D @storybook/addon-essentials`. You will also need to add the addon manually in your `addons` array in your root `main.js` file.
- All the stories you generate from that moment on will be using controls/args
- Your existing stories will not be touched and will still work
## Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
@ -251,7 +274,7 @@ Check your `package.json` file for all `@storybook` packages. Install the latest
For example:
```
```bash
yarn add --dev @storybook/react@latest
```
@ -267,14 +290,14 @@ If you have not changed the content of the files which the `storybook-configurat
- In the root `./storybook` directory, create a new file named `main.js` with the following content:
```
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-knobs/register'],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should only have the `@storybook/addon-knobs/register` addon, which we already put in the array. You can now delete the `addons.js` file.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
@ -282,7 +305,7 @@ module.exports = {
- In the library `./storybook` directory, create a new file named `main.js` with the following content:
```
```typescript
const lib_main_module = require('../../.storybook/main');
lib_main_module.stories.push('../src/lib/**/*.stories.mdx');
@ -294,7 +317,7 @@ Please take extra care making sure that the path to the root `./storybook` direc
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:
```
```typescript
lib_main_module.addons.push('<YOUR_ADDON_HERE>');
```
@ -302,35 +325,34 @@ After you add any addons in the `main.js` file, you can safely delete the `addon
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```
import { addDecorator } from '<%= uiFramework %>';
import { withKnobs } from '@storybook/addon-knobs';
```typescript
import { addDecorator } from '@storybook/react';
addDecorator(withKnobs);
addDecorator(<YourDecorator>);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
```
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
}
});
```typescript
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
});
```
#### Check final folder structure
Your folder structure should now look like this:
```
```treeview
<workspace name>/
├── .storybook/
│ ├── main.js

View File

@ -80,6 +80,7 @@
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "7.1.1",
"@schematics/angular": "^12.0.0",
"@storybook/addon-essentials": "~6.3.0",
"@storybook/addon-knobs": "~6.3.0",
"@storybook/angular": "~6.3.0",
"@storybook/core": "~6.3.0",

View File

@ -2,11 +2,9 @@
exports[`componentCypressSpec generator should generate the component spec file 1`] = `
"describe('ng-app1', () => {
beforeEach(() => cy.visit('/iframe.html?id=testbuttoncomponent--primary&knob-buttonType=button&knob-style=default&knob-age&knob-isOn=false'));
beforeEach(() => cy.visit('/iframe.html?id=testbuttoncomponent--primary&args=buttonType:button;style:default;age;isOn:false;'));
it('should render the component', () => {
cy.get('proj-test-button').should('exist');
});
});
"
});"
`;

View File

@ -6,7 +6,7 @@ import {
} from '@nrwl/devkit';
import { getComponentProps } from '../utils/storybook';
import { getComponentSelector } from './lib/get-component-selector';
import { getKnobDefaultValue } from './lib/get-knob-default-value';
import { getArgsDefaultValue } from './lib/get-args-default-value';
import type { ComponentCypressSpecGeneratorOptions } from './schema';
export function componentCypressSpecGenerator(
@ -50,7 +50,7 @@ export function componentCypressSpecGenerator(
componentPath,
`${componentFileName}.ts`
);
const props = getComponentProps(tree, fullComponentPath, getKnobDefaultValue);
const props = getComponentProps(tree, fullComponentPath, getArgsDefaultValue);
const componentSelector = getComponentSelector(tree, fullComponentPath);
generateFiles(tree, templatesDir, destinationDir, {

View File

@ -1,13 +1,12 @@
describe('<%=projectName%>', () => {
beforeEach(() => cy.visit('/iframe.html?id=<%= componentName.toLowerCase() %>--primary<%
beforeEach(() => cy.visit('/iframe.html?id=<%= componentName.toLowerCase() %>--primary<% if ( props && props.length > 0 ) { %>&args=<% } %><%
for(let prop of props) {
%>&knob-<%=prop.name%><%
if(prop.defaultValue !== undefined) {
%>=<%=prop.defaultValue%><%
} %><%
%><%=prop.name%><%
if(prop.defaultValue !== undefined && (prop.defaultValue || prop.defaultValue === false)) {
%>:<%=prop.defaultValue%><%
} %>;<%
}%>'));
it('should render the component', () => {
cy.get('<%=componentSelector%>').should('exist');
});
});
});

View File

@ -1,7 +1,7 @@
import type { PropertyDeclaration } from 'typescript';
import { SyntaxKind } from 'typescript';
export function getKnobDefaultValue(
export function getArgsDefaultValue(
property: PropertyDeclaration
): string | undefined {
if (!property.initializer) {
@ -9,7 +9,8 @@ export function getKnobDefaultValue(
}
switch (property.initializer.kind) {
case SyntaxKind.StringLiteral:
return property.initializer.getText().slice(1, -1);
const returnString = property.initializer.getText().slice(1, -1);
return returnString.replace(/\s/g, '+');
case SyntaxKind.NumericLiteral:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:

View File

@ -1,23 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`componentStory generator should generate the right props 1`] = `
"import { text, number, boolean } from '@storybook/addon-knobs';
"import { moduleMetadata, Story, Meta } from '@storybook/angular';
import { TestButtonComponent } from './test-button.component';
export default {
title: 'TestButtonComponent',
component: TestButtonComponent
}
component: TestButtonComponent,
decorators: [
moduleMetadata({
imports: [],
})
],
} as Meta<TestButtonComponent>;
export const primary = () => ({
moduleMetadata: {
imports: []
},
props: {
buttonType: text('buttonType', 'button'),
style: text('style', 'default'),
age: number('age', 0),
isOn: boolean('isOn', false),
}
})"
const Template: Story<TestButtonComponent> = (args: TestButtonComponent) => ({
component: TestButtonComponent,
props: args,
});
export const Primary = Template.bind({});
Primary.args = {
buttonType: 'button',
style: 'default',
age: 0,
isOn: false,
}"
`;

View File

@ -1,7 +1,7 @@
import type { Tree } from '@nrwl/devkit';
import { generateFiles, joinPathFragments } from '@nrwl/devkit';
import { getComponentProps } from '../utils/storybook';
import { getKnobDefaultValue } from './lib/get-knob-default-value';
import { getArgsDefaultValue } from './lib/get-args-default-value';
import type { ComponentStoryGeneratorOptions } from './schema';
export function componentStoryGenerator(
@ -25,7 +25,7 @@ export function componentStoryGenerator(
const props = getComponentProps(
tree,
joinPathFragments(destinationDir, `${componentFileName}.ts`),
getKnobDefaultValue
getArgsDefaultValue
);
generateFiles(tree, templatesDir, destinationDir, {

View File

@ -1,16 +1,23 @@
<% if(props.length > 0) { %>import { text, number, boolean } from '@storybook/addon-knobs';<% } %>
import { moduleMetadata, Story, Meta } from '@storybook/angular';
import { <%=componentName%> } from './<%=componentFileName%>';
export default {
title: '<%=componentName%>',
component: <%=componentName%>
}
component: <%=componentName%>,
decorators: [
moduleMetadata({
imports: [],
})
],
} as Meta<<%=componentName%>>;
export const primary = () => ({
moduleMetadata: {
imports: []
},
props: {<% for (let prop of props) { %>
<%=prop.name%>: <%=prop.type%>('<%=prop.name%>', <%-prop.defaultValue%>),<% } %>
}
})
const Template: Story<<%=componentName%>> = (args: <%=componentName%>) => ({
component: <%=componentName%>,
props: args,
});
export const Primary = Template.bind({});
Primary.args = {<% for (let prop of props) { %>
<%= prop.name %>: <%- prop.defaultValue %>,<% } %>
}

View File

@ -1,6 +1,6 @@
import type { PropertyDeclaration } from 'typescript';
export function getKnobDefaultValue(property: PropertyDeclaration): string {
export function getArgsDefaultValue(property: PropertyDeclaration): string {
const typeNameToDefault = {
string: "''",
number: '0',

View File

@ -2,33 +2,38 @@
exports[`angularStories generator: libraries Stories for non-empty Angular library should generate cypress spec files 1`] = `
"describe('test-ui-lib', () => {
beforeEach(() => cy.visit('/iframe.html?id=testbuttoncomponent--primary&knob-buttonType=button&knob-style=default&knob-age&knob-isOn=false'));
beforeEach(() => cy.visit('/iframe.html?id=testbuttoncomponent--primary&args=buttonType:button;style:default;age;isOn:false;'));
it('should render the component', () => {
cy.get('proj-test-button').should('exist');
});
});
"
});"
`;
exports[`angularStories generator: libraries Stories for non-empty Angular library should generate stories.ts files 1`] = `
"import { text, number, boolean } from '@storybook/addon-knobs';
"import { moduleMetadata, Story, Meta } from '@storybook/angular';
import { TestButtonComponent } from './test-button.component';
export default {
title: 'TestButtonComponent',
component: TestButtonComponent
}
component: TestButtonComponent,
decorators: [
moduleMetadata({
imports: [],
})
],
} as Meta<TestButtonComponent>;
export const primary = () => ({
moduleMetadata: {
imports: []
},
props: {
buttonType: text('buttonType', 'button'),
style: text('style', 'default'),
age: number('age', 0),
isOn: boolean('isOn', false),
}
})"
const Template: Story<TestButtonComponent> = (args: TestButtonComponent) => ({
component: TestButtonComponent,
props: args,
});
export const Primary = Template.bind({});
Primary.args = {
buttonType: 'button',
style: 'default',
age: 0,
isOn: false,
}"
`;

View File

@ -37,8 +37,8 @@ describe('StorybookConfiguration generator', () => {
}));
jest.spyOn(fileUtils, 'readPackageJson').mockReturnValue({
devDependencies: {
'@storybook/addon-essentials': '^6.0.21',
'@storybook/react': '^6.0.21',
'@storybook/addon-essentials': '~6.2.9',
'@storybook/react': '~6.2.9',
},
});
});

View File

@ -36,7 +36,7 @@ export function getInputPropertyDeclarations(
export function getComponentProps(
tree: Tree,
componentPath: string,
getKnobDefaultValueFn: (property: PropertyDeclaration) => string | undefined
getArgsDefaultValueFn: (property: PropertyDeclaration) => string | undefined
): InputDescriptor[] {
const props = getInputPropertyDeclarations(tree, componentPath).map(
(node) => {
@ -49,7 +49,7 @@ export function getComponentProps(
: node.name.getText();
const type = getKnobType(node);
const defaultValue = getKnobDefaultValueFn(node);
const defaultValue = getArgsDefaultValueFn(node);
return {
name,

View File

@ -105,7 +105,7 @@ describe('react:component-cypress-spec', () => {
formatFile`${appTree.read(cypressStorySpecFilePath, 'utf-8')}`
)
.toContain(formatFile`describe('test-ui-lib: Test component', () => {
beforeEach(() => cy.visit('/iframe.html?id=test--primary&knob-name=&knob-displayAge=false'));
beforeEach(() => cy.visit('/iframe.html?id=test--primary&args=name;displayAge:false;'));
it('should render the component', () => {
cy.get('h1').should('contain', 'Welcome to test-ui-lib!');

View File

@ -27,7 +27,7 @@ export function componentCypressGenerator(
}
// TODO: candidate to refactor with the angular component story
export function getKnobDefaultValue(property: ts.SyntaxKind): string {
export function getArgsDefaultValue(property: ts.SyntaxKind): string {
const typeNameToDefault: Record<number, any> = {
[ts.SyntaxKind.StringKeyword]: '',
[ts.SyntaxKind.NumberKeyword]: 0,
@ -37,6 +37,8 @@ export function getKnobDefaultValue(property: ts.SyntaxKind): string {
const resolvedValue = typeNameToDefault[property];
if (typeof resolvedValue === undefined) {
return '';
} else if (typeof resolvedValue === 'string') {
return resolvedValue.replace(/\s/g, '+');
} else {
return resolvedValue;
}
@ -90,7 +92,7 @@ export function createComponentSpecFile(
props = propsInterface.members.map((member: ts.PropertySignature) => {
return {
name: (member.name as ts.Identifier).text,
defaultValue: getKnobDefaultValue(member.type.kind),
defaultValue: getArgsDefaultValue(member.type.kind),
};
});
}

View File

@ -1,10 +1,11 @@
describe('<%=projectName%>: <%= componentSelector %> component', () => {
beforeEach(() => cy.visit('/iframe.html?id=<%= componentSelector.toLowerCase() %>--primary<%
beforeEach(() => cy.visit('/iframe.html?id=<%= componentSelector.toLowerCase() %>--primary<% if ( props && props.length > 0 ) { %>&args=<% } %><%
for(let prop of props) {
%>&knob-<%=prop.name%><%
if(prop.defaultValue !== undefined) {
%>=<%=prop.defaultValue%><%
} %><%}%>'));
%><%=prop.name%><%
if(prop.defaultValue !== undefined && (prop.defaultValue || prop.defaultValue === false)) {
%>:<%=prop.defaultValue%><%
} %>;<%
}%>'));
it('should render the component', () => {
cy.get('h1').should('contain', 'Welcome to <%=projectName%>!');

View File

@ -52,20 +52,18 @@ describe('react:component-story', () => {
it('should properly set up the story', () => {
expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`)
.toContain(formatFile`
import React from 'react';
import { TestUiLib, TestUiLibProps } from './test-ui-lib';
export default {
component: TestUiLib,
title: 'TestUiLib',
};
export const primary = () => {
/* eslint-disable-next-line */
const props: TestUiLibProps = {};
return <TestUiLib />;
};
import { Story, Meta } from '@storybook/react';
import { TestUiLib, TestUiLibProps } from './test-ui-lib';
export default {
component: TestUiLib,
title: 'TestUiLib',
} as Meta;
const Template: Story<TestUiLibProps> = (args) => <TestUiLib {...args} />;
export const Primary = Template.bind({});
Primary.args = {};
`);
});
});
@ -106,20 +104,17 @@ describe('react:component-story', () => {
it('should properly set up the story', () => {
expect(formatFile`${appTree.read(storyFilePathPlain, 'utf-8')}`)
.toContain(formatFile`
import React from 'react';
import { Test } from './test-ui-libplain';
export default {
component: Test,
title: 'Test',
};
export const primary = () => {
/* eslint-disable-next-line */
const props = {};
return <Test />;
};
import Test from './test-ui-libplain';
export default {
component: Test,
title: 'Test',
};
const Template = (args) => <Test {...args} />;
export const Primary = Template.bind({});
Primary.args = {};
`);
});
});
@ -150,20 +145,21 @@ describe('react:component-story', () => {
});
});
it('should create a story without knobs', () => {
it('should create a story without controls', () => {
expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`)
.toContain(formatFile`
import React from 'react';
import { Test } from './test-ui-lib';
export default {
component: Test,
title: 'Test',
};
export const primary = () => {
return <Test />;
}
import { Story, Meta } from '@storybook/react';
import { Test } from './test-ui-lib';
export default {
component: Test,
title: 'Test',
} as Meta;
const Template: Story<> = (args) => <Test {...args} />;
export const Primary = Template.bind({});
Primary.args = {};
`);
});
});
@ -199,25 +195,23 @@ describe('react:component-story', () => {
});
});
it('should setup knobs based on the component props', () => {
it('should setup controls based on the component props', () => {
expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`)
.toContain(formatFile`
import { text, boolean } from '@storybook/addon-knobs';
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Test, TestProps } from './test-ui-lib';
export default {
component: Test,
title: 'Test',
};
export const primary = () => {
const props: TestProps = {
name: text('name', ''),
displayAge: boolean('displayAge', false),
};
return <Test name={props.name} displayAge={props.displayAge} />;
} as Meta;
const Template: Story<TestProps> = (args) => <Test {...args} />;
export const Primary = Template.bind({});
Primary.args = {
name: '',
displayAge: false,
};
`);
});
@ -356,25 +350,23 @@ describe('react:component-story', () => {
});
});
it('should properly setup the knobs based on the component props', () => {
it('should properly setup the controls based on the component props', () => {
expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`)
.toContain(formatFile`
import { text, boolean } from '@storybook/addon-knobs';
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Test, TestProps } from './test-ui-lib';
export default {
component: Test,
title: 'Test',
};
export const primary = () => {
const props: TestProps = {
name: text('name', ''),
displayAge: boolean('displayAge', false),
};
return <Test name={props.name} displayAge={props.displayAge} />;
} as Meta;
const Template: Story<TestProps> = (args) => <Test {...args} />;
export const Primary = Template.bind({});
Primary.args = {
name: '',
displayAge: false,
};
`);
});
@ -394,20 +386,18 @@ describe('react:component-story', () => {
it('should properly set up the story', () => {
expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`)
.toContain(formatFile`
import React from 'react';
import { TestUiLib, TestUiLibProps } from './test-ui-lib';
export default {
component: TestUiLib,
title: 'TestUiLib',
};
export const primary = () => {
/* eslint-disable-next-line */
const props: TestUiLibProps = {};
return <TestUiLib />;
};
import { Story, Meta } from '@storybook/react';
import { TestUiLib, TestUiLibProps } from './test-ui-lib';
export default {
component: TestUiLib,
title: 'TestUiLib',
} as Meta;
const Template: Story<TestUiLibProps> = (args) => <TestUiLib {...args} />;
export const Primary = Template.bind({});
Primary.args = {};
`);
});
});

View File

@ -18,10 +18,8 @@ export interface CreateComponentStoriesFileSchema {
componentPath: string;
}
export type KnobType = 'text' | 'boolean' | 'number' | 'select';
// TODO: candidate to refactor with the angular component story
export function getKnobDefaultValue(property: ts.SyntaxKind): string {
export function getArgsDefaultValue(property: ts.SyntaxKind): string {
const typeNameToDefault: Record<number, any> = {
[ts.SyntaxKind.StringKeyword]: "''",
[ts.SyntaxKind.NumberKeyword]: 0,
@ -56,7 +54,8 @@ export function createComponentStoriesFile(
''
);
const isPlainJs = componentFilePath.endsWith('.jsx');
const isPlainJs =
componentFilePath.endsWith('.jsx') || componentFilePath.endsWith('.js');
let fileExt = 'tsx';
if (componentFilePath.endsWith('.jsx')) {
fileExt = 'jsx';
@ -97,7 +96,6 @@ export function createComponentStoriesFile(
let propsTypeName: string = null;
let props: {
name: string;
type: KnobType;
defaultValue: any;
}[] = [];
@ -105,16 +103,9 @@ export function createComponentStoriesFile(
propsTypeName = propsInterface.name.text;
props = propsInterface.members.map((member: ts.PropertySignature) => {
const initializerKindToKnobType: Record<number, KnobType> = {
[ts.SyntaxKind.StringKeyword]: 'text',
[ts.SyntaxKind.NumberKeyword]: 'number',
[ts.SyntaxKind.BooleanKeyword]: 'boolean',
};
return {
name: (member.name as ts.Identifier).text,
type: initializerKindToKnobType[member.type.kind],
defaultValue: getKnobDefaultValue(member.type.kind),
defaultValue: getArgsDefaultValue(member.type.kind),
};
});
}
@ -127,7 +118,6 @@ export function createComponentStoriesFile(
componentFileName: name,
propsTypeName,
props,
usedKnobs: props.map((x) => x.type).join(', '),
componentName: (cmpDeclaration as any).name.text,
isPlainJs,
fileExt,

View File

@ -1,19 +1,14 @@
<% if(usedKnobs && usedKnobs.length > 0) { %>import { <%= usedKnobs %> } from '@storybook/addon-knobs';<% } %>
import React from 'react';
import { <%= componentName %><% if ( propsTypeName && !isPlainJs ) { %>, <%= propsTypeName %> <% } %> } from './<%= componentFileName %>';
<% if ( !isPlainJs ) { %>import { Story, Meta } from '@storybook/react';<% } %>
import<% if ( !isPlainJs ) { %> { <% } %> <%= componentName %><% if ( propsTypeName && !isPlainJs ) { %>, <%= propsTypeName %> <% } %> <% if ( !isPlainJs ) { %> } <% } %> from './<%= componentFileName %>';
export default {
component: <%= componentName %>,
title: '<%= componentName %>'
};
}<% if ( !isPlainJs ) { %> as Meta <% } %>;
export const primary = () => {
<% if (propsTypeName || isPlainJs ) { %>
<% if (props.length === 0) { %>/* <%= usesEsLint ? 'eslint' : 'tslint'%>-disable-next-line */<% } %>
const props<%= isPlainJs ? '': ':' + propsTypeName %> = {<% for (let prop of props) { %>
<%= prop.name %>: <%= prop.type %>('<%= prop.name %>', <%- prop.defaultValue %>),<% } %>
};
<% } %>
const Template<% if ( !isPlainJs ) { %>: Story<<%= propsTypeName %>><% } %> = (args) => <<%= componentName %> {...args} />;
return <<%= componentName %> <% for (let prop of props) { %><%= prop.name %> = {props.<%= prop.name %>} <% } %> />;
};
export const Primary = Template.bind({})
Primary.args = {<% for (let prop of props) { %>
<%= prop.name %>: <%- prop.defaultValue %>,<% } %>
}

View File

@ -34,7 +34,7 @@
"update-11-6-0": {
"version": "11.6.4",
"cli": "nx",
"description": "Update storybook if installed and above 6 but below 6.2.7",
"description": "Update storybook if installed and above 6 but below 6.2.9",
"factory": "./src/migrations/update-11-6-0/update-storybook"
},
"update-12-1-0": {
@ -46,7 +46,7 @@
"update-12-3-0": {
"version": "12.3.0-rc.1",
"cli": "nx",
"description": "Update storybook if installed and above 6 but below 6.2.7",
"description": "Update storybook if installed and above 6 but below 6.2.9",
"factory": "./src/migrations/update-11-6-0/update-storybook"
},
"update-12-5-0": {
@ -54,6 +54,12 @@
"cli": "nx",
"description": "Upgrade Storybook to v6.3",
"factory": "./src/migrations/update-12-5-0/migrate-storybook-6-3"
},
"install-addon-essentials": {
"version": "12.5.0-beta.5",
"cli": "nx",
"description": "Install the @storybook/addon-essentials package",
"factory": "./src/migrations/update-12-5-0/install-addon-essentials"
}
},
"packageJsonUpdates": {

View File

@ -14,8 +14,8 @@ describe('Build storybook', () => {
beforeEach(async () => {
jest.spyOn(fileUtils, 'readPackageJson').mockReturnValue({
devDependencies: {
'@storybook/addon-essentials': '^6.2.7',
'@storybook/angular': '^6.2.7',
'@storybook/addon-essentials': '~6.2.9',
'@storybook/angular': '~6.2.9',
},
});

View File

@ -19,8 +19,8 @@ describe('@nrwl/storybook:storybook', () => {
beforeEach(() => {
jest.spyOn(fileUtils, 'readPackageJson').mockReturnValue({
devDependencies: {
'@storybook/addon-essentials': '^6.2.7',
'@storybook/angular': '^6.2.7',
'@storybook/addon-essentials': '~6.2.9',
'@storybook/angular': '~6.2.9',
},
});

View File

@ -24,8 +24,8 @@ describe('@nrwl/storybook:configuration', () => {
});
writeJson(tree, 'package.json', {
devDependencies: {
'@storybook/addon-knobs': '^6.0.21',
'@storybook/react': '^6.0.21',
'@storybook/addon-essentials': '~6.2.9',
'@storybook/react': '~6.2.9',
},
});
});
@ -86,7 +86,7 @@ describe('@nrwl/storybook:configuration', () => {
const newContents = `module.exports = {
stories: [],
addons: ['@storybook/addon-knobs', 'new-addon'],
addons: ['@storybook/addon-essentials', 'new-addon'],
};
`;
// Setup a new lib

View File

@ -1,4 +0,0 @@
import { addDecorator } from '<%= uiFramework %>';
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);

View File

@ -1,4 +1,4 @@
module.exports = {
stories: [],
addons: ['@storybook/addon-knobs'],
addons: ['@storybook/addon-essentials'],
};

View File

@ -8,7 +8,7 @@ Object {
"devDependencies": Object {
"@angular/forms": "*",
"@nrwl/storybook": "~6.3.0",
"@storybook/addon-knobs": "~6.3.0",
"@storybook/addon-essentials": "~6.3.0",
"@storybook/angular": "~6.3.0",
"@storybook/builder-webpack5": "~6.3.0",
"@storybook/manager-webpack5": "~6.3.0",

View File

@ -33,7 +33,7 @@ describe('@nrwl/storybook:init', () => {
expect(packageJson.dependencies[existing]).toBeDefined();
expect(packageJson.devDependencies[existing]).toBeDefined();
expect(
packageJson.devDependencies['@storybook/addon-knobs']
packageJson.devDependencies['@storybook/addon-essentials']
).toBeDefined();
// angular specific
@ -68,7 +68,7 @@ describe('@nrwl/storybook:init', () => {
expect(packageJson.dependencies[existing]).toBeDefined();
expect(packageJson.devDependencies[existing]).toBeDefined();
expect(
packageJson.devDependencies['@storybook/addon-knobs']
packageJson.devDependencies['@storybook/addon-essentials']
).toBeDefined();
// react specific
@ -105,7 +105,9 @@ describe('@nrwl/storybook:init', () => {
expect(packageJson.dependencies['@nrwl/storybook']).toBeUndefined();
expect(packageJson.dependencies[existing]).toBeDefined();
expect(packageJson.devDependencies[existing]).toBeDefined();
expect(packageJson.devDependencies['@storybook/addon-knobs']).toBeDefined();
expect(
packageJson.devDependencies['@storybook/addon-essentials']
).toBeDefined();
// react specific
expect(packageJson.devDependencies['@storybook/react']).not.toBeDefined();

View File

@ -35,10 +35,10 @@ function checkDependenciesInstalled(host: Tree, schema: Schema) {
*/
if (
!packageJson.dependencies['@storybook/addon-knobs'] &&
!packageJson.devDependencies['@storybook/addon-knobs']
!packageJson.dependencies['@storybook/addon-essentials'] &&
!packageJson.devDependencies['@storybook/addon-essentials']
) {
devDependencies['@storybook/addon-knobs'] = storybookVersion;
devDependencies['@storybook/addon-essentials'] = storybookVersion;
}
if (isFramework('angular', schema)) {

View File

@ -10,7 +10,7 @@ describe('Update 11-6-0/12-3-0', () => {
tree = createTree();
});
it('should update storybook versions if storybook is already above 6 but below 6.2.7', async () => {
it('should update storybook versions if storybook is already above 6 but below 6.2.9', async () => {
writeJson(tree, 'package.json', {
devDependencies: {
'@storybook/angular': '^6.0.0',
@ -21,21 +21,21 @@ describe('Update 11-6-0/12-3-0', () => {
await updateStorybook(tree);
expect(
readJson(tree, 'package.json').devDependencies['@storybook/angular']
).toBe('^6.2.7');
).toBe('~6.2.9');
});
it('should not update storybook versions if storybook is already above 6.2.7', async () => {
it('should not update storybook versions if storybook is already above 6.2.9', async () => {
writeJson(tree, 'package.json', {
devDependencies: {
'@storybook/angular': '6.2.8',
'@storybook/react': '6.2.8',
'@storybook/addon-knobs': '6.2.8',
'@storybook/angular': '~6.2.9',
'@storybook/react': '~6.2.9',
'@storybook/addon-knobs': '~6.2.9',
},
});
await updateStorybook(tree);
expect(
readJson(tree, 'package.json').devDependencies['@storybook/angular']
).toBe('6.2.8');
).toBe('~6.2.9');
});
it('should not update storybook versions if storybook is below 6', async () => {

View File

@ -26,8 +26,8 @@ function maybeUpdateVersion(tree: Tree) {
storybookPackageName,
json.dependencies[storybookPackageName]
);
if (gte(version, '6.0.0') && lt(version, '6.2.7')) {
json.dependencies[storybookPackageName] = '^6.2.7';
if (gte(version, '6.0.0') && lt(version, '6.2.9')) {
json.dependencies[storybookPackageName] = '~6.2.9';
needsInstall = true;
}
}
@ -36,8 +36,8 @@ function maybeUpdateVersion(tree: Tree) {
storybookPackageName,
json.devDependencies[storybookPackageName]
);
if (gte(version, '6.0.0') && lt(version, '6.2.7')) {
json.devDependencies[storybookPackageName] = '^6.2.7';
if (gte(version, '6.0.0') && lt(version, '6.2.9')) {
json.devDependencies[storybookPackageName] = '~6.2.9';
needsInstall = true;
}
}

View File

@ -0,0 +1,38 @@
import { Tree, readJson, writeJson } from '@nrwl/devkit';
import { createTree } from '@nrwl/devkit/testing';
import installAddonEssentials from './install-addon-essentials';
describe('Add the @storybook/addon-essentials package to package.json', () => {
let tree: Tree;
beforeEach(async () => {
tree = createTree();
});
it('should update package.json to include the new package', async () => {
writeJson(tree, 'package.json', {
devDependencies: {},
});
await installAddonEssentials(tree);
expect(
readJson(tree, 'package.json').devDependencies[
'@storybook/addon-essentials'
]
).toBeTruthy();
});
it('should not update package.json if package already exists', async () => {
writeJson(tree, 'package.json', {
dependencies: {
'@storybook/addon-essentials': '6.3.0',
},
});
await installAddonEssentials(tree);
expect(
readJson(tree, 'package.json').devDependencies[
'@storybook/addon-essentials'
]
).toBeFalsy();
});
});

View File

@ -0,0 +1,63 @@
import { formatFiles, Tree, logger, updateJson } from '@nrwl/devkit';
import { join } from 'path';
let needsInstall = false;
const targetStorybookVersion = '6.3.0';
function installAddonEssentials(tree: Tree) {
updateJson(tree, 'package.json', (json) => {
json.dependencies = json.dependencies || {};
json.devDependencies = json.devDependencies || {};
if (
!json.dependencies['@storybook/addon-essentials'] &&
!json.devDependencies['@storybook/addon-essentials']
) {
needsInstall = true;
json.devDependencies['@storybook/addon-essentials'] =
targetStorybookVersion;
}
return json;
});
}
function editRootMainJs(tree: Tree) {
let newContent: string;
const rootMainJsExists = tree.exists(`.storybook/main.js`);
if (rootMainJsExists) {
const rootMainJs = require(join(tree.root, '.storybook/main.js'));
const addonsArray: string[] = rootMainJs?.addons;
if (addonsArray) {
if (!addonsArray.includes('@storybook/addon-essentials')) {
addonsArray.push('@storybook/addon-essentials');
rootMainJs.addons = addonsArray;
}
} else {
rootMainJs.addons = ['@storybook/addon-essentials'];
}
newContent = `
module.exports = ${JSON.stringify(rootMainJs)}
`;
} else {
newContent = `
module.exports = {
stories: [],
addons: ['@storybook/addon-essentials'],
};
`;
}
tree.write(`.storybook/main.js`, newContent);
}
export default async function (tree: Tree) {
editRootMainJs(tree);
installAddonEssentials(tree);
await formatFiles(tree);
if (needsInstall) {
logger.info(
'Please make sure to run npm install or yarn install to get the latest packages added by this migration'
);
}
}

View File

@ -63,6 +63,7 @@ const IGNORE_MATCHES = {
'@angular-devkit/core',
'@angular-devkit/schematics',
'@storybook/addon-knobs',
'@storybook/addon-essentials',
'@storybook/core',
'rxjs',
],

365
yarn.lock
View File

@ -2272,7 +2272,14 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
"@babel/runtime@^7.0.0":
version "7.14.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d"
integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4":
version "7.13.10"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
@ -2420,6 +2427,11 @@
"@babel/helper-validator-identifier" "^7.14.0"
to-fast-properties "^2.0.0"
"@base2/pretty-print-object@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.0.tgz#860ce718b0b73f4009e153541faff2cb6b85d047"
integrity sha512-4Th98KlMHr5+JkxfcoDT//6vY8vM+iSPrLNpHhRyLx2CFYi8e2RfqPLdpbnpo0Q5lQC5hNB79yes07zb02fvCw==
"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@ -2548,7 +2560,7 @@
"@francoischalifour/autocomplete-preset-algolia" "^1.0.0-alpha.14"
algoliasearch "^4.0.0"
"@emotion/cache@^10.0.27", "@emotion/cache@^10.0.9":
"@emotion/cache@^10.0.27":
version "10.0.29"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0"
integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==
@ -2558,7 +2570,7 @@
"@emotion/utils" "0.11.3"
"@emotion/weak-memoize" "0.2.5"
"@emotion/core@^10.0.9", "@emotion/core@^10.1.1":
"@emotion/core@^10.1.1":
version "10.1.1"
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3"
integrity sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==
@ -2570,7 +2582,7 @@
"@emotion/sheet" "0.9.4"
"@emotion/utils" "0.11.3"
"@emotion/css@^10.0.27", "@emotion/css@^10.0.9":
"@emotion/css@^10.0.27":
version "10.0.27"
resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c"
integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==
@ -2921,7 +2933,16 @@
merge-source-map "^1.1.0"
schema-utils "^2.7.0"
"@mdx-js/mdx@^1.6.22":
"@mdx-js/loader@^1.6.22":
version "1.6.22"
resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-1.6.22.tgz#d9e8fe7f8185ff13c9c8639c048b123e30d322c4"
integrity sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==
dependencies:
"@mdx-js/mdx" "1.6.22"
"@mdx-js/react" "1.6.22"
loader-utils "2.0.0"
"@mdx-js/mdx@1.6.22", "@mdx-js/mdx@^1.6.22":
version "1.6.22"
resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba"
integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==
@ -2946,6 +2967,11 @@
unist-builder "2.0.3"
unist-util-visit "2.0.3"
"@mdx-js/react@1.6.22", "@mdx-js/react@^1.6.22":
version "1.6.22"
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573"
integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==
"@mdx-js/util@1.6.22":
version "1.6.22"
resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b"
@ -3678,6 +3704,131 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@storybook/addon-actions@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.3.0.tgz#e5a24c69d70da9aa98560f19d10c06a50495ca2e"
integrity sha512-7Ls1OIAdtAa4a27/bTuAlejQee4j7bFBkRzAeaHzcaZT1VVXoF6yBfMGuEGJI8brQ+KuSaIhIU2b0Iuzq47dDQ==
dependencies:
"@storybook/addons" "6.3.0"
"@storybook/api" "6.3.0"
"@storybook/client-api" "6.3.0"
"@storybook/components" "6.3.0"
"@storybook/core-events" "6.3.0"
"@storybook/theming" "6.3.0"
core-js "^3.8.2"
fast-deep-equal "^3.1.3"
global "^4.4.0"
lodash "^4.17.20"
polished "^4.0.5"
prop-types "^15.7.2"
react-inspector "^5.1.0"
regenerator-runtime "^0.13.7"
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
uuid-browser "^3.1.0"
"@storybook/addon-backgrounds@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.3.0.tgz#0562ec41ffff479803bd4b8a9d17abea2d6d6cdd"
integrity sha512-MzqD94IDfJ9oipFKMLoJhf3zTxqQ0DVfsWXGV1o2nslg8gZFFH04yXex2kVuTiHYCuaLxfk/wnlpSyzqX2+CZQ==
dependencies:
"@storybook/addons" "6.3.0"
"@storybook/api" "6.3.0"
"@storybook/client-logger" "6.3.0"
"@storybook/components" "6.3.0"
"@storybook/core-events" "6.3.0"
"@storybook/theming" "6.3.0"
core-js "^3.8.2"
global "^4.4.0"
memoizerific "^1.11.3"
regenerator-runtime "^0.13.7"
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
"@storybook/addon-controls@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.3.0.tgz#30275b9508a4d1acd1f3fa8f7dd432be629c3fec"
integrity sha512-caiWFJ/iCdZPHI5rwk26fAQsf8QI7WXIoB850SYVDhkIirzJVZjugvwgrqgTfVf2Z5dWOe9aceroC9rBClHAlQ==
dependencies:
"@storybook/addons" "6.3.0"
"@storybook/api" "6.3.0"
"@storybook/client-api" "6.3.0"
"@storybook/components" "6.3.0"
"@storybook/node-logger" "6.3.0"
"@storybook/theming" "6.3.0"
core-js "^3.8.2"
ts-dedent "^2.0.0"
"@storybook/addon-docs@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.3.0.tgz#b8b7f3b8a38d78b7c63ba2aa9b87bf078e8e942b"
integrity sha512-FpANy+7J3jpoxUoMfqwAetMatwbxQctOwN+Eh95uwQWYRZwsNHqdTv72/rtHiWR9wMaYThok5vqYHFvCpQTVPw==
dependencies:
"@babel/core" "^7.12.10"
"@babel/generator" "^7.12.11"
"@babel/parser" "^7.12.11"
"@babel/plugin-transform-react-jsx" "^7.12.12"
"@babel/preset-env" "^7.12.11"
"@jest/transform" "^26.6.2"
"@mdx-js/loader" "^1.6.22"
"@mdx-js/mdx" "^1.6.22"
"@mdx-js/react" "^1.6.22"
"@storybook/addons" "6.3.0"
"@storybook/api" "6.3.0"
"@storybook/builder-webpack4" "6.3.0"
"@storybook/client-api" "6.3.0"
"@storybook/client-logger" "6.3.0"
"@storybook/components" "6.3.0"
"@storybook/core" "6.3.0"
"@storybook/core-events" "6.3.0"
"@storybook/csf" "0.0.1"
"@storybook/csf-tools" "6.3.0"
"@storybook/node-logger" "6.3.0"
"@storybook/postinstall" "6.3.0"
"@storybook/source-loader" "6.3.0"
"@storybook/theming" "6.3.0"
acorn "^7.4.1"
acorn-jsx "^5.3.1"
acorn-walk "^7.2.0"
core-js "^3.8.2"
doctrine "^3.0.0"
escodegen "^2.0.0"
fast-deep-equal "^3.1.3"
global "^4.4.0"
html-tags "^3.1.0"
js-string-escape "^1.0.1"
loader-utils "^2.0.0"
lodash "^4.17.20"
p-limit "^3.1.0"
prettier "~2.2.1"
prop-types "^15.7.2"
react-element-to-jsx-string "^14.3.2"
regenerator-runtime "^0.13.7"
remark-external-links "^8.0.0"
remark-slug "^6.0.0"
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
"@storybook/addon-essentials@~6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.3.0.tgz#8b0329042e0f25192c04c78eac5c38d4d8259a62"
integrity sha512-8ejOP3l4UC2utDbcq8QUQ2nOqAOzL9ri20So5qrlTuBPtMmSNUea7p5yAGB0GOJ9j96k3pS2nU1/dlEqepo5nA==
dependencies:
"@storybook/addon-actions" "6.3.0"
"@storybook/addon-backgrounds" "6.3.0"
"@storybook/addon-controls" "6.3.0"
"@storybook/addon-docs" "6.3.0"
"@storybook/addon-measure" "^1.2.3"
"@storybook/addon-toolbars" "6.3.0"
"@storybook/addon-viewport" "6.3.0"
"@storybook/addons" "6.3.0"
"@storybook/api" "6.3.0"
"@storybook/node-logger" "6.3.0"
core-js "^3.8.2"
regenerator-runtime "^0.13.7"
storybook-addon-outline "^1.3.3"
ts-dedent "^2.0.0"
"@storybook/addon-knobs@~6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-6.3.0.tgz#f289c072729651150a27a163371df20922c24f93"
@ -3694,7 +3845,42 @@
react-lifecycles-compat "^3.0.4"
react-select "^3.2.0"
"@storybook/addons@6.3.0":
"@storybook/addon-measure@^1.2.3":
version "1.2.4"
resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-1.2.4.tgz#149705ef9de5e9251c012deb84406b3bc9307452"
integrity sha512-pxAo7QcETdiienZYMjAhX/3BqPnYTuH0ZSjmJzsr+yCBvZmZUciq1h3WvyUN59rT0ewFwLTKsmZG/wVZj+aN+Q==
"@storybook/addon-toolbars@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.3.0.tgz#5e5837812c7ba94e4d5be3b02b0f915a33b4f98b"
integrity sha512-E0LwAaoWNtmPfMq9GbySsK2ZdXlPf9gJQD1uI3KXbcaGBhtY136QmZS+VpUmPfilplrYJ2G6GAQoPHrIPUf1VQ==
dependencies:
"@storybook/addons" "6.3.0"
"@storybook/api" "6.3.0"
"@storybook/client-api" "6.3.0"
"@storybook/components" "6.3.0"
"@storybook/theming" "6.3.0"
core-js "^3.8.2"
regenerator-runtime "^0.13.7"
"@storybook/addon-viewport@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.3.0.tgz#a30660fe1873f16e955798718e3f14e26f4bff09"
integrity sha512-aOENuKIfmeQOhm++p2ezwIV9gET05s5/QQ1TTZrrPixQ3FxmCwAb/OqsmD4m/8e075C5gLXQEV47vGAkYyTm0Q==
dependencies:
"@storybook/addons" "6.3.0"
"@storybook/api" "6.3.0"
"@storybook/client-logger" "6.3.0"
"@storybook/components" "6.3.0"
"@storybook/core-events" "6.3.0"
"@storybook/theming" "6.3.0"
core-js "^3.8.2"
global "^4.4.0"
memoizerific "^1.11.3"
prop-types "^15.7.2"
regenerator-runtime "^0.13.7"
"@storybook/addons@6.3.0", "@storybook/addons@^6.3.0-beta.6":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.3.0.tgz#a86849f46a654d2d78b91fad0088264a32d4e58e"
integrity sha512-/dcq20HtdSw5+cG8znR59Y/uv2zCR2VjRK3N52IkGWk162b/UbSjjL0PhNnnQFGpH9Fruft6mqvjTAKT41kmJw==
@ -3740,7 +3926,7 @@
util-deprecate "^1.0.2"
webpack "4"
"@storybook/api@6.3.0":
"@storybook/api@6.3.0", "@storybook/api@^6.3.0-beta.6":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.3.0.tgz#5ecb646e7c3c4c7c494bb15f4c94554f7f4ee09e"
integrity sha512-swPMcQadLDRTnMjL9dwY6K1zXHn3KcAa3euvSHd1R4OKXTSBBj1zHvIaOrq6yHz7RIYOACmZlEV3CUru9FlvEA==
@ -3896,7 +4082,7 @@
core-js "^3.8.2"
global "^4.4.0"
"@storybook/components@6.3.0":
"@storybook/components@6.3.0", "@storybook/components@^6.3.0-beta.6":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.3.0.tgz#5ad372abd60ee0cb02516f960f514659e3fbf865"
integrity sha512-TDcazQAtNgE1E33jKKABx51XpvWyXMcJZFWA0d5wu8XrElrL1PuZqz7dPePoWKGMfTaPYWP6rRyDg4Svv36j+A==
@ -4003,7 +4189,7 @@
util-deprecate "^1.0.2"
webpack "4"
"@storybook/core-events@6.3.0":
"@storybook/core-events@6.3.0", "@storybook/core-events@^6.3.0-beta.6":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.3.0.tgz#5e220a866db5b93550b5c3464774a7b10ad036a6"
integrity sha512-ZGTm5nQvFLlc2LVgoDyxo99MbQcFqQzkxIQReFkO7hPwwkcjcwmdBtnlmkn9/p5QQ5/8aU0k+ceCkrBNu1M83w==
@ -4138,6 +4324,13 @@
npmlog "^4.1.2"
pretty-hrtime "^1.0.3"
"@storybook/postinstall@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.3.0.tgz#616999e96bc2f30e5deefd3c75415ce1dbc35cb3"
integrity sha512-QhhrhnB4yRdn5DGzygitccoKOYV+nKXWtQQm1TvEjMGrbZu57kI4X3TAsU4f3+wU8Xbdlfc8vhXpgCSzofRzGA==
dependencies:
core-js "^3.8.2"
"@storybook/react-docgen-typescript-plugin@1.0.2-canary.3c70e01.0":
version "1.0.2-canary.3c70e01.0"
resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.3c70e01.0.tgz#de49451523b86640463acc6028985ca11d8a63d1"
@ -4204,6 +4397,22 @@
core-js "^3.6.5"
find-up "^4.1.0"
"@storybook/source-loader@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.3.0.tgz#d1bbbb9c350c89f1207233d209694dcac5350e76"
integrity sha512-5LpqY5uu35Fg01D7Zu0xAT7ow6tcuHz+fkIxsGAJhzWovbV5NYl/BP8WSPv7TH+WjYve+RI2Xp6a9JFrgi9gpQ==
dependencies:
"@storybook/addons" "6.3.0"
"@storybook/client-logger" "6.3.0"
"@storybook/csf" "0.0.1"
core-js "^3.8.2"
estraverse "^5.2.0"
global "^4.4.0"
loader-utils "^2.0.0"
lodash "^4.17.20"
prettier "~2.2.1"
regenerator-runtime "^0.13.7"
"@storybook/theming@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.3.0.tgz#4b6ef023631663d8e50f1348469b9a9641244cd0"
@ -5808,7 +6017,7 @@ acorn-walk@^6.0.1:
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c"
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
acorn-walk@^7.0.0, acorn-walk@^7.1.1:
acorn-walk@^7.0.0, acorn-walk@^7.1.1, acorn-walk@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
@ -5818,7 +6027,7 @@ acorn@^6.0.1, acorn@^6.2.1, acorn@^6.4.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
acorn@^7.0.0, acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0:
acorn@^7.0.0, acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
@ -10530,14 +10739,6 @@ dom-converter@^0.2:
dependencies:
utila "~0.4"
dom-helpers@^5.0.1:
version "5.2.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
dom-serialize@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
@ -11140,7 +11341,7 @@ escalade@^3.0.2, escalade@^3.1.1:
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
escape-html@^1.0.3, escape-html@~1.0.3:
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
@ -12454,7 +12655,7 @@ gitconfiglocal@^1.0.0:
dependencies:
ini "^1.3.2"
github-slugger@^1.1.1:
github-slugger@^1.0.0, github-slugger@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9"
integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==
@ -13865,7 +14066,7 @@ is-absolute-url@^2.0.0:
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=
is-absolute-url@^3.0.3:
is-absolute-url@^3.0.0, is-absolute-url@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698"
integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==
@ -14052,6 +14253,14 @@ is-docker@^2.1.1:
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
is-dom@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a"
integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==
dependencies:
is-object "^1.0.1"
is-window "^1.0.2"
is-dotfile@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
@ -14288,6 +14497,11 @@ is-plain-obj@^2.0.0:
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
is-plain-object@3.0.1, is-plain-object@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b"
integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==
is-plain-object@^2.0.3, is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
@ -14295,11 +14509,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
is-plain-object@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b"
integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==
is-potential-custom-element-name@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397"
@ -14427,6 +14636,11 @@ is-whitespace-character@^1.0.0:
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7"
integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==
is-window@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d"
integrity sha1-LIlspT25feRdPDMTOmXYyfVjSA0=
is-windows@^1.0.1, is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@ -16451,6 +16665,11 @@ mdast-util-to-markdown@^0.6.0, mdast-util-to-markdown@^0.6.1, mdast-util-to-mark
repeat-string "^1.0.0"
zwitch "^1.0.0"
mdast-util-to-string@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527"
integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==
mdast-util-to-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b"
@ -16498,11 +16717,6 @@ memfs@^3.1.2, memfs@^3.2.0:
dependencies:
fs-monkey "1.0.3"
memoize-one@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==
memoizee@0.4.15:
version "0.4.15"
resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72"
@ -19911,7 +20125,7 @@ prompts@^2.4.0:
kleur "^3.0.3"
sisteransi "^1.0.5"
prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
prop-types@15.7.2, prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@ -20305,6 +20519,14 @@ react-draggable@^4.4.3:
classnames "^2.2.5"
prop-types "^15.6.0"
react-element-to-jsx-string@^14.3.2:
version "14.3.2"
resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.2.tgz#c0000ed54d1f8b4371731b669613f2d4e0f63d5c"
integrity sha512-WZbvG72cjLXAxV7VOuSzuHEaI3RHj10DZu8EcKQpkKcAj7+qAkG5XUeSdX5FXrA0vPrlx0QsnAzZEBJwzV0e+w==
dependencies:
"@base2/pretty-print-object" "1.0.0"
is-plain-object "3.0.1"
react-error-boundary@^3.1.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.3.tgz#276bfa05de8ac17b863587c9e0647522c25e2a0b"
@ -20333,12 +20555,14 @@ react-helmet-async@^1.0.7:
react-fast-compare "^3.2.0"
shallowequal "^1.1.0"
react-input-autosize@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85"
integrity sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==
react-inspector@^5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8"
integrity sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==
dependencies:
prop-types "^15.5.8"
"@babel/runtime" "^7.0.0"
is-dom "^1.0.0"
prop-types "^15.0.0"
react-is@16.13.1, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
@ -20447,20 +20671,6 @@ react-router@5.1.2:
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
react-select@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.2.0.tgz#de9284700196f5f9b5277c5d850a9ce85f5c72fe"
integrity sha512-B/q3TnCZXEKItO0fFN/I0tWOX3WJvi/X2wtdffmwSQVRwg5BpValScTO1vdic9AxlUgmeSzib2hAZAwIUQUZGQ==
dependencies:
"@babel/runtime" "^7.4.4"
"@emotion/cache" "^10.0.9"
"@emotion/core" "^10.0.9"
"@emotion/css" "^10.0.9"
memoize-one "^5.0.0"
prop-types "^15.6.0"
react-input-autosize "^3.0.0"
react-transition-group "^4.3.0"
react-sizeme@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-3.0.1.tgz#4d12f4244e0e6a0fb97253e7af0314dc7c83a5a0"
@ -20502,16 +20712,6 @@ react-textarea-autosize@^8.3.0:
use-composed-ref "^1.0.0"
use-latest "^1.0.0"
react-transition-group@^4.3.0:
version "4.4.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==
dependencies:
"@babel/runtime" "^7.5.5"
dom-helpers "^5.0.1"
loose-envify "^1.4.0"
prop-types "^15.6.2"
react@16.14.0:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
@ -20926,6 +21126,17 @@ release-it@^7.4.0:
window-size "1.1.1"
yargs-parser "11.0.0"
remark-external-links@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345"
integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA==
dependencies:
extend "^3.0.0"
is-absolute-url "^3.0.0"
mdast-util-definitions "^4.0.0"
space-separated-tokens "^1.0.0"
unist-util-visit "^2.0.0"
remark-footnotes@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f"
@ -20989,6 +21200,15 @@ remark-rehype@^8.0.0:
dependencies:
mdast-util-to-hast "^10.2.0"
remark-slug@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.0.0.tgz#2b54a14a7b50407a5e462ac2f376022cce263e2c"
integrity sha512-ln67v5BrGKHpETnm6z6adlJPhESFJwfuZZ3jrmi+lKTzeZxh2tzFzUfDD4Pm2hRGOarHLuGToO86MNMZ/hA67Q==
dependencies:
github-slugger "^1.0.0"
mdast-util-to-string "^1.0.0"
unist-util-visit "^2.0.0"
remark-squeeze-paragraphs@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead"
@ -22502,6 +22722,17 @@ store2@^2.12.0:
resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf"
integrity sha512-7t+/wpKLanLzSnQPX8WAcuLCCeuSHoWdQuh9SB3xD0kNOM38DNf+0Oa+wmvxmYueRzkmh6IcdKFtvTa+ecgPDw==
storybook-addon-outline@^1.3.3:
version "1.3.4"
resolved "https://registry.yarnpkg.com/storybook-addon-outline/-/storybook-addon-outline-1.3.4.tgz#4d90c262781db995312ca8bb6d4ba26028ff55b6"
integrity sha512-UNFansfJq1j5Z+GdB8/eoSck9A27VPm5HPG4LBnPKwvAmvjccVgY9mcbcG/ezF83RlrtCOKkfQ1NgOqz2NlGGg==
dependencies:
"@storybook/addons" "^6.3.0-beta.6"
"@storybook/api" "^6.3.0-beta.6"
"@storybook/components" "^6.3.0-beta.6"
"@storybook/core-events" "^6.3.0-beta.6"
ts-dedent "^2.1.1"
stream-browserify@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f"
@ -23623,6 +23854,11 @@ ts-dedent@^2.0.0:
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.0.0.tgz#47c5eb23d9096f3237cc413bc82d387d36dbe690"
integrity sha512-DfxKjSFQfw9+uf7N9Cy8Ebx9fv5fquK4hZ6SD3Rzr+1jKP6AVA6H8+B5457ZpUs0JKsGpGqIevbpZ9DMQJDp1A==
ts-dedent@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.1.1.tgz#6dd56870bb5493895171334fa5d7e929107e5bbc"
integrity sha512-riHuwnzAUCfdIeTBNUq7+Yj+ANnrMXo/7+Z74dIdudS7ys2k8aSGMzpJRMFDF7CLwUTbtvi1ZZff/Wl+XxmqIA==
ts-essentials@^2.0.3:
version "2.0.12"
resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745"
@ -24401,6 +24637,11 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
uuid-browser@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410"
integrity sha1-DwWkCu90+eWVHiDvv0SxGHHlZBA=
uuid@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"