Skip to content

Commit

Permalink
Merge pull request #9877 from storybookjs/refactor-client-api
Browse files Browse the repository at this point in the history
Refactor Client API: pull metadata handling code into the store.
  • Loading branch information
tmeasday authored Feb 20, 2020
2 parents f9f0b82 + 5b56f44 commit a7dc544
Show file tree
Hide file tree
Showing 27 changed files with 649 additions and 602 deletions.
51 changes: 49 additions & 2 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
- [Migration](#migration)
- [From version 5.3.x to 6.0.x](#from-version-53x-to-60x)
- [New addon presets](#new-addon-presets)
- [Removed legacy story APIs](#removed-legacy-story-apis)
- [Client API changes](#client-api-changes)
- [Removed legacy story APIs](#removed-legacy-story-apis)
- [Can no longer add decorators/parameters after stories](#can-no-longer-add-decorators-parameters-after-stories)
- [Changed Parameter Handling](#changed-parameter-handling)
- [From version 5.2.x to 5.3.x](#from-version-52x-to-53x)
- [To main.js configuration](#to-mainjs-configuration)
- [Create React App preset](#create-react-app-preset)
Expand Down Expand Up @@ -126,14 +129,58 @@ MyNonCheckedStory.story = {
};
```

### Removed Legacy Story APIs
### Client API changes

#### Removed Legacy Story APIs

In 6.0 we removed a set of APIs from the underlying `StoryStore` (which wasn't publicly accessible):

- `getStories`, `getStoryFileName`, `getStoryAndParameters`, `getStory`, `getStoryWithContext`, `hasStoryKind`, `hasStory`, `dumpStoryBook`, `size`, `clean`

Although these were private APIs, if you were using them, you could probably use the newer APIs (which are still private): `getStoriesForKind`, `getRawStory`, `removeStoryKind`, `remove`.

#### Can no longer add decorators/parameters after stories

You can no longer add decorators and parameters globally after you added your first story, and you can no longer add decorators and parameters to a kind after you've added your first story to it.

It unclear and confusing what happened if you did. If you want to disable a decorator for certain stories, use a parameter to do so:

```js
export StoryOne = ...;
StoryOne.story = { parameters: { addon: { disable: true } } };
```

If you want to use a parameter for a subset of stories in a kind, simply use a variable to do so:

```js
const commonParameters = { x: { y: 'z' } };
export StoryOne = ...;
StoryOne.story = { parameters: { ...commonParameters, other: 'things' } };
```

#### Changed Parameter Handling

There have been a few rationalizations of parameter handling in 6.0 to make things more predictable and fit better with the intention of parameters:

_All parameters are now merged recursively to arbitrary depth._

In 5.3 we sometimes merged parameters all the way down and sometimes did not depending on where you added them. It was confusing. If you were relying on this behaviour, let us know.

_Array parameters are no longer "merged"._

If you override an array parameter, the override will be the end product. If you want the old behaviour (appending a new value to an array parameter), export the original and use array spread. This will give you maximum flexibility:

```js
import { allBackgrounds } from './util/allBackgrounds';

export StoryOne = ...;
StoryOne.story = { parameters: { backgrounds: [...allBackgrounds, '#zyx' ] } };
```

_You cannot set parameters from decorators_

Parameters are intended to be statically set at story load time. So setting them via a decorator doesn't quite make sense. If you were using this to control the rendering of a story, chances are using the new `args` feature is a more idiomatic way to do this.

## From version 5.2.x to 5.3.x

### To main.js configuration
Expand Down
3 changes: 1 addition & 2 deletions addons/a11y/src/preset/addDecorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { addDecorator } from '@storybook/client-api';
import { withA11Y } from '../index';

addDecorator(withA11Y);
export const decorators = [withA11Y];
3 changes: 1 addition & 2 deletions addons/knobs/src/preset/addDecorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { addDecorator } from '@storybook/client-api';
import { withKnobs } from '../index';

addDecorator(withKnobs);
export const decorators = [withKnobs];
23 changes: 7 additions & 16 deletions app/vue/src/client/preview/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,13 @@ function decorateStory(
(decorated: StoryFn<VueConstructor>, decorator) => (context: StoryContext = defaultContext) => {
let story;

const decoratedStory = decorator(p => {
story = decorated(
p
? {
...context,
...p,
parameters: {
...context.parameters,
...p.parameters,
},
}
: context
);

return story;
}, context);
const decoratedStory = decorator(
({ parameters, ...innerContext }: StoryContext = {} as StoryContext) => {
story = decorated({ ...context, ...innerContext });
return story;
},
context
);

if (!story) {
story = decorated(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ exports[`Storyshots Core/Parameters passed to story 1`] = `
<button
_ngcontent-a-c18=""
>
Parameters are {"docs":{"iframeHeight":"60px"},"options":{},"globalParameter":"globalParameter","framework":"angular","chapterParameter":"chapterParameter","storyParameter":"storyParameter","__id":"core-parameters--passed-to-story"}
Parameters are {"docs":{"iframeHeight":"60px"},"globalParameter":"globalParameter","framework":"angular","chapterParameter":"chapterParameter","storyParameter":"storyParameter","__id":"core-parameters--passed-to-story"}
</button>
</storybook-button-component>
</storybook-dynamic-app-root>
Expand Down
16 changes: 4 additions & 12 deletions examples/angular-cli/src/stories/addon-background.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,6 @@ import { moduleMetadata, storiesOf } from '@storybook/angular';
import { Button } from '@storybook/angular/demo';
import { AppComponent } from '../app/app.component';

storiesOf('Addon/Background', module)
.addParameters({
backgrounds: [
{ name: 'twitter', value: '#00aced', default: true },
{ name: 'facebook', value: '#3b5998' },
],
})
.add('background component', () => ({
component: AppComponent,
props: {},
}));

storiesOf('Addon/Background', module)
.addDecorator(
moduleMetadata({
Expand All @@ -26,6 +14,10 @@ storiesOf('Addon/Background', module)
{ name: 'facebook', value: '#3b5998' },
],
})
.add('background component', () => ({
component: AppComponent,
props: {},
}))
.add('background template', () => ({
template: `<storybook-button-component [text]="text" (onClick)="onClick($event)"></storybook-button-component>`,
props: {
Expand Down
11 changes: 4 additions & 7 deletions examples/angular-cli/src/stories/addon-centered.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@ import { moduleMetadata, storiesOf } from '@storybook/angular';
import { Button } from '@storybook/angular/demo';
import { AppComponent } from '../app/app.component';

storiesOf('Addon/Centered', module)
.addDecorator(centered)
.add('centered component', () => ({
component: AppComponent,
props: {},
}));

storiesOf('Addon/Centered', module)
.addDecorator(
moduleMetadata({
declarations: [Button],
})
)
.addDecorator(centered)
.add('centered component', () => ({
component: AppComponent,
props: {},
}))
.add('centered template', () => ({
template: `<storybook-button-component [text]="text" (onClick)="onClick($event)"></storybook-button-component>`,
props: {
Expand Down
4 changes: 4 additions & 0 deletions examples/official-storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ addParameters({
page: () => <DocsPage subtitleSlot={({ selectedKind }) => `Subtitle: ${selectedKind}`} />,
},
});

export const parameters = {
exportedParameter: 'exportedParameter',
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@ import React from 'react';

// We would need to add this in config.js idiomatically however that would make this file a bit confusing
import { addParameters } from '@storybook/react';
import { addDecorator } from '@storybook/react/dist/client/preview';

addDecorator(fn => fn({ customStoryContext: 52, parameters: { customParameter: 42 } }));

addParameters({ globalParameter: 'globalParameter' });

export default {
title: 'Core/Parameters',
decorators: [fn => fn({ parameters: { decoratorParameter: 'decoratorParameter' } })],
parameters: {
chapterParameter: 'chapterParameter',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exports[`Storyshots Core/Parameters passed to story 1`] = `
id="root"
>
<div>
Parameters are {"globalParameter":"globalParameter","options":{},"docs":{},"framework":"riot","chapterParameter":"chapterParameter","__id":"core-parameters--passed-to-story","storyParameter":"storyParameter","id":"root","dataIs":"parameters"}
Parameters are {"globalParameter":"globalParameter","framework":"riot","chapterParameter":"chapterParameter","__id":"core-parameters--passed-to-story","storyParameter":"storyParameter","id":"root","dataIs":"parameters"}
</div>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

exports[`Storyshots Core/Parameters passed to story 1`] = `
<div>
Parameters are {"docs":{"inlineStories":true,"iframeHeight":"60px"},"options":{},"globalParameter":"globalParameter","framework":"vue","chapterParameter":"chapterParameter","storyParameter":"storyParameter","__id":"core-parameters--passed-to-story"}
Parameters are {"docs":{"inlineStories":true,"iframeHeight":"60px"},"globalParameter":"globalParameter","framework":"vue","chapterParameter":"chapterParameter","storyParameter":"storyParameter","__id":"core-parameters--passed-to-story"}
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,9 @@ exports[`Storyshots Custom/Decorator for Vue With Data 1`] = `
"inlineStories": true,
"iframeHeight": "60px"
},
"options": {},
"globalParameter": "globalParameter",
"framework": "vue",
"__id": "custom-decorator-for-vue--with-data",
"customParameter": 42
"__id": "custom-decorator-for-vue--with-data"
},
"customContext": 52
}
Expand Down
11 changes: 0 additions & 11 deletions lib/client-api/src/client_api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ jest.mock('@storybook/client-logger', () => ({
}));

describe('preview.client_api', () => {
afterEach(() => {
const { clientApi } = getContext();
clientApi.clearDecorators();
clientApi.clearParameters();
});
describe('setAddon', () => {
it('should register addons', () => {
const { clientApi } = getContext();
Expand Down Expand Up @@ -598,8 +593,6 @@ describe('preview.client_api', () => {
b: 'kind',
c: 'story',
fileName: expect.any(String),
options: expect.any(Object),
docs: expect.any(Object),
});
});

Expand All @@ -616,8 +609,6 @@ describe('preview.client_api', () => {
global: true,
sub: { global: true },
},
options: expect.any(Object),
docs: expect.any(Object),
});

storiesOf('kind', module)
Expand Down Expand Up @@ -654,8 +645,6 @@ describe('preview.client_api', () => {
},
},
fileName: expect.any(String),
options: expect.any(Object),
docs: expect.any(Object),
});
});
});
Expand Down
Loading

0 comments on commit a7dc544

Please sign in to comment.