From 5715718e883f342a2d05ea80ced789161f096603 Mon Sep 17 00:00:00 2001 From: jonniebigodes Date: Fri, 2 Jul 2021 21:29:08 +0100 Subject: [PATCH] updates the loader docs --- docs/snippets/angular/loader-story.mdx.mdx | 28 ++++++++++++++ docs/snippets/angular/loader-story.ts.mdx | 37 +++++++++++++++++++ .../storybook-preview-global-loader.js.mdx | 2 +- docs/snippets/react/loader-story.js.mdx | 5 +++ docs/snippets/react/loader-story.mdx.mdx | 26 +++++++++++++ .../storybook-preview-global-loader.js.mdx | 13 ------- docs/snippets/svelte/loader-story.js.mdx | 11 ++++-- docs/snippets/svelte/loader-story.mdx.mdx | 30 +++++++++++++++ docs/snippets/vue/loader-story.3.js.mdx | 28 ++++++++++++++ docs/snippets/vue/loader-story.mdx.mdx | 30 +++++++++++++++ docs/writing-stories/loaders.md | 29 +++++++++------ 11 files changed, 211 insertions(+), 28 deletions(-) create mode 100644 docs/snippets/angular/loader-story.mdx.mdx create mode 100644 docs/snippets/angular/loader-story.ts.mdx rename docs/snippets/{svelte => common}/storybook-preview-global-loader.js.mdx (56%) create mode 100644 docs/snippets/react/loader-story.mdx.mdx delete mode 100644 docs/snippets/react/storybook-preview-global-loader.js.mdx create mode 100644 docs/snippets/svelte/loader-story.mdx.mdx create mode 100644 docs/snippets/vue/loader-story.3.js.mdx create mode 100644 docs/snippets/vue/loader-story.mdx.mdx diff --git a/docs/snippets/angular/loader-story.mdx.mdx b/docs/snippets/angular/loader-story.mdx.mdx new file mode 100644 index 000000000000..e1f84461b134 --- /dev/null +++ b/docs/snippets/angular/loader-story.mdx.mdx @@ -0,0 +1,28 @@ +```md + + +import { Meta, Story } from '@storybook/addon-docs/blocks'; + +import TodoItem from './TodoItem'; + +import fetch from 'node-fetch'; + + + + ({ + todo: await ( + await fetch("https://jsonplaceholder.typicode.com/todos/1") + ).json(), + }), + ]} +> + {(args, { loaded: { todo } }) => ({ + props: { + todo: todo, + }, + })} + +``` \ No newline at end of file diff --git a/docs/snippets/angular/loader-story.ts.mdx b/docs/snippets/angular/loader-story.ts.mdx new file mode 100644 index 000000000000..837cd804a9a5 --- /dev/null +++ b/docs/snippets/angular/loader-story.ts.mdx @@ -0,0 +1,37 @@ +```ts +// TodoItem.stories.ts + +import { moduleMetadata, Story, Meta } from '@storybook/angular'; + +import fetch from 'node-fetch'; + +import { CommonModule } from '@angular/common'; + +import TodoItem from './TodoItem'; + +export default { + component: TodoItem, + decorators: [ + moduleMetadata({ + declarations: [TodoItem], + imports: [CommonModule], + }), + ], + title: 'Examples/Loader', +} as Meta; + +export const Primary = (args, { loaded: { todo } }) => { + return { + props: { + args, + todo, + }, + }; +}; + +Primary.loaders = [ + async () => ({ + todo: await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(), + }), +]; +``` \ No newline at end of file diff --git a/docs/snippets/svelte/storybook-preview-global-loader.js.mdx b/docs/snippets/common/storybook-preview-global-loader.js.mdx similarity index 56% rename from docs/snippets/svelte/storybook-preview-global-loader.js.mdx rename to docs/snippets/common/storybook-preview-global-loader.js.mdx index 8c10b6a19050..2e0fe2398059 100644 --- a/docs/snippets/svelte/storybook-preview-global-loader.js.mdx +++ b/docs/snippets/common/storybook-preview-global-loader.js.mdx @@ -5,7 +5,7 @@ import fetch from 'node-fetch'; export const loaders = [ async () => ({ - currentUser: (await fetch('https://jsonplaceholder.typicode.com/users/1')).json(), + currentUser: await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(), }), ]; ``` \ No newline at end of file diff --git a/docs/snippets/react/loader-story.js.mdx b/docs/snippets/react/loader-story.js.mdx index b5ea01dec7c3..d901a012173a 100644 --- a/docs/snippets/react/loader-story.js.mdx +++ b/docs/snippets/react/loader-story.js.mdx @@ -7,6 +7,11 @@ import fetch from 'node-fetch'; import { TodoItem } from './TodoItem'; +export default { + component: TodoItem, + title: 'Examples/Loader', +}; + export const Primary = (args, { loaded: { todo } }) => ; Primary.loaders = [ async () => ({ diff --git a/docs/snippets/react/loader-story.mdx.mdx b/docs/snippets/react/loader-story.mdx.mdx new file mode 100644 index 000000000000..71b0e979a36d --- /dev/null +++ b/docs/snippets/react/loader-story.mdx.mdx @@ -0,0 +1,26 @@ +```md + + +import { Meta, Story } from '@storybook/addon-docs'; + +import fetch from 'node-fetch'; + +import { TodoItem } from './TodoItem'; + + + + ({ + todo: await ( + await fetch("https://jsonplaceholder.typicode.com/todos/1") + ).json(), + }), + ]} +> + {(args, { loaded: { todo } }) => ( + + )} + +``` \ No newline at end of file diff --git a/docs/snippets/react/storybook-preview-global-loader.js.mdx b/docs/snippets/react/storybook-preview-global-loader.js.mdx deleted file mode 100644 index 1b005cbdf353..000000000000 --- a/docs/snippets/react/storybook-preview-global-loader.js.mdx +++ /dev/null @@ -1,13 +0,0 @@ -```js -// .storybook/preview.js - -import React from 'react'; - -import fetch from 'node-fetch'; - -export const loaders = [ - async () => ({ - currentUser: (await fetch('https://jsonplaceholder.typicode.com/users/1')).json(), - }), -]; -``` \ No newline at end of file diff --git a/docs/snippets/svelte/loader-story.js.mdx b/docs/snippets/svelte/loader-story.js.mdx index cb17b610f1ae..87977a4c083a 100644 --- a/docs/snippets/svelte/loader-story.js.mdx +++ b/docs/snippets/svelte/loader-story.js.mdx @@ -5,14 +5,19 @@ import fetch from 'node-fetch'; import TodoItem from './TodoItem.svelte'; +export default { + component: TodoItem, + title: 'Examples/Loader', +}; + export const Primary = (args, { loaded: { todo } }) => ({ Component: TodoItem, - props: {...args, ...todo}, + props: { ...args, ...todo }, }); -Primary.loaders = [ +Primaryloaders = [ async () => ({ - todo: (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(), + todo: await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(), }), ]; ``` \ No newline at end of file diff --git a/docs/snippets/svelte/loader-story.mdx.mdx b/docs/snippets/svelte/loader-story.mdx.mdx new file mode 100644 index 000000000000..fcda10e867d9 --- /dev/null +++ b/docs/snippets/svelte/loader-story.mdx.mdx @@ -0,0 +1,30 @@ +```md + + +import { Meta, Story } from '@storybook/addon-docs'; + +import TodoItem from './TodoItem.svelte'; + +import fetch from 'node-fetch'; + + + + ({ + todo: await ( + await fetch("https://jsonplaceholder.typicode.com/todos/1") + ).json(), + }), + ]} +> + {(args, { loaded: { todo } }) => ({ + Component: SampleLoaderComponent, + props: { + ...args, + todo, + }, + })} + +``` \ No newline at end of file diff --git a/docs/snippets/vue/loader-story.3.js.mdx b/docs/snippets/vue/loader-story.3.js.mdx new file mode 100644 index 000000000000..f8a7739a6ec0 --- /dev/null +++ b/docs/snippets/vue/loader-story.3.js.mdx @@ -0,0 +1,28 @@ +```js +// TodoItem.stories.js + +import TodoItem from './TodoItem.vue'; + +import fetch from 'node-fetch'; + +export default { + component: TodoItem, + title: 'Examples/Loader', +}; + +export const Primary = (args, { loaded: { todo } }) => { + return { + components: { TodoItem }, + setup() { + return { args, todo: todo }; + }, + template: ``, + }; +}; + +SampleStory.loaders = [ + async () => ({ + todo: await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(), + }), +]; +``` \ No newline at end of file diff --git a/docs/snippets/vue/loader-story.mdx.mdx b/docs/snippets/vue/loader-story.mdx.mdx new file mode 100644 index 000000000000..8d3e8e8cf9c8 --- /dev/null +++ b/docs/snippets/vue/loader-story.mdx.mdx @@ -0,0 +1,30 @@ +```md + + +import { Meta, Story } from '@storybook/addon-docs'; + +import TodoItem from './TodoItem.vue'; + +import fetch from 'node-fetch'; + + + + ({ + todo: await ( + await fetch("https://jsonplaceholder.typicode.com/todos/1") + ).json(), + }), + ]} +> + {(args, { loaded: { todo } }) => ({ + components: { TodoItem }, + setup() { + return { args, todo: todo }; + }, + template: ``, + })} + +``` \ No newline at end of file diff --git a/docs/writing-stories/loaders.md b/docs/writing-stories/loaders.md index af5a8bd4568e..6dd9c9e5e2ee 100644 --- a/docs/writing-stories/loaders.md +++ b/docs/writing-stories/loaders.md @@ -2,30 +2,36 @@ title: 'Loaders (experimental)' --- -Loaders (experimental) are asynchronous functions that load data for a story and its [decorators](./decorators.md). A story's loaders run before the story renders, and the loaded data is passed into the story via its render context. +Loaders (experimental) are asynchronous functions that load data for a story and its [decorators](./decorators.md). A story's loaders run before the story renders, and the loaded data injected into the story via its render context. -Loaders can be used to load any asset, typically as a performance optimization. They were designed for to lazy load components and other large story imports. They can also be used to load remote API data to be used in a story. However, [Args](./args.md) is the recommended way to manage story data, and we're building up an ecosystem of tools and techniques around Args which might not be compatible with loaded data. +Loaders can be used to load any asset, lazy load components, or fetch data from a remote API. This feature was designed as a performance optimization to handle large story imports. However, [Args](./args.md) is the recommended way to manage story data. We're building up an ecosystem of tools and techniques around Args that might not be compatible with loaded data. -Loaders are an advanced feature ("escape hatch") and we only recommend using them if you have a specific need that can't be fulfilled by other means. They are experimental in Storybook 6.1 and the APIs are subject to change outside of the normal semver cycle. +They are an advanced feature (i.e., escape hatch), and we only recommend using them if you have a specific need that other means can't fulfill. They are experimental in Storybook 6.1, and the APIs are subject to change outside of the normal semver cycle. ## Fetching API data -Stories are isolated component examples that render internal data that's defined as part of the story or alongside the story as [args](./args.md). +Stories are isolated component examples that render internal data defined as part of the story or alongside the story as [args](./args.md). -Loaders are useful when you need to load story data externally, e.g. from a remote API. Consider the following example that fetches a todo item for display in a todo list: +Loaders are helpful when you need to load story data externally (e.g., from a remote API). Consider the following example that fetches a todo item to display in a todo list: -The loaded data is combined into a `loaded` field on the story context, which is the second argument to a story function. In this example we spread the story's args in first, so they take priority over the static data provided by the loader. +The response obtained from the remote API call is combined into a `loaded` field on the story context, which is the second argument to a story function. For example, in React, the story's args were spread first to prioritize them over the static data provided by the loader. Other frameworks will not need such requisite. ## Global loaders @@ -35,20 +41,19 @@ We can also set a loader for **all stories** via the `loaders` export of your [` -In this example, we load a "current user" that is available as `loaded.currentUser` for all stories. +In this example, we load a "current user" available as `loaded.currentUser` for all stories. ## Loader inheritance -Like parameters, loaders can be defined globally, at the component level and for a single story (as we’ve seen). +Like [parameters](./parameters.md), loaders can be defined globally, at the component level, and for a single story (as we’ve seen). -All loaders, defined at all levels that apply to a story, run before the story is rendered. +All loaders, defined at all levels that apply to a story, run before the story renders in Storybook's canvas. - All loaders run in parallel - All results are the `loaded` field in the story context @@ -63,3 +68,5 @@ Loaders have the following known limitations: - They are not yet compatible with the storyshots addon ([#12703](https://github.com/storybookjs/storybook/issues/12703)). - They are not yet compatible with inline-rendered stories in Storybook Docs ([#12726](https://github.com/storybookjs/storybook/issues/12726)). + +If you're interested in contributing to this feature, read our [contribution guide](../contribute/how-to-contribute.md) and submit a pull request with your work. \ No newline at end of file