From 244bc1b943c1658da5b0198961ea83a2401e39a1 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 25 Jul 2021 22:13:31 +1000 Subject: [PATCH 001/285] WIP --- lib/client-api/src/new/ArgsStore.ts | 25 ++++++ lib/client-api/src/new/GlobalsStore.ts | 21 +++++ lib/client-api/src/new/PreviewStore.ts | 81 +++++++++++++++++++ .../src/new/StoriesMetadataStore.ts | 28 +++++++ lib/client-api/src/new/prepareStory.ts | 46 +++++++++++ lib/client-api/src/new/processCSFFile.ts | 11 +++ lib/client-api/src/new/types.ts | 69 ++++++++++++++++ 7 files changed, 281 insertions(+) create mode 100644 lib/client-api/src/new/ArgsStore.ts create mode 100644 lib/client-api/src/new/GlobalsStore.ts create mode 100644 lib/client-api/src/new/PreviewStore.ts create mode 100644 lib/client-api/src/new/StoriesMetadataStore.ts create mode 100644 lib/client-api/src/new/prepareStory.ts create mode 100644 lib/client-api/src/new/processCSFFile.ts create mode 100644 lib/client-api/src/new/types.ts diff --git a/lib/client-api/src/new/ArgsStore.ts b/lib/client-api/src/new/ArgsStore.ts new file mode 100644 index 00000000000..f2f6093cd95 --- /dev/null +++ b/lib/client-api/src/new/ArgsStore.ts @@ -0,0 +1,25 @@ +import { Channel, StoryId, Args } from './types'; + +export class ArgsStore { + argsByStoryId: Record; + + constructor({ channel }: { channel: Channel }) { + // TODO -- watch + emit on channel + + // QN -- how do args get initialized? + // -- we need pass args when a story is first rendered + this.argsByStoryId = {}; + } + + argsForStoryId(storyId: StoryId) { + if (!storyId in this.argsForStoryId) { + throw new Error(`No args know for ${storyId} -- has it been rendered yet?`); + } + + return this.argsByStoryId[storyId]; + } + + updateArgsByStoryId() { + // TODO: set, emit + } +} diff --git a/lib/client-api/src/new/GlobalsStore.ts b/lib/client-api/src/new/GlobalsStore.ts new file mode 100644 index 00000000000..c260fd270a2 --- /dev/null +++ b/lib/client-api/src/new/GlobalsStore.ts @@ -0,0 +1,21 @@ +import { Channel, Globals } from './types'; + +export class GlobalsStore { + globals: Globals; + + constructor({ channel }: { channel: Channel }) { + // TODO -- watch + emit on channel + + // QN -- how do globals get initialized? + // -- we need to get passed metadata after preview entries are initialized. + this.globals = {}; + } + + get() { + return this.globals; + } + + update() { + // TODO: set, emit + } +} diff --git a/lib/client-api/src/new/PreviewStore.ts b/lib/client-api/src/new/PreviewStore.ts new file mode 100644 index 00000000000..3cc66a5206e --- /dev/null +++ b/lib/client-api/src/new/PreviewStore.ts @@ -0,0 +1,81 @@ +import { StoriesMetadataStore } from './StoriesMetadataStore'; +import { ArgsStore } from './ArgsStore'; +import { GlobalsStore } from './GlobalsStore'; +import { processCSFFile } from './processCSFFile'; +import { prepareStory } from './prepareStory'; +import { CSFFile, StoryId, Channel, StoriesMetadata, ModuleImporter, GlobalMeta } from './types'; + +// TODO: +// - figure out how the channel is wired up? Do we pass it into every substore? + +export class PreviewStore { + storiesMetadata: StoriesMetadataStore; + + importer: ModuleImporter; + + globalMeta: GlobalMeta; + + globals: GlobalsStore; + + args: ArgsStore; + + constructor({ + channel, + storiesMetadata, + importerInput, + }: { + channel: Channel; + storiesMetadata: StoriesMetadata; + importerInput: ModuleImporter; + }) { + this.storiesMetadata = new StoriesMetadataStore(storiesMetadata); + this.importer = importerInput; + this.globalMeta = {}; + this.globals = new GlobalsStore({ channel }); + this.args = new ArgsStore({ channel }); + } + + updateGlobalMeta(update: Partial>) { + // TODO -- patch in decorators, etc? + // QN: should this be setGlobalMeta and take the place of finish configuring? + this.globalMeta = { ...this.globalMeta, ...update }; + } + + // QN: should these two live in a higher layer? perhaps w/ url handling? + // - maybe even in the story renderer? + setConfigurationError() {} + + // TODO + setStorySelection() {} + + loadCSFFileByStoryId(storyId: StoryId): CSFFile { + const path = this.storiesMetadata.storyIdToCSFFilePath(storyId); + + // TODO -- do we need to cache this? Probably not, as import is self-cached. + const exports = this.importer(path); + + // TODO -- we should probably cache this, obviously taking into account HMR + // -- then again, maybe not; maybe the caching happens in the `prepareStory` layer? + return processCSFFile(exports); + } + + renderStoryId(storyId: StoryId) { + const csfFile = this.loadCSFFileByStoryId(storyId); + + const storyMeta = csfFile[storyId]; + if (!storyMeta) { + throw new Error(`Didn't find '${storyId}' in CSF file, this is unexpected`); + } + const componentMeta = csfFile.metadata; + + const preparedStory = prepareStory(storyMeta, componentMeta, this.globalMeta); + + // TODO -- we need some kind of cache at this point. + + // QN: is this the time when args is set for this story (I think so?) + // -- although only if this is the first time it is rendered, I guess? + // QN: how do we currently distinguish first from subsequent render of a story? + + return preparedStory({ globals: this.globals.get() }); + } +} diff --git a/lib/client-api/src/new/StoriesMetadataStore.ts b/lib/client-api/src/new/StoriesMetadataStore.ts new file mode 100644 index 00000000000..57c3a9c352d --- /dev/null +++ b/lib/client-api/src/new/StoriesMetadataStore.ts @@ -0,0 +1,28 @@ +import { StoryId, ModuleImporter, Path, StoriesMetadata } from './types'; + +export class StoriesMetadataStore { + storiesMetadata: StoriesMetadata; + + constructor(storiesMetadataInput: StoriesMetadata) { + this.storiesMetadata = storiesMetadataInput; + + // TODO -- add a channel and watch it + } + + storyIdToCSFFilePath(storyId: StoryId): Path { + const storyMetadata = this.storiesMetadata.stories[storyId]; + if (!storyMetadata) { + throw new Error(`Didn't find '${storyId}' in story metadata (\`stories.json\`)`); + } + + const path = storyMetadata.parameters?.fileName; + if (!path) { + // TODO: Is this possible or are we guaranteeing this will exist now? + throw new Error( + `No \`parameters.fileName\` for '${storyId}' in story metadata (\`stories.json\`)` + ); + } + + return path; + } +} diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts new file mode 100644 index 00000000000..226f37dee5b --- /dev/null +++ b/lib/client-api/src/new/prepareStory.ts @@ -0,0 +1,46 @@ +import { StoryMeta, ComponentMeta, GlobalMeta, LegacyStoryFn, StoryContext } from './types'; + +// Combine all the metadata about a story (both direct and inherited from the component/global scope) +// into a "renderable" story function, with all decorators applied, parameters passed as context etc +// +// Note that this story function is *stateless* in the sense that it does not track args or globals +// Instead, it is expected these are tracked separately (if necessary) and are passed into each invocation. +export function prepareStory( + story: StoryMeta, + component: ComponentMeta, + globals: GlobalMeta +) { + // QN: to what extent should we defer some of this work until render time? + + // Combine parameters + // Combine decorators and get decorator combination fn + // Combine args + argTypes + // Combine loaders + + // Get render + play function + + // Create various functions + // getDecorated, + // getOriginal, + // applyLoaders, + // runPlayFunction, + // storyFn, + // unboundStoryFn, + + // Prepare initial story context + // - includes default args (enhanced) + const initialContext = { + // QN: who's job is it to emit these? + initialArgs: { + /* ... */ + }, + }; + const basicStoryFn = (inputContext: Partial = {}) => { + const context = { ...initialContext, ...inputContext }; + }; + + // QN: what should the return type here be? + return Object.assign(basicStoryFn, initialContext, { + // ? + }); +} diff --git a/lib/client-api/src/new/processCSFFile.ts b/lib/client-api/src/new/processCSFFile.ts new file mode 100644 index 00000000000..4561b0a40d2 --- /dev/null +++ b/lib/client-api/src/new/processCSFFile.ts @@ -0,0 +1,11 @@ +import { ModuleExports, CSFFile } from './types'; + +// Given the raw exports of a CSF file, check and normalize it. +export function processCSFFile( + exports: ModuleExports +): CSFFile { + // TODO check + // TODO call normalize CSF + + return exports as CSFFile; +} diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts new file mode 100644 index 00000000000..c69bf5ef515 --- /dev/null +++ b/lib/client-api/src/new/types.ts @@ -0,0 +1,69 @@ +import { + Parameters, + DecoratorFunction, + LoaderFunction, + Args, + ArgTypes, + ArgsStoryFn, + StoryId, + StoryKind, + StoryName, +} from '@storybook/addons'; + +export type { StoryId }; + +export type ModuleExports = Record; + +export type Meta = { + decorators?: DecoratorFunction[]; + parameters?: Parameters; + args?: Args; + argTypes?: ArgTypes; + loaders?: LoaderFunction[]; +}; + +export type GlobalMeta = Meta; + +export type ComponentTitle = StoryKind; +export type ComponentMeta = Meta & { + title: ComponentTitle; + + // component, + // subcomponents, +}; + +export type StoryMeta = Meta & { + render: ArgsStoryFn; +}; + +export type CSFFile = { + metadata: ComponentMeta; +} & Record>; + +export type Path = string; + +// TODO -- these types probably need to live in a common spot w/ where stories.json is generated +export interface StoriesMetadataStory { + id: StoryId; + name: StoryName; + parameters: { fileName: Path }; +} + +export interface StoriesMetadata { + v: number; + stories: Record; +} + +export type ModuleImporter = (path: Path) => ModuleExports; + +export type StoryContext = { + id: StoryId; + parameters: Parameters; + args: Args; + argTypes: ArgTypes; + globals: Args; +}; + +export type Channel = any; + +export type Globals = Args; From 4ddc359278e882c6eaa10884f58d1ca7c2638478 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 27 Jul 2021 21:59:55 +1000 Subject: [PATCH 002/285] Finished first roughing out --- lib/client-api/src/new/ArgsStore.ts | 30 +- lib/client-api/src/new/GlobalsStore.ts | 50 ++- lib/client-api/src/new/PreviewStore.ts | 81 ----- lib/client-api/src/new/StoriesListStore.ts | 63 ++++ .../src/new/StoriesMetadataStore.ts | 28 -- lib/client-api/src/new/StoryStore.ts | 89 ++++++ lib/client-api/src/new/UrlStore.ts | 21 ++ lib/client-api/src/new/WebPreview.ts | 290 ++++++++++++++++++ lib/client-api/src/new/WebView.tsx | 140 +++++++++ lib/client-api/src/new/prepareStory.ts | 222 +++++++++++--- lib/client-api/src/new/processCSFFile.ts | 82 ++++- lib/client-api/src/new/types.ts | 127 ++++++-- 12 files changed, 1027 insertions(+), 196 deletions(-) delete mode 100644 lib/client-api/src/new/PreviewStore.ts create mode 100644 lib/client-api/src/new/StoriesListStore.ts delete mode 100644 lib/client-api/src/new/StoriesMetadataStore.ts create mode 100644 lib/client-api/src/new/StoryStore.ts create mode 100644 lib/client-api/src/new/UrlStore.ts create mode 100644 lib/client-api/src/new/WebPreview.ts create mode 100644 lib/client-api/src/new/WebView.tsx diff --git a/lib/client-api/src/new/ArgsStore.ts b/lib/client-api/src/new/ArgsStore.ts index f2f6093cd95..fef7e8e4a91 100644 --- a/lib/client-api/src/new/ArgsStore.ts +++ b/lib/client-api/src/new/ArgsStore.ts @@ -1,25 +1,25 @@ -import { Channel, StoryId, Args } from './types'; +import { StoryId, Args, SelectionSpecifier } from './types'; export class ArgsStore { - argsByStoryId: Record; + argsByStoryId: Record = {}; - constructor({ channel }: { channel: Channel }) { - // TODO -- watch + emit on channel - - // QN -- how do args get initialized? - // -- we need pass args when a story is first rendered - this.argsByStoryId = {}; - } - - argsForStoryId(storyId: StoryId) { - if (!storyId in this.argsForStoryId) { - throw new Error(`No args know for ${storyId} -- has it been rendered yet?`); + get(storyId: StoryId) { + if (!(storyId in this.argsByStoryId)) { + throw new Error(`No args known for ${storyId} -- has it been rendered yet?`); } return this.argsByStoryId[storyId]; } - updateArgsByStoryId() { - // TODO: set, emit + set(storyId: StoryId, args: Args) { + this.argsByStoryId[storyId] = args; + } + + update(storyId: StoryId, argsUpdate: Partial) { + if (!(storyId in this.argsByStoryId)) { + throw new Error(`No args known for ${storyId} -- has it been rendered yet?`); + } + + this.argsByStoryId[storyId] = { ...this.argsByStoryId[storyId], ...argsUpdate }; } } diff --git a/lib/client-api/src/new/GlobalsStore.ts b/lib/client-api/src/new/GlobalsStore.ts index c260fd270a2..ea2de849227 100644 --- a/lib/client-api/src/new/GlobalsStore.ts +++ b/lib/client-api/src/new/GlobalsStore.ts @@ -1,21 +1,53 @@ -import { Channel, Globals } from './types'; +import { Globals, GlobalTypes } from './types'; +import { combineParameters } from '../parameters'; export class GlobalsStore { - globals: Globals; + allowedGlobalNames: Set; - constructor({ channel }: { channel: Channel }) { - // TODO -- watch + emit on channel + initialGlobals: Globals; - // QN -- how do globals get initialized? - // -- we need to get passed metadata after preview entries are initialized. - this.globals = {}; + globals: Globals = {}; + + // NOTE: globals are initialized every time the preview entries are loaded + // This happens both initially when the SB first loads, and also on HMR + constructor({ globals, globalTypes }: { globals: Globals; globalTypes: GlobalTypes }) { + this.allowedGlobalNames = new Set([...Object.keys(globals), ...Object.keys(globalTypes)]); + + const defaultGlobals = Object.entries(globalTypes).reduce((acc, [arg, { defaultValue }]) => { + if (defaultValue) acc[arg] = defaultValue; + return acc; + }, {} as Globals); + + this.initialGlobals = { ...defaultGlobals, ...globals }; + + // To deal with HMR & persistence, we consider the previous value of global args, and: + // 1. Remove any keys that are not in the new parameter + // 2. Preference any keys that were already set + // 3. Use any new keys from the new parameter + this.globals = Object.entries(this.globals).reduce( + (acc, [key, previousValue]) => { + if (this.allowedGlobalNames.has(key)) acc[key] = previousValue; + + return acc; + }, + { ...this.initialGlobals } + ); + } + + updateFromCache(cachedGlobals: Globals) { + const allowedUrlGlobals = Object.entries(cachedGlobals).reduce((acc, [key, value]) => { + if (this.allowedGlobalNames.has(key)) acc[key] = value; + return acc; + }, {} as Globals); + // TODO(Gert) -- why do we use combineParameters here? + this.globals = combineParameters(this.globals, allowedUrlGlobals); } get() { return this.globals; } - update() { - // TODO: set, emit + update(newGlobals: Globals) { + this.globals = { ...this.globals, ...newGlobals }; } } diff --git a/lib/client-api/src/new/PreviewStore.ts b/lib/client-api/src/new/PreviewStore.ts deleted file mode 100644 index 3cc66a5206e..00000000000 --- a/lib/client-api/src/new/PreviewStore.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { StoriesMetadataStore } from './StoriesMetadataStore'; -import { ArgsStore } from './ArgsStore'; -import { GlobalsStore } from './GlobalsStore'; -import { processCSFFile } from './processCSFFile'; -import { prepareStory } from './prepareStory'; -import { CSFFile, StoryId, Channel, StoriesMetadata, ModuleImporter, GlobalMeta } from './types'; - -// TODO: -// - figure out how the channel is wired up? Do we pass it into every substore? - -export class PreviewStore { - storiesMetadata: StoriesMetadataStore; - - importer: ModuleImporter; - - globalMeta: GlobalMeta; - - globals: GlobalsStore; - - args: ArgsStore; - - constructor({ - channel, - storiesMetadata, - importerInput, - }: { - channel: Channel; - storiesMetadata: StoriesMetadata; - importerInput: ModuleImporter; - }) { - this.storiesMetadata = new StoriesMetadataStore(storiesMetadata); - this.importer = importerInput; - this.globalMeta = {}; - this.globals = new GlobalsStore({ channel }); - this.args = new ArgsStore({ channel }); - } - - updateGlobalMeta(update: Partial>) { - // TODO -- patch in decorators, etc? - // QN: should this be setGlobalMeta and take the place of finish configuring? - this.globalMeta = { ...this.globalMeta, ...update }; - } - - // QN: should these two live in a higher layer? perhaps w/ url handling? - // - maybe even in the story renderer? - setConfigurationError() {} - - // TODO - setStorySelection() {} - - loadCSFFileByStoryId(storyId: StoryId): CSFFile { - const path = this.storiesMetadata.storyIdToCSFFilePath(storyId); - - // TODO -- do we need to cache this? Probably not, as import is self-cached. - const exports = this.importer(path); - - // TODO -- we should probably cache this, obviously taking into account HMR - // -- then again, maybe not; maybe the caching happens in the `prepareStory` layer? - return processCSFFile(exports); - } - - renderStoryId(storyId: StoryId) { - const csfFile = this.loadCSFFileByStoryId(storyId); - - const storyMeta = csfFile[storyId]; - if (!storyMeta) { - throw new Error(`Didn't find '${storyId}' in CSF file, this is unexpected`); - } - const componentMeta = csfFile.metadata; - - const preparedStory = prepareStory(storyMeta, componentMeta, this.globalMeta); - - // TODO -- we need some kind of cache at this point. - - // QN: is this the time when args is set for this story (I think so?) - // -- although only if this is the first time it is rendered, I guess? - // QN: how do we currently distinguish first from subsequent render of a story? - - return preparedStory({ globals: this.globals.get() }); - } -} diff --git a/lib/client-api/src/new/StoriesListStore.ts b/lib/client-api/src/new/StoriesListStore.ts new file mode 100644 index 00000000000..e467f113d82 --- /dev/null +++ b/lib/client-api/src/new/StoriesListStore.ts @@ -0,0 +1,63 @@ +// import global from 'global'; + +import { StoryId, StorySpecifier, Path, StoriesList } from './types'; + +// TODO -- can we use fetch? how to do this in a portable way? +// const { fetch } = global; + +export class StoriesListStore { + storiesList: StoriesList; + + // TODO -- add a node-channel and watch it + // constructor() {} + + async initialize() { + return this.fetchStoriesList(); + } + + async fetchStoriesList() { + // TODO -- what is the URL here, how can we get this in a portable way? + // await fetch('/stories.json') + this.storiesList = { v: 1, stories: {} }; + } + + storyIdFromSpecifier(specifier: StorySpecifier) { + const storyIds = Object.keys(this.storiesList.stories); + if (specifier === '*') { + // '*' means select the first story. If there is none, we have no selection. + return storyIds[0]; + } + + if (typeof specifier === 'string') { + // Find the story with the exact id that matches the specifier (see #11571) + if (storyIds.indexOf(specifier) >= 0) { + return specifier; + } + // Fallback to the first story that starts with the specifier + return storyIds.find((storyId) => storyId.startsWith(specifier)); + } + + // Try and find a story matching the name/kind, setting no selection if they don't exist. + const { name, kind } = specifier; + return Object.values(this.storiesList.stories).find( + (story) => story.name === name && story.kind === kind + )?.id; + } + + storyIdToCSFFilePath(storyId: StoryId): Path { + const storyMetadata = this.storiesList.stories[storyId]; + if (!storyMetadata) { + throw new Error(`Didn't find '${storyId}' in story metadata (\`stories.json\`)`); + } + + const path = storyMetadata.parameters?.fileName; + if (!path) { + // TODO: Is this possible or are we guaranteeing this will exist now? + throw new Error( + `No \`parameters.fileName\` for '${storyId}' in story metadata (\`stories.json\`)` + ); + } + + return path; + } +} diff --git a/lib/client-api/src/new/StoriesMetadataStore.ts b/lib/client-api/src/new/StoriesMetadataStore.ts deleted file mode 100644 index 57c3a9c352d..00000000000 --- a/lib/client-api/src/new/StoriesMetadataStore.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { StoryId, ModuleImporter, Path, StoriesMetadata } from './types'; - -export class StoriesMetadataStore { - storiesMetadata: StoriesMetadata; - - constructor(storiesMetadataInput: StoriesMetadata) { - this.storiesMetadata = storiesMetadataInput; - - // TODO -- add a channel and watch it - } - - storyIdToCSFFilePath(storyId: StoryId): Path { - const storyMetadata = this.storiesMetadata.stories[storyId]; - if (!storyMetadata) { - throw new Error(`Didn't find '${storyId}' in story metadata (\`stories.json\`)`); - } - - const path = storyMetadata.parameters?.fileName; - if (!path) { - // TODO: Is this possible or are we guaranteeing this will exist now? - throw new Error( - `No \`parameters.fileName\` for '${storyId}' in story metadata (\`stories.json\`)` - ); - } - - return path; - } -} diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts new file mode 100644 index 00000000000..65f1e194e1f --- /dev/null +++ b/lib/client-api/src/new/StoryStore.ts @@ -0,0 +1,89 @@ +import { StoriesListStore } from './StoriesListStore'; +import { ArgsStore } from './ArgsStore'; +import { GlobalsStore } from './GlobalsStore'; +import { processCSFFile } from './processCSFFile'; +import { prepareStory } from './prepareStory'; +import { Args, CSFFile, StoryId, ModuleImportFn, GlobalMeta, Story, StoryContext } from './types'; +import { combineArgs, mapArgsToTypes } from '../args'; + +export class StoryStore { + storiesList: StoriesListStore; + + importFn: ModuleImportFn; + + globalMeta: GlobalMeta; + + globals: GlobalsStore; + + args: ArgsStore; + + constructor({ + importFn, + globalMeta, + }: { + importFn: ModuleImportFn; + globalMeta: GlobalMeta; + }) { + this.storiesList = new StoriesListStore(); + this.importFn = importFn; + this.globalMeta = globalMeta; + + const { globals, globalTypes } = globalMeta; + this.globals = new GlobalsStore({ globals, globalTypes }); + this.args = new ArgsStore(); + } + + async initialize() { + await this.storiesList.initialize(); + } + + loadCSFFileByStoryId(storyId: StoryId): CSFFile { + const path = this.storiesList.storyIdToCSFFilePath(storyId); + const moduleExports = this.importFn(path); + return processCSFFile({ moduleExports, path }); + } + + getStory({ + storyId, + cachedArgs, + }: { + storyId: StoryId; + cachedArgs?: Args; + }): Story { + const csfFile = this.loadCSFFileByStoryId(storyId); + + const storyMeta = csfFile.stories[storyId]; + if (!storyMeta) { + throw new Error(`Didn't find '${storyId}' in CSF file, this is unexpected`); + } + const componentMeta = csfFile.meta; + + const story = prepareStory(storyMeta, componentMeta, this.globalMeta); + + // TODO -- we need some kind of cache at this point. + + let { initialArgs } = story; + if (cachedArgs) { + initialArgs = combineArgs(initialArgs, mapArgsToTypes(cachedArgs, story.argTypes)); + } + this.args.set(storyId, initialArgs); + + // QN: how do we currently distinguish first from subsequent render of a story? + // -- ANS: we have a concept of "unmounting" a story + // -- second answer: the StoryRenderer currently knows + + // TODO + // If we are setting args once when the story is first rendered, we need to + // some how do it at the point of rendering + + return story; + } + + getStoryContext(story: Story): StoryContext { + return { + ...story, + args: this.args.get(story.id), + globals: this.globals.get(), + }; + } +} diff --git a/lib/client-api/src/new/UrlStore.ts b/lib/client-api/src/new/UrlStore.ts new file mode 100644 index 00000000000..2e056f23339 --- /dev/null +++ b/lib/client-api/src/new/UrlStore.ts @@ -0,0 +1,21 @@ +import Events from '@storybook/core-events'; + +import { Channel, SelectionSpecifier, Selection } from './types'; +// TODO -- this import is wrong +import { getSelectionSpecifierFromPath, setPath } from '../../../core-client/src/preview/url'; + +export class UrlStore { + selectionSpecifier: SelectionSpecifier; + + selection: Selection; + + constructor() { + this.selectionSpecifier = getSelectionSpecifierFromPath(); + } + + setSelection(selection: Selection) { + this.selection = selection; + + setPath(this.selection); + } +} diff --git a/lib/client-api/src/new/WebPreview.ts b/lib/client-api/src/new/WebPreview.ts new file mode 100644 index 00000000000..97d6554c550 --- /dev/null +++ b/lib/client-api/src/new/WebPreview.ts @@ -0,0 +1,290 @@ +import Events from '@storybook/core-events'; +import { logger } from '@storybook/client-logger'; +import { global } from 'global'; +import { addons, Channel } from '@storybook/addons'; +import createChannel from '@storybook/channel-postmessage'; + +import { + WebGlobalMeta, + ModuleImportFn, + Selection, + Story, + RenderContextWithoutStoryContext, + Globals, + StoryId, + Args, +} from './types'; +import { StoryStore } from './StoryStore'; +import { UrlStore } from './UrlStore'; +import { WebView } from './WebView'; +import { StorySpecifier } from '../types'; + +const { navigator, window: globalWindow } = global; + +// TODO -- what's up with this code? Is it for HMR? Can we be smarter? +function getOrCreateChannel() { + try { + return addons.getChannel(); + } catch (err) { + const channel = createChannel({ page: 'preview' }); + addons.setChannel(channel); + return channel; + } +} + +function focusInInput(event: Event) { + const target = event.target as Element; + return /input|textarea/i.test(target.tagName) || target.getAttribute('contenteditable') !== null; +} + +export class WebPreview { + channel: Channel; + + urlStore: UrlStore; + + storyStore: StoryStore; + + view: WebView; + + renderToDOM: WebGlobalMeta['renderToDOM']; + + previousSelection: Selection; + + constructor({ + getGlobalMeta, + importFn, + }: { + getGlobalMeta: () => WebGlobalMeta; + importFn: ModuleImportFn; + }) { + this.channel = getOrCreateChannel(); + + let globalMeta; + try { + globalMeta = getGlobalMeta(); + this.renderToDOM = globalMeta.renderToDOM; + } catch (err) { + // This is an error extracting the globalMeta (i.e. evaluating the previewEntries) and + // needs to be show to the user as a simple error + this.renderPreviewEntryError(err); + return; + } + + this.urlStore = new UrlStore(); + this.storyStore = new StoryStore({ + selectionSpecifier: this.urlStore.selectionSpecifier, + importFn, + globalMeta, + }); + this.view = new WebView(); + } + + async initialize() { + await this.storyStore.initialize(); + this.setupListeners(); + await this.selectSpecifiedStory(); + } + + setupListeners() { + globalWindow.onkeydown = this.onKeydown.bind(this); + + this.channel.on(Events.SET_CURRENT_STORY, this.onSetCurrentStory.bind(this)); + this.channel.on(Events.UPDATE_GLOBALS, this.onUpdateGlobals.bind(this)); + this.channel.on(Events.UPDATE_STORY_ARGS, this.onUpdateArgs.bind(this)); + this.channel.on(Events.RESET_STORY_ARGS, this.onResetArgs.bind(this)); + } + + // Use the selection specifier to choose a story + async selectSpecifiedStory() { + const { storySpecifier, viewMode, globals, args } = this.urlStore.selectionSpecifier; + const storyId = this.storyStore.storiesList.storyIdFromSpecifier(storySpecifier); + + if (!storyId) { + this.renderMissingStory(storySpecifier); + return; + } + + this.urlStore.setSelection({ storyId, viewMode }); + + if (globals) { + this.storyStore.globals.updateFromCache(globals); + } + + await this.renderSelection({ forceRender: false, cachedArgs: args }); + } + + onKeydown(event: KeyboardEvent) { + if (!focusInInput(event)) { + // We have to pick off the keys of the event that we need on the other side + const { altKey, ctrlKey, metaKey, shiftKey, key, code, keyCode } = event; + this.channel.emit(Events.PREVIEW_KEYDOWN, { + event: { altKey, ctrlKey, metaKey, shiftKey, key, code, keyCode }, + }); + } + } + + onSetCurrentStory(selection: Selection) { + this.urlStore.setSelection(selection); + this.channel.emit(Events.CURRENT_STORY_WAS_SET, this.urlStore.selection); + this.renderSelection({ forceRender: false }); + } + + onUpdateGlobals({ globals }: { globals: Globals }) { + this.storyStore.globals.update(globals); + + this.channel.emit(Events.GLOBALS_UPDATED, { + globals, + initialGlobals: this.storyStore.globals.initialGlobals, + }); + + this.renderSelection({ forceRender: true }); + } + + onUpdateArgs({ storyId, updatedArgs }: { storyId: StoryId; updatedArgs: Args }) { + this.storyStore.args.update(storyId, updatedArgs); + this.channel.emit(Events.STORY_ARGS_UPDATED, { + storyId, + args: this.storyStore.args.get(storyId), + }); + this.renderSelection({ forceRender: true }); + } + + async onResetArgs({ storyId, argNames }: { storyId: string; argNames?: string[] }) { + const { initialArgs } = await this.storyStore.getStory(storyId); + + // TODO ensure this technique works with falsey/null initialArgs + const updatedArgs = argNames.reduce((acc, argName) => { + acc[argName] = initialArgs[argName]; + return acc; + }, {} as Partial); + + this.onUpdateArgs({ storyId, updatedArgs }); + } + + // We can either have: + // - a story selected in "story" viewMode, + // in which case we render it to the root element, OR + // - a story selected in "docs" viewMode, + // in which case we render the docsPage for that story + async renderSelection({ forceRender, cachedArgs }: { forceRender: boolean; cachedArgs: Args }) { + if (!this.urlStore.selection) { + throw new Error('Cannot render story as no selection was made'); + } + + const { selection } = this.urlStore; + + const story = await this.storyStore.getStory({ storyId: selection.storyId, cachedArgs }); + + // We need to: + + const storyChanged = this.previousSelection?.storyId !== selection.storyId; + const viewModeChanged = this.previousSelection?.viewMode !== selection.viewMode; + + // TODO -- think about this. Do we just compare previousStory === story? + const implementationChanged = false; + + if (this.previousSelection?.viewMode === 'story' && (storyChanged || viewModeChanged)) { + const previousStory = await this.storyStore.getStory({ + storyId: this.previousSelection.storyId, + }); + this.removeStory({ story: previousStory }); + } + + // Don't re-render the story if nothing has changed to justify it + if (!forceRender && !storyChanged && !implementationChanged && !viewModeChanged) { + // TODO -- the api of this changed, but the previous API made no sense. Did we use it? + this.channel.emit(Events.STORY_UNCHANGED, selection.storyId); + return; + } + + // If we are rendering something new (as opposed to re-rendering the same or first story), emit + if (this.previousSelection && (storyChanged || viewModeChanged)) { + this.channel.emit(Events.STORY_CHANGED, selection.storyId); + } + + // Record the previous selection *before* awaiting the rendering, in cases things change before it is done. + this.previousSelection = selection; + + if (selection.viewMode === 'docs') { + await this.view.renderDocs(story); + // TODO -- changed the API, previous it had a kind -- did we use it? + this.channel.emit(Events.DOCS_RENDERED, selection.storyId); + return; + } + + const element = this.view.prepareForStory(story, forceRender); + + const { id, kind, name } = story; + const renderContext: RenderContextWithoutStoryContext = { + id, + kind, + name, + forceRender, + showMain: () => this.view.showMain(), + showError: ({ title, description }: { title: string; description: string }) => + this.renderError({ title, description }), + showException: (err: Error) => this.renderException(err), + }; + + await this.renderStoryToElement({ story, renderContext, element }); + } + + // We want this function to be called directly by `renderSelection` above, + // but also by the `` docs component + async renderStoryToElement({ + story, + renderContext, + element, + }: { + story: Story; + renderContext: RenderContextWithoutStoryContext; + element: Element; + }) { + const { id, applyLoaders, storyFn, runPlayFunction } = story; + + const storyContext = this.storyStore.getStoryContext(story); + + const loadedContext = await applyLoaders(storyContext); + + await this.renderToDOM({ ...loadedContext, ...renderContext, storyFn }, element); + + // TODO -- discuss why not forceRender? and do features better + if (global.FEATURES.previewCsfV3 && !renderContext.forceRender) { + await runPlayFunction(); + } + this.channel.emit(Events.STORY_RENDERED, id); + } + + removeStory({ story }: { story: Story }) { + story.cleanup(); + } + + renderPreviewEntryError(err: Error) { + this.view.showErrorDisplay(err); + // TODO -- should we emit here? + } + + renderMissingStory(storySpecifier: StorySpecifier) { + this.view.showNoPreview(); + this.channel.emit(Events.STORY_MISSING, storySpecifier); + } + + // renderException is used if we fail to render the story and it is uncaught by the app layer + renderException(err: Error) { + this.view.showErrorDisplay(err); + this.channel.emit(Events.STORY_THREW_EXCEPTION, err); + + // Log the stack to the console. So, user could check the source code. + logger.error(err); + } + + // renderError is used by the various app layers to inform the user they have done something + // wrong -- for instance returned the wrong thing from a story + renderError({ title, description }: { title: string; description: string }) { + this.channel.emit(Events.STORY_ERRORED, { title, description }); + this.view.showErrorDisplay({ + message: title, + stack: description, + }); + } +} diff --git a/lib/client-api/src/new/WebView.tsx b/lib/client-api/src/new/WebView.tsx new file mode 100644 index 00000000000..bccbf0f3e3c --- /dev/null +++ b/lib/client-api/src/new/WebView.tsx @@ -0,0 +1,140 @@ +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; +import global from 'global'; +import { logger } from '@storybook/client-logger'; +import AnsiToHtml from 'ansi-to-html'; +import dedent from 'ts-dedent'; + +import { Story, ViewMode } from './types'; +import { NoDocs } from './NoDocs'; + +const { document, FEATURES = {} } = global; + +const layoutClassMap = { + centered: 'sb-main-centered', + fullscreen: 'sb-main-fullscreen', + padded: 'sb-main-padded', +} as const; +type Layout = keyof typeof layoutClassMap | 'none'; + +const classes = { + MAIN: 'sb-show-main', + NOPREVIEW: 'sb-show-nopreview', + ERROR: 'sb-show-errordisplay', +}; + +const ansiConverter = new AnsiToHtml({ + escapeXML: true, +}); + +export class WebView { + currentViewMode: ViewMode; + + currentLayoutClass?: typeof layoutClassMap[keyof typeof layoutClassMap] | null; + + // Get ready to render a story, returning the element to render to + prepareForStory(story: Story, forceRender: boolean) { + if (this.currentViewMode === 'docs') { + ReactDOM.unmountComponentAtNode(document.getElementById('docs-root')); + } + + this.applyLayout(story.parameters.layout); + + if (!forceRender) { + document.documentElement.scrollTop = 0; + document.documentElement.scrollLeft = 0; + } + + this.currentViewMode = 'story'; + return document.getElementById('root'); + } + + async renderDocs(story: Story) { + this.showMain(); + this.showDocs(); + this.applyLayout('fullscreen'); + + const { docs } = story.parameters; + if (docs?.page && !docs?.container) { + throw new Error('No `docs.container` set, did you run `addon-docs/preset`?'); + } + + const DocsContainer: Component = + docs.container || (({ children }: { children: Element }) => <>{children}); + const Page: Component = docs.page || NoDocs; + + // TODO -- what is docs context? pass in here? + // Docs context includes the storyStore. Probably it would be better if it didn't but that can be fixed in a later refactor + + await new Promise((resolve) => { + ReactDOM.render( + + + , + document.getElementById('docs-root'), + resolve + ); + }); + + this.currentViewMode = 'docs'; + } + + applyLayout(layout: Layout = 'padded') { + if (layout === 'none') { + document.body.classList.remove(this.currentLayoutClass); + this.currentLayoutClass = null; + return; + } + + this.checkIfLayoutExists(layout); + + const layoutClass = layoutClassMap[layout]; + + document.body.classList.remove(this.currentLayoutClass); + document.body.classList.add(layoutClass); + this.currentLayoutClass = layoutClass; + } + + checkIfLayoutExists(layout: keyof typeof layoutClassMap) { + if (!layoutClassMap[layout]) { + logger.warn( + dedent`The desired layout: ${layout} is not a valid option. + The possible options are: ${Object.keys(layoutClassMap).join(', ')}, none.` + ); + } + } + + showErrorDisplay({ message = '', stack = '' }) { + document.getElementById('error-message').innerHTML = ansiConverter.toHtml(message); + document.getElementById('error-stack').innerHTML = ansiConverter.toHtml(stack); + + document.body.classList.remove(classes.MAIN); + document.body.classList.remove(classes.NOPREVIEW); + + document.body.classList.add(classes.ERROR); + } + + showNoPreview() { + document.body.classList.remove(classes.MAIN); + document.body.classList.remove(classes.ERROR); + + document.body.classList.add(classes.NOPREVIEW); + } + + showMain() { + document.body.classList.remove(classes.NOPREVIEW); + document.body.classList.remove(classes.ERROR); + + document.body.classList.add(classes.MAIN); + } + + showDocs() { + document.getElementById('root').setAttribute('hidden', 'true'); + document.getElementById('docs-root').removeAttribute('hidden'); + } + + showStory() { + document.getElementById('docs-root').setAttribute('hidden', 'true'); + document.getElementById('root').removeAttribute('hidden'); + } +} diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts index 226f37dee5b..6ab46abe69d 100644 --- a/lib/client-api/src/new/prepareStory.ts +++ b/lib/client-api/src/new/prepareStory.ts @@ -1,4 +1,33 @@ -import { StoryMeta, ComponentMeta, GlobalMeta, LegacyStoryFn, StoryContext } from './types'; +import dedent from 'ts-dedent'; +import deprecate from 'util-deprecate'; + +import { + Parameters, + StoryMeta, + ComponentMeta, + GlobalMeta, + LegacyStoryFn, + ArgsStoryFn, + StoryContext, + Story, + Args, + ArgTypes, + ArgsEnhancer, + ArgTypesEnhancer, +} from './types'; + +import { combineParameters } from '../parameters'; +import { applyHooks, HooksContext } from '../hooks'; +import { validateOptions } from '../args'; +import { defaultDecorateStory } from '../decorators'; + +const argTypeDefaultValueWarning = deprecate( + () => {}, + dedent` + \`argType.defaultValue\` is deprecated and will be removed in Storybook 7.0. + + https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-argtype-defaultValue` +); // Combine all the metadata about a story (both direct and inherited from the component/global scope) // into a "renderable" story function, with all decorators applied, parameters passed as context etc @@ -6,41 +35,164 @@ import { StoryMeta, ComponentMeta, GlobalMeta, LegacyStoryFn, StoryContext } fro // Note that this story function is *stateless* in the sense that it does not track args or globals // Instead, it is expected these are tracked separately (if necessary) and are passed into each invocation. export function prepareStory( - story: StoryMeta, - component: ComponentMeta, - globals: GlobalMeta -) { - // QN: to what extent should we defer some of this work until render time? - - // Combine parameters - // Combine decorators and get decorator combination fn - // Combine args + argTypes - // Combine loaders - - // Get render + play function - - // Create various functions - // getDecorated, - // getOriginal, - // applyLoaders, - // runPlayFunction, - // storyFn, - // unboundStoryFn, - - // Prepare initial story context - // - includes default args (enhanced) - const initialContext = { - // QN: who's job is it to emit these? - initialArgs: { - /* ... */ - }, + storyMeta: StoryMeta, + componentMeta: ComponentMeta, + globalMeta: GlobalMeta +): Story { + // NOTE: in the current implementation we are doing everything once, up front, rather than doing + // anything at render time. The assumption is that as we don't load all the stories at once, this + // will have a limited cost. If this proves misguided, we can refactor it. + + const { id, name } = storyMeta; + const { title } = componentMeta; + + const parameters: Parameters = combineParameters( + globalMeta.parameters, + componentMeta.parameters, + storyMeta.parameters + ); + + const decorators = [ + ...storyMeta.decorators, + ...componentMeta.decorators, + ...globalMeta.decorators, + ]; + + // Currently it is only possible to set these globally + const { + applyDecorators = defaultDecorateStory, + argTypesEnhancers = [], + argsEnhancers = [], + } = globalMeta; + + const loaders = [...globalMeta.loaders, ...componentMeta.loaders, ...storyMeta.loaders]; + + const hooks = new HooksContext(); + const cleanup = () => hooks.clean(); + + const render = storyMeta.render || componentMeta.render || globalMeta.render; + + // TODO -- generalize combineParameters + const passedArgTypes: ArgTypes = combineParameters( + globalMeta.argTypes, + componentMeta.argTypes, + storyMeta.argTypes + ) as ArgTypes; + + const { passArgsFirst = true } = parameters; + // eslint-disable-next-line no-underscore-dangle + parameters.__isArgsStory = passArgsFirst && render.length > 0; + + const contextForEnhancers: StoryContext = { + id, + name, + kind: title, // TODO ? + parameters, + argTypes: passedArgTypes, + hooks, + // TODO -- does it make sense for this to include args? globals? + args: {}, + globals: {}, }; - const basicStoryFn = (inputContext: Partial = {}) => { - const context = { ...initialContext, ...inputContext }; + + // BACKCOMPAT: do argTypeEnhancers expect to find existing argTypes on enhancers? + const argTypes = argTypesEnhancers.reduce( + (accumulatedArgTypes, enhancer) => ({ + ...accumulatedArgTypes, + ...enhancer({ + ...contextForEnhancers, + argTypes: accumulatedArgTypes, + }), + }), + {} as ArgTypes + ); + + // TODO -- are we still doing this? + // parameters.argTypes = argTypes; + + // Pull out args[X] || argTypes[X].defaultValue into initialArgs + // TODO -- generalize combineParameters + const passedArgs: Args = combineParameters( + globalMeta.args, + componentMeta.args, + storyMeta.args + ) as Args; + + const defaultArgs: Args = Object.entries( + argTypes as Record + ).reduce((acc, [arg, { defaultValue }]) => { + if (typeof defaultValue !== 'undefined') { + acc[arg] = defaultValue; + } + return acc; + }, {} as Args); + if (Object.keys(defaultArgs).length > 0) { + argTypeDefaultValueWarning(); + } + + const initialArgsBeforeEnhancers = { ...defaultArgs, ...passedArgs }; + const initialArgs = argsEnhancers.reduce( + (accumulatedArgs: Args, enhancer) => ({ + ...accumulatedArgs, + ...enhancer({ + ...contextForEnhancers, + args: accumulatedArgs, + }), + }), + initialArgsBeforeEnhancers + ); + + const applyLoaders = async (context: StoryContext) => { + const loadResults = await Promise.all(loaders.map((loader) => loader(context))); + const loaded = Object.assign({}, ...loadResults); + return { ...context, loaded }; + }; + + const undecoratedStoryFn: LegacyStoryFn = (context: StoryContext) => { + const mappedArgs = Object.entries(context.args).reduce((acc, [key, val]) => { + const { mapping } = context.argTypes[key] || {}; + acc[key] = mapping && val in mapping ? mapping[val] : val; + return acc; + }, {} as Args); + + const validatedContext = { + ...context, + args: validateOptions(mappedArgs, context.argTypes), + }; + return context.parameters.passArgsFirst + ? (render as ArgsStoryFn)(validatedContext.args, validatedContext) + : (render as LegacyStoryFn)(validatedContext); + }; + // TODO -- should this be unboundStoryFn? + // TODO -- fix types + const storyFn = applyHooks(applyDecorators)(undecoratedStoryFn, decorators as any); + + const runPlayFunction = async () => { + if (parameters.play) { + return parameters.play(); + } + return undefined; }; - // QN: what should the return type here be? - return Object.assign(basicStoryFn, initialContext, { - // ? - }); + return { + id, + name, + kind: title, // TODO ? + parameters, + initialArgs, + argTypes, + hooks, + applyLoaders, + storyFn, + runPlayFunction, + cleanup, + }; } + +// function preparedStoryToFunction(preparedStory) { +// return () => { +// const result = preparedStory.unboundStoryFn(preparedStory.initialContext) +// preparedStory.cleanup(); + +// return result; +// } diff --git a/lib/client-api/src/new/processCSFFile.ts b/lib/client-api/src/new/processCSFFile.ts index 4561b0a40d2..f7bec508f97 100644 --- a/lib/client-api/src/new/processCSFFile.ts +++ b/lib/client-api/src/new/processCSFFile.ts @@ -1,11 +1,79 @@ -import { ModuleExports, CSFFile } from './types'; +import { isExportStory } from '@storybook/csf'; +import { logger } from '@storybook/client-logger'; + +import { ModuleExports, CSFFile, ComponentMeta, StoryMeta, Path, Parameters } from './types'; +import { autoTitle } from './autoTitle'; // TODO +import { normalizeStory } from './normalizeStory'; // TODO + +const checkGlobals = (parameters: Parameters) => { + const { globals, globalTypes } = parameters; + if (globals || globalTypes) { + logger.error( + 'Global args/argTypes can only be set globally', + JSON.stringify({ + globals, + globalTypes, + }) + ); + } +}; + +const checkStorySort = (parameters: Parameters) => { + const { options } = parameters; + if (options?.storySort) logger.error('The storySort option parameter can only be set globally'); +}; + +const checkDisallowedParameters = (parameters: Parameters) => { + if (!parameters) { + return; + } + checkGlobals(parameters); + checkStorySort(parameters); +}; // Given the raw exports of a CSF file, check and normalize it. -export function processCSFFile( - exports: ModuleExports -): CSFFile { - // TODO check - // TODO call normalize CSF +export function processCSFFile({ + moduleExports, + path, +}: { + moduleExports: ModuleExports; + path: Path; +}): CSFFile { + const { default: defaultExport, __namedExportsOrder, ...namedExports } = moduleExports; + let exports = namedExports; + + const title = autoTitle(defaultExport, path); + if (!title) { + throw new Error( + `Unexpected default export without title: ${JSON.stringify(moduleExports.default)}` + ); + } + + const meta: ComponentMeta = { ...defaultExport, title }; + checkDisallowedParameters(meta.parameters); + + // prefer a user/loader provided `__namedExportsOrder` array if supplied + // we do this as es module exports are always ordered alphabetically + // see https://github.com/storybookjs/storybook/issues/9136 + if (Array.isArray(__namedExportsOrder)) { + exports = {}; + __namedExportsOrder.forEach((name) => { + if (namedExports[name]) { + exports[name] = namedExports[name]; + } + }); + } + + const csfFile: CSFFile = { meta, stories: {} }; + + Object.keys(exports).forEach((key) => { + if (isExportStory(key, meta)) { + const storyMeta: StoryMeta = normalizeStory(key, exports[key], meta); + checkDisallowedParameters(storyMeta.parameters); + + csfFile.stories[storyMeta.id] = storyMeta; + } + }); - return exports as CSFFile; + return csfFile; } diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index c69bf5ef515..0f58eeda35c 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -8,11 +8,57 @@ import { StoryId, StoryKind, StoryName, + ViewMode, + LegacyStoryFn, + StoryFn, } from '@storybook/addons'; -export type { StoryId }; +import { HooksContext } from '../hooks'; + +export type { StoryId, ViewMode, Parameters, Args, ArgTypes, LegacyStoryFn, ArgsStoryFn }; export type ModuleExports = Record; +export interface StoryIdentifier { + id: StoryId; + kind: StoryKind; // TODO -- rename this to componentTitle or just title? + name: StoryName; + // TODO -- do we still need story here? +} + +// TODO -- these should probably have their own definition +export type Globals = Args; +export type GlobalTypes = ArgTypes; + +export type StoryContext = StoryIdentifier & { + parameters: Parameters; + args: Args; + argTypes: ArgTypes; + globals: Globals; + hooks: HooksContext; +}; + +// Theoretically you can update anything, in practice you should probably only be able to update args + globals? +// TODO - should we reflect that in the type? +export type StoryContextUpdate = Partial; + +export type LoadedStoryContext = StoryContext & { + loaded: Record; +}; + +export declare type RenderContextWithoutStoryContext = StoryIdentifier & { + forceRender: boolean; + showMain: () => void; + showError: (error: { title: string; description: string }) => void; + showException: (err: Error) => void; +}; + +export type RenderContext = RenderContextWithoutStoryContext & + LoadedStoryContext & { + storyFn: LegacyStoryFn; + }; + +export type ArgTypesEnhancer = (context: StoryContext) => ArgTypes; +export type ArgsEnhancer = (context: StoryContext) => Args; export type Meta = { decorators?: DecoratorFunction[]; @@ -20,50 +66,89 @@ export type Meta = { args?: Args; argTypes?: ArgTypes; loaders?: LoaderFunction[]; + render?: ArgsStoryFn; + play?: () => Promise; // TODO -- should this take story context }; -export type GlobalMeta = Meta; +export type GlobalMeta = Meta & { + applyDecorators?: DecoratorApplicator; + argsEnhancers?: ArgsEnhancer[]; + argTypesEnhancers?: ArgTypesEnhancer[]; + globals?: Globals; + globalTypes?: GlobalTypes; +}; + +export type WebGlobalMeta = GlobalMeta & { + renderToDOM?: (context: RenderContext, element: Element) => Promise; +}; export type ComponentTitle = StoryKind; +type StoryDescriptor = string[] | RegExp; export type ComponentMeta = Meta & { title: ComponentTitle; - // component, - // subcomponents, + // TODO - check these + component?: any; + subcomponents?: Record; + includeStories?: StoryDescriptor; + excludeStories?: StoryDescriptor; }; export type StoryMeta = Meta & { - render: ArgsStoryFn; + id: StoryId; + name: StoryName; }; export type CSFFile = { - metadata: ComponentMeta; -} & Record>; + meta: ComponentMeta; + stories: Record>; +}; + +export type Story = StoryIdentifier & { + parameters: Parameters; + initialArgs: Args; + argTypes: ArgTypes; + hooks: HooksContext; + applyLoaders: (context: StoryContext) => Promise; + storyFn: LegacyStoryFn; + runPlayFunction: () => Promise; // TODO -- should this take story context? + cleanup: () => void; +}; export type Path = string; -// TODO -- these types probably need to live in a common spot w/ where stories.json is generated -export interface StoriesMetadataStory { +export interface StoriesListStory { id: StoryId; name: StoryName; + kind: ComponentTitle; // TODO -- should we rename this? parameters: { fileName: Path }; } -export interface StoriesMetadata { +export interface StoriesList { v: number; - stories: Record; + stories: Record; } -export type ModuleImporter = (path: Path) => ModuleExports; - -export type StoryContext = { - id: StoryId; - parameters: Parameters; - args: Args; - argTypes: ArgTypes; - globals: Args; -}; +export type ModuleImportFn = (path: Path) => ModuleExports; export type Channel = any; -export type Globals = Args; +export type StorySpecifier = StoryId | { name: StoryName; kind: StoryKind } | '*'; + +export interface SelectionSpecifier { + storySpecifier: StorySpecifier; + viewMode: ViewMode; + singleStory?: boolean; + args?: Args; + globals?: Args; +} + +export interface Selection { + storyId: StoryId; + viewMode: ViewMode; +} + +export type DecoratorApplicator = ( + storyFn: LegacyStoryFn, + decorators: DecoratorFunction[] +) => LegacyStoryFn; From 1d09e1e51b3e3fb78f085f37ec29d4482fc5ed95 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 28 Jul 2021 16:18:27 +1000 Subject: [PATCH 003/285] Cleaned up some things: - URL ("persisted") globals/args a bit more sensible - Moved docs rendering to WebPreview - Cleaned up context a bit --- lib/client-api/src/new/ArgsStore.ts | 10 ++- lib/client-api/src/new/GlobalsStore.ts | 4 +- lib/client-api/src/new/StoryStore.ts | 24 +------ .../src/new/{WebPreview.ts => WebPreview.tsx} | 56 ++++++++++++---- .../src/new/{WebView.tsx => WebView.ts} | 42 +++--------- lib/client-api/src/new/prepareStory.ts | 66 ++++++++----------- lib/client-api/src/new/types.ts | 24 ++++--- 7 files changed, 111 insertions(+), 115 deletions(-) rename lib/client-api/src/new/{WebPreview.ts => WebPreview.tsx} (84%) rename lib/client-api/src/new/{WebView.tsx => WebView.ts} (72%) diff --git a/lib/client-api/src/new/ArgsStore.ts b/lib/client-api/src/new/ArgsStore.ts index fef7e8e4a91..76c5fac74ba 100644 --- a/lib/client-api/src/new/ArgsStore.ts +++ b/lib/client-api/src/new/ArgsStore.ts @@ -1,4 +1,5 @@ -import { StoryId, Args, SelectionSpecifier } from './types'; +import { StoryId, Story, Args } from './types'; +import { combineArgs, mapArgsToTypes } from '../args'; export class ArgsStore { argsByStoryId: Record = {}; @@ -15,6 +16,13 @@ export class ArgsStore { this.argsByStoryId[storyId] = args; } + updateFromPersisted(story: Story, persisted: Args) { + this.argsByStoryId[story.id] = combineArgs( + this.argsByStoryId[story.id], + mapArgsToTypes(persisted, story.argTypes) + ); + } + update(storyId: StoryId, argsUpdate: Partial) { if (!(storyId in this.argsByStoryId)) { throw new Error(`No args known for ${storyId} -- has it been rendered yet?`); diff --git a/lib/client-api/src/new/GlobalsStore.ts b/lib/client-api/src/new/GlobalsStore.ts index ea2de849227..c41fb55d04b 100644 --- a/lib/client-api/src/new/GlobalsStore.ts +++ b/lib/client-api/src/new/GlobalsStore.ts @@ -34,8 +34,8 @@ export class GlobalsStore { ); } - updateFromCache(cachedGlobals: Globals) { - const allowedUrlGlobals = Object.entries(cachedGlobals).reduce((acc, [key, value]) => { + updateFromPersisted(persisted: Globals) { + const allowedUrlGlobals = Object.entries(persisted).reduce((acc, [key, value]) => { if (this.allowedGlobalNames.has(key)) acc[key] = value; return acc; }, {} as Globals); diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index 65f1e194e1f..afc00b8894f 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -4,7 +4,6 @@ import { GlobalsStore } from './GlobalsStore'; import { processCSFFile } from './processCSFFile'; import { prepareStory } from './prepareStory'; import { Args, CSFFile, StoryId, ModuleImportFn, GlobalMeta, Story, StoryContext } from './types'; -import { combineArgs, mapArgsToTypes } from '../args'; export class StoryStore { storiesList: StoriesListStore; @@ -43,13 +42,7 @@ export class StoryStore { return processCSFFile({ moduleExports, path }); } - getStory({ - storyId, - cachedArgs, - }: { - storyId: StoryId; - cachedArgs?: Args; - }): Story { + getStory({ storyId }: { storyId: StoryId }): Story { const csfFile = this.loadCSFFileByStoryId(storyId); const storyMeta = csfFile.stories[storyId]; @@ -62,19 +55,8 @@ export class StoryStore { // TODO -- we need some kind of cache at this point. - let { initialArgs } = story; - if (cachedArgs) { - initialArgs = combineArgs(initialArgs, mapArgsToTypes(cachedArgs, story.argTypes)); - } - this.args.set(storyId, initialArgs); - - // QN: how do we currently distinguish first from subsequent render of a story? - // -- ANS: we have a concept of "unmounting" a story - // -- second answer: the StoryRenderer currently knows - - // TODO - // If we are setting args once when the story is first rendered, we need to - // some how do it at the point of rendering + // TODO(HMR) -- figure out when we set this on first run vs HMR + this.args.set(storyId, story.initialArgs); return story; } diff --git a/lib/client-api/src/new/WebPreview.ts b/lib/client-api/src/new/WebPreview.tsx similarity index 84% rename from lib/client-api/src/new/WebPreview.ts rename to lib/client-api/src/new/WebPreview.tsx index 97d6554c550..4fab3a4e537 100644 --- a/lib/client-api/src/new/WebPreview.ts +++ b/lib/client-api/src/new/WebPreview.tsx @@ -1,3 +1,5 @@ +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; import Events from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; import { global } from 'global'; @@ -71,11 +73,7 @@ export class WebPreview { } this.urlStore = new UrlStore(); - this.storyStore = new StoryStore({ - selectionSpecifier: this.urlStore.selectionSpecifier, - importFn, - globalMeta, - }); + this.storyStore = new StoryStore({ importFn, globalMeta }); this.view = new WebView(); } @@ -107,10 +105,10 @@ export class WebPreview { this.urlStore.setSelection({ storyId, viewMode }); if (globals) { - this.storyStore.globals.updateFromCache(globals); + this.storyStore.globals.updateFromPersisted(globals); } - await this.renderSelection({ forceRender: false, cachedArgs: args }); + await this.renderSelection({ forceRender: false, persistedArgs: args }); } onKeydown(event: KeyboardEvent) { @@ -150,7 +148,7 @@ export class WebPreview { } async onResetArgs({ storyId, argNames }: { storyId: string; argNames?: string[] }) { - const { initialArgs } = await this.storyStore.getStory(storyId); + const { initialArgs } = await this.storyStore.getStory({ storyId }); // TODO ensure this technique works with falsey/null initialArgs const updatedArgs = argNames.reduce((acc, argName) => { @@ -166,14 +164,23 @@ export class WebPreview { // in which case we render it to the root element, OR // - a story selected in "docs" viewMode, // in which case we render the docsPage for that story - async renderSelection({ forceRender, cachedArgs }: { forceRender: boolean; cachedArgs: Args }) { + async renderSelection({ + forceRender, + persistedArgs, + }: { + forceRender: boolean; + persistedArgs?: Args; + }) { if (!this.urlStore.selection) { throw new Error('Cannot render story as no selection was made'); } const { selection } = this.urlStore; - const story = await this.storyStore.getStory({ storyId: selection.storyId, cachedArgs }); + const story = await this.storyStore.getStory({ storyId: selection.storyId }); + if (persistedArgs) { + this.storyStore.args.updateFromPersisted(story, persistedArgs); + } // We need to: @@ -190,6 +197,10 @@ export class WebPreview { this.removeStory({ story: previousStory }); } + if (viewModeChanged && this.previousSelection.viewMode === 'docs') { + ReactDOM.unmountComponentAtNode(this.view.docsRoot()); + } + // Don't re-render the story if nothing has changed to justify it if (!forceRender && !storyChanged && !implementationChanged && !viewModeChanged) { // TODO -- the api of this changed, but the previous API made no sense. Did we use it? @@ -206,7 +217,30 @@ export class WebPreview { this.previousSelection = selection; if (selection.viewMode === 'docs') { - await this.view.renderDocs(story); + const element = this.view.prepareForDocs(); + + const { docs } = story.parameters; + if (docs?.page && !docs?.container) { + throw new Error('No `docs.container` set, did you run `addon-docs/preset`?'); + } + + const DocsContainer: Component = + docs.container || (({ children }: { children: Element }) => <>{children}); + const Page: Component = docs.page || NoDocs; + + // TODO -- what is docs context? pass in here? + // Docs context includes the storyStore. Probably it would be better if it didn't but that can be fixed in a later refactor + + await new Promise((resolve) => { + ReactDOM.render( + + + , + document.getElementById('docs-root'), + resolve + ); + }); + // TODO -- changed the API, previous it had a kind -- did we use it? this.channel.emit(Events.DOCS_RENDERED, selection.storyId); return; diff --git a/lib/client-api/src/new/WebView.tsx b/lib/client-api/src/new/WebView.ts similarity index 72% rename from lib/client-api/src/new/WebView.tsx rename to lib/client-api/src/new/WebView.ts index bccbf0f3e3c..d3550ef2d88 100644 --- a/lib/client-api/src/new/WebView.tsx +++ b/lib/client-api/src/new/WebView.ts @@ -1,5 +1,3 @@ -import React, { Component } from 'react'; -import ReactDOM from 'react-dom'; import global from 'global'; import { logger } from '@storybook/client-logger'; import AnsiToHtml from 'ansi-to-html'; @@ -28,16 +26,10 @@ const ansiConverter = new AnsiToHtml({ }); export class WebView { - currentViewMode: ViewMode; - currentLayoutClass?: typeof layoutClassMap[keyof typeof layoutClassMap] | null; // Get ready to render a story, returning the element to render to prepareForStory(story: Story, forceRender: boolean) { - if (this.currentViewMode === 'docs') { - ReactDOM.unmountComponentAtNode(document.getElementById('docs-root')); - } - this.applyLayout(story.parameters.layout); if (!forceRender) { @@ -45,38 +37,22 @@ export class WebView { document.documentElement.scrollLeft = 0; } - this.currentViewMode = 'story'; + return this.storyRoot(); + } + + storyRoot() { return document.getElementById('root'); } - async renderDocs(story: Story) { + prepareForDocs() { this.showMain(); this.showDocs(); this.applyLayout('fullscreen'); + return this.docsRoot(); + } - const { docs } = story.parameters; - if (docs?.page && !docs?.container) { - throw new Error('No `docs.container` set, did you run `addon-docs/preset`?'); - } - - const DocsContainer: Component = - docs.container || (({ children }: { children: Element }) => <>{children}); - const Page: Component = docs.page || NoDocs; - - // TODO -- what is docs context? pass in here? - // Docs context includes the storyStore. Probably it would be better if it didn't but that can be fixed in a later refactor - - await new Promise((resolve) => { - ReactDOM.render( - - - , - document.getElementById('docs-root'), - resolve - ); - }); - - this.currentViewMode = 'docs'; + docsRoot() { + return document.getElementById('docs-root'); } applyLayout(layout: Layout = 'padded') { diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts index 6ab46abe69d..3987a7a6e10 100644 --- a/lib/client-api/src/new/prepareStory.ts +++ b/lib/client-api/src/new/prepareStory.ts @@ -14,6 +14,7 @@ import { ArgTypes, ArgsEnhancer, ArgTypesEnhancer, + StoryContextForEnhancers, } from './types'; import { combineParameters } from '../parameters'; @@ -83,33 +84,6 @@ export function prepareStory( // eslint-disable-next-line no-underscore-dangle parameters.__isArgsStory = passArgsFirst && render.length > 0; - const contextForEnhancers: StoryContext = { - id, - name, - kind: title, // TODO ? - parameters, - argTypes: passedArgTypes, - hooks, - // TODO -- does it make sense for this to include args? globals? - args: {}, - globals: {}, - }; - - // BACKCOMPAT: do argTypeEnhancers expect to find existing argTypes on enhancers? - const argTypes = argTypesEnhancers.reduce( - (accumulatedArgTypes, enhancer) => ({ - ...accumulatedArgTypes, - ...enhancer({ - ...contextForEnhancers, - argTypes: accumulatedArgTypes, - }), - }), - {} as ArgTypes - ); - - // TODO -- are we still doing this? - // parameters.argTypes = argTypes; - // Pull out args[X] || argTypes[X].defaultValue into initialArgs // TODO -- generalize combineParameters const passedArgs: Args = combineParameters( @@ -119,7 +93,7 @@ export function prepareStory( ) as Args; const defaultArgs: Args = Object.entries( - argTypes as Record + passedArgTypes as Record ).reduce((acc, [arg, { defaultValue }]) => { if (typeof defaultValue !== 'undefined') { acc[arg] = defaultValue; @@ -131,17 +105,41 @@ export function prepareStory( } const initialArgsBeforeEnhancers = { ...defaultArgs, ...passedArgs }; - const initialArgs = argsEnhancers.reduce( + const contextForEnhancers: StoryContextForEnhancers = { + id, + name, + story: name, // Back compat + title, + kind: title, // Back compat + parameters, + hooks, + initialArgs: initialArgsBeforeEnhancers, + argTypes: passedArgTypes, + }; + + contextForEnhancers.initialArgs = argsEnhancers.reduce( (accumulatedArgs: Args, enhancer) => ({ ...accumulatedArgs, ...enhancer({ ...contextForEnhancers, - args: accumulatedArgs, + initialArgs: accumulatedArgs, }), }), initialArgsBeforeEnhancers ); + // BACKCOMPAT: do argTypeEnhancers expect to find existing argTypes on enhancers? + contextForEnhancers.argTypes = argTypesEnhancers.reduce( + (accumulatedArgTypes, enhancer) => ({ + ...accumulatedArgTypes, + ...enhancer({ + ...contextForEnhancers, + argTypes: accumulatedArgTypes, + }), + }), + contextForEnhancers.argTypes + ); + const applyLoaders = async (context: StoryContext) => { const loadResults = await Promise.all(loaders.map((loader) => loader(context))); const loaded = Object.assign({}, ...loadResults); @@ -175,13 +173,7 @@ export function prepareStory( }; return { - id, - name, - kind: title, // TODO ? - parameters, - initialArgs, - argTypes, - hooks, + ...contextForEnhancers, applyLoaders, storyFn, runPlayFunction, diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 0f58eeda35c..2ab6cb7d378 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -20,26 +20,30 @@ export type { StoryId, ViewMode, Parameters, Args, ArgTypes, LegacyStoryFn, Args export type ModuleExports = Record; export interface StoryIdentifier { id: StoryId; - kind: StoryKind; // TODO -- rename this to componentTitle or just title? + kind: ComponentTitle; // deprecated + title: ComponentTitle; name: StoryName; - // TODO -- do we still need story here? + story: StoryName; // deprecated } // TODO -- these should probably have their own definition export type Globals = Args; export type GlobalTypes = ArgTypes; -export type StoryContext = StoryIdentifier & { +export type StoryContextForEnhancers = StoryIdentifier & { parameters: Parameters; - args: Args; - argTypes: ArgTypes; globals: Globals; hooks: HooksContext; + initialArgs: Args; + argTypes: ArgTypes; +}; + +export type StoryContextUpdate = { + args: Args; + globals: Globals; }; -// Theoretically you can update anything, in practice you should probably only be able to update args + globals? -// TODO - should we reflect that in the type? -export type StoryContextUpdate = Partial; +export type StoryContext = StoryContextForEnhancers & StoryContextUpdate; export type LoadedStoryContext = StoryContext & { loaded: Record; @@ -57,8 +61,8 @@ export type RenderContext = RenderContextWithoutStoryContext storyFn: LegacyStoryFn; }; -export type ArgTypesEnhancer = (context: StoryContext) => ArgTypes; -export type ArgsEnhancer = (context: StoryContext) => Args; +export type ArgTypesEnhancer = (context: StoryContextForEnhancers) => ArgTypes; +export type ArgsEnhancer = (context: StoryContextForEnhancers) => Args; export type Meta = { decorators?: DecoratorFunction[]; From db31df7765c133cd3efafc070513c756ac0a4585 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 28 Jul 2021 16:33:07 +1000 Subject: [PATCH 004/285] Some type fixes --- lib/client-api/src/new/WebPreview.tsx | 52 ++++++++++++++------------- lib/client-api/src/new/WebView.ts | 5 ++- lib/client-api/src/new/types.ts | 3 ++ 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/lib/client-api/src/new/WebPreview.tsx b/lib/client-api/src/new/WebPreview.tsx index 4fab3a4e537..92609c0ba57 100644 --- a/lib/client-api/src/new/WebPreview.tsx +++ b/lib/client-api/src/new/WebPreview.tsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { ComponentType } from 'react'; import ReactDOM from 'react-dom'; import Events from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; @@ -15,11 +15,13 @@ import { Globals, StoryId, Args, + DocsContext, } from './types'; import { StoryStore } from './StoryStore'; import { UrlStore } from './UrlStore'; import { WebView } from './WebView'; import { StorySpecifier } from '../types'; +import { NoDocs } from './NoDocs'; const { navigator, window: globalWindow } = global; @@ -216,47 +218,49 @@ export class WebPreview { // Record the previous selection *before* awaiting the rendering, in cases things change before it is done. this.previousSelection = selection; + const { id, title, name } = story; + if (selection.viewMode === 'docs') { const element = this.view.prepareForDocs(); + const docsContext = { + id, + title, + name, + storyStore: this.storyStore, + renderStoryToElement: this.renderStoryToElement.bind(this), + }; const { docs } = story.parameters; if (docs?.page && !docs?.container) { throw new Error('No `docs.container` set, did you run `addon-docs/preset`?'); } - const DocsContainer: Component = + const DocsContainer: ComponentType<{ context: DocsContext }> = docs.container || (({ children }: { children: Element }) => <>{children}); - const Page: Component = docs.page || NoDocs; - - // TODO -- what is docs context? pass in here? - // Docs context includes the storyStore. Probably it would be better if it didn't but that can be fixed in a later refactor - - await new Promise((resolve) => { - ReactDOM.render( - - - , - document.getElementById('docs-root'), - resolve - ); - }); - - // TODO -- changed the API, previous it had a kind -- did we use it? - this.channel.emit(Events.DOCS_RENDERED, selection.storyId); + const Page: ComponentType = docs.page || NoDocs; + + const docsElement = ( + + + + ); + ReactDOM.render(docsElement, element, () => + // TODO -- changed the API, previous it had a kind -- did we use it? + this.channel.emit(Events.DOCS_RENDERED, selection.storyId) + ); return; } const element = this.view.prepareForStory(story, forceRender); - - const { id, kind, name } = story; const renderContext: RenderContextWithoutStoryContext = { id, - kind, + title, + kind: title, name, + story: name, forceRender, showMain: () => this.view.showMain(), - showError: ({ title, description }: { title: string; description: string }) => - this.renderError({ title, description }), + showError: (err: { title: string; description: string }) => this.renderError(err), showException: (err: Error) => this.renderException(err), }; diff --git a/lib/client-api/src/new/WebView.ts b/lib/client-api/src/new/WebView.ts index d3550ef2d88..957d7a7d29e 100644 --- a/lib/client-api/src/new/WebView.ts +++ b/lib/client-api/src/new/WebView.ts @@ -4,7 +4,6 @@ import AnsiToHtml from 'ansi-to-html'; import dedent from 'ts-dedent'; import { Story, ViewMode } from './types'; -import { NoDocs } from './NoDocs'; const { document, FEATURES = {} } = global; @@ -40,7 +39,7 @@ export class WebView { return this.storyRoot(); } - storyRoot() { + storyRoot(): Element { return document.getElementById('root'); } @@ -51,7 +50,7 @@ export class WebView { return this.docsRoot(); } - docsRoot() { + docsRoot(): Element { return document.getElementById('docs-root'); } diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 2ab6cb7d378..5c4281f9d10 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -156,3 +156,6 @@ export type DecoratorApplicator = ( storyFn: LegacyStoryFn, decorators: DecoratorFunction[] ) => LegacyStoryFn; + +// TODO +export type DocsContext = any; From 8e2fa0b657f33b13a0abf088d45bcbdaeec98398 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 28 Jul 2021 22:12:23 +1000 Subject: [PATCH 005/285] Small refactor --- lib/client-api/src/new/StoryStore.ts | 2 +- lib/client-api/src/new/WebPreview.tsx | 77 ++++++++++++++++----------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index afc00b8894f..e18c5ce40e7 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -42,7 +42,7 @@ export class StoryStore { return processCSFFile({ moduleExports, path }); } - getStory({ storyId }: { storyId: StoryId }): Story { + loadStory({ storyId }: { storyId: StoryId }): Story { const csfFile = this.loadCSFFileByStoryId(storyId); const storyMeta = csfFile.stories[storyId]; diff --git a/lib/client-api/src/new/WebPreview.tsx b/lib/client-api/src/new/WebPreview.tsx index 92609c0ba57..64a9630dd2b 100644 --- a/lib/client-api/src/new/WebPreview.tsx +++ b/lib/client-api/src/new/WebPreview.tsx @@ -150,7 +150,7 @@ export class WebPreview { } async onResetArgs({ storyId, argNames }: { storyId: string; argNames?: string[] }) { - const { initialArgs } = await this.storyStore.getStory({ storyId }); + const { initialArgs } = await this.storyStore.loadStory({ storyId }); // TODO ensure this technique works with falsey/null initialArgs const updatedArgs = argNames.reduce((acc, argName) => { @@ -179,7 +179,7 @@ export class WebPreview { const { selection } = this.urlStore; - const story = await this.storyStore.getStory({ storyId: selection.storyId }); + const story = await this.storyStore.loadStory({ storyId: selection.storyId }); if (persistedArgs) { this.storyStore.args.updateFromPersisted(story, persistedArgs); } @@ -193,7 +193,7 @@ export class WebPreview { const implementationChanged = false; if (this.previousSelection?.viewMode === 'story' && (storyChanged || viewModeChanged)) { - const previousStory = await this.storyStore.getStory({ + const previousStory = await this.storyStore.loadStory({ storyId: this.previousSelection.storyId, }); this.removeStory({ story: previousStory }); @@ -218,40 +218,53 @@ export class WebPreview { // Record the previous selection *before* awaiting the rendering, in cases things change before it is done. this.previousSelection = selection; + if (selection.viewMode === 'docs') { + await this.renderDocs({ story }); + } else { + await this.renderStory({ story, forceRender }); + } + } + + async renderDocs({ story }: { story: Story }) { const { id, title, name } = story; + const element = this.view.prepareForDocs(); + const docsContext = { + id, + title, + name, + storyStore: this.storyStore, + renderStoryToElement: this.renderStoryToElement.bind(this), + }; - if (selection.viewMode === 'docs') { - const element = this.view.prepareForDocs(); - const docsContext = { - id, - title, - name, - storyStore: this.storyStore, - renderStoryToElement: this.renderStoryToElement.bind(this), - }; - - const { docs } = story.parameters; - if (docs?.page && !docs?.container) { - throw new Error('No `docs.container` set, did you run `addon-docs/preset`?'); - } - - const DocsContainer: ComponentType<{ context: DocsContext }> = - docs.container || (({ children }: { children: Element }) => <>{children}); - const Page: ComponentType = docs.page || NoDocs; - - const docsElement = ( - - - - ); - ReactDOM.render(docsElement, element, () => - // TODO -- changed the API, previous it had a kind -- did we use it? - this.channel.emit(Events.DOCS_RENDERED, selection.storyId) - ); - return; + const { docs } = story.parameters; + if (docs?.page && !docs?.container) { + throw new Error('No `docs.container` set, did you run `addon-docs/preset`?'); } + const DocsContainer: ComponentType<{ context: DocsContext }> = + docs.container || (({ children }: { children: Element }) => <>{children}); + const Page: ComponentType = docs.page || NoDocs; + + const docsElement = ( + + + + ); + ReactDOM.render(docsElement, element, () => + // TODO -- changed the API, previous it had a kind -- did we use it? + this.channel.emit(Events.DOCS_RENDERED, id) + ); + } + + async renderStory({ + story, + forceRender, + }: { + story: Story; + forceRender: boolean; + }) { const element = this.view.prepareForStory(story, forceRender); + const { id, title, name } = story; const renderContext: RenderContextWithoutStoryContext = { id, title, From 28a8ea42b9030546ac00118ebf3f25796d925462 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 29 Jul 2021 16:25:23 +1000 Subject: [PATCH 006/285] Moved things around and got it bootstrapping Albeit with some compromises for now --- lib/client-api/src/new/autoTitle.test.ts | 65 ++++++ lib/client-api/src/new/autoTitle.ts | 56 +++++ lib/client-api/src/new/normalizeStory.test.ts | 208 ++++++++++++++++++ lib/client-api/src/new/normalizeStory.ts | 49 +++++ lib/client-api/src/new/processCSFFile.ts | 4 +- lib/client-api/src/new/types.ts | 3 +- .../src/preview}/new/UrlStore.ts | 5 +- .../src/preview}/new/WebPreview.tsx | 9 +- .../src/preview}/new/WebView.ts | 2 +- 9 files changed, 390 insertions(+), 11 deletions(-) create mode 100644 lib/client-api/src/new/autoTitle.test.ts create mode 100644 lib/client-api/src/new/autoTitle.ts create mode 100644 lib/client-api/src/new/normalizeStory.test.ts create mode 100644 lib/client-api/src/new/normalizeStory.ts rename lib/{client-api/src => core-client/src/preview}/new/UrlStore.ts (60%) rename lib/{client-api/src => core-client/src/preview}/new/WebPreview.tsx (98%) rename lib/{client-api/src => core-client/src/preview}/new/WebView.ts (97%) diff --git a/lib/client-api/src/new/autoTitle.test.ts b/lib/client-api/src/new/autoTitle.test.ts new file mode 100644 index 00000000000..3f64db00d69 --- /dev/null +++ b/lib/client-api/src/new/autoTitle.test.ts @@ -0,0 +1,65 @@ +import { autoTitleFromEntry as auto } from './autoTitle'; + +expect.addSnapshotSerializer({ + print: (val: any) => val, + test: (val) => true, +}); + +describe('autoTitle', () => { + it('no directory', () => { + expect(auto('/path/to/file', { glob: '' })).toBeFalsy(); + }); + + it('no match', () => { + expect(auto('/path/to/file', { glob: '', specifier: { directory: '/other' } })).toBeFalsy(); + }); + + describe('no trailing slash', () => { + it('match with no titlePrefix', () => { + expect( + auto('/path/to/file', { glob: '', specifier: { directory: '/path' } }) + ).toMatchInlineSnapshot(`to/file`); + }); + + it('match with titlePrefix', () => { + expect( + auto('/path/to/file', { glob: '', specifier: { directory: '/path', titlePrefix: 'atoms' } }) + ).toMatchInlineSnapshot(`atoms/to/file`); + }); + + it('match with extension', () => { + expect( + auto('/path/to/file.stories.tsx', { + glob: '', + specifier: { directory: '/path', titlePrefix: 'atoms' }, + }) + ).toMatchInlineSnapshot(`atoms/to/file`); + }); + }); + + describe('trailing slash', () => { + it('match with no titlePrefix', () => { + expect( + auto('/path/to/file', { glob: '', specifier: { directory: '/path/' } }) + ).toMatchInlineSnapshot(`to/file`); + }); + + it('match with titlePrefix', () => { + expect( + auto('/path/to/file', { + glob: '', + specifier: { directory: '/path/', titlePrefix: 'atoms' }, + }) + ).toMatchInlineSnapshot(`atoms/to/file`); + }); + + it('match with extension', () => { + expect( + auto('/path/to/file.stories.tsx', { + glob: '', + specifier: { directory: '/path/', titlePrefix: 'atoms' }, + }) + ).toMatchInlineSnapshot(`atoms/to/file`); + }); + }); +}); diff --git a/lib/client-api/src/new/autoTitle.ts b/lib/client-api/src/new/autoTitle.ts new file mode 100644 index 00000000000..7ae6ba224b3 --- /dev/null +++ b/lib/client-api/src/new/autoTitle.ts @@ -0,0 +1,56 @@ +// TODO copied over from core-client ?? + +import global from 'global'; + +// TODO +// import type { NormalizedStoriesEntry } from './types'; +interface NormalizedStoriesEntrySpecifier { + directory: string; + titlePrefix?: string; +} +interface NormalizedStoriesEntry { + specifier: NormalizedStoriesEntrySpecifier; +} + +const { FEATURES = {}, STORIES = [] } = global; + +interface Meta { + title?: string; +} + +const autoTitleV2 = (meta: Meta, fileName: string) => { + return meta.title; +}; + +const stripExtension = (titleWithExtension: string) => { + let parts = titleWithExtension.split('/'); + const last = parts[parts.length - 1]; + const dotIndex = last.indexOf('.'); + const stripped = dotIndex > 0 ? last.substr(0, dotIndex) : last; + parts[parts.length - 1] = stripped; + const [first, ...rest] = parts; + if (first === '') { + parts = rest; + } + return parts.join('/'); +}; + +export const autoTitleFromEntry = (fileName: string, entry: NormalizedStoriesEntry) => { + const { directory, titlePrefix = '' } = entry.specifier || {}; + if (fileName.startsWith(directory)) { + const suffix = fileName.replace(directory, ''); + return stripExtension([titlePrefix, suffix].join('/')); + } + return undefined; +}; + +const autoTitleV3 = (meta: Meta, fileName: string) => { + if (meta.title) return meta.title; + for (let i = 0; i < STORIES.length; i += 1) { + const title = autoTitleFromEntry(fileName, STORIES[i]); + if (title) return title; + } + return undefined; +}; + +export const autoTitle = FEATURES.previewCsfV3 ? autoTitleV3 : autoTitleV2; diff --git a/lib/client-api/src/new/normalizeStory.test.ts b/lib/client-api/src/new/normalizeStory.test.ts new file mode 100644 index 00000000000..ec424dfff2c --- /dev/null +++ b/lib/client-api/src/new/normalizeStory.test.ts @@ -0,0 +1,208 @@ +import { normalizeV2, normalizeV3 } from './normalizeStory'; + +const globalRender = 'global-render'; + +describe('normalizeStory', () => { + describe('user-provided story function', () => { + describe('v2', () => { + it('should normalize into an object', () => { + const storyFn = () => {}; + const meta = { title: 'title' }; + expect(normalizeV2('storyExport', storyFn, meta, globalRender)).toMatchInlineSnapshot(` + Object { + "name": "Story Export", + "parameters": Object { + "__id": "title--story-export", + "argTypes": Object {}, + "args": Object {}, + "decorators": Array [], + "loaders": Array [], + }, + "storyFn": [Function], + } + `); + }); + }); + describe('v3', () => { + it('should normalize into an object', () => { + const storyFn = () => {}; + const meta = { title: 'title' }; + expect(normalizeV3('storyExport', storyFn, meta, globalRender)).toMatchInlineSnapshot(` + Object { + "name": "Story Export", + "parameters": Object { + "__id": "title--story-export", + "argTypes": Object {}, + "args": Object {}, + "decorators": Array [], + "loaders": Array [], + "play": undefined, + }, + "storyFn": [Function], + } + `); + }); + it('should throw on story annotation', async () => { + const storyFn = () => {}; + storyFn.story = { name: 'v1 style name' }; + const meta = { title: 'title' }; + await expect(async () => + normalizeV3('storyExport', storyFn, meta, globalRender) + ).rejects.toThrow(); + }); + }); + }); + describe('user-provided story object', () => { + describe('v2', () => { + it('should treat it the same as if it was a function', () => { + const storyObj = {}; + const meta = { title: 'title' }; + expect(normalizeV2('storyExport', storyObj, meta, globalRender)).toMatchInlineSnapshot(` + Object { + "name": "Story Export", + "parameters": Object { + "__id": "title--story-export", + "argTypes": Object {}, + "args": Object {}, + "decorators": Array [], + "loaders": Array [], + }, + "storyFn": Object {}, + } + `); + }); + }); + describe('v3', () => { + describe('render function', () => { + it('implicit render function', () => { + const storyObj = {}; + const meta = { title: 'title' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized.storyFn).toBe(globalRender); + }); + + it('user-provided story render function', () => { + const storyObj = { render: () => 'story' }; + const meta = { title: 'title', render: () => 'meta' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized.storyFn).toBe(storyObj.render); + }); + + it('user-provided meta render function', () => { + const storyObj = {}; + const meta = { title: 'title', render: () => 'meta' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized.storyFn).toBe(meta.render); + }); + }); + + describe('play function', () => { + it('no render function', () => { + const storyObj = {}; + const meta = { title: 'title' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized.parameters.play).toBeUndefined(); + }); + + it('user-provided story render function', () => { + const storyObj = { play: () => 'story' }; + const meta = { title: 'title', play: () => 'meta' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized.parameters.play).toBe(storyObj.play); + }); + + it('user-provided meta render function', () => { + const storyObj = {}; + const meta = { title: 'title', play: () => 'meta' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized.parameters.play).toBe(meta.play); + }); + }); + + describe('annotations', () => { + it('empty annotations', () => { + const storyObj = {}; + const meta = { title: 'title' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized).toMatchInlineSnapshot(` + Object { + "name": "Story Export", + "parameters": Object { + "__id": "title--story-export", + "argTypes": Object {}, + "args": Object {}, + "decorators": Array [], + "loaders": Array [], + "play": undefined, + }, + "storyFn": "global-render", + } + `); + }); + + it('full annotations', () => { + const storyObj = { + name: 'story name', + parameters: { storyParam: 'val' }, + decorators: [() => {}], + loaders: [() => {}], + args: { storyArg: 'val' }, + argTypes: { storyArgType: 'val' }, + }; + const meta = { title: 'title' }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized).toMatchInlineSnapshot(` + Object { + "name": "story name", + "parameters": Object { + "__id": "title--story-export", + "argTypes": Object { + "storyArgType": "val", + }, + "args": Object { + "storyArg": "val", + }, + "decorators": Array [ + [Function], + ], + "loaders": Array [ + [Function], + ], + "play": undefined, + "storyParam": "val", + }, + "storyFn": "global-render", + } + `); + }); + + it('meta annotations', () => { + const storyObj = {}; + const meta = { + title: 'title', + parameters: { metaParam: 'val' }, + decorators: [() => {}], + loaders: [() => {}], + args: { metaArg: 'val' }, + argTypes: { metaArgType: 'val' }, + }; + const normalized = normalizeV3('storyExport', storyObj, meta, globalRender); + expect(normalized).toMatchInlineSnapshot(` + Object { + "name": "Story Export", + "parameters": Object { + "__id": "title--story-export", + "argTypes": Object {}, + "args": Object {}, + "decorators": Array [], + "loaders": Array [], + "play": undefined, + }, + "storyFn": "global-render", + } + `); + }); + }); + }); + }); +}); diff --git a/lib/client-api/src/new/normalizeStory.ts b/lib/client-api/src/new/normalizeStory.ts new file mode 100644 index 00000000000..2a0318db2b1 --- /dev/null +++ b/lib/client-api/src/new/normalizeStory.ts @@ -0,0 +1,49 @@ +// TODO -- Copied/Adapted from core-client + +import { storyNameFromExport, toId } from '@storybook/csf'; +import dedent from 'ts-dedent'; + +import { ComponentMeta, StoryMeta } from './types'; + +const deprecatedStoryAnnotation = dedent` +CSF .story annotations deprecated; annotate story functions directly: +- StoryFn.story.name => StoryFn.storyName +- StoryFn.story.(parameters|decorators) => StoryFn.(parameters|decorators) +See https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#hoisted-csf-annotations for details and codemod. +`; + +export function normalizeStory( + key: string, + storyExport: any, + meta: ComponentMeta +): StoryMeta { + let storyObject = storyExport; + if (typeof storyExport === 'function') { + storyObject = { ...storyExport }; + storyObject.render = storyExport; + } + + if (storyObject.story) { + throw new Error(deprecatedStoryAnnotation); + } + + const exportName = storyNameFromExport(key); + const id = toId(meta.id || meta.title, exportName); + + const { decorators, parameters, args, argTypes, loaders, render, play } = storyObject; + + return { + id, + name: storyObject.name || storyObject.storyName || exportName, + decorators, + parameters: { + ...parameters, + __id: id, + }, + args, + argTypes, + loaders, + render, + play, + }; +} diff --git a/lib/client-api/src/new/processCSFFile.ts b/lib/client-api/src/new/processCSFFile.ts index f7bec508f97..6d82c4d81d1 100644 --- a/lib/client-api/src/new/processCSFFile.ts +++ b/lib/client-api/src/new/processCSFFile.ts @@ -2,8 +2,8 @@ import { isExportStory } from '@storybook/csf'; import { logger } from '@storybook/client-logger'; import { ModuleExports, CSFFile, ComponentMeta, StoryMeta, Path, Parameters } from './types'; -import { autoTitle } from './autoTitle'; // TODO -import { normalizeStory } from './normalizeStory'; // TODO +import { autoTitle } from './autoTitle'; +import { normalizeStory } from './normalizeStory'; const checkGlobals = (parameters: Parameters) => { const { globals, globalTypes } = parameters; diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 5c4281f9d10..76d73c658cd 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -32,7 +32,6 @@ export type GlobalTypes = ArgTypes; export type StoryContextForEnhancers = StoryIdentifier & { parameters: Parameters; - globals: Globals; hooks: HooksContext; initialArgs: Args; argTypes: ArgTypes; @@ -87,9 +86,11 @@ export type WebGlobalMeta = GlobalMeta & { }; export type ComponentTitle = StoryKind; +export type ComponentId = string; type StoryDescriptor = string[] | RegExp; export type ComponentMeta = Meta & { title: ComponentTitle; + id?: ComponentId; // TODO - check these component?: any; diff --git a/lib/client-api/src/new/UrlStore.ts b/lib/core-client/src/preview/new/UrlStore.ts similarity index 60% rename from lib/client-api/src/new/UrlStore.ts rename to lib/core-client/src/preview/new/UrlStore.ts index 2e056f23339..b3484f3c882 100644 --- a/lib/client-api/src/new/UrlStore.ts +++ b/lib/core-client/src/preview/new/UrlStore.ts @@ -1,8 +1,7 @@ -import Events from '@storybook/core-events'; +import { SelectionSpecifier, Selection } from '@storybook/client-api/dist/ts3.9/new/types'; -import { Channel, SelectionSpecifier, Selection } from './types'; // TODO -- this import is wrong -import { getSelectionSpecifierFromPath, setPath } from '../../../core-client/src/preview/url'; +import { getSelectionSpecifierFromPath, setPath } from '../url'; export class UrlStore { selectionSpecifier: SelectionSpecifier; diff --git a/lib/client-api/src/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx similarity index 98% rename from lib/client-api/src/new/WebPreview.tsx rename to lib/core-client/src/preview/new/WebPreview.tsx index 64a9630dd2b..2b0c212e5a2 100644 --- a/lib/client-api/src/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -16,12 +16,13 @@ import { StoryId, Args, DocsContext, -} from './types'; -import { StoryStore } from './StoryStore'; + StorySpecifier, +} from '@storybook/client-api/dist/ts3.9/new/types'; +import { StoryStore } from '@storybook/client-api/dist/ts3.9/new/StoryStore'; + import { UrlStore } from './UrlStore'; import { WebView } from './WebView'; -import { StorySpecifier } from '../types'; -import { NoDocs } from './NoDocs'; +import { NoDocs } from '../NoDocs'; const { navigator, window: globalWindow } = global; diff --git a/lib/client-api/src/new/WebView.ts b/lib/core-client/src/preview/new/WebView.ts similarity index 97% rename from lib/client-api/src/new/WebView.ts rename to lib/core-client/src/preview/new/WebView.ts index 957d7a7d29e..87ad466d45e 100644 --- a/lib/client-api/src/new/WebView.ts +++ b/lib/core-client/src/preview/new/WebView.ts @@ -3,7 +3,7 @@ import { logger } from '@storybook/client-logger'; import AnsiToHtml from 'ansi-to-html'; import dedent from 'ts-dedent'; -import { Story, ViewMode } from './types'; +import { Story } from '@storybook/client-api/dist/ts3.9/new/types'; const { document, FEATURES = {} } = global; From adf5d0ec342290fcfe11c8a0bf43b9c3979e7681 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 30 Jul 2021 14:46:31 +1000 Subject: [PATCH 007/285] Got rendering working --- app/react/preset.js | 7 ++ app/react/src/client/preview/config.tsx | 15 ++++ examples/react-ts/main.ts | 2 + examples/react-ts/src/AccountForm.stories.tsx | 1 + lib/builder-webpack4/src/index.ts | 9 +- lib/builder-webpack4/src/preview/entries.ts | 1 + .../src/preview/iframe-webpack.config.ts | 84 +++++++++---------- lib/client-api/src/new/StoriesListStore.ts | 14 ++-- lib/client-api/src/new/StoryStore.ts | 23 +++-- lib/client-api/src/new/normalizeStory.ts | 7 +- lib/client-api/src/new/prepareStory.ts | 18 ++-- lib/client-api/src/new/types.ts | 12 ++- lib/client-api/src/parameters.ts | 4 +- .../src/preview/new/WebPreview.tsx | 29 +++++-- .../src/preview/new/getGlobalsFromEntries.ts | 38 +++++++++ lib/core-server/src/utils/stories-json.ts | 2 + 16 files changed, 191 insertions(+), 75 deletions(-) create mode 100644 app/react/preset.js create mode 100644 app/react/src/client/preview/config.tsx create mode 100644 lib/core-client/src/preview/new/getGlobalsFromEntries.ts diff --git a/app/react/preset.js b/app/react/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/react/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/react/src/client/preview/config.tsx b/app/react/src/client/preview/config.tsx new file mode 100644 index 00000000000..03e35294214 --- /dev/null +++ b/app/react/src/client/preview/config.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import { Story } from './types-6-3'; +import renderToDOM from './render'; + +export const render: Story = (args, { id, component: Component }) => { + if (!Component) { + throw new Error( + `Unable to render story ${id} as the component annotation is missing from the default export` + ); + } + return ; +}; + +export { renderToDOM }; diff --git a/examples/react-ts/main.ts b/examples/react-ts/main.ts index 20b85cb03b2..8b6b82792e6 100644 --- a/examples/react-ts/main.ts +++ b/examples/react-ts/main.ts @@ -4,6 +4,7 @@ const config: StorybookConfig = { stories: [{ directory: './src', titlePrefix: 'Demo' }], logLevel: 'debug', addons: [ + '@storybook/react', '@storybook/addon-essentials', '@storybook/addon-storysource', '@storybook/addon-storyshots', @@ -21,6 +22,7 @@ const config: StorybookConfig = { features: { postcss: false, previewCsfV3: true, + buildStoriesJson: true, }, }; diff --git a/examples/react-ts/src/AccountForm.stories.tsx b/examples/react-ts/src/AccountForm.stories.tsx index 4cbc7d48faa..3fab54f612f 100644 --- a/examples/react-ts/src/AccountForm.stories.tsx +++ b/examples/react-ts/src/AccountForm.stories.tsx @@ -5,6 +5,7 @@ import userEvent from '@testing-library/user-event'; import { AccountForm, AccountFormProps } from './AccountForm'; export default { + title: 'AccountForm', component: AccountForm, parameters: { layout: 'centered', diff --git a/lib/builder-webpack4/src/index.ts b/lib/builder-webpack4/src/index.ts index b3794a4e718..269e7713759 100644 --- a/lib/builder-webpack4/src/index.ts +++ b/lib/builder-webpack4/src/index.ts @@ -9,6 +9,7 @@ import { useProgressReporting, checkWebpackVersion, Options, + loadPreviewOrConfigFile, normalizeStories, } from '@storybook/core-common'; @@ -32,13 +33,18 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { const { presets } = options; const typescriptOptions = await presets.apply('typescript', {}, options); const babelOptions = await presets.apply('babel', {}, { ...options, typescriptOptions }); - const entries = await presets.apply('entries', [], options); + const entries = await presets.apply('previewEntries', [], options); const stories = normalizeStories(await presets.apply('stories', [], options), { configDir: options.configDir, workingDir: process.cwd(), }); const frameworkOptions = await presets.apply(`${options.framework}Options`, {}, options); + const configs = [ + loadPreviewOrConfigFile(options), + ...(await presets.apply('config', [], options)), + ].filter(Boolean); + return presets.apply( 'webpack', {}, @@ -46,6 +52,7 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { ...options, babelOptions, entries, + configs, stories, typescriptOptions, [`${options.framework}Options`]: frameworkOptions, diff --git a/lib/builder-webpack4/src/preview/entries.ts b/lib/builder-webpack4/src/preview/entries.ts index cfa8984b1a0..a23fc97bd37 100644 --- a/lib/builder-webpack4/src/preview/entries.ts +++ b/lib/builder-webpack4/src/preview/entries.ts @@ -57,6 +57,7 @@ export async function createPreviewEntry(options: { configDir: string; presets: logger.info(`=> Loading ${other.length} other ${noun} in "${configDir}"`); entries.push(...other.map((filename: string) => `${filename}-generated-other-entry.js`)); } + console.log(configs, other, entries); if (stories && stories.length) { entries.push(path.resolve(path.join(configDir, `generated-stories-entry.js`))); diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index d34bda09452..079ecdc94cd 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -13,6 +13,7 @@ import PnpWebpackPlugin from 'pnp-webpack-plugin'; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; // @ts-ignore import FilterWarningsPlugin from 'webpack-filter-warnings-plugin'; +import dedent from 'ts-dedent'; import themingPaths from '@storybook/theming/paths'; @@ -55,6 +56,7 @@ export default async ({ configDir, babelOptions, entries, + configs, stories, outputDir = path.join('.', 'public'), quiet, @@ -77,50 +79,48 @@ export default async ({ const babelLoader = createBabelLoader(babelOptions, framework); const isProd = configType === 'PRODUCTION'; - // TODO FIX ME - does this need to be ESM? - const entryTemplate = await fse.readFile(path.join(__dirname, 'virtualModuleEntry.template.js'), { - encoding: 'utf8', - }); - const storyTemplate = await fse.readFile(path.join(__dirname, 'virtualModuleStory.template.js'), { - encoding: 'utf8', - }); - const frameworkInitEntry = path.resolve( - path.join(configDir, 'storybook-init-framework-entry.js') - ); + const configEntry = path.resolve(path.join(configDir, 'storybook-config-entry.js')); + // Allows for custom frameworks that are not published under the @storybook namespace - const frameworkImportPath = frameworkPath || `@storybook/${framework}`; const virtualModuleMapping = { - // Ensure that the client API is initialized by the framework before any other iframe code - // is loaded. That way our client-apis can assume the existence of the API+store - [frameworkInitEntry]: `import '${frameworkImportPath}';`, + [configEntry]: dedent` + import { getGlobalsFromEntries } from '@storybook/core-client/dist/esm/preview/new/getGlobalsFromEntries'; + import { WebPreview } from '@storybook/core-client/dist/esm/preview/new/WebPreview'; + + ${configs + .map( + (fileName: string, index: number) => + `import * as configModuleExport${index} from "${fileName}";` + ) + .join('\n')} + + // TODO -- non-hardcoded importFn + const importFn = async (path) => import('./src/' + path.replace(/^src\//, '')); + + const getGlobalMeta = () => + getGlobalsFromEntries([ + ${configs + .map((fileName: string, index: number) => `configModuleExport${index}`) + .join(',\n')} + ]); + + window.__STORYBOOK_PREVIEW__ = new WebPreview({ importFn, getGlobalMeta });`, }; - entries.forEach((entryFilename: any) => { - const match = entryFilename.match(/(.*)-generated-(config|other)-entry.js$/); - if (match) { - const configFilename = match[1]; - const clientApi = storybookPaths['@storybook/client-api']; - const clientLogger = storybookPaths['@storybook/client-logger']; - - virtualModuleMapping[entryFilename] = interpolate(entryTemplate, { - configFilename, - clientApi, - clientLogger, - }); - } - }); - if (stories) { - const storiesFilename = path.resolve(path.join(configDir, `generated-stories-entry.js`)); - // Make sure we also replace quotes for this one - virtualModuleMapping[storiesFilename] = interpolate(storyTemplate, { - frameworkImportPath, - }).replace( - "'{{stories}}'", - stories - .map((s: NormalizedStoriesEntry) => s.glob) - .map(toRequireContextString) - .join(',') - ); - } + + console.log(virtualModuleMapping[configEntry]); + // if (stories) { + // const storiesFilename = path.resolve(path.join(configDir, `generated-stories-entry.js`)); + // // Make sure we also replace quotes for this one + // virtualModuleMapping[storiesFilename] = interpolate(storyTemplate, { + // frameworkImportPath, + // }).replace( + // "'{{stories}}'", + // stories + // .map((s: NormalizedStoriesEntry) => s.glob) + // .map(toRequireContextString) + // .join(',') + // ); + // } const shouldCheckTs = useBaseTsSupport(framework) && typescriptOptions.check; const tsCheckOptions = typescriptOptions.checkOptions || {}; @@ -130,7 +130,7 @@ export default async ({ mode: isProd ? 'production' : 'development', bail: isProd, devtool: 'cheap-module-source-map', - entry: entries, + entry: [...entries, configEntry], // stats: 'errors-only', output: { path: path.resolve(process.cwd(), outputDir), diff --git a/lib/client-api/src/new/StoriesListStore.ts b/lib/client-api/src/new/StoriesListStore.ts index e467f113d82..bb00b292749 100644 --- a/lib/client-api/src/new/StoriesListStore.ts +++ b/lib/client-api/src/new/StoriesListStore.ts @@ -6,19 +6,21 @@ import { StoryId, StorySpecifier, Path, StoriesList } from './types'; // const { fetch } = global; export class StoriesListStore { + fetchStoriesList: () => Promise; + storiesList: StoriesList; // TODO -- add a node-channel and watch it - // constructor() {} + constructor({ fetchStoriesList }: { fetchStoriesList: () => Promise }) { + this.fetchStoriesList = fetchStoriesList; + } async initialize() { - return this.fetchStoriesList(); + return this.cacheStoriesList(); } - async fetchStoriesList() { - // TODO -- what is the URL here, how can we get this in a portable way? - // await fetch('/stories.json') - this.storiesList = { v: 1, stories: {} }; + async cacheStoriesList() { + this.storiesList = await this.fetchStoriesList(); } storyIdFromSpecifier(specifier: StorySpecifier) { diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index e18c5ce40e7..cf89358d1ed 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -3,7 +3,16 @@ import { ArgsStore } from './ArgsStore'; import { GlobalsStore } from './GlobalsStore'; import { processCSFFile } from './processCSFFile'; import { prepareStory } from './prepareStory'; -import { Args, CSFFile, StoryId, ModuleImportFn, GlobalMeta, Story, StoryContext } from './types'; +import { + Args, + CSFFile, + StoryId, + ModuleImportFn, + GlobalMeta, + Story, + StoryContext, + StoriesList, +} from './types'; export class StoryStore { storiesList: StoriesListStore; @@ -19,11 +28,13 @@ export class StoryStore { constructor({ importFn, globalMeta, + fetchStoriesList, }: { importFn: ModuleImportFn; globalMeta: GlobalMeta; + fetchStoriesList: () => Promise; }) { - this.storiesList = new StoriesListStore(); + this.storiesList = new StoriesListStore({ fetchStoriesList }); this.importFn = importFn; this.globalMeta = globalMeta; @@ -36,14 +47,14 @@ export class StoryStore { await this.storiesList.initialize(); } - loadCSFFileByStoryId(storyId: StoryId): CSFFile { + async loadCSFFileByStoryId(storyId: StoryId): CSFFile { const path = this.storiesList.storyIdToCSFFilePath(storyId); - const moduleExports = this.importFn(path); + const moduleExports = await this.importFn(path); return processCSFFile({ moduleExports, path }); } - loadStory({ storyId }: { storyId: StoryId }): Story { - const csfFile = this.loadCSFFileByStoryId(storyId); + async loadStory({ storyId }: { storyId: StoryId }): Story { + const csfFile = await this.loadCSFFileByStoryId(storyId); const storyMeta = csfFile.stories[storyId]; if (!storyMeta) { diff --git a/lib/client-api/src/new/normalizeStory.ts b/lib/client-api/src/new/normalizeStory.ts index 2a0318db2b1..6febc87230e 100644 --- a/lib/client-api/src/new/normalizeStory.ts +++ b/lib/client-api/src/new/normalizeStory.ts @@ -32,14 +32,13 @@ export function normalizeStory( const { decorators, parameters, args, argTypes, loaders, render, play } = storyObject; + // TODO back compat for exports.story.X + return { id, name: storyObject.name || storyObject.storyName || exportName, decorators, - parameters: { - ...parameters, - __id: id, - }, + parameters, args, argTypes, loaders, diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts index 3987a7a6e10..315bf82faa5 100644 --- a/lib/client-api/src/new/prepareStory.ts +++ b/lib/client-api/src/new/prepareStory.ts @@ -54,9 +54,9 @@ export function prepareStory( ); const decorators = [ - ...storyMeta.decorators, - ...componentMeta.decorators, - ...globalMeta.decorators, + ...(storyMeta.decorators || []), + ...(componentMeta.decorators || []), + ...(globalMeta.decorators || []), ]; // Currently it is only possible to set these globally @@ -66,7 +66,11 @@ export function prepareStory( argsEnhancers = [], } = globalMeta; - const loaders = [...globalMeta.loaders, ...componentMeta.loaders, ...storyMeta.loaders]; + const loaders = [ + ...(globalMeta.loaders || []), + ...(componentMeta.loaders || []), + ...(storyMeta.loaders || []), + ]; const hooks = new HooksContext(); const cleanup = () => hooks.clean(); @@ -157,7 +161,9 @@ export function prepareStory( ...context, args: validateOptions(mappedArgs, context.argTypes), }; - return context.parameters.passArgsFirst + + const { passArgsFirst: renderTimePassArgsFirst = true } = context.parameters; + return renderTimePassArgsFirst ? (render as ArgsStoryFn)(validatedContext.args, validatedContext) : (render as LegacyStoryFn)(validatedContext); }; @@ -174,6 +180,8 @@ export function prepareStory( return { ...contextForEnhancers, + component: componentMeta.component, + subcomponents: componentMeta.subcomponents, applyLoaders, storyFn, runPlayFunction, diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 76d73c658cd..6ee47eda517 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -55,10 +55,13 @@ export declare type RenderContextWithoutStoryContext = StoryIdentifier & { showException: (err: Error) => void; }; -export type RenderContext = RenderContextWithoutStoryContext & - LoadedStoryContext & { +export type RenderContext = RenderContextWithoutStoryContext & { + // TODO -- this is pretty surprising -- why is this here? + unboundStoryFn: LegacyStoryFn; + storyContext: LoadedStoryContext & { storyFn: LegacyStoryFn; }; +}; export type ArgTypesEnhancer = (context: StoryContextForEnhancers) => ArgTypes; export type ArgsEnhancer = (context: StoryContextForEnhancers) => Args; @@ -92,7 +95,8 @@ export type ComponentMeta = Meta & { title: ComponentTitle; id?: ComponentId; - // TODO - check these + // TODO - should we have a type parameter for these? + // Also TODO -- can you override at the story level? component?: any; subcomponents?: Record; includeStories?: StoryDescriptor; @@ -110,6 +114,8 @@ export type CSFFile = { }; export type Story = StoryIdentifier & { + component?: any; + subcomponents?: Record; parameters: Parameters; initialArgs: Args; argTypes: ArgTypes; diff --git a/lib/client-api/src/parameters.ts b/lib/client-api/src/parameters.ts index 8f3b0010dde..e4639c44968 100644 --- a/lib/client-api/src/parameters.ts +++ b/lib/client-api/src/parameters.ts @@ -8,9 +8,9 @@ import isPlainObject from 'lodash/isPlainObject'; * are plain objects. In this case flag the key as "special" and handle * it with a heuristic. */ -export const combineParameters = (...parameterSets: Parameters[]) => { +export const combineParameters = (...parameterSets: (Parameters | undefined)[]) => { const mergeKeys: Record = {}; - const combined = parameterSets.reduce((acc, p) => { + const combined = parameterSets.filter(Boolean).reduce((acc, p) => { Object.entries(p).forEach(([key, value]) => { const existing = acc[key]; if (Array.isArray(value) || typeof existing === 'undefined') { diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index 2b0c212e5a2..56d55ff70e0 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -2,9 +2,10 @@ import React, { ComponentType } from 'react'; import ReactDOM from 'react-dom'; import Events from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; -import { global } from 'global'; +import global from 'global'; import { addons, Channel } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; +import fetch from 'unfetch'; import { WebGlobalMeta, @@ -12,13 +13,14 @@ import { Selection, Story, RenderContextWithoutStoryContext, + RenderContext, Globals, StoryId, Args, DocsContext, StorySpecifier, } from '@storybook/client-api/dist/ts3.9/new/types'; -import { StoryStore } from '@storybook/client-api/dist/ts3.9/new/StoryStore'; +import { StoryStore } from '@storybook/client-api/dist/esm/new/StoryStore'; import { UrlStore } from './UrlStore'; import { WebView } from './WebView'; @@ -75,9 +77,16 @@ export class WebPreview { return; } + const fetchStoriesList = async () => { + const response = await fetch('/stories.json'); + return response.json(); + }; + this.urlStore = new UrlStore(); - this.storyStore = new StoryStore({ importFn, globalMeta }); + this.storyStore = new StoryStore({ importFn, globalMeta, fetchStoriesList }); this.view = new WebView(); + + this.initialize(); } async initialize() { @@ -200,7 +209,7 @@ export class WebPreview { this.removeStory({ story: previousStory }); } - if (viewModeChanged && this.previousSelection.viewMode === 'docs') { + if (viewModeChanged && this.previousSelection?.viewMode === 'docs') { ReactDOM.unmountComponentAtNode(this.view.docsRoot()); } @@ -285,7 +294,7 @@ export class WebPreview { // but also by the `` docs component async renderStoryToElement({ story, - renderContext, + renderContext: renderContextWithoutStoryContext, element, }: { story: Story; @@ -298,7 +307,15 @@ export class WebPreview { const loadedContext = await applyLoaders(storyContext); - await this.renderToDOM({ ...loadedContext, ...renderContext, storyFn }, element); + const renderContext: RenderContext = { + ...renderContextWithoutStoryContext, + unboundStoryFn: storyFn, + storyContext: { + ...loadedContext, + storyFn: () => storyFn(loadedContext), + }, + }; + await this.renderToDOM(renderContext, element); // TODO -- discuss why not forceRender? and do features better if (global.FEATURES.previewCsfV3 && !renderContext.forceRender) { diff --git a/lib/core-client/src/preview/new/getGlobalsFromEntries.ts b/lib/core-client/src/preview/new/getGlobalsFromEntries.ts new file mode 100644 index 00000000000..cf248a72bce --- /dev/null +++ b/lib/core-client/src/preview/new/getGlobalsFromEntries.ts @@ -0,0 +1,38 @@ +import { ModuleExports, WebGlobalMeta } from '@storybook/client-api/dist/ts3.4/new/types'; +import { combineParameters } from '@storybook/client-api'; + +function getField(moduleExportList: ModuleExports[], field: string): any[] { + return moduleExportList.map((xs) => xs[field]).filter(Boolean); +} + +function getArrayField(moduleExportList: ModuleExports[], field: string): any[] { + return getField(moduleExportList, field).reduce((a, b) => [...a, ...b], []); +} + +function getObjectField(moduleExportList: ModuleExports[], field: string): Record { + return Object.assign({}, ...getField(moduleExportList, field)); +} + +function getSingletonField(moduleExportList: ModuleExports[], field: string): any { + return getField(moduleExportList, field)[0]; +} + +export function getGlobalsFromEntries( + moduleExportList: ModuleExports[] +): WebGlobalMeta { + return { + parameters: combineParameters(...getField(moduleExportList, 'parameters')), + decorators: getArrayField(moduleExportList, 'decorators'), + args: getObjectField(moduleExportList, 'args'), + argsEnhancers: getArrayField(moduleExportList, 'argsEnhancers'), + argTypes: getObjectField(moduleExportList, 'argTypes'), + argTypesEnhancers: getArrayField(moduleExportList, 'argTypesEnhancers'), + globals: getObjectField(moduleExportList, 'globals'), + globalTypes: getObjectField(moduleExportList, 'globalTypes'), + loaders: getArrayField(moduleExportList, 'loaders'), + render: getSingletonField(moduleExportList, 'render'), + play: getSingletonField(moduleExportList, 'play'), + renderToDOM: getSingletonField(moduleExportList, 'renderToDOM'), + applyDecorators: getSingletonField(moduleExportList, 'applyDecorators'), + }; +} diff --git a/lib/core-server/src/utils/stories-json.ts b/lib/core-server/src/utils/stories-json.ts index e32d2363e17..fdec4ffcac0 100644 --- a/lib/core-server/src/utils/stories-json.ts +++ b/lib/core-server/src/utils/stories-json.ts @@ -70,7 +70,9 @@ export async function useStoriesJson(router: any, options: Options) { }); const globs = stories.map((s) => s.glob); extractStoriesJson(storiesJson, globs, options.configDir); + console.log('extracted'); router.use('/stories.json', async (_req: any, res: any) => { + console.log('getting stories.json'); for (let i = 0; i < timeout / step; i += 1) { if (fs.existsSync(storiesJson)) { // eslint-disable-next-line no-await-in-loop From 1c2e7a596df4d176bee69607b6ac2f59f0ecb7f5 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 30 Jul 2021 15:21:55 +1000 Subject: [PATCH 008/285] Working in basic SB mode --- lib/client-api/src/new/StoryStore.ts | 20 +++++++++++++++++++ lib/client-api/src/new/prepareStory.ts | 6 ++++-- .../src/preview/new/WebPreview.tsx | 11 ++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index cf89358d1ed..84ef487f477 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -12,6 +12,7 @@ import { Story, StoryContext, StoriesList, + Parameters, } from './types'; export class StoryStore { @@ -79,4 +80,23 @@ export class StoryStore { globals: this.globals.get(), }; } + + getSetStoriesPayload() { + const { v, stories } = this.storiesList.storiesList; + const kindParameters: Parameters = Object.values(stories).reduce( + (acc: Parameters, { kind }) => { + acc[kind] = {}; + return acc; + }, + {} as Parameters + ); + + return { + v, + globals: this.globals.get(), + globalParameters: {}, + kindParameters, + stories, + }; + } } diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts index 315bf82faa5..44295c52fff 100644 --- a/lib/client-api/src/new/prepareStory.ts +++ b/lib/client-api/src/new/prepareStory.ts @@ -171,9 +171,11 @@ export function prepareStory( // TODO -- fix types const storyFn = applyHooks(applyDecorators)(undecoratedStoryFn, decorators as any); + // TODO -- can you define play functions at other levels? + const { play } = storyMeta; const runPlayFunction = async () => { - if (parameters.play) { - return parameters.play(); + if (play) { + return play(); } return undefined; }; diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index 56d55ff70e0..097396fe5d8 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -19,6 +19,7 @@ import { Args, DocsContext, StorySpecifier, + Parameters, } from '@storybook/client-api/dist/ts3.9/new/types'; import { StoryStore } from '@storybook/client-api/dist/esm/new/StoryStore'; @@ -93,6 +94,9 @@ export class WebPreview { await this.storyStore.initialize(); this.setupListeners(); await this.selectSpecifiedStory(); + + // TODO -- which way round is SET_STORIES/STORY_WAS_SELECTED in 6.3/ + this.channel.emit(Events.SET_STORIES, this.storyStore.getSetStoriesPayload()); } setupListeners() { @@ -115,6 +119,10 @@ export class WebPreview { } this.urlStore.setSelection({ storyId, viewMode }); + this.channel.emit(Events.STORY_SPECIFIED, this.urlStore.selection); + + // TODO -- previously this only emitted if the selection failed. I don't know if we really need it + this.channel.emit(Events.CURRENT_STORY_WAS_SET, this.urlStore.selection); if (globals) { this.storyStore.globals.updateFromPersisted(globals); @@ -317,8 +325,7 @@ export class WebPreview { }; await this.renderToDOM(renderContext, element); - // TODO -- discuss why not forceRender? and do features better - if (global.FEATURES.previewCsfV3 && !renderContext.forceRender) { + if (!renderContext.forceRender) { await runPlayFunction(); } this.channel.emit(Events.STORY_RENDERED, id); From 146af5bf2471989305a69617f785567a521cd4e1 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 1 Aug 2021 12:49:40 +1000 Subject: [PATCH 009/285] Got HMR going again --- lib/builder-webpack4/src/index.ts | 2 +- lib/builder-webpack4/src/presets/preview-preset.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/builder-webpack4/src/index.ts b/lib/builder-webpack4/src/index.ts index 269e7713759..9a96ce359d5 100644 --- a/lib/builder-webpack4/src/index.ts +++ b/lib/builder-webpack4/src/index.ts @@ -33,7 +33,7 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { const { presets } = options; const typescriptOptions = await presets.apply('typescript', {}, options); const babelOptions = await presets.apply('babel', {}, { ...options, typescriptOptions }); - const entries = await presets.apply('previewEntries', [], options); + const entries = await presets.apply('entries', [], options); const stories = normalizeStories(await presets.apply('stories', [], options), { configDir: options.configDir, workingDir: process.cwd(), diff --git a/lib/builder-webpack4/src/presets/preview-preset.ts b/lib/builder-webpack4/src/presets/preview-preset.ts index 1e2d3949220..2a341a446ba 100644 --- a/lib/builder-webpack4/src/presets/preview-preset.ts +++ b/lib/builder-webpack4/src/presets/preview-preset.ts @@ -6,7 +6,7 @@ export const webpack = async (_: any, options: any) => webpackConfig(options); export const entries = async (_: any, options: any) => { let result: string[] = []; - result = result.concat(await createPreviewEntry(options)); + result = result.concat(await options.presets.apply('previewEntries', [], options)); if (options.configType === 'DEVELOPMENT') { // Suppress informational messages when --quiet is specified. webpack-hot-middleware's quiet From f50d88cae931a0c0790bfef15a4c5944cebbbf63 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 1 Aug 2021 12:49:49 +1000 Subject: [PATCH 010/285] Fix argEnhancers --- addons/actions/src/preset/addArgsHelpers.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/actions/src/preset/addArgsHelpers.ts b/addons/actions/src/preset/addArgsHelpers.ts index abe4456d8aa..89117bf5726 100644 --- a/addons/actions/src/preset/addArgsHelpers.ts +++ b/addons/actions/src/preset/addArgsHelpers.ts @@ -14,7 +14,7 @@ import { action } from '../index'; export const inferActionsFromArgTypesRegex: ArgsEnhancer = (context) => { const { - args, + initialArgs, argTypes, parameters: { actions }, } = context; @@ -28,7 +28,7 @@ export const inferActionsFromArgTypesRegex: ArgsEnhancer = (context) => { ); return argTypesMatchingRegex.reduce((acc, [name, argType]) => { - if (typeof args[name] === 'undefined') { + if (typeof initialArgs[name] === 'undefined') { acc[name] = action(name); } return acc; @@ -40,7 +40,7 @@ export const inferActionsFromArgTypesRegex: ArgsEnhancer = (context) => { */ export const addActionsFromArgTypes: ArgsEnhancer = (context) => { const { - args, + initialArgs, argTypes, parameters: { actions }, } = context; @@ -51,7 +51,7 @@ export const addActionsFromArgTypes: ArgsEnhancer = (context) => { const argTypesWithAction = Object.entries(argTypes).filter(([name, argType]) => !!argType.action); return argTypesWithAction.reduce((acc, [name, argType]) => { - if (typeof args[name] === 'undefined') { + if (typeof initialArgs[name] === 'undefined') { acc[name] = action(typeof argType.action === 'string' ? argType.action : name); } return acc; From 923c8ba3347f6aa714a2331587c655b6e5f82fa9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 1 Aug 2021 12:49:53 +1000 Subject: [PATCH 011/285] Type fix --- lib/client-api/src/new/StoryStore.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index 84ef487f477..79e013185d0 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -48,13 +48,13 @@ export class StoryStore { await this.storiesList.initialize(); } - async loadCSFFileByStoryId(storyId: StoryId): CSFFile { + async loadCSFFileByStoryId(storyId: StoryId): Promise> { const path = this.storiesList.storyIdToCSFFilePath(storyId); const moduleExports = await this.importFn(path); return processCSFFile({ moduleExports, path }); } - async loadStory({ storyId }: { storyId: StoryId }): Story { + async loadStory({ storyId }: { storyId: StoryId }): Promise> { const csfFile = await this.loadCSFFileByStoryId(storyId); const storyMeta = csfFile.stories[storyId]; From 6586738d1cea39afa03a99717d9d3c76dc052eff Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 1 Aug 2021 14:25:07 +1000 Subject: [PATCH 012/285] HMR working for story file changes --- .../src/preview/iframe-webpack.config.ts | 35 ++++++++++++++----- lib/client-api/src/new/StoryStore.ts | 18 +++++++--- lib/client-api/src/new/prepareStory.ts | 1 + lib/client-api/src/new/processCSFFile.ts | 12 +++---- .../src/preview/new/WebPreview.tsx | 22 +++++++----- 5 files changed, 60 insertions(+), 28 deletions(-) diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index 079ecdc94cd..a7c516c5a2d 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -79,14 +79,25 @@ export default async ({ const babelLoader = createBabelLoader(babelOptions, framework); const isProd = configType === 'PRODUCTION'; - const configEntry = path.resolve(path.join(configDir, 'storybook-config-entry.js')); + const configEntryPath = path.resolve(path.join(configDir, 'storybook-config-entry.js')); + const storiesFilename = 'storybook-stories.js'; + const storiesPath = path.resolve(path.join(configDir, storiesFilename)); // Allows for custom frameworks that are not published under the @storybook namespace const virtualModuleMapping = { - [configEntry]: dedent` + [storiesPath]: dedent` + // TODO -- non-hardcoded importFn + export const importFn = async (path) => { + console.log('importFn ' + path); + return import('./src/' + path.replace(/^src\//, '')); + }; + `, + [configEntryPath]: dedent` import { getGlobalsFromEntries } from '@storybook/core-client/dist/esm/preview/new/getGlobalsFromEntries'; import { WebPreview } from '@storybook/core-client/dist/esm/preview/new/WebPreview'; + import { importFn } from './${storiesFilename}'; + ${configs .map( (fileName: string, index: number) => @@ -94,9 +105,6 @@ export default async ({ ) .join('\n')} - // TODO -- non-hardcoded importFn - const importFn = async (path) => import('./src/' + path.replace(/^src\//, '')); - const getGlobalMeta = () => getGlobalsFromEntries([ ${configs @@ -104,10 +112,21 @@ export default async ({ .join(',\n')} ]); - window.__STORYBOOK_PREVIEW__ = new WebPreview({ importFn, getGlobalMeta });`, + const preview = new WebPreview({ importFn, getGlobalMeta }); + window.__STORYBOOK_PREVIEW__ = preview; + + if (module.hot) { + module.hot.accept('./${storiesFilename}', () => { + console.log('configEntry HMR accept storybook-stories.js'); + console.log(arguments); + // importFn has changed so we need to patch the new one in + preview.onModuleReload({ importFn }); + }); + } + `, }; - console.log(virtualModuleMapping[configEntry]); + console.log(virtualModuleMapping[configEntryPath]); // if (stories) { // const storiesFilename = path.resolve(path.join(configDir, `generated-stories-entry.js`)); // // Make sure we also replace quotes for this one @@ -130,7 +149,7 @@ export default async ({ mode: isProd ? 'production' : 'development', bail: isProd, devtool: 'cheap-module-source-map', - entry: [...entries, configEntry], + entry: [...entries, configEntryPath], // stats: 'errors-only', output: { path: path.resolve(process.cwd(), outputDir), diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index 79e013185d0..8b068732e4e 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -1,3 +1,5 @@ +import memoize from 'memoizerific'; + import { StoriesListStore } from './StoriesListStore'; import { ArgsStore } from './ArgsStore'; import { GlobalsStore } from './GlobalsStore'; @@ -13,8 +15,17 @@ import { StoryContext, StoriesList, Parameters, + ModuleExports, } from './types'; +// TODO -- what are reasonable values for these? +const CSF_CACHE_SIZE = 100; +const STORY_CACHE_SIZE = 1000; + +// TODO -- are these caches even worth it? how long does it actually take to process/prepare a single story? +const processCSFFileWithCache = memoize(CSF_CACHE_SIZE)(processCSFFile); +const prepareStoryWithCache = memoize(STORY_CACHE_SIZE)(prepareStory); + export class StoryStore { storiesList: StoriesListStore; @@ -51,7 +62,7 @@ export class StoryStore { async loadCSFFileByStoryId(storyId: StoryId): Promise> { const path = this.storiesList.storyIdToCSFFilePath(storyId); const moduleExports = await this.importFn(path); - return processCSFFile({ moduleExports, path }); + return processCSFFileWithCache(moduleExports, path); } async loadStory({ storyId }: { storyId: StoryId }): Promise> { @@ -63,11 +74,8 @@ export class StoryStore { } const componentMeta = csfFile.meta; - const story = prepareStory(storyMeta, componentMeta, this.globalMeta); - - // TODO -- we need some kind of cache at this point. + const story = prepareStoryWithCache(storyMeta, componentMeta, this.globalMeta); - // TODO(HMR) -- figure out when we set this on first run vs HMR this.args.set(storyId, story.initialArgs); return story; diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts index 44295c52fff..38d421cd2d5 100644 --- a/lib/client-api/src/new/prepareStory.ts +++ b/lib/client-api/src/new/prepareStory.ts @@ -40,6 +40,7 @@ export function prepareStory( componentMeta: ComponentMeta, globalMeta: GlobalMeta ): Story { + console.log(`prepareStory ${storyMeta.id}`); // NOTE: in the current implementation we are doing everything once, up front, rather than doing // anything at render time. The assumption is that as we don't load all the stories at once, this // will have a limited cost. If this proves misguided, we can refactor it. diff --git a/lib/client-api/src/new/processCSFFile.ts b/lib/client-api/src/new/processCSFFile.ts index 6d82c4d81d1..29bffc7f9cd 100644 --- a/lib/client-api/src/new/processCSFFile.ts +++ b/lib/client-api/src/new/processCSFFile.ts @@ -32,13 +32,11 @@ const checkDisallowedParameters = (parameters: Parameters) => { }; // Given the raw exports of a CSF file, check and normalize it. -export function processCSFFile({ - moduleExports, - path, -}: { - moduleExports: ModuleExports; - path: Path; -}): CSFFile { +export function processCSFFile( + moduleExports: ModuleExports, + path: Path +): CSFFile { + console.log(`processCSFFile ${path}`); const { default: defaultExport, __namedExportsOrder, ...namedExports } = moduleExports; let exports = namedExports; diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index 097396fe5d8..c900b22d35d 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -58,6 +58,8 @@ export class WebPreview { previousSelection: Selection; + previousStory: Story; + constructor({ getGlobalMeta, importFn, @@ -65,6 +67,7 @@ export class WebPreview { getGlobalMeta: () => WebGlobalMeta; importFn: ModuleImportFn; }) { + console.log('creating WebPreview'); this.channel = getOrCreateChannel(); let globalMeta; @@ -179,6 +182,12 @@ export class WebPreview { this.onUpdateArgs({ storyId, updatedArgs }); } + // This happens when a glob gets HMR-ed + onModuleReload({ importFn }: { importFn: ModuleImportFn }) { + this.storyStore.importFn = importFn; + this.renderSelection({ forceRender: false }); + } + // We can either have: // - a story selected in "story" viewMode, // in which case we render it to the root element, OR @@ -202,19 +211,15 @@ export class WebPreview { this.storyStore.args.updateFromPersisted(story, persistedArgs); } - // We need to: - const storyChanged = this.previousSelection?.storyId !== selection.storyId; const viewModeChanged = this.previousSelection?.viewMode !== selection.viewMode; - // TODO -- think about this. Do we just compare previousStory === story? - const implementationChanged = false; + console.log(story, this.previousStory, story === this.previousStory); + + const implementationChanged = story !== this.previousStory; if (this.previousSelection?.viewMode === 'story' && (storyChanged || viewModeChanged)) { - const previousStory = await this.storyStore.loadStory({ - storyId: this.previousSelection.storyId, - }); - this.removeStory({ story: previousStory }); + this.removeStory({ story: this.previousStory }); } if (viewModeChanged && this.previousSelection?.viewMode === 'docs') { @@ -235,6 +240,7 @@ export class WebPreview { // Record the previous selection *before* awaiting the rendering, in cases things change before it is done. this.previousSelection = selection; + this.previousStory = story; if (selection.viewMode === 'docs') { await this.renderDocs({ story }); From bd3f86a9ea83ef1390cb1368dcce36b529cd6ac1 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 1 Aug 2021 14:37:54 +1000 Subject: [PATCH 013/285] Deal with HMR of config files too. --- .../src/preview/iframe-webpack.config.ts | 9 +++- .../src/preview/new/WebPreview.tsx | 44 +++++++++++++++---- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index a7c516c5a2d..cbdd4c50cc7 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -120,7 +120,14 @@ export default async ({ console.log('configEntry HMR accept storybook-stories.js'); console.log(arguments); // importFn has changed so we need to patch the new one in - preview.onModuleReload({ importFn }); + preview.onImportFnChanged({ importFn }); + }); + + module.hot.accept([${configs.map((fileName: string) => `'${fileName}'`).join(',')}], () => { + console.log('configEntry HMR accept config file'); + console.log(arguments); + // getGlobalMeta has changed so we need to patch the new one in + preview.onGetGlobalMetaChanged({ getGlobalMeta }); }); } `, diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index c900b22d35d..a28a336d389 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -14,6 +14,7 @@ import { Story, RenderContextWithoutStoryContext, RenderContext, + GlobalMeta, Globals, StoryId, Args, @@ -70,14 +71,8 @@ export class WebPreview { console.log('creating WebPreview'); this.channel = getOrCreateChannel(); - let globalMeta; - try { - globalMeta = getGlobalMeta(); - this.renderToDOM = globalMeta.renderToDOM; - } catch (err) { - // This is an error extracting the globalMeta (i.e. evaluating the previewEntries) and - // needs to be show to the user as a simple error - this.renderPreviewEntryError(err); + const globalMeta = this.getGlobalMetaOrRenderError(getGlobalMeta); + if (!globalMeta) { return; } @@ -93,6 +88,22 @@ export class WebPreview { this.initialize(); } + getGlobalMetaOrRenderError( + getGlobalMeta: () => WebGlobalMeta + ): GlobalMeta | undefined { + let globalMeta; + try { + globalMeta = getGlobalMeta(); + this.renderToDOM = globalMeta.renderToDOM; + return globalMeta; + } catch (err) { + // This is an error extracting the globalMeta (i.e. evaluating the previewEntries) and + // needs to be show to the user as a simple error + this.renderPreviewEntryError(err); + return undefined; + } + } + async initialize() { await this.storyStore.initialize(); this.setupListeners(); @@ -183,11 +194,26 @@ export class WebPreview { } // This happens when a glob gets HMR-ed - onModuleReload({ importFn }: { importFn: ModuleImportFn }) { + onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { this.storyStore.importFn = importFn; this.renderSelection({ forceRender: false }); } + // This happens when a config file gets reloade + onGetGlobalMetaChanged({ + getGlobalMeta, + }: { + getGlobalMeta: () => GlobalMeta; + }) { + const globalMeta = this.getGlobalMetaOrRenderError(getGlobalMeta); + if (!globalMeta) { + return; + } + + this.storyStore.globalMeta = globalMeta; + this.renderSelection({ forceRender: false }); + } + // We can either have: // - a story selected in "story" viewMode, // in which case we render it to the root element, OR From 61b6189c6661dc863b05862ff2c0d3d9c949f188 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 1 Aug 2021 16:02:23 +1000 Subject: [PATCH 014/285] Watch a websocket channel in `StoriesList` --- lib/client-api/package.json | 1 + lib/client-api/src/new/StoriesListStore.ts | 31 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/client-api/package.json b/lib/client-api/package.json index b04f48fcbd2..37dbf29513d 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -42,6 +42,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.19", "@storybook/channel-postmessage": "6.4.0-alpha.19", + "@storybook/channel-websocket": "6.4.0-alpha.19", "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", diff --git a/lib/client-api/src/new/StoriesListStore.ts b/lib/client-api/src/new/StoriesListStore.ts index bb00b292749..6591324b53a 100644 --- a/lib/client-api/src/new/StoriesListStore.ts +++ b/lib/client-api/src/new/StoriesListStore.ts @@ -1,24 +1,45 @@ -// import global from 'global'; +import createChannel from '@storybook/channel-websocket'; +import { Channel } from '@storybook/addons'; import { StoryId, StorySpecifier, Path, StoriesList } from './types'; -// TODO -- can we use fetch? how to do this in a portable way? -// const { fetch } = global; - export class StoriesListStore { fetchStoriesList: () => Promise; + channel: Channel; + storiesList: StoriesList; - // TODO -- add a node-channel and watch it constructor({ fetchStoriesList }: { fetchStoriesList: () => Promise }) { this.fetchStoriesList = fetchStoriesList; + + // TODO -- where do we get the URL from? + this.channel = createChannel({ + url: 'ws://localhost:8080', + async: false, + onError: this.onChannelError.bind(this), + }); } async initialize() { + // TODO -- constants + // this.channel.on('INITIALIZE_STORIES', this.onStoriesChanged.bind(this)); + this.channel.on('PATCH_STORIES', this.onStoriesChanged.bind(this)); + this.channel.on('DELETE_STORIES', this.onStoriesChanged.bind(this)); + return this.cacheStoriesList(); } + // TODO -- what to do here? + onChannelError(err: Error) { + console.log(err); + } + + async onStoriesChanged() { + console.log('onStoriesChanged'); + this.storiesList = await this.fetchStoriesList(); + } + async cacheStoriesList() { this.storiesList = await this.fetchStoriesList(); } From 5b6d4b25b94017f4acce20c0b811d034b6f8a162 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 2 Aug 2021 14:59:09 +1000 Subject: [PATCH 015/285] Rename to `composeConfigs` --- lib/builder-webpack4/src/preview/iframe-webpack.config.ts | 4 ++-- .../new/{getGlobalsFromEntries.ts => composeConfigs.ts} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename lib/core-client/src/preview/new/{getGlobalsFromEntries.ts => composeConfigs.ts} (96%) diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index cbdd4c50cc7..c7b75b2c16e 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -93,7 +93,7 @@ export default async ({ }; `, [configEntryPath]: dedent` - import { getGlobalsFromEntries } from '@storybook/core-client/dist/esm/preview/new/getGlobalsFromEntries'; + import { composeConfigs } from '@storybook/core-client/dist/esm/preview/new/composeConfigs'; import { WebPreview } from '@storybook/core-client/dist/esm/preview/new/WebPreview'; import { importFn } from './${storiesFilename}'; @@ -106,7 +106,7 @@ export default async ({ .join('\n')} const getGlobalMeta = () => - getGlobalsFromEntries([ + composeConfigs([ ${configs .map((fileName: string, index: number) => `configModuleExport${index}`) .join(',\n')} diff --git a/lib/core-client/src/preview/new/getGlobalsFromEntries.ts b/lib/core-client/src/preview/new/composeConfigs.ts similarity index 96% rename from lib/core-client/src/preview/new/getGlobalsFromEntries.ts rename to lib/core-client/src/preview/new/composeConfigs.ts index cf248a72bce..8edefe6ee32 100644 --- a/lib/core-client/src/preview/new/getGlobalsFromEntries.ts +++ b/lib/core-client/src/preview/new/composeConfigs.ts @@ -17,7 +17,7 @@ function getSingletonField(moduleExportList: ModuleExports[], field: string): an return getField(moduleExportList, field)[0]; } -export function getGlobalsFromEntries( +export function composeConfigs( moduleExportList: ModuleExports[] ): WebGlobalMeta { return { From bb9f36e9b4b4ae59ff84811f37a25db117d4ea6d Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 3 Aug 2021 21:43:32 +1000 Subject: [PATCH 016/285] Got docs working (first pass) --- addons/docs/src/blocks/ArgsTable.tsx | 59 +++++++++++-------- addons/docs/src/blocks/Canvas.tsx | 2 +- addons/docs/src/blocks/Description.tsx | 3 +- addons/docs/src/blocks/DocsContainer.tsx | 15 +++-- addons/docs/src/blocks/DocsContext.ts | 20 ++----- addons/docs/src/blocks/Meta.tsx | 5 +- addons/docs/src/blocks/Primary.tsx | 5 +- addons/docs/src/blocks/Source.tsx | 42 +++++-------- addons/docs/src/blocks/Stories.tsx | 6 +- addons/docs/src/blocks/Story.tsx | 16 +++-- addons/docs/src/blocks/Subtitle.tsx | 4 +- addons/docs/src/blocks/Title.tsx | 6 +- addons/docs/src/blocks/enhanceSource.ts | 7 ++- addons/docs/src/blocks/mdx.tsx | 2 +- addons/docs/src/blocks/utils.ts | 15 +---- lib/client-api/src/new/StoryStore.ts | 26 ++++++-- lib/client-api/src/new/types.ts | 21 ++++++- .../src/preview/new/WebPreview.tsx | 18 ++++-- 18 files changed, 149 insertions(+), 123 deletions(-) diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index fe8702db042..6c3b877015c 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -16,7 +16,7 @@ import Events from '@storybook/core-events'; import { DocsContext, DocsContextProps } from './DocsContext'; import { Component, CURRENT_SELECTION, PRIMARY_STORY } from './types'; -import { getComponentName, getDocsStories } from './utils'; +import { getComponentName } from './utils'; import { ArgTypesExtractor } from '../lib/docgen/types'; import { lookupStoryId } from './Story'; @@ -75,12 +75,12 @@ const useArgs = ( export const extractComponentArgTypes = ( component: Component, - { parameters }: DocsContextProps, + { id, storyById }: DocsContextProps, include?: PropDescriptor, exclude?: PropDescriptor ): ArgTypes => { - const params = parameters || {}; - const { extractArgTypes }: { extractArgTypes: ArgTypesExtractor } = params.docs || {}; + const { parameters } = storyById(id); + const { extractArgTypes }: { extractArgTypes: ArgTypesExtractor } = parameters.docs || {}; if (!extractArgTypes) { throw new Error(ArgsTableError.ARGS_UNSUPPORTED); } @@ -94,11 +94,13 @@ const isShortcut = (value?: string) => { return value && [CURRENT_SELECTION, PRIMARY_STORY].includes(value); }; -export const getComponent = (props: ArgsTableProps = {}, context: DocsContextProps): Component => { +export const getComponent = ( + props: ArgsTableProps = {}, + { id, storyById }: DocsContextProps +): Component => { const { of } = props as OfProps; const { story } = props as StoryProps; - const { parameters = {} } = context; - const { component } = parameters; + const { component } = storyById(id); if (isShortcut(of) || isShortcut(story)) { return component || null; } @@ -111,7 +113,7 @@ export const getComponent = (props: ArgsTableProps = {}, context: DocsContextPro const addComponentTabs = ( tabs: Record, components: Record, - context: DocsContextProps, + context: DocsContextProps, include?: PropDescriptor, exclude?: PropDescriptor, sort?: SortType @@ -127,39 +129,44 @@ export const StoryTable: FC< StoryProps & { component: Component; subcomponents: Record } > = (props) => { const context = useContext(DocsContext); + const { id: currentId, storyById, componentStories } = context; const { - id: currentId, - parameters: { argTypes }, - storyStore, - } = context; - const { story, component, subcomponents, showComponent, include, exclude, sort } = props; - let storyArgTypes; + story: storyName, + component, + subcomponents, + showComponent, + include, + exclude, + sort, + } = props; + const { argTypes, parameters } = storyById(currentId); + let storyArgTypes: ArgTypes; try { let storyId; - switch (story) { + switch (storyName) { case CURRENT_SELECTION: { storyId = currentId; storyArgTypes = argTypes; break; } case PRIMARY_STORY: { - const primaryStory = getDocsStories(context)[0]; + const primaryStory = componentStories()[0]; storyId = primaryStory.id; - storyArgTypes = primaryStory.parameters.argTypes; + storyArgTypes = primaryStory.argTypes; break; } default: { - storyId = lookupStoryId(story, context); - const data = storyStore.fromId(storyId); - storyArgTypes = data.parameters.argTypes; + storyId = lookupStoryId(storyName, context); + storyArgTypes = storyById(storyId).argTypes; } } storyArgTypes = filterArgTypes(storyArgTypes, include, exclude); const mainLabel = getComponentName(component) || 'Story'; + // TODO -- how to get the current args and channel? // eslint-disable-next-line prefer-const - let [args, updateArgs, resetArgs] = useArgs(storyId, storyStore); + let [args, updateArgs, resetArgs] = [storyById(storyId).initialArgs, () => 0, () => 0]; let tabs = { [mainLabel]: { rows: storyArgTypes, args, updateArgs, resetArgs } } as Record< string, PureArgsTableProps @@ -203,15 +210,19 @@ export const ComponentsTable: FC = (props) => { export const ArgsTable: FC = (props) => { const context = useContext(DocsContext); - const { parameters: { subcomponents, controls } = {} } = context; + const { id, storyById } = context; + const { + parameters: { controls }, + subcomponents, + } = storyById(id); const { include, exclude, components, sort: sortProp } = props as ComponentsProps; - const { story } = props as StoryProps; + const { story: storyName } = props as StoryProps; const sort = sortProp || controls?.sort; const main = getComponent(props, context); - if (story) { + if (storyName) { return ; } diff --git a/addons/docs/src/blocks/Canvas.tsx b/addons/docs/src/blocks/Canvas.tsx index 41deb826d8d..c1271a5bd80 100644 --- a/addons/docs/src/blocks/Canvas.tsx +++ b/addons/docs/src/blocks/Canvas.tsx @@ -19,7 +19,7 @@ type CanvasProps = PurePreviewProps & { const getPreviewProps = ( { withSource, mdxSource, children, ...props }: CanvasProps & { children?: ReactNode }, - docsContext: DocsContextProps, + docsContext: DocsContextProps, sourceContext: SourceContextProps ): PurePreviewProps => { const { mdxComponentMeta, mdxStoryNameToKey } = docsContext; diff --git a/addons/docs/src/blocks/Description.tsx b/addons/docs/src/blocks/Description.tsx index f8bf8e711db..64b6b6c6638 100644 --- a/addons/docs/src/blocks/Description.tsx +++ b/addons/docs/src/blocks/Description.tsx @@ -31,8 +31,9 @@ const noDescription = (component?: Component): string | null => null; export const getDescriptionProps = ( { of, type, markdown, children }: DescriptionProps, - { parameters }: DocsContextProps + { id, storyById }: DocsContextProps ): PureDescriptionProps => { + const { parameters } = storyById(id); if (children || markdown) { return { markdown: children || markdown }; } diff --git a/addons/docs/src/blocks/DocsContainer.tsx b/addons/docs/src/blocks/DocsContainer.tsx index 214090580a4..f82a70e2331 100644 --- a/addons/docs/src/blocks/DocsContainer.tsx +++ b/addons/docs/src/blocks/DocsContainer.tsx @@ -14,8 +14,8 @@ import { scrollToElement } from './utils'; const { document, window: globalWindow } = global; -export interface DocsContainerProps { - context: DocsContextProps; +export interface DocsContainerProps { + context: DocsContextProps; } const defaultComponents = { @@ -34,9 +34,14 @@ const warnOptionsTheme = deprecate( ` ); -export const DocsContainer: FunctionComponent = ({ context, children }) => { - const { id: storyId = null, parameters = {} } = context || {}; - const { options = {}, docs = {} } = parameters; +export const DocsContainer: FunctionComponent> = ({ + context, + children, +}) => { + const { id: storyId, storyById } = context; + const { + parameters: { options = {}, docs = {} }, + } = storyById(storyId); let themeVars = docs.theme; if (!themeVars && options.theme) { warnOptionsTheme(); diff --git a/addons/docs/src/blocks/DocsContext.ts b/addons/docs/src/blocks/DocsContext.ts index 9f66a258855..ade324fde26 100644 --- a/addons/docs/src/blocks/DocsContext.ts +++ b/addons/docs/src/blocks/DocsContext.ts @@ -1,22 +1,9 @@ import { Context, createContext } from 'react'; import { window as globalWindow } from 'global'; -export interface DocsContextProps { - id?: string; - kind?: string; - name?: string; +import { DocsContextProps } from '@storybook/client-api/dist/ts3.9/new/types'; - /** - * mdxStoryNameToKey is an MDX-compiler-generated mapping of an MDX story's - * display name to its story key for ID generation. It's used internally by the `` - * and `Preview` doc blocks. - */ - mdxStoryNameToKey?: Record; - mdxComponentMeta?: any; - parameters?: any; - storyStore?: any; - forceRender?: () => void; -} +export type { DocsContextProps }; // We add DocsContext to window. The reason is that in case DocsContext.ts is // imported multiple times (maybe once directly, and another time from a minified bundle) @@ -29,4 +16,5 @@ if (globalWindow.__DOCS_CONTEXT__ === undefined) { globalWindow.__DOCS_CONTEXT__.displayName = 'DocsContext'; } -export const DocsContext: Context = globalWindow.__DOCS_CONTEXT__; +// TODO -- how to parameterize this by +export const DocsContext: Context> = globalWindow.__DOCS_CONTEXT__; diff --git a/addons/docs/src/blocks/Meta.tsx b/addons/docs/src/blocks/Meta.tsx index 5fd193e5df2..48390923b06 100644 --- a/addons/docs/src/blocks/Meta.tsx +++ b/addons/docs/src/blocks/Meta.tsx @@ -3,15 +3,14 @@ import global from 'global'; import { Args, BaseAnnotations, BaseMeta } from '@storybook/addons'; import { Anchor } from './Anchor'; import { DocsContext, DocsContextProps } from './DocsContext'; -import { getDocsStories } from './utils'; import { Component } from './types'; const { document } = global; type MetaProps = BaseMeta & BaseAnnotations; -function getFirstStoryId(docsContext: DocsContextProps): string { - const stories = getDocsStories(docsContext); +function getFirstStoryId(docsContext: DocsContextProps): string { + const stories = docsContext.componentStories(); return stories.length > 0 ? stories[0].id : null; } diff --git a/addons/docs/src/blocks/Primary.tsx b/addons/docs/src/blocks/Primary.tsx index 242e1779487..7e87f21cacc 100644 --- a/addons/docs/src/blocks/Primary.tsx +++ b/addons/docs/src/blocks/Primary.tsx @@ -1,15 +1,14 @@ import React, { useContext, FC } from 'react'; import { DocsContext } from './DocsContext'; import { DocsStory } from './DocsStory'; -import { getDocsStories } from './utils'; interface PrimaryProps { name?: string; } export const Primary: FC = ({ name }) => { - const context = useContext(DocsContext); - const componentStories = getDocsStories(context); + const { componentStories: getComponentStories } = useContext(DocsContext); + const componentStories = getComponentStories(); let story; if (componentStories) { story = name ? componentStories.find((s) => s.name === name) : componentStories[0]; diff --git a/addons/docs/src/blocks/Source.tsx b/addons/docs/src/blocks/Source.tsx index 4777d11072e..1b0c3aabe6d 100644 --- a/addons/docs/src/blocks/Source.tsx +++ b/addons/docs/src/blocks/Source.tsx @@ -7,6 +7,7 @@ import { import { StoryId } from '@storybook/api'; import { logger } from '@storybook/client-logger'; import { StoryContext } from '@storybook/addons'; +import { Story } from '@storybook/client-api/dist/ts3.9/new/types'; import { DocsContext, DocsContextProps } from './DocsContext'; import { SourceContext, SourceContextProps } from './SourceContainer'; @@ -43,25 +44,11 @@ type NoneProps = CommonProps; type SourceProps = SingleSourceProps | MultiSourceProps | CodeProps | NoneProps; -const getStoryContext = (storyId: StoryId, docsContext: DocsContextProps): StoryContext | null => { - const { storyStore } = docsContext; - const storyContext = storyStore?.fromId(storyId); - - if (!storyContext) { - // Fallback if we can't get the story data for this story - logger.warn(`Unable to find information for story ID '${storyId}'`); - return null; - } - - return storyContext; -}; - -const getSourceState = (storyIds: string[], docsContext: DocsContextProps) => { +const getSourceState = (storyIds: string[], docsContext: DocsContextProps) => { const states = storyIds .map((storyId) => { - const storyContext = getStoryContext(storyId, docsContext); - if (!storyContext) return null; - return storyContext.parameters.docs?.source?.state; + const story = docsContext.storyById(storyId); + return story.parameters.docs?.source?.state; }) .filter(Boolean); @@ -77,12 +64,12 @@ const getStorySource = (storyId: StoryId, sourceContext: SourceContextProps): st return sources?.[storyId] || ''; }; -const getSnippet = (snippet: string, storyContext?: StoryContext): string => { - if (!storyContext) { +const getSnippet = (snippet: string, story?: Story): string => { + if (!story) { return snippet; } - const { parameters } = storyContext; + const { parameters } = story; // eslint-disable-next-line no-underscore-dangle const isArgsStory = parameters.__isArgsStory; const type = parameters.docs?.source?.type || SourceType.AUTO; @@ -95,16 +82,16 @@ const getSnippet = (snippet: string, storyContext?: StoryContext): string => { // if user has explicitly set this as dynamic, use snippet if (type === SourceType.DYNAMIC) { - return parameters.docs?.transformSource?.(snippet, storyContext) || snippet; + return parameters.docs?.transformSource?.(snippet, story) || snippet; } // if this is an args story and there's a snippet if (type === SourceType.AUTO && snippet && isArgsStory) { - return parameters.docs?.transformSource?.(snippet, storyContext) || snippet; + return parameters.docs?.transformSource?.(snippet, story) || snippet; } // otherwise, use the source code logic - const enhanced = enhanceSource(storyContext) || parameters; + const enhanced = enhanceSource(story) || parameters; return enhanced?.docs?.source?.code || ''; }; @@ -112,10 +99,11 @@ type SourceStateProps = { state: SourceState }; export const getSourceProps = ( props: SourceProps, - docsContext: DocsContextProps, + docsContext: DocsContextProps, sourceContext: SourceContextProps ): PureSourceProps & SourceStateProps => { - const { id: currentId, parameters = {} } = docsContext; + const { id: currentId, storyById } = docsContext; + const { parameters } = storyById(currentId); const codeProps = props as CodeProps; const singleProps = props as SingleSourceProps; @@ -131,8 +119,8 @@ export const getSourceProps = ( source = targetIds .map((storyId) => { const storySource = getStorySource(storyId, sourceContext); - const storyContext = getStoryContext(storyId, docsContext); - return getSnippet(storySource, storyContext); + const story = docsContext.storyById(storyId); + return getSnippet(storySource, story); }) .join('\n\n'); } diff --git a/addons/docs/src/blocks/Stories.tsx b/addons/docs/src/blocks/Stories.tsx index afb7de3e8ad..9d460a5cd83 100644 --- a/addons/docs/src/blocks/Stories.tsx +++ b/addons/docs/src/blocks/Stories.tsx @@ -2,7 +2,6 @@ import React, { useContext, FunctionComponent } from 'react'; import { DocsContext } from './DocsContext'; import { DocsStory } from './DocsStory'; import { Heading } from './Heading'; -import { getDocsStories } from './utils'; import { DocsStoryProps } from './types'; interface StoriesProps { @@ -11,10 +10,9 @@ interface StoriesProps { } export const Stories: FunctionComponent = ({ title, includePrimary = false }) => { - const context = useContext(DocsContext); - const componentStories = getDocsStories(context); + const { componentStories } = useContext(DocsContext); - let stories: DocsStoryProps[] = componentStories; + let stories: DocsStoryProps[] = componentStories(); if (!includePrimary) stories = stories.slice(1); if (!stories || stories.length === 0) { diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 6e239f072ca..323feee337d 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -34,22 +34,25 @@ export type StoryProps = (StoryDefProps | StoryRefProps | StoryImportProps) & Co export const lookupStoryId = ( storyName: string, - { mdxStoryNameToKey, mdxComponentMeta }: DocsContextProps + { mdxStoryNameToKey, mdxComponentMeta }: DocsContextProps ) => toId( mdxComponentMeta.id || mdxComponentMeta.title, storyNameFromExport(mdxStoryNameToKey[storyName]) ); -export const getStoryProps = (props: StoryProps, context: DocsContextProps): PureStoryProps => { +export const getStoryProps = ( + props: StoryProps, + context: DocsContextProps +): PureStoryProps => { const { id } = props as StoryRefProps; const { name } = props as StoryDefProps; const inputId = id === CURRENT_SELECTION ? context.id : id; const previewId = inputId || lookupStoryId(name, context); - const data = context.storyStore.fromId(previewId) || {}; + const story = context.storyById(previewId); const { height, inline } = props; - const { storyFn = undefined, name: storyName = undefined, parameters = {} } = data; + const { storyFn, name: storyName, parameters } = story; const { docs = {} } = parameters; if (docs.disable) { @@ -65,11 +68,14 @@ export const getStoryProps = (props: StoryProps, context: DocsContextProps): Pur ); } + const boundStoryFn = context.bindStoryFn(story); return { parameters, inline: storyIsInline, id: previewId, - storyFn: prepareForInline && storyFn ? () => prepareForInline(storyFn, data) : storyFn, + // TODO -- how can `storyFn` be undefined? + storyFn: + prepareForInline && boundStoryFn ? () => prepareForInline(boundStoryFn, story) : boundStoryFn, height: height || (storyIsInline ? undefined : iframeHeight), title: storyName, }; diff --git a/addons/docs/src/blocks/Subtitle.tsx b/addons/docs/src/blocks/Subtitle.tsx index 3fb44a8af5a..64e160176dd 100644 --- a/addons/docs/src/blocks/Subtitle.tsx +++ b/addons/docs/src/blocks/Subtitle.tsx @@ -7,8 +7,8 @@ interface SubtitleProps { } export const Subtitle: FunctionComponent = ({ children }) => { - const context = useContext(DocsContext); - const { parameters } = context; + const { id, storyById } = useContext(DocsContext); + const { parameters } = storyById(id); let text: JSX.Element | string = children; if (!text) { text = parameters?.componentSubtitle; diff --git a/addons/docs/src/blocks/Title.tsx b/addons/docs/src/blocks/Title.tsx index 052f0dbe904..a815a189486 100644 --- a/addons/docs/src/blocks/Title.tsx +++ b/addons/docs/src/blocks/Title.tsx @@ -8,9 +8,9 @@ interface TitleProps { const STORY_KIND_PATH_SEPARATOR = /\s*\/\s*/; -export const extractTitle = ({ kind }: DocsContextProps) => { - const groups = kind.trim().split(STORY_KIND_PATH_SEPARATOR); - return (groups && groups[groups.length - 1]) || kind; +export const extractTitle = ({ title }: DocsContextProps) => { + const groups = title.trim().split(STORY_KIND_PATH_SEPARATOR); + return (groups && groups[groups.length - 1]) || title; }; export const Title: FunctionComponent = ({ children }) => { diff --git a/addons/docs/src/blocks/enhanceSource.ts b/addons/docs/src/blocks/enhanceSource.ts index 42a87ca906a..4066b31f1da 100644 --- a/addons/docs/src/blocks/enhanceSource.ts +++ b/addons/docs/src/blocks/enhanceSource.ts @@ -1,5 +1,6 @@ import { combineParameters } from '@storybook/client-api'; import { StoryContext, Parameters } from '@storybook/addons'; +import { Story } from '@storybook/client-api/dist/ts3.9/new/types'; // ============================================================ // START @storybook/source-loader/extract-source @@ -76,8 +77,8 @@ const extract = (targetId: string, { source, locationsMap }: StorySource) => { return extractSource(location, lines); }; -export const enhanceSource = (context: StoryContext): Parameters => { - const { id, parameters } = context; +export const enhanceSource = (story: Story): Parameters => { + const { id, parameters } = story; const { storySource, docs = {} } = parameters; const { transformSource } = docs; @@ -87,7 +88,7 @@ export const enhanceSource = (context: StoryContext): Parameters => { } const input = extract(id, storySource); - const code = transformSource ? transformSource(input, context) : input; + const code = transformSource ? transformSource(input, story) : input; return { docs: combineParameters(docs, { source: { code } }) }; }; diff --git a/addons/docs/src/blocks/mdx.tsx b/addons/docs/src/blocks/mdx.tsx index 3dbc6746ee9..59566c72930 100644 --- a/addons/docs/src/blocks/mdx.tsx +++ b/addons/docs/src/blocks/mdx.tsx @@ -17,7 +17,7 @@ export const assertIsFn = (val: any) => { }; // Hacky utility for adding mdxStoryToId to the default context -export const AddContext: FC = (props) => { +export const AddContext: FC> = (props) => { const { children, ...rest } = props; const parentContext = React.useContext(DocsContext); return ( diff --git a/addons/docs/src/blocks/utils.ts b/addons/docs/src/blocks/utils.ts index 036925af27e..75395913774 100644 --- a/addons/docs/src/blocks/utils.ts +++ b/addons/docs/src/blocks/utils.ts @@ -1,18 +1,5 @@ /* eslint-disable no-underscore-dangle */ -import { DocsContextProps } from './DocsContext'; -import { StoryData, Component } from './types'; - -export const getDocsStories = (context: DocsContextProps): StoryData[] => { - const { storyStore, kind } = context; - - if (!storyStore) { - return []; - } - - return storyStore - .getStoriesForKind(kind) - .filter((s: any) => !(s.parameters && s.parameters.docs && s.parameters.docs.disable)); -}; +import { Component } from './types'; const titleCase = (str: string): string => str diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index 8b068732e4e..607d50c3cd2 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -6,16 +6,15 @@ import { GlobalsStore } from './GlobalsStore'; import { processCSFFile } from './processCSFFile'; import { prepareStory } from './prepareStory'; import { - Args, CSFFile, StoryId, ModuleImportFn, GlobalMeta, + StoryMeta, Story, StoryContext, StoriesList, Parameters, - ModuleExports, } from './types'; // TODO -- what are reasonable values for these? @@ -67,7 +66,16 @@ export class StoryStore { async loadStory({ storyId }: { storyId: StoryId }): Promise> { const csfFile = await this.loadCSFFileByStoryId(storyId); + return this.storyFromCSFFile({ storyId, csfFile }); + } + storyFromCSFFile({ + storyId, + csfFile, + }: { + storyId: StoryId; + csfFile: CSFFile; + }): Story { const storyMeta = csfFile.stories[storyId]; if (!storyMeta) { throw new Error(`Didn't find '${storyId}' in CSF file, this is unexpected`); @@ -75,12 +83,20 @@ export class StoryStore { const componentMeta = csfFile.meta; const story = prepareStoryWithCache(storyMeta, componentMeta, this.globalMeta); - - this.args.set(storyId, story.initialArgs); - + this.args.set(story.id, story.initialArgs); return story; } + componentStoriesFromCSFFile({ + csfFile, + }: { + csfFile: CSFFile; + }): Story[] { + return Object.keys(csfFile.stories).map((storyId: StoryId) => + this.storyFromCSFFile({ storyId, csfFile }) + ); + } + getStoryContext(story: Story): StoryContext { return { ...story, diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 6ee47eda517..615981c2ad5 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -164,5 +164,22 @@ export type DecoratorApplicator = ( decorators: DecoratorFunction[] ) => LegacyStoryFn; -// TODO -export type DocsContext = any; +export interface DocsContextProps { + id: string; + title: string; + name: string; + storyById: (id: StoryId) => Story; + componentStories: () => Story[]; + renderStoryToElement: (story: Story) => void; + + // TODO -- we need this for the `prepareForInline` docs approach + bindStoryFn: (story: Story) => LegacyStoryFn; + + /** + * mdxStoryNameToKey is an MDX-compiler-generated mapping of an MDX story's + * display name to its story key for ID generation. It's used internally by the `` + * and `Preview` doc blocks. + */ + mdxStoryNameToKey?: Record; + mdxComponentMeta?: any; +} diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index a28a336d389..4b9c37aa578 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -18,9 +18,10 @@ import { Globals, StoryId, Args, - DocsContext, + DocsContextProps, StorySpecifier, Parameters, + CSFFile, } from '@storybook/client-api/dist/ts3.9/new/types'; import { StoryStore } from '@storybook/client-api/dist/esm/new/StoryStore'; @@ -28,7 +29,7 @@ import { UrlStore } from './UrlStore'; import { WebView } from './WebView'; import { NoDocs } from '../NoDocs'; -const { navigator, window: globalWindow } = global; +const { window: globalWindow } = global; // TODO -- what's up with this code? Is it for HMR? Can we be smarter? function getOrCreateChannel() { @@ -278,12 +279,21 @@ export class WebPreview { async renderDocs({ story }: { story: Story }) { const { id, title, name } = story; const element = this.view.prepareForDocs(); + const csfFile: CSFFile = await this.storyStore.loadCSFFileByStoryId(id); const docsContext = { id, title, name, - storyStore: this.storyStore, + // NOTE: these two functions are *sync* so cannot access stories from other CSF files + storyById: (storyId: StoryId) => this.storyStore.storyFromCSFFile({ storyId, csfFile }), + componentStories: () => this.storyStore.componentStoriesFromCSFFile({ csfFile }), renderStoryToElement: this.renderStoryToElement.bind(this), + + // TODO -- this is for prepareForInline. Note this *DOES NOT* run loaders, + // or play, or any of the stuff that `renderStoryToElement` below does. + // If we want to stick with this approach, we should refactor to share code. + bindStoryFn: (renderedStory: Story) => () => + renderedStory.storyFn(this.storyStore.getStoryContext(renderedStory)), }; const { docs } = story.parameters; @@ -291,7 +301,7 @@ export class WebPreview { throw new Error('No `docs.container` set, did you run `addon-docs/preset`?'); } - const DocsContainer: ComponentType<{ context: DocsContext }> = + const DocsContainer: ComponentType<{ context: DocsContextProps }> = docs.container || (({ children }: { children: Element }) => <>{children}); const Page: ComponentType = docs.page || NoDocs; From 3c180e927c567746628d78cb54c5a2073b0a0c50 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 3 Aug 2021 21:44:03 +1000 Subject: [PATCH 017/285] Need to export framework parameter --- app/react/src/client/preview/config.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/react/src/client/preview/config.tsx b/app/react/src/client/preview/config.tsx index 03e35294214..cc92571a601 100644 --- a/app/react/src/client/preview/config.tsx +++ b/app/react/src/client/preview/config.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { Story } from './types-6-3'; +import { Story, Parameters } from './types-6-3'; import renderToDOM from './render'; export const render: Story = (args, { id, component: Component }) => { @@ -13,3 +13,5 @@ export const render: Story = (args, { id, component: Component }) => { }; export { renderToDOM }; + +export const parameters: Parameters = { framework: 'react' }; From 0775c4d3124a4e5205c57c72949f233655539ef0 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 4 Aug 2021 16:00:44 +1000 Subject: [PATCH 018/285] Move hooks out of the Story type --- lib/client-api/src/new/StoryStore.ts | 6 ++++++ lib/client-api/src/new/prepareStory.ts | 3 --- lib/client-api/src/new/types.ts | 4 +--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index 607d50c3cd2..998d7dc43b8 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -16,6 +16,7 @@ import { StoriesList, Parameters, } from './types'; +import { HooksContext } from '../hooks'; // TODO -- what are reasonable values for these? const CSF_CACHE_SIZE = 100; @@ -36,6 +37,8 @@ export class StoryStore { args: ArgsStore; + hooks: Record; + constructor({ importFn, globalMeta, @@ -52,6 +55,7 @@ export class StoryStore { const { globals, globalTypes } = globalMeta; this.globals = new GlobalsStore({ globals, globalTypes }); this.args = new ArgsStore(); + this.hooks = {}; } async initialize() { @@ -84,6 +88,7 @@ export class StoryStore { const story = prepareStoryWithCache(storyMeta, componentMeta, this.globalMeta); this.args.set(story.id, story.initialArgs); + this.hooks[story.id] = new HooksContext(); return story; } @@ -102,6 +107,7 @@ export class StoryStore { ...story, args: this.args.get(story.id), globals: this.globals.get(), + hooks: this.hooks[story.id], }; } diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts index 38d421cd2d5..4fc92af1c44 100644 --- a/lib/client-api/src/new/prepareStory.ts +++ b/lib/client-api/src/new/prepareStory.ts @@ -12,8 +12,6 @@ import { Story, Args, ArgTypes, - ArgsEnhancer, - ArgTypesEnhancer, StoryContextForEnhancers, } from './types'; @@ -117,7 +115,6 @@ export function prepareStory( title, kind: title, // Back compat parameters, - hooks, initialArgs: initialArgsBeforeEnhancers, argTypes: passedArgTypes, }; diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 615981c2ad5..74c9f1d61f4 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -10,7 +10,6 @@ import { StoryName, ViewMode, LegacyStoryFn, - StoryFn, } from '@storybook/addons'; import { HooksContext } from '../hooks'; @@ -32,7 +31,6 @@ export type GlobalTypes = ArgTypes; export type StoryContextForEnhancers = StoryIdentifier & { parameters: Parameters; - hooks: HooksContext; initialArgs: Args; argTypes: ArgTypes; }; @@ -40,6 +38,7 @@ export type StoryContextForEnhancers = StoryIdentifier & { export type StoryContextUpdate = { args: Args; globals: Globals; + hooks: HooksContext; }; export type StoryContext = StoryContextForEnhancers & StoryContextUpdate; @@ -119,7 +118,6 @@ export type Story = StoryIdentifier & { parameters: Parameters; initialArgs: Args; argTypes: ArgTypes; - hooks: HooksContext; applyLoaders: (context: StoryContext) => Promise; storyFn: LegacyStoryFn; runPlayFunction: () => Promise; // TODO -- should this take story context? From ae3174ab2f62bc96f95b74058885770b063ea05e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 4 Aug 2021 16:03:19 +1000 Subject: [PATCH 019/285] Fix not showing story when switching from docs=>canvas --- lib/core-client/src/preview/new/WebPreview.tsx | 2 -- lib/core-client/src/preview/new/WebView.ts | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index 4b9c37aa578..bae1294e8e6 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -241,8 +241,6 @@ export class WebPreview { const storyChanged = this.previousSelection?.storyId !== selection.storyId; const viewModeChanged = this.previousSelection?.viewMode !== selection.viewMode; - console.log(story, this.previousStory, story === this.previousStory); - const implementationChanged = story !== this.previousStory; if (this.previousSelection?.viewMode === 'story' && (storyChanged || viewModeChanged)) { diff --git a/lib/core-client/src/preview/new/WebView.ts b/lib/core-client/src/preview/new/WebView.ts index 87ad466d45e..2058b51d69d 100644 --- a/lib/core-client/src/preview/new/WebView.ts +++ b/lib/core-client/src/preview/new/WebView.ts @@ -29,6 +29,7 @@ export class WebView { // Get ready to render a story, returning the element to render to prepareForStory(story: Story, forceRender: boolean) { + this.showStory(); this.applyLayout(story.parameters.layout); if (!forceRender) { From ee341ec5d2d2c9d317e24a73bf6e91af398c97bb Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 4 Aug 2021 16:50:44 +1000 Subject: [PATCH 020/285] Add default argTypesEnhancers to presets --- addons/controls/package.json | 2 + addons/controls/preset.js | 6 +- addons/controls/src/inferControls.ts | 78 +++++++++++++++++++ .../src/frameworks/common/enhanceArgTypes.ts | 6 +- lib/client-api/src/inferArgTypes.ts | 7 +- lib/core-server/src/presets/common-preset.ts | 3 + lib/core-server/src/presets/inferArgTypes.ts | 3 + 7 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 addons/controls/src/inferControls.ts create mode 100644 lib/core-server/src/presets/inferArgTypes.ts diff --git a/addons/controls/package.json b/addons/controls/package.json index 9c2f176974b..5cf46f86c3a 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -48,10 +48,12 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/api": "6.4.0-alpha.19", "@storybook/client-api": "6.4.0-alpha.19", + "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", + "lodash": "^4.17.20", "ts-dedent": "^2.0.0" }, "peerDependencies": { diff --git a/addons/controls/preset.js b/addons/controls/preset.js index 1fac913bc69..dd5a388d5eb 100644 --- a/addons/controls/preset.js +++ b/addons/controls/preset.js @@ -5,4 +5,8 @@ function managerEntries(entry = [], options) { return [...entry, require.resolve('./dist/esm/register')]; } -module.exports = { managerEntries }; +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/inferControls')]; +} + +module.exports = { managerEntries, config }; diff --git a/addons/controls/src/inferControls.ts b/addons/controls/src/inferControls.ts new file mode 100644 index 00000000000..e27e1c64b08 --- /dev/null +++ b/addons/controls/src/inferControls.ts @@ -0,0 +1,78 @@ +import mapValues from 'lodash/mapValues'; +import { ArgType } from '@storybook/addons'; +import { logger } from '@storybook/client-logger'; + +import { + SBEnumType, + ArgTypesEnhancer, + filterArgTypes, + combineParameters, +} from '@storybook/client-api'; + +type ControlsMatchers = { + date: RegExp; + color: RegExp; +}; + +const inferControl = (argType: ArgType, name: string, matchers: ControlsMatchers): any => { + const { type, options } = argType; + if (!type && !options) { + return undefined; + } + + // args that end with background or color e.g. iconColor + if (matchers.color && matchers.color.test(name)) { + const controlType = argType.type.name; + + if (controlType === 'string') { + return { control: { type: 'color' } }; + } + + logger.warn( + `Addon controls: Control of type color only supports string, received "${controlType}" instead` + ); + } + + // args that end with date e.g. purchaseDate + if (matchers.date && matchers.date.test(name)) { + return { control: { type: 'date' } }; + } + + switch (type.name) { + case 'array': + return { control: { type: 'object' } }; + case 'boolean': + return { control: { type: 'boolean' } }; + case 'string': + return { control: { type: 'text' } }; + case 'number': + return { control: { type: 'number' } }; + case 'enum': { + const { value } = type as SBEnumType; + return { control: { type: value?.length <= 5 ? 'radio' : 'select' }, options: value }; + } + case 'function': + case 'symbol': + case 'void': + return null; + default: + return { control: { type: options ? 'select' : 'object' } }; + } +}; + +const inferControls: ArgTypesEnhancer = (context) => { + const { + argTypes, + parameters: { __isArgsStory, controls: { include = null, exclude = null, matchers = {} } = {} }, + } = context; + if (!__isArgsStory) return argTypes; + + const filteredArgTypes = filterArgTypes(argTypes, include, exclude); + const withControls = mapValues(filteredArgTypes, (argType, name) => { + return argType?.type && inferControl(argType, name, matchers); + }); + + return combineParameters(withControls, filteredArgTypes); +}; + +export const argTypesEnhancers = [inferControls]; diff --git a/addons/docs/src/frameworks/common/enhanceArgTypes.ts b/addons/docs/src/frameworks/common/enhanceArgTypes.ts index f1ee242400e..b1bf93e7501 100644 --- a/addons/docs/src/frameworks/common/enhanceArgTypes.ts +++ b/addons/docs/src/frameworks/common/enhanceArgTypes.ts @@ -3,7 +3,11 @@ import { ArgTypesEnhancer, combineParameters } from '@storybook/client-api'; import { normalizeArgTypes } from './normalizeArgTypes'; export const enhanceArgTypes: ArgTypesEnhancer = (context) => { - const { component, argTypes: userArgTypes = {}, docs = {} } = context.parameters; + const { + component, + argTypes: userArgTypes, + parameters: { docs = {} }, + } = context; const { extractArgTypes } = docs; const normalizedArgTypes = normalizeArgTypes(userArgTypes); diff --git a/lib/client-api/src/inferArgTypes.ts b/lib/client-api/src/inferArgTypes.ts index ed2a3b1cacf..cf532333cb0 100644 --- a/lib/client-api/src/inferArgTypes.ts +++ b/lib/client-api/src/inferArgTypes.ts @@ -41,10 +41,9 @@ const inferType = (value: any, name: string, visited: Set): SBType => { }; export const inferArgTypes: ArgTypesEnhancer = (context) => { - const { id, parameters } = context; - const { argTypes: userArgTypes = {}, args = {} } = parameters; - if (!args) return userArgTypes; - const argTypes = mapValues(args, (arg, key) => ({ + const { id, argTypes: userArgTypes = {}, initialArgs = {} } = context; + if (!initialArgs) return userArgTypes; + const argTypes = mapValues(initialArgs, (arg, key) => ({ type: inferType(arg, `${id}.${key}`, new Set()), })); return combineParameters(argTypes, userArgTypes); diff --git a/lib/core-server/src/presets/common-preset.ts b/lib/core-server/src/presets/common-preset.ts index 4382b106b6a..ea186af808c 100644 --- a/lib/core-server/src/presets/common-preset.ts +++ b/lib/core-server/src/presets/common-preset.ts @@ -62,3 +62,6 @@ export const features = async (existing: Record) => ({ ...existing, postcss: true, }); + +// TODO -- this feels like it should live in core-client or client-api +export const config = (entry: string[] = []) => [...entry, require.resolve('./inferArgTypes')]; diff --git a/lib/core-server/src/presets/inferArgTypes.ts b/lib/core-server/src/presets/inferArgTypes.ts new file mode 100644 index 00000000000..e24fffd9b97 --- /dev/null +++ b/lib/core-server/src/presets/inferArgTypes.ts @@ -0,0 +1,3 @@ +import { inferArgTypes } from '@storybook/client-api/dist/esm/inferArgTypes'; + +export const argTypesEnhancers = [inferArgTypes]; From 95d3fed76fb779683b00dbb2a2dd8cc19aa8c57e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 4 Aug 2021 16:53:49 +1000 Subject: [PATCH 021/285] Ensure that `ensureControls` runs in the second pass --- addons/controls/src/inferControls.ts | 2 ++ lib/client-api/src/new/types.ts | 6 +++++- lib/client-api/src/types.ts | 6 +++++- lib/core-client/src/preview/new/composeConfigs.ts | 7 ++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/addons/controls/src/inferControls.ts b/addons/controls/src/inferControls.ts index e27e1c64b08..6e324e938d7 100644 --- a/addons/controls/src/inferControls.ts +++ b/addons/controls/src/inferControls.ts @@ -75,4 +75,6 @@ const inferControls: ArgTypesEnhancer = (context) => { return combineParameters(withControls, filteredArgTypes); }; +inferControls.secondPass = true; + export const argTypesEnhancers = [inferControls]; diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 74c9f1d61f4..b815b8cf971 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -63,7 +63,11 @@ export type RenderContext = RenderContextWithoutStoryContext }; export type ArgTypesEnhancer = (context: StoryContextForEnhancers) => ArgTypes; -export type ArgsEnhancer = (context: StoryContextForEnhancers) => Args; +export type ArgsEnhancer = ( + context: StoryContextForEnhancers +) => Args & { + secondPass?: boolean; +}; export type Meta = { decorators?: DecoratorFunction[]; diff --git a/lib/client-api/src/types.ts b/lib/client-api/src/types.ts index 131a6c30e02..96c9ef41d26 100644 --- a/lib/client-api/src/types.ts +++ b/lib/client-api/src/types.ts @@ -29,7 +29,11 @@ export interface StoryMetadata { decorators?: DecoratorFunction[]; loaders?: LoaderFunction[]; } -export type ArgTypesEnhancer = (context: StoryContext) => ArgTypes; +export type ArgTypesEnhancer = ( + context: StoryContext +) => ArgTypes & { + secondPass?: boolean; +}; export type ArgsEnhancer = (context: StoryContext) => Args; export type StorySpecifier = StoryId | { name: StoryName; kind: StoryKind } | '*'; diff --git a/lib/core-client/src/preview/new/composeConfigs.ts b/lib/core-client/src/preview/new/composeConfigs.ts index 8edefe6ee32..967f866993a 100644 --- a/lib/core-client/src/preview/new/composeConfigs.ts +++ b/lib/core-client/src/preview/new/composeConfigs.ts @@ -20,13 +20,18 @@ function getSingletonField(moduleExportList: ModuleExports[], field: string): an export function composeConfigs( moduleExportList: ModuleExports[] ): WebGlobalMeta { + const allArgTypeEnhancers = getArrayField(moduleExportList, 'argTypesEnhancers'); + return { parameters: combineParameters(...getField(moduleExportList, 'parameters')), decorators: getArrayField(moduleExportList, 'decorators'), args: getObjectField(moduleExportList, 'args'), argsEnhancers: getArrayField(moduleExportList, 'argsEnhancers'), argTypes: getObjectField(moduleExportList, 'argTypes'), - argTypesEnhancers: getArrayField(moduleExportList, 'argTypesEnhancers'), + argTypesEnhancers: [ + ...allArgTypeEnhancers.filter((e) => !e.secondPass), + ...allArgTypeEnhancers.filter((e) => e.secondPass), + ], globals: getObjectField(moduleExportList, 'globals'), globalTypes: getObjectField(moduleExportList, 'globalTypes'), loaders: getArrayField(moduleExportList, 'loaders'), From 110b587aa14ccc3cd93f40f72ee892e4301ee78f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 4 Aug 2021 17:07:18 +1000 Subject: [PATCH 022/285] Update StoryList to a simpler format as agreed --- lib/client-api/src/new/StoriesListStore.ts | 19 +++++++++---------- lib/client-api/src/new/StoryStore.ts | 14 +++++++++++--- lib/client-api/src/new/types.ts | 7 +++---- lib/core-client/src/preview/new/UrlStore.ts | 17 ++++++++++++++++- lib/core-server/src/utils/stories-json.ts | 16 ++++++++-------- 5 files changed, 47 insertions(+), 26 deletions(-) diff --git a/lib/client-api/src/new/StoriesListStore.ts b/lib/client-api/src/new/StoriesListStore.ts index 6591324b53a..453d464c819 100644 --- a/lib/client-api/src/new/StoriesListStore.ts +++ b/lib/client-api/src/new/StoriesListStore.ts @@ -61,10 +61,12 @@ export class StoriesListStore { } // Try and find a story matching the name/kind, setting no selection if they don't exist. - const { name, kind } = specifier; - return Object.values(this.storiesList.stories).find( - (story) => story.name === name && story.kind === kind - )?.id; + const { name, title } = specifier; + const match = Object.entries(this.storiesList.stories).find( + ([id, story]) => story.name === name && story.title === title + ); + + return match && match[0]; } storyIdToCSFFilePath(storyId: StoryId): Path { @@ -73,14 +75,11 @@ export class StoriesListStore { throw new Error(`Didn't find '${storyId}' in story metadata (\`stories.json\`)`); } - const path = storyMetadata.parameters?.fileName; - if (!path) { + if (!storyMetadata.importPath) { // TODO: Is this possible or are we guaranteeing this will exist now? - throw new Error( - `No \`parameters.fileName\` for '${storyId}' in story metadata (\`stories.json\`)` - ); + throw new Error(`No \`importPath\` for '${storyId}' in story metadata (\`stories.json\`)`); } - return path; + return storyMetadata.importPath; } } diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index 998d7dc43b8..e692e82b295 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -114,8 +114,8 @@ export class StoryStore { getSetStoriesPayload() { const { v, stories } = this.storiesList.storiesList; const kindParameters: Parameters = Object.values(stories).reduce( - (acc: Parameters, { kind }) => { - acc[kind] = {}; + (acc: Parameters, { title }) => { + acc[title] = {}; return acc; }, {} as Parameters @@ -126,7 +126,15 @@ export class StoryStore { globals: this.globals.get(), globalParameters: {}, kindParameters, - stories, + stories: Object.entries(stories).reduce((acc: any, [id, { name, title, importPath }]) => { + acc[id] = { + id, + name, + kind: title, + parameters: { fileName: importPath }, + }; + return acc; + }, {}), }; } } diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index b815b8cf971..fe7d89a45b2 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -131,10 +131,9 @@ export type Story = StoryIdentifier & { export type Path = string; export interface StoriesListStory { - id: StoryId; name: StoryName; - kind: ComponentTitle; // TODO -- should we rename this? - parameters: { fileName: Path }; + title: ComponentTitle; + importPath: Path; } export interface StoriesList { @@ -146,7 +145,7 @@ export type ModuleImportFn = (path: Path) => ModuleExports; export type Channel = any; -export type StorySpecifier = StoryId | { name: StoryName; kind: StoryKind } | '*'; +export type StorySpecifier = StoryId | { name: StoryName; title: ComponentTitle } | '*'; export interface SelectionSpecifier { storySpecifier: StorySpecifier; diff --git a/lib/core-client/src/preview/new/UrlStore.ts b/lib/core-client/src/preview/new/UrlStore.ts index b3484f3c882..a399931cc94 100644 --- a/lib/core-client/src/preview/new/UrlStore.ts +++ b/lib/core-client/src/preview/new/UrlStore.ts @@ -9,7 +9,22 @@ export class UrlStore { selection: Selection; constructor() { - this.selectionSpecifier = getSelectionSpecifierFromPath(); + const oldSpec = getSelectionSpecifierFromPath(); + + if (!oldSpec) { + this.selectionSpecifier = null; + } else if (typeof oldSpec.storySpecifier === 'string') { + this.selectionSpecifier = { + ...oldSpec, + storySpecifier: oldSpec.storySpecifier as string, + }; + } else { + const { name, kind: title } = oldSpec.storySpecifier; + this.selectionSpecifier = { + ...oldSpec, + storySpecifier: { name, title }, + }; + } } setSelection(selection: Selection) { diff --git a/lib/core-server/src/utils/stories-json.ts b/lib/core-server/src/utils/stories-json.ts index fdec4ffcac0..726b2081f53 100644 --- a/lib/core-server/src/utils/stories-json.ts +++ b/lib/core-server/src/utils/stories-json.ts @@ -5,11 +5,11 @@ import { logger } from '@storybook/node-logger'; import { resolvePathInStorybookCache, Options, normalizeStories } from '@storybook/core-common'; import { readCsf } from '@storybook/csf-tools'; +// TODO -- use proper types for these? share with StoriesListStory? interface ExtractedStory { - id: string; - kind: string; + title: string; name: string; - parameters: Record; + importPath: string; } type ExtractedStories = Record; @@ -42,11 +42,11 @@ export async function extractStoriesJson( } try { const csf = (await readCsf(absolutePath)).parse(); - csf.stories.forEach((story) => { - stories[story.id] = { - ...story, - kind: csf.meta.title, - parameters: { ...story.parameters, fileName: relativePath }, + csf.stories.forEach(({ id, name }) => { + stories[id] = { + title: csf.meta.title, + name, + importPath: relativePath, }; }); } catch (err) { From 7deccf85f9be8a074a1cf4e131ade441c477b2ad Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 5 Aug 2021 15:28:40 +1000 Subject: [PATCH 023/285] Disabled SET_STORIES for now, manager fetches stories.json --- lib/api/src/lib/stories.ts | 43 ++++++++++++++++--- lib/api/src/modules/stories.ts | 36 ++++++++++++---- .../src/preview/new/WebPreview.tsx | 5 ++- 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/lib/api/src/lib/stories.ts b/lib/api/src/lib/stories.ts index 98a6f5b10a4..e940023353c 100644 --- a/lib/api/src/lib/stories.ts +++ b/lib/api/src/lib/stories.ts @@ -63,8 +63,8 @@ export interface Story { viewMode?: ViewMode; [parameterName: string]: any; }; - args: Args; - initialArgs: Args; + args?: Args; + initialArgs?: Args; } export interface StoryInput { @@ -72,7 +72,6 @@ export interface StoryInput { name: string; refId?: string; kind: StoryKind; - children: string[]; parameters: { fileName: string; options: { @@ -82,9 +81,8 @@ export interface StoryInput { viewMode?: ViewMode; [parameterName: string]: any; }; - isLeaf: boolean; - args: Args; - initialArgs: Args; + args?: Args; + initialArgs?: Args; } export interface StoriesHash { @@ -99,6 +97,20 @@ export interface StoriesRaw { [id: string]: StoryInput; } +// TODO reconcile these types with the same ones in the frontend +type StoryName = string; +type ComponentTitle = StoryKind; +type Path = string; +export interface StoriesListStory { + name: StoryName; + title: ComponentTitle; + importPath: Path; +} +export interface StoriesListJson { + v: number; + stories: Record; +} + export type SetStoriesPayload = | { v: 2; @@ -149,6 +161,25 @@ export const denormalizeStoryParameters = ({ const STORY_KIND_PATH_SEPARATOR = /\s*\/\s*/; +export const transformStoriesListToStoriesHash = ( + list: StoriesListJson, + { provider }: { provider: Provider } +): StoriesHash => { + const input = Object.entries(list.stories).reduce((acc, [id, { title, name, importPath }]) => { + acc[id] = { + id, + kind: title, + name, + // TODO -- does the manager use this? Should we wait for this to come over with parameters + // and store `importPath` unchanged or not at all (given it is a preview "concern") + parameters: { fileName: importPath, options: {} }, + }; + return acc; + }, {} as StoriesRaw); + + return transformStoriesRawToStoriesHash(input, { provider }); +}; + export const transformStoriesRawToStoriesHash = ( input: StoriesRaw, { provider }: { provider: Provider } diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index d6297f073b7..d2917ec3c1f 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -17,6 +17,7 @@ import { transformStoriesRawToStoriesHash, isStory, isRoot, + transformStoriesListToStoriesHash, } from '../lib/stories'; import type { StoriesHash, @@ -26,6 +27,7 @@ import type { Root, StoriesRaw, SetStoriesPayload, + StoriesListJson, } from '../lib/stories'; import { Args, ModuleFn } from '../index'; @@ -68,6 +70,8 @@ export interface SubAPI { updateStoryArgs(story: Story, newArgs: Args): void; resetStoryArgs: (story: Story, argNames?: string[]) => void; findLeafStoryId(StoriesHash: StoriesHash, storyId: StoryId): StoryId; + fetchStoryList: () => Promise; + setStoryList: (storyList: StoriesListJson) => Promise; } interface Meta { @@ -327,9 +331,30 @@ export const init: ModuleFn = ({ }, }); }, + fetchStoryList: async () => { + // TODO where to get endpoint from? + const result = await global.fetch('/stories.json'); + // TODO deal with errors + const storyList = (await result.json()) as StoriesListJson; + + fullAPI.setStoryList(storyList); + }, + setStoryList: async (storyList: StoriesListJson) => { + const hash = transformStoriesListToStoriesHash(storyList, { + provider, + }); + + await store.setState({ + storiesHash: hash, + storiesConfigured: true, + storiesFailed: null, + }); + }, }; const initModule = () => { + fullAPI.fetchStoryList(); + // On initial load, the local iframe will select the first story (or other "selection specifier") // and emit STORY_SPECIFIED with the id. We need to ensure we respond to this change. fullAPI.on( @@ -372,18 +397,11 @@ export const init: ModuleFn = ({ fullAPI.on(SET_STORIES, function handler(data: SetStoriesPayload) { const { ref } = getEventMetadata(this, fullAPI); - const error = data.error || undefined; const stories = data.v ? denormalizeStoryParameters(data) : data.stories; if (!ref) { - if (!data.v) { - throw new Error('Unexpected legacy SET_STORIES event from local source'); - } - - fullAPI.setStories(stories, error); - const options = fullAPI.getCurrentParameter('options'); - checkDeprecatedOptionParameters(options); - fullAPI.setOptions(options); + // Or silently drop it. + throw new Error('Cannot SET_STORIES from a local source'); } else { fullAPI.setRef(ref.id, { ...ref, ...data, stories }, true); } diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index bae1294e8e6..cf5a316f4ee 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -110,8 +110,9 @@ export class WebPreview { this.setupListeners(); await this.selectSpecifiedStory(); - // TODO -- which way round is SET_STORIES/STORY_WAS_SELECTED in 6.3/ - this.channel.emit(Events.SET_STORIES, this.storyStore.getSetStoriesPayload()); + // TODO are we doing this? back-compat? + // TODO -- which way round is SET_STORIES/STORY_WAS_SELECTED in 6.3? + // this.channel.emit(Events.SET_STORIES, this.storyStore.getSetStoriesPayload()); } setupListeners() { From ea1910930541e52c7a04addd67f3c4f26ec6e1a8 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 6 Aug 2021 13:08:34 +1000 Subject: [PATCH 024/285] Got parameter emission working --- lib/api/src/index.tsx | 9 +++- lib/api/src/lib/stories.ts | 3 +- lib/api/src/modules/stories.ts | 48 ++++++++++++++----- lib/client-api/src/new/ArgsStore.ts | 6 ++- lib/client-api/src/new/StoryStore.ts | 2 +- .../src/preview/new/WebPreview.tsx | 8 ++++ lib/core-events/src/index.ts | 3 ++ 7 files changed, 63 insertions(+), 16 deletions(-) diff --git a/lib/api/src/index.tsx b/lib/api/src/index.tsx index 30bb0031e84..8bd56300180 100644 --- a/lib/api/src/index.tsx +++ b/lib/api/src/index.tsx @@ -460,8 +460,15 @@ export function useGlobals(): [Args, (newGlobals: Args) => void] { return [oldGlobals, updateGlobals]; } +// TODO what if a kind is selected? Is that possible? +function useCurrentStory(): Story { + const { getCurrentStoryData } = useStorybookApi(); + + return getCurrentStoryData() as Story; +} + export function useArgTypes(): ArgTypes { - return useParameter('argTypes', {}); + return useCurrentStory()?.argTypes || {}; } export function useGlobalTypes(): ArgTypes { diff --git a/lib/api/src/lib/stories.ts b/lib/api/src/lib/stories.ts index e940023353c..d0a11a3a143 100644 --- a/lib/api/src/lib/stories.ts +++ b/lib/api/src/lib/stories.ts @@ -4,7 +4,7 @@ import dedent from 'ts-dedent'; import { sanitize } from '@storybook/csf'; import mapValues from 'lodash/mapValues'; -import { StoryId, StoryKind, Args, Parameters, combineParameters } from '../index'; +import { StoryId, StoryKind, Args, ArgTypes, Parameters, combineParameters } from '../index'; import merge from './merge'; import { Provider } from '../modules/provider'; import { ViewMode } from '../modules/addons'; @@ -64,6 +64,7 @@ export interface Story { [parameterName: string]: any; }; args?: Args; + argTypes?: ArgTypes; initialArgs?: Args; } diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index d2917ec3c1f..00c2805c608 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -1,6 +1,7 @@ import global from 'global'; import { toId, sanitize } from '@storybook/csf'; import { + STORY_PREPARED, UPDATE_STORY_ARGS, RESET_STORY_ARGS, STORY_ARGS_UPDATED, @@ -39,6 +40,7 @@ type Direction = -1 | 1; type ParameterName = string; type ViewMode = 'story' | 'info' | 'settings' | string | undefined; +type StoryUpdate = Pick; export interface SubState { storiesHash: StoriesHash; @@ -72,6 +74,7 @@ export interface SubAPI { findLeafStoryId(StoriesHash: StoriesHash, storyId: StoryId): StoryId; fetchStoryList: () => Promise; setStoryList: (storyList: StoriesListJson) => Promise; + updateStory: (storyId: StoryId, update: StoryUpdate, ref?: ComposedRef) => Promise; } interface Meta { @@ -144,7 +147,13 @@ export const init: ModuleFn = ({ if (isStory(data)) { const { parameters } = data; - return parameterName ? parameters[parameterName] : parameters; + + if (parameters) { + return parameterName ? parameters[parameterName] : parameters; + } + + // TODO -- is this right? + return null; } return null; @@ -350,6 +359,27 @@ export const init: ModuleFn = ({ storiesFailed: null, }); }, + updateStory: async ( + storyId: StoryId, + update: StoryUpdate, + ref?: ComposedRef + ): Promise => { + if (!ref) { + const { storiesHash } = store.getState(); + storiesHash[storyId] = { + ...storiesHash[storyId], + ...update, + } as Story; + await store.setState({ storiesHash }); + } else { + const { id: refId, stories } = ref; + stories[storyId] = { + ...stories[storyId], + ...update, + } as Story; + await fullAPI.updateRef(refId, { stories }); + } + }, }; const initModule = () => { @@ -428,20 +458,16 @@ export const init: ModuleFn = ({ } ); + fullAPI.on(STORY_PREPARED, function handler({ id, ...update }) { + const { ref } = getEventMetadata(this, fullAPI); + fullAPI.updateStory(id, update, ref); + }); + fullAPI.on( STORY_ARGS_UPDATED, function handleStoryArgsUpdated({ storyId, args }: { storyId: StoryId; args: Args }) { const { ref } = getEventMetadata(this, fullAPI); - - if (!ref) { - const { storiesHash } = store.getState(); - (storiesHash[storyId] as Story).args = args; - store.setState({ storiesHash }); - } else { - const { id: refId, stories } = ref; - (stories[storyId] as Story).args = args; - fullAPI.updateRef(refId, { stories }); - } + fullAPI.updateStory(storyId, { args }, ref); } ); }; diff --git a/lib/client-api/src/new/ArgsStore.ts b/lib/client-api/src/new/ArgsStore.ts index 76c5fac74ba..c1952850f06 100644 --- a/lib/client-api/src/new/ArgsStore.ts +++ b/lib/client-api/src/new/ArgsStore.ts @@ -12,8 +12,10 @@ export class ArgsStore { return this.argsByStoryId[storyId]; } - set(storyId: StoryId, args: Args) { - this.argsByStoryId[storyId] = args; + setInitial(storyId: StoryId, args: Args) { + if (!this.argsByStoryId[storyId]) { + this.argsByStoryId[storyId] = args; + } } updateFromPersisted(story: Story, persisted: Args) { diff --git a/lib/client-api/src/new/StoryStore.ts b/lib/client-api/src/new/StoryStore.ts index e692e82b295..8ac60fe4d30 100644 --- a/lib/client-api/src/new/StoryStore.ts +++ b/lib/client-api/src/new/StoryStore.ts @@ -87,7 +87,7 @@ export class StoryStore { const componentMeta = csfFile.meta; const story = prepareStoryWithCache(storyMeta, componentMeta, this.globalMeta); - this.args.set(story.id, story.initialArgs); + this.args.setInitial(story.id, story.initialArgs); this.hooks[story.id] = new HooksContext(); return story; } diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index cf5a316f4ee..7374a8579a8 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -354,6 +354,14 @@ export class WebPreview { const storyContext = this.storyStore.getStoryContext(story); + const { name, title, parameters, initialArgs, argTypes, args } = storyContext; + this.channel.emit(Events.STORY_PREPARED, { + id, + parameters, + initialArgs, + argTypes, + args, + }); const loadedContext = await applyLoaders(storyContext); const renderContext: RenderContext = { diff --git a/lib/core-events/src/index.ts b/lib/core-events/src/index.ts index bf7850305b4..ed021b4619d 100644 --- a/lib/core-events/src/index.ts +++ b/lib/core-events/src/index.ts @@ -10,6 +10,8 @@ enum events { CURRENT_STORY_WAS_SET = 'currentStoryWasSet', // Force the current story to re-render FORCE_RE_RENDER = 'forceReRender', + // The story has been loaded into the store, we have parameters/args/etc + STORY_PREPARED = 'storyPrepared', // The next 6 events are emitted by the StoryRenderer when rendering the current story STORY_CHANGED = 'storyChanged', STORY_UNCHANGED = 'storyUnchanged', @@ -51,6 +53,7 @@ export const { SET_CURRENT_STORY, CURRENT_STORY_WAS_SET, FORCE_RE_RENDER, + STORY_PREPARED, STORY_CHANGED, STORY_UNCHANGED, STORY_RENDERED, From 779b996cd32e99394b14dc1bc55b119d6b6c1d70 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 6 Aug 2021 13:37:14 +1000 Subject: [PATCH 025/285] Emit a SET_GLOBALS event to initialize global[Type]s --- lib/api/src/index.tsx | 14 +++---- lib/api/src/modules/globals.ts | 40 +++++++++++++------ .../src/preview/new/WebPreview.tsx | 6 ++- lib/core-events/src/index.ts | 6 ++- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/lib/api/src/index.tsx b/lib/api/src/index.tsx index 8bd56300180..8bd322c814f 100644 --- a/lib/api/src/index.tsx +++ b/lib/api/src/index.tsx @@ -452,12 +452,12 @@ export function useArgs(): [Args, (newArgs: Args) => void, (argNames?: string[]) } export function useGlobals(): [Args, (newGlobals: Args) => void] { - const { - state: { globals: oldGlobals }, - api: { updateGlobals }, - } = useContext(ManagerContext); + const api = useStorybookApi(); + return [api.getGlobals(), api.updateGlobals]; +} - return [oldGlobals, updateGlobals]; +export function useGlobalTypes(): ArgTypes { + return useStorybookApi().getGlobalTypes(); } // TODO what if a kind is selected? Is that possible? @@ -470,7 +470,3 @@ function useCurrentStory(): Story { export function useArgTypes(): ArgTypes { return useCurrentStory()?.argTypes || {}; } - -export function useGlobalTypes(): ArgTypes { - return useParameter('globalTypes', {}); -} diff --git a/lib/api/src/modules/globals.ts b/lib/api/src/modules/globals.ts index e40f2cc7772..41b869fe944 100644 --- a/lib/api/src/modules/globals.ts +++ b/lib/api/src/modules/globals.ts @@ -1,22 +1,39 @@ -import { SET_STORIES, UPDATE_GLOBALS, GLOBALS_UPDATED } from '@storybook/core-events'; +import { SET_GLOBALS, UPDATE_GLOBALS, GLOBALS_UPDATED } from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; import deepEqual from 'fast-deep-equal'; -import { Args, ModuleFn } from '../index'; +import { Args, ArgTypes, ModuleFn, useArgs } from '../index'; -import { SetStoriesPayload } from '../lib/stories'; import { getEventMetadata } from '../lib/events'; +// TODO -- these types +type Globals = Args; +type GlobalTypes = ArgTypes; +interface SetGlobalsPayload { + globals: Globals; + globalTypes: GlobalTypes; +} + export interface SubState { - globals: Args; + globals?: Globals; + globalArgs?: GlobalTypes; } export interface SubAPI { - updateGlobals: (newGlobals: Args) => void; + getGlobals: () => Globals; + getGlobalTypes: () => GlobalTypes; + updateGlobals: (newGlobals: Globals) => void; } export const init: ModuleFn = ({ store, fullAPI }) => { const api: SubAPI = { + // TODO -- should these be {} before they are set? + getGlobals() { + return store.getState().globals || {}; + }, + getGlobalTypes() { + return store.getState().globalTypes || {}; + }, updateGlobals(newGlobals) { // Only emit the message to the local ref fullAPI.emit(UPDATE_GLOBALS, { @@ -28,12 +45,9 @@ export const init: ModuleFn = ({ store, fullAPI }) => { }, }; - const state: SubState = { - // Currently global args always start empty. TODO -- should this be set on the channel at init time? - globals: {}, - }; + const state: SubState = {}; - const updateGlobals = (globals: Args) => { + const updateGlobals = (globals: Globals) => { const currentGlobals = store.getState()?.globals; if (!deepEqual(globals, currentGlobals)) { store.setState({ globals }); @@ -41,7 +55,7 @@ export const init: ModuleFn = ({ store, fullAPI }) => { }; const initModule = () => { - fullAPI.on(GLOBALS_UPDATED, function handleGlobalsUpdated({ globals }: { globals: Args }) { + fullAPI.on(GLOBALS_UPDATED, function handleGlobalsUpdated({ globals }: { globals: Globals }) { const { ref } = getEventMetadata(this, fullAPI); if (!ref) { @@ -52,11 +66,11 @@ export const init: ModuleFn = ({ store, fullAPI }) => { ); } }); - fullAPI.on(SET_STORIES, function handleSetStories({ globals }: SetStoriesPayload) { + fullAPI.on(SET_GLOBALS, function handleSetStories({ globals, globalTypes }: SetGlobalsPayload) { const { ref } = getEventMetadata(this, fullAPI); if (!ref) { - updateGlobals(globals); + store.setState({ globals, globalTypes }); } else if (Object.keys(globals).length > 0) { logger.warn('received globals from a non-local ref. This is not currently supported.'); } diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index 7374a8579a8..1407883ffc1 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -143,6 +143,10 @@ export class WebPreview { if (globals) { this.storyStore.globals.updateFromPersisted(globals); } + this.channel.emit(Events.SET_GLOBALS, { + globals: this.storyStore.globals.get(), + globalTypes: this.storyStore.globalMeta.globalTypes, + }); await this.renderSelection({ forceRender: false, persistedArgs: args }); } @@ -354,7 +358,7 @@ export class WebPreview { const storyContext = this.storyStore.getStoryContext(story); - const { name, title, parameters, initialArgs, argTypes, args } = storyContext; + const { parameters, initialArgs, argTypes, args } = storyContext; this.channel.emit(Events.STORY_PREPARED, { id, parameters, diff --git a/lib/core-events/src/index.ts b/lib/core-events/src/index.ts index ed021b4619d..32e44b17bbe 100644 --- a/lib/core-events/src/index.ts +++ b/lib/core-events/src/index.ts @@ -25,8 +25,11 @@ enum events { STORY_ARGS_UPDATED = 'storyArgsUpdated', // Reset either a single arg of a story all args of a story RESET_STORY_ARGS = 'resetStoryArgs', - // As above + // Emitted by the preview at startup once it knows the initial set of globals+globalTypes + SET_GLOBALS = 'setGlobals', + // Tell the preview to update the value of a global UPDATE_GLOBALS = 'updateGlobals', + // A global was just updated GLOBALS_UPDATED = 'globalsUpdated', REGISTER_SUBSCRIPTION = 'registerSubscription', // Tell the manager that the user pressed a key in the preview @@ -63,6 +66,7 @@ export const { UPDATE_STORY_ARGS, STORY_ARGS_UPDATED, RESET_STORY_ARGS, + SET_GLOBALS, UPDATE_GLOBALS, GLOBALS_UPDATED, REGISTER_SUBSCRIPTION, From 3b6902535e8f5a42a312dfb00846020febdb8892 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 6 Aug 2021 13:43:19 +1000 Subject: [PATCH 026/285] Update globals/args persistence handling as per gert --- lib/client-api/src/new/ArgsStore.ts | 5 +++++ lib/client-api/src/new/GlobalsStore.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/client-api/src/new/ArgsStore.ts b/lib/client-api/src/new/ArgsStore.ts index c1952850f06..3939cf59907 100644 --- a/lib/client-api/src/new/ArgsStore.ts +++ b/lib/client-api/src/new/ArgsStore.ts @@ -19,8 +19,13 @@ export class ArgsStore { } updateFromPersisted(story: Story, persisted: Args) { + // NOTE: we use `combineArgs` here rather than `combineParameters` because changes to arg + // array values are persisted in the URL as sparse arrays, and we have to take that into + // account when overriding the initialArgs (e.g. we patch [,'changed'] over ['initial', 'val']) this.argsByStoryId[story.id] = combineArgs( this.argsByStoryId[story.id], + // Use the argType to ensure we aren't persisting the wrong type of value to the type. + // For instance you could try and set a string-valued arg to a number by changing the URL mapArgsToTypes(persisted, story.argTypes) ); } diff --git a/lib/client-api/src/new/GlobalsStore.ts b/lib/client-api/src/new/GlobalsStore.ts index c41fb55d04b..23c0a388675 100644 --- a/lib/client-api/src/new/GlobalsStore.ts +++ b/lib/client-api/src/new/GlobalsStore.ts @@ -39,7 +39,8 @@ export class GlobalsStore { if (this.allowedGlobalNames.has(key)) acc[key] = value; return acc; }, {} as Globals); - // TODO(Gert) -- why do we use combineParameters here? + // Note that unlike args, we do not have the same type information for globals to allow us + // to type check them here, so we just set them naively this.globals = combineParameters(this.globals, allowedUrlGlobals); } From f8f3dba01d82717dcb4f2256a7ab7dcf8ead8a95 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 6 Aug 2021 15:03:11 +1000 Subject: [PATCH 027/285] Add a `modernInlineRender` that renders the story using the framework's `renderToDOM` Replaces https://github.com/storybookjs/storybook/pull/14911 --- addons/docs/src/blocks/Story.tsx | 110 +++++++++++++++++------- app/react/src/client/preview/render.tsx | 17 ++-- examples/react-ts/main.ts | 1 + lib/client-api/src/new/types.ts | 6 +- lib/core-common/src/types.ts | 5 ++ 5 files changed, 98 insertions(+), 41 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 323feee337d..708dd23b480 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -1,8 +1,18 @@ -import React, { FunctionComponent, ReactNode, ElementType, ComponentProps } from 'react'; +import React, { + FunctionComponent, + ReactNode, + ElementType, + ComponentProps, + useContext, + useRef, + useEffect, +} from 'react'; import { MDXProvider } from '@mdx-js/react'; import { resetComponents, Story as PureStory } from '@storybook/components'; import { toId, storyNameFromExport } from '@storybook/csf'; import { Args, BaseAnnotations } from '@storybook/addons'; +import { Story as StoryType } from '@storybook/client-api/dist/ts3.9/new/types'; +import global from 'global'; import { CURRENT_SELECTION } from './types'; import { DocsContext, DocsContextProps } from './DocsContext'; @@ -41,18 +51,32 @@ export const lookupStoryId = ( storyNameFromExport(mdxStoryNameToKey[storyName]) ); -export const getStoryProps = ( - props: StoryProps, - context: DocsContextProps -): PureStoryProps => { +// TODO -- this can be async +export const getStory = (props: StoryProps, context: DocsContextProps): StoryType => { const { id } = props as StoryRefProps; const { name } = props as StoryDefProps; const inputId = id === CURRENT_SELECTION ? context.id : id; const previewId = inputId || lookupStoryId(name, context); - const story = context.storyById(previewId); + return context.storyById(previewId); +}; + +export const getStoryProps = ( + { height, inline }: StoryProps, + story: StoryType, + context: DocsContextProps +): PureStoryProps => { + const defaultIframeHeight = 100; + + if (!story) { + return { + id: story.id, + inline: false, + height: height || defaultIframeHeight.toString(), + title: undefined, + }; + } - const { height, inline } = props; - const { storyFn, name: storyName, parameters } = story; + const { name: storyName, parameters } = story; const { docs = {} } = parameters; if (docs.disable) { @@ -72,32 +96,60 @@ export const getStoryProps = ( return { parameters, inline: storyIsInline, - id: previewId, - // TODO -- how can `storyFn` be undefined? - storyFn: - prepareForInline && boundStoryFn ? () => prepareForInline(boundStoryFn, story) : boundStoryFn, + id: story.id, + storyFn: prepareForInline ? () => prepareForInline(boundStoryFn, story) : boundStoryFn, height: height || (storyIsInline ? undefined : iframeHeight), title: storyName, }; }; -const Story: FunctionComponent = (props) => ( - - {(context) => { - const storyProps = getStoryProps(props, context); - if (!storyProps) { - return null; - } - return ( -
- - - -
- ); - }} -
-); +const Story: FunctionComponent = (props) => { + const context = useContext(DocsContext); + const ref = useRef(); + const story = getStory(props, context); + const { id, title, name } = story; + const renderContext = { + id, + title, + kind: title, + name, + story: name, + // TODO -- shouldn't this be true sometimes? How to react to arg changes + forceRender: false, + // TODO what to do when these fail? + showMain: () => {}, + showError: () => {}, + showException: () => {}, + }; + useEffect(() => { + if (story && ref.current) { + setTimeout(() => { + context.renderStoryToElement({ story, renderContext, element: ref.current as Element }); + }, 1000); + } + return () => story?.cleanup(); + }, [story]); + + if (global?.FEATURES.modernInlineRender) { + return ( +
+ loading story... +
+ ); + } + + const storyProps = getStoryProps(props, story, context); + if (!storyProps) { + return null; + } + return ( +
+ + + +
+ ); +}; Story.defaultProps = { children: null, diff --git a/app/react/src/client/preview/render.tsx b/app/react/src/client/preview/render.tsx index f7ba50dd21b..5652c2c1997 100644 --- a/app/react/src/client/preview/render.tsx +++ b/app/react/src/client/preview/render.tsx @@ -6,8 +6,6 @@ import { StoryContext, RenderContext } from './types'; const { document, FRAMEWORK_OPTIONS } = global; -const rootEl = document ? document.getElementById('root') : null; - const render = (node: ReactElement, el: Element) => new Promise((resolve) => { ReactDOM.render(node, el, resolve); @@ -47,13 +45,10 @@ class ErrorBoundary extends Component<{ const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment; -export default async function renderMain({ - storyContext, - unboundStoryFn, - showMain, - showException, - forceRender, -}: RenderContext) { +export default async function renderMain( + { storyContext, unboundStoryFn, showMain, showException, forceRender }: RenderContext, + domElement: Element +) { const Story = unboundStoryFn as FunctionComponent; const content = ( @@ -71,8 +66,8 @@ export default async function renderMain({ // https://github.com/storybookjs/react-storybook/issues/81 // But forceRender means that it's the same story, so we want too keep the state in that case. if (!forceRender) { - ReactDOM.unmountComponentAtNode(rootEl); + ReactDOM.unmountComponentAtNode(domElement); } - await render(element, rootEl); + await render(element, domElement); } diff --git a/examples/react-ts/main.ts b/examples/react-ts/main.ts index 8b6b82792e6..c2ec2ae4186 100644 --- a/examples/react-ts/main.ts +++ b/examples/react-ts/main.ts @@ -23,6 +23,7 @@ const config: StorybookConfig = { postcss: false, previewCsfV3: true, buildStoriesJson: true, + modernInlineRender: true, }, }; diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index fe7d89a45b2..faa828404a3 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -171,7 +171,11 @@ export interface DocsContextProps { name: string; storyById: (id: StoryId) => Story; componentStories: () => Story[]; - renderStoryToElement: (story: Story) => void; + renderStoryToElement: (args: { + story: Story; + renderContext: RenderContextWithoutStoryContext; + element: Element; + }) => void; // TODO -- we need this for the `prepareForInline` docs approach bindStoryFn: (story: Story) => LegacyStoryFn; diff --git a/lib/core-common/src/types.ts b/lib/core-common/src/types.ts index b2c150985f8..c2e850ed998 100644 --- a/lib/core-common/src/types.ts +++ b/lib/core-common/src/types.ts @@ -264,6 +264,11 @@ export interface StorybookConfig { * Activate preview of CSF v3.0 */ previewCsfV3?: boolean; + + /** + * Activate modern inline rendering + */ + modernInlineRender?: boolean; }; /** * Tells Storybook where to find stories. From 5ced26ca76ca44d30277afdd9de36b68b598db54 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 6 Aug 2021 15:10:58 +1000 Subject: [PATCH 028/285] Update source to deal with missing storyIds --- addons/docs/src/blocks/Source.tsx | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/addons/docs/src/blocks/Source.tsx b/addons/docs/src/blocks/Source.tsx index 1b0c3aabe6d..2d2a880d55c 100644 --- a/addons/docs/src/blocks/Source.tsx +++ b/addons/docs/src/blocks/Source.tsx @@ -6,7 +6,6 @@ import { } from '@storybook/components'; import { StoryId } from '@storybook/api'; import { logger } from '@storybook/client-logger'; -import { StoryContext } from '@storybook/addons'; import { Story } from '@storybook/client-api/dist/ts3.9/new/types'; import { DocsContext, DocsContextProps } from './DocsContext'; @@ -44,11 +43,25 @@ type NoneProps = CommonProps; type SourceProps = SingleSourceProps | MultiSourceProps | CodeProps | NoneProps; +const getStory = (storyId: StoryId, docsContext: DocsContextProps): Story | null => { + const { storyById } = docsContext; + const story = storyById(storyId); + + // TODO we could move this warning to docsContext.storyById() et al. + if (!story) { + // Fallback if we can't get the story data for this story + logger.warn(`Unable to find information for story ID '${storyId}'`); + return null; + } + + return story; +}; + const getSourceState = (storyIds: string[], docsContext: DocsContextProps) => { const states = storyIds .map((storyId) => { - const story = docsContext.storyById(storyId); - return story.parameters.docs?.source?.state; + const story = getStory(storyId, docsContext); + return story?.parameters.docs?.source?.state; }) .filter(Boolean); @@ -119,7 +132,7 @@ export const getSourceProps = ( source = targetIds .map((storyId) => { const storySource = getStorySource(storyId, sourceContext); - const story = docsContext.storyById(storyId); + const story = getStory(storyId, docsContext); return getSnippet(storySource, story); }) .join('\n\n'); From 951e8db97c1eede16f89a02b1c6ca76aa9f0d082 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 6 Aug 2021 15:19:39 +1000 Subject: [PATCH 029/285] Change `bindStoryFn` to `getStoryContext` and bind in `` --- addons/docs/src/blocks/Story.tsx | 6 ++---- lib/client-api/src/new/types.ts | 4 +--- lib/core-client/src/preview/new/WebPreview.tsx | 8 ++------ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 708dd23b480..66ac6a81e4a 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -92,7 +92,7 @@ export const getStoryProps = ( ); } - const boundStoryFn = context.bindStoryFn(story); + const boundStoryFn = () => story.storyFn(context.getStoryContext(story)); return { parameters, inline: storyIsInline, @@ -123,9 +123,7 @@ const Story: FunctionComponent = (props) => { }; useEffect(() => { if (story && ref.current) { - setTimeout(() => { - context.renderStoryToElement({ story, renderContext, element: ref.current as Element }); - }, 1000); + context.renderStoryToElement({ story, renderContext, element: ref.current as Element }); } return () => story?.cleanup(); }, [story]); diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index faa828404a3..0d3d33fcd6e 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -176,9 +176,7 @@ export interface DocsContextProps { renderContext: RenderContextWithoutStoryContext; element: Element; }) => void; - - // TODO -- we need this for the `prepareForInline` docs approach - bindStoryFn: (story: Story) => LegacyStoryFn; + getStoryContext: (story: Story) => StoryContext; /** * mdxStoryNameToKey is an MDX-compiler-generated mapping of an MDX story's diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index 1407883ffc1..fba031c320f 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -291,12 +291,8 @@ export class WebPreview { storyById: (storyId: StoryId) => this.storyStore.storyFromCSFFile({ storyId, csfFile }), componentStories: () => this.storyStore.componentStoriesFromCSFFile({ csfFile }), renderStoryToElement: this.renderStoryToElement.bind(this), - - // TODO -- this is for prepareForInline. Note this *DOES NOT* run loaders, - // or play, or any of the stuff that `renderStoryToElement` below does. - // If we want to stick with this approach, we should refactor to share code. - bindStoryFn: (renderedStory: Story) => () => - renderedStory.storyFn(this.storyStore.getStoryContext(renderedStory)), + getStoryContext: (renderedStory: Story) => + this.storyStore.getStoryContext(renderedStory), }; const { docs } = story.parameters; From 27d0c710573fb0996eab89f40cc509ea3469a291 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 06:49:00 +1000 Subject: [PATCH 030/285] Update `ensureArgTypes` to also check that all arg types have a name. Previously we did that at the *start*: https://github.com/storybookjs/storybook/pull/12048/commits/4ae9e4714a7f375e582cb309c20a04af7b45c38d but we decide there was no reason not to do this at the end. --- lib/client-api/src/inferArgTypes.ts | 8 +++++++- lib/client-api/src/inferControls.ts | 10 +++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/client-api/src/inferArgTypes.ts b/lib/client-api/src/inferArgTypes.ts index cf532333cb0..afc5c23802e 100644 --- a/lib/client-api/src/inferArgTypes.ts +++ b/lib/client-api/src/inferArgTypes.ts @@ -44,7 +44,13 @@ export const inferArgTypes: ArgTypesEnhancer = (context) => { const { id, argTypes: userArgTypes = {}, initialArgs = {} } = context; if (!initialArgs) return userArgTypes; const argTypes = mapValues(initialArgs, (arg, key) => ({ + name: key, type: inferType(arg, `${id}.${key}`, new Set()), })); - return combineParameters(argTypes, userArgTypes); + const userArgTypesNames = mapValues(userArgTypes, (argType, key) => ({ + name: key, + })); + return combineParameters(argTypes, userArgTypesNames, userArgTypes); }; + +inferArgTypes.secondPass = true; diff --git a/lib/client-api/src/inferControls.ts b/lib/client-api/src/inferControls.ts index 85439860763..1117ad9f688 100644 --- a/lib/client-api/src/inferControls.ts +++ b/lib/client-api/src/inferControls.ts @@ -11,14 +11,14 @@ type ControlsMatchers = { color: RegExp; }; -const inferControl = (argType: ArgType, name: string, matchers: ControlsMatchers): any => { +const inferControl = (argType: ArgType, key: string, matchers: ControlsMatchers): any => { const { type, options } = argType; if (!type && !options) { return undefined; } // args that end with background or color e.g. iconColor - if (matchers.color && matchers.color.test(name)) { + if (matchers.color && matchers.color.test(key)) { const controlType = argType.type.name; if (controlType === 'string') { @@ -31,7 +31,7 @@ const inferControl = (argType: ArgType, name: string, matchers: ControlsMatchers } // args that end with date e.g. purchaseDate - if (matchers.date && matchers.date.test(name)) { + if (matchers.date && matchers.date.test(key)) { return { control: { type: 'date' } }; } @@ -66,8 +66,8 @@ export const inferControls: ArgTypesEnhancer = (context) => { if (!__isArgsStory) return argTypes; const filteredArgTypes = filterArgTypes(argTypes, include, exclude); - const withControls = mapValues(filteredArgTypes, (argType, name) => { - return argType?.type && inferControl(argType, name, matchers); + const withControls = mapValues(filteredArgTypes, (argType, key) => { + return argType?.type && inferControl(argType, key, matchers); }); return combineParameters(withControls, filteredArgTypes); From 34f3df447d508c1e9335ef28e0d4a564c89541c3 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 06:49:46 +1000 Subject: [PATCH 031/285] Ensure we pass component to enhancers --- lib/client-api/src/new/prepareStory.ts | 4 ++-- lib/client-api/src/new/types.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/client-api/src/new/prepareStory.ts b/lib/client-api/src/new/prepareStory.ts index 4fc92af1c44..4a38cface22 100644 --- a/lib/client-api/src/new/prepareStory.ts +++ b/lib/client-api/src/new/prepareStory.ts @@ -114,6 +114,8 @@ export function prepareStory( story: name, // Back compat title, kind: title, // Back compat + component: componentMeta.component, + subcomponents: componentMeta.subcomponents, parameters, initialArgs: initialArgsBeforeEnhancers, argTypes: passedArgTypes, @@ -180,8 +182,6 @@ export function prepareStory( return { ...contextForEnhancers, - component: componentMeta.component, - subcomponents: componentMeta.subcomponents, applyLoaders, storyFn, runPlayFunction, diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 0d3d33fcd6e..adb4116cc96 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -30,6 +30,11 @@ export type Globals = Args; export type GlobalTypes = ArgTypes; export type StoryContextForEnhancers = StoryIdentifier & { + // TODO - should we have a type parameter for these? + // Also TODO -- can you override at the story level? + component?: any; + subcomponents?: Record; + parameters: Parameters; initialArgs: Args; argTypes: ArgTypes; @@ -97,11 +102,6 @@ type StoryDescriptor = string[] | RegExp; export type ComponentMeta = Meta & { title: ComponentTitle; id?: ComponentId; - - // TODO - should we have a type parameter for these? - // Also TODO -- can you override at the story level? - component?: any; - subcomponents?: Record; includeStories?: StoryDescriptor; excludeStories?: StoryDescriptor; }; From 1cf4fe257bca50200a20e37d46caf908794ed27b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 06:50:06 +1000 Subject: [PATCH 032/285] Update `useArgs` for `ArgsTable` --- addons/docs/src/blocks/ArgsTable.tsx | 29 +++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index 6c3b877015c..148caa6a7f0 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -9,7 +9,7 @@ import { SortType, TabbedArgsTable, } from '@storybook/components'; -import { Args } from '@storybook/addons'; +import { addons, Args } from '@storybook/addons'; import { StoryStore, filterArgTypes } from '@storybook/client-api'; import type { PropDescriptor } from '@storybook/client-api'; import Events from '@storybook/core-events'; @@ -45,29 +45,33 @@ type ArgsTableProps = BaseProps | OfProps | ComponentsProps | StoryProps; const useArgs = ( storyId: string, - storyStore: StoryStore + context: DocsContextProps ): [Args, (args: Args) => void, (argNames?: string[]) => void] => { - const story = storyStore.fromId(storyId); + const channel = addons.getChannel(); + + const story = context.storyById(storyId); if (!story) { throw new Error(`Unknown story: ${storyId}`); } - const { args: initialArgs } = story; - const [args, setArgs] = useState(initialArgs); + const storyContext = context.getStoryContext(story); + + const [args, setArgs] = useState(storyContext.args); useEffect(() => { const cb = (changed: { storyId: string; args: Args }) => { if (changed.storyId === storyId) { setArgs(changed.args); } }; - storyStore._channel.on(Events.STORY_ARGS_UPDATED, cb); - return () => storyStore._channel.off(Events.STORY_ARGS_UPDATED, cb); + channel.on(Events.STORY_ARGS_UPDATED, cb); + return () => channel.off(Events.STORY_ARGS_UPDATED, cb); }, [storyId]); - const updateArgs = useCallback((newArgs) => storyStore.updateStoryArgs(storyId, newArgs), [ - storyId, - ]); + const updateArgs = useCallback( + (updatedArgs) => channel.emit(Events.UPDATE_STORY_ARGS, { storyId, updatedArgs }), + [storyId] + ); const resetArgs = useCallback( - (argNames?: string[]) => storyStore.resetStoryArgs(storyId, argNames), + (argNames?: string[]) => channel.emit(Events.RESET_STORY_ARGS, { storyId, argNames }), [storyId] ); return [args, updateArgs, resetArgs]; @@ -164,9 +168,8 @@ export const StoryTable: FC< const mainLabel = getComponentName(component) || 'Story'; - // TODO -- how to get the current args and channel? // eslint-disable-next-line prefer-const - let [args, updateArgs, resetArgs] = [storyById(storyId).initialArgs, () => 0, () => 0]; + let [args, updateArgs, resetArgs] = useArgs(storyId, context); let tabs = { [mainLabel]: { rows: storyArgTypes, args, updateArgs, resetArgs } } as Record< string, PureArgsTableProps From f6b13d5efbbe56d1288aa829e5566df16bc3ae4e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 09:33:16 +1000 Subject: [PATCH 033/285] Make `renderStoryToElement` responsible for re-rendering Instead of re-rendering at the top level when `args` or `globals` change, instead the call to `renderStoryToElement` (which may happen at the top level, or inside a docs page), sets up listeners which re-render when relevant things change. --- addons/docs/src/blocks/Story.tsx | 14 ++- lib/client-api/src/new/types.ts | 4 +- .../src/preview/new/WebPreview.tsx | 91 ++++++++++++------- lib/core-client/src/preview/new/WebView.ts | 8 +- 4 files changed, 73 insertions(+), 44 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 66ac6a81e4a..69585989866 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -122,10 +122,20 @@ const Story: FunctionComponent = (props) => { showException: () => {}, }; useEffect(() => { + let cleanup: () => void; if (story && ref.current) { - context.renderStoryToElement({ story, renderContext, element: ref.current as Element }); + cleanup = context + .renderStoryToElement({ + story, + renderContext, + element: ref.current as Element, + }) + // TODO -- no .then() -- should renderStoryToElement not be async? + .then((cleanupFn: () => void) => { + cleanup = cleanupFn; + }); } - return () => story?.cleanup(); + return () => cleanup && cleanup(); }, [story]); if (global?.FEATURES.modernInlineRender) { diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index adb4116cc96..7b2facd035e 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -53,13 +53,13 @@ export type LoadedStoryContext = StoryContext & { }; export declare type RenderContextWithoutStoryContext = StoryIdentifier & { - forceRender: boolean; showMain: () => void; showError: (error: { title: string; description: string }) => void; showException: (err: Error) => void; }; export type RenderContext = RenderContextWithoutStoryContext & { + forceRender: boolean; // TODO -- this is pretty surprising -- why is this here? unboundStoryFn: LegacyStoryFn; storyContext: LoadedStoryContext & { @@ -175,7 +175,7 @@ export interface DocsContextProps { story: Story; renderContext: RenderContextWithoutStoryContext; element: Element; - }) => void; + }) => () => void; getStoryContext: (story: Story) => StoryContext; /** diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index fba031c320f..ecd1190dda0 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -62,6 +62,8 @@ export class WebPreview { previousStory: Story; + previousCleanup: () => void; + constructor({ getGlobalMeta, importFn, @@ -148,7 +150,7 @@ export class WebPreview { globalTypes: this.storyStore.globalMeta.globalTypes, }); - await this.renderSelection({ forceRender: false, persistedArgs: args }); + await this.renderSelection({ persistedArgs: args }); } onKeydown(event: KeyboardEvent) { @@ -164,7 +166,7 @@ export class WebPreview { onSetCurrentStory(selection: Selection) { this.urlStore.setSelection(selection); this.channel.emit(Events.CURRENT_STORY_WAS_SET, this.urlStore.selection); - this.renderSelection({ forceRender: false }); + this.renderSelection(); } onUpdateGlobals({ globals }: { globals: Globals }) { @@ -174,8 +176,6 @@ export class WebPreview { globals, initialGlobals: this.storyStore.globals.initialGlobals, }); - - this.renderSelection({ forceRender: true }); } onUpdateArgs({ storyId, updatedArgs }: { storyId: StoryId; updatedArgs: Args }) { @@ -184,7 +184,6 @@ export class WebPreview { storyId, args: this.storyStore.args.get(storyId), }); - this.renderSelection({ forceRender: true }); } async onResetArgs({ storyId, argNames }: { storyId: string; argNames?: string[] }) { @@ -202,7 +201,7 @@ export class WebPreview { // This happens when a glob gets HMR-ed onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { this.storyStore.importFn = importFn; - this.renderSelection({ forceRender: false }); + this.renderSelection(); } // This happens when a config file gets reloade @@ -217,7 +216,7 @@ export class WebPreview { } this.storyStore.globalMeta = globalMeta; - this.renderSelection({ forceRender: false }); + this.renderSelection(); } // We can either have: @@ -225,13 +224,7 @@ export class WebPreview { // in which case we render it to the root element, OR // - a story selected in "docs" viewMode, // in which case we render the docsPage for that story - async renderSelection({ - forceRender, - persistedArgs, - }: { - forceRender: boolean; - persistedArgs?: Args; - }) { + async renderSelection({ persistedArgs }: { persistedArgs?: Args } = {}) { if (!this.urlStore.selection) { throw new Error('Cannot render story as no selection was made'); } @@ -248,19 +241,18 @@ export class WebPreview { const implementationChanged = story !== this.previousStory; - if (this.previousSelection?.viewMode === 'story' && (storyChanged || viewModeChanged)) { - this.removeStory({ story: this.previousStory }); + // Don't re-render the story if nothing has changed to justify it + if (!storyChanged && !implementationChanged && !viewModeChanged) { + // TODO -- the api of this changed, but the previous API made no sense. Did we use it? + this.channel.emit(Events.STORY_UNCHANGED, selection.storyId); + return; } - if (viewModeChanged && this.previousSelection?.viewMode === 'docs') { ReactDOM.unmountComponentAtNode(this.view.docsRoot()); } - // Don't re-render the story if nothing has changed to justify it - if (!forceRender && !storyChanged && !implementationChanged && !viewModeChanged) { - // TODO -- the api of this changed, but the previous API made no sense. Did we use it? - this.channel.emit(Events.STORY_UNCHANGED, selection.storyId); - return; + if (this.previousSelection?.viewMode === 'story') { + this.removePreviousStory(); } // If we are rendering something new (as opposed to re-rendering the same or first story), emit @@ -275,7 +267,7 @@ export class WebPreview { if (selection.viewMode === 'docs') { await this.renderDocs({ story }); } else { - await this.renderStory({ story, forceRender }); + this.previousCleanup = await this.renderStory({ story }); } } @@ -315,14 +307,8 @@ export class WebPreview { ); } - async renderStory({ - story, - forceRender, - }: { - story: Story; - forceRender: boolean; - }) { - const element = this.view.prepareForStory(story, forceRender); + async renderStory({ story }: { story: Story }) { + const element = this.view.prepareForStory(story); const { id, title, name } = story; const renderContext: RenderContextWithoutStoryContext = { id, @@ -330,13 +316,12 @@ export class WebPreview { kind: title, name, story: name, - forceRender, showMain: () => this.view.showMain(), showError: (err: { title: string; description: string }) => this.renderError(err), showException: (err: Error) => this.renderException(err), }; - await this.renderStoryToElement({ story, renderContext, element }); + return this.renderStoryToElement({ story, renderContext, element }); } // We want this function to be called directly by `renderSelection` above, @@ -366,6 +351,7 @@ export class WebPreview { const renderContext: RenderContext = { ...renderContextWithoutStoryContext, + forceRender: false, unboundStoryFn: storyFn, storyContext: { ...loadedContext, @@ -378,10 +364,45 @@ export class WebPreview { await runPlayFunction(); } this.channel.emit(Events.STORY_RENDERED, id); + + const rerenderStory = async () => { + // This story context will have the updated values of args and globals + const rerenderStoryContext = this.storyStore.getStoryContext(story); + const rerenderRenderContext: RenderContext = { + ...renderContext, + forceRender: true, + storyContext: { + // NOTE: loaders are not getting run again. So we are just patching + // the output of the loaders over the top of the updated story context. + // Loaders aren't allowed to touch anything but the `loaded` key but + // this means loaders never run again with new values of args/globals + ...loadedContext, + ...rerenderStoryContext, + }, + }; + + await this.renderToDOM(rerenderRenderContext, element); + this.channel.emit(Events.STORY_RENDERED, id); + }; + const rerenderStoryIfMatches = async ({ storyId }: { storyId: StoryId }) => { + if (storyId === story.id) rerenderStory(); + }; + + // Listen to events and re-render story + this.channel.on(Events.UPDATE_GLOBALS, rerenderStory); + this.channel.on(Events.UPDATE_STORY_ARGS, rerenderStoryIfMatches); + this.channel.on(Events.RESET_STORY_ARGS, rerenderStoryIfMatches); + + return () => { + story.cleanup(); + this.channel.off(Events.UPDATE_GLOBALS, rerenderStory); + this.channel.off(Events.UPDATE_STORY_ARGS, rerenderStoryIfMatches); + this.channel.off(Events.RESET_STORY_ARGS, rerenderStoryIfMatches); + }; } - removeStory({ story }: { story: Story }) { - story.cleanup(); + removePreviousStory() { + this.previousCleanup(); } renderPreviewEntryError(err: Error) { diff --git a/lib/core-client/src/preview/new/WebView.ts b/lib/core-client/src/preview/new/WebView.ts index 2058b51d69d..d11b4ab7f76 100644 --- a/lib/core-client/src/preview/new/WebView.ts +++ b/lib/core-client/src/preview/new/WebView.ts @@ -28,14 +28,12 @@ export class WebView { currentLayoutClass?: typeof layoutClassMap[keyof typeof layoutClassMap] | null; // Get ready to render a story, returning the element to render to - prepareForStory(story: Story, forceRender: boolean) { + prepareForStory(story: Story) { this.showStory(); this.applyLayout(story.parameters.layout); - if (!forceRender) { - document.documentElement.scrollTop = 0; - document.documentElement.scrollLeft = 0; - } + document.documentElement.scrollTop = 0; + document.documentElement.scrollLeft = 0; return this.storyRoot(); } From 3100f4d7c91d5f3e255de04de81150f8cbc8cba9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 10:00:59 +1000 Subject: [PATCH 034/285] Work around React's "render insider render" warning --- addons/docs/src/blocks/Story.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 69585989866..f66ddc5ffc1 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -139,10 +139,10 @@ const Story: FunctionComponent = (props) => { }, [story]); if (global?.FEATURES.modernInlineRender) { + // We do this so React doesn't complain when we replace the span in a secondary render + const htmlContents = `loading story...`; return ( -
- loading story... -
+
); } From 15fe97cb8b785ef1db08f085222d2757d33b4736 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 17:14:44 +1000 Subject: [PATCH 035/285] Make `renderStoryToElement` sync Moving the async part to a function that runs outside of it. Handle the race conditions of "what happens if a story is torn down or re-rendered" during initial render as best we can. --- addons/docs/src/blocks/Story.tsx | 15 +-- .../src/preview/new/WebPreview.tsx | 117 +++++++++++++----- 2 files changed, 88 insertions(+), 44 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index f66ddc5ffc1..88655452743 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -124,16 +124,11 @@ const Story: FunctionComponent = (props) => { useEffect(() => { let cleanup: () => void; if (story && ref.current) { - cleanup = context - .renderStoryToElement({ - story, - renderContext, - element: ref.current as Element, - }) - // TODO -- no .then() -- should renderStoryToElement not be async? - .then((cleanupFn: () => void) => { - cleanup = cleanupFn; - }); + cleanup = context.renderStoryToElement({ + story, + renderContext, + element: ref.current as Element, + }); } return () => cleanup && cleanup(); }, [story]); diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index ecd1190dda0..c6566686e53 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -29,7 +29,7 @@ import { UrlStore } from './UrlStore'; import { WebView } from './WebView'; import { NoDocs } from '../NoDocs'; -const { window: globalWindow } = global; +const { window: globalWindow, AbortController } = global; // TODO -- what's up with this code? Is it for HMR? Can we be smarter? function getOrCreateChannel() { @@ -47,6 +47,8 @@ function focusInInput(event: Event) { return /input|textarea/i.test(target.tagName) || target.getAttribute('contenteditable') !== null; } +type InitialRenderPhase = 'init' | 'loaded' | 'rendered' | 'done'; + export class WebPreview { channel: Channel; @@ -267,7 +269,7 @@ export class WebPreview { if (selection.viewMode === 'docs') { await this.renderDocs({ story }); } else { - this.previousCleanup = await this.renderStory({ story }); + this.previousCleanup = this.renderStory({ story }); } } @@ -307,7 +309,7 @@ export class WebPreview { ); } - async renderStory({ story }: { story: Story }) { + renderStory({ story }: { story: Story }) { const element = this.view.prepareForStory(story); const { id, title, name } = story; const renderContext: RenderContextWithoutStoryContext = { @@ -326,7 +328,7 @@ export class WebPreview { // We want this function to be called directly by `renderSelection` above, // but also by the `` docs component - async renderStoryToElement({ + renderStoryToElement({ story, renderContext: renderContextWithoutStoryContext, element, @@ -337,35 +339,77 @@ export class WebPreview { }) { const { id, applyLoaders, storyFn, runPlayFunction } = story; - const storyContext = this.storyStore.getStoryContext(story); - - const { parameters, initialArgs, argTypes, args } = storyContext; - this.channel.emit(Events.STORY_PREPARED, { - id, - parameters, - initialArgs, - argTypes, - args, - }); - const loadedContext = await applyLoaders(storyContext); - - const renderContext: RenderContext = { - ...renderContextWithoutStoryContext, - forceRender: false, - unboundStoryFn: storyFn, - storyContext: { - ...loadedContext, - storyFn: () => storyFn(loadedContext), - }, - }; - await this.renderToDOM(renderContext, element); + const controller = new AbortController(); + let initialRenderPhase: InitialRenderPhase = 'init'; + let renderContext: RenderContext; + const initialRender = async () => { + const storyContext = this.storyStore.getStoryContext(story); + + const { parameters, initialArgs, argTypes, args } = storyContext; + this.channel.emit(Events.STORY_PREPARED, { + id, + parameters, + initialArgs, + argTypes, + args, + }); - if (!renderContext.forceRender) { + const loadedContext = await applyLoaders(storyContext); + if (controller.signal.aborted) { + return; + } + initialRenderPhase = 'loaded'; + + // By this stage, it is possible that new args/globals have been received for this story + // and we need to ensure we render it with the new values + const updatedStoryContext = this.storyStore.getStoryContext(story); + renderContext = { + ...renderContextWithoutStoryContext, + forceRender: false, + unboundStoryFn: storyFn, + storyContext: { + storyFn: () => storyFn(loadedContext), + ...loadedContext, + ...updatedStoryContext, + }, + }; + await this.renderToDOM(renderContext, element); + if (controller.signal.aborted) { + return; + } + initialRenderPhase = 'rendered'; + + // NOTE: if the story is torn down during the play function, there could be negative + // side-effects (as the play function tries to modify something that is no longer visible). + // In the future we will likely pass the AbortController signal into play(), and also + // attempt to scope the play function by passing the element. + // + // NOTE: it is possible that args/globals have changed in between us starting to render + // the story and executing the play function (it is also possible that they change mid-way + // through executing the play function). We explicitly allow such changes to re-render the + // story by setting `initialRenderDone=true` immediate after `renderToDOM` completes. await runPlayFunction(); - } - this.channel.emit(Events.STORY_RENDERED, id); + if (controller.signal.aborted) { + return; + } + initialRenderPhase = 'done'; + + this.channel.emit(Events.STORY_RENDERED, id); + }; const rerenderStory = async () => { + // The story has not finished rendered the first time. The loaders are still running + // and we will pick up the new args/globals values when renderToDOM is called. + if (initialRenderPhase === 'init') { + return; + } + // The loaders are done but we are part way through rendering the story to the DOM + // This is a bit of an edge case and not something we can deal with sensibly, let's just warn + if (initialRenderPhase === 'loaded') { + logger.warn('Changed story args during rendering. Arg changes have been ignored.'); + return; + } + // This story context will have the updated values of args and globals const rerenderStoryContext = this.storyStore.getStoryContext(story); const rerenderRenderContext: RenderContext = { @@ -373,10 +417,10 @@ export class WebPreview { forceRender: true, storyContext: { // NOTE: loaders are not getting run again. So we are just patching - // the output of the loaders over the top of the updated story context. + // the updated story context over the previous value (that included loader output). // Loaders aren't allowed to touch anything but the `loaded` key but // this means loaders never run again with new values of args/globals - ...loadedContext, + ...renderContext.storyContext, ...rerenderStoryContext, }, }; @@ -384,16 +428,21 @@ export class WebPreview { await this.renderToDOM(rerenderRenderContext, element); this.channel.emit(Events.STORY_RENDERED, id); }; - const rerenderStoryIfMatches = async ({ storyId }: { storyId: StoryId }) => { - if (storyId === story.id) rerenderStory(); - }; + + // Start the first render + initialRender().catch((err) => logger.error(`Error rendering story: ${err}`)); // Listen to events and re-render story this.channel.on(Events.UPDATE_GLOBALS, rerenderStory); + const rerenderStoryIfMatches = async ({ storyId }: { storyId: StoryId }) => { + if (storyId === story.id) rerenderStory(); + }; this.channel.on(Events.UPDATE_STORY_ARGS, rerenderStoryIfMatches); this.channel.on(Events.RESET_STORY_ARGS, rerenderStoryIfMatches); return () => { + // Make sure the story stops rendering, as much as we can. + controller.abort(); story.cleanup(); this.channel.off(Events.UPDATE_GLOBALS, rerenderStory); this.channel.off(Events.UPDATE_STORY_ARGS, rerenderStoryIfMatches); From f716a4af9a65cbc41e34c9731af4a1c8b5f21f7b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 22:45:32 +1000 Subject: [PATCH 036/285] Switch `forceRender` to `!forceRemount` --- addons/docs/src/blocks/Story.tsx | 2 -- app/react/src/client/preview/render.tsx | 8 ++++---- lib/client-api/src/new/types.ts | 2 +- lib/core-client/src/preview/new/WebPreview.tsx | 5 +++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 88655452743..24e199e0ebc 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -114,8 +114,6 @@ const Story: FunctionComponent = (props) => { kind: title, name, story: name, - // TODO -- shouldn't this be true sometimes? How to react to arg changes - forceRender: false, // TODO what to do when these fail? showMain: () => {}, showError: () => {}, diff --git a/app/react/src/client/preview/render.tsx b/app/react/src/client/preview/render.tsx index 5652c2c1997..a18ac569609 100644 --- a/app/react/src/client/preview/render.tsx +++ b/app/react/src/client/preview/render.tsx @@ -46,7 +46,7 @@ class ErrorBoundary extends Component<{ const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment; export default async function renderMain( - { storyContext, unboundStoryFn, showMain, showException, forceRender }: RenderContext, + { storyContext, unboundStoryFn, showMain, showException, forceRemount }: RenderContext, domElement: Element ) { const Story = unboundStoryFn as FunctionComponent; @@ -60,12 +60,12 @@ export default async function renderMain( // For React 15, StrictMode & Fragment doesn't exists. const element = Wrapper ? {content} : content; - // We need to unmount the existing set of components in the DOM node. + // In most cases, we need to unmount the existing set of components in the DOM node. // Otherwise, React may not recreate instances for every story run. // This could leads to issues like below: // https://github.com/storybookjs/react-storybook/issues/81 - // But forceRender means that it's the same story, so we want too keep the state in that case. - if (!forceRender) { + // (This is not the case when we change args or globals to the story however) + if (forceRemount) { ReactDOM.unmountComponentAtNode(domElement); } diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 7b2facd035e..0ec5a889f39 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -59,7 +59,7 @@ export declare type RenderContextWithoutStoryContext = StoryIdentifier & { }; export type RenderContext = RenderContextWithoutStoryContext & { - forceRender: boolean; + forceRemount: boolean; // TODO -- this is pretty surprising -- why is this here? unboundStoryFn: LegacyStoryFn; storyContext: LoadedStoryContext & { diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index c6566686e53..4f32f8c196f 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -365,7 +365,8 @@ export class WebPreview { const updatedStoryContext = this.storyStore.getStoryContext(story); renderContext = { ...renderContextWithoutStoryContext, - forceRender: false, + // Whenever the selection changes we want to force the component to be remounted. + forceRemount: true, unboundStoryFn: storyFn, storyContext: { storyFn: () => storyFn(loadedContext), @@ -414,7 +415,7 @@ export class WebPreview { const rerenderStoryContext = this.storyStore.getStoryContext(story); const rerenderRenderContext: RenderContext = { ...renderContext, - forceRender: true, + forceRemount: false, storyContext: { // NOTE: loaders are not getting run again. So we are just patching // the updated story context over the previous value (that included loader output). From 72fc66daa7020fb3b71b647c55f964bfb27cb0e3 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 9 Aug 2021 22:58:54 +1000 Subject: [PATCH 037/285] Add some comments about an alternative approach --- .../src/preview/new/WebPreview.tsx | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/core-client/src/preview/new/WebPreview.tsx b/lib/core-client/src/preview/new/WebPreview.tsx index 4f32f8c196f..7f79f571084 100644 --- a/lib/core-client/src/preview/new/WebPreview.tsx +++ b/lib/core-client/src/preview/new/WebPreview.tsx @@ -398,6 +398,16 @@ export class WebPreview { this.channel.emit(Events.STORY_RENDERED, id); }; + // Setup a callback to run when the story needs to be re-rendered due to args or globals changes + // We need to be careful for race conditions if the initial rendering of the story (which + // can take some time due to loaders + the play function) hasn't completed yet. + // Our current approach is to either stop, or rerender immediately depending on which phase + // the initial render is in (see comments below). + // An alternative approach would be to *wait* until the initial render is done, before + // re-rendering with the new args. This would be relatively easy if we tracked the initial + // render via awaiting result of the call to `initialRender`. (We would also need to track + // if a subsequent *re-render* is in progress, but that is less likely) + // See also the note about cancelling below. const rerenderStory = async () => { // The story has not finished rendered the first time. The loaders are still running // and we will pick up the new args/globals values when renderToDOM is called. @@ -411,6 +421,12 @@ export class WebPreview { return; } + if (initialRenderPhase === 'rendered') { + logger.warn( + 'Changed story args during play function. Continuing but there may be problems.' + ); + } + // This story context will have the updated values of args and globals const rerenderStoryContext = this.storyStore.getStoryContext(story); const rerenderRenderContext: RenderContext = { @@ -442,7 +458,13 @@ export class WebPreview { this.channel.on(Events.RESET_STORY_ARGS, rerenderStoryIfMatches); return () => { - // Make sure the story stops rendering, as much as we can. + // If the story is torn down (either a new story is rendered or the docs page removes it) + // we need to consider the fact that the initial render may not be finished + // (possibly the loaders or the play function are still running). We use the controller + // as a method to abort them, ASAP, but this is not foolproof as we cannot control what + // happens inside the user's code. Still, we do render the new story right away. + // Alternatively, we could make this function async and await the teardown before rendering + // the new story. This might be a bit complicated for docs however. controller.abort(); story.cleanup(); this.channel.off(Events.UPDATE_GLOBALS, rerenderStory); From d758c4e7dd5f9a524940ce436bf34c16cc9a43aa Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 10 Aug 2021 11:06:50 +0800 Subject: [PATCH 038/285] Make yarn bootstrap work --- addons/controls/src/inferControls.ts | 1 + app/react/src/client/preview/index.tsx | 1 + app/react/src/client/preview/render.tsx | 1 + lib/client-api/src/inferArgTypes.ts | 1 + lib/client-api/src/new/types.ts | 9 ++++++++- lib/client-api/src/types.ts | 6 +++++- lib/core-client/typings.d.ts | 4 ++++ lib/core-server/typings.d.ts | 7 +++++-- yarn.lock | 5 ++++- 9 files changed, 30 insertions(+), 5 deletions(-) diff --git a/addons/controls/src/inferControls.ts b/addons/controls/src/inferControls.ts index 6e324e938d7..c5abf992e5e 100644 --- a/addons/controls/src/inferControls.ts +++ b/addons/controls/src/inferControls.ts @@ -75,6 +75,7 @@ const inferControls: ArgTypesEnhancer = (context) => { return combineParameters(withControls, filteredArgTypes); }; +// @ts-ignore FIXME inferControls.secondPass = true; export const argTypesEnhancers = [inferControls]; diff --git a/app/react/src/client/preview/index.tsx b/app/react/src/client/preview/index.tsx index cc9b300fc51..62505c82931 100644 --- a/app/react/src/client/preview/index.tsx +++ b/app/react/src/client/preview/index.tsx @@ -24,6 +24,7 @@ const globalRender: Story = (args, { parameters }) => { return ; }; +// @ts-ignore FIXME const api = start(render); api.clientApi.globalRender = globalRender; diff --git a/app/react/src/client/preview/render.tsx b/app/react/src/client/preview/render.tsx index a18ac569609..489c9966294 100644 --- a/app/react/src/client/preview/render.tsx +++ b/app/react/src/client/preview/render.tsx @@ -46,6 +46,7 @@ class ErrorBoundary extends Component<{ const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment; export default async function renderMain( + // @ts-ignore FIXME refactor in progress { storyContext, unboundStoryFn, showMain, showException, forceRemount }: RenderContext, domElement: Element ) { diff --git a/lib/client-api/src/inferArgTypes.ts b/lib/client-api/src/inferArgTypes.ts index afc5c23802e..93f32aa1515 100644 --- a/lib/client-api/src/inferArgTypes.ts +++ b/lib/client-api/src/inferArgTypes.ts @@ -53,4 +53,5 @@ export const inferArgTypes: ArgTypesEnhancer = (context) => { return combineParameters(argTypes, userArgTypesNames, userArgTypes); }; +// @ts-ignore FIXME inferArgTypes.secondPass = true; diff --git a/lib/client-api/src/new/types.ts b/lib/client-api/src/new/types.ts index 0ec5a889f39..8122884c486 100644 --- a/lib/client-api/src/new/types.ts +++ b/lib/client-api/src/new/types.ts @@ -67,7 +67,12 @@ export type RenderContext = RenderContextWithoutStoryContext }; }; -export type ArgTypesEnhancer = (context: StoryContextForEnhancers) => ArgTypes; +export type ArgTypesEnhancer = ( + context: StoryContextForEnhancers +) => ArgTypes & { + secondPass?: boolean; +}; + export type ArgsEnhancer = ( context: StoryContextForEnhancers ) => Args & { @@ -104,6 +109,8 @@ export type ComponentMeta = Meta & { id?: ComponentId; includeStories?: StoryDescriptor; excludeStories?: StoryDescriptor; + component?: any; + subcomponents?: Record; }; export type StoryMeta = Meta & { diff --git a/lib/client-api/src/types.ts b/lib/client-api/src/types.ts index 96c9ef41d26..313210dd14c 100644 --- a/lib/client-api/src/types.ts +++ b/lib/client-api/src/types.ts @@ -34,7 +34,11 @@ export type ArgTypesEnhancer = ( ) => ArgTypes & { secondPass?: boolean; }; -export type ArgsEnhancer = (context: StoryContext) => Args; +export type ArgsEnhancer = ( + context: StoryContext +) => Args & { + secondPass?: boolean; +}; export type StorySpecifier = StoryId | { name: StoryName; kind: StoryKind } | '*'; diff --git a/lib/core-client/typings.d.ts b/lib/core-client/typings.d.ts index faea2fff4fb..9d91b21f5e5 100644 --- a/lib/core-client/typings.d.ts +++ b/lib/core-client/typings.d.ts @@ -4,3 +4,7 @@ declare class AnsiToHtml { toHtml: (ansi: string) => string; } + +// FIXME refactor in progress +declare module '@storybook/client-api/dist/esm/new/StoryStore'; +declare type StoryStore = any; diff --git a/lib/core-server/typings.d.ts b/lib/core-server/typings.d.ts index 94f3fdaa253..f49e612f7e4 100644 --- a/lib/core-server/typings.d.ts +++ b/lib/core-server/typings.d.ts @@ -22,15 +22,18 @@ declare module 'file-system-cache' { ensureBasePath(): Promise; get(key: string, defaultValue?: any): Promise; getSync(key: string, defaultValue?: any): any | typeof defaultValue; - set(key: string, value: any): Promise<{ path: string }> + set(key: string, value: any): Promise<{ path: string }>; setSync(key: string, value: any): this; remove(key: string): Promise; clear(): Promise; save(): Promise<{ paths: string[] }>; - load(): Promise<{ files: Array<{ path: string, value: any }> }>; + load(): Promise<{ files: Array<{ path: string; value: any }> }>; } function create(options: Options): FileSystemCache; export = create; } + +// FIXME refactor in progress +declare module '@storybook/client-api/dist/esm/inferArgTypes'; diff --git a/yarn.lock b/yarn.lock index 4d9a1f8cbaa..12bcecfc76f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5628,10 +5628,12 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/api": 6.4.0-alpha.19 "@storybook/client-api": 6.4.0-alpha.19 + "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 core-js: ^3.8.2 + lodash: ^4.17.20 ts-dedent: ^2.0.0 peerDependencies: react: ^16.8.0 || ^17.0.0 @@ -6432,7 +6434,7 @@ __metadata: languageName: unknown linkType: soft -"@storybook/channel-websocket@workspace:*, @storybook/channel-websocket@workspace:lib/channel-websocket": +"@storybook/channel-websocket@6.4.0-alpha.19, @storybook/channel-websocket@workspace:*, @storybook/channel-websocket@workspace:lib/channel-websocket": version: 0.0.0-use.local resolution: "@storybook/channel-websocket@workspace:lib/channel-websocket" dependencies: @@ -6504,6 +6506,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.19 "@storybook/channel-postmessage": 6.4.0-alpha.19 + "@storybook/channel-websocket": 6.4.0-alpha.19 "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 From 0b77e47f2a16537aada2e6b73ee1b79fb638fc89 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 10 Aug 2021 21:24:06 +1000 Subject: [PATCH 039/285] Add a `to-importFn` utility --- .../src/preview/iframe-webpack.config.ts | 10 ++-- lib/core-common/src/index.ts | 1 + lib/core-common/src/utils/to-importFn.ts | 46 +++++++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 lib/core-common/src/utils/to-importFn.ts diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index c7b75b2c16e..a99b56871be 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -25,6 +25,7 @@ import { nodeModulesPaths, Options, NormalizedStoriesEntry, + toImportFn, } from '@storybook/core-common'; import { createBabelLoader } from './babel-loader-preview'; @@ -85,13 +86,7 @@ export default async ({ // Allows for custom frameworks that are not published under the @storybook namespace const virtualModuleMapping = { - [storiesPath]: dedent` - // TODO -- non-hardcoded importFn - export const importFn = async (path) => { - console.log('importFn ' + path); - return import('./src/' + path.replace(/^src\//, '')); - }; - `, + [storiesPath]: toImportFn(stories), [configEntryPath]: dedent` import { composeConfigs } from '@storybook/core-client/dist/esm/preview/new/composeConfigs'; import { WebPreview } from '@storybook/core-client/dist/esm/preview/new/WebPreview'; @@ -133,6 +128,7 @@ export default async ({ `, }; + console.log(virtualModuleMapping[storiesPath]); console.log(virtualModuleMapping[configEntryPath]); // if (stories) { // const storiesFilename = path.resolve(path.join(configDir, `generated-stories-entry.js`)); diff --git a/lib/core-common/src/index.ts b/lib/core-common/src/index.ts index 7eb2cdaca71..736d0235c8a 100644 --- a/lib/core-common/src/index.ts +++ b/lib/core-common/src/index.ts @@ -23,5 +23,6 @@ export * from './utils/validate-configuration-files'; export * from './utils/to-require-context'; export * from './utils/has-dotenv'; export * from './utils/normalize-stories'; +export * from './utils/to-importFn'; export * from './types'; diff --git a/lib/core-common/src/utils/to-importFn.ts b/lib/core-common/src/utils/to-importFn.ts new file mode 100644 index 00000000000..7310bc904e8 --- /dev/null +++ b/lib/core-common/src/utils/to-importFn.ts @@ -0,0 +1,46 @@ +import globBase from 'glob-base'; +import { makeRe } from 'micromatch'; +import dedent from 'ts-dedent'; + +import type { NormalizedStoriesEntry } from '../types'; + +export function toImportFnPart(entry: NormalizedStoriesEntry) { + const { base } = globBase(entry.glob); + const regex = makeRe(entry.glob, { fastpaths: false, noglobstar: false, bash: false }); + + const webpackIncludeRegex = new RegExp(regex.source.substring(1)); + + // NOTE: `base` looks like './src' but `path`, (and what micromatch expects) + // is something that starts with `src/`. So to strip off base from path, we + // need to drop `base.length - 1` chars. + return dedent` + async (path) => { + if (!${regex}.exec(path)) { + return; + } + const remainder = path.substring(${base.length - 1}); + return import( + /* webpackInclude: ${webpackIncludeRegex} */ + '${base}/' + remainder + ); + } + + `; +} + +export function toImportFn(stories: NormalizedStoriesEntry[]) { + return dedent` + const importers = [ + ${stories.map(toImportFnPart).join(',\n')} + ]; + + export async function importFn(path) { + for (let i = 0; i < importers.length; i++) { + const moduleExports = await importers[i](path); + if (moduleExports) { + return moduleExports; + } + } + } + `; +} From 379921eb890e32b1164fbcb9a43e501daa6ae4dd Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 10 Aug 2021 19:15:46 +0800 Subject: [PATCH 040/285] Core: MDX support for built-in stories.json --- examples/angular-cli/.storybook/main.js | 4 ++++ examples/react-ts/src/AccountForm.stories.tsx | 2 +- .../src/addon-docs/docs-only.stories.mdx | 9 ++++++++ .../react-ts/src/addon-docs/docs.stories.mdx | 12 ++++++++++ lib/core-server/src/utils/stories-json.ts | 10 ++++---- lib/csf-tools/src/CsfFile.test.ts | 23 +++++++++++++++++++ lib/csf-tools/src/CsfFile.ts | 9 ++++++-- lib/csf-tools/src/index.ts | 14 +++++++++++ lib/csf-tools/src/mdx/typings.d.ts | 1 + 9 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 examples/react-ts/src/addon-docs/docs-only.stories.mdx create mode 100644 examples/react-ts/src/addon-docs/docs.stories.mdx diff --git a/examples/angular-cli/.storybook/main.js b/examples/angular-cli/.storybook/main.js index c494920d567..2fa56977386 100644 --- a/examples/angular-cli/.storybook/main.js +++ b/examples/angular-cli/.storybook/main.js @@ -21,6 +21,10 @@ module.exports = { }, // These are just here to test composition. They could be added to any storybook example project refs: { + react: { + title: 'ReactTS', + url: 'http://localhost:9011', + }, first: { title: 'Composition test one', url: 'https://storybookjs.netlify.app/cra-ts-essentials', diff --git a/examples/react-ts/src/AccountForm.stories.tsx b/examples/react-ts/src/AccountForm.stories.tsx index 3fab54f612f..0cc67a0fff4 100644 --- a/examples/react-ts/src/AccountForm.stories.tsx +++ b/examples/react-ts/src/AccountForm.stories.tsx @@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event'; import { AccountForm, AccountFormProps } from './AccountForm'; export default { - title: 'AccountForm', + title: 'Demo/AccountForm', component: AccountForm, parameters: { layout: 'centered', diff --git a/examples/react-ts/src/addon-docs/docs-only.stories.mdx b/examples/react-ts/src/addon-docs/docs-only.stories.mdx new file mode 100644 index 00000000000..3063e6e867a --- /dev/null +++ b/examples/react-ts/src/addon-docs/docs-only.stories.mdx @@ -0,0 +1,9 @@ +import { Meta, Canvas } from '@storybook/addon-docs'; + + + +# Documentation-only MDX + +## [Link](http://https://storybook.js.org/) in heading + +This file is a documentation-only MDX file, i.e. it doesn't contain any `` definitions. diff --git a/examples/react-ts/src/addon-docs/docs.stories.mdx b/examples/react-ts/src/addon-docs/docs.stories.mdx new file mode 100644 index 00000000000..44639a3698f --- /dev/null +++ b/examples/react-ts/src/addon-docs/docs.stories.mdx @@ -0,0 +1,12 @@ +import { Meta, Story } from '@storybook/addon-docs'; +import { Button } from '../button'; + + + +# Button + + +
)) .add('up to date', () => ( - + )) .add('old version race condition', () => ( diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 4a1f154198a..7a1f9dfbd3d 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -224,6 +224,8 @@ export class WebPreview { try { story = await this.storyStore.loadStory({ storyId: selection.storyId }); } catch (err) { + logger.warn('Issue loading story:'); + logger.warn(err); this.renderMissingStory(selection.storyId); return; } From 18a6e511366425fcbd8c0d790cdc5748db24e767 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 30 Aug 2021 17:06:25 +1000 Subject: [PATCH 101/285] HMR tests for start --- lib/client-api/src/client_api.ts | 29 +- lib/core-client/src/preview/start.test.ts | 363 +++++++++++++++++++++- lib/core-client/src/preview/start.ts | 48 ++- lib/web-preview/src/WebPreview.tsx | 10 +- 4 files changed, 416 insertions(+), 34 deletions(-) diff --git a/lib/client-api/src/client_api.ts b/lib/client-api/src/client_api.ts index 4fd8434ee4f..8cd31b8212a 100644 --- a/lib/client-api/src/client_api.ts +++ b/lib/client-api/src/client_api.ts @@ -226,13 +226,7 @@ export default class ClientApi { // itself automatically without us needing to look at our imports m.hot.accept(); m.hot.dispose(() => { - // Clear this module's stories from the storyList and existing exports - Object.entries(this.storiesList.stories).forEach(([id, { importPath }]) => { - if (importPath === fileName) { - delete this.storiesList.stories[id]; - } - }); - delete this.csfExports[fileName]; + this.clearFilenameExports(fileName); // We need to update the importFn as soon as the module re-evaluates // (and calls storiesOf() again, etc). We could call `onImportFnChanged()` @@ -336,8 +330,29 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m return api; }; + clearFilenameExports(fileName: Path) { + if (!this.csfExports[fileName]) { + return; + } + + // Clear this module's stories from the storyList and existing exports + Object.entries(this.storiesList.stories).forEach(([id, { importPath }]) => { + if (importPath === fileName) { + delete this.storiesList.stories[id]; + } + }); + delete this.csfExports[fileName]; + } + // NOTE: we could potentially share some of this code with the stories.json generation addStoriesFromExports(fileName: Path, fileExports: ModuleExports) { + // if the export haven't changed since last time we added them, this is a no-op + if (this.csfExports[fileName] === fileExports) { + return; + } + // OTOH, if they have changed, let's clear them out first + this.clearFilenameExports(fileName); + const { default: defaultExport, __namedExportsOrder, ...namedExports } = fileExports; const { title } = defaultExport || {}; if (!title) { diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index 96e01dd4545..b0934badda8 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -4,7 +4,7 @@ import Events from '@storybook/core-events'; import { waitForRender, - emitter, + waitForEvents, mockChannel, } from '@storybook/web-preview/dist/cjs/WebPreview.mockdata'; @@ -49,9 +49,7 @@ describe('start', () => { .add('Story Three', jest.fn()); }); - await waitForRender(); - - expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_STORIES, expect.any(Object)); + await waitForEvents([Events.SET_STORIES]); expect( mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] ).toMatchInlineSnapshot(` @@ -204,6 +202,147 @@ describe('start', () => { expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_RENDERED, 'component-a--default'); expect(secondImplementation).toHaveBeenCalled(); }); + + it('re-emits SET_STORIES when a story is added', async () => { + const render = jest.fn(({ storyFn }) => storyFn()); + + const { configure, clientApi, forceReRender } = start(render); + + let disposeCallback: () => void; + const module = { + id: 'file1', + hot: { + accept: jest.fn(), + dispose(cb: () => void) { + disposeCallback = cb; + }, + }, + }; + configure('test', () => { + clientApi.storiesOf('Component A', module as any).add('default', jest.fn()); + }); + + await waitForRender(); + + mockChannel.emit.mockClear(); + disposeCallback(); + clientApi + .storiesOf('Component A', module as any) + .add('default', jest.fn()) + .add('new', jest.fn()); + + await waitForEvents([Events.SET_STORIES]); + expect( + mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] + ).toMatchInlineSnapshot(` + Object { + "globalParameters": Object {}, + "globals": Object {}, + "kindParameters": Object { + "Component A": Object {}, + }, + "stories": Object { + "component-a--default": Object { + "id": "component-a--default", + "kind": "Component A", + "name": "default", + "parameters": Object { + "fileName": "file1", + }, + }, + "component-a--new": Object { + "id": "component-a--new", + "kind": "Component A", + "name": "new", + "parameters": Object { + "fileName": "file1", + }, + }, + }, + "v": 3, + } + `); + }); + + it('re-emits SET_STORIES when a story file is removed', async () => { + const render = jest.fn(({ storyFn }) => storyFn()); + + const { configure, clientApi, forceReRender } = start(render); + + let disposeCallback: () => void; + const moduleB = { + id: 'file2', + hot: { + accept: jest.fn(), + dispose(cb: () => void) { + disposeCallback = cb; + }, + }, + }; + configure('test', () => { + clientApi.storiesOf('Component A', { id: 'file1' } as any).add('default', jest.fn()); + clientApi.storiesOf('Component B', moduleB as any).add('default', jest.fn()); + }); + + await waitForEvents([Events.SET_STORIES]); + expect( + mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] + ).toMatchInlineSnapshot(` + Object { + "globalParameters": Object {}, + "globals": Object {}, + "kindParameters": Object { + "Component A": Object {}, + "Component B": Object {}, + }, + "stories": Object { + "component-a--default": Object { + "id": "component-a--default", + "kind": "Component A", + "name": "default", + "parameters": Object { + "fileName": "file1", + }, + }, + "component-b--default": Object { + "id": "component-b--default", + "kind": "Component B", + "name": "default", + "parameters": Object { + "fileName": "file2", + }, + }, + }, + "v": 3, + } + `); + mockChannel.emit.mockClear(); + disposeCallback(); + + await waitForEvents([Events.SET_STORIES]); + expect( + mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] + ).toMatchInlineSnapshot(` + Object { + "globalParameters": Object {}, + "globals": Object {}, + "kindParameters": Object { + "Component A": Object {}, + }, + "stories": Object { + "component-a--default": Object { + "id": "component-a--default", + "kind": "Component A", + "name": "default", + "parameters": Object { + "fileName": "file1", + }, + }, + }, + "v": 3, + } + `); + }); }); const componentCExports = { @@ -221,9 +360,7 @@ describe('start', () => { const { configure } = start(render); configure('test', () => [componentCExports]); - await waitForRender(); - - expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_STORIES, expect.any(Object)); + await waitForEvents([Events.SET_STORIES]); expect( mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] ).toMatchInlineSnapshot(` @@ -267,6 +404,214 @@ describe('start', () => { undefined ); }); + + it('supports HMR when a story file changes', async () => { + const render = jest.fn(({ storyFn }) => storyFn()); + + let disposeCallback: (data: object) => void; + const module = { + id: 'file1', + hot: { + data: {}, + accept: jest.fn(), + dispose(cb: () => void) { + disposeCallback = cb; + }, + }, + }; + + const { configure } = start(render); + configure('test', () => [componentCExports], module as any); + + await waitForRender(); + expect(mockChannel.emit).toHaveBeenCalledWith( + Events.STORY_RENDERED, + 'component-c--story-one' + ); + expect(componentCExports.StoryOne).toHaveBeenCalled(); + expect(module.hot.accept).toHaveBeenCalled(); + expect(disposeCallback).toBeDefined(); + + mockChannel.emit.mockClear(); + disposeCallback(module.hot.data); + const secondImplementation = jest.fn(); + configure( + 'test', + () => [{ ...componentCExports, StoryOne: secondImplementation }], + module as any + ); + + await waitForRender(); + expect(mockChannel.emit).toHaveBeenCalledWith( + Events.STORY_RENDERED, + 'component-c--story-one' + ); + expect(secondImplementation).toHaveBeenCalled(); + }); + + it('re-emits SET_STORIES when a story is added', async () => { + const render = jest.fn(({ storyFn }) => storyFn()); + + let disposeCallback: (data: object) => void; + const module = { + id: 'file1', + hot: { + data: {}, + accept: jest.fn(), + dispose(cb: () => void) { + disposeCallback = cb; + }, + }, + }; + const { configure } = start(render); + configure('test', () => [componentCExports], module as any); + + await waitForRender(); + + mockChannel.emit.mockClear(); + disposeCallback(module.hot.data); + configure('test', () => [{ ...componentCExports, StoryThree: jest.fn() }], module as any); + + await waitForEvents([Events.SET_STORIES]); + expect( + mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] + ).toMatchInlineSnapshot(` + Object { + "globalParameters": Object {}, + "globals": Object {}, + "kindParameters": Object { + "Component C": Object {}, + }, + "stories": Object { + "component-c--story-one": Object { + "id": "component-c--story-one", + "kind": "Component C", + "name": "Story One", + "parameters": Object { + "fileName": "exports-map-0", + }, + }, + "component-c--story-three": Object { + "id": "component-c--story-three", + "kind": "Component C", + "name": "Story Three", + "parameters": Object { + "fileName": "exports-map-0", + }, + }, + "component-c--story-two": Object { + "id": "component-c--story-two", + "kind": "Component C", + "name": "Story Two", + "parameters": Object { + "fileName": "exports-map-0", + }, + }, + }, + "v": 3, + } + `); + }); + + it('re-emits SET_STORIES when a story file is removed', async () => { + const render = jest.fn(({ storyFn }) => storyFn()); + + let disposeCallback: (data: object) => void; + const module = { + id: 'file1', + hot: { + data: {}, + accept: jest.fn(), + dispose(cb: () => void) { + disposeCallback = cb; + }, + }, + }; + const { configure } = start(render); + configure( + 'test', + () => [componentCExports, { default: { title: 'Component D' }, StoryFour: jest.fn() }], + module as any + ); + + await waitForEvents([Events.SET_STORIES]); + expect( + mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] + ).toMatchInlineSnapshot(` + Object { + "globalParameters": Object {}, + "globals": Object {}, + "kindParameters": Object { + "Component C": Object {}, + "Component D": Object {}, + }, + "stories": Object { + "component-c--story-one": Object { + "id": "component-c--story-one", + "kind": "Component C", + "name": "Story One", + "parameters": Object { + "fileName": "exports-map-0", + }, + }, + "component-c--story-two": Object { + "id": "component-c--story-two", + "kind": "Component C", + "name": "Story Two", + "parameters": Object { + "fileName": "exports-map-0", + }, + }, + "component-d--story-four": Object { + "id": "component-d--story-four", + "kind": "Component D", + "name": "Story Four", + "parameters": Object { + "fileName": "exports-map-1", + }, + }, + }, + "v": 3, + } + `); + + mockChannel.emit.mockClear(); + console.log('rerunning'); + disposeCallback(module.hot.data); + configure('test', () => [componentCExports], module as any); + + await waitForEvents([Events.SET_STORIES]); + expect( + mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] + ).toMatchInlineSnapshot(` + Object { + "globalParameters": Object {}, + "globals": Object {}, + "kindParameters": Object { + "Component C": Object {}, + }, + "stories": Object { + "component-c--story-one": Object { + "id": "component-c--story-one", + "kind": "Component C", + "name": "Story One", + "parameters": Object { + "fileName": "exports-map-0", + }, + }, + "component-c--story-two": Object { + "id": "component-c--story-two", + "kind": "Component C", + "name": "Story Two", + "parameters": Object { + "fileName": "exports-map-0", + }, + }, + }, + "v": 3, + } + `); + }); }); describe('when configure is called with a combination', () => { @@ -287,9 +632,7 @@ describe('start', () => { return [componentCExports]; }); - await waitForRender(); - - expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_STORIES, expect.any(Object)); + await waitForEvents([Events.SET_STORIES]); expect( mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] ).toMatchInlineSnapshot(` diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 2b71ecec6dc..d7383ecc20b 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -26,18 +26,34 @@ export function start( clientApi, configure(framework: string, loadable: Loadable, m?: NodeModule) { + let lastExportsMap: ReturnType = + m?.hot?.data?.lastExportsMap || new Map(); + if (m?.hot?.dispose) { + m.hot.accept(); + m.hot.dispose((data) => { + // eslint-disable-next-line no-param-reassign + data.lastExportsMap = lastExportsMap; + }); + } + clientApi.addParameters({ framework }); const getGlobalAnnotations = () => { - // TODO - // clientApi.resetGlobalAnnotations(); - const exportsMap = executeLoadable(loadable); Array.from(exportsMap.entries()) .filter(([, fileExports]) => !!fileExports.default) .forEach(([fileName, fileExports]) => { + // Exports haven't changed so there is so no need to do anything + if (lastExportsMap.get(fileName) === fileExports) { + return; + } + clientApi.addStoriesFromExports(fileName, fileExports); }); + Array.from(lastExportsMap.keys()) + .filter((fileName) => !exportsMap.has(fileName)) + .forEach((fileName) => clientApi.clearFilenameExports(fileName)); + lastExportsMap = exportsMap; return { ...clientApi.globalAnnotations, @@ -45,17 +61,23 @@ export function start( applyDecorators: decorateStory, }; }; + if (!preview) { + preview = new WebPreview({ + importFn: (path: Path) => clientApi.importFn(path), + getGlobalAnnotations, + fetchStoriesList: async () => clientApi.storiesList, + }); + clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); - preview = new WebPreview({ - importFn: (path: Path) => clientApi.importFn(path), - getGlobalAnnotations, - fetchStoriesList: async () => clientApi.storiesList, - }); - - clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); - - // TODO - preview.initialize().then(() => console.log('init!')); + // TODO + preview + .initialize() + .then(() => console.log('init!')) + .catch((err) => console.error(err)); + } else { + getGlobalAnnotations(); + preview.onImportFnChanged({ importFn: clientApi.importFn.bind(clientApi) }); + } }, }; } diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 7a1f9dfbd3d..71049b70ab1 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -78,6 +78,7 @@ export class WebPreview { this.renderToDOM = globalAnnotations.renderToDOM; return globalAnnotations; } catch (err) { + logger.warn(err); // This is an error extracting the globalAnnotations (i.e. evaluating the previewEntries) and // needs to be show to the user as a simple error this.renderPreviewEntryError(err); @@ -100,8 +101,7 @@ export class WebPreview { await this.selectSpecifiedStory(); - // TODO are we doing this? back-compat? - // TODO -- which way round is SET_STORIES/STORY_WAS_SELECTED in 6.3? + // TODO -- only with feature this.channel.emit(Events.SET_STORIES, await this.storyStore.getSetStoriesPayload()); } @@ -183,7 +183,7 @@ export class WebPreview { } // This happens when a glob gets HMR-ed - onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { + async onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { this.storyStore.importFn = importFn; if (this.urlStore.selection) { @@ -191,6 +191,9 @@ export class WebPreview { } else { this.selectSpecifiedStory(); } + + // TODO -- only with feature + this.channel.emit(Events.SET_STORIES, await this.storyStore.getSetStoriesPayload()); } // This happens when a config file gets reloade @@ -224,7 +227,6 @@ export class WebPreview { try { story = await this.storyStore.loadStory({ storyId: selection.storyId }); } catch (err) { - logger.warn('Issue loading story:'); logger.warn(err); this.renderMissingStory(selection.storyId); return; From dbf9e2f26c0da8473236e77318541abd146d8303 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 30 Aug 2021 17:06:45 +1000 Subject: [PATCH 102/285] Added a new feature `storyStoreV7` --- examples/react-ts/main.ts | 2 +- .../src/preview/iframe-webpack.config.ts | 3 +-- lib/core-common/src/types.ts | 5 +++++ lib/core-server/src/build-static.ts | 2 +- lib/core-server/src/core-presets.test.ts | 2 +- lib/core-server/src/dev-server.ts | 2 +- lib/web-preview/src/WebPreview.tsx | 12 +++++++----- 7 files changed, 17 insertions(+), 11 deletions(-) diff --git a/examples/react-ts/main.ts b/examples/react-ts/main.ts index b0f001b01f1..28e9932d75f 100644 --- a/examples/react-ts/main.ts +++ b/examples/react-ts/main.ts @@ -22,8 +22,8 @@ const config: StorybookConfig = { features: { postcss: false, previewCsfV3: true, - // buildStoriesJson: true, modernInlineRender: true, + storyStoreV7: true, }, }; diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index 4f73a43ae83..3a1e9a1f03d 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -92,8 +92,7 @@ export default async ({ const configEntryPath = path.resolve(path.join(configDir, 'storybook-config-entry.js')); const virtualModuleMapping: Record = {}; - // TODO -- this is likely a separate feature onDemandStore? - if (features.buildStoriesJson) { + if (features?.storyStoreV7) { const storiesFilename = 'storybook-stories.js'; const storiesPath = path.resolve(path.join(configDir, storiesFilename)); diff --git a/lib/core-common/src/types.ts b/lib/core-common/src/types.ts index c2e850ed998..32b4db40720 100644 --- a/lib/core-common/src/types.ts +++ b/lib/core-common/src/types.ts @@ -269,6 +269,11 @@ export interface StorybookConfig { * Activate modern inline rendering */ modernInlineRender?: boolean; + + /** + * Activate on demand story store + */ + storyStoreV7?: boolean; }; /** * Tells Storybook where to find stories. diff --git a/lib/core-server/src/build-static.ts b/lib/core-server/src/build-static.ts index 78043f53735..af21da2960e 100644 --- a/lib/core-server/src/build-static.ts +++ b/lib/core-server/src/build-static.ts @@ -68,7 +68,7 @@ export async function buildStaticStandalone(options: CLIOptions & LoadOptions & }); const features = await presets.apply('features'); - if (features?.buildStoriesJson) { + if (features?.buildStoriesJson || features?.storyStoreV7) { const stories = normalizeStories(await presets.apply('stories'), { configDir: options.configDir, workingDir: process.cwd(), diff --git a/lib/core-server/src/core-presets.test.ts b/lib/core-server/src/core-presets.test.ts index 1ada0f578e6..82d7ff13103 100644 --- a/lib/core-server/src/core-presets.test.ts +++ b/lib/core-server/src/core-presets.test.ts @@ -22,7 +22,7 @@ import { outputStats } from './utils/output-stats'; // this only applies to this file jest.setTimeout(10000); -const skipStoriesJsonPreset = [{ features: { buildStoriesJson: false } }]; +const skipStoriesJsonPreset = [{ features: { buildStoriesJson: false, storyStoreV7: false } }]; jest.mock('@storybook/builder-webpack4', () => { const value = jest.fn(); diff --git a/lib/core-server/src/dev-server.ts b/lib/core-server/src/dev-server.ts index 6f433c8966a..c873af1bf5f 100644 --- a/lib/core-server/src/dev-server.ts +++ b/lib/core-server/src/dev-server.ts @@ -37,7 +37,7 @@ export async function storybookDevServer(options: Options) { await useStatics(router, options); const features = await options.presets.apply('features'); - if (features?.buildStoriesJson) { + if (features?.buildStoriesJson || features?.storyStoreV7) { await useStoriesJson(router, options); } diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 71049b70ab1..f60d1b1e606 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -22,7 +22,7 @@ import { UrlStore } from './UrlStore'; import { WebView } from './WebView'; import { NoDocs } from './NoDocs'; -const { window: globalWindow, AbortController } = global; +const { window: globalWindow, AbortController, FEATURES } = global; function focusInInput(event: Event) { const target = event.target as Element; @@ -101,8 +101,9 @@ export class WebPreview { await this.selectSpecifiedStory(); - // TODO -- only with feature - this.channel.emit(Events.SET_STORIES, await this.storyStore.getSetStoriesPayload()); + if (!FEATURES?.storyStoreV7) { + this.channel.emit(Events.SET_STORIES, await this.storyStore.getSetStoriesPayload()); + } } setupListeners() { @@ -192,8 +193,9 @@ export class WebPreview { this.selectSpecifiedStory(); } - // TODO -- only with feature - this.channel.emit(Events.SET_STORIES, await this.storyStore.getSetStoriesPayload()); + if (!FEATURES?.storyStoreV7) { + this.channel.emit(Events.SET_STORIES, await this.storyStore.getSetStoriesPayload()); + } } // This happens when a config file gets reloade From 5921d526271cef19d0e746832f80ad76cd45625a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 30 Aug 2021 17:33:49 +1000 Subject: [PATCH 103/285] Maintain component order on HMR --- lib/client-api/src/client_api.test.ts | 523 ++-------------------- lib/client-api/src/client_api.ts | 40 +- lib/core-client/src/preview/start.test.ts | 1 - lib/core-client/src/preview/start.ts | 2 +- 4 files changed, 71 insertions(+), 495 deletions(-) diff --git a/lib/client-api/src/client_api.test.ts b/lib/client-api/src/client_api.test.ts index 0dc6fc1edc9..5197a038433 100644 --- a/lib/client-api/src/client_api.test.ts +++ b/lib/client-api/src/client_api.test.ts @@ -2,32 +2,13 @@ import { logger } from '@storybook/client-logger'; import { addons, mockChannel } from '@storybook/addons'; import Events from '@storybook/core-events'; import ClientApi from './client_api'; -import ConfigApi from './config_api'; -import StoryStore from './story_store'; - -const getContext = (clientApiOptions = {}) => { - const channel = mockChannel(); - addons.setChannel(channel); - const storyStore = new StoryStore({ channel }); - const clientApi = new ClientApi({ storyStore, ...clientApiOptions }); - const configApi = new ConfigApi({ storyStore }); - - return { - configApi, - storyStore, - channel, - clientApi, - }; -}; - -jest.mock('@storybook/client-logger', () => ({ - logger: { warn: jest.fn(), log: jest.fn() }, -})); - -describe('preview.client_api', () => { + +// import ConfigApi from './config_api'; + +describe('ClientApi', () => { describe('setAddon', () => { it('should register addons', () => { - const { clientApi } = getContext(); + const clientApi = new ClientApi(); let data; clientApi.setAddon({ @@ -36,12 +17,13 @@ describe('preview.client_api', () => { }, }); + // @ts-ignore clientApi.storiesOf('none', module).aa(); expect(data).toBe('foo'); }); it('should not remove previous addons', () => { - const { clientApi } = getContext(); + const clientApi = new ClientApi(); const data = []; clientApi.setAddon({ @@ -56,12 +38,13 @@ describe('preview.client_api', () => { }, }); + // @ts-ignore clientApi.storiesOf('none', module).aa().bb(); expect(data).toEqual(['foo', 'bar']); }); it('should call with the clientApi context', () => { - const { clientApi } = getContext(); + const clientApi = new ClientApi(); let data; clientApi.setAddon({ @@ -70,12 +53,13 @@ describe('preview.client_api', () => { }, }); + // @ts-ignore clientApi.storiesOf('none', module).aa(); expect(data).toBe('function'); }); it('should be able to access addons added previously', () => { - const { clientApi } = getContext(); + const clientApi = new ClientApi(); let data; clientApi.setAddon({ @@ -90,12 +74,13 @@ describe('preview.client_api', () => { }, }); + // @ts-ignore clientApi.storiesOf('none', module).bb(); expect(data).toBe('foo'); }); it('should be able to access the current kind', () => { - const { clientApi } = getContext(); + const clientApi = new ClientApi(); const kind = 'dfdwf3e3'; let data; @@ -105,199 +90,14 @@ describe('preview.client_api', () => { }, }); + // @ts-ignore clientApi.storiesOf(kind, module).aa(); expect(data).toBe(kind); }); }); - describe('addParameters', () => { - it('should add parameters', () => { - const { clientApi, storyStore } = getContext(); - const { storiesOf } = clientApi; - - clientApi.addParameters({ a: 1 }); - storiesOf('kind', module).add('name', (_args, { parameters }) => parameters); - - const result = storyStore.fromId('kind--name').storyFn(); - // @ts-ignore - const { docs, fileName, options, argTypes, __isArgsStory, ...rest } = result; - - expect(rest).toEqual({ a: 1 }); - }); - - it('should merge options', () => { - const { clientApi, storyStore } = getContext(); - const { storiesOf } = clientApi; - - clientApi.addParameters({ options: { a: '1' } }); - clientApi.addParameters({ options: { b: '2' } }); - storiesOf('kind', module).add('name', (_args, { parameters }) => parameters); - - // @ts-ignore - const { - options: { hierarchyRootSeparator, hierarchySeparator, ...rest }, - } = storyStore.fromId('kind--name').storyFn(); - - expect(rest).toEqual({ a: '1', b: '2' }); - }); - - it('should override specific properties in options', () => { - const { clientApi, storyStore } = getContext(); - const { storiesOf } = clientApi; - - clientApi.addParameters({ backgrounds: ['value'], options: { a: '1', b: '3' } }); - clientApi.addParameters({ options: { a: '2' } }); - storiesOf('kind', module).add('name', (_args, { parameters }) => parameters); - - // @ts-ignore - const { - options: { hierarchyRootSeparator, hierarchySeparator, ...rest }, - backgrounds, - } = storyStore.fromId('kind--name').storyFn(); - - expect(backgrounds).toEqual(['value']); - expect(rest).toEqual({ a: '2', b: '3' }); - }); - - it('should replace top level properties and override specific properties in options', () => { - const { clientApi, storyStore } = getContext(); - const { storiesOf } = clientApi; - - clientApi.addParameters({ backgrounds: ['value'], options: { a: '1', b: '3' } }); - clientApi.addParameters({ backgrounds: [], options: { a: '2' } }); - storiesOf('kind', module).add('name', (_args, { parameters }) => parameters); - - // @ts-ignore - const { - options: { hierarchyRootSeparator, hierarchySeparator, ...rest }, - backgrounds, - } = storyStore.fromId('kind--name').storyFn(); - - expect(backgrounds).toEqual([]); - expect(rest).toEqual({ a: '2', b: '3' }); - }); - - it('should deep merge in options', () => { - const { clientApi, storyStore } = getContext(); - const { storiesOf } = clientApi; - - clientApi.addParameters({ options: { a: '1', b: '2', theming: { c: '3' } } }); - clientApi.addParameters({ options: { theming: { c: '4', d: '5' } } }); - storiesOf('kind', module).add('name', (_args, { parameters }) => parameters); - - // @ts-ignore - const { - options: { hierarchyRootSeparator, hierarchySeparator, ...rest }, - } = storyStore.fromId('kind--name').storyFn(); - - expect(rest).toEqual({ a: '1', b: '2', theming: { c: '4', d: '5' } }); - }); - }); - - describe('addDecorator', () => { - it('should add local decorators', () => { - const { - clientApi: { storiesOf }, - storyStore, - } = getContext(); - - storiesOf('kind', module) - .addDecorator((fn) => `aa-${fn()}`) - .add('name', () => 'Hello'); - - expect(storyStore.fromId('kind--name').storyFn()).toBe('aa-Hello'); - }); - - it('should add global decorators', () => { - const { - clientApi: { addDecorator, storiesOf }, - storyStore, - } = getContext(); - - addDecorator((fn) => `bb-${fn()}`); - - storiesOf('kind', module).add('name', () => 'Hello'); - const f = storyStore.fromId('x'); - - expect(storyStore.fromId('kind--name').storyFn()).toBe('bb-Hello'); - }); - - it('should not add global decorators twice', () => { - const { - clientApi: { addDecorator, storiesOf }, - storyStore, - } = getContext(); - - const decorator = (fn) => `bb-${fn()}`; - addDecorator(decorator); - addDecorator(decorator); // this one is ignored - - storiesOf('kind', module).add('name', () => 'Hello'); - const f = storyStore.fromId('x'); - - expect(storyStore.fromId('kind--name').storyFn()).toBe('bb-Hello'); - }); - - it('should utilize both decorators at once', () => { - const { - clientApi: { addDecorator, storiesOf }, - storyStore, - } = getContext(); - - addDecorator((fn) => `aa-${fn()}`); - - storiesOf('kind', module) - .addDecorator((fn) => `bb-${fn()}`) - .add('name', () => 'Hello'); - - expect(storyStore.fromId('kind--name').storyFn()).toBe('aa-bb-Hello'); - }); - - it('should pass the context', () => { - const { - clientApi: { storiesOf }, - storyStore, - } = getContext(); - - storiesOf('kind', module) - .addDecorator((fn) => `aa-${fn()}`) - .add('name', (_args, c) => `${c.kind}-${c.name}`); - - const result = storyStore.fromId('kind--name').storyFn(); - expect(result).toBe(`aa-kind-name`); - }); - - it('should have access to the context', () => { - const { - clientApi: { storiesOf }, - storyStore, - } = getContext(); - - storiesOf('kind', module) - .addDecorator((fn, { kind, name }) => `${kind}-${name}-${fn()}`) - .add('name', () => 'Hello'); - - const result = storyStore.fromId('kind--name').storyFn(); - expect(result).toBe(`kind-name-Hello`); - }); - }); - - describe('clearDecorators', () => { - it('should remove all global decorators', () => { - const { clientApi, storyStore } = getContext(); - const { storiesOf } = clientApi; - - clientApi.addDecorator(() => 'foo'); - clientApi.clearDecorators(); - - storiesOf('kind', module).add('name', () => 'bar'); - - const result = storyStore.fromId('kind--name').storyFn(); - expect(result).toBe(`bar`); - }); - }); - - describe('getStorybook', () => { + // TODO + describe.skip('getStorybook', () => { it('should transform the storybook to an array with filenames', () => { const { clientApi: { getStorybook, storiesOf }, @@ -399,277 +199,38 @@ describe('preview.client_api', () => { }); }); - describe('hot module loading', () => { - class MockModule { - id = 'mock-module-id'; - - hot = { - callbacks: [], - dispose(fn) { - this.callbacks.push(fn); - }, - reload() { - this.callbacks.forEach((fn) => fn()); + describe('getStoriesList', () => { + it('should remember the order that files were added in', async () => { + const clientApi = new ClientApi(); + + let disposeCallback: () => void; + const module1 = { + id: 'file1', + hot: { + data: {}, + accept: jest.fn(), + dispose(cb: () => void) { + disposeCallback = cb; + }, }, }; - } - - it('should replace a kind when the module reloads', () => { - const { - clientApi: { storiesOf, getStorybook }, - } = getContext(); - const mod = new MockModule(); - - const stories = [jest.fn(), jest.fn()]; - - expect(getStorybook()).toEqual([]); - - storiesOf('kind', (mod as unknown) as NodeModule).add('story', stories[0]); - - const firstStorybook = getStorybook(); - expect(firstStorybook).toEqual([ - { - fileName: expect.any(String), - kind: 'kind', - stories: [{ name: 'story', render: expect.anything() }], - }, - ]); - - firstStorybook[0].stories[0].render(); - expect(stories[0]).toHaveBeenCalled(); - - mod.hot.reload(); - expect(getStorybook()).toEqual([]); - - storiesOf('kind', module).add('story', stories[1]); - - const secondStorybook = getStorybook(); - expect(secondStorybook).toEqual([ - { - fileName: expect.any(String), - kind: 'kind', - stories: [{ name: 'story', render: expect.anything() }], - }, - ]); - secondStorybook[0].stories[0].render(); - expect(stories[1]).toHaveBeenCalled(); - expect(logger.warn).not.toHaveBeenCalled(); - }); - - it('should maintain kind order when the module reloads', async () => { - const { - clientApi: { storiesOf, getStorybook }, - storyStore, - channel, - } = getContext(); - const module0 = new MockModule(); - const module1 = new MockModule(); - const module2 = new MockModule(); - - const mockChannelEmit = jest.fn(); - channel.emit = mockChannelEmit; - - expect(getStorybook()).toEqual([]); + const module2 = { + id: 'file2', + }; + clientApi.storiesOf('kind1', (module1 as unknown) as NodeModule).add('story1', jest.fn()); + clientApi.storiesOf('kind2', (module2 as unknown) as NodeModule).add('story2', jest.fn()); - storyStore.startConfiguring(); - storiesOf('kind0', (module0 as unknown) as NodeModule).add('story0-docs-only', jest.fn(), { - docsOnly: true, - }); - storiesOf('kind1', (module1 as unknown) as NodeModule).add('story1', jest.fn()); - storiesOf('kind2', (module2 as unknown) as NodeModule).add('story2', jest.fn()); - storyStore.finishConfiguring(); - - let [event, args] = mockChannelEmit.mock.calls[1]; - expect(event).toEqual(Events.SET_STORIES); - expect(Object.values(args.stories as [{ kind: string }]).map((v) => v.kind)).toEqual([ - 'kind0', - 'kind1', - 'kind2', + expect(Object.keys(clientApi.getStoriesList().stories)).toEqual([ + 'kind1--story1', + 'kind2--story2', ]); - expect(getStorybook().map((story) => story.kind)).toEqual(['kind1', 'kind2']); - - mockChannelEmit.mockClear(); - // simulate an HMR of kind1, which would cause it to go to the end - // if the original order is not maintained - module1.hot.reload(); - storyStore.startConfiguring(); - storiesOf('kind1', (module1 as unknown) as NodeModule).add('story1', jest.fn()); - storyStore.finishConfiguring(); - - // eslint-disable-next-line prefer-destructuring - [event, args] = mockChannelEmit.mock.calls[1]; - - expect(event).toEqual(Events.SET_STORIES); - expect(Object.values(args.stories as [{ kind: string }]).map((v) => v.kind)).toEqual([ - 'kind0', - 'kind1', - 'kind2', + disposeCallback(); + clientApi.storiesOf('kind1', (module1 as unknown) as NodeModule).add('story1', jest.fn()); + expect(Object.keys(clientApi.getStoriesList().stories)).toEqual([ + 'kind1--story1', + 'kind2--story2', ]); - expect(getStorybook().map((story) => story.kind)).toEqual(['kind1', 'kind2']); - }); - - it('should call `module.hot.dispose` inside add and storiesOf by default', () => { - const mod = (new MockModule() as unknown) as NodeModule; - const mockHotDispose = jest.fn(); - mod.hot.dispose = mockHotDispose; - - const { - clientApi: { storiesOf, getStorybook }, - } = getContext(); - - storiesOf('kind', mod).add('story', jest.fn()); - - expect(mockHotDispose.mock.calls.length).toEqual(2); - }); - - it('should not call `module.hot.dispose` inside add when noStoryModuleAddMethodHotDispose is true', () => { - const mod = (new MockModule() as unknown) as NodeModule; - const mockHotDispose = jest.fn(); - mod.hot.dispose = mockHotDispose; - - const { - clientApi: { storiesOf, getStorybook }, - } = getContext({ noStoryModuleAddMethodHotDispose: true }); - - storiesOf('kind', mod).add('story', jest.fn()); - - expect(mockHotDispose.mock.calls.length).toEqual(1); - }); - }); - - describe('parameters', () => { - it('collects parameters across different modalities', () => { - const { - storyStore, - clientApi: { storiesOf, addParameters }, - } = getContext(); - - addParameters({ a: 'global', b: 'global', c: 'global' }); - - const kind = storiesOf('kind', module); - kind.addParameters({ b: 'kind', c: 'kind' }); - - kind.add('name', jest.fn(), { c: 'story' }); - - expect(storyStore.fromId('kind--name').parameters).toEqual({ - a: 'global', - b: 'kind', - c: 'story', - __isArgsStory: false, - fileName: expect.any(String), - argTypes: {}, - }); - }); - - it('combines object parameters per-key', () => { - const { - storyStore, - clientApi: { storiesOf, addParameters }, - } = getContext(); - - addParameters({ - addon1: 'global string value', - addon2: ['global array value'], - addon3: { - global: true, - sub: { global: true }, - }, - }); - - storiesOf('kind', module) - .addParameters({ - addon1: 'local string value', - addon2: ['local array value'], - addon3: { - local: true, - sub: { - local: true, - }, - }, - }) - .add('name', jest.fn(), { - addon1: 'local string value', - addon2: ['local array value'], - addon3: { - local: true, - sub: { - local: true, - }, - }, - }); - - expect(storyStore.fromId('kind--name').parameters).toEqual({ - addon1: 'local string value', - addon2: ['local array value'], - addon3: { - global: true, - local: true, - sub: { - global: true, - local: true, - }, - }, - __isArgsStory: false, - fileName: expect.any(String), - argTypes: {}, - }); - }); - }); - - describe('storiesOf', () => { - describe('add', () => { - it('should replace stories when adding the same story', () => { - const stories = [jest.fn().mockReturnValue('story1'), jest.fn().mockReturnValue('story2')]; - - const { - clientApi: { storiesOf, getStorybook }, - } = getContext(); - - expect(getStorybook()).toEqual([]); - - storiesOf('kind', module).add('story', stories[0]); - { - const book = getStorybook(); - expect(book).toHaveLength(1); - - const entry = book[0]; - expect(entry.kind).toMatch('kind'); - expect(entry.stories).toHaveLength(1); - expect(entry.stories[0].name).toBe('story'); - - expect(entry.stories[0].render()).toBe('story1'); - } - - storiesOf('kind', module).add('story', stories[1]); - // @ts-ignore - expect(logger.warn.mock.calls[0][0]).toMatch( - /Story with id kind--story already exists in the store/ - ); - { - const book = getStorybook(); - expect(book).toHaveLength(1); - - const entry = book[0]; - expect(entry.kind).toMatch('kind'); - expect(entry.stories).toHaveLength(1); - expect(entry.stories[0].name).toBe('story'); - - expect(entry.stories[0].render()).toBe('story2'); - } - }); - - it('should throw an error if story is in wrong format', () => { - const { - clientApi: { storiesOf }, - } = getContext(); - - expect(() => { - storiesOf('kind', module).add('test', 'String that should be a function instead' as any); - }).toThrow( - 'Cannot load story "test" in "kind" due to invalid format. Storybook expected a function/object but received string instead.' - ); - }); }); }); }); diff --git a/lib/client-api/src/client_api.ts b/lib/client-api/src/client_api.ts index 8cd31b8212a..515fa2748fb 100644 --- a/lib/client-api/src/client_api.ts +++ b/lib/client-api/src/client_api.ts @@ -19,9 +19,9 @@ import { NormalizedGlobalAnnotations, Path, StoriesList, - combineParameters, ModuleExports, ModuleImportFn, + combineParameters, } from '@storybook/store'; import { ClientApiAddons, StoryApi } from '@storybook/addons'; @@ -109,9 +109,11 @@ const invalidStoryTypes = new Set(['string', 'number', 'boolean', 'symbol']); export default class ClientApi { globalAnnotations: NormalizedGlobalAnnotations; - storiesList: StoriesList; + private fileNames: Record; + + private stories: StoriesList['stories']; - csfExports: Record; + private csfExports: Record; onImportFnChanged?: ({ importFn: ModuleImportFn }) => void; @@ -130,10 +132,7 @@ export default class ClientApi { argTypesEnhancers: [], }; - this.storiesList = { - v: 3, - stories: {}, - }; + this.stories = {}; this.csfExports = {}; @@ -148,6 +147,21 @@ export default class ClientApi { return this.csfExports[path]; } + getStoriesList() { + const fileNameOrder = Object.keys(this.csfExports); + const sortedStoryEntries = Object.entries(this.stories).sort(([id1, story1], [id2, story2]) => { + return fileNameOrder.indexOf(story1.importPath) - fileNameOrder.indexOf(story2.importPath); + }); + + return { + v: 3, + stories: sortedStoryEntries.reduce((acc, [id, entry]) => { + acc[id] = entry; + return acc; + }, {} as StoriesList['stories']), + }; + } + setAddon = deprecate( (addon: any) => { this._addons = { @@ -293,7 +307,7 @@ export default class ClientApi { }; const storyId = parameters?.__id || toId(kind, storyName); - this.storiesList.stories[storyId] = { + this.stories[storyId] = { title: csfExports.default.title, name: storyName, importPath: fileName, @@ -336,12 +350,14 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m } // Clear this module's stories from the storyList and existing exports - Object.entries(this.storiesList.stories).forEach(([id, { importPath }]) => { + Object.entries(this.stories).forEach(([id, { importPath }]) => { if (importPath === fileName) { - delete this.storiesList.stories[id]; + delete this.stories[id]; } }); - delete this.csfExports[fileName]; + + // We keep this as an empty record so we can use it to maintain component order + this.csfExports[fileName] = {}; } // NOTE: we could potentially share some of this code with the stories.json generation @@ -380,7 +396,7 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m storyNameFromExport(key); // eslint-disable-next-line no-underscore-dangle const id = storyExport.parameters?.__id || toId(title, actualName); - this.storiesList.stories[id] = { + this.stories[id] = { name: actualName, title, importPath: fileName, diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index b0934badda8..fae9ced6e4b 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -576,7 +576,6 @@ describe('start', () => { `); mockChannel.emit.mockClear(); - console.log('rerunning'); disposeCallback(module.hot.data); configure('test', () => [componentCExports], module as any); diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index d7383ecc20b..6bd8c40ede1 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -65,7 +65,7 @@ export function start( preview = new WebPreview({ importFn: (path: Path) => clientApi.importFn(path), getGlobalAnnotations, - fetchStoriesList: async () => clientApi.storiesList, + fetchStoriesList: async () => clientApi.getStoriesList(), }); clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); From 1290b1e7339c55c60b5c0d44f0fe316104c4acd9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 30 Aug 2021 21:41:57 +1000 Subject: [PATCH 104/285] Small cleanups --- lib/client-api/src/index.ts | 2 +- lib/core-client/src/preview/start.test.ts | 6 ++++-- lib/core-client/src/preview/start.ts | 5 +++-- lib/ui/src/settings/about.stories.js | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/client-api/src/index.ts b/lib/client-api/src/index.ts index 0429f02fe37..d287b8ff05f 100644 --- a/lib/client-api/src/index.ts +++ b/lib/client-api/src/index.ts @@ -6,7 +6,7 @@ import ClientApi, { addArgTypesEnhancer, setGlobalRender, getGlobalRender, -} from './client_api'; +} from './ClientApi'; import { simulatePageLoad, simulateDOMContentLoaded } from './simulate-pageload'; diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index fae9ced6e4b..fb2fb098d9c 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -1,10 +1,10 @@ import global from 'global'; -import { EventEmitter } from 'events'; import Events from '@storybook/core-events'; import { waitForRender, waitForEvents, + emitter, mockChannel, } from '@storybook/web-preview/dist/cjs/WebPreview.mockdata'; @@ -28,7 +28,9 @@ jest.mock('global', () => ({ jest.mock('@storybook/channel-postmessage', () => () => mockChannel); beforeEach(() => { - // mockChannel.emit.mockClear(); + mockChannel.emit.mockClear(); + // Preview doesn't clean itself up as it isn't designed to ever be stopped :shrug: + emitter.removeAllListeners(); }); describe('start', () => { diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 6bd8c40ede1..aefc0793d32 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -5,6 +5,7 @@ import createChannel from '@storybook/channel-postmessage'; import { addons } from '@storybook/addons'; import Events from '@storybook/core-events'; import { Path } from '@storybook/store'; +import { logger } from '@storybook/client-logger'; import { Loadable } from './types'; import { executeLoadable } from './executeLoadable'; @@ -72,8 +73,8 @@ export function start( // TODO preview .initialize() - .then(() => console.log('init!')) - .catch((err) => console.error(err)); + .then(() => {}) + .catch((err: Error) => logger.error(err)); } else { getGlobalAnnotations(); preview.onImportFnChanged({ importFn: clientApi.importFn.bind(clientApi) }); diff --git a/lib/ui/src/settings/about.stories.js b/lib/ui/src/settings/about.stories.js index 0c22e2e90ba..552bf4b2cd1 100644 --- a/lib/ui/src/settings/about.stories.js +++ b/lib/ui/src/settings/about.stories.js @@ -25,7 +25,7 @@ storiesOf('UI/Settings/AboutScreen', module) )) .add('up to date', () => ( - + )) .add('old version race condition', () => ( From ac043f901106cb3fb712971966bfc3e9671687df Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 30 Aug 2021 21:42:13 +1000 Subject: [PATCH 105/285] We need to refetch the story list when the import fn changes --- .../src/{client_api.test.ts => ClientApi.test.ts} | 0 lib/client-api/src/{client_api.ts => ClientApi.ts} | 7 ++++--- lib/store/src/StoryStore.ts | 6 ++++++ lib/web-preview/src/WebPreview.tsx | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) rename lib/client-api/src/{client_api.test.ts => ClientApi.test.ts} (100%) rename lib/client-api/src/{client_api.ts => ClientApi.ts} (98%) diff --git a/lib/client-api/src/client_api.test.ts b/lib/client-api/src/ClientApi.test.ts similarity index 100% rename from lib/client-api/src/client_api.test.ts rename to lib/client-api/src/ClientApi.test.ts diff --git a/lib/client-api/src/client_api.ts b/lib/client-api/src/ClientApi.ts similarity index 98% rename from lib/client-api/src/client_api.ts rename to lib/client-api/src/ClientApi.ts index 515fa2748fb..ccc0266800d 100644 --- a/lib/client-api/src/client_api.ts +++ b/lib/client-api/src/ClientApi.ts @@ -149,9 +149,10 @@ export default class ClientApi { getStoriesList() { const fileNameOrder = Object.keys(this.csfExports); - const sortedStoryEntries = Object.entries(this.stories).sort(([id1, story1], [id2, story2]) => { - return fileNameOrder.indexOf(story1.importPath) - fileNameOrder.indexOf(story2.importPath); - }); + const sortedStoryEntries = Object.entries(this.stories).sort( + ([id1, story1], [id2, story2]) => + fileNameOrder.indexOf(story1.importPath) - fileNameOrder.indexOf(story2.importPath) + ); return { v: 3, diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 19ba90f2179..5f572f3cc86 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -91,6 +91,12 @@ export class StoryStore { this.globals.resetOnGlobalAnnotationsChange({ globals, globalTypes }); } + async onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { + this.importFn = importFn; + // We need to refetch the stories list as it may have changed too + await this.storiesList.cacheStoriesList(); + } + async loadCSFFileByStoryId(storyId: StoryId): Promise> { const { importPath, title } = this.storiesList.storyIdToMetadata(storyId); const moduleExports = await this.importFn(importPath); diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index f60d1b1e606..96ce3236aed 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -185,7 +185,7 @@ export class WebPreview { // This happens when a glob gets HMR-ed async onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { - this.storyStore.importFn = importFn; + await this.storyStore.onImportFnChanged({ importFn }); if (this.urlStore.selection) { this.renderSelection(); From 54d3cd06fc964d523a573c22a90e5331faa91548 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 30 Aug 2021 22:50:05 +1000 Subject: [PATCH 106/285] Implemented .extract() and better getSetStoriesPayload() on store --- lib/client-api/src/story_store.test.ts | 28 ---- lib/store/src/StoriesListStore.ts | 1 - lib/store/src/StoryStore.test.ts | 174 +++++++++++++++++++++++-- lib/store/src/StoryStore.ts | 87 ++++++++++--- lib/store/src/types.ts | 4 + 5 files changed, 237 insertions(+), 57 deletions(-) diff --git a/lib/client-api/src/story_store.test.ts b/lib/client-api/src/story_store.test.ts index b3f33aee25b..e2be4c17b66 100644 --- a/lib/client-api/src/story_store.test.ts +++ b/lib/client-api/src/story_store.test.ts @@ -51,34 +51,6 @@ // } // ); -// describe('preview.story_store', () => { -// describe('extract', () => { -// it('produces stories objects with inherited (denormalized) metadata', () => { -// const store = new StoryStore({ channel }); - -// store.addGlobalMetadata({ parameters: { global: 'global' }, decorators: [] }); - -// store.addKindMetadata('a', { parameters: { kind: 'kind' }, decorators: [] }); - -// addStoryToStore(store, 'a', '1', () => 0, { story: 'story' }); -// addStoryToStore(store, 'a', '2', () => 0); -// addStoryToStore(store, 'b', '1', () => 0); - -// const extracted = store.extract(); - -// // We need exact key ordering, even if in theory JS doesn't guarantee it -// expect(Object.keys(extracted)).toEqual(['a--1', 'a--2', 'b--1']); - -// // content of item should be correct -// expect(extracted['a--1']).toMatchObject({ -// id: 'a--1', -// kind: 'a', -// name: '1', -// parameters: { global: 'global', kind: 'kind', story: 'story' }, -// }); -// }); -// }); - // describe('configuration', () => { // it('does not allow addStory if not configuring, unless allowUsafe=true', () => { // const store = new StoryStore({ channel }); diff --git a/lib/store/src/StoriesListStore.ts b/lib/store/src/StoriesListStore.ts index 850b15055cf..d350c24deca 100644 --- a/lib/store/src/StoriesListStore.ts +++ b/lib/store/src/StoriesListStore.ts @@ -37,7 +37,6 @@ export class StoriesListStore { } async onStoriesChanged() { - console.log('onStoriesChanged'); this.storiesList = await this.fetchStoriesList(); } diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index 258157bf489..62331ab44c4 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -188,10 +188,118 @@ describe('StoryStore', () => { }); }); + describe('loadAllCSFFiles', () => { + it('imports *all* csf files', async () => { + const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + await store.initialize(); + + importFn.mockClear(); + const csfFiles = await store.loadAllCSFFiles(); + + expect(Object.keys(csfFiles)).toEqual([ + './src/ComponentOne.stories.js', + './src/ComponentTwo.stories.js', + ]); + }); + }); + + describe('extract', () => { + it('throws if you have not called cacheAllCSFFiles', async () => { + const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + await store.initialize(); + + expect(() => store.extract()).toThrow(/Cannot call extract/); + }); + + it('produces objects with functions and hooks stripped', async () => { + const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + await store.initialize(); + await store.cacheAllCSFFiles(); + + expect(store.extract()).toMatchInlineSnapshot(` + Array [ + Object { + "argTypes": Object { + "a": Object { + "name": "a", + "type": Object { + "name": "string", + }, + }, + }, + "component": undefined, + "componentId": "component-one", + "id": "component-one--a", + "initialArgs": Object { + "foo": "a", + }, + "kind": "Component One", + "name": "A", + "parameters": Object { + "__isArgsStory": false, + }, + "story": "A", + "subcomponents": undefined, + "title": "Component One", + }, + Object { + "argTypes": Object { + "a": Object { + "name": "a", + "type": Object { + "name": "string", + }, + }, + }, + "component": undefined, + "componentId": "component-one", + "id": "component-one--b", + "initialArgs": Object { + "foo": "b", + }, + "kind": "Component One", + "name": "B", + "parameters": Object { + "__isArgsStory": false, + }, + "story": "B", + "subcomponents": undefined, + "title": "Component One", + }, + Object { + "argTypes": Object { + "a": Object { + "name": "a", + "type": Object { + "name": "string", + }, + }, + }, + "component": undefined, + "componentId": "component-two", + "id": "component-two--c", + "initialArgs": Object { + "foo": "c", + }, + "kind": "Component Two", + "name": "C", + "parameters": Object { + "__isArgsStory": false, + }, + "story": "C", + "subcomponents": undefined, + "title": "Component Two", + }, + ] + `); + }); + }); + describe('getSetStoriesPayload', () => { it('maps stories list to payload correctly', async () => { const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); await store.initialize(); + await store.cacheAllCSFFiles(); expect(store.getSetStoriesPayload()).toMatchInlineSnapshot(` Object { @@ -203,33 +311,81 @@ describe('StoryStore', () => { "Component One": Object {}, "Component Two": Object {}, }, - "stories": Object { - "component-one--a": Object { + "stories": Array [ + Object { + "argTypes": Object { + "a": Object { + "name": "a", + "type": Object { + "name": "string", + }, + }, + }, + "component": undefined, + "componentId": "component-one", "id": "component-one--a", + "initialArgs": Object { + "foo": "a", + }, "kind": "Component One", "name": "A", "parameters": Object { - "fileName": "./src/ComponentOne.stories.js", + "__isArgsStory": false, }, + "story": "A", + "subcomponents": undefined, + "title": "Component One", }, - "component-one--b": Object { + Object { + "argTypes": Object { + "a": Object { + "name": "a", + "type": Object { + "name": "string", + }, + }, + }, + "component": undefined, + "componentId": "component-one", "id": "component-one--b", + "initialArgs": Object { + "foo": "b", + }, "kind": "Component One", "name": "B", "parameters": Object { - "fileName": "./src/ComponentOne.stories.js", + "__isArgsStory": false, }, + "story": "B", + "subcomponents": undefined, + "title": "Component One", }, - "component-two--c": Object { + Object { + "argTypes": Object { + "a": Object { + "name": "a", + "type": Object { + "name": "string", + }, + }, + }, + "component": undefined, + "componentId": "component-two", "id": "component-two--c", + "initialArgs": Object { + "foo": "c", + }, "kind": "Component Two", "name": "C", "parameters": Object { - "fileName": "./src/ComponentTwo.stories.js", + "__isArgsStory": false, }, + "story": "C", + "subcomponents": undefined, + "title": "Component Two", }, - }, - "v": 3, + ], + "v": 2, } `); }); diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 5f572f3cc86..8c1d8797bae 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -1,5 +1,4 @@ import memoize from 'memoizerific'; - import { Parameters, StoryId, @@ -20,6 +19,8 @@ import { StoriesList, NormalizedGlobalAnnotations, NormalizedStoriesEntry, + Path, + ExtractOptions, } from './types'; import { HooksContext } from './hooks'; import { normalizeInputTypes } from './normalizeInputTypes'; @@ -55,6 +56,8 @@ export class StoryStore { hooks: Record>; + cachedCSFFiles?: Record>; + processCSFFileWithCache: typeof processCSFFile; prepareStoryWithCache: typeof prepareStory; @@ -103,6 +106,31 @@ export class StoryStore { return this.processCSFFileWithCache(moduleExports, title); } + async loadAllCSFFiles(): Promise>> { + const importPaths: Record = {}; + Object.entries(this.storiesList.storiesList.stories).forEach(([storyId, { importPath }]) => { + importPaths[importPath] = storyId; + }); + + const csfFileList = await Promise.all( + Object.entries(importPaths).map( + async ([importPath, storyId]): Promise<[Path, CSFFile]> => [ + importPath, + await this.loadCSFFileByStoryId(storyId), + ] + ) + ); + + return csfFileList.reduce((acc, [importPath, csfFile]) => { + acc[importPath] = csfFile; + return acc; + }, {} as Record>); + } + + async cacheAllCSFFiles(): Promise { + this.cachedCSFFiles = await this.loadAllCSFFiles(); + } + async loadStory({ storyId }: { storyId: StoryId }): Promise> { const csfFile = await this.loadCSFFileByStoryId(storyId); return this.storyFromCSFFile({ storyId, csfFile }); @@ -146,30 +174,51 @@ export class StoryStore { this.hooks[story.id].clean(); } + extract(options: ExtractOptions = {}) { + if (!this.cachedCSFFiles) { + throw new Error('Cannot call extract() unless you call cacheAllCSFFiles() first.'); + } + + return Object.entries(this.storiesList.storiesList.stories) + .map(([storyId, { importPath }]) => { + const csfFile = this.cachedCSFFiles[importPath]; + const story = this.storyFromCSFFile({ storyId, csfFile }); + + // TODO: docs only + if (options.includeDocsOnly && story.parameters.docsOnly) { + return false; + } + + return Object.entries(story).reduce((acc, [key, value]) => { + if (typeof value === 'function') { + return acc; + } + if (['hooks'].includes(key)) { + return acc; + } + if (Array.isArray(value)) { + return Object.assign(acc, { [key]: value.slice().sort() }); + } + return Object.assign(acc, { [key]: value }); + }, {}); + }) + .filter(Boolean); + } + getSetStoriesPayload() { - const { v, stories } = this.storiesList.storiesList; - const kindParameters: Parameters = Object.values(stories).reduce( - (acc: Parameters, { title }) => { - acc[title] = {}; - return acc; - }, - {} as Parameters - ); + const stories = this.extract(); + + const kindParameters: Parameters = stories.reduce((acc: Parameters, { title }) => { + acc[title] = {}; + return acc; + }, {} as Parameters); return { - v, + v: 2, globals: this.globals.get(), globalParameters: {}, kindParameters, - stories: Object.entries(stories).reduce((acc: any, [id, { name, title, importPath }]) => { - acc[id] = { - id, - name, - kind: title, - parameters: { fileName: importPath }, - }; - return acc; - }, {}), + stories, }; } } diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 7269393172f..8aad846fc15 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -109,3 +109,7 @@ export interface NormalizedStoriesEntry { glob?: string; specifier?: NormalizedStoriesEntrySpecifier; } + +export type ExtractOptions = { + includeDocsOnly?: boolean; +}; From 0df595a0e5bac95dce45b7460ebffef83bd462b6 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 30 Aug 2021 22:51:17 +1000 Subject: [PATCH 107/285] Small type fix --- lib/store/src/StoryStore.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 8c1d8797bae..92e56423371 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -5,6 +5,7 @@ import { StoryContextForLoaders, Framework, GlobalAnnotations, + ComponentTitle, } from '@storybook/csf'; import { StoriesListStore } from './StoriesListStore'; @@ -208,10 +209,13 @@ export class StoryStore { getSetStoriesPayload() { const stories = this.extract(); - const kindParameters: Parameters = stories.reduce((acc: Parameters, { title }) => { - acc[title] = {}; - return acc; - }, {} as Parameters); + const kindParameters: Parameters = stories.reduce( + (acc: Parameters, { title }: { title: ComponentTitle }) => { + acc[title] = {}; + return acc; + }, + {} as Parameters + ); return { v: 2, From ecf335e66e16fbbcd3047e13b6c41597ffe24933 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 16:07:29 +1000 Subject: [PATCH 108/285] Got getStorybook() going, refactor start + client-api --- lib/client-api/src/ClientApi.test.ts | 116 +---- .../src/preview/executeLoadable.ts | 45 +- lib/core-client/src/preview/start.test.ts | 432 +++++++++++++++--- lib/core-client/src/preview/start.ts | 60 +-- lib/core-client/src/preview/types.ts | 2 + lib/store/src/StoryStore.ts | 11 +- .../src/WebPreview.integration.test.ts | 3 + lib/web-preview/src/WebPreview.test.ts | 3 + lib/web-preview/src/WebPreview.tsx | 4 +- 9 files changed, 460 insertions(+), 216 deletions(-) diff --git a/lib/client-api/src/ClientApi.test.ts b/lib/client-api/src/ClientApi.test.ts index 5197a038433..a834e550246 100644 --- a/lib/client-api/src/ClientApi.test.ts +++ b/lib/client-api/src/ClientApi.test.ts @@ -1,9 +1,12 @@ -import { logger } from '@storybook/client-logger'; -import { addons, mockChannel } from '@storybook/addons'; -import Events from '@storybook/core-events'; -import ClientApi from './client_api'; +import { Path, ModuleExports } from '@storybook/store'; +import addons, { mockChannel } from '@storybook/addons'; +import ClientApi from './ClientApi'; -// import ConfigApi from './config_api'; +const getExportChanges = () => ({ added: new Map(), removed: new Map() }); + +beforeEach(() => { + addons.setChannel(mockChannel()); +}); describe('ClientApi', () => { describe('setAddon', () => { @@ -96,109 +99,6 @@ describe('ClientApi', () => { }); }); - // TODO - describe.skip('getStorybook', () => { - it('should transform the storybook to an array with filenames', () => { - const { - clientApi: { getStorybook, storiesOf }, - } = getContext(); - - let book; - - book = getStorybook(); - expect(book).toEqual([]); - - storiesOf('kind 1', module) - .add('name 1', () => '1') - .add('name 2', () => '2'); - - storiesOf('kind 2', module) - .add('name 1', () => '1') - .add('name 2', () => '2'); - - book = getStorybook(); - - expect(book).toEqual([ - expect.objectContaining({ - fileName: expect.any(String), - kind: 'kind 1', - stories: [ - { - name: 'name 1', - render: expect.any(Function), - }, - { - name: 'name 2', - render: expect.any(Function), - }, - ], - }), - expect.objectContaining({ - fileName: expect.any(String), - kind: 'kind 2', - stories: [ - { - name: 'name 1', - render: expect.any(Function), - }, - { - name: 'name 2', - render: expect.any(Function), - }, - ], - }), - ]); - }); - - it('reads filename from module', () => { - const { - clientApi: { getStorybook, storiesOf }, - } = getContext(); - - const fn = jest.fn(); - storiesOf('kind', { id: 'foo.js' } as NodeModule).add('name', fn); - - const storybook = getStorybook(); - - expect(storybook).toEqual([ - { - kind: 'kind', - fileName: 'foo.js', - stories: [ - { - name: 'name', - render: expect.any(Function), - }, - ], - }, - ]); - }); - - it('should stringify ids from module', () => { - const { - clientApi: { getStorybook, storiesOf }, - } = getContext(); - - const fn = jest.fn(); - storiesOf('kind', { id: 1211 } as NodeModule).add('name', fn); - - const storybook = getStorybook(); - - expect(storybook).toEqual([ - { - kind: 'kind', - fileName: '1211', - stories: [ - { - name: 'name', - render: expect.any(Function), - }, - ], - }, - ]); - }); - }); - describe('getStoriesList', () => { it('should remember the order that files were added in', async () => { const clientApi = new ClientApi(); diff --git a/lib/core-client/src/preview/executeLoadable.ts b/lib/core-client/src/preview/executeLoadable.ts index 7a6a713fc53..c7394360d3c 100644 --- a/lib/core-client/src/preview/executeLoadable.ts +++ b/lib/core-client/src/preview/executeLoadable.ts @@ -1,5 +1,5 @@ import { logger } from '@storybook/client-logger'; -import { ModuleExports } from '@storybook/store'; +import { Path, ModuleExports } from '@storybook/store'; import { Loadable, RequireContext, LoaderFunction } from './types'; /** @@ -7,7 +7,7 @@ import { Loadable, RequireContext, LoaderFunction } from './types'; * and returns a map of filename => module exports * * @param loadable Loadable - * @returns Map + * @returns Map */ export function executeLoadable(loadable: Loadable) { let reqs = null; @@ -18,7 +18,7 @@ export function executeLoadable(loadable: Loadable) { reqs = [loadable as RequireContext]; } - let exportsMap = new Map(); + let exportsMap = new Map(); if (reqs) { reqs.forEach((req) => { req.keys().forEach((filename: string) => { @@ -50,3 +50,42 @@ export function executeLoadable(loadable: Loadable) { return exportsMap; } + +/** + * Executes a Loadable (function that returns exports or require context(s)) + * and compares it's output to the last time it was run (as stored on a node module) + * + * @param loadable Loadable + * @param m NodeModule + * @returns { added: Map, removed: Map } + */ +export function executeLoadableForChanges(loadable: Loadable, m?: NodeModule) { + let lastExportsMap: ReturnType = + m?.hot?.data?.lastExportsMap || new Map(); + if (m?.hot?.dispose) { + m.hot.accept(); + m.hot.dispose((data) => { + // eslint-disable-next-line no-param-reassign + data.lastExportsMap = lastExportsMap; + }); + } + + const exportsMap = executeLoadable(loadable); + const added = new Map(); + Array.from(exportsMap.entries()) + // Ignore files that do not have a default export + .filter(([, fileExports]) => !!fileExports.default) + // Ignore exports that are equal (by reference) to last time, this means the file hasn't changed + .filter(([fileName, fileExports]) => lastExportsMap.get(fileName) !== fileExports) + .forEach(([fileName, fileExports]) => added.set(fileName, fileExports)); + + const removed = new Map(); + Array.from(lastExportsMap.keys()) + .filter((fileName) => !exportsMap.has(fileName)) + .forEach((fileName) => removed.set(fileName, lastExportsMap.get(fileName))); + + // Save the value for the dispose() call above + lastExportsMap = exportsMap; + + return { added, removed }; +} diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index fb2fb098d9c..0d3b94eda36 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -62,33 +62,60 @@ describe('start', () => { "Component A": Object {}, "Component B": Object {}, }, - "stories": Object { - "component-a--story-one": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--story-one", + "initialArgs": Object {}, "kind": "Component A", "name": "Story One", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component A", }, - "component-a--story-two": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--story-two", + "initialArgs": Object {}, "kind": "Component A", "name": "Story Two", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "Story Two", + "subcomponents": undefined, + "title": "Component A", }, - "component-b--story-three": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-b", "id": "component-b--story-three", + "initialArgs": Object {}, "kind": "Component B", "name": "Story Three", "parameters": Object { + "__isArgsStory": false, "fileName": "file2", + "framework": "test", }, + "story": "Story Three", + "subcomponents": undefined, + "title": "Component B", }, - }, - "v": 3, + ], + "v": 2, } `); @@ -243,25 +270,43 @@ describe('start', () => { "kindParameters": Object { "Component A": Object {}, }, - "stories": Object { - "component-a--default": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--default", + "initialArgs": Object {}, "kind": "Component A", "name": "default", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "default", + "subcomponents": undefined, + "title": "Component A", }, - "component-a--new": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--new", + "initialArgs": Object {}, "kind": "Component A", "name": "new", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "new", + "subcomponents": undefined, + "title": "Component A", }, - }, - "v": 3, + ], + "v": 2, } `); }); @@ -297,25 +342,43 @@ describe('start', () => { "Component A": Object {}, "Component B": Object {}, }, - "stories": Object { - "component-a--default": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--default", + "initialArgs": Object {}, "kind": "Component A", "name": "default", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "default", + "subcomponents": undefined, + "title": "Component A", }, - "component-b--default": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-b", "id": "component-b--default", + "initialArgs": Object {}, "kind": "Component B", "name": "default", "parameters": Object { + "__isArgsStory": false, "fileName": "file2", + "framework": "test", }, + "story": "default", + "subcomponents": undefined, + "title": "Component B", }, - }, - "v": 3, + ], + "v": 2, } `); mockChannel.emit.mockClear(); @@ -331,17 +394,26 @@ describe('start', () => { "kindParameters": Object { "Component A": Object {}, }, - "stories": Object { - "component-a--default": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--default", + "initialArgs": Object {}, "kind": "Component A", "name": "default", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "default", + "subcomponents": undefined, + "title": "Component A", }, - }, - "v": 3, + ], + "v": 2, } `); }); @@ -372,25 +444,41 @@ describe('start', () => { "kindParameters": Object { "Component C": Object {}, }, - "stories": Object { - "component-c--story-one": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-one", + "initialArgs": Object {}, "kind": "Component C", "name": "Story One", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component C", }, - "component-c--story-two": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-two", + "initialArgs": Object {}, "kind": "Component C", "name": "Story Two", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story Two", + "subcomponents": undefined, + "title": "Component C", }, - }, - "v": 3, + ], + "v": 2, } `); @@ -484,33 +572,57 @@ describe('start', () => { "kindParameters": Object { "Component C": Object {}, }, - "stories": Object { - "component-c--story-one": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-one", + "initialArgs": Object {}, "kind": "Component C", "name": "Story One", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component C", }, - "component-c--story-three": Object { - "id": "component-c--story-three", + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", + "id": "component-c--story-two", + "initialArgs": Object {}, "kind": "Component C", - "name": "Story Three", + "name": "Story Two", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story Two", + "subcomponents": undefined, + "title": "Component C", }, - "component-c--story-two": Object { - "id": "component-c--story-two", + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", + "id": "component-c--story-three", + "initialArgs": Object {}, "kind": "Component C", - "name": "Story Two", + "name": "Story Three", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story Three", + "subcomponents": undefined, + "title": "Component C", }, - }, - "v": 3, + ], + "v": 2, } `); }); @@ -547,33 +659,57 @@ describe('start', () => { "Component C": Object {}, "Component D": Object {}, }, - "stories": Object { - "component-c--story-one": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-one", + "initialArgs": Object {}, "kind": "Component C", "name": "Story One", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component C", }, - "component-c--story-two": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-two", + "initialArgs": Object {}, "kind": "Component C", "name": "Story Two", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story Two", + "subcomponents": undefined, + "title": "Component C", }, - "component-d--story-four": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-d", "id": "component-d--story-four", + "initialArgs": Object {}, "kind": "Component D", "name": "Story Four", "parameters": Object { - "fileName": "exports-map-1", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story Four", + "subcomponents": undefined, + "title": "Component D", }, - }, - "v": 3, + ], + "v": 2, } `); @@ -591,25 +727,41 @@ describe('start', () => { "kindParameters": Object { "Component C": Object {}, }, - "stories": Object { - "component-c--story-one": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-one", + "initialArgs": Object {}, "kind": "Component C", "name": "Story One", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component C", }, - "component-c--story-two": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-two", + "initialArgs": Object {}, "kind": "Component C", "name": "Story Two", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story Two", + "subcomponents": undefined, + "title": "Component C", }, - }, - "v": 3, + ], + "v": 2, } `); }); @@ -645,49 +797,92 @@ describe('start', () => { "Component B": Object {}, "Component C": Object {}, }, - "stories": Object { - "component-a--story-one": Object { + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--story-one", + "initialArgs": Object {}, "kind": "Component A", "name": "Story One", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component A", }, - "component-a--story-two": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", "id": "component-a--story-two", + "initialArgs": Object {}, "kind": "Component A", "name": "Story Two", "parameters": Object { + "__isArgsStory": false, "fileName": "file1", + "framework": "test", }, + "story": "Story Two", + "subcomponents": undefined, + "title": "Component A", }, - "component-b--story-three": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-b", "id": "component-b--story-three", + "initialArgs": Object {}, "kind": "Component B", "name": "Story Three", "parameters": Object { + "__isArgsStory": false, "fileName": "file2", + "framework": "test", }, + "story": "Story Three", + "subcomponents": undefined, + "title": "Component B", }, - "component-c--story-one": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-one", + "initialArgs": Object {}, "kind": "Component C", "name": "Story One", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component C", }, - "component-c--story-two": Object { + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-c", "id": "component-c--story-two", + "initialArgs": Object {}, "kind": "Component C", "name": "Story Two", "parameters": Object { - "fileName": "exports-map-0", + "__isArgsStory": false, + "framework": "test", }, + "story": "Story Two", + "subcomponents": undefined, + "title": "Component C", }, - }, - "v": 3, + ], + "v": 2, } `); @@ -704,4 +899,109 @@ describe('start', () => { ); }); }); + + // These tests need to be in here, as they require a convoluted hookup between + // a ClientApi and a StoryStore + describe('ClientApi.getStorybook', () => { + it('should transform the storybook to an array with filenames', async () => { + const { configure, clientApi } = start(jest.fn); + + let book; + + book = clientApi.getStorybook(); + expect(book).toEqual([]); + + await configure('test', () => { + clientApi + .storiesOf('kind 1', { id: 'file1' } as any) + .add('name 1', () => '1') + .add('name 2', () => '2'); + + clientApi + .storiesOf('kind 2', { id: 'file2' } as any) + .add('name 1', () => '1') + .add('name 2', () => '2'); + }); + book = clientApi.getStorybook(); + + expect(book).toEqual([ + expect.objectContaining({ + fileName: expect.any(String), + kind: 'kind 1', + stories: [ + { + name: 'name 1', + render: expect.any(Function), + }, + { + name: 'name 2', + render: expect.any(Function), + }, + ], + }), + expect.objectContaining({ + fileName: expect.any(String), + kind: 'kind 2', + stories: [ + { + name: 'name 1', + render: expect.any(Function), + }, + { + name: 'name 2', + render: expect.any(Function), + }, + ], + }), + ]); + }); + + it('reads filename from module', async () => { + const { configure, clientApi } = start(jest.fn); + + const fn = jest.fn(); + await configure('test', () => { + clientApi.storiesOf('kind', { id: 'foo.js' } as NodeModule).add('name', fn); + }); + + const storybook = clientApi.getStorybook(); + + expect(storybook).toEqual([ + { + kind: 'kind', + fileName: 'foo.js', + stories: [ + { + name: 'name', + render: expect.any(Function), + }, + ], + }, + ]); + }); + + it('should stringify ids from module', async () => { + const { configure, clientApi } = start(jest.fn); + + const fn = jest.fn(); + await configure('test', () => { + clientApi.storiesOf('kind', { id: 1211 } as any).add('name', fn); + }); + + const storybook = clientApi.getStorybook(); + + expect(storybook).toEqual([ + { + kind: 'kind', + fileName: '1211', + stories: [ + { + name: 'name', + render: expect.any(Function), + }, + ], + }, + ]); + }); + }); }); diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index aefc0793d32..973788c94a6 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -5,20 +5,19 @@ import createChannel from '@storybook/channel-postmessage'; import { addons } from '@storybook/addons'; import Events from '@storybook/core-events'; import { Path } from '@storybook/store'; -import { logger } from '@storybook/client-logger'; import { Loadable } from './types'; -import { executeLoadable } from './executeLoadable'; +import { executeLoadableForChanges } from './executeLoadable'; export function start( - render: WebGlobalAnnotations['renderToDOM'], + renderToDOM: WebGlobalAnnotations['renderToDOM'], { decorateStory }: { decorateStory?: WebGlobalAnnotations['applyDecorators'] } = {} ) { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); - const clientApi = new ClientApi(); let preview: WebPreview; + const clientApi = new ClientApi(); return { forceReRender: () => channel.emit(Events.FORCE_RE_RENDER), @@ -26,58 +25,47 @@ export function start( raw: (): void => {}, clientApi, - configure(framework: string, loadable: Loadable, m?: NodeModule) { - let lastExportsMap: ReturnType = - m?.hot?.data?.lastExportsMap || new Map(); - if (m?.hot?.dispose) { - m.hot.accept(); - m.hot.dispose((data) => { - // eslint-disable-next-line no-param-reassign - data.lastExportsMap = lastExportsMap; - }); - } - + // This gets called each time the user calls configure (i.e. once per HMR) + // The first time, it constructs the preview, subsequently it updates it + async configure(framework: string, loadable: Loadable, m?: NodeModule) { clientApi.addParameters({ framework }); + // We need to run the `executeLoadableForChanges` function *inside* the `getGlobalAnnotations + // function in case it throws. So we also need to process its output there also const getGlobalAnnotations = () => { - const exportsMap = executeLoadable(loadable); - Array.from(exportsMap.entries()) - .filter(([, fileExports]) => !!fileExports.default) - .forEach(([fileName, fileExports]) => { - // Exports haven't changed so there is so no need to do anything - if (lastExportsMap.get(fileName) === fileExports) { - return; - } + const { added, removed } = executeLoadableForChanges(loadable, m); + + Array.from(added.entries()).forEach(([fileName, fileExports]) => + clientApi.addStoriesFromExports(fileName, fileExports) + ); - clientApi.addStoriesFromExports(fileName, fileExports); - }); - Array.from(lastExportsMap.keys()) - .filter((fileName) => !exportsMap.has(fileName)) - .forEach((fileName) => clientApi.clearFilenameExports(fileName)); - lastExportsMap = exportsMap; + Array.from(removed.entries()).forEach(([fileName]) => + clientApi.clearFilenameExports(fileName) + ); return { ...clientApi.globalAnnotations, - renderToDOM: render, + renderToDOM, applyDecorators: decorateStory, }; }; + if (!preview) { preview = new WebPreview({ importFn: (path: Path) => clientApi.importFn(path), getGlobalAnnotations, fetchStoriesList: async () => clientApi.getStoriesList(), }); + + // These two bits are a bit ugly, but due to dependencies, `ClientApi` cannot have + // direct reference to `WebPreview`, so we need to patch in bits clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); + clientApi.storyStore = preview.storyStore; - // TODO - preview - .initialize() - .then(() => {}) - .catch((err: Error) => logger.error(err)); + await preview.initialize({ cacheAllCSFFiles: true }); } else { getGlobalAnnotations(); - preview.onImportFnChanged({ importFn: clientApi.importFn.bind(clientApi) }); + preview.onImportFnChanged({ importFn: (path: Path) => clientApi.importFn(path) }); } }, }; diff --git a/lib/core-client/src/preview/types.ts b/lib/core-client/src/preview/types.ts index 7dcc960038b..f5f8aa08021 100644 --- a/lib/core-client/src/preview/types.ts +++ b/lib/core-client/src/preview/types.ts @@ -1,3 +1,5 @@ +import { ModuleExports, Path } from '@storybook/store'; + export interface PreviewError { message?: string; stack?: string; diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 92e56423371..aaf89ebfba7 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -85,8 +85,12 @@ export class StoryStore { this.prepareStoryWithCache = memoize(STORY_CACHE_SIZE)(prepareStory) as typeof prepareStory; } - async initialize() { + async initialize({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { await this.storiesList.initialize(); + + if (cacheAllCSFFiles) { + await this.cacheAllCSFFiles(); + } } updateGlobalAnnotations(globalAnnotations: GlobalAnnotations) { @@ -97,8 +101,13 @@ export class StoryStore { async onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { this.importFn = importFn; + // We need to refetch the stories list as it may have changed too await this.storiesList.cacheStoriesList(); + + if (this.cachedCSFFiles) { + await this.cacheAllCSFFiles(); + } } async loadCSFFileByStoryId(storyId: StoryId): Promise> { diff --git a/lib/web-preview/src/WebPreview.integration.test.ts b/lib/web-preview/src/WebPreview.integration.test.ts index 09ac9c4ee6c..aef86bf35e2 100644 --- a/lib/web-preview/src/WebPreview.integration.test.ts +++ b/lib/web-preview/src/WebPreview.integration.test.ts @@ -35,6 +35,9 @@ jest.mock('global', () => ({ search: '?id=*', }, }, + FEATURES: { + storyStoreV7: true, + }, })); beforeEach(() => { diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index 16fbab23ccb..a48aaea3892 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -31,6 +31,9 @@ jest.mock('global', () => ({ search: '?id=*', }, }, + FEATURES: { + storyStoreV7: true, + }, })); jest.mock('@storybook/client-logger'); diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 96ce3236aed..6e264664476 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -86,8 +86,8 @@ export class WebPreview { } } - async initialize() { - await this.storyStore.initialize(); + async initialize({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { + await this.storyStore.initialize({ cacheAllCSFFiles }); this.setupListeners(); const { globals } = this.urlStore.selectionSpecifier || {}; From 966a023322ea783a317b4f04870525054882e4ac Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 16:18:41 +1000 Subject: [PATCH 109/285] Somehow this got lost --- lib/client-api/src/ClientApi.ts | 58 +++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index ccc0266800d..e656ae44931 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -1,4 +1,3 @@ -/* eslint no-underscore-dangle: 0 */ import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; import { logger } from '@storybook/client-logger'; @@ -13,6 +12,7 @@ import { StoryFn, sanitize, storyNameFromExport, + ComponentTitle, } from '@storybook/csf'; import { NormalizedComponentAnnotations, @@ -22,10 +22,22 @@ import { ModuleExports, ModuleImportFn, combineParameters, + StoryStore, } from '@storybook/store'; import { ClientApiAddons, StoryApi } from '@storybook/addons'; +export interface GetStorybookStory { + name: string; + render: StoryFn; +} + +export interface GetStorybookKind { + kind: string; + fileName: string; + stories: GetStorybookStory[]; +} + // ClientApi (and StoreStore) are really singletons. However they are not created until the // relevant framework instanciates them via `start.js`. The good news is this happens right away. let singleton: ClientApi; @@ -109,19 +121,19 @@ const invalidStoryTypes = new Set(['string', 'number', 'boolean', 'symbol']); export default class ClientApi { globalAnnotations: NormalizedGlobalAnnotations; - private fileNames: Record; + storyStore?: StoryStore; + + onImportFnChanged?: ({ importFn: ModuleImportFn }) => void; private stories: StoriesList['stories']; private csfExports: Record; - onImportFnChanged?: ({ importFn: ModuleImportFn }) => void; - - private _addons: ClientApiAddons; + private addons: ClientApiAddons; // If we don't get passed modules so don't know filenames, we can // just use numeric indexes - private _lastFileName = 0; + private lastFileName = 0; constructor() { this.globalAnnotations = { @@ -136,7 +148,7 @@ export default class ClientApi { this.csfExports = {}; - this._addons = {}; + this.addons = {}; singleton = this; } @@ -165,10 +177,7 @@ export default class ClientApi { setAddon = deprecate( (addon: any) => { - this._addons = { - ...this._addons, - ...addon, - }; + this.addons = { ...this.addons, ...addon }; }, dedent` \`setAddon\` is deprecated and will be removed in Storybook 7.0. @@ -234,7 +243,7 @@ export default class ClientApi { } // eslint-disable-next-line no-plusplus - const fileName = m && m.id ? `${m.id}` : (this._lastFileName++).toString(); + const fileName = m && m.id ? `${m.id}` : (this.lastFileName++).toString(); if (m && m.hot && m.hot.accept) { // This module used storiesOf(), so when it re-runs on HMR, it will reload @@ -264,8 +273,8 @@ export default class ClientApi { }; // apply addons - Object.keys(this._addons).forEach((name) => { - const addon = this._addons[name]; + Object.keys(this.addons).forEach((name) => { + const addon = this.addons[name]; api[name] = (...args: any[]) => { addon.apply(api, args); return api; @@ -405,8 +414,23 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m }); } - // TODO - getStorybook: () => []; + getStorybook(): GetStorybookKind[] { + const storiesList = this.getStoriesList(); + + const kinds: Record> = {}; + Object.entries(storiesList.stories).forEach(([storyId, { title, name, importPath }]) => { + if (!kinds[title]) { + kinds[title] = { kind: title, fileName: importPath, stories: [] }; + } - raw: () => []; + const csfFile = this.storyStore.cachedCSFFiles[importPath]; + const { unboundStoryFn } = this.storyStore.storyFromCSFFile({ + storyId, + csfFile, + }); + kinds[title].stories.push({ name, render: unboundStoryFn }); + }); + + return Object.values(kinds); + } } From e88f66e958a217406c12a0da249345ad96cf61cd Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 16:20:07 +1000 Subject: [PATCH 110/285] Fix type --- lib/client-api/src/ClientApi.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index e656ae44931..9cdfa3c7465 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -123,7 +123,7 @@ export default class ClientApi { storyStore?: StoryStore; - onImportFnChanged?: ({ importFn: ModuleImportFn }) => void; + onImportFnChanged?: ({ importFn }: { importFn: ModuleImportFn }) => void; private stories: StoriesList['stories']; @@ -404,7 +404,6 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m storyExport.storyName || storyExport.story?.name || storyNameFromExport(key); - // eslint-disable-next-line no-underscore-dangle const id = storyExport.parameters?.__id || toId(title, actualName); this.stories[id] = { name: actualName, From bee50c814930dddd256e31da84f350efaa49c517 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 16:21:18 +1000 Subject: [PATCH 111/285] Add errors for removed APIs --- lib/client-api/src/ClientApi.ts | 4 ++++ lib/store/src/StoryStore.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 9cdfa3c7465..b584f9a7621 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -432,4 +432,8 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m return Object.values(kinds); } + + raw() { + return this.storyStore.raw(); + } } diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index aaf89ebfba7..758142433b8 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -234,4 +234,16 @@ export class StoryStore { stories, }; } + + raw() { + throw new Error( + `StoryStore.raw() is no longer implemented. If you were relying on this API, please contact us on Discord.` + ); + } + + fromId() { + throw new Error( + `StoryStore.fromId() is no longer implemented. If you were relying on this API, please contact us on Discord.` + ); + } } From 3ee15379a1beaae7c8d957b0033fe5d246abf061 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 16:45:44 +1000 Subject: [PATCH 112/285] Update decorators to use a common sanitization --- .../src/client/preview/decorateStory.ts | 19 ++++++------- app/svelte/package.json | 1 + app/svelte/src/client/preview/decorators.ts | 19 ++++++------- app/vue/package.json | 1 + app/vue/src/client/preview/index.ts | 12 ++++----- app/vue3/package.json | 1 + app/vue3/src/client/preview/index.ts | 12 ++++----- lib/store/src/decorators.ts | 27 ++++++++++++++++--- 8 files changed, 53 insertions(+), 39 deletions(-) diff --git a/app/angular/src/client/preview/decorateStory.ts b/app/angular/src/client/preview/decorateStory.ts index 505ac674d64..239633f29cb 100644 --- a/app/angular/src/client/preview/decorateStory.ts +++ b/app/angular/src/client/preview/decorateStory.ts @@ -1,4 +1,5 @@ -import { DecoratorFunction, StoryContext, StoryContextUpdate, StoryFn } from '@storybook/csf'; +import { DecoratorFunction, StoryContext, StoryFn } from '@storybook/csf'; +import { sanitizeStoryContextUpdate } from '@storybook/store'; import { computesTemplateFromComponent } from './angular-beta/ComputesTemplateFromComponent'; import { AngularFramework } from './types-6-0'; @@ -11,16 +12,12 @@ export default function decorateStory( (previousStoryFn: StoryFn, decorator) => ( context: StoryContext ) => { - const decoratedStory = decorator( - ({ args, globals }: StoryContextUpdate = {} as StoryContextUpdate) => { - return previousStoryFn({ - ...context, - ...(args && { args }), - ...(globals && { globals }), - }); - }, - context - ); + const decoratedStory = decorator((update) => { + return previousStoryFn({ + ...context, + ...sanitizeStoryContextUpdate(update), + }); + }, context); return decoratedStory; }, diff --git a/app/svelte/package.json b/app/svelte/package.json index 1868a8c1b53..e62b6634c92 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -49,6 +49,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/store": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", "react": "16.14.0", diff --git a/app/svelte/src/client/preview/decorators.ts b/app/svelte/src/client/preview/decorators.ts index 33ccbdb8ffb..f784c17b746 100644 --- a/app/svelte/src/client/preview/decorators.ts +++ b/app/svelte/src/client/preview/decorators.ts @@ -1,4 +1,5 @@ import { StoryFn, DecoratorFunction, StoryContext, StoryContextUpdate } from '@storybook/csf'; +import { sanitizeStoryContextUpdate } from '@storybook/store'; import SlotDecorator from './SlotDecorator.svelte'; import { SvelteFramework } from './types'; @@ -68,17 +69,13 @@ export function decorateStory(storyFn: any, decorators: any[]) { context: StoryContext ) => { let story; - const decoratedStory = decorator( - ({ args, globals }: StoryContextUpdate = {} as StoryContextUpdate) => { - story = previousStoryFn({ - ...context, - ...(args && { args }), - ...(globals && { globals }), - }); - return story; - }, - context - ); + const decoratedStory = decorator((update) => { + story = previousStoryFn({ + ...context, + ...sanitizeStoryContextUpdate(update), + }); + return story; + }, context); if (!story) { story = previousStoryFn(context); diff --git a/app/vue/package.json b/app/vue/package.json index a8ff149d86d..3b81cdee416 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -49,6 +49,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/src/client/preview/index.ts b/app/vue/src/client/preview/index.ts index c4e46e1de34..7ecf4990efc 100644 --- a/app/vue/src/client/preview/index.ts +++ b/app/vue/src/client/preview/index.ts @@ -3,6 +3,7 @@ import Vue, { VueConstructor, ComponentOptions } from 'vue'; import { start } from '@storybook/core/client'; import { StoryFn, DecoratorFunction, StoryContext, StoryContextUpdate } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; +import { sanitizeStoryContextUpdate } from '@storybook/store'; import './globals'; import { IStorybookSection, StoryFnVueReturnType } from './types'; @@ -67,13 +68,10 @@ function decorateStory( (decorated: StoryFn, decorator) => (context: StoryContext) => { let story; - const decoratedStory = decorator( - ({ args, globals }: StoryContextUpdate = {} as StoryContextUpdate) => { - story = decorated({ ...context, ...(args && { args }), ...(globals && { globals }) }); - return story; - }, - context - ); + const decoratedStory = decorator((update) => { + story = decorated({ ...context, ...sanitizeStoryContextUpdate(update) }); + return story; + }, context); if (!story) { story = decorated(context); diff --git a/app/vue3/package.json b/app/vue3/package.json index 8af995eb9a0..59506dea90e 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -49,6 +49,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue3/src/client/preview/index.ts b/app/vue3/src/client/preview/index.ts index 86ca74807e0..9271a54160b 100644 --- a/app/vue3/src/client/preview/index.ts +++ b/app/vue3/src/client/preview/index.ts @@ -9,6 +9,7 @@ import { LegacyStoryFn, } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; +import { sanitizeStoryContextUpdate } from '@storybook/store'; import './globals'; import { IStorybookSection, StoryFnVueReturnType } from './types'; @@ -61,13 +62,10 @@ function decorateStory( ) => { let story: VueFramework['storyResult']; - const decoratedStory: VueFramework['storyResult'] = decorator( - ({ args, globals }: StoryContextUpdate = {} as StoryContextUpdate) => { - story = decorated({ ...context, ...(args && { args }), ...(globals && { globals }) }); - return story; - }, - context - ); + const decoratedStory: VueFramework['storyResult'] = decorator((update) => { + story = decorated({ ...context, ...sanitizeStoryContextUpdate(update) }); + return story; + }, context); if (!story) { story = decorated(context); diff --git a/lib/store/src/decorators.ts b/lib/store/src/decorators.ts index 1e4c3972f8d..2772a0bf3ab 100644 --- a/lib/store/src/decorators.ts +++ b/lib/store/src/decorators.ts @@ -22,6 +22,28 @@ export function decorateStory( type ContextStore = { value?: StoryContext }; +/** + * Currently StoryContextUpdates are allowed to have any key in the type. + * However, you cannot overwrite any of the build-it "static" keys. + * + * @param inputContextUpdate StoryContextUpdate + * @returns StoryContextUpdate + */ +export function sanitizeStoryContextUpdate({ + componentId, + title, + kind, + id, + name, + story, + parameters, + initialArgs, + argTypes, + ...update +}: StoryContextUpdate = {}): StoryContextUpdate { + return update; +} + export function defaultDecorateStory( storyFn: LegacyStoryFn, decorators: DecoratorFunction[] @@ -46,11 +68,10 @@ export function defaultDecorateStory( */ const bindWithContext = ( decoratedStoryFn: LegacyStoryFn - ): PartialStoryFn => ({ args, globals } = {} as StoryContextUpdate) => { + ): PartialStoryFn => (update) => { contextStore.value = { ...contextStore.value, - ...(args && { args }), - ...(globals && { globals }), + ...sanitizeStoryContextUpdate(update), }; return decoratedStoryFn(contextStore.value); }; From c3dfc33d0397c3a36002fa1252562396cb330c3a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 16:48:08 +1000 Subject: [PATCH 113/285] Type finangling --- lib/web-preview/src/WebPreview.tsx | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 6e264664476..4befce7452e 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -4,7 +4,15 @@ import Events from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; import global from 'global'; import { addons, Channel } from '@storybook/addons'; -import { Framework, StoryId, GlobalAnnotations, Args, Globals, ViewMode } from '@storybook/csf'; +import { + Framework, + StoryId, + GlobalAnnotations, + Args, + Globals, + ViewMode, + StoryContextForLoaders, +} from '@storybook/csf'; import { ModuleImportFn, Selection, @@ -286,10 +294,11 @@ export class WebPreview { storyById: (storyId: StoryId) => this.storyStore.storyFromCSFFile({ storyId, csfFile }), componentStories: () => this.storyStore.componentStoriesFromCSFFile({ csfFile }), renderStoryToElement: this.renderStoryToElement.bind(this), - getStoryContext: (renderedStory: Story) => ({ - ...this.storyStore.getStoryContext(renderedStory), - viewMode: 'docs' as ViewMode, - }), + getStoryContext: (renderedStory: Story) => + ({ + ...this.storyStore.getStoryContext(renderedStory), + viewMode: 'docs' as ViewMode, + } as StoryContextForLoaders), }; const { docs } = story.parameters; @@ -359,7 +368,10 @@ export class WebPreview { }); const viewMode = element === this.view.storyRoot() ? 'story' : 'docs'; - const loadedContext = await applyLoaders({ ...storyContext, viewMode }); + const loadedContext = await applyLoaders({ + ...storyContext, + viewMode, + } as StoryContextForLoaders); if (controller.signal.aborted) { return; } From 82d2b572287b863cf38484e88b2870be016d711c Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 19:00:41 +1000 Subject: [PATCH 114/285] Upgrade CSF again --- addons/a11y/package.json | 2 +- addons/actions/package.json | 2 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/links/package.json | 2 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 3 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 3 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 3 +- lib/addons/package.json | 2 +- lib/api/package.json | 2 +- lib/client-api/package.json | 2 +- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- lib/web-preview/package.json | 2 +- yarn.lock | 64 ++++++++++--------- 26 files changed, 64 insertions(+), 55 deletions(-) diff --git a/addons/a11y/package.json b/addons/a11y/package.json index f08f8184698..4dadc3b51bb 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/theming": "6.4.0-alpha.19", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/actions/package.json b/addons/actions/package.json index 78f6f21cfd2..c2b76c82683 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/controls/package.json b/addons/controls/package.json index 6b7afd682c5..2fe5f7673d0 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", diff --git a/addons/docs/package.json b/addons/docs/package.json index 856d514584c..d9f19f7decf 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/postinstall": "6.4.0-alpha.19", diff --git a/addons/links/package.json b/addons/links/package.json index 46a22f7d4a5..170e6a7823e 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/router": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index cd832eec042..fe0ada88123 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index 245c1be6cf7..114663ec05f 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/node-logger": "6.4.0-alpha.19", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index b28c2141041..1e5bdff81b1 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index 8a6d501c52a..dca82bc9039 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,8 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/preact/package.json b/app/preact/package.json index 5fd15cd364c..fae342cdbcf 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/react/package.json b/app/react/package.json index 304c65a01fa..0cbad212b41 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index 9ceabca51a6..d257e4a6820 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,8 +50,9 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/node-logger": "6.4.0-alpha.19", + "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/svelte/package.json b/app/svelte/package.json index e62b6634c92..38251ed4bfe 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/store": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index 3b81cdee416..d8416fbc8ab 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index 59506dea90e..356c6111c76 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index 2eedbef192c..171d918a4a6 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,8 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "babel-plugin-bundled-import-meta": "^0.3.1", "core-js": "^3.8.2", diff --git a/lib/addons/package.json b/lib/addons/package.json index 52a96e42801..806f4599b86 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/api/package.json b/lib/api/package.json index 0321fb877b6..af8d00bb1d4 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.19", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index ce616f220a1..444384fd488 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -46,7 +46,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/store": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index 754a7c37333..0eeaae921bb 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index 082c750a019..487e017d4c7 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/theming": "6.4.0-alpha.19", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index f1bc62e078f..58338e77666 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/store": "6.4.0-alpha.19", "@storybook/ui": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index ea95302b0fd..2a3a2a67b0f 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index f3738311c98..f575e8995af 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -44,7 +44,7 @@ "@storybook/channel-websocket": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/lib/web-preview/package.json b/lib/web-preview/package.json index 715846f5482..0d221f96dd5 100644 --- a/lib/web-preview/package.json +++ b/lib/web-preview/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.cc8c2b0.0", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/store": "6.4.0-alpha.19", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/yarn.lock b/yarn.lock index f28e233348a..78340f95b96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5536,7 +5536,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/theming": 6.4.0-alpha.19 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -5567,7 +5567,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/theming": 6.4.0-alpha.19 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -5629,7 +5629,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 @@ -5672,7 +5672,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/postinstall": 6.4.0-alpha.19 @@ -5856,7 +5856,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/router": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -5943,7 +5943,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/node-logger": 6.4.0-alpha.19 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -5972,7 +5972,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/react": 6.4.0-alpha.19 "@storybook/vue": 6.4.0-alpha.19 "@storybook/vue3": 6.4.0-alpha.19 @@ -6135,7 +6135,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6168,7 +6168,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@types/autoprefixer": ^9.7.2 @@ -6237,7 +6237,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.19 @@ -6519,7 +6519,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/store": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -6555,7 +6555,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6577,7 +6577,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/theming": 6.4.0-alpha.19 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -6616,7 +6616,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 @@ -6814,12 +6814,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.cc8c2b0.0": - version: 0.0.2--canary.cc8c2b0.0 - resolution: "@storybook/csf@npm:0.0.2--canary.cc8c2b0.0" +"@storybook/csf@npm:0.0.2--canary.c10361d.0": + version: 0.0.2--canary.c10361d.0 + resolution: "@storybook/csf@npm:0.0.2--canary.c10361d.0" dependencies: lodash: ^4.17.15 - checksum: c0e2eb7349e3bf14d32d2020dd70cdd89cb5cf2444f4780efb6594a0290038b5ac6dce5186215510d20c5c6f152105a7663b2065d65c955848435821a0bf9e0e + checksum: 9534f6c87d1e109c692a9202e228eed07f0508ea2bfee9e36214dcc8519e86f09d80a40ed435281fe1555ef5d682e02c4211900e5b3a7ff81017878e2a73c77c languageName: node linkType: hard @@ -6955,7 +6955,8 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7155,7 +7156,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7235,7 +7236,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -7532,8 +7533,9 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/node-logger": 6.4.0-alpha.19 + "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -7559,7 +7561,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -7581,7 +7583,7 @@ __metadata: "@storybook/channel-websocket": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -7599,7 +7601,8 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7698,7 +7701,8 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 "@vue/compiler-sfc": ^3.0.0 @@ -7734,7 +7738,8 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7776,7 +7781,8 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 babel-plugin-bundled-import-meta: ^0.3.1 core-js: ^3.8.2 @@ -7804,7 +7810,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.cc8c2b0.0 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/store": 6.4.0-alpha.19 ansi-to-html: ^0.6.11 core-js: ^3.8.2 From e1268c751d6d3b1361d02d612c3c78a740c246a6 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 19:00:56 +1000 Subject: [PATCH 115/285] Clean up some exported APIs --- app/html/src/client/preview/render.ts | 2 +- app/server/src/client/preview/render.ts | 2 +- .../src/client/preview/render.ts | 2 +- lib/client-api/src/index.ts | 12 ------------ lib/client-api/src/queryparams.ts | 18 ------------------ lib/web-preview/src/index.ts | 1 + .../src/simulate-pageload.ts | 0 7 files changed, 4 insertions(+), 33 deletions(-) delete mode 100644 lib/client-api/src/queryparams.ts rename lib/{client-api => web-preview}/src/simulate-pageload.ts (100%) diff --git a/app/html/src/client/preview/render.ts b/app/html/src/client/preview/render.ts index 919fbd49a1a..ffe562db5b3 100644 --- a/app/html/src/client/preview/render.ts +++ b/app/html/src/client/preview/render.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import global from 'global'; import dedent from 'ts-dedent'; -import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/client-api'; +import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; import { RenderContext } from './types'; import { HtmlFramework } from './types-6-0'; diff --git a/app/server/src/client/preview/render.ts b/app/server/src/client/preview/render.ts index 18019c43aef..c299d97fa2e 100644 --- a/app/server/src/client/preview/render.ts +++ b/app/server/src/client/preview/render.ts @@ -2,7 +2,7 @@ import global from 'global'; import dedent from 'ts-dedent'; import { Args, ArgTypes } from '@storybook/api'; -import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/client-api'; +import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; import { RenderContext, FetchStoryHtmlType, ServerFramework } from './types'; const { fetch, Node } = global; diff --git a/app/web-components/src/client/preview/render.ts b/app/web-components/src/client/preview/render.ts index 876bab192f1..807380682e4 100644 --- a/app/web-components/src/client/preview/render.ts +++ b/app/web-components/src/client/preview/render.ts @@ -5,7 +5,7 @@ import { render, TemplateResult } from 'lit-html'; // Keep `.js` extension to avoid issue with Webpack (related to export map?) // eslint-disable-next-line import/extensions import { isTemplateResult } from 'lit-html/directive-helpers.js'; -import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/client-api'; +import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; import { RenderContext } from './types'; import { WebComponentsFramework } from './types-6-0'; diff --git a/lib/client-api/src/index.ts b/lib/client-api/src/index.ts index d287b8ff05f..a4be36a1c41 100644 --- a/lib/client-api/src/index.ts +++ b/lib/client-api/src/index.ts @@ -8,10 +8,6 @@ import ClientApi, { getGlobalRender, } from './ClientApi'; -import { simulatePageLoad, simulateDOMContentLoaded } from './simulate-pageload'; - -import { getQueryParams, getQueryParam } from './queryparams'; - export * from '@storybook/store'; export { @@ -25,12 +21,4 @@ export { ClientApi, // TODO -- back compat? // ConfigApi, - // TODO -- keep for back-compat? - getQueryParam, - getQueryParams, - // Now in lib/store/UrlStore - TODO - rexport for back-compat? - // pathToId, - // TODO -- move somewhere appropriate (utils for app layers) - simulateDOMContentLoaded, - simulatePageLoad, }; diff --git a/lib/client-api/src/queryparams.ts b/lib/client-api/src/queryparams.ts deleted file mode 100644 index e9d120f6263..00000000000 --- a/lib/client-api/src/queryparams.ts +++ /dev/null @@ -1,18 +0,0 @@ -import global from 'global'; -import { parse } from 'qs'; - -const { document } = global; - -export const getQueryParams = () => { - // document.location is not defined in react-native - if (document && document.location && document.location.search) { - return parse(document.location.search, { ignoreQueryPrefix: true }); - } - return {}; -}; - -export const getQueryParam = (key: string) => { - const params = getQueryParams(); - - return params[key]; -}; diff --git a/lib/web-preview/src/index.ts b/lib/web-preview/src/index.ts index ab895f04fc8..14be448affc 100644 --- a/lib/web-preview/src/index.ts +++ b/lib/web-preview/src/index.ts @@ -1,5 +1,6 @@ export { WebPreview } from './WebPreview'; export { composeConfigs } from './composeConfigs'; +export { simulatePageLoad, simulateDOMContentLoaded } from './simulate-pageload'; export * from './types'; diff --git a/lib/client-api/src/simulate-pageload.ts b/lib/web-preview/src/simulate-pageload.ts similarity index 100% rename from lib/client-api/src/simulate-pageload.ts rename to lib/web-preview/src/simulate-pageload.ts From b9c8b873a1c175de1bbef19c2d4c69b946587dc6 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 19:10:41 +1000 Subject: [PATCH 116/285] Don't export `ConfigApi` any more -- not sure it could be used directly anyway --- lib/client-api/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/client-api/src/index.ts b/lib/client-api/src/index.ts index a4be36a1c41..619967c1cc9 100644 --- a/lib/client-api/src/index.ts +++ b/lib/client-api/src/index.ts @@ -19,6 +19,4 @@ export { setGlobalRender, getGlobalRender, ClientApi, - // TODO -- back compat? - // ConfigApi, }; From 53ed7b4e4dedfca0ac3d2814ffac05a566789117 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 19:25:19 +1000 Subject: [PATCH 117/285] Throw from client api exports if using storyStoreV7 --- lib/client-api/src/ClientApi.ts | 95 ++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index b584f9a7621..317e4f2c4f4 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -1,5 +1,6 @@ import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; +import { global } from 'global'; import { logger } from '@storybook/client-logger'; import { Framework, @@ -27,6 +28,8 @@ import { import { ClientApiAddons, StoryApi } from '@storybook/addons'; +const { FEATURES } = global; + export interface GetStorybookStory { name: string; render: StoryFn; @@ -42,78 +45,82 @@ export interface GetStorybookKind { // relevant framework instanciates them via `start.js`. The good news is this happens right away. let singleton: ClientApi; -const addDecoratorDeprecationWarning = deprecate( - () => {}, - `\`addDecorator\` is deprecated, and will be removed in Storybook 7.0. -Instead, use \`export const decorators = [];\` in your \`preview.js\`. -Read more at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-addparameters-and-adddecorator).` -); +const warningAlternatives = { + addDecorator: `Instead, use \`export const decorators = [];\` in your \`preview.js\`.`, + addParameters: `Instead, use \`export const parameters = {};\` in your \`preview.js\`.`, + addLoaders: `Instead, use \`export const loaders = [];\` in your \`preview.js\`.`, +}; + +const warningMessage = (method: keyof typeof warningAlternatives) => + deprecate( + () => {}, + dedent` + \`${method}\` is deprecated, and will be removed in Storybook 7.0. + + ${warningAlternatives[method]} + + Read more at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-addparameters-and-adddecorator).` + ); + +const warnings = { + addDecorator: warningMessage('addDecorator'), + addParameters: warningMessage('addParameters'), + addLoaders: warningMessage('addLoaders'), +}; + +const checkMethod = (method: string, deprecationWarning: boolean) => { + if (FEATURES.storyStoreV7) { + throw new Error( + dedent`You cannot use \`${method}\` with the new Story Store. + + ${warningAlternatives[method as keyof typeof warningAlternatives]}` + ); + } + + if (!singleton) { + throw new Error(`Singleton client API not yet initialized, cannot call \`${method}\`.`); + } + + if (deprecationWarning) { + warnings[method as keyof typeof warningAlternatives](); + } +}; + export const addDecorator = ( decorator: DecoratorFunction, deprecationWarning = true ) => { - if (!singleton) - throw new Error(`Singleton client API not yet initialized, cannot call addDecorator`); - - if (deprecationWarning) addDecoratorDeprecationWarning(); - + checkMethod('addDecorator', deprecationWarning); singleton.addDecorator(decorator); }; -const addParametersDeprecationWarning = deprecate( - () => {}, - `\`addParameters\` is deprecated, and will be removed in Storybook 7.0. -Instead, use \`export const parameters = {};\` in your \`preview.js\`. -Read more at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-addparameters-and-adddecorator).` -); export const addParameters = (parameters: Parameters, deprecationWarning = true) => { - if (!singleton) - throw new Error(`Singleton client API not yet initialized, cannot call addParameters`); - - if (deprecationWarning) addParametersDeprecationWarning(); - + checkMethod('addParameters', deprecationWarning); singleton.addParameters(parameters); }; -const addLoaderDeprecationWarning = deprecate( - () => {}, - `\`addLoader\` is deprecated, and will be removed in Storybook 7.0. -Instead, use \`export const loaders = [];\` in your \`preview.js\`. -Read more at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-addparameters-and-adddecorator).` -); export const addLoader = (loader: LoaderFunction, deprecationWarning = true) => { - if (!singleton) - throw new Error(`Singleton client API not yet initialized, cannot call addParameters`); - - if (deprecationWarning) addLoaderDeprecationWarning(); - + checkMethod('addLoader', deprecationWarning); singleton.addLoader(loader); }; export const addArgsEnhancer = (enhancer: ArgsEnhancer) => { - if (!singleton) - throw new Error(`Singleton client API not yet initialized, cannot call addArgsEnhancer`); - + checkMethod('addArgsEnhancer', false); singleton.addArgsEnhancer(enhancer); }; export const addArgTypesEnhancer = (enhancer: ArgTypesEnhancer) => { - if (!singleton) - throw new Error(`Singleton client API not yet initialized, cannot call addArgTypesEnhancer`); - + checkMethod('addArgTypesEnhancer', false); singleton.addArgTypesEnhancer(enhancer); }; export const getGlobalRender = () => { - if (!singleton) - throw new Error(`Singleton client API not yet initialized, cannot call getGlobalRender`); - + checkMethod('getGlobalRender', false); return singleton.globalAnnotations.render; }; export const setGlobalRender = (render: StoryFn) => { - if (!singleton) - throw new Error(`Singleton client API not yet initialized, cannot call setGobalRender`); + checkMethod('setGlobalRender', false); singleton.globalAnnotations.render = render; }; From 2b4996cd6f53414c650ea4f4f53365aa7647a972 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 21:35:43 +1000 Subject: [PATCH 118/285] Ensure SB globals are always defined --- .../preview/virtualModuleModernEntry.js.handlebars | 7 ++++++- lib/core-client/src/preview/start.ts | 13 +++++++++++++ lib/core-client/typings.d.ts | 4 ---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index 7cc2d5379b2..0e11ef12698 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -16,9 +16,14 @@ const fetchStoriesList = async () => { return result.json(); } -addons.setChannel(createChannel({ page: 'preview' })); +const channel = createChannel({ page: 'preview' }); +addons.setChannel(channel); const preview = new WebPreview({ importFn, getGlobalAnnotations, fetchStoriesList }); + window.__STORYBOOK_PREVIEW__ = preview; +window.__STORYBOOK_STORY_STORE__ = preview.storyStore; +window.__STORYBOOK_ADDONS_CHANNEL__ = channel; + preview.initialize(); if (module.hot) { diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 973788c94a6..dc7ba4132d3 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -1,3 +1,4 @@ +import { global } from 'global'; import { ClientApi } from '@storybook/client-api'; import { WebGlobalAnnotations, WebPreview } from '@storybook/web-preview'; import { Framework } from '@storybook/csf'; @@ -9,6 +10,8 @@ import { Path } from '@storybook/store'; import { Loadable } from './types'; import { executeLoadableForChanges } from './executeLoadable'; +const { window: globalWindow } = global; + export function start( renderToDOM: WebGlobalAnnotations['renderToDOM'], { decorateStory }: { decorateStory?: WebGlobalAnnotations['applyDecorators'] } = {} @@ -19,6 +22,11 @@ export function start( let preview: WebPreview; const clientApi = new ClientApi(); + if (globalWindow) { + globalWindow.__STORYBOOK_CLIENT_API__ = clientApi; + globalWindow.__STORYBOOK_ADDONS_CHANNEL__ = channel; + } + return { forceReRender: () => channel.emit(Events.FORCE_RE_RENDER), getStorybook: (): void[] => [], @@ -56,6 +64,11 @@ export function start( getGlobalAnnotations, fetchStoriesList: async () => clientApi.getStoriesList(), }); + if (globalWindow) { + // eslint-disable-next-line no-underscore-dangle + globalWindow.__STORYBOOK_PREVIEW__ = preview; + globalWindow.__STORYBOOK_STORY_STORE__ = preview.storyStore; + } // These two bits are a bit ugly, but due to dependencies, `ClientApi` cannot have // direct reference to `WebPreview`, so we need to patch in bits diff --git a/lib/core-client/typings.d.ts b/lib/core-client/typings.d.ts index 9d91b21f5e5..faea2fff4fb 100644 --- a/lib/core-client/typings.d.ts +++ b/lib/core-client/typings.d.ts @@ -4,7 +4,3 @@ declare class AnsiToHtml { toHtml: (ansi: string) => string; } - -// FIXME refactor in progress -declare module '@storybook/client-api/dist/esm/new/StoryStore'; -declare type StoryStore = any; From 1d91c33fb1a1efd25eb05330b35eb4831205ac7f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 22:35:36 +1000 Subject: [PATCH 119/285] Re-established old addons types --- lib/addons/src/make-decorator.ts | 17 ++---- lib/addons/src/types.ts | 101 ++++++++++++++++++------------- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/lib/addons/src/make-decorator.ts b/lib/addons/src/make-decorator.ts index b042b3df1b3..683bc59b1fd 100644 --- a/lib/addons/src/make-decorator.ts +++ b/lib/addons/src/make-decorator.ts @@ -1,26 +1,21 @@ -import { Framework, LegacyStoryFn, StoryContext } from '@storybook/csf'; - -import { StoryWrapper } from './types'; +import { StoryWrapper, LegacyStoryFn, StoryContext } from './types'; type MakeDecoratorResult = (...args: any) => any; -interface MakeDecoratorOptions { +interface MakeDecoratorOptions { name: string; parameterName: string; skipIfNoParametersOrOptions?: boolean; - wrapper: StoryWrapper; + wrapper: StoryWrapper; } -export const makeDecorator = ({ +export const makeDecorator = ({ name, parameterName, wrapper, skipIfNoParametersOrOptions = false, -}: MakeDecoratorOptions): MakeDecoratorResult => { - const decorator: any = (options: object) => ( - storyFn: LegacyStoryFn, - context: StoryContext - ) => { +}: MakeDecoratorOptions): MakeDecoratorResult => { + const decorator: any = (options: object) => (storyFn: LegacyStoryFn, context: StoryContext) => { const parameters = context.parameters && context.parameters[parameterName]; if (parameters && parameters.disable) { diff --git a/lib/addons/src/types.ts b/lib/addons/src/types.ts index 9c1e7e1755b..0bbca209a51 100644 --- a/lib/addons/src/types.ts +++ b/lib/addons/src/types.ts @@ -1,38 +1,60 @@ import { - DecoratorFunction, Framework, - LegacyStoryFn, - LoaderFunction, + InputType, Parameters, - StoryContext, - StoryContextForEnhancers, - StoryFn, + StoryContext as StoryContextForFramework, + LegacyStoryFn as LegacyStoryFnForFramework, + PartialStoryFn as PartialStoryFnForFramework, + ArgsStoryFn as ArgsStoryFnForFramework, + StoryFn as StoryFnForFramework, + DecoratorFunction as DecoratorFunctionForFramework, + LoaderFunction as LoaderFunctionForFramework, StoryId, StoryKind, StoryName, + Args, } from '@storybook/csf'; import { Addon } from './index'; +// NOTE: The types exported from this file are simplified versions of the types exported +// by @storybook/csf, with the simpler form retained for backwards compatibility. +// We will likely start exporting the more complex based types in 7.0 + export type { - Framework, StoryId, StoryKind, StoryName, + StoryIdentifier, ViewMode, Parameters, Args, - ArgTypes, - StoryContextUpdate, - StoryContext, - PartialStoryFn, - LegacyStoryFn, - ArgsStoryFn, - StoryFn, - DecoratorFunction, - LoaderFunction, } from '@storybook/csf'; +export type ArgTypes = { + [key in keyof Partial]: InputType; +}; + +export type StoryContext = StoryContextForFramework; +export type StoryContextUpdate = Partial; + +type ReturnTypeFramework = { component: any; storyResult: ReturnType }; +export type PartialStoryFn = PartialStoryFnForFramework< + ReturnTypeFramework +>; +export type LegacyStoryFn = LegacyStoryFnForFramework< + ReturnTypeFramework +>; +export type ArgsStoryFn = ArgsStoryFnForFramework< + ReturnTypeFramework +>; +export type StoryFn = StoryFnForFramework>; + +export type DecoratorFunction = DecoratorFunctionForFramework< + ReturnTypeFramework +>; +export type LoaderFunction = LoaderFunctionForFramework>; + export enum types { TAB = 'tab', PANEL = 'panel', @@ -55,27 +77,27 @@ export interface WrapperSettings { }; } -export type StoryWrapper = ( - storyFn: LegacyStoryFn, - context: StoryContext, +export type StoryWrapper = ( + storyFn: LegacyStoryFn, + context: StoryContext, settings: WrapperSettings ) => any; export type MakeDecoratorResult = (...args: any) => any; -export interface AddStoryArgs { +export interface AddStoryArgs { id: StoryId; kind: StoryKind; name: StoryName; - storyFn: StoryFn; + storyFn: StoryFn; parameters: Parameters; } -export interface ClientApiAddon extends Addon { - apply: (a: StoryApi, b: any[]) => any; +export interface ClientApiAddon extends Addon { + apply: (a: StoryApi, b: any[]) => any; } -export interface ClientApiAddons { - [key: string]: ClientApiAddon; +export interface ClientApiAddons { + [key: string]: ClientApiAddon; } // Old types for getStorybook() @@ -89,30 +111,27 @@ export interface IStorybookSection { stories: IStorybookStory[]; } -export type ClientApiReturnFn = ( +export type ClientApiReturnFn = ( ...args: any[] -) => StoryApi; +) => StoryApi; -export interface StoryApi { +export interface StoryApi { kind: StoryKind; add: ( storyName: StoryName, - storyFn: StoryFn, + storyFn: StoryFn, parameters?: Parameters - ) => StoryApi; - addDecorator: (decorator: DecoratorFunction) => StoryApi; - addLoader: (decorator: LoaderFunction) => StoryApi; - addParameters: (parameters: Parameters) => StoryApi; - [k: string]: string | ClientApiReturnFn; + ) => StoryApi; + addDecorator: (decorator: DecoratorFunction) => StoryApi; + addLoader: (decorator: LoaderFunction) => StoryApi; + addParameters: (parameters: Parameters) => StoryApi; + [k: string]: string | ClientApiReturnFn; } -export interface ClientStoryApi { - storiesOf(kind: StoryKind, module: NodeModule): StoryApi; - addDecorator(decorator: DecoratorFunction): StoryApi; - addParameters(parameter: Parameters): StoryApi; - getStorybook(): IStorybookSection[]; - // TODO -- should be Story from store? - raw: () => StoryContextForEnhancers[]; +export interface ClientStoryApi { + storiesOf(kind: StoryKind, module: NodeModule): StoryApi; + addDecorator(decorator: DecoratorFunction): StoryApi; + addParameters(parameter: Parameters): StoryApi; } type LoadFn = () => any; From 10e6545ca49ef6e99fcf66d67b766ed0550f38c5 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 22:36:51 +1000 Subject: [PATCH 120/285] Re-add CSF types to addons --- lib/addons/src/types.ts | 123 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/lib/addons/src/types.ts b/lib/addons/src/types.ts index 0bbca209a51..0bec427389d 100644 --- a/lib/addons/src/types.ts +++ b/lib/addons/src/types.ts @@ -137,3 +137,126 @@ export interface ClientStoryApi { type LoadFn = () => any; type RequireContext = any; // FIXME export type Loadable = RequireContext | [RequireContext] | LoadFn; + +// CSF types, to be re-org'ed in 6.1 + +export type BaseDecorators = Array< + (story: () => StoryFnReturnType, context: StoryContext) => StoryFnReturnType +>; + +export interface BaseAnnotations { + /** + * Dynamic data that are provided (and possibly updated by) Storybook and its addons. + * @see [Arg story inputs](https://storybook.js.org/docs/react/api/csf#args-story-inputs) + */ + args?: Partial; + + /** + * ArgTypes encode basic metadata for args, such as `name`, `description`, `defaultValue` for an arg. These get automatically filled in by Storybook Docs. + * @see [Control annotations](https://github.com/storybookjs/storybook/blob/91e9dee33faa8eff0b342a366845de7100415367/addons/controls/README.md#control-annotations) + */ + argTypes?: ArgTypes; + + /** + * Custom metadata for a story. + * @see [Parameters](https://storybook.js.org/docs/basics/writing-stories/#parameters) + */ + parameters?: Parameters; + + /** + * Wrapper components or Storybook decorators that wrap a story. + * + * Decorators defined in Meta will be applied to every story variation. + * @see [Decorators](https://storybook.js.org/docs/addons/introduction/#1-decorators) + */ + decorators?: BaseDecorators; + /** + * Define a custom render function for the story(ies). If not passed, a default render function by the framework will be used. + */ + render?: (args: Args, context: StoryContext) => StoryFnReturnType; + /** + * Function that is executed after the story is rendered. + */ + play?: Function; +} + +export interface Annotations + extends BaseAnnotations { + /** + * Used to only include certain named exports as stories. Useful when you want to have non-story exports such as mock data or ignore a few stories. + * @example + * includeStories: ['SimpleStory', 'ComplexStory'] + * includeStories: /.*Story$/ + * + * @see [Non-story exports](https://storybook.js.org/docs/formats/component-story-format/#non-story-exports) + */ + includeStories?: string[] | RegExp; + + /** + * Used to exclude certain named exports. Useful when you want to have non-story exports such as mock data or ignore a few stories. + * @example + * excludeStories: ['simpleData', 'complexData'] + * excludeStories: /.*Data$/ + * + * @see [Non-story exports](https://storybook.js.org/docs/formats/component-story-format/#non-story-exports) + */ + excludeStories?: string[] | RegExp; +} + +export interface BaseMeta { + /** + * Title of the story which will be presented in the navigation. **Should be unique.** + * + * Stories can be organized in a nested structure using "/" as a separator. + * + * Since CSF 3.0 this property is optional. + * + * @example + * export default { + * ... + * title: 'Design System/Atoms/Button' + * } + * + * @see [Story Hierarchy](https://storybook.js.org/docs/basics/writing-stories/#story-hierarchy) + */ + title?: string; + + /** + * The primary component for your story. + * + * Used by addons for automatic prop table generation and display of other component metadata. + */ + component?: ComponentType; + + /** + * Auxiliary subcomponents that are part of the stories. + * + * Used by addons for automatic prop table generation and display of other component metadata. + * + * @example + * import { Button, ButtonGroup } from './components'; + * + * export default { + * ... + * subcomponents: { Button, ButtonGroup } + * } + * + * By defining them each component will have its tab in the args table. + */ + subcomponents?: Record; +} + +export type BaseStoryObject = { + /** + * Override the display name in the UI + */ + storyName?: string; +}; + +export type BaseStoryFn = { + (args: Args, context: StoryContext): StoryFnReturnType; +} & BaseStoryObject; + +export type BaseStory = + | BaseStoryFn + | BaseStoryObject; From a09a5317a96311b0188e30ce974f715b4ed9c28d Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 22:42:53 +1000 Subject: [PATCH 121/285] Fixed up ClientApi types --- lib/client-api/src/ClientApi.ts | 6 +- lib/client-api/src/index.ts | 1 + lib/client-api/src/types.ts | 132 +++++++++++++++++++++++++++ lib/core-client/src/preview/index.ts | 15 +-- 4 files changed, 139 insertions(+), 15 deletions(-) create mode 100644 lib/client-api/src/types.ts diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 317e4f2c4f4..a9035787eab 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -136,7 +136,7 @@ export default class ClientApi { private csfExports: Record; - private addons: ClientApiAddons; + private addons: ClientApiAddons; // If we don't get passed modules so don't know filenames, we can // just use numeric indexes @@ -228,7 +228,7 @@ export default class ClientApi { }; // what are the occasions that "m" is a boolean vs an obj - storiesOf = (kind: string, m?: NodeModule): StoryApi => { + storiesOf = (kind: string, m?: NodeModule): StoryApi => { if (!kind && typeof kind !== 'string') { throw new Error('Invalid or missing kind provided for stories, should be a string'); } @@ -271,7 +271,7 @@ export default class ClientApi { } let hasAdded = false; - const api: StoryApi = { + const api: StoryApi = { kind: kind.toString(), add: () => api, addDecorator: () => api, diff --git a/lib/client-api/src/index.ts b/lib/client-api/src/index.ts index 619967c1cc9..f5f59d9f2bb 100644 --- a/lib/client-api/src/index.ts +++ b/lib/client-api/src/index.ts @@ -9,6 +9,7 @@ import ClientApi, { } from './ClientApi'; export * from '@storybook/store'; +export * from './types'; export { addArgsEnhancer, diff --git a/lib/client-api/src/types.ts b/lib/client-api/src/types.ts new file mode 100644 index 00000000000..b038c9d8a82 --- /dev/null +++ b/lib/client-api/src/types.ts @@ -0,0 +1,132 @@ +import { + Addon, + StoryId, + StoryName, + StoryKind, + ViewMode, + StoryFn, + Parameters, + Args, + ArgTypes, + StoryApi, + DecoratorFunction, + LoaderFunction, + StoryContext, +} from '@storybook/addons'; +import { Framework, StoryIdentifier, GlobalAnnotations } from '@storybook/csf'; +import { StoryStore, HooksContext } from '@storybook/store'; + +export type { + SBType, + SBScalarType, + SBArrayType, + SBObjectType, + SBEnumType, + SBIntersectionType, + SBUnionType, + SBOtherType, +} from '@storybook/csf'; + +// NOTE: these types are really just here for back-compat. Many of them don't have much meaning +// Remove in 7.0 + +export interface ErrorLike { + message: string; + stack: string; +} + +// Metadata about a story that can be set at various levels: global, for a kind, or for a single story. +export interface StoryMetadata { + parameters?: Parameters; + decorators?: DecoratorFunction[]; + loaders?: LoaderFunction[]; +} +export type ArgTypesEnhancer = (context: StoryContext) => ArgTypes; +export type ArgsEnhancer = (context: StoryContext) => Args; + +export type StorySpecifier = StoryId | { name: StoryName; kind: StoryKind } | '*'; + +export interface StoreSelectionSpecifier { + storySpecifier: StorySpecifier; + viewMode: ViewMode; + singleStory?: boolean; + args?: Args; + globals?: Args; +} + +export interface StoreSelection { + storyId: StoryId; + viewMode: ViewMode; +} + +export type AddStoryArgs = StoryIdentifier & { + storyFn: StoryFn; + parameters?: Parameters; + decorators?: DecoratorFunction[]; + loaders?: LoaderFunction[]; +}; + +export type StoreItem = StoryIdentifier & { + parameters: Parameters; + getDecorated: () => StoryFn; + getOriginal: () => StoryFn; + applyLoaders: () => Promise; + runPlayFunction: () => Promise; + storyFn: StoryFn; + unboundStoryFn: StoryFn; + hooks: HooksContext; + args: Args; + initialArgs: Args; + argTypes: ArgTypes; +}; + +export type PublishedStoreItem = StoreItem & { + globals: Args; +}; + +export interface StoreData { + [key: string]: StoreItem; +} + +export interface ClientApiParams { + storyStore: StoryStore; + decorateStory?: GlobalAnnotations['applyDecorators']; + noStoryModuleAddMethodHotDispose?: boolean; +} + +export type ClientApiReturnFn = (...args: any[]) => StoryApi; + +export type { StoryApi, DecoratorFunction }; + +export interface ClientApiAddon extends Addon { + apply: (a: StoryApi, b: any[]) => any; +} + +export interface ClientApiAddons { + [key: string]: ClientApiAddon; +} + +export interface GetStorybookStory { + name: string; + render: StoryFn; +} + +export interface GetStorybookKind { + kind: string; + fileName: string; + stories: GetStorybookStory[]; +} + +// This really belongs in lib/core, but that depends on lib/ui which (dev) depends on app/react +// which needs this type. So we put it here to avoid the circular dependency problem. +export type RenderContextWithoutStoryContext = StoreItem & { + forceRender: boolean; + + showMain: () => void; + showError: (error: { title: string; description: string }) => void; + showException: (err: Error) => void; +}; + +export type RenderContext = RenderContextWithoutStoryContext & { + storyContext: StoryContext; +}; diff --git a/lib/core-client/src/preview/index.ts b/lib/core-client/src/preview/index.ts index 26bd5907664..b4505e71850 100644 --- a/lib/core-client/src/preview/index.ts +++ b/lib/core-client/src/preview/index.ts @@ -1,4 +1,5 @@ import { ClientApi } from '@storybook/client-api'; +import { StoryStore } from '@storybook/store'; import { toId } from '@storybook/csf'; import { start } from './start'; @@ -6,19 +7,9 @@ export default { start, toId, ClientApi, - - // TODO -- back compat - // ConfigApi, - // StoryStore, + StoryStore, }; -export { - start, - toId, - ClientApi, - // TODO back compat - // ConfigApi, - // StoryStore, -}; +export { start, toId, ClientApi, StoryStore }; export { inferArgTypes } from './inferArgTypes'; From 922e5ee802aba48a08d7e931791201c21be1057e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 22:56:59 +1000 Subject: [PATCH 122/285] Update types in core-client --- lib/client-api/src/index.ts | 5 ++++- lib/core-client/src/preview/types.ts | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/client-api/src/index.ts b/lib/client-api/src/index.ts index f5f59d9f2bb..6107177e0e7 100644 --- a/lib/client-api/src/index.ts +++ b/lib/client-api/src/index.ts @@ -8,9 +8,12 @@ import ClientApi, { getGlobalRender, } from './ClientApi'; -export * from '@storybook/store'; export * from './types'; +// Typescript isn't happy that we are overwriting some types from store here +// @ts-ignore +export * from '@storybook/store'; + export { addArgsEnhancer, addArgTypesEnhancer, diff --git a/lib/core-client/src/preview/types.ts b/lib/core-client/src/preview/types.ts index f5f8aa08021..d964e501260 100644 --- a/lib/core-client/src/preview/types.ts +++ b/lib/core-client/src/preview/types.ts @@ -1,4 +1,4 @@ -import { ModuleExports, Path } from '@storybook/store'; +import { RenderContext, RenderContextWithoutStoryContext } from '@storybook/client-api'; export interface PreviewError { message?: string; @@ -23,6 +23,7 @@ export interface RequireContext { export type LoaderFunction = () => void | any[]; export type Loadable = RequireContext | RequireContext[] | LoaderFunction; -// The function used by a framework to render story to the DOM +export type { RenderContext, RenderContextWithoutStoryContext }; -export * from '@storybook/client-api'; +// The function used by a framework to render story to the DOM +export type RenderStoryFunction = (context: RenderContext) => void; From 275155fa4624b6efd84b5c80ae2cd7a7df63c063 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 23:00:24 +1000 Subject: [PATCH 123/285] Got core-client going too --- lib/client-api/src/ClientApi.ts | 2 +- lib/core-client/src/preview/start.test.ts | 6 +++--- lib/core-client/src/preview/start.ts | 2 +- lib/core-client/typings.d.ts | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index a9035787eab..3dd49367e6d 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -1,6 +1,6 @@ import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; -import { global } from 'global'; +import global from 'global'; import { logger } from '@storybook/client-logger'; import { Framework, diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index 0d3b94eda36..871eee370ec 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -904,7 +904,7 @@ describe('start', () => { // a ClientApi and a StoryStore describe('ClientApi.getStorybook', () => { it('should transform the storybook to an array with filenames', async () => { - const { configure, clientApi } = start(jest.fn); + const { configure, clientApi } = start(jest.fn()); let book; @@ -957,7 +957,7 @@ describe('start', () => { }); it('reads filename from module', async () => { - const { configure, clientApi } = start(jest.fn); + const { configure, clientApi } = start(jest.fn()); const fn = jest.fn(); await configure('test', () => { @@ -981,7 +981,7 @@ describe('start', () => { }); it('should stringify ids from module', async () => { - const { configure, clientApi } = start(jest.fn); + const { configure, clientApi } = start(jest.fn()); const fn = jest.fn(); await configure('test', () => { diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index dc7ba4132d3..37b35af8ee4 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -1,4 +1,4 @@ -import { global } from 'global'; +import global from 'global'; import { ClientApi } from '@storybook/client-api'; import { WebGlobalAnnotations, WebPreview } from '@storybook/web-preview'; import { Framework } from '@storybook/csf'; diff --git a/lib/core-client/typings.d.ts b/lib/core-client/typings.d.ts index faea2fff4fb..93d506c6280 100644 --- a/lib/core-client/typings.d.ts +++ b/lib/core-client/typings.d.ts @@ -1,4 +1,6 @@ declare module 'ansi-to-html'; +declare module '@storybook/web-preview/dist/cjs/WebPreview.mockdata'; + declare class AnsiToHtml { constructor(options: { escapeHtml: boolean }); From 462115395df1f80f9f0a2fe724de0b27afec737f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 23:00:52 +1000 Subject: [PATCH 124/285] Cleanup --- lib/client-api/src/story_store.test.ts | 196 ------ lib/client-api/src/story_store.ts | 861 ------------------------- 2 files changed, 1057 deletions(-) delete mode 100644 lib/client-api/src/story_store.test.ts delete mode 100644 lib/client-api/src/story_store.ts diff --git a/lib/client-api/src/story_store.test.ts b/lib/client-api/src/story_store.test.ts deleted file mode 100644 index e2be4c17b66..00000000000 --- a/lib/client-api/src/story_store.test.ts +++ /dev/null @@ -1,196 +0,0 @@ -// /* eslint-disable no-underscore-dangle */ -// import createChannel from '@storybook/channel-postmessage'; -// import { toId } from '@storybook/csf'; -// import { addons, mockChannel } from '@storybook/addons'; -// import Events from '@storybook/core-events'; - -// import StoryStore from './story_store'; -// import { defaultDecorateStory } from './decorators'; - -// jest.mock('@storybook/node-logger', () => ({ -// logger: { -// info: jest.fn(), -// warn: jest.fn(), -// error: jest.fn(), -// }, -// })); - -// let channel; -// beforeEach(() => { -// channel = createChannel({ page: 'preview' }); -// }); - -// function addReverseSorting(store) { -// store.addGlobalMetadata({ -// decorators: [], -// parameters: { -// options: { -// // Test function does reverse alphabetical ordering. -// storySort: (a: any, b: any): number => -// a[1].kind === b[1].kind -// ? 0 -// : -1 * a[1].id.localeCompare(b[1].id, undefined, { numeric: true }), -// }, -// }, -// }); -// } - -// // make a story and add it to the store -// const addStoryToStore = (store, kind, name, storyFn, parameters = {}) => -// store.addStory( -// { -// kind, -// name, -// storyFn, -// parameters, -// id: toId(kind, name), -// }, -// { -// // FIXME: need applyHooks, but this breaks the current tests -// applyDecorators: defaultDecorateStory, -// } -// ); - -// describe('configuration', () => { -// it('does not allow addStory if not configuring, unless allowUsafe=true', () => { -// const store = new StoryStore({ channel }); -// store.finishConfiguring(); - -// expect(() => addStoryToStore(store, 'a', '1', () => 0)).toThrow( -// 'Cannot add a story when not configuring' -// ); - -// expect(() => -// store.addStory( -// { -// kind: 'a', -// name: '1', -// storyFn: () => 0, -// parameters: {}, -// id: 'a--1', -// }, -// { -// applyDecorators: defaultDecorateStory, -// allowUnsafe: true, -// } -// ) -// ).not.toThrow(); -// }); - -// it('does not allow remove if not configuring, unless allowUsafe=true', () => { -// const store = new StoryStore({ channel }); -// addons.setChannel(channel); -// addStoryToStore(store, 'a', '1', () => 0); -// store.finishConfiguring(); - -// expect(() => store.remove('a--1')).toThrow('Cannot remove a story when not configuring'); -// expect(() => store.remove('a--1', { allowUnsafe: true })).not.toThrow(); -// }); - -// it('does not allow removeStoryKind if not configuring, unless allowUsafe=true', () => { -// const store = new StoryStore({ channel }); -// addons.setChannel(channel); -// addStoryToStore(store, 'a', '1', () => 0); -// store.finishConfiguring(); - -// expect(() => store.removeStoryKind('a')).toThrow('Cannot remove a kind when not configuring'); -// expect(() => store.removeStoryKind('a', { allowUnsafe: true })).not.toThrow(); -// }); - -// it('waits for configuration to be over before emitting SET_STORIES', () => { -// const onSetStories = jest.fn(); -// channel.on(Events.SET_STORIES, onSetStories); -// const store = new StoryStore({ channel }); - -// addStoryToStore(store, 'a', '1', () => 0); -// expect(onSetStories).not.toHaveBeenCalled(); - -// store.finishConfiguring(); -// expect(onSetStories).toHaveBeenCalledWith({ -// v: 2, -// globals: {}, -// globalParameters: {}, -// kindParameters: { a: {} }, -// stories: { -// 'a--1': expect.objectContaining({ -// id: 'a--1', -// }), -// }, -// }); -// }); - -// it('correctly emits globals with SET_STORIES', () => { -// const onSetStories = jest.fn(); -// channel.on(Events.SET_STORIES, onSetStories); -// const store = new StoryStore({ channel }); - -// store.addGlobalMetadata({ -// decorators: [], -// parameters: { -// globalTypes: { -// arg1: { defaultValue: 'arg1' }, -// }, -// }, -// }); - -// addStoryToStore(store, 'a', '1', () => 0); -// expect(onSetStories).not.toHaveBeenCalled(); - -// store.finishConfiguring(); -// expect(onSetStories).toHaveBeenCalledWith({ -// v: 2, -// globals: { arg1: 'arg1' }, -// globalParameters: { -// // NOTE: Currently globalArg[Types] are emitted as parameters but this may not remain -// globalTypes: { -// arg1: { defaultValue: 'arg1' }, -// }, -// }, -// kindParameters: { a: {} }, -// stories: { -// 'a--1': expect.objectContaining({ -// id: 'a--1', -// }), -// }, -// }); -// }); - -// it('emits an empty SET_STORIES if no stories were added during configuration', () => { -// const onSetStories = jest.fn(); -// channel.on(Events.SET_STORIES, onSetStories); -// const store = new StoryStore({ channel }); - -// store.finishConfiguring(); -// expect(onSetStories).toHaveBeenCalledWith({ -// v: 2, -// globals: {}, -// globalParameters: {}, -// kindParameters: {}, -// stories: {}, -// }); -// }); - -// it('allows configuration as second time (HMR)', () => { -// const onSetStories = jest.fn(); -// channel.on(Events.SET_STORIES, onSetStories); -// const store = new StoryStore({ channel }); -// store.finishConfiguring(); - -// onSetStories.mockClear(); -// store.startConfiguring(); -// addStoryToStore(store, 'a', '1', () => 0); -// store.finishConfiguring(); - -// expect(onSetStories).toHaveBeenCalledWith({ -// v: 2, -// globals: {}, -// globalParameters: {}, -// kindParameters: { a: {} }, -// stories: { -// 'a--1': expect.objectContaining({ -// id: 'a--1', -// }), -// }, -// }); -// }); -// }); diff --git a/lib/client-api/src/story_store.ts b/lib/client-api/src/story_store.ts deleted file mode 100644 index 44795d41fb2..00000000000 --- a/lib/client-api/src/story_store.ts +++ /dev/null @@ -1,861 +0,0 @@ -export {}; - -/* eslint no-underscore-dangle: 0 */ -// import memoize from 'memoizerific'; -// import dedent from 'ts-dedent'; -// import stable from 'stable'; -// import mapValues from 'lodash/mapValues'; -// import pick from 'lodash/pick'; -// import deprecate from 'util-deprecate'; - -// import { Channel } from '@storybook/channels'; -// import Events from '@storybook/core-events'; -// import { logger } from '@storybook/client-logger'; -// import { sanitize, toId } from '@storybook/csf'; -// import { -// Comparator, -// Parameters, -// Args, -// LegacyStoryFn, -// ArgsStoryFn, -// StoryContext, -// StoryKind, -// StoryId, -// } from '@storybook/addons'; -// import { -// combineArgs, -// mapArgsToTypes, -// validateOptions, -// HooksContext, -// combineParameters, -// } from '@storybook/store'; - -// import { -// DecoratorFunction, -// StoryMetadata, -// StoreData, -// AddStoryArgs, -// StoreItem, -// PublishedStoreItem, -// ErrorLike, -// GetStorybookKind, -// ArgsEnhancer, -// ArgTypesEnhancer, -// StoreSelectionSpecifier, -// StoreSelection, -// StorySpecifier, -// } from './types'; -// import { storySort } from './storySort'; -// import { ensureArgTypes } from './ensureArgTypes'; -// import { inferArgTypes } from './inferArgTypes'; -// import { inferControls } from './inferControls'; - -// interface StoryOptions { -// includeDocsOnly?: boolean; -// } - -// type KindMetadata = StoryMetadata & { order: number }; - -// function extractSanitizedKindNameFromStorySpecifier(storySpecifier: StorySpecifier): string { -// if (typeof storySpecifier === 'string') { -// return storySpecifier.split('--').shift(); -// } - -// return sanitize(storySpecifier.kind); -// } - -// function extractIdFromStorySpecifier(storySpecifier: StorySpecifier): string { -// if (typeof storySpecifier === 'string') { -// return storySpecifier; -// } - -// return toId(storySpecifier.kind, storySpecifier.name); -// } - -// const isStoryDocsOnly = (parameters?: Parameters) => { -// return parameters && parameters.docsOnly; -// }; - -// const includeStory = (story: StoreItem, options: StoryOptions = { includeDocsOnly: false }) => { -// if (options.includeDocsOnly) { -// return true; -// } -// return !isStoryDocsOnly(story.parameters); -// }; - -// const checkGlobals = (parameters: Parameters) => { -// const { globals, globalTypes } = parameters; -// if (globals || globalTypes) { -// logger.error( -// 'Global args/argTypes can only be set globally', -// JSON.stringify({ -// globals, -// globalTypes, -// }) -// ); -// } -// }; - -// const checkStorySort = (parameters: Parameters) => { -// const { options } = parameters; -// if (options?.storySort) logger.error('The storySort option parameter can only be set globally'); -// }; - -// const storyFnWarning = deprecate( -// () => {}, -// dedent` -// \`storyFn\` is deprecated and will be removed in Storybook 7.0. - -// https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-storyfn` -// ); - -// const argTypeDefaultValueWarning = deprecate( -// () => {}, -// dedent` -// \`argType.defaultValue\` is deprecated and will be removed in Storybook 7.0. - -// https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-argtype-defaultValue` -// ); - -// interface AllowUnsafeOption { -// allowUnsafe?: boolean; -// } - -// const toExtracted = (obj: T) => -// Object.entries(obj).reduce((acc, [key, value]) => { -// if (typeof value === 'function') { -// return acc; -// } -// // NOTE: We're serializing argTypes twice, at the top-level and also in parameters. -// // We currently rely on useParameters in the manager, so strip out the top-level argTypes -// // instead for performance. -// if (['hooks', 'argTypes'].includes(key)) { -// return acc; -// } -// if (Array.isArray(value)) { -// return Object.assign(acc, { [key]: value.slice().sort() }); -// } -// return Object.assign(acc, { [key]: value }); -// }, {}); - -// export default class StoryStore { -// _error?: ErrorLike; - -// _channel: Channel; - -// _configuring: boolean; - -// _globals: Args; - -// _initialGlobals: Args; - -// _defaultGlobals: Args; - -// _globalMetadata: StoryMetadata; - -// // Keyed on kind name -// _kinds: Record; - -// // Keyed on storyId -// _stories: StoreData; - -// _argsEnhancers: ArgsEnhancer[]; - -// _argTypesEnhancers: ArgTypesEnhancer[]; - -// _selectionSpecifier?: StoreSelectionSpecifier; - -// _selection?: StoreSelection; - -// constructor(params: { channel: Channel }) { -// // Assume we are configuring until we hear otherwise -// this._configuring = true; -// this._globals = {}; -// this._defaultGlobals = {}; -// this._initialGlobals = {}; -// this._globalMetadata = { parameters: {}, decorators: [], loaders: [] }; -// this._kinds = {}; -// this._stories = {}; -// this._argsEnhancers = []; -// this._argTypesEnhancers = [ensureArgTypes]; -// this._error = undefined; -// this._channel = params.channel; - -// this.setupListeners(); -// } - -// setupListeners() { -// // Channel can be null in StoryShots -// if (!this._channel) return; - -// this._channel.on(Events.SET_CURRENT_STORY, ({ storyId, viewMode }) => -// this.setSelection({ storyId, viewMode }) -// ); - -// this._channel.on( -// Events.UPDATE_STORY_ARGS, -// ({ storyId, updatedArgs }: { storyId: string; updatedArgs: Args }) => -// this.updateStoryArgs(storyId, updatedArgs) -// ); - -// this._channel.on( -// Events.RESET_STORY_ARGS, -// ({ storyId, argNames }: { storyId: string; argNames?: string[] }) => -// this.resetStoryArgs(storyId, argNames) -// ); - -// this._channel.on(Events.UPDATE_GLOBALS, ({ globals }: { globals: Args }) => -// this.updateGlobals(globals) -// ); -// } - -// startConfiguring() { -// this._configuring = true; - -// const safePush = (enhancer: ArgTypesEnhancer, enhancers: ArgTypesEnhancer[]) => { -// if (!enhancers.includes(enhancer)) enhancers.push(enhancer); -// }; -// // run these at the end -// safePush(inferArgTypes, this._argTypesEnhancers); -// safePush(inferControls, this._argTypesEnhancers); -// } - -// finishConfiguring() { -// this._configuring = false; - -// const { globals = {}, globalTypes = {} } = this._globalMetadata.parameters; -// const allowedGlobals = new Set([...Object.keys(globals), ...Object.keys(globalTypes)]); -// const defaultGlobals = Object.entries( -// globalTypes as Record -// ).reduce((acc, [arg, { defaultValue }]) => { -// if (defaultValue) acc[arg] = defaultValue; -// return acc; -// }, {} as Args); - -// this._initialGlobals = { ...defaultGlobals, ...globals }; - -// // To deal with HMR & persistence, we consider the previous value of global args, and: -// // 1. Remove any keys that are not in the new parameter -// // 2. Preference any keys that were already set -// // 3. Use any new keys from the new parameter -// this._globals = Object.entries(this._globals || {}).reduce( -// (acc, [key, previousValue]) => { -// if (allowedGlobals.has(key)) acc[key] = previousValue; - -// return acc; -// }, -// { ...this._initialGlobals } -// ); - -// // Set the current selection based on the current selection specifier, if selection is not yet set -// const stories = this.sortedStories(); -// let foundStory; -// if (this._selectionSpecifier && !this._selection) { -// const { -// storySpecifier, -// viewMode, -// args: urlArgs, -// globals: urlGlobals, -// } = this._selectionSpecifier; - -// if (urlGlobals) { -// const allowedUrlGlobals = Object.entries(urlGlobals).reduce((acc, [key, value]) => { -// if (allowedGlobals.has(key)) acc[key] = value; -// return acc; -// }, {} as Args); -// this._globals = combineParameters(this._globals, allowedUrlGlobals); -// } - -// if (storySpecifier === '*') { -// // '*' means select the first story. If there is none, we have no selection. -// [foundStory] = stories; -// } else if (typeof storySpecifier === 'string') { -// // Find the story with the exact id that matches the specifier (see #11571) -// foundStory = Object.values(stories).find((s) => s.id === storySpecifier); -// if (!foundStory) { -// // Fallback to the first story that starts with the specifier -// foundStory = Object.values(stories).find((s) => s.id.startsWith(storySpecifier)); -// } -// } else { -// // Try and find a story matching the name/kind, setting no selection if they don't exist. -// const { name, kind } = storySpecifier; -// foundStory = this.getRawStory(kind, name); -// } - -// if (foundStory) { -// if (urlArgs) { -// const mappedUrlArgs = mapArgsToTypes(urlArgs, foundStory.argTypes); -// foundStory.args = combineArgs(foundStory.args, mappedUrlArgs); -// } -// foundStory.args = validateOptions(foundStory.args, foundStory.argTypes); -// this.setSelection({ storyId: foundStory.id, viewMode }); -// this._channel.emit(Events.STORY_SPECIFIED, { storyId: foundStory.id, viewMode }); -// } -// } - -// // If we didn't find a story matching the specifier, we always want to emit CURRENT_STORY_WAS_SET anyway -// // in order to tell the StoryRenderer to render something (a "missing story" view) -// if (!foundStory && this._channel) { -// this._channel.emit(Events.CURRENT_STORY_WAS_SET, this._selection); -// } - -// this.pushToManager(); -// } - -// addGlobalMetadata({ parameters = {}, decorators = [], loaders = [] }: StoryMetadata) { -// if (parameters) { -// const { args, argTypes } = parameters; -// if (args || argTypes) -// logger.warn( -// 'Found args/argTypes in global parameters.', -// JSON.stringify({ args, argTypes }) -// ); -// } -// const globalParameters = this._globalMetadata.parameters; - -// this._globalMetadata.parameters = combineParameters(globalParameters, parameters); - -// function _safeAdd(items: any[], collection: any[], caption: string) { -// items.forEach((item) => { -// if (collection.includes(item)) { -// logger.warn(`You tried to add a duplicate ${caption}, this is not expected`, item); -// } else { -// collection.push(item); -// } -// }); -// } - -// _safeAdd(decorators, this._globalMetadata.decorators, 'decorator'); -// _safeAdd(loaders, this._globalMetadata.loaders, 'loader'); -// } - -// clearGlobalDecorators() { -// this._globalMetadata.decorators = []; -// } - -// ensureKind(kind: string) { -// if (!this._kinds[kind]) { -// this._kinds[kind] = { -// order: Object.keys(this._kinds).length, -// parameters: {}, -// decorators: [], -// loaders: [], -// }; -// } -// } - -// addKindMetadata(kind: string, { parameters = {}, decorators = [], loaders = [] }: StoryMetadata) { -// if (this.shouldBlockAddingKindMetadata(kind)) { -// return; -// } - -// this.ensureKind(kind); -// if (parameters) { -// checkGlobals(parameters); -// checkStorySort(parameters); -// } -// this._kinds[kind].parameters = combineParameters(this._kinds[kind].parameters, parameters); - -// this._kinds[kind].decorators.push(...decorators); -// this._kinds[kind].loaders.push(...loaders); -// } - -// addArgsEnhancer(argsEnhancer: ArgsEnhancer) { -// if (Object.keys(this._stories).length > 0) -// throw new Error('Cannot add an args enhancer to the store after a story has been added.'); - -// this._argsEnhancers.push(argsEnhancer); -// } - -// addArgTypesEnhancer(argTypesEnhancer: ArgTypesEnhancer) { -// if (Object.keys(this._stories).length > 0) -// throw new Error('Cannot add an argTypes enhancer to the store after a story has been added.'); - -// this._argTypesEnhancers.push(argTypesEnhancer); -// } - -// // Combine the global, kind & story parameters of a story -// combineStoryParameters(parameters: Parameters, kind: StoryKind) { -// return combineParameters( -// this._globalMetadata.parameters, -// this._kinds[kind].parameters, -// parameters -// ); -// } - -// shouldBlockAddingStory(id: string): boolean { -// return ( -// this.isSingleStoryMode() && -// id !== extractIdFromStorySpecifier(this._selectionSpecifier.storySpecifier) -// ); -// } - -// shouldBlockAddingKindMetadata(kind: string): boolean { -// return ( -// this.isSingleStoryMode() && -// sanitize(kind) !== -// extractSanitizedKindNameFromStorySpecifier(this._selectionSpecifier.storySpecifier) -// ); -// } - -// addStory( -// { -// id, -// kind, -// name, -// storyFn: original, -// parameters: storyParameters = {}, -// decorators: storyDecorators = [], -// loaders: storyLoaders = [], -// }: AddStoryArgs, -// { -// applyDecorators, -// allowUnsafe = false, -// }: { -// applyDecorators: (fn: LegacyStoryFn, decorators: DecoratorFunction[]) => any; -// } & AllowUnsafeOption -// ) { -// if (!this._configuring && !allowUnsafe) -// throw new Error( -// 'Cannot add a story when not configuring, see https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#story-store-immutable-outside-of-configuration' -// ); - -// if (this.shouldBlockAddingStory(id)) { -// return; -// } - -// checkGlobals(storyParameters); -// checkStorySort(storyParameters); - -// const { _stories } = this; - -// if (_stories[id]) { -// logger.warn(dedent` -// Story with id ${id} already exists in the store! - -// Perhaps you added the same story twice, or you have a name collision? -// Story ids need to be unique -- ensure you aren't using the same names modulo url-sanitization. -// `); -// } - -// const identification = { -// id, -// kind, -// name, -// story: name, // legacy -// }; - -// // immutable original storyFn -// const getOriginal = () => original; - -// this.ensureKind(kind); -// const kindMetadata: KindMetadata = this._kinds[kind]; -// const decorators = [ -// ...storyDecorators, -// ...kindMetadata.decorators, -// ...this._globalMetadata.decorators, -// ]; -// const loaders = [...this._globalMetadata.loaders, ...kindMetadata.loaders, ...storyLoaders]; - -// const finalStoryFn = (context: StoryContext) => { -// const { args = {}, argTypes = {}, parameters } = context; -// const { passArgsFirst = true } = parameters; -// const mapped = { -// ...context, -// args: Object.entries(args).reduce((acc, [key, val]) => { -// const { mapping } = argTypes[key] || {}; -// acc[key] = mapping && val in mapping ? mapping[val] : val; -// return acc; -// }, {} as Args), -// }; -// return passArgsFirst -// ? (original as ArgsStoryFn)(mapped.args, mapped) -// : (original as LegacyStoryFn)(mapped); -// }; - -// // lazily decorate the story when it's loaded -// const getDecorated: () => LegacyStoryFn = memoize(1)(() => -// applyDecorators(finalStoryFn, decorators) -// ); - -// const hooks = new HooksContext(); - -// // We need the combined parameters now in order to calculate argTypes, but we won't keep them -// const combinedParameters = this.combineStoryParameters(storyParameters, kind); - -// // We are going to make various UI changes in both the manager and the preview -// // based on whether it's an "args story", i.e. whether the story accepts a first -// // argument which is an `Args` object. Here we store it as a parameter on every story -// // for convenience, but we preface it with `__` to denote that it's an internal API -// // and that users probably shouldn't look at it. -// const { passArgsFirst = true } = combinedParameters; -// const __isArgsStory = passArgsFirst && original.length > 0; - -// const { argTypes = {} } = this._argTypesEnhancers.reduce( -// (accumulatedParameters: Parameters, enhancer) => ({ -// ...accumulatedParameters, -// argTypes: enhancer({ -// ...identification, -// storyFn: original, -// parameters: accumulatedParameters, -// args: {}, -// argTypes: {}, -// globals: {}, -// originalStoryFn: getOriginal(), -// }), -// }), -// { __isArgsStory, ...combinedParameters } -// ); - -// const storyParametersWithArgTypes = { ...storyParameters, argTypes, __isArgsStory }; - -// const storyFn: LegacyStoryFn = (runtimeContext: StoryContext) => { -// storyFnWarning(); -// return getDecorated()({ -// ...identification, -// ...runtimeContext, -// // Calculate "combined" parameters at render time (NOTE: for perf we could just use combinedParameters from above?) -// parameters: this.combineStoryParameters(storyParametersWithArgTypes, kind), -// hooks, -// args: _stories[id].args, -// argTypes, -// globals: this._globals, -// viewMode: this._selection?.viewMode, -// originalStoryFn: getOriginal(), -// }); -// }; - -// const unboundStoryFn: LegacyStoryFn = (context: StoryContext) => getDecorated()(context); - -// const applyLoaders = async () => { -// const context = { -// ...identification, -// // Calculate "combined" parameters at render time (NOTE: for perf we could just use combinedParameters from above?) -// parameters: this.combineStoryParameters(storyParametersWithArgTypes, kind), -// hooks, -// args: _stories[id].args, -// argTypes, -// globals: this._globals, -// viewMode: this._selection?.viewMode, -// originalStoryFn: getOriginal(), -// }; -// const loadResults = await Promise.all(loaders.map((loader) => loader(context))); -// const loaded = Object.assign({}, ...loadResults); -// return { ...context, loaded }; -// }; - -// // Pull out parameters.args.$ || .argTypes.$.defaultValue into initialArgs -// const passedArgs: Args = { -// ...this._kinds[kind].parameters.args, -// ...storyParameters.args, -// }; -// const defaultArgs: Args = Object.entries( -// argTypes as Record -// ).reduce((acc, [arg, { defaultValue }]) => { -// if (typeof defaultValue !== 'undefined') { -// acc[arg] = defaultValue; -// } -// return acc; -// }, {} as Args); -// if (Object.keys(defaultArgs).length > 0) { -// argTypeDefaultValueWarning(); -// } - -// const initialArgsBeforeEnhancers = { ...defaultArgs, ...passedArgs }; -// const initialArgs = this._argsEnhancers.reduce( -// (accumulatedArgs: Args, enhancer) => ({ -// ...accumulatedArgs, -// ...enhancer({ -// ...identification, -// parameters: combinedParameters, -// args: initialArgsBeforeEnhancers, -// argTypes, -// globals: {}, -// originalStoryFn: getOriginal(), -// }), -// }), -// initialArgsBeforeEnhancers -// ); - -// const runPlayFunction = async () => { -// const { play } = combinedParameters as { play?: () => any }; -// return play ? play() : undefined; -// }; - -// _stories[id] = { -// ...identification, - -// hooks, -// getDecorated, -// getOriginal, -// applyLoaders, -// runPlayFunction, -// storyFn, -// unboundStoryFn, - -// parameters: storyParametersWithArgTypes, -// args: initialArgs, -// argTypes, -// initialArgs, -// }; -// } - -// remove = (id: string, { allowUnsafe = false }: AllowUnsafeOption = {}): void => { -// if (!this._configuring && !allowUnsafe) -// throw new Error( -// 'Cannot remove a story when not configuring, see https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#story-store-immutable-outside-of-configuration' -// ); - -// const { _stories } = this; -// const story = _stories[id]; -// delete _stories[id]; - -// if (story) story.hooks.clean(); -// }; - -// removeStoryKind(kind: string, { allowUnsafe = false }: AllowUnsafeOption = {}) { -// if (!this._configuring && !allowUnsafe) -// throw new Error( -// 'Cannot remove a kind when not configuring, see https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#story-store-immutable-outside-of-configuration' -// ); - -// if (!this._kinds[kind]) return; - -// this._kinds[kind].parameters = {}; -// this._kinds[kind].decorators = []; - -// this.cleanHooksForKind(kind); -// this._stories = Object.entries(this._stories).reduce((acc: StoreData, [id, story]) => { -// if (story.kind !== kind) acc[id] = story; - -// return acc; -// }, {}); -// } - -// updateGlobals(newGlobals: Args) { -// this._globals = { ...this._globals, ...newGlobals }; -// this._channel.emit(Events.GLOBALS_UPDATED, { -// globals: this._globals, -// initialGlobals: this._initialGlobals, -// }); -// } - -// updateStoryArgs(id: string, newArgs: Args) { -// if (!this._stories[id]) throw new Error(`No story for id ${id}`); -// const { args } = this._stories[id]; -// this._stories[id].args = { ...args, ...newArgs }; - -// this._channel.emit(Events.STORY_ARGS_UPDATED, { storyId: id, args: this._stories[id].args }); -// } - -// resetStoryArgs(id: string, argNames?: string[]) { -// if (!this._stories[id]) throw new Error(`No story for id ${id}`); -// const { args, initialArgs } = this._stories[id]; - -// this._stories[id].args = { ...args }; // Make a copy to avoid problems -// (argNames || Object.keys(args)).forEach((name) => { -// // We overwrite like this to ensure we can reset to falsey values -// this._stories[id].args[name] = initialArgs[name]; -// }); - -// this._channel.emit(Events.STORY_ARGS_UPDATED, { storyId: id, args: this._stories[id].args }); -// } - -// fromId = (id: string): PublishedStoreItem | null => { -// try { -// const data = this._stories[id as string]; - -// if (!data || !data.getDecorated) { -// return null; -// } - -// return this.mergeAdditionalDataToStory(data); -// } catch (e) { -// logger.warn('failed to get story:', this._stories); -// logger.error(e); -// return null; -// } -// }; - -// raw(options?: StoryOptions): PublishedStoreItem[] { -// return Object.values(this._stories) -// .filter((i) => !!i.getDecorated) -// .filter((i) => includeStory(i, options)) -// .map((i) => this.mergeAdditionalDataToStory(i)); -// } - -// sortedStories(): StoreItem[] { -// // NOTE: when kinds are HMR'ed they get temporarily removed from the `_stories` array -// // and thus lose order. However `_kinds[x].order` preservers the original load order -// const kindOrder = mapValues(this._kinds, ({ order }) => order); -// const storySortParameter = this._globalMetadata.parameters?.options?.storySort; - -// const storyEntries = Object.entries(this._stories); -// // Add the kind parameters and global parameters to each entry -// const stories: [ -// StoryId, -// StoreItem, -// Parameters, -// Parameters -// ][] = storyEntries.map(([id, story]) => [ -// id, -// story, -// this._kinds[story.kind].parameters, -// this._globalMetadata.parameters, -// ]); -// if (storySortParameter) { -// let sortFn: Comparator; -// if (typeof storySortParameter === 'function') { -// sortFn = storySortParameter; -// } else { -// sortFn = storySort(storySortParameter); -// } -// stable.inplace(stories, sortFn); -// } else { -// stable.inplace(stories, (s1, s2) => kindOrder[s1[1].kind] - kindOrder[s2[1].kind]); -// } -// return stories.map(([id, s]) => s); -// } - -// extract(options: StoryOptions & { normalizeParameters?: boolean } = {}) { -// const stories = this.sortedStories(); - -// // removes function values from all stories so they are safe to transport over the channel -// return stories.reduce((acc, story) => { -// if (!includeStory(story, options)) return acc; - -// const extracted = toExtracted(story); -// if (options.normalizeParameters) return Object.assign(acc, { [story.id]: extracted }); - -// const { parameters, kind } = extracted as { -// parameters: Parameters; -// kind: StoryKind; -// }; -// return Object.assign(acc, { -// [story.id]: Object.assign(extracted, { -// parameters: this.combineStoryParameters(parameters, kind), -// }), -// }); -// }, {}); -// } - -// clearError() { -// this._error = null; -// } - -// setError = (err: ErrorLike) => { -// this._error = err; -// }; - -// getError = (): ErrorLike | undefined => this._error; - -// setSelectionSpecifier(selectionSpecifier: StoreSelectionSpecifier): void { -// this._selectionSpecifier = selectionSpecifier; -// } - -// setSelection(selection: StoreSelection): void { -// this._selection = selection; - -// if (this._channel) { -// this._channel.emit(Events.CURRENT_STORY_WAS_SET, this._selection); -// } -// } - -// isSingleStoryMode(): boolean { -// if (!this._selectionSpecifier) { -// return false; -// } - -// const { singleStory, storySpecifier } = this._selectionSpecifier; -// return storySpecifier && storySpecifier !== '*' && singleStory; -// } - -// getSelection = (): StoreSelection => this._selection; - -// getDataForManager = () => { -// return { -// v: 2, -// globalParameters: this._globalMetadata.parameters, -// globals: this._globals, -// error: this.getError(), -// kindParameters: mapValues(this._kinds, (metadata) => metadata.parameters), -// stories: this.extract({ includeDocsOnly: true, normalizeParameters: true }), -// }; -// }; - -// getStoriesJsonData = () => { -// const value = this.getDataForManager(); -// const allowed = ['fileName', 'docsOnly', 'framework', '__id', '__isArgsStory']; - -// return { -// v: 2, -// globalParameters: pick(value.globalParameters, allowed), -// kindParameters: mapValues(value.kindParameters, (v) => pick(v, allowed)), -// stories: mapValues(value.stories, (v: any) => ({ -// ...pick(v, ['id', 'name', 'kind', 'story']), -// parameters: pick(v.parameters, allowed), -// })), -// }; -// }; - -// pushToManager = () => { -// if (this._channel) { -// // send to the parent frame. -// this._channel.emit(Events.SET_STORIES, this.getDataForManager()); -// } -// }; - -// getStoryKinds() { -// return Array.from(new Set(this.raw().map((s) => s.kind))); -// } - -// getStoriesForKind = (kind: string) => this.raw().filter((story) => story.kind === kind); - -// getRawStory(kind: string, name: string) { -// return this.getStoriesForKind(kind).find((s) => s.name === name); -// } - -// cleanHooks(id: string) { -// if (this._stories[id]) { -// this._stories[id].hooks.clean(); -// } -// } - -// cleanHooksForKind(kind: string) { -// this.getStoriesForKind(kind).map((story) => this.cleanHooks(story.id)); -// } - -// // This API is a re-implementation of Storybook's original getStorybook() API. -// // As such it may not behave *exactly* the same, but aims to. Some notes: -// // - It is *NOT* sorted by the user's sort function, but remains sorted in "insertion order" -// // - It does not include docs-only stories -// getStorybook(): GetStorybookKind[] { -// return Object.values( -// this.raw().reduce((kinds: { [kind: string]: GetStorybookKind }, story) => { -// if (!includeStory(story)) return kinds; - -// const { -// kind, -// name, -// storyFn, -// parameters: { fileName }, -// } = story; - -// // eslint-disable-next-line no-param-reassign -// if (!kinds[kind]) kinds[kind] = { kind, fileName, stories: [] }; - -// kinds[kind].stories.push({ name, render: storyFn }); - -// return kinds; -// }, {}) -// ).sort((s1, s2) => this._kinds[s1.kind].order - this._kinds[s2.kind].order); -// } - -// private mergeAdditionalDataToStory(story: StoreItem): PublishedStoreItem { -// return { -// ...story, -// parameters: this.combineStoryParameters(story.parameters, story.kind), -// globals: this._globals, -// }; -// } -// } From ec5ddda840ba5663bb89f98b8eec0b91602935b6 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 23:01:17 +1000 Subject: [PATCH 125/285] More cleanup --- lib/core-client/src/preview/loadCsf.test.ts | 203 ----------------- lib/core-client/src/preview/loadCsf.ts | 231 -------------------- 2 files changed, 434 deletions(-) delete mode 100644 lib/core-client/src/preview/loadCsf.test.ts delete mode 100644 lib/core-client/src/preview/loadCsf.ts diff --git a/lib/core-client/src/preview/loadCsf.test.ts b/lib/core-client/src/preview/loadCsf.test.ts deleted file mode 100644 index 78efc43e710..00000000000 --- a/lib/core-client/src/preview/loadCsf.test.ts +++ /dev/null @@ -1,203 +0,0 @@ -// TODO - -export {}; - -// import { ConfigApi, ClientApi, StoryStore } from '@storybook/client-api'; -// import { logger } from '@storybook/client-logger'; -// import { RequireContext } from './types'; - -// import { loadCsf } from './loadCsf'; - -// jest.mock('@storybook/client-logger', () => ({ -// logger: { warn: jest.fn(), debug: jest.fn() }, -// })); - -// let cbs: ((data: any) => void)[]; -// let mod: NodeModule; -// beforeEach(() => { -// cbs = []; -// mod = ({ -// hot: { -// data: {}, -// dispose: (cb: (data: any) => void) => cbs.push(cb), -// accept: jest.fn(), -// }, -// } as unknown) as NodeModule; -// }); - -// function doHMRDispose() { -// cbs.forEach((cb) => cb(mod.hot.data)); -// cbs = []; -// } - -// afterEach(() => { -// doHMRDispose(); -// }); - -// function makeMocks() { -// const configApi = ({ configure: (x: Function) => x() } as unknown) as ConfigApi; -// const storyStore = ({ -// removeStoryKind: jest.fn(), -// } as unknown) as StoryStore; -// const clientApi = ({ -// storiesOf: jest.fn().mockImplementation(() => ({ -// addParameters: jest.fn(), -// addDecorator: jest.fn(), -// add: jest.fn(), -// })), -// } as unknown) as ClientApi; - -// const context = { configApi, storyStore, clientApi }; -// const configure = loadCsf(context); -// return { ...context, configure }; -// } - -// function makeRequireContext(map: Record): RequireContext { -// const context = (key: string) => map[key]; - -// return Object.assign(context, { -// keys: () => Object.keys(map), -// resolve: (key: string) => key, -// }); -// } - -// describe('core.preview.loadCsf', () => { - -// it('handles HMR correctly when adding stories', () => { -// const { configure, clientApi, storyStore } = makeMocks(); - -// const firstInput = { -// a: { -// default: { -// title: 'a', -// }, -// x: () => 0, -// }, -// }; -// configure('react', makeRequireContext(firstInput), mod); - -// // HMR dispose callbacks -// doHMRDispose(); - -// const mockedStoriesOf = clientApi.storiesOf as jest.Mock; -// mockedStoriesOf.mockClear(); -// const secondInput = { -// ...firstInput, -// b: { -// default: { -// title: 'b', -// }, -// x: () => 0, -// }, -// }; -// configure('react', makeRequireContext(secondInput), mod); - -// expect(storyStore.removeStoryKind).not.toHaveBeenCalled(); -// expect(mockedStoriesOf).toHaveBeenCalledWith('b', true); -// }); - -// it('handles HMR correctly when removing stories', () => { -// const { configure, clientApi, storyStore } = makeMocks(); - -// const firstInput = { -// a: { -// default: { -// title: 'a', -// }, -// x: () => 0, -// }, -// b: { -// default: { -// title: 'b', -// }, -// x: () => 0, -// }, -// }; -// configure('react', makeRequireContext(firstInput), mod); - -// // HMR dispose callbacks -// doHMRDispose(); - -// const mockedStoriesOf = clientApi.storiesOf as jest.Mock; -// mockedStoriesOf.mockClear(); -// const secondInput = { -// a: firstInput.a, -// }; -// configure('react', makeRequireContext(secondInput), mod); - -// expect(storyStore.removeStoryKind).toHaveBeenCalledWith('b'); -// expect(mockedStoriesOf).not.toHaveBeenCalled(); -// }); - -// it('handles HMR correctly when changing stories', () => { -// const { configure, clientApi, storyStore } = makeMocks(); - -// const firstInput = { -// a: { -// default: { -// title: 'a', -// }, -// x: () => 0, -// }, - -// b: { -// default: { -// title: 'b', -// }, -// x: () => 0, -// }, -// }; -// configure('react', makeRequireContext(firstInput), mod); - -// // HMR dispose callbacks -// doHMRDispose(); - -// const mockedStoriesOf = clientApi.storiesOf as jest.Mock; -// mockedStoriesOf.mockClear(); -// const secondInput = { -// ...firstInput, -// a: { -// default: { -// title: 'a', -// }, -// x: () => 0, -// y: () => 0, -// }, -// }; -// configure('react', makeRequireContext(secondInput), mod); - -// expect(storyStore.removeStoryKind).toHaveBeenCalledTimes(1); -// expect(storyStore.removeStoryKind).toHaveBeenCalledWith('a'); -// expect(mockedStoriesOf).toHaveBeenCalledWith('a', true); -// }); - -// it('gives a warning if there are no exported stories', () => { -// const { configure } = makeMocks(); - -// const input = { -// a: { -// default: { -// title: 'MissingExportsComponent', -// }, -// // no named exports, will not present a story -// }, -// }; -// configure('react', makeRequireContext(input), mod); -// expect(logger.warn).toHaveBeenCalled(); -// }); - -// it('does not give a warning if there are exported stories', () => { -// const { configure } = makeMocks(); - -// const input = { -// a: { -// default: { -// title: 'MissingExportsComponent', -// }, -// x: () => 0, -// }, -// }; -// configure('react', makeRequireContext(input), mod); -// expect(logger.warn).not.toHaveBeenCalled(); -// }); -// }); diff --git a/lib/core-client/src/preview/loadCsf.ts b/lib/core-client/src/preview/loadCsf.ts deleted file mode 100644 index 0ea038872f0..00000000000 --- a/lib/core-client/src/preview/loadCsf.ts +++ /dev/null @@ -1,231 +0,0 @@ -// TODO - -export {}; - -// import { ConfigApi, ClientApi, StoryStore } from '@storybook/client-api'; -// import { isExportStory } from '@storybook/csf'; -// import { logger } from '@storybook/client-logger'; -// import dedent from 'ts-dedent'; -// import deprecate from 'util-deprecate'; - -// import { Loadable, LoaderFunction, RequireContext } from './types'; -// import { normalizeStory } from './normalizeStory'; -// import { autoTitle } from './autoTitle'; - -// const duplicateKindWarning = deprecate( -// (kindName: string) => { -// logger.warn(`Duplicate title: '${kindName}'`); -// }, -// dedent` -// Duplicate title used in multiple files; use unique titles or a primary file for a component with re-exported stories. - -// https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-support-for-duplicate-kinds -// ` -// ); - -// let previousExports = new Map(); -// const loadStories = ( -// loadable: Loadable, -// framework: string, -// { clientApi, storyStore }: { clientApi: ClientApi; storyStore: StoryStore } -// ) => () => { -// // Make sure we don't try to define a kind more than once within the same load -// const loadedKinds = new Set(); - -// let reqs = null; -// // todo discuss / improve type check -// if (Array.isArray(loadable)) { -// reqs = loadable; -// } else if ((loadable as RequireContext).keys) { -// reqs = [loadable as RequireContext]; -// } - -// let currentExports = new Map(); -// if (reqs) { -// reqs.forEach((req) => { -// req.keys().forEach((filename: string) => { -// try { -// const fileExports = req(filename); -// currentExports.set( -// fileExports, -// // todo discuss: types infer that this is RequireContext; no checks needed? -// // NOTE: turns out `babel-plugin-require-context-hook` doesn't implement this (yet) -// typeof req.resolve === 'function' ? req.resolve(filename) : filename -// ); -// } catch (error) { -// logger.warn(`Unexpected error while loading ${filename}: ${error}`); -// } -// }); -// }); -// } else { -// const exported = (loadable as LoaderFunction)(); -// if (Array.isArray(exported) && exported.every((obj) => obj.default != null)) { -// currentExports = new Map(exported.map((fileExports) => [fileExports, null])); -// } else if (exported) { -// logger.warn( -// `Loader function passed to 'configure' should return void or an array of module exports that all contain a 'default' export. Received: ${JSON.stringify( -// exported -// )}` -// ); -// } -// } - -// const removed = Array.from(previousExports.keys()).filter((exp) => !currentExports.has(exp)); -// removed.forEach((exp) => { -// if (exp.default) { -// storyStore.removeStoryKind(exp.default.title); -// } -// }); - -// const added = Array.from(currentExports.keys()).filter((exp) => !previousExports.has(exp)); - -// added.forEach((fileExports) => { -// // An old-style story file -// if (!fileExports.default) { -// return; -// } - -// const { default: defaultExport, __namedExportsOrder, ...namedExports } = fileExports; -// let exports = namedExports; - -// const fileName = currentExports.get(fileExports); -// const title = autoTitle(defaultExport, fileName); -// if (!title) { -// throw new Error( -// `Unexpected default export without title: ${JSON.stringify(fileExports.default)}` -// ); -// } - -// const meta = { ...defaultExport, title }; - -// // prefer a user/loader provided `__namedExportsOrder` array if supplied -// // we do this as es module exports are always ordered alphabetically -// // see https://github.com/storybookjs/storybook/issues/9136 -// if (Array.isArray(__namedExportsOrder)) { -// exports = {}; -// __namedExportsOrder.forEach((name) => { -// if (namedExports[name]) { -// exports[name] = namedExports[name]; -// } -// }); -// } - -// const { -// title: kindName, -// parameters: kindParameters, -// decorators: kindDecorators, -// loaders: kindLoaders = [], -// component, -// subcomponents, -// args: kindArgs, -// argTypes: kindArgTypes, -// } = meta; - -// if (loadedKinds.has(kindName)) { -// duplicateKindWarning(kindName); -// } -// loadedKinds.add(kindName); - -// // We pass true here to avoid the warning about HMR. It's cool clientApi, we got this -// // todo discuss: TS now wants a NodeModule; should we fix this differently? -// const kind = clientApi.storiesOf(kindName, true as any); - -// // we should always have a framework, rest optional -// kind.addParameters({ -// framework, -// component, -// subcomponents, -// fileName, -// ...kindParameters, -// args: kindArgs, -// argTypes: kindArgTypes, -// }); - -// // todo add type -// (kindDecorators || []).forEach((decorator: any) => { -// kind.addDecorator(decorator); -// }); - -// kindLoaders.forEach((loader: any) => { -// kind.addLoader(loader); -// }); - -// const storyExports = Object.keys(exports); -// if (storyExports.length === 0) { -// logger.warn( -// dedent` -// Found a story file for "${kindName}" but no exported stories. -// Check the docs for reference: https://storybook.js.org/docs/formats/component-story-format/ -// ` -// ); -// return; -// } - -// storyExports.forEach((key) => { -// if (isExportStory(key, meta)) { -// const { name, storyFn, parameters } = normalizeStory( -// key, -// exports[key], -// meta, -// clientApi.globalRender -// ); -// kind.add(name, storyFn, parameters); -// } -// }); -// }); -// previousExports = currentExports; -// }; - -// const configureDeprecationWarning = deprecate( -// () => {}, -// `\`configure()\` is deprecated and will be removed in Storybook 7.0. -// Please use the \`stories\` field of \`main.js\` to load stories. -// Read more at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-configure` -// ); -// let loaded = false; -// export const loadCsf = ({ -// clientApi, -// storyStore, -// configApi, -// }: { -// clientApi: ClientApi; -// storyStore: StoryStore; -// configApi: ConfigApi; -// }) => -// /** -// * Load a collection of stories. If it has a default export, assume that it is a module-style -// * file and process its named exports as stories. If not, assume it's an old-style -// * storiesof file and require it. -// * -// * @param {*} framework - name of framework in use, e.g. "react" -// * @param {*} loadable a require.context `req`, an array of `req`s, or a loader function that returns void or an array of exports -// * @param {*} m - ES module object for hot-module-reloading (HMR) -// * @param {boolean} showDeprecationWarning - show the deprecation warning (default true) -// */ -// (framework: string, loadable: Loadable, m: NodeModule, showDeprecationWarning = true) => { -// if (showDeprecationWarning) { -// configureDeprecationWarning(); -// } - -// if (typeof m === 'string') { -// throw new Error( -// `Invalid module '${m}'. Did you forget to pass \`module\` as the second argument to \`configure\`"?` -// ); -// } - -// if (m && m.hot && m.hot.dispose) { -// ({ previousExports = new Map() } = m.hot.data || {}); -// m.hot.dispose((data) => { -// loaded = false; -// // eslint-disable-next-line no-param-reassign -// data.previousExports = previousExports; -// }); -// m.hot.accept(); -// } -// if (loaded) { -// logger.warn('Unexpected loaded state. Did you call `load` twice?'); -// } -// loaded = true; - -// configApi.configure(loadStories(loadable, framework, { clientApi, storyStore }), m); -// }; From 3279dbc9fb2aded330e7f1954d35f3fb5da2a137 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 31 Aug 2021 23:03:29 +1000 Subject: [PATCH 126/285] Update frameworks to use legacy types --- app/angular/src/client/preview/index.ts | 2 +- app/html/src/client/preview/index.ts | 2 +- app/preact/src/client/preview/index.ts | 2 +- app/react/src/client/preview/index.tsx | 2 +- app/server/src/client/preview/index.ts | 2 +- app/vue/src/client/preview/index.ts | 2 +- app/vue3/src/client/preview/index.ts | 2 +- app/web-components/src/client/preview/index.ts | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/angular/src/client/preview/index.ts b/app/angular/src/client/preview/index.ts index b8c011314a1..870babd2501 100644 --- a/app/angular/src/client/preview/index.ts +++ b/app/angular/src/client/preview/index.ts @@ -10,7 +10,7 @@ import { AngularFramework } from './types-6-0'; const framework = 'angular'; -interface ClientApi extends ClientStoryApi { +interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; diff --git a/app/html/src/client/preview/index.ts b/app/html/src/client/preview/index.ts index d48895a9735..e0fd7fdbdff 100644 --- a/app/html/src/client/preview/index.ts +++ b/app/html/src/client/preview/index.ts @@ -9,7 +9,7 @@ import { StoryFnHtmlReturnType, IStorybookSection } from './types'; const framework = 'html'; -interface ClientApi extends ClientStoryApi { +interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; diff --git a/app/preact/src/client/preview/index.ts b/app/preact/src/client/preview/index.ts index e8a004b293e..6f35fcf2060 100644 --- a/app/preact/src/client/preview/index.ts +++ b/app/preact/src/client/preview/index.ts @@ -7,7 +7,7 @@ import render from './render'; import { IStorybookSection } from './types'; import { PreactFramework } from './types-6-0'; -export interface ClientApi extends ClientStoryApi { +export interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; diff --git a/app/react/src/client/preview/index.tsx b/app/react/src/client/preview/index.tsx index ff2bfbfc8eb..0f482624abf 100644 --- a/app/react/src/client/preview/index.tsx +++ b/app/react/src/client/preview/index.tsx @@ -8,7 +8,7 @@ import render from './render'; import { IStorybookSection } from './types'; import { ReactFramework } from './types-6-0'; -interface ClientApi extends ClientStoryApi { +interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; diff --git a/app/server/src/client/preview/index.ts b/app/server/src/client/preview/index.ts index 619fb7c6166..fbbf1bd00d5 100644 --- a/app/server/src/client/preview/index.ts +++ b/app/server/src/client/preview/index.ts @@ -7,7 +7,7 @@ import { IStorybookSection, ServerFramework } from './types'; const framework = 'server'; -interface ClientApi extends ClientStoryApi { +interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; diff --git a/app/vue/src/client/preview/index.ts b/app/vue/src/client/preview/index.ts index 7ecf4990efc..52e98b3cfde 100644 --- a/app/vue/src/client/preview/index.ts +++ b/app/vue/src/client/preview/index.ts @@ -88,7 +88,7 @@ function decorateStory( } const framework = 'vue'; -interface ClientApi extends ClientStoryApi { +interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; diff --git a/app/vue3/src/client/preview/index.ts b/app/vue3/src/client/preview/index.ts index 9271a54160b..778fe899bc0 100644 --- a/app/vue3/src/client/preview/index.ts +++ b/app/vue3/src/client/preview/index.ts @@ -82,7 +82,7 @@ function decorateStory( } const framework = 'vue3'; -interface ClientApi extends ClientStoryApi { +interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; diff --git a/app/web-components/src/client/preview/index.ts b/app/web-components/src/client/preview/index.ts index 33ee97b66c5..f6f71e6669d 100644 --- a/app/web-components/src/client/preview/index.ts +++ b/app/web-components/src/client/preview/index.ts @@ -9,7 +9,7 @@ import { WebComponentsFramework } from './types-6-0'; const framework = 'web-components'; -interface ClientApi extends ClientStoryApi { +interface ClientApi extends ClientStoryApi { setAddon(addon: any): void; configure(loader: Loadable, module: NodeModule): void; getStorybook(): IStorybookSection[]; From 23ee4028a33d9718aa5e56910d4725bcd08c8698 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 1 Sep 2021 14:17:05 +1000 Subject: [PATCH 127/285] Update a bunch of types to get things to 'strap --- addons/backgrounds/package.json | 1 + .../src/decorators/withBackground.ts | 9 ++------- addons/backgrounds/src/decorators/withGrid.ts | 9 ++------- addons/measure/package.json | 1 + addons/measure/src/withMeasure.ts | 3 ++- addons/outline/package.json | 1 + addons/outline/src/withOutline.ts | 9 ++------- .../storyshots-core/src/frameworks/Loader.ts | 17 +++++++++-------- app/ember/package.json | 1 + app/ember/src/client/preview/render.ts | 3 ++- app/html/package.json | 1 + app/html/src/client/preview/render.ts | 2 +- app/preact/package.json | 1 + app/preact/src/client/preview/render.tsx | 3 ++- app/react/package.json | 1 + app/react/src/client/preview/render.tsx | 3 ++- app/server/package.json | 1 + app/server/src/client/preview/render.ts | 3 ++- app/svelte/src/client/preview/render.ts | 3 ++- app/vue/src/client/preview/render.ts | 2 +- app/vue3/src/client/preview/render.ts | 3 ++- app/web-components/package.json | 1 + app/web-components/src/client/preview/render.ts | 2 +- lib/store/src/StoryStore.ts | 2 -- yarn.lock | 9 +++++++++ 25 files changed, 50 insertions(+), 41 deletions(-) diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index 19b7cbe1dbb..8d4cb84c62c 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,6 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", + "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/backgrounds/src/decorators/withBackground.ts b/addons/backgrounds/src/decorators/withBackground.ts index 8d3be38596c..65395bc936a 100644 --- a/addons/backgrounds/src/decorators/withBackground.ts +++ b/addons/backgrounds/src/decorators/withBackground.ts @@ -1,10 +1,5 @@ -import { - Framework, - StoryFn as StoryFunction, - StoryContext, - useMemo, - useEffect, -} from '@storybook/addons'; +import { useMemo, useEffect } from '@storybook/addons'; +import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; import { diff --git a/addons/backgrounds/src/decorators/withGrid.ts b/addons/backgrounds/src/decorators/withGrid.ts index f5065ab908b..ecb7e55b6cb 100644 --- a/addons/backgrounds/src/decorators/withGrid.ts +++ b/addons/backgrounds/src/decorators/withGrid.ts @@ -1,12 +1,7 @@ import dedent from 'ts-dedent'; import deprecate from 'util-deprecate'; -import { - Framework, - StoryFn as StoryFunction, - StoryContext, - useMemo, - useEffect, -} from '@storybook/addons'; +import { useMemo, useEffect } from '@storybook/addons'; +import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { clearStyles, addGridStyle } from '../helpers'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; diff --git a/addons/measure/package.json b/addons/measure/package.json index 94a47f295f1..4df4c9a7c6f 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,6 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", + "@storybook/csf": "0.0.2--canary.c10361d.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/measure/src/withMeasure.ts b/addons/measure/src/withMeasure.ts index e47c4565b52..92f47637378 100644 --- a/addons/measure/src/withMeasure.ts +++ b/addons/measure/src/withMeasure.ts @@ -1,5 +1,6 @@ /* eslint-env browser */ -import { Framework, StoryFn as StoryFunction, StoryContext, useEffect } from '@storybook/addons'; +import { useEffect } from '@storybook/addons'; +import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { drawSelectedElement } from './box-model/visualizer'; import { init, rescale, destroy } from './box-model/canvas'; import { deepElementFromPoint } from './util'; diff --git a/addons/outline/package.json b/addons/outline/package.json index 4601fb9d607..4f3db5a5986 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,6 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", + "@storybook/csf": "0.0.2--canary.c10361d.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/outline/src/withOutline.ts b/addons/outline/src/withOutline.ts index ca49cf75427..22fa4595613 100644 --- a/addons/outline/src/withOutline.ts +++ b/addons/outline/src/withOutline.ts @@ -1,10 +1,5 @@ -import { - Framework, - StoryFn as StoryFunction, - StoryContext, - useMemo, - useEffect, -} from '@storybook/addons'; +import { useMemo, useEffect } from '@storybook/addons'; +import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { clearStyles, addOutlineStyles } from './helpers'; import { PARAM_KEY } from './constants'; diff --git a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts index 577f76291bb..4c60abdebd2 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts @@ -1,20 +1,21 @@ import { Framework } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; -import { ClientApi as ClientApiThing } from '@storybook/client-api'; +import { ClientApi as ClientApiClass } from '@storybook/client-api'; import { StoryshotsOptions } from '../api/StoryshotsOptions'; import { SupportedFramework } from './SupportedFramework'; export type RenderTree = (story: any, context?: any, options?: any) => any; -export interface ClientApi extends ClientStoryApi { +export interface ClientApi + extends ClientStoryApi { configure(loader: Loadable, module: NodeModule | false, showDeprecationWarning?: boolean): void; forceReRender(): void; - clearDecorators: ClientApiThing['clearDecorators']; - getStorybook: ClientApiThing['getStorybook']; - setAddon: ClientApiThing['setAddon']; - raw: ClientApiThing['raw']; - addArgsEnhancer: ClientApiThing['addArgsEnhancer']; - addArgTypesEnhancer: ClientApiThing['addArgTypesEnhancer']; + clearDecorators: ClientApiClass['clearDecorators']; + getStorybook: ClientApiClass['getStorybook']; + setAddon: ClientApiClass['setAddon']; + raw: ClientApiClass['raw']; + addArgsEnhancer: ClientApiClass['addArgsEnhancer']; + addArgTypesEnhancer: ClientApiClass['addArgTypesEnhancer']; } // TODO -- this is untyped for now, we could import each framework's Framework type diff --git a/app/ember/package.json b/app/ember/package.json index 68f587f79db..9dd36c0bbd9 100644 --- a/app/ember/package.json +++ b/app/ember/package.json @@ -45,6 +45,7 @@ "@ember/test-helpers": "^2.1.4", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", "react": "16.14.0", diff --git a/app/ember/src/client/preview/render.ts b/app/ember/src/client/preview/render.ts index 07c92e6ca6a..adc1fc01a8d 100644 --- a/app/ember/src/client/preview/render.ts +++ b/app/ember/src/client/preview/render.ts @@ -1,6 +1,7 @@ import global from 'global'; import dedent from 'ts-dedent'; -import { RenderContext, ElementArgs, OptionsArgs, EmberFramework } from './types'; +import { RenderContext } from '@storybook/store'; +import { ElementArgs, OptionsArgs, EmberFramework } from './types'; const { window: globalWindow, document } = global; diff --git a/app/html/package.json b/app/html/package.json index dca82bc9039..846e4ce19a2 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -50,6 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/html/src/client/preview/render.ts b/app/html/src/client/preview/render.ts index ffe562db5b3..a073bf8912d 100644 --- a/app/html/src/client/preview/render.ts +++ b/app/html/src/client/preview/render.ts @@ -2,7 +2,7 @@ import global from 'global'; import dedent from 'ts-dedent'; import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; -import { RenderContext } from './types'; +import { RenderContext } from '@storybook/store'; import { HtmlFramework } from './types-6-0'; const { Node } = global; diff --git a/app/preact/package.json b/app/preact/package.json index fae342cdbcf..9dc54aed196 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -50,6 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/preact/src/client/preview/render.tsx b/app/preact/src/client/preview/render.tsx index 21e2c11a6d2..981197f28f7 100644 --- a/app/preact/src/client/preview/render.tsx +++ b/app/preact/src/client/preview/render.tsx @@ -1,6 +1,7 @@ import * as preact from 'preact'; import dedent from 'ts-dedent'; -import { RenderContext, StoryFnPreactReturnType } from './types'; +import { RenderContext } from '@storybook/store'; +import { StoryFnPreactReturnType } from './types'; import { PreactFramework } from './types-6-0'; let renderedStory: Element; diff --git a/app/react/package.json b/app/react/package.json index 0cbad212b41..819b85f855a 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -56,6 +56,7 @@ "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", + "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "babel-plugin-add-react-displayname": "^0.0.5", "babel-plugin-named-asset-import": "^0.3.1", diff --git a/app/react/src/client/preview/render.tsx b/app/react/src/client/preview/render.tsx index 273ffe286d2..bb60d46359b 100644 --- a/app/react/src/client/preview/render.tsx +++ b/app/react/src/client/preview/render.tsx @@ -1,8 +1,9 @@ import global from 'global'; import React, { Component, FunctionComponent, ReactElement, StrictMode, Fragment } from 'react'; import ReactDOM from 'react-dom'; +import { RenderContext } from '@storybook/store'; -import { StoryContext, RenderContext } from './types'; +import { StoryContext } from './types'; import { ReactFramework } from './types-6-0'; const { FRAMEWORK_OPTIONS } = global; diff --git a/app/server/package.json b/app/server/package.json index d257e4a6820..b4d518d0b2e 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -52,6 +52,7 @@ "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.c10361d.0", "@storybook/node-logger": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/server/src/client/preview/render.ts b/app/server/src/client/preview/render.ts index c299d97fa2e..4420c9bc91b 100644 --- a/app/server/src/client/preview/render.ts +++ b/app/server/src/client/preview/render.ts @@ -2,8 +2,9 @@ import global from 'global'; import dedent from 'ts-dedent'; import { Args, ArgTypes } from '@storybook/api'; +import { RenderContext } from '@storybook/store'; import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; -import { RenderContext, FetchStoryHtmlType, ServerFramework } from './types'; +import { FetchStoryHtmlType, ServerFramework } from './types'; const { fetch, Node } = global; diff --git a/app/svelte/src/client/preview/render.ts b/app/svelte/src/client/preview/render.ts index 57dd00673dc..8e3a64cff02 100644 --- a/app/svelte/src/client/preview/render.ts +++ b/app/svelte/src/client/preview/render.ts @@ -1,5 +1,6 @@ import global from 'global'; -import { RenderContext, SvelteFramework } from './types'; +import { RenderContext } from '@storybook/store'; +import { SvelteFramework } from './types'; import PreviewRender from './PreviewRender.svelte'; const { document } = global; diff --git a/app/vue/src/client/preview/render.ts b/app/vue/src/client/preview/render.ts index 71e479066b8..5da7594f79d 100644 --- a/app/vue/src/client/preview/render.ts +++ b/app/vue/src/client/preview/render.ts @@ -1,6 +1,6 @@ import dedent from 'ts-dedent'; import Vue, { VNode } from 'vue'; -import { RenderContext } from './types'; +import { RenderContext } from '@storybook/store'; import { VueFramework } from './types-6-0'; export const COMPONENT = 'STORYBOOK_COMPONENT'; diff --git a/app/vue3/src/client/preview/render.ts b/app/vue3/src/client/preview/render.ts index aee3f9f118c..22fa07929eb 100644 --- a/app/vue3/src/client/preview/render.ts +++ b/app/vue3/src/client/preview/render.ts @@ -1,6 +1,7 @@ import dedent from 'ts-dedent'; import { createApp, h, shallowRef, ComponentPublicInstance } from 'vue'; -import { RenderContext, StoryFnVueReturnType } from './types'; +import { RenderContext } from '@storybook/store'; +import { StoryFnVueReturnType } from './types'; import { VueFramework } from './types-6-0'; const activeStoryComponent = shallowRef(null); diff --git a/app/web-components/package.json b/app/web-components/package.json index 171d918a4a6..7f7faedb689 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -55,6 +55,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "babel-plugin-bundled-import-meta": "^0.3.1", diff --git a/app/web-components/src/client/preview/render.ts b/app/web-components/src/client/preview/render.ts index 807380682e4..22eac448b3b 100644 --- a/app/web-components/src/client/preview/render.ts +++ b/app/web-components/src/client/preview/render.ts @@ -6,7 +6,7 @@ import { render, TemplateResult } from 'lit-html'; // eslint-disable-next-line import/extensions import { isTemplateResult } from 'lit-html/directive-helpers.js'; import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; -import { RenderContext } from './types'; +import { RenderContext } from '@storybook/store'; import { WebComponentsFramework } from './types-6-0'; const { Node } = global; diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 758142433b8..3869a23b090 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -42,8 +42,6 @@ function normalizeGlobalAnnotations({ }; } -// FIXME: what are we doing with autoTitle and entries? -const entries: NormalizedStoriesEntry[] = []; export class StoryStore { storiesList: StoriesListStore; diff --git a/yarn.lock b/yarn.lock index 78340f95b96..d25c386dfc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5602,6 +5602,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/theming": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -5886,6 +5887,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -5909,6 +5911,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 + "@storybook/csf": 0.0.2--canary.c10361d.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -6873,6 +6876,7 @@ __metadata: "@ember/test-helpers": ^2.1.4 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.19 core-js: ^3.8.2 global: ^4.4.0 react: 16.14.0 @@ -6956,6 +6960,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7157,6 +7162,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7240,6 +7246,7 @@ __metadata: "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 + "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/prompts": ^2.0.9 "@types/webpack-env": ^1.16.0 @@ -7535,6 +7542,7 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/node-logger": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7782,6 +7790,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 babel-plugin-bundled-import-meta: ^0.3.1 From 8dfe9f9fde5bbef2abc5ae74bb4fe072690b7d5f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 1 Sep 2021 15:01:41 +1000 Subject: [PATCH 128/285] Added a "sync" init path to allow storyshots to be sycn --- .../storyshots-core/src/api/index.ts | 6 +- .../storyshots-core/src/frameworks/Loader.ts | 2 +- lib/client-api/src/ClientApi.ts | 1 + lib/core-client/src/preview/start.ts | 6 +- lib/store/src/StoriesListStore.ts | 34 ++++++---- lib/store/src/StoryStore.ts | 68 ++++++++++++++++--- lib/store/src/types.ts | 2 +- lib/web-preview/src/WebPreview.tsx | 12 +++- 8 files changed, 98 insertions(+), 33 deletions(-) diff --git a/addons/storyshots/storyshots-core/src/api/index.ts b/addons/storyshots/storyshots-core/src/api/index.ts index 211205abfaa..6a39efa557c 100644 --- a/addons/storyshots/storyshots-core/src/api/index.ts +++ b/addons/storyshots/storyshots-core/src/api/index.ts @@ -1,6 +1,5 @@ import global from 'global'; import { addons, mockChannel } from '@storybook/addons'; -import { Framework, StoryContextForLoaders } from '@storybook/csf'; import ensureOptionsDefaults from './ensureOptionsDefaults'; import snapshotsTests from './snapshotsTestsTemplate'; import integrityTest from './integrityTestTemplate'; @@ -51,8 +50,7 @@ function testStorySnapshots(options: StoryshotsOptions = {}) { }; const data = storybook.raw().reduce( - // TODO - (acc, item: StoryContextForLoaders) => { + (acc, item) => { if (storyNameRegex && !item.name.match(storyNameRegex)) { return acc; } @@ -61,8 +59,6 @@ function testStorySnapshots(options: StoryshotsOptions = {}) { return acc; } - // FIXME -- need raw() to return story s - // @ts-ignore const { kind, storyFn: render, parameters } = item; const existing = acc.find((i: any) => i.kind === kind); const { fileName } = item.parameters; diff --git a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts index 4c60abdebd2..22773bc7ed4 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts @@ -13,9 +13,9 @@ export interface ClientApi clearDecorators: ClientApiClass['clearDecorators']; getStorybook: ClientApiClass['getStorybook']; setAddon: ClientApiClass['setAddon']; - raw: ClientApiClass['raw']; addArgsEnhancer: ClientApiClass['addArgsEnhancer']; addArgTypesEnhancer: ClientApiClass['addArgTypesEnhancer']; + raw: ClientApiClass['raw']; } // TODO -- this is untyped for now, we could import each framework's Framework type diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 3dd49367e6d..331be9e275b 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -440,6 +440,7 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m return Object.values(kinds); } + // @deprecated raw() { return this.storyStore.raw(); } diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 37b35af8ee4..fc8a71f1b23 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -35,7 +35,7 @@ export function start( clientApi, // This gets called each time the user calls configure (i.e. once per HMR) // The first time, it constructs the preview, subsequently it updates it - async configure(framework: string, loadable: Loadable, m?: NodeModule) { + configure(framework: string, loadable: Loadable, m?: NodeModule) { clientApi.addParameters({ framework }); // We need to run the `executeLoadableForChanges` function *inside* the `getGlobalAnnotations @@ -62,7 +62,7 @@ export function start( preview = new WebPreview({ importFn: (path: Path) => clientApi.importFn(path), getGlobalAnnotations, - fetchStoriesList: async () => clientApi.getStoriesList(), + fetchStoriesList: () => clientApi.getStoriesList(), }); if (globalWindow) { // eslint-disable-next-line no-underscore-dangle @@ -75,7 +75,7 @@ export function start( clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); clientApi.storyStore = preview.storyStore; - await preview.initialize({ cacheAllCSFFiles: true }); + preview.initializeSync({ cacheAllCSFFiles: true }); } else { getGlobalAnnotations(); preview.onImportFnChanged({ importFn: (path: Path) => clientApi.importFn(path) }); diff --git a/lib/store/src/StoriesListStore.ts b/lib/store/src/StoriesListStore.ts index d350c24deca..85c79d8be89 100644 --- a/lib/store/src/StoriesListStore.ts +++ b/lib/store/src/StoriesListStore.ts @@ -1,36 +1,35 @@ -import createChannel from '@storybook/channel-websocket'; +// import createChannel from '@storybook/channel-websocket'; import { Channel } from '@storybook/addons'; import { StoryId } from '@storybook/csf'; import { StorySpecifier, Path, StoriesList, StoriesListStory } from './types'; export class StoriesListStore { - fetchStoriesList: () => Promise; + fetchStoriesList: () => Promise | StoriesList; channel: Channel; storiesList: StoriesList; - constructor({ fetchStoriesList }: { fetchStoriesList: () => Promise }) { + constructor({ fetchStoriesList }: { fetchStoriesList: StoriesListStore['fetchStoriesList'] }) { this.fetchStoriesList = fetchStoriesList; // TODO -- where do we get the URL from? - this.channel = createChannel({ - url: 'ws://localhost:8080', - async: false, - onError: this.onChannelError.bind(this), - }); + // this.channel = createChannel({ + // url: 'ws://localhost:8080', + // async: false, + // onError: this.onChannelError.bind(this), + // }); } async initialize() { - // TODO -- constants - // this.channel.on('INITIALIZE_STORIES', this.onStoriesChanged.bind(this)); - this.channel.on('PATCH_STORIES', this.onStoriesChanged.bind(this)); - this.channel.on('DELETE_STORIES', this.onStoriesChanged.bind(this)); - return this.cacheStoriesList(); } + initializeSync() { + return this.cacheStoriesListSync(); + } + // TODO -- what to do here? onChannelError(err: Error) { // console.log(err); @@ -44,6 +43,15 @@ export class StoriesListStore { this.storiesList = await this.fetchStoriesList(); } + async cacheStoriesListSync() { + this.storiesList = this.fetchStoriesList() as StoriesList; + if (!this.storiesList.v) { + throw new Error( + `fetchStoriesList() didn't return a stories list, did you pass an async version then call initializeSync()?` + ); + } + } + storyIdFromSpecifier(specifier: StorySpecifier) { const storyIds = Object.keys(this.storiesList.stories); if (specifier === '*') { diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 3869a23b090..50ac52d8bd3 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -6,6 +6,7 @@ import { Framework, GlobalAnnotations, ComponentTitle, + StoryContext, } from '@storybook/csf'; import { StoriesListStore } from './StoriesListStore'; @@ -19,9 +20,9 @@ import { Story, StoriesList, NormalizedGlobalAnnotations, - NormalizedStoriesEntry, Path, ExtractOptions, + ModuleExports, } from './types'; import { HooksContext } from './hooks'; import { normalizeInputTypes } from './normalizeInputTypes'; @@ -68,7 +69,7 @@ export class StoryStore { }: { importFn: ModuleImportFn; globalAnnotations: GlobalAnnotations; - fetchStoriesList: () => Promise; + fetchStoriesList: ConstructorParameters[0]['fetchStoriesList']; }) { this.storiesList = new StoriesListStore({ fetchStoriesList }); this.importFn = importFn; @@ -91,6 +92,14 @@ export class StoryStore { } } + initializeSync({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { + this.storiesList.initializeSync(); + + if (cacheAllCSFFiles) { + this.cacheAllCSFFilesSync(); + } + } + updateGlobalAnnotations(globalAnnotations: GlobalAnnotations) { this.globalAnnotations = normalizeGlobalAnnotations(globalAnnotations); const { globals, globalTypes } = globalAnnotations; @@ -114,6 +123,17 @@ export class StoryStore { return this.processCSFFileWithCache(moduleExports, title); } + loadCSFFileByStoryIdSync(storyId: StoryId): CSFFile { + const { importPath, title } = this.storiesList.storyIdToMetadata(storyId); + const moduleExports = this.importFn(importPath); + if (Promise.resolve(moduleExports) === moduleExports) { + throw new Error( + `importFn() returned a promise, did you pass an async version then call initializeSync()?` + ); + } + return this.processCSFFileWithCache(moduleExports as ModuleExports, title); + } + async loadAllCSFFiles(): Promise>> { const importPaths: Record = {}; Object.entries(this.storiesList.storiesList.stories).forEach(([storyId, { importPath }]) => { @@ -135,10 +155,31 @@ export class StoryStore { }, {} as Record>); } + loadAllCSFFilesSync(): Record> { + const importPaths: Record = {}; + Object.entries(this.storiesList.storiesList.stories).forEach(([storyId, { importPath }]) => { + importPaths[importPath] = storyId; + }); + + const csfFileList = Object.entries(importPaths).map(([importPath, storyId]): [ + Path, + CSFFile + ] => [importPath, this.loadCSFFileByStoryIdSync(storyId)]); + + return csfFileList.reduce((acc, [importPath, csfFile]) => { + acc[importPath] = csfFile; + return acc; + }, {} as Record>); + } + async cacheAllCSFFiles(): Promise { this.cachedCSFFiles = await this.loadAllCSFFiles(); } + cacheAllCSFFilesSync() { + this.cachedCSFFiles = this.loadAllCSFFilesSync(); + } + async loadStory({ storyId }: { storyId: StoryId }): Promise> { const csfFile = await this.loadCSFFileByStoryId(storyId); return this.storyFromCSFFile({ storyId, csfFile }); @@ -234,14 +275,23 @@ export class StoryStore { } raw() { - throw new Error( - `StoryStore.raw() is no longer implemented. If you were relying on this API, please contact us on Discord.` - ); + return this.extract().map(({ id }: { id: StoryId }) => this.fromId(id)); } - fromId() { - throw new Error( - `StoryStore.fromId() is no longer implemented. If you were relying on this API, please contact us on Discord.` - ); + fromId(storyId: StoryId): StoryContextForLoaders { + if (!this.cachedCSFFiles) { + throw new Error('Cannot call fromId/raw() unless you call cacheAllCSFFiles() first.'); + } + + const { importPath } = this.storiesList.storyIdToMetadata(storyId); + if (!importPath) { + throw new Error(`Unknown storyId ${storyId}`); + } + const csfFile = this.cachedCSFFiles[importPath]; + const story = this.storyFromCSFFile({ storyId, csfFile }); + return { + ...this.getStoryContext(story), + viewMode: 'story', + } as StoryContextForLoaders; } } diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 8aad846fc15..1ec5998f9e8 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -22,7 +22,7 @@ import { export type Path = string; export type ModuleExports = Record; -export type ModuleImportFn = (path: Path) => ModuleExports; +export type ModuleImportFn = (path: Path) => Promise | ModuleExports; export type NormalizedGlobalAnnotations< TFramework extends Framework diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 4befce7452e..8fe83fed0d3 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -63,7 +63,7 @@ export class WebPreview { }: { getGlobalAnnotations: () => WebGlobalAnnotations; importFn: ModuleImportFn; - fetchStoriesList: () => Promise; + fetchStoriesList: ConstructorParameters[0]['fetchStoriesList']; }) { this.channel = addons.getChannel(); this.view = new WebView(); @@ -96,6 +96,16 @@ export class WebPreview { async initialize({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { await this.storyStore.initialize({ cacheAllCSFFiles }); + await this.setupListenersAndRenderSelection(); + } + + initializeSync({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { + this.storyStore.initializeSync({ cacheAllCSFFiles }); + // NOTE: we don't await this, but return the promise so the caller can await it if they want + return this.setupListenersAndRenderSelection(); + } + + async setupListenersAndRenderSelection() { this.setupListeners(); const { globals } = this.urlStore.selectionSpecifier || {}; From 7168f33b726a1ceac1800c78a72c1618b9eaac07 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 1 Sep 2021 15:03:30 +1000 Subject: [PATCH 129/285] Don't watch a channel just yet in SLS --- lib/store/package.json | 1 - lib/store/src/StoriesListStore.ts | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/lib/store/package.json b/lib/store/package.json index f575e8995af..e30843220d4 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -41,7 +41,6 @@ }, "dependencies": { "@storybook/addons": "6.4.0-alpha.19", - "@storybook/channel-websocket": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.c10361d.0", diff --git a/lib/store/src/StoriesListStore.ts b/lib/store/src/StoriesListStore.ts index 85c79d8be89..5f4b93389ec 100644 --- a/lib/store/src/StoriesListStore.ts +++ b/lib/store/src/StoriesListStore.ts @@ -1,4 +1,3 @@ -// import createChannel from '@storybook/channel-websocket'; import { Channel } from '@storybook/addons'; import { StoryId } from '@storybook/csf'; @@ -13,13 +12,6 @@ export class StoriesListStore { constructor({ fetchStoriesList }: { fetchStoriesList: StoriesListStore['fetchStoriesList'] }) { this.fetchStoriesList = fetchStoriesList; - - // TODO -- where do we get the URL from? - // this.channel = createChannel({ - // url: 'ws://localhost:8080', - // async: false, - // onError: this.onChannelError.bind(this), - // }); } async initialize() { @@ -30,11 +22,6 @@ export class StoriesListStore { return this.cacheStoriesListSync(); } - // TODO -- what to do here? - onChannelError(err: Error) { - // console.log(err); - } - async onStoriesChanged() { this.storiesList = await this.fetchStoriesList(); } From 6f584a212c2dab239dc34957d705d6807d9aa1bf Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 12:34:24 +1000 Subject: [PATCH 130/285] Fixed up getStorybook/raw and made storyshots work --- .../storyshot.metadata.test.js.snap | 1 - lib/client-api/src/ClientApi.ts | 58 +++++++++---------- lib/store/src/StoryStore.ts | 23 +++++--- lib/store/src/prepareStory.ts | 12 +--- lib/store/src/types.ts | 6 +- 5 files changed, 48 insertions(+), 52 deletions(-) diff --git a/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap b/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap index c9965e394a4..3f1706c5fc8 100644 --- a/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap +++ b/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap @@ -6,6 +6,5 @@ exports[`Storyshots Text Simple 1`] = ` contents - suffix `; diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 331be9e275b..32d823900eb 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -5,6 +5,7 @@ import { logger } from '@storybook/client-logger'; import { Framework, toId, + isExportStory, DecoratorFunction, Parameters, ArgTypesEnhancer, @@ -387,7 +388,7 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m this.clearFilenameExports(fileName); const { default: defaultExport, __namedExportsOrder, ...namedExports } = fileExports; - const { title } = defaultExport || {}; + const { id: componentId, title } = defaultExport || {}; if (!title) { throw new Error( `Unexpected default export without title: ${JSON.stringify(fileExports.default)}` @@ -396,31 +397,27 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m this.csfExports[fileName] = fileExports; - let exports = namedExports; - if (Array.isArray(__namedExportsOrder)) { - exports = {}; - __namedExportsOrder.forEach((name) => { - if (namedExports[name]) { - exports[name] = namedExports[name]; - } + Object.entries(namedExports) + .filter(([key]) => isExportStory(key, defaultExport)) + .forEach(([key, storyExport]: [string, any]) => { + // TODO -- this little block of code is common with `processCSFFile` + const exportName = storyNameFromExport(key); + const id = storyExport.parameters?.__id || toId(componentId || title, exportName); + const name = + (typeof storyExport !== 'function' && storyExport.name) || + storyExport.storyName || + storyExport.story?.name || + exportName; + + this.stories[id] = { + name, + title, + importPath: fileName, + }; }); - } - Object.entries(exports).forEach(([key, storyExport]: [string, any]) => { - const actualName: string = - (typeof storyExport !== 'function' && storyExport.name) || - storyExport.storyName || - storyExport.story?.name || - storyNameFromExport(key); - const id = storyExport.parameters?.__id || toId(title, actualName); - this.stories[id] = { - name: actualName, - title, - importPath: fileName, - }; - }); } - getStorybook(): GetStorybookKind[] { + getStorybook = (): GetStorybookKind[] => { const storiesList = this.getStoriesList(); const kinds: Record> = {}; @@ -429,19 +426,16 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m kinds[title] = { kind: title, fileName: importPath, stories: [] }; } - const csfFile = this.storyStore.cachedCSFFiles[importPath]; - const { unboundStoryFn } = this.storyStore.storyFromCSFFile({ - storyId, - csfFile, - }); - kinds[title].stories.push({ name, render: unboundStoryFn }); + const { storyFn } = this.storyStore.fromId(storyId); + + kinds[title].stories.push({ name, render: storyFn }); }); return Object.values(kinds); - } + }; // @deprecated - raw() { + raw = () => { return this.storyStore.raw(); - } + }; } diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 50ac52d8bd3..9fc3ce30b70 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -23,6 +23,7 @@ import { Path, ExtractOptions, ModuleExports, + UnboundStory, } from './types'; import { HooksContext } from './hooks'; import { normalizeInputTypes } from './normalizeInputTypes'; @@ -201,7 +202,15 @@ export class StoryStore { const story = this.prepareStoryWithCache(storyMeta, componentMeta, this.globalAnnotations); this.args.setInitial(story.id, story.initialArgs); this.hooks[story.id] = new HooksContext(); - return story; + return { + ...story, + storyFn: (context) => + story.unboundStoryFn({ + ...this.getStoryContext(story), + viewMode: 'story', + ...context, + }), + }; } componentStoriesFromCSFFile({ csfFile }: { csfFile: CSFFile }): Story[] { @@ -210,7 +219,9 @@ export class StoryStore { ); } - getStoryContext(story: Story): Omit, 'viewMode'> { + getStoryContext( + story: UnboundStory + ): Omit, 'viewMode'> { return { ...story, args: this.args.get(story.id), @@ -278,7 +289,7 @@ export class StoryStore { return this.extract().map(({ id }: { id: StoryId }) => this.fromId(id)); } - fromId(storyId: StoryId): StoryContextForLoaders { + fromId(storyId: StoryId): Story { if (!this.cachedCSFFiles) { throw new Error('Cannot call fromId/raw() unless you call cacheAllCSFFiles() first.'); } @@ -288,10 +299,6 @@ export class StoryStore { throw new Error(`Unknown storyId ${storyId}`); } const csfFile = this.cachedCSFFiles[importPath]; - const story = this.storyFromCSFFile({ storyId, csfFile }); - return { - ...this.getStoryContext(story), - viewMode: 'story', - } as StoryContextForLoaders; + return this.storyFromCSFFile({ storyId, csfFile }); } } diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index acb5c7b5dd7..9ccc46b169f 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -16,7 +16,7 @@ import { import { NormalizedComponentAnnotations, - Story, + UnboundStory, NormalizedStoryAnnotations, NormalizedGlobalAnnotations, } from './types'; @@ -41,7 +41,7 @@ export function prepareStory( storyAnnotations: NormalizedStoryAnnotations, componentAnnotations: NormalizedComponentAnnotations, globalAnnotations: NormalizedGlobalAnnotations -): Story { +): UnboundStory { // NOTE: in the current implementation we are doing everything once, up front, rather than doing // anything at render time. The assumption is that as we don't load all the stories at once, this // will have a limited cost. If this proves misguided, we can refactor it. @@ -175,11 +175,3 @@ export function prepareStory( runPlayFunction, }; } - -// function preparedStoryToFunction(preparedStory) { -// return () => { -// const result = preparedStory.unboundStoryFn(preparedStory.initialContext) -// preparedStory.cleanup(); - -// return result; -// } diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 1ec5998f9e8..80c725b70cd 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -53,7 +53,7 @@ export type CSFFile = { stories: Record>; }; -export type Story = StoryContextForEnhancers & { +export type UnboundStory = StoryContextForEnhancers & { originalStoryFn: StoryFn; undecoratedStoryFn: LegacyStoryFn; unboundStoryFn: LegacyStoryFn; @@ -61,6 +61,10 @@ export type Story = StoryContextForEnhancers Promise; }; +export type Story = UnboundStory & { + storyFn: LegacyStoryFn; +}; + export declare type RenderContext = StoryIdentifier & { showMain: () => void; showError: (error: { title: string; description: string }) => void; From 6b4b75305ee50ed264cb99bb2f297f5ecb19e7ec Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 12:51:32 +1000 Subject: [PATCH 131/285] Lock update --- yarn.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index d25c386dfc6..ea726b97430 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7588,7 +7588,6 @@ __metadata: resolution: "@storybook/store@workspace:lib/store" dependencies: "@storybook/addons": 6.4.0-alpha.19 - "@storybook/channel-websocket": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.c10361d.0 From 134d4ec71fa4b577ab5762eb05844f8ec6c08dbc Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 13:07:24 +1000 Subject: [PATCH 132/285] Reverse Story/UnboundStory --- lib/store/src/StoryStore.ts | 31 ++++++++++++++----------------- lib/store/src/prepareStory.ts | 6 ++---- lib/store/src/types.ts | 4 ++-- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 9fc3ce30b70..2df06812c74 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -6,7 +6,6 @@ import { Framework, GlobalAnnotations, ComponentTitle, - StoryContext, } from '@storybook/csf'; import { StoriesListStore } from './StoriesListStore'; @@ -18,12 +17,11 @@ import { CSFFile, ModuleImportFn, Story, - StoriesList, NormalizedGlobalAnnotations, Path, ExtractOptions, ModuleExports, - UnboundStory, + BoundStory, } from './types'; import { HooksContext } from './hooks'; import { normalizeInputTypes } from './normalizeInputTypes'; @@ -202,15 +200,7 @@ export class StoryStore { const story = this.prepareStoryWithCache(storyMeta, componentMeta, this.globalAnnotations); this.args.setInitial(story.id, story.initialArgs); this.hooks[story.id] = new HooksContext(); - return { - ...story, - storyFn: (context) => - story.unboundStoryFn({ - ...this.getStoryContext(story), - viewMode: 'story', - ...context, - }), - }; + return story; } componentStoriesFromCSFFile({ csfFile }: { csfFile: CSFFile }): Story[] { @@ -219,9 +209,7 @@ export class StoryStore { ); } - getStoryContext( - story: UnboundStory - ): Omit, 'viewMode'> { + getStoryContext(story: Story): Omit, 'viewMode'> { return { ...story, args: this.args.get(story.id), @@ -289,7 +277,7 @@ export class StoryStore { return this.extract().map(({ id }: { id: StoryId }) => this.fromId(id)); } - fromId(storyId: StoryId): Story { + fromId(storyId: StoryId): BoundStory { if (!this.cachedCSFFiles) { throw new Error('Cannot call fromId/raw() unless you call cacheAllCSFFiles() first.'); } @@ -299,6 +287,15 @@ export class StoryStore { throw new Error(`Unknown storyId ${storyId}`); } const csfFile = this.cachedCSFFiles[importPath]; - return this.storyFromCSFFile({ storyId, csfFile }); + const story = this.storyFromCSFFile({ storyId, csfFile }); + return { + ...story, + storyFn: (context) => + story.unboundStoryFn({ + ...this.getStoryContext(story), + viewMode: 'story', + ...context, + }), + }; } } diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 9ccc46b169f..0c783580615 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -4,19 +4,17 @@ import deprecate from 'util-deprecate'; import { Parameters, Args, - ArgTypes, LegacyStoryFn, ArgsStoryFn, StoryContextForEnhancers, StoryContext, Framework, StrictArgTypes, - StrictInputType, } from '@storybook/csf'; import { NormalizedComponentAnnotations, - UnboundStory, + Story, NormalizedStoryAnnotations, NormalizedGlobalAnnotations, } from './types'; @@ -41,7 +39,7 @@ export function prepareStory( storyAnnotations: NormalizedStoryAnnotations, componentAnnotations: NormalizedComponentAnnotations, globalAnnotations: NormalizedGlobalAnnotations -): UnboundStory { +): Story { // NOTE: in the current implementation we are doing everything once, up front, rather than doing // anything at render time. The assumption is that as we don't load all the stories at once, this // will have a limited cost. If this proves misguided, we can refactor it. diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 80c725b70cd..b4d76c8a1de 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -53,7 +53,7 @@ export type CSFFile = { stories: Record>; }; -export type UnboundStory = StoryContextForEnhancers & { +export type Story = StoryContextForEnhancers & { originalStoryFn: StoryFn; undecoratedStoryFn: LegacyStoryFn; unboundStoryFn: LegacyStoryFn; @@ -61,7 +61,7 @@ export type UnboundStory = StoryContextForEnhancer runPlayFunction: () => Promise; }; -export type Story = UnboundStory & { +export type BoundStory = Story & { storyFn: LegacyStoryFn; }; From 9cdd8f898aebc69b43b76a017659a2f237509671 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 13:13:02 +1000 Subject: [PATCH 133/285] Update argTypes tests --- .../frameworks/common/enhanceArgTypes.test.ts | 27 +++++++++++-------- .../frameworks/svelte/extractArgTypes.test.ts | 9 ++++--- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts b/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts index 50222a9fda4..50a03e483df 100644 --- a/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts +++ b/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts @@ -1,4 +1,5 @@ import { ArgType, ArgTypes } from '@storybook/api'; +import { StrictInputType } from '@storybook/csf'; import { enhanceArgTypes } from './enhanceArgTypes'; expect.addSnapshotSerializer({ @@ -12,15 +13,18 @@ const enhance = ({ extractedArgTypes, isArgsStory = true, }: { - argType?: ArgType; + argType?: StrictInputType; arg?: any; extractedArgTypes?: ArgTypes; isArgsStory?: boolean; }) => { const context = { - id: 'foo--bar', + componentId: 'foo', + title: 'foo', kind: 'foo', + id: 'foo--bar', name: 'bar', + story: 'bar', component: 'dummy', parameters: { __isArgsStory: isArgsStory, @@ -29,6 +33,7 @@ const enhance = ({ }, }, argTypes: argType && { input: argType }, + initialArgs: { input: arg }, args: { input: arg }, globals: {}, }; @@ -40,7 +45,7 @@ describe('enhanceArgTypes', () => { it('should no-op', () => { expect( enhance({ - argType: { foo: 'unmodified', type: { name: 'number' } }, + argType: { name: 'input', foo: 'unmodified', type: { name: 'number' } }, isArgsStory: false, }).input ).toMatchInlineSnapshot(` @@ -60,7 +65,7 @@ describe('enhanceArgTypes', () => { it('number', () => { expect( enhance({ - argType: { type: { name: 'number' } }, + argType: { name: 'input', type: { name: 'number' } }, }).input ).toMatchInlineSnapshot(` { @@ -93,7 +98,7 @@ describe('enhanceArgTypes', () => { it('range', () => { expect( enhance({ - argType: { control: { type: 'range', min: 0, max: 100 } }, + argType: { name: 'input', control: { type: 'range', min: 0, max: 100 } }, }).input ).toMatchInlineSnapshot(` { @@ -109,7 +114,7 @@ describe('enhanceArgTypes', () => { it('options', () => { expect( enhance({ - argType: { control: { type: 'radio', options: [1, 2] } }, + argType: { name: 'input', control: { type: 'radio', options: [1, 2] } }, }).input ).toMatchInlineSnapshot(` { @@ -131,7 +136,7 @@ describe('enhanceArgTypes', () => { it('user-specified argTypes take precedence over extracted argTypes', () => { expect( enhance({ - argType: { type: { name: 'number' } }, + argType: { name: 'input', type: { name: 'number' } }, extractedArgTypes: { input: { type: { name: 'string' } } }, }).input ).toMatchInlineSnapshot(` @@ -147,7 +152,7 @@ describe('enhanceArgTypes', () => { it('user-specified argTypes take precedence over inferred argTypes', () => { expect( enhance({ - argType: { type: { name: 'number' } }, + argType: { name: 'input', type: { name: 'number' } }, arg: 'hello', }).input ).toMatchInlineSnapshot(` @@ -178,7 +183,7 @@ describe('enhanceArgTypes', () => { it('user-specified controls take precedence over inferred controls', () => { expect( enhance({ - argType: { defaultValue: 5, control: { type: 'range', step: 50 } }, + argType: { name: 'input', defaultValue: 5, control: { type: 'range', step: 50 } }, arg: 3, extractedArgTypes: { input: { name: 'input' } }, }).input @@ -217,7 +222,7 @@ describe('enhanceArgTypes', () => { it('includes extracted argTypes when user-specified argTypes match', () => { expect( enhance({ - argType: { type: { name: 'number' } }, + argType: { name: 'input', type: { name: 'number' } }, extractedArgTypes: { input: { name: 'input' }, foo: { type: { name: 'number' } } }, }) ).toMatchInlineSnapshot(` @@ -240,7 +245,7 @@ describe('enhanceArgTypes', () => { it('excludes extracted argTypes when user-specified argTypes do not match', () => { expect( enhance({ - argType: { type: { name: 'number' } }, + argType: { name: 'input', type: { name: 'number' } }, extractedArgTypes: { foo: { type: { name: 'number' } } }, }) ).toMatchInlineSnapshot(` diff --git a/addons/docs/src/frameworks/svelte/extractArgTypes.test.ts b/addons/docs/src/frameworks/svelte/extractArgTypes.test.ts index 0f96ae85552..a67b08db35a 100644 --- a/addons/docs/src/frameworks/svelte/extractArgTypes.test.ts +++ b/addons/docs/src/frameworks/svelte/extractArgTypes.test.ts @@ -73,7 +73,8 @@ describe('Extracting Arguments', () => { "category": "events", }, "type": Object { - "name": "void", + "name": "other", + "value": "void", }, }, "event_click": Object { @@ -83,7 +84,8 @@ describe('Extracting Arguments', () => { "category": "events", }, "type": Object { - "name": "void", + "name": "other", + "value": "void", }, }, "rounded": Object { @@ -115,7 +117,8 @@ describe('Extracting Arguments', () => { "category": "slots", }, "type": Object { - "name": "void", + "name": "other", + "value": "void", }, }, "text": Object { From 7bfbe4cb9684cbce4aa9f60bff90b166f42f4c22 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 13:42:56 +1000 Subject: [PATCH 134/285] Fix up angular decorators --- .../src/client/preview/decorateStory.test.ts | 14 ++++++------ .../src/client/preview/decorateStory.ts | 2 +- .../src/client/preview/decorators.test.ts | 22 ++++++++++++++----- app/angular/src/client/preview/index.ts | 2 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/app/angular/src/client/preview/decorateStory.test.ts b/app/angular/src/client/preview/decorateStory.test.ts index 52209bcaa95..4015964c3e9 100644 --- a/app/angular/src/client/preview/decorateStory.test.ts +++ b/app/angular/src/client/preview/decorateStory.test.ts @@ -21,7 +21,7 @@ describe('decorateStory', () => { expect( decorated( makeContext({ - parameters: { component: FooComponent }, + component: FooComponent, args: { parentInput: 'Parent input', grandparentInput: 'grandparent input', @@ -63,7 +63,7 @@ describe('decorateStory', () => { expect( decorated( makeContext({ - parameters: { component: FooComponent }, + component: FooComponent, }) ) ).toEqual({ @@ -86,7 +86,7 @@ describe('decorateStory', () => { ]; const decorated = decorateStory(() => ({ template: '' }), decorators); - expect(decorated(makeContext({ parameters: { component: FooComponent } }))).toEqual({ + expect(decorated(makeContext({ component: FooComponent }))).toEqual({ template: '', }); @@ -118,7 +118,7 @@ describe('decorateStory', () => { ]; const decorated = decorateStory(() => ({ template: '' }), decorators); - expect(decorated(makeContext({ parameters: { component: FooComponent } }))).toEqual({ + expect(decorated(makeContext({ component: FooComponent }))).toEqual({ template: '', }); @@ -182,7 +182,7 @@ describe('decorateStory', () => { ]; const decorated = decorateStory(() => ({}), decorators); - expect(decorated(makeContext({ parameters: { component: FooComponent } }))).toEqual({ + expect(decorated(makeContext({ component: FooComponent }))).toEqual({ template: '', }); @@ -227,7 +227,7 @@ describe('decorateStory', () => { ]; const decorated = decorateStory(() => ({ template: '' }), decorators); - expect(decorated(makeContext({ parameters: { component: FooComponent } }))).toEqual({ + expect(decorated(makeContext({ component: FooComponent }))).toEqual({ template: '', }); }); @@ -243,7 +243,7 @@ describe('decorateStory', () => { expect( decorated( makeContext({ - parameters: { component: FooComponent }, + component: FooComponent, argTypes: { withControl: { control: { type: 'object' }, name: 'withControl' }, withAction: { action: 'onClick', name: 'withAction' }, diff --git a/app/angular/src/client/preview/decorateStory.ts b/app/angular/src/client/preview/decorateStory.ts index 239633f29cb..6f2c9c75882 100644 --- a/app/angular/src/client/preview/decorateStory.ts +++ b/app/angular/src/client/preview/decorateStory.ts @@ -33,7 +33,7 @@ const prepareMain = ( ): AngularFramework['storyResult'] => { let { template } = story; - const component = story.component ?? context.parameters.component; + const component = story.component ?? context.component; if (hasNoTemplate(template) && component) { template = computesTemplateFromComponent(component, story.props, ''); diff --git a/app/angular/src/client/preview/decorators.test.ts b/app/angular/src/client/preview/decorators.test.ts index 0cf5caa0113..58d008b3780 100644 --- a/app/angular/src/client/preview/decorators.test.ts +++ b/app/angular/src/client/preview/decorators.test.ts @@ -2,16 +2,24 @@ import { addons, mockChannel, StoryContext } from '@storybook/addons'; import { Component } from '@angular/core'; import { moduleMetadata } from './decorators'; -import { addDecorator, storiesOf, clearDecorators, getStorybook } from '.'; +import { addDecorator, storiesOf, clearDecorators, getStorybook, configure } from '.'; const defaultContext: StoryContext = { + componentId: 'unspecified', + kind: 'unspecified', + title: 'unspecified', id: 'unspecified', name: 'unspecified', - kind: 'unspecified', + story: 'unspecified', parameters: {}, + initialArgs: {}, args: {}, argTypes: {}, globals: {}, + hooks: {}, + loaded: {}, + originalStoryFn: jest.fn(), + viewMode: 'story', }; class MockModule {} @@ -102,11 +110,13 @@ describe('moduleMetadata', () => { }; addons.setChannel(mockChannel()); - addDecorator(moduleMetadata(metadata)); - storiesOf('Test', module).add('Default', () => ({ - component: MockComponent, - })); + configure(() => { + addDecorator(moduleMetadata(metadata)); + storiesOf('Test', module).add('Default', () => ({ + component: MockComponent, + })); + }, {} as NodeModule); const [storybook] = getStorybook(); diff --git a/app/angular/src/client/preview/index.ts b/app/angular/src/client/preview/index.ts index 870babd2501..c0a28cb3f69 100644 --- a/app/angular/src/client/preview/index.ts +++ b/app/angular/src/client/preview/index.ts @@ -20,7 +20,7 @@ interface ClientApi extends ClientStoryApi { load: (...args: any[]) => void; } -const api = start(render as any, { decorateStory }); +const api = start(render, { decorateStory }); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ From 990d53db91b2c57ae3c36148645ff02a3f8f3cae Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 14:10:36 +1000 Subject: [PATCH 135/285] Pass component through angular properly (not on parameters any more) --- .../src/frameworks/angular/renderTree.ts | 2 +- .../preview/angular-beta/AbstractRenderer.ts | 5 +++- .../preview/angular-beta/CanvasRenderer.ts | 1 + .../preview/angular-beta/DocsRenderer.ts | 1 + .../angular-beta/ElementRendererService.ts | 4 +++- .../angular-beta/RendererFactory.test.ts | 23 +++++++++---------- .../angular-beta/RendererService.test.ts | 23 +++++++++---------- .../preview/angular-beta/RendererService.ts | 6 +++-- .../angular-beta/StorybookModule.test.ts | 14 +++++------ .../preview/angular-beta/StorybookModule.ts | 6 ++--- app/angular/src/client/preview/render.ts | 3 ++- app/angular/src/client/preview/types-6-0.ts | 1 - .../__snapshots__/core.stories.storyshot | 5 +--- .../custom-decorators.stories.storyshot | 13 ++++++----- 14 files changed, 56 insertions(+), 51 deletions(-) diff --git a/addons/storyshots/storyshots-core/src/frameworks/angular/renderTree.ts b/addons/storyshots/storyshots-core/src/frameworks/angular/renderTree.ts index 1b38679bd79..5385f4a85d7 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/angular/renderTree.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/angular/renderTree.ts @@ -15,7 +15,7 @@ function getRenderedTree(story: any) { const moduleMeta = getStorybookModuleMetadata( { storyFnAngular: currentStory, - parameters: story.parameters, + component: story.component, // TODO : To change with the story Id in v7. Currently keep with static id to avoid changes in snapshots targetSelector: 'storybook-wrapper', }, diff --git a/app/angular/src/client/preview/angular-beta/AbstractRenderer.ts b/app/angular/src/client/preview/angular-beta/AbstractRenderer.ts index 8dbaaf5b1c4..d2d5108b2e8 100644 --- a/app/angular/src/client/preview/angular-beta/AbstractRenderer.ts +++ b/app/angular/src/client/preview/angular-beta/AbstractRenderer.ts @@ -92,16 +92,19 @@ export abstract class AbstractRenderer { * @param forced {boolean} If : * - true render will only use the StoryFn `props' in storyProps observable that will update sotry's component/template properties. Improves performance without reloading the whole module&component if props changes * - false fully recharges or initializes angular module & component + * @param component {Component} * @param parameters {Parameters} */ public async render({ storyFnAngular, forced, parameters, + component, targetDOMNode, }: { storyFnAngular: StoryFnAngularReturnType; forced: boolean; + component?: any; parameters: Parameters; targetDOMNode: HTMLElement; }) { @@ -109,7 +112,7 @@ export abstract class AbstractRenderer { const newStoryProps$ = new BehaviorSubject(storyFnAngular.props); const moduleMetadata = getStorybookModuleMetadata( - { storyFnAngular, parameters, targetSelector }, + { storyFnAngular, component, targetSelector }, newStoryProps$ ); diff --git a/app/angular/src/client/preview/angular-beta/CanvasRenderer.ts b/app/angular/src/client/preview/angular-beta/CanvasRenderer.ts index 26e05c91ead..dcd13483ae3 100644 --- a/app/angular/src/client/preview/angular-beta/CanvasRenderer.ts +++ b/app/angular/src/client/preview/angular-beta/CanvasRenderer.ts @@ -7,6 +7,7 @@ export class CanvasRenderer extends AbstractRenderer { storyFnAngular: StoryFnAngularReturnType; forced: boolean; parameters: Parameters; + component: any; targetDOMNode: HTMLElement; }) { await super.render(options); diff --git a/app/angular/src/client/preview/angular-beta/DocsRenderer.ts b/app/angular/src/client/preview/angular-beta/DocsRenderer.ts index b5553731f90..6960f5dba4c 100644 --- a/app/angular/src/client/preview/angular-beta/DocsRenderer.ts +++ b/app/angular/src/client/preview/angular-beta/DocsRenderer.ts @@ -8,6 +8,7 @@ export class DocsRenderer extends AbstractRenderer { public async render(options: { storyFnAngular: StoryFnAngularReturnType; forced: boolean; + component: any; parameters: Parameters; targetDOMNode: HTMLElement; }) { diff --git a/app/angular/src/client/preview/angular-beta/ElementRendererService.ts b/app/angular/src/client/preview/angular-beta/ElementRendererService.ts index 00157efbf32..0c85550efc6 100644 --- a/app/angular/src/client/preview/angular-beta/ElementRendererService.ts +++ b/app/angular/src/client/preview/angular-beta/ElementRendererService.ts @@ -27,12 +27,14 @@ export class ElementRendererService { public async renderAngularElement({ storyFnAngular, parameters, + component, }: { storyFnAngular: StoryFnAngularReturnType; parameters: Parameters; + component: any; }): Promise { const ngModule = getStorybookModuleMetadata( - { storyFnAngular, parameters, targetSelector: RendererService.SELECTOR_STORYBOOK_WRAPPER }, + { storyFnAngular, component, targetSelector: RendererService.SELECTOR_STORYBOOK_WRAPPER }, new BehaviorSubject(storyFnAngular.props) ); diff --git a/app/angular/src/client/preview/angular-beta/RendererFactory.test.ts b/app/angular/src/client/preview/angular-beta/RendererFactory.test.ts index 754cc894fc7..01c53b86cb1 100644 --- a/app/angular/src/client/preview/angular-beta/RendererFactory.test.ts +++ b/app/angular/src/client/preview/angular-beta/RendererFactory.test.ts @@ -46,7 +46,7 @@ describe('RendererFactory', () => { props: {}, }, forced: false, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); @@ -63,9 +63,8 @@ describe('RendererFactory', () => { props: {}, }, forced: false, - parameters: { - component: FooComponent, - }, + parameters: {}, + component: FooComponent, targetDOMNode: rootTargetDOMNode, }); @@ -87,7 +86,7 @@ describe('RendererFactory', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); }); @@ -111,7 +110,7 @@ describe('RendererFactory', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); expect(countDestroy).toEqual(0); @@ -129,7 +128,7 @@ describe('RendererFactory', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); @@ -157,7 +156,7 @@ describe('RendererFactory', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); expect(countDestroy).toEqual(0); @@ -177,7 +176,7 @@ describe('RendererFactory', () => { moduleMetadata: { providers: [{ provide: 'foo', useValue: 42 }] }, }, forced: true, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); expect(countDestroy).toEqual(1); @@ -194,7 +193,7 @@ describe('RendererFactory', () => { props: {}, }, forced: false, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); @@ -209,7 +208,7 @@ describe('RendererFactory', () => { props: {}, }, forced: false, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); @@ -227,7 +226,7 @@ describe('RendererFactory', () => { template: 'Canvas 🖼', }, forced: true, - parameters: {} as any, + parameters: {}, targetDOMNode: rootTargetDOMNode, }); }); diff --git a/app/angular/src/client/preview/angular-beta/RendererService.test.ts b/app/angular/src/client/preview/angular-beta/RendererService.test.ts index d404a287ab2..a878d7a7db6 100644 --- a/app/angular/src/client/preview/angular-beta/RendererService.test.ts +++ b/app/angular/src/client/preview/angular-beta/RendererService.test.ts @@ -36,7 +36,7 @@ describe('RendererService', () => { props: {}, }, forced: false, - parameters: {} as any, + parameters: {}, }); expect(document.body.getElementsByTagName('storybook-wrapper')[0].innerHTML).toBe('🦊'); @@ -51,9 +51,8 @@ describe('RendererService', () => { props: {}, }, forced: false, - parameters: { - component: FooComponent, - }, + component: FooComponent, + parameters: {}, }); expect(document.body.getElementsByTagName('storybook-wrapper')[0].innerHTML).toBe( @@ -78,7 +77,7 @@ describe('RendererService', () => { moduleMetadata: { providers: [{ provide: 'foo', useValue: token }] }, }, forced: false, - parameters: {} as any, + parameters: {}, }); expect(document.body.getElementsByTagName('storybook-wrapper')[0].innerHTML).toBe('🦊'); @@ -96,7 +95,7 @@ describe('RendererService', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, }); }); @@ -120,7 +119,7 @@ describe('RendererService', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, }); expect(countDestroy).toEqual(0); @@ -138,7 +137,7 @@ describe('RendererService', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, }); expect(document.body.getElementsByTagName('storybook-wrapper')[0].innerHTML).toBe('🍺'); @@ -161,7 +160,7 @@ describe('RendererService', () => { }, }, forced: true, - parameters: {} as any, + parameters: {}, }); expect(countDestroy).toEqual(0); @@ -176,7 +175,7 @@ describe('RendererService', () => { moduleMetadata: { providers: [{ provide: 'foo', useValue: 42 }] }, }, forced: true, - parameters: {} as any, + parameters: {}, }); expect(countDestroy).toEqual(1); }); @@ -191,7 +190,7 @@ describe('RendererService', () => { props: {}, }, forced: false, - parameters: {} as any, + parameters: {}, }); rendererService.platform.onDestroy(() => { @@ -204,7 +203,7 @@ describe('RendererService', () => { props: {}, }, forced: false, - parameters: {} as any, + parameters: {}, }); expect(countDestroy).toEqual(1); diff --git a/app/angular/src/client/preview/angular-beta/RendererService.ts b/app/angular/src/client/preview/angular-beta/RendererService.ts index 9909cf0f24a..f0e451cdcca 100644 --- a/app/angular/src/client/preview/angular-beta/RendererService.ts +++ b/app/angular/src/client/preview/angular-beta/RendererService.ts @@ -55,20 +55,22 @@ export class RendererService { * @param forced {boolean} If : * - true render will only use the StoryFn `props' in storyProps observable that will update sotry's component/template properties. Improves performance without reloading the whole module&component if props changes * - false fully recharges or initializes angular module & component - * @param parameters {Parameters} + * @param component {Parameters} */ public async render({ storyFnAngular, forced, + component, parameters, }: { storyFnAngular: StoryFnAngularReturnType; forced: boolean; + component?: any; parameters: Parameters; }) { const storyProps$ = new BehaviorSubject(storyFnAngular.props); const moduleMetadata = getStorybookModuleMetadata( - { storyFnAngular, parameters, targetSelector: RendererService.SELECTOR_STORYBOOK_WRAPPER }, + { storyFnAngular, component, targetSelector: RendererService.SELECTOR_STORYBOOK_WRAPPER }, storyProps$ ); diff --git a/app/angular/src/client/preview/angular-beta/StorybookModule.test.ts b/app/angular/src/client/preview/angular-beta/StorybookModule.test.ts index 711f6678c6c..cceba5cfe89 100644 --- a/app/angular/src/client/preview/angular-beta/StorybookModule.test.ts +++ b/app/angular/src/client/preview/angular-beta/StorybookModule.test.ts @@ -49,7 +49,7 @@ describe('StorybookModule', () => { const ngModule = getStorybookModuleMetadata( { storyFnAngular: { props }, - parameters: { component: FooComponent }, + component: FooComponent, targetSelector: 'my-selector', }, new BehaviorSubject(props) @@ -85,7 +85,7 @@ describe('StorybookModule', () => { const ngModule = getStorybookModuleMetadata( { storyFnAngular: { props }, - parameters: { component: FooComponent }, + component: FooComponent, targetSelector: 'my-selector', }, new BehaviorSubject(props) @@ -110,7 +110,7 @@ describe('StorybookModule', () => { const ngModule = getStorybookModuleMetadata( { storyFnAngular: { props: initialProps }, - parameters: { component: FooComponent }, + component: FooComponent, targetSelector: 'my-selector', }, storyProps$ @@ -162,7 +162,7 @@ describe('StorybookModule', () => { const ngModule = getStorybookModuleMetadata( { storyFnAngular: { props: initialProps }, - parameters: { component: FooComponent }, + component: FooComponent, targetSelector: 'my-selector', }, storyProps$ @@ -203,7 +203,7 @@ describe('StorybookModule', () => { props: initialProps, template: '

', }, - parameters: { component: FooComponent }, + component: FooComponent, targetSelector: 'my-selector', }, storyProps$ @@ -242,7 +242,7 @@ describe('StorybookModule', () => { props, moduleMetadata: { entryComponents: [WithoutSelectorComponent] }, }, - parameters: { component: WithoutSelectorComponent }, + component: WithoutSelectorComponent, targetSelector: 'my-selector', }, new BehaviorSubject(props) @@ -265,7 +265,7 @@ describe('StorybookModule', () => { const ngModule = getStorybookModuleMetadata( { storyFnAngular: { template: '' }, - parameters: { component: FooComponent }, + component: FooComponent, targetSelector: 'my-selector', }, new BehaviorSubject({}) diff --git a/app/angular/src/client/preview/angular-beta/StorybookModule.ts b/app/angular/src/client/preview/angular-beta/StorybookModule.ts index 4b25f46d6a5..67d851a6585 100644 --- a/app/angular/src/client/preview/angular-beta/StorybookModule.ts +++ b/app/angular/src/client/preview/angular-beta/StorybookModule.ts @@ -30,11 +30,11 @@ const deprecatedStoryComponentWarning = deprecate( export const getStorybookModuleMetadata = ( { storyFnAngular, - parameters, + component: annotatedComponent, targetSelector, }: { storyFnAngular: StoryFnAngularReturnType; - parameters: Parameters; + component?: any; targetSelector: string; }, storyProps$: Subject @@ -45,7 +45,7 @@ export const getStorybookModuleMetadata = ( if (storyComponent) { deprecatedStoryComponentWarning(); } - const component = storyComponent ?? parameters.component; + const component = storyComponent ?? annotatedComponent; if (hasNoTemplate(template) && component) { template = computesTemplateFromComponent(component, props, ''); diff --git a/app/angular/src/client/preview/render.ts b/app/angular/src/client/preview/render.ts index eb5d111e8e3..4b6749a5e10 100644 --- a/app/angular/src/client/preview/render.ts +++ b/app/angular/src/client/preview/render.ts @@ -28,7 +28,8 @@ export default async function renderMain( await renderer.render({ storyFnAngular: storyFn(), - parameters: { ...parameters, component }, + component, + parameters, forced: !forceRemount, targetDOMNode: element, }); diff --git a/app/angular/src/client/preview/types-6-0.ts b/app/angular/src/client/preview/types-6-0.ts index eb60153ee45..dcff4f49d04 100644 --- a/app/angular/src/client/preview/types-6-0.ts +++ b/app/angular/src/client/preview/types-6-0.ts @@ -32,7 +32,6 @@ export type Story = StoryAnnotationsOrFn; export type Parameters = DefaultParameters & { /** Uses legacy angular rendering engine that use dynamic component */ angularLegacyRendering?: boolean; - component: unknown; bootstrapModuleOptions?: unknown; }; diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot index a8db6fb38ee..c5dce74f714 100644 --- a/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot @@ -8,13 +8,10 @@ exports[`Storyshots Core/Parameters passed to story 1`] = ` "docs": { "iframeHeight": "60px" }, - "globalParameter": "globalParameter", "framework": "vue", + "globalParameter": "globalParameter", "chapterParameter": "chapterParameter", - "args": {}, - "argTypes": {}, "storyParameter": "storyParameter", - "__id": "core-parameters--passed-to-story", "__isArgsStory": true } diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot index d1b0a347fac..975094a2635 100644 --- a/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot @@ -45,24 +45,25 @@ exports[`Storyshots Custom/Decorator for Vue With Data 1`] = ` >
       {
-  "id": "custom-decorator-for-vue--with-data",
+  "componentId": "custom-decorator-for-vue",
+  "title": "Custom/Decorator for Vue",
   "kind": "Custom/Decorator for Vue",
+  "id": "custom-decorator-for-vue--with-data",
   "name": "With Data",
   "story": "With Data",
   "parameters": {
     "docs": {
       "iframeHeight": "60px"
     },
-    "globalParameter": "globalParameter",
     "framework": "vue",
-    "args": {},
-    "argTypes": {},
-    "__id": "custom-decorator-for-vue--with-data",
+    "globalParameter": "globalParameter",
     "__isArgsStory": true
   },
-  "args": {},
+  "initialArgs": {},
   "argTypes": {},
+  "args": {},
   "globals": {},
+  "viewMode": "story",
   "customContext": 52
 }
     
From 45084879ba84caa76eaafbda71ebaa23106f5a14 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 20:40:58 +1000 Subject: [PATCH 136/285] Little improvement to `inferArgTypes` --- .../src/preview/inferArgTypes.test.ts | 44 +++++++++++++++++++ lib/core-client/src/preview/inferArgTypes.ts | 2 - 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/core-client/src/preview/inferArgTypes.test.ts b/lib/core-client/src/preview/inferArgTypes.test.ts index 65cef9e17a9..0703f49d613 100644 --- a/lib/core-client/src/preview/inferArgTypes.test.ts +++ b/lib/core-client/src/preview/inferArgTypes.test.ts @@ -97,4 +97,48 @@ describe('inferArgTypes', () => { }); expect(logger.warn).toHaveBeenCalled(); }); + + it('ensures names', () => { + (logger.warn as jest.MockedFunction).mockClear(); + expect( + inferArgTypes({ + initialArgs: { + a: 1, + }, + argTypes: { + a: { + control: { + type: 'range', + }, + }, + }, + } as any) + ).toEqual({ + a: { + name: 'a', + type: { name: 'number' }, + control: { type: 'range' }, + }, + }); + }); + + it('ensures names even with no arg', () => { + (logger.warn as jest.MockedFunction).mockClear(); + expect( + inferArgTypes({ + argTypes: { + a: { + type: { + name: 'string', + }, + }, + }, + } as any) + ).toEqual({ + a: { + name: 'a', + type: { name: 'string' }, + }, + }); + }); }); diff --git a/lib/core-client/src/preview/inferArgTypes.ts b/lib/core-client/src/preview/inferArgTypes.ts index 64559035ab4..b9e99bcfe8f 100644 --- a/lib/core-client/src/preview/inferArgTypes.ts +++ b/lib/core-client/src/preview/inferArgTypes.ts @@ -42,7 +42,6 @@ const inferType = (value: any, name: string, visited: Set): SBType => { export const inferArgTypes: ArgTypesEnhancer = (context) => { const { id, argTypes: userArgTypes = {}, initialArgs = {} } = context; - if (!initialArgs) return userArgTypes; const argTypes = mapValues(initialArgs, (arg, key) => ({ name: key, type: inferType(arg, `${id}.${key}`, new Set()), @@ -53,5 +52,4 @@ export const inferArgTypes: ArgTypesEnhancer = (context) => { return combineParameters(argTypes, userArgTypesNames, userArgTypes); }; -// @ts-ignore FIXME inferArgTypes.secondPass = true; From e4236c1452c745a19499e764a6a7bf8881004192 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 20:57:18 +1000 Subject: [PATCH 137/285] Repair globals/globalTypes in legacy --- lib/client-api/src/ClientApi.ts | 17 +++++++++++++++-- lib/store/src/index.ts | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 32d823900eb..a6f19dcf8d3 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -15,6 +15,8 @@ import { sanitize, storyNameFromExport, ComponentTitle, + Globals, + GlobalTypes, } from '@storybook/csf'; import { NormalizedComponentAnnotations, @@ -25,6 +27,7 @@ import { ModuleImportFn, combineParameters, StoryStore, + normalizeInputTypes, } from '@storybook/store'; import { ClientApiAddons, StoryApi } from '@storybook/addons'; @@ -70,7 +73,7 @@ const warnings = { }; const checkMethod = (method: string, deprecationWarning: boolean) => { - if (FEATURES.storyStoreV7) { + if (FEATURES?.storyStoreV7) { throw new Error( dedent`You cannot use \`${method}\` with the new Story Store. @@ -209,11 +212,21 @@ export default class ClientApi { ` ); - addParameters = (parameters: Parameters) => { + addParameters = ({ + globals, + globalTypes, + ...parameters + }: Parameters & { globals?: Globals; globalTypes?: GlobalTypes }) => { this.globalAnnotations.parameters = combineParameters( this.globalAnnotations.parameters, parameters ); + if (globals) { + this.globalAnnotations.globals = globals; + } + if (globalTypes) { + this.globalAnnotations.globalTypes = normalizeInputTypes(globalTypes); + } }; addLoader = (loader: LoaderFunction) => { diff --git a/lib/store/src/index.ts b/lib/store/src/index.ts index 193d661be48..22265b86e13 100644 --- a/lib/store/src/index.ts +++ b/lib/store/src/index.ts @@ -1,6 +1,7 @@ export { StoryStore } from './StoryStore'; export { combineParameters } from './parameters'; export { filterArgTypes } from './filterArgTypes'; +export { normalizeInputTypes } from './normalizeInputTypes'; export type { PropDescriptor } from './filterArgTypes'; export * from './types'; From b75ad5889eb5a1092f92d0fea68454e242421d66 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 20:58:30 +1000 Subject: [PATCH 138/285] Temporary work arounds for a couple of angular issues --- .../storyshots/storyshots-core/package.json | 1 + .../src/frameworks/configure.ts | 5 ++++ .../src/client/preview/decorateStory.ts | 28 ++++++++++--------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index fe0ada88123..059ea924dca 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -48,6 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", + "@storybook/core-client": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.c10361d.0", "@types/glob": "^7.1.3", diff --git a/addons/storyshots/storyshots-core/src/frameworks/configure.ts b/addons/storyshots/storyshots-core/src/frameworks/configure.ts index 4d17000e12d..fadd277624f 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/configure.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/configure.ts @@ -4,6 +4,8 @@ import { toRequireContext } from '@storybook/core-common'; import registerRequireContextHook from 'babel-plugin-require-context-hook/register'; import global from 'global'; import { Framework, ArgsEnhancer, ArgTypesEnhancer, DecoratorFunction } from '@storybook/csf'; +import { inferArgTypes } from '@storybook/core-client'; +import { addArgTypesEnhancer } from '@storybook/client-api'; import { ClientApi } from './Loader'; import { StoryshotsOptions } from '../api/StoryshotsOptions'; @@ -76,6 +78,9 @@ function configure( ): void { const { configPath = '.storybook', config, storybook } = options; + // TODO -- this is temporary while we work out a better approach + addArgTypesEnhancer(inferArgTypes); + if (config && typeof config === 'function') { config(storybook); return; diff --git a/app/angular/src/client/preview/decorateStory.ts b/app/angular/src/client/preview/decorateStory.ts index 6f2c9c75882..cf371dcc988 100644 --- a/app/angular/src/client/preview/decorateStory.ts +++ b/app/angular/src/client/preview/decorateStory.ts @@ -49,21 +49,23 @@ function hasNoTemplate(template: string | null | undefined): template is undefin } const cleanArgsDecorator: DecoratorFunction = (storyFn, context) => { - if (!context.argTypes || !context.args) { - return storyFn(); - } + // TODO --temporary + return storyFn(); + // if (!context.argTypes || !context.args) { + // return storyFn(); + // } - const argsToClean = context.args; + // const argsToClean = context.args; - context.args = Object.entries(argsToClean).reduce((obj, [key, arg]) => { - const argType = context.argTypes[key]; + // context.args = Object.entries(argsToClean).reduce((obj, [key, arg]) => { + // const argType = context.argTypes[key]; - // Only keeps args with a control or an action in argTypes - if (argType.action || argType.control) { - return { ...obj, [key]: arg }; - } - return obj; - }, {}); + // // Only keeps args with a control or an action in argTypes + // if (argType.action || argType.control) { + // return { ...obj, [key]: arg }; + // } + // return obj; + // }, {}); - return storyFn(); + // return storyFn(); }; From 6a7ddf38ed432007efe934845397cbe1aa5dd525 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 23:04:11 +1000 Subject: [PATCH 139/285] Fix vue+svelte shots --- .../storyshots-core/src/frameworks/vue/renderTree.ts | 2 +- app/svelte/src/client/preview/decorators.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/storyshots/storyshots-core/src/frameworks/vue/renderTree.ts b/addons/storyshots/storyshots-core/src/frameworks/vue/renderTree.ts index ea3f0f8bc0a..811566d23aa 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/vue/renderTree.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/vue/renderTree.ts @@ -14,7 +14,7 @@ function getRenderedTree(story: any) { }); // @ts-ignore - vm[VALUES] = story.args; + vm[VALUES] = story.initialArgs; return vm.$mount().$el; } diff --git a/app/svelte/src/client/preview/decorators.ts b/app/svelte/src/client/preview/decorators.ts index f784c17b746..71fbde66abb 100644 --- a/app/svelte/src/client/preview/decorators.ts +++ b/app/svelte/src/client/preview/decorators.ts @@ -23,7 +23,7 @@ function unWrap(obj: any) { * Transform a story to be compatible with the PreviewRender component. * * - `() => MyComponent` is translated to `() => ({ Component: MyComponent })` - * - `() => ({})` is translated to `() => ({ Component: })` + * - `() => ({})` is translated to `() => ({ Component: })` * - A decorator component is wrapped with SlotDecorator. The decorated component is inject through * a * @@ -55,8 +55,8 @@ function prepareStory(context: StoryContext, story: any, origin } else { let cpn = result.Component; if (!cpn) { - // if the component is not defined, get it from parameters - cpn = context.parameters.component; + // if the component is not defined, get it the context + cpn = context.component; } result.Component = unWrap(cpn); } From 92ef52f8fd636d9e6960136bea34f62d77611edb Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 23:14:56 +1000 Subject: [PATCH 140/285] Update snapshot (looks like this one was broken before) --- .../stories/__snapshots__/storyshot.metadata.test.js.snap | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap b/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap index 3f1706c5fc8..c9965e394a4 100644 --- a/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap +++ b/addons/storyshots/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap @@ -6,5 +6,6 @@ exports[`Storyshots Text Simple 1`] = ` contents + suffix `; From 2f5048402638dee28adf8901449d26f33289fe59 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 2 Sep 2021 23:20:45 +1000 Subject: [PATCH 141/285] Update `yarn.lock` --- yarn.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn.lock b/yarn.lock index ea726b97430..322e3cb2684 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5974,6 +5974,7 @@ __metadata: "@storybook/angular": 6.4.0-alpha.19 "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 + "@storybook/core-client": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.c10361d.0 "@storybook/react": 6.4.0-alpha.19 From c062b8a0b773b75cfe3f79d9f0a3230f36a4ad4e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 12:44:15 +1000 Subject: [PATCH 142/285] No need to mock in this test --- app/react/src/client/preview/index.test.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/react/src/client/preview/index.test.ts b/app/react/src/client/preview/index.test.ts index 6bd053669e7..546e442130e 100644 --- a/app/react/src/client/preview/index.test.ts +++ b/app/react/src/client/preview/index.test.ts @@ -13,14 +13,6 @@ describe('preview', () => { }); it('should return the client api in a node.js environment', () => { - jest.mock( - 'global', - () => - ({ - document: undefined, - window: {}, - } as any) - ); const api = require('.'); expect(Object.keys(api).length).toBeGreaterThan(0); expect(Object.values(api).every(isFunction)).toEqual(true); From b8d5b1e7e36bc7ba79e764727c09e1e1ca7067a9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 13:00:18 +1000 Subject: [PATCH 143/285] Move inferControls from the controls addon back into the store For backwards compatibility reasons, we will undo this commit in 7.0 --- addons/controls/preset.js | 6 +--- .../src/client/preview/decorateStory.ts | 28 +++++++++---------- lib/store/src/StoryStore.ts | 4 +++ .../store}/src/inferControls.test.ts | 0 .../store}/src/inferControls.ts | 5 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) rename {addons/controls => lib/store}/src/inferControls.test.ts (100%) rename {addons/controls => lib/store}/src/inferControls.ts (92%) diff --git a/addons/controls/preset.js b/addons/controls/preset.js index dd5a388d5eb..1fac913bc69 100644 --- a/addons/controls/preset.js +++ b/addons/controls/preset.js @@ -5,8 +5,4 @@ function managerEntries(entry = [], options) { return [...entry, require.resolve('./dist/esm/register')]; } -function config(entry = []) { - return [...entry, require.resolve('./dist/esm/inferControls')]; -} - -module.exports = { managerEntries, config }; +module.exports = { managerEntries }; diff --git a/app/angular/src/client/preview/decorateStory.ts b/app/angular/src/client/preview/decorateStory.ts index cf371dcc988..6f2c9c75882 100644 --- a/app/angular/src/client/preview/decorateStory.ts +++ b/app/angular/src/client/preview/decorateStory.ts @@ -49,23 +49,21 @@ function hasNoTemplate(template: string | null | undefined): template is undefin } const cleanArgsDecorator: DecoratorFunction = (storyFn, context) => { - // TODO --temporary - return storyFn(); - // if (!context.argTypes || !context.args) { - // return storyFn(); - // } + if (!context.argTypes || !context.args) { + return storyFn(); + } - // const argsToClean = context.args; + const argsToClean = context.args; - // context.args = Object.entries(argsToClean).reduce((obj, [key, arg]) => { - // const argType = context.argTypes[key]; + context.args = Object.entries(argsToClean).reduce((obj, [key, arg]) => { + const argType = context.argTypes[key]; - // // Only keeps args with a control or an action in argTypes - // if (argType.action || argType.control) { - // return { ...obj, [key]: arg }; - // } - // return obj; - // }, {}); + // Only keeps args with a control or an action in argTypes + if (argType.action || argType.control) { + return { ...obj, [key]: arg }; + } + return obj; + }, {}); - // return storyFn(); + return storyFn(); }; diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 2df06812c74..7e89428dd9f 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -25,6 +25,7 @@ import { } from './types'; import { HooksContext } from './hooks'; import { normalizeInputTypes } from './normalizeInputTypes'; +import { inferControls } from './inferControls'; // TODO -- what are reasonable values for these? const CSF_CACHE_SIZE = 100; @@ -33,11 +34,14 @@ const STORY_CACHE_SIZE = 1000; function normalizeGlobalAnnotations({ argTypes, globalTypes, + argTypesEnhancers, ...annotations }: GlobalAnnotations): NormalizedGlobalAnnotations { return { ...(argTypes && { argTypes: normalizeInputTypes(argTypes) }), ...(globalTypes && { globalTypes: normalizeInputTypes(globalTypes) }), + // For backwards compatibilty reasons we add this, remove in 7.0 TODO -- explanation + argTypesEnhancers: [...(argTypesEnhancers || []), inferControls], ...annotations, }; } diff --git a/addons/controls/src/inferControls.test.ts b/lib/store/src/inferControls.test.ts similarity index 100% rename from addons/controls/src/inferControls.test.ts rename to lib/store/src/inferControls.test.ts diff --git a/addons/controls/src/inferControls.ts b/lib/store/src/inferControls.ts similarity index 92% rename from addons/controls/src/inferControls.ts rename to lib/store/src/inferControls.ts index c59776b3832..a84293e3dc3 100644 --- a/addons/controls/src/inferControls.ts +++ b/lib/store/src/inferControls.ts @@ -1,7 +1,8 @@ import mapValues from 'lodash/mapValues'; import { logger } from '@storybook/client-logger'; import { Framework, SBEnumType, StrictInputType, ArgTypesEnhancer } from '@storybook/csf'; -import { filterArgTypes, combineParameters } from '@storybook/store'; +import { filterArgTypes } from './filterArgTypes'; +import { combineParameters } from './parameters'; type ControlsMatchers = { date: RegExp; @@ -54,7 +55,7 @@ const inferControl = (argType: StrictInputType, name: string, matchers: Controls } }; -const inferControls: ArgTypesEnhancer = (context) => { +export const inferControls: ArgTypesEnhancer = (context) => { const { argTypes, parameters: { __isArgsStory, controls: { include = null, exclude = null, matchers = {} } = {} }, From a886599e0f5bf5030338a116980ab0bcfe70db1c Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 13:12:50 +1000 Subject: [PATCH 144/285] Move inferArgTypes back into the store So we don't need to do it in Storyshots anymore. --- .../storyshots-core/src/frameworks/configure.ts | 5 ----- lib/core-server/src/presets/common-preset.ts | 3 --- lib/core-server/src/presets/inferArgTypes.ts | 3 --- lib/store/src/StoryStore.ts | 9 +++++++-- .../src/preview => store/src}/inferArgTypes.test.ts | 0 .../src/preview => store/src}/inferArgTypes.ts | 2 +- 6 files changed, 8 insertions(+), 14 deletions(-) delete mode 100644 lib/core-server/src/presets/inferArgTypes.ts rename lib/{core-client/src/preview => store/src}/inferArgTypes.test.ts (100%) rename lib/{core-client/src/preview => store/src}/inferArgTypes.ts (97%) diff --git a/addons/storyshots/storyshots-core/src/frameworks/configure.ts b/addons/storyshots/storyshots-core/src/frameworks/configure.ts index fadd277624f..4d17000e12d 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/configure.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/configure.ts @@ -4,8 +4,6 @@ import { toRequireContext } from '@storybook/core-common'; import registerRequireContextHook from 'babel-plugin-require-context-hook/register'; import global from 'global'; import { Framework, ArgsEnhancer, ArgTypesEnhancer, DecoratorFunction } from '@storybook/csf'; -import { inferArgTypes } from '@storybook/core-client'; -import { addArgTypesEnhancer } from '@storybook/client-api'; import { ClientApi } from './Loader'; import { StoryshotsOptions } from '../api/StoryshotsOptions'; @@ -78,9 +76,6 @@ function configure( ): void { const { configPath = '.storybook', config, storybook } = options; - // TODO -- this is temporary while we work out a better approach - addArgTypesEnhancer(inferArgTypes); - if (config && typeof config === 'function') { config(storybook); return; diff --git a/lib/core-server/src/presets/common-preset.ts b/lib/core-server/src/presets/common-preset.ts index ea186af808c..4382b106b6a 100644 --- a/lib/core-server/src/presets/common-preset.ts +++ b/lib/core-server/src/presets/common-preset.ts @@ -62,6 +62,3 @@ export const features = async (existing: Record) => ({ ...existing, postcss: true, }); - -// TODO -- this feels like it should live in core-client or client-api -export const config = (entry: string[] = []) => [...entry, require.resolve('./inferArgTypes')]; diff --git a/lib/core-server/src/presets/inferArgTypes.ts b/lib/core-server/src/presets/inferArgTypes.ts deleted file mode 100644 index 10209ca4ed4..00000000000 --- a/lib/core-server/src/presets/inferArgTypes.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { inferArgTypes } from '@storybook/core-client'; - -export const argTypesEnhancers = [inferArgTypes]; diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 7e89428dd9f..ec71442ef1b 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -25,6 +25,7 @@ import { } from './types'; import { HooksContext } from './hooks'; import { normalizeInputTypes } from './normalizeInputTypes'; +import { inferArgTypes } from './inferArgTypes'; import { inferControls } from './inferControls'; // TODO -- what are reasonable values for these? @@ -40,8 +41,12 @@ function normalizeGlobalAnnotations({ return { ...(argTypes && { argTypes: normalizeInputTypes(argTypes) }), ...(globalTypes && { globalTypes: normalizeInputTypes(globalTypes) }), - // For backwards compatibilty reasons we add this, remove in 7.0 TODO -- explanation - argTypesEnhancers: [...(argTypesEnhancers || []), inferControls], + argTypesEnhancers: [ + ...(argTypesEnhancers || []), + inferArgTypes, + // For backwards compatibilty reasons we add this, remove in 7.0 TODO -- explanation + inferControls, + ], ...annotations, }; } diff --git a/lib/core-client/src/preview/inferArgTypes.test.ts b/lib/store/src/inferArgTypes.test.ts similarity index 100% rename from lib/core-client/src/preview/inferArgTypes.test.ts rename to lib/store/src/inferArgTypes.test.ts diff --git a/lib/core-client/src/preview/inferArgTypes.ts b/lib/store/src/inferArgTypes.ts similarity index 97% rename from lib/core-client/src/preview/inferArgTypes.ts rename to lib/store/src/inferArgTypes.ts index b9e99bcfe8f..3abfb155383 100644 --- a/lib/core-client/src/preview/inferArgTypes.ts +++ b/lib/store/src/inferArgTypes.ts @@ -1,8 +1,8 @@ import mapValues from 'lodash/mapValues'; import dedent from 'ts-dedent'; import { logger } from '@storybook/client-logger'; -import { combineParameters } from '@storybook/store'; import { Framework, SBType, ArgTypesEnhancer } from '@storybook/csf'; +import { combineParameters } from './parameters'; const inferType = (value: any, name: string, visited: Set): SBType => { const type = typeof value; From dbffe939834601c7e252f0d57c6a5ccb5db0b15d Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 13:32:46 +1000 Subject: [PATCH 145/285] Fix angular stories by moving component back into return value --- .../multiple-selector.component.stories.ts | 21 ++++++++----------- .../inheritance.stories.ts | 8 ++----- .../ng-content-about-parent.stories.ts | 9 +++----- .../basics/ng-module/import-module.stories.ts | 8 ++----- lib/store/src/StoryStore.ts | 5 ++--- 5 files changed, 18 insertions(+), 33 deletions(-) diff --git a/examples/angular-cli/src/stories/basics/component-with-complex-selectors/multiple-selector.component.stories.ts b/examples/angular-cli/src/stories/basics/component-with-complex-selectors/multiple-selector.component.stories.ts index 52633a23fe6..479baa05ed0 100644 --- a/examples/angular-cli/src/stories/basics/component-with-complex-selectors/multiple-selector.component.stories.ts +++ b/examples/angular-cli/src/stories/basics/component-with-complex-selectors/multiple-selector.component.stories.ts @@ -6,23 +6,20 @@ export default { title: 'Basics / Component / With Complex Selectors', }; -export const MultipleSelectors = () => ({}); +export const MultipleSelectors = () => ({ + component: MultipleSelectorComponent, +}); MultipleSelectors.storyName = 'multiple selectors'; -MultipleSelectors.parameters = { - component: MultipleSelectorComponent, -}; -export const AttributeSelectors = () => ({}); +export const AttributeSelectors = () => ({ + component: AttributeSelectorComponent, +}); AttributeSelectors.storyName = 'attribute selectors'; -AttributeSelectors.parameters = { - component: AttributeSelectorComponent, -}; -export const ClassSelectors = () => ({}); +export const ClassSelectors = () => ({ + component: ClassSelectorComponent, +}); ClassSelectors.storyName = 'class selectors'; -ClassSelectors.parameters = { - component: ClassSelectorComponent, -}; diff --git a/examples/angular-cli/src/stories/basics/component-with-inheritance/inheritance.stories.ts b/examples/angular-cli/src/stories/basics/component-with-inheritance/inheritance.stories.ts index a7caf2f4e9f..bf1e6a05082 100644 --- a/examples/angular-cli/src/stories/basics/component-with-inheritance/inheritance.stories.ts +++ b/examples/angular-cli/src/stories/basics/component-with-inheritance/inheritance.stories.ts @@ -6,6 +6,7 @@ export default { }; export const IconButton = () => ({ + component: IconButtonComponent, props: { icon: 'this is icon', label: 'this is label', @@ -13,17 +14,12 @@ export const IconButton = () => ({ }); IconButton.storyName = 'icon button'; -IconButton.parameters = { - component: IconButtonComponent, -}; export const BaseButton = () => ({ + component: BaseButtonComponent, props: { label: 'this is label', }, }); BaseButton.storyName = 'base button'; -BaseButton.parameters = { - component: BaseButtonComponent, -}; diff --git a/examples/angular-cli/src/stories/basics/component-with-ng-content/ng-content-about-parent.stories.ts b/examples/angular-cli/src/stories/basics/component-with-ng-content/ng-content-about-parent.stories.ts index 27688157013..14f8fd06a02 100644 --- a/examples/angular-cli/src/stories/basics/component-with-ng-content/ng-content-about-parent.stories.ts +++ b/examples/angular-cli/src/stories/basics/component-with-ng-content/ng-content-about-parent.stories.ts @@ -74,12 +74,11 @@ class SbEmojiComponent { emoji = '👾'; } -export const WithComponent: Story = () => ({}); -WithComponent.parameters = { +export const WithComponent: Story = () => ({ // Override the default component // It is therefore necessary to manually declare the parent component with moduleMetadata component: SbEmojiComponent, -}; +}); WithComponent.decorators = [ moduleMetadata({ declarations: [SbButtonComponent], @@ -89,11 +88,9 @@ WithComponent.decorators = [ export const WithComponentAndArgs: Story = (args) => { return { props: args, + component: SbEmojiComponent, }; }; -WithComponentAndArgs.parameters = { - component: SbEmojiComponent, -}; WithComponentAndArgs.decorators = [ moduleMetadata({ declarations: [SbButtonComponent], diff --git a/examples/angular-cli/src/stories/basics/ng-module/import-module.stories.ts b/examples/angular-cli/src/stories/basics/ng-module/import-module.stories.ts index 7c6493e6cf9..eaadf5c0499 100644 --- a/examples/angular-cli/src/stories/basics/ng-module/import-module.stories.ts +++ b/examples/angular-cli/src/stories/basics/ng-module/import-module.stories.ts @@ -13,11 +13,9 @@ export default { } as Meta; export const ChipsGroup: Story = (args) => ({ + component: ChipsGroupComponent, props: args, }); -ChipsGroup.parameters = { - component: ChipsGroupComponent, -}; ChipsGroup.args = { chips: [ { @@ -36,11 +34,9 @@ ChipsGroup.argTypes = { }; export const Chip: Story = (args) => ({ + component: ChipComponent, props: args, }); -Chip.parameters = { - component: ChipComponent, -}; Chip.args = { displayText: 'Chip', }; diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index ec71442ef1b..4e8d9a10cee 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -231,7 +231,7 @@ export class StoryStore { this.hooks[story.id].clean(); } - extract(options: ExtractOptions = {}) { + extract(options: ExtractOptions = { includeDocsOnly: false }) { if (!this.cachedCSFFiles) { throw new Error('Cannot call extract() unless you call cacheAllCSFFiles() first.'); } @@ -241,8 +241,7 @@ export class StoryStore { const csfFile = this.cachedCSFFiles[importPath]; const story = this.storyFromCSFFile({ storyId, csfFile }); - // TODO: docs only - if (options.includeDocsOnly && story.parameters.docsOnly) { + if (!options.includeDocsOnly && story.parameters.docsOnly) { return false; } From c14d5efd044e7368f8f1c88017a0e693d7b4a3df Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 13:39:15 +1000 Subject: [PATCH 146/285] Set legacy parameters in context for back-compat. Also add a `breakingChangesV7` feature to turn of things like this to check future compatibility. --- .../__snapshots__/all-parameters.stories.storyshot | 14 +++++++------- lib/core-common/src/types.ts | 5 +++++ lib/store/src/prepareStory.ts | 12 ++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot b/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot index a277673e9a4..5672a686aec 100644 --- a/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot +++ b/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot @@ -25,6 +25,12 @@ exports[`Storyshots Core / Parameters / All parameters All parameters passed to ] } }, + "framework": "angular", + "globalParameter": "globalParameter", + "chapterParameter": "chapterParameter", + "storyParameter": "storyParameter", + "__isArgsStory": true, + "__id": "core-parameters-all-parameters--passed-to-story", "globalTypes": { "theme": { "name": "Theme", @@ -75,14 +81,8 @@ exports[`Storyshots Core / Parameters / All parameters All parameters passed to } } }, - "globalParameter": "globalParameter", - "framework": "angular", - "chapterParameter": "chapterParameter", "args": {}, - "argTypes": {}, - "storyParameter": "storyParameter", - "__id": "core-parameters-all-parameters--passed-to-story", - "__isArgsStory": true + "argTypes": {} } diff --git a/lib/core-common/src/types.ts b/lib/core-common/src/types.ts index 32b4db40720..f13260887e4 100644 --- a/lib/core-common/src/types.ts +++ b/lib/core-common/src/types.ts @@ -274,6 +274,11 @@ export interface StorybookConfig { * Activate on demand story store */ storyStoreV7?: boolean; + + /** + * Enable a set of planned breaking changes for SB7.0 + */ + breakingChangesV7: boolean; }; /** * Tells Storybook where to find stories. diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 0c783580615..903a6f013a1 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -1,5 +1,6 @@ import dedent from 'ts-dedent'; import deprecate from 'util-deprecate'; +import global from 'global'; import { Parameters, @@ -135,6 +136,17 @@ export function prepareStory( contextForEnhancers.argTypes ); + // Add some of our metadata into parameters as we used to do this in 6.x and users may be relying on it + if (!global.FEATURES?.breakingChangesV7) { + contextForEnhancers.parameters = { + ...contextForEnhancers.parameters, + __id: id, + globalTypes: globalAnnotations.globalTypes, + args: contextForEnhancers.initialArgs, + argTypes: contextForEnhancers.argTypes, + }; + } + const applyLoaders = async (context: StoryContext) => { const loadResults = await Promise.all(loaders.map((loader) => loader(context))); const loaded = Object.assign({}, ...loadResults); From 82d186b645f14a187159e4578952fd2d06d38e65 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 13:48:15 +1000 Subject: [PATCH 147/285] Fix addon-docs tests --- addons/docs/src/blocks/DocsPage.test.ts | 7 +++---- .../docs/src/frameworks/react/react-properties.test.ts | 10 +++++++--- lib/store/src/index.ts | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/addons/docs/src/blocks/DocsPage.test.ts b/addons/docs/src/blocks/DocsPage.test.ts index 34a120d6e90..0e94fcb1d7d 100644 --- a/addons/docs/src/blocks/DocsPage.test.ts +++ b/addons/docs/src/blocks/DocsPage.test.ts @@ -2,9 +2,8 @@ import { extractTitle } from './Title'; describe('defaultTitleSlot', () => { it('splits on last /', () => { - const parameters = {}; - expect(extractTitle({ kind: 'a/b/c', parameters })).toBe('c'); - expect(extractTitle({ kind: 'a|b', parameters })).toBe('a|b'); - expect(extractTitle({ kind: 'a/b/c.d', parameters })).toBe('c.d'); + expect(extractTitle({ title: 'a/b/c' } as any)).toBe('c'); + expect(extractTitle({ title: 'a|b' } as any)).toBe('a|b'); + expect(extractTitle({ title: 'a/b/c.d' } as any)).toBe('c.d'); }); }); diff --git a/addons/docs/src/frameworks/react/react-properties.test.ts b/addons/docs/src/frameworks/react/react-properties.test.ts index 1417a82b5ab..0a9b1ea0eb6 100644 --- a/addons/docs/src/frameworks/react/react-properties.test.ts +++ b/addons/docs/src/frameworks/react/react-properties.test.ts @@ -3,8 +3,9 @@ import path from 'path'; import fs from 'fs'; import { transformFileSync, transformSync } from '@babel/core'; -import { inferControls } from '@storybook/client-api'; +import { inferControls } from '@storybook/store'; import { StoryContext } from '@storybook/react'; +import { Framework } from '@storybook/csf'; import requireFromString from 'require-from-string'; import { extractProps } from './extractProps'; @@ -69,8 +70,11 @@ describe('react component properties', () => { // snapshot the output of `extractArgTypes` const argTypes = extractArgTypes(component); - const parameters = { __isArgsStory: true, argTypes }; - const rows = inferControls(({ parameters } as unknown) as StoryContext); + const parameters = { __isArgsStory: true }; + const rows = inferControls(({ + argTypes, + parameters, + } as unknown) as StoryContext); expect(rows).toMatchSpecificSnapshot(path.join(testDir, 'argTypes.snapshot')); }); } diff --git a/lib/store/src/index.ts b/lib/store/src/index.ts index 22265b86e13..c0eec7f8d26 100644 --- a/lib/store/src/index.ts +++ b/lib/store/src/index.ts @@ -3,6 +3,7 @@ export { combineParameters } from './parameters'; export { filterArgTypes } from './filterArgTypes'; export { normalizeInputTypes } from './normalizeInputTypes'; export type { PropDescriptor } from './filterArgTypes'; +export { inferControls } from './inferControls'; export * from './types'; From 088ea7631e54af696ec7be945c9cf6f0527779f3 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 14:18:30 +1000 Subject: [PATCH 148/285] Change `Framework` => `TFramework` --- addons/a11y/package.json | 2 +- addons/a11y/src/index.ts | 4 +- addons/actions/package.json | 2 +- addons/actions/src/preset/addArgsHelpers.ts | 6 +- addons/backgrounds/package.json | 2 +- .../src/decorators/withBackground.ts | 6 +- addons/backgrounds/src/decorators/withGrid.ts | 7 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/docs/src/blocks/Canvas.tsx | 4 +- addons/docs/src/blocks/DocsContainer.tsx | 4 +- addons/docs/src/blocks/DocsContext.ts | 4 +- addons/docs/src/blocks/Story.tsx | 4 +- .../src/frameworks/common/enhanceArgTypes.ts | 4 +- .../frameworks/react/react-properties.test.ts | 4 +- .../src/frameworks/svelte/prepareForInline.ts | 4 +- .../src/frameworks/svelte/sourceDecorator.ts | 6 +- addons/links/package.json | 2 +- addons/measure/package.json | 2 +- addons/measure/src/withMeasure.ts | 6 +- addons/outline/package.json | 2 +- addons/outline/src/withOutline.ts | 6 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-core/src/frameworks/Loader.ts | 8 +-- .../src/frameworks/configure.ts | 4 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 2 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 2 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 2 +- lib/addons/package.json | 2 +- lib/addons/src/hooks.ts | 18 +++--- lib/addons/src/types.ts | 4 +- lib/api/package.json | 2 +- lib/cli/src/project_types.ts | 2 +- lib/client-api/package.json | 2 +- lib/client-api/src/ClientApi.ts | 20 +++--- lib/client-api/src/types.ts | 8 +-- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/core-client/src/preview/index.ts | 2 - lib/core-client/src/preview/start.ts | 4 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- lib/store/src/StoryStore.test.ts | 4 +- lib/store/src/StoryStore.ts | 6 +- lib/store/src/decorators.test.ts | 6 +- lib/store/src/decorators.ts | 8 +-- lib/store/src/inferArgTypes.ts | 4 +- lib/store/src/inferControls.ts | 4 +- lib/store/src/normalizeStory.test.ts | 4 +- lib/store/src/normalizeStory.ts | 4 +- lib/store/src/prepareStory.ts | 4 +- lib/store/src/processCSFFile.ts | 4 +- lib/store/src/types.ts | 18 +++--- lib/web-preview/package.json | 2 +- lib/web-preview/src/WebPreview.tsx | 4 +- lib/web-preview/src/composeConfigs.ts | 4 +- lib/web-preview/src/types.ts | 8 ++- yarn.lock | 64 +++++++++---------- 66 files changed, 173 insertions(+), 170 deletions(-) diff --git a/addons/a11y/package.json b/addons/a11y/package.json index 4dadc3b51bb..72e66369a4f 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/theming": "6.4.0-alpha.19", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/a11y/src/index.ts b/addons/a11y/src/index.ts index 649e700be65..6f91315bf62 100644 --- a/addons/a11y/src/index.ts +++ b/addons/a11y/src/index.ts @@ -1,4 +1,4 @@ -import { Framework, DecoratorFunction } from '@storybook/csf'; +import { AnyFramework, DecoratorFunction } from '@storybook/csf'; import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; @@ -9,7 +9,7 @@ if (module && module.hot && module.hot.decline) { module.hot.decline(); } -export const withA11y: DecoratorFunction = deprecate( +export const withA11y: DecoratorFunction = deprecate( (storyFn, storyContext) => { return storyFn(storyContext); }, diff --git a/addons/actions/package.json b/addons/actions/package.json index c2b76c82683..6da1a2828db 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/actions/src/preset/addArgsHelpers.ts b/addons/actions/src/preset/addArgsHelpers.ts index f8e99099cd6..0155d8130e5 100644 --- a/addons/actions/src/preset/addArgsHelpers.ts +++ b/addons/actions/src/preset/addArgsHelpers.ts @@ -1,5 +1,5 @@ import { Args } from '@storybook/addons'; -import { Framework, ArgsEnhancer } from '@storybook/csf'; +import { AnyFramework, ArgsEnhancer } from '@storybook/csf'; import { action } from '../index'; // interface ActionsParameter { @@ -12,7 +12,7 @@ import { action } from '../index'; * matches a regex, such as `^on.*` for react-style `onClick` etc. */ -export const inferActionsFromArgTypesRegex: ArgsEnhancer = (context) => { +export const inferActionsFromArgTypesRegex: ArgsEnhancer = (context) => { const { initialArgs, argTypes, @@ -38,7 +38,7 @@ export const inferActionsFromArgTypesRegex: ArgsEnhancer = (context) /** * Add action args for list of strings. */ -export const addActionsFromArgTypes: ArgsEnhancer = (context) => { +export const addActionsFromArgTypes: ArgsEnhancer = (context) => { const { initialArgs, argTypes, diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index 8d4cb84c62c..eba042ac9ea 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,7 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/backgrounds/src/decorators/withBackground.ts b/addons/backgrounds/src/decorators/withBackground.ts index 65395bc936a..e86378bf96c 100644 --- a/addons/backgrounds/src/decorators/withBackground.ts +++ b/addons/backgrounds/src/decorators/withBackground.ts @@ -1,5 +1,5 @@ import { useMemo, useEffect } from '@storybook/addons'; -import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; import { @@ -10,8 +10,8 @@ import { } from '../helpers'; export const withBackground = ( - StoryFn: StoryFunction, - context: StoryContext + StoryFn: StoryFunction, + context: StoryContext ) => { const { globals, parameters } = context; const globalsBackgroundColor = globals[BACKGROUNDS_PARAM_KEY]?.value; diff --git a/addons/backgrounds/src/decorators/withGrid.ts b/addons/backgrounds/src/decorators/withGrid.ts index ecb7e55b6cb..b7c0422cebf 100644 --- a/addons/backgrounds/src/decorators/withGrid.ts +++ b/addons/backgrounds/src/decorators/withGrid.ts @@ -1,7 +1,7 @@ import dedent from 'ts-dedent'; import deprecate from 'util-deprecate'; import { useMemo, useEffect } from '@storybook/addons'; -import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { clearStyles, addGridStyle } from '../helpers'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; @@ -16,7 +16,10 @@ const deprecatedCellSizeWarning = deprecate( ` ); -export const withGrid = (StoryFn: StoryFunction, context: StoryContext) => { +export const withGrid = ( + StoryFn: StoryFunction, + context: StoryContext +) => { const { globals, parameters } = context; const gridParameters = parameters[BACKGROUNDS_PARAM_KEY].grid; const isActive = globals[BACKGROUNDS_PARAM_KEY]?.grid === true && gridParameters.disable !== true; diff --git a/addons/controls/package.json b/addons/controls/package.json index 2fe5f7673d0..43145221039 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", diff --git a/addons/docs/package.json b/addons/docs/package.json index d9f19f7decf..782dc90f52a 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/postinstall": "6.4.0-alpha.19", diff --git a/addons/docs/src/blocks/Canvas.tsx b/addons/docs/src/blocks/Canvas.tsx index 3617203033b..1f42270c907 100644 --- a/addons/docs/src/blocks/Canvas.tsx +++ b/addons/docs/src/blocks/Canvas.tsx @@ -1,6 +1,6 @@ import React, { FC, ReactElement, ReactNode, ReactNodeArray, useContext } from 'react'; import { MDXProvider } from '@mdx-js/react'; -import { toId, storyNameFromExport, Framework } from '@storybook/csf'; +import { toId, storyNameFromExport, AnyFramework } from '@storybook/csf'; import { resetComponents, Preview as PurePreview, @@ -19,7 +19,7 @@ type CanvasProps = PurePreviewProps & { const getPreviewProps = ( { withSource, mdxSource, children, ...props }: CanvasProps & { children?: ReactNode }, - docsContext: DocsContextProps, + docsContext: DocsContextProps, sourceContext: SourceContextProps ): PurePreviewProps => { const { mdxComponentAnnotations, mdxStoryNameToKey } = docsContext; diff --git a/addons/docs/src/blocks/DocsContainer.tsx b/addons/docs/src/blocks/DocsContainer.tsx index cc4c929992c..a3cf42db9ac 100644 --- a/addons/docs/src/blocks/DocsContainer.tsx +++ b/addons/docs/src/blocks/DocsContainer.tsx @@ -5,7 +5,7 @@ import dedent from 'ts-dedent'; import { MDXProvider } from '@mdx-js/react'; import { ThemeProvider, ensure as ensureTheme } from '@storybook/theming'; import { DocsWrapper, DocsContent, components as htmlComponents } from '@storybook/components'; -import { Framework } from '@storybook/csf'; +import { AnyFramework } from '@storybook/csf'; import { DocsContextProps, DocsContext } from './DocsContext'; import { anchorBlockIdFromId } from './Anchor'; import { storyBlockIdFromId } from './Story'; @@ -15,7 +15,7 @@ import { scrollToElement } from './utils'; const { document, window: globalWindow } = global; -export interface DocsContainerProps { +export interface DocsContainerProps { context: DocsContextProps; } diff --git a/addons/docs/src/blocks/DocsContext.ts b/addons/docs/src/blocks/DocsContext.ts index 3972b643122..f9963f53bb7 100644 --- a/addons/docs/src/blocks/DocsContext.ts +++ b/addons/docs/src/blocks/DocsContext.ts @@ -2,7 +2,7 @@ import { Context, createContext } from 'react'; import { window as globalWindow } from 'global'; import { DocsContextProps } from '@storybook/web-preview'; -import { Framework } from '@storybook/csf'; +import { AnyFramework } from '@storybook/csf'; export type { DocsContextProps }; @@ -17,4 +17,4 @@ if (globalWindow.__DOCS_CONTEXT__ === undefined) { globalWindow.__DOCS_CONTEXT__.displayName = 'DocsContext'; } -export const DocsContext: Context> = globalWindow.__DOCS_CONTEXT__; +export const DocsContext: Context> = globalWindow.__DOCS_CONTEXT__; diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 00926ae15e4..044d5cf188a 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -9,7 +9,7 @@ import React, { } from 'react'; import { MDXProvider } from '@mdx-js/react'; import { resetComponents, Story as PureStory } from '@storybook/components'; -import { toId, storyNameFromExport, StoryAnnotations, Framework } from '@storybook/csf'; +import { toId, storyNameFromExport, StoryAnnotations, AnyFramework } from '@storybook/csf'; import { Story as StoryType } from '@storybook/store'; import global from 'global'; import { CURRENT_SELECTION } from './types'; @@ -21,7 +21,7 @@ export const storyBlockIdFromId = (storyId: string) => `story--${storyId}`; type PureStoryProps = ComponentProps; type Annotations = Pick< - StoryAnnotations, + StoryAnnotations, 'decorators' | 'parameters' | 'args' | 'argTypes' | 'loaders' >; type CommonProps = Annotations & { diff --git a/addons/docs/src/frameworks/common/enhanceArgTypes.ts b/addons/docs/src/frameworks/common/enhanceArgTypes.ts index 59a8b4a0f24..80493bbcd03 100644 --- a/addons/docs/src/frameworks/common/enhanceArgTypes.ts +++ b/addons/docs/src/frameworks/common/enhanceArgTypes.ts @@ -1,8 +1,8 @@ import mapValues from 'lodash/mapValues'; -import { Framework, StoryContextForEnhancers } from '@storybook/csf'; +import { AnyFramework, StoryContextForEnhancers } from '@storybook/csf'; import { combineParameters } from '@storybook/store'; -export const enhanceArgTypes = ( +export const enhanceArgTypes = ( context: StoryContextForEnhancers ) => { const { diff --git a/addons/docs/src/frameworks/react/react-properties.test.ts b/addons/docs/src/frameworks/react/react-properties.test.ts index 0a9b1ea0eb6..30bdc5aa69c 100644 --- a/addons/docs/src/frameworks/react/react-properties.test.ts +++ b/addons/docs/src/frameworks/react/react-properties.test.ts @@ -5,7 +5,7 @@ import fs from 'fs'; import { transformFileSync, transformSync } from '@babel/core'; import { inferControls } from '@storybook/store'; import { StoryContext } from '@storybook/react'; -import { Framework } from '@storybook/csf'; +import { AnyFramework } from '@storybook/csf'; import requireFromString from 'require-from-string'; import { extractProps } from './extractProps'; @@ -74,7 +74,7 @@ describe('react component properties', () => { const rows = inferControls(({ argTypes, parameters, - } as unknown) as StoryContext); + } as unknown) as StoryContext); expect(rows).toMatchSpecificSnapshot(path.join(testDir, 'argTypes.snapshot')); }); } diff --git a/addons/docs/src/frameworks/svelte/prepareForInline.ts b/addons/docs/src/frameworks/svelte/prepareForInline.ts index a3dc244d7d3..e8f4ce7c5ab 100644 --- a/addons/docs/src/frameworks/svelte/prepareForInline.ts +++ b/addons/docs/src/frameworks/svelte/prepareForInline.ts @@ -1,11 +1,11 @@ -import { Framework, StoryFn } from '@storybook/csf'; +import { AnyFramework, StoryFn } from '@storybook/csf'; import React from 'react'; // @ts-ignore import HOC from './HOC.svelte'; -export const prepareForInline = (storyFn: StoryFn) => { +export const prepareForInline = (storyFn: StoryFn) => { const el = React.useRef(null); React.useEffect(() => { const root = new HOC({ diff --git a/addons/docs/src/frameworks/svelte/sourceDecorator.ts b/addons/docs/src/frameworks/svelte/sourceDecorator.ts index 3470aa60b92..6eb2d41c2c0 100644 --- a/addons/docs/src/frameworks/svelte/sourceDecorator.ts +++ b/addons/docs/src/frameworks/svelte/sourceDecorator.ts @@ -1,5 +1,5 @@ import { addons } from '@storybook/addons'; -import { ArgTypes, Args, StoryContext, Framework } from '@storybook/csf'; +import { ArgTypes, Args, StoryContext, AnyFramework } from '@storybook/csf'; import { SourceType, SNIPPET_RENDERED } from '../../shared'; @@ -8,7 +8,7 @@ import { SourceType, SNIPPET_RENDERED } from '../../shared'; * * @param context StoryContext */ -const skipSourceRender = (context: StoryContext) => { +const skipSourceRender = (context: StoryContext) => { const sourceParams = context?.parameters.docs?.source; const isArgsStory = context?.parameters.__isArgsStory; @@ -144,7 +144,7 @@ function getWrapperProperties(component: any) { * @param storyFn Fn * @param context StoryContext */ -export const sourceDecorator = (storyFn: any, context: StoryContext) => { +export const sourceDecorator = (storyFn: any, context: StoryContext) => { const story = storyFn(); if (skipSourceRender(context)) { diff --git a/addons/links/package.json b/addons/links/package.json index 170e6a7823e..6b2ee209ee1 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/router": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/measure/package.json b/addons/measure/package.json index 4df4c9a7c6f..8992539f8d8 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,7 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/measure/src/withMeasure.ts b/addons/measure/src/withMeasure.ts index 92f47637378..7ef5ba92101 100644 --- a/addons/measure/src/withMeasure.ts +++ b/addons/measure/src/withMeasure.ts @@ -1,6 +1,6 @@ /* eslint-env browser */ import { useEffect } from '@storybook/addons'; -import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { drawSelectedElement } from './box-model/visualizer'; import { init, rescale, destroy } from './box-model/canvas'; import { deepElementFromPoint } from './util'; @@ -14,8 +14,8 @@ function findAndDrawElement(x: number, y: number) { } export const withMeasure = ( - StoryFn: StoryFunction, - context: StoryContext + StoryFn: StoryFunction, + context: StoryContext ) => { const { measureEnabled } = context.globals; diff --git a/addons/outline/package.json b/addons/outline/package.json index 4f3db5a5986..2eb3f7a268b 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,7 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/outline/src/withOutline.ts b/addons/outline/src/withOutline.ts index 22fa4595613..de3878f57e4 100644 --- a/addons/outline/src/withOutline.ts +++ b/addons/outline/src/withOutline.ts @@ -1,13 +1,13 @@ import { useMemo, useEffect } from '@storybook/addons'; -import { Framework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { clearStyles, addOutlineStyles } from './helpers'; import { PARAM_KEY } from './constants'; import outlineCSS from './outlineCSS'; export const withOutline = ( - StoryFn: StoryFunction, - context: StoryContext + StoryFn: StoryFunction, + context: StoryContext ) => { const { globals } = context; const isActive = globals[PARAM_KEY] === true; diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index 059ea924dca..b626983364e 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-client": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts index 22773bc7ed4..f296bc0aa89 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts @@ -1,4 +1,4 @@ -import { Framework } from '@storybook/csf'; +import { AnyFramework } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import { ClientApi as ClientApiClass } from '@storybook/client-api'; import { StoryshotsOptions } from '../api/StoryshotsOptions'; @@ -6,7 +6,7 @@ import { SupportedFramework } from './SupportedFramework'; export type RenderTree = (story: any, context?: any, options?: any) => any; -export interface ClientApi +export interface ClientApi extends ClientStoryApi { configure(loader: Loadable, module: NodeModule | false, showDeprecationWarning?: boolean): void; forceReRender(): void; @@ -18,7 +18,7 @@ export interface ClientApi raw: ClientApiClass['raw']; } -// TODO -- this is untyped for now, we could import each framework's Framework type +// TODO -- this is untyped for now, we could import each framework's AnyFramework type export interface Loader { load: ( options: StoryshotsOptions @@ -26,7 +26,7 @@ export interface Loader { framework: SupportedFramework; renderTree: RenderTree; renderShallowTree: any; - storybook: ClientApi; + storybook: ClientApi; }; test: (options: StoryshotsOptions) => boolean; } diff --git a/addons/storyshots/storyshots-core/src/frameworks/configure.ts b/addons/storyshots/storyshots-core/src/frameworks/configure.ts index 4d17000e12d..a1b6064dbd7 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/configure.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/configure.ts @@ -3,7 +3,7 @@ import path from 'path'; import { toRequireContext } from '@storybook/core-common'; import registerRequireContextHook from 'babel-plugin-require-context-hook/register'; import global from 'global'; -import { Framework, ArgsEnhancer, ArgTypesEnhancer, DecoratorFunction } from '@storybook/csf'; +import { AnyFramework, ArgsEnhancer, ArgTypesEnhancer, DecoratorFunction } from '@storybook/csf'; import { ClientApi } from './Loader'; import { StoryshotsOptions } from '../api/StoryshotsOptions'; @@ -69,7 +69,7 @@ function getConfigPathParts(input: string): Output { return { preview: configDir }; } -function configure( +function configure( options: { storybook: ClientApi; } & StoryshotsOptions diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index 114663ec05f..97d4ae8ad8e 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/node-logger": "6.4.0-alpha.19", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index 1e5bdff81b1..0e6f32579d5 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index 846e4ce19a2..3eaf148dee5 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/app/preact/package.json b/app/preact/package.json index 9dc54aed196..30ee7e5b311 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/react/package.json b/app/react/package.json index 819b85f855a..0a71d0a79e7 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index b4d518d0b2e..75b40ca0f1a 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,7 +50,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", diff --git a/app/svelte/package.json b/app/svelte/package.json index 38251ed4bfe..a47804d977d 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index d8416fbc8ab..ae757e5c343 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index 356c6111c76..59c72065303 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index 7f7faedb689..ff875b1123b 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/lib/addons/package.json b/lib/addons/package.json index 806f4599b86..9e592740961 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/addons/src/hooks.ts b/lib/addons/src/hooks.ts index dffe9eefb8b..19d05e5ba85 100644 --- a/lib/addons/src/hooks.ts +++ b/lib/addons/src/hooks.ts @@ -1,7 +1,7 @@ import global from 'global'; import { logger } from '@storybook/client-logger'; import { - Framework, + AnyFramework, DecoratorFunction, DecoratorApplicator, StoryContext, @@ -36,7 +36,7 @@ type AbstractFunction = (...args: any[]) => any; const RenderEvents = [STORY_RENDERED, DOCS_RENDERED]; -export class HooksContext { +export class HooksContext { hookListsMap: WeakMap; mountedDecorators: Set; @@ -129,13 +129,13 @@ export class HooksContext { } } -function hookify( +function hookify( storyFn: LegacyStoryFn ): LegacyStoryFn; -function hookify( +function hookify( decorator: DecoratorFunction ): DecoratorFunction; -function hookify(fn: AbstractFunction) { +function hookify(fn: AbstractFunction) { return (...args: any[]) => { const { hooks }: { hooks: HooksContext } = typeof args[0] === 'function' ? args[1] : args[0]; @@ -179,7 +179,7 @@ function hookify(fn: AbstractFunction) { // Counter to prevent infinite loops. let numberOfRenders = 0; const RENDER_LIMIT = 25; -export const applyHooks = ( +export const applyHooks = ( applyDecorators: DecoratorApplicator ): DecoratorApplicator => ( storyFn: LegacyStoryFn, @@ -219,11 +219,11 @@ const areDepsEqual = (deps: any[], nextDeps: any[]) => const invalidHooksError = () => new Error('Storybook preview hooks can only be called inside decorators and story functions.'); -function getHooksContextOrNull(): HooksContext | null { +function getHooksContextOrNull(): HooksContext | null { return globalWindow.STORYBOOK_HOOKS_CONTEXT || null; } -function getHooksContextOrThrow(): HooksContext { +function getHooksContextOrThrow(): HooksContext { const hooks = getHooksContextOrNull(); if (hooks == null) { throw invalidHooksError(); @@ -408,7 +408,7 @@ export function useChannel(eventMap: EventMap, deps: any[] = []) { } /* Returns current story context */ -export function useStoryContext(): StoryContext { +export function useStoryContext(): StoryContext { const { currentContext } = getHooksContextOrThrow(); if (currentContext == null) { throw invalidHooksError(); diff --git a/lib/addons/src/types.ts b/lib/addons/src/types.ts index 0bec427389d..a24bef00740 100644 --- a/lib/addons/src/types.ts +++ b/lib/addons/src/types.ts @@ -1,5 +1,5 @@ import { - Framework, + AnyFramework, InputType, Parameters, StoryContext as StoryContextForFramework, @@ -35,7 +35,7 @@ export type ArgTypes = { [key in keyof Partial]: InputType; }; -export type StoryContext = StoryContextForFramework; +export type StoryContext = StoryContextForFramework; export type StoryContextUpdate = Partial; type ReturnTypeFramework = { component: any; storyResult: ReturnType }; diff --git a/lib/api/package.json b/lib/api/package.json index af8d00bb1d4..ce6f36e8696 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.19", diff --git a/lib/cli/src/project_types.ts b/lib/cli/src/project_types.ts index 222af9925f4..a4c7c549d95 100644 --- a/lib/cli/src/project_types.ts +++ b/lib/cli/src/project_types.ts @@ -277,7 +277,7 @@ export const supportedTemplates: TemplateConfiguration[] = [ ]; // A TemplateConfiguration that matches unsupported frameworks -// Framework matchers can be added to this object to give +// AnyFramework matchers can be added to this object to give // users an "Unsupported framework" message export const unsupportedTemplate: TemplateConfiguration = { preset: ProjectType.UNSUPPORTED, diff --git a/lib/client-api/package.json b/lib/client-api/package.json index 444384fd488..4d97f60640a 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -46,7 +46,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index a6f19dcf8d3..b2351a609ac 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -3,7 +3,7 @@ import dedent from 'ts-dedent'; import global from 'global'; import { logger } from '@storybook/client-logger'; import { - Framework, + AnyFramework, toId, isExportStory, DecoratorFunction, @@ -34,12 +34,12 @@ import { ClientApiAddons, StoryApi } from '@storybook/addons'; const { FEATURES } = global; -export interface GetStorybookStory { +export interface GetStorybookStory { name: string; render: StoryFn; } -export interface GetStorybookKind { +export interface GetStorybookKind { kind: string; fileName: string; stories: GetStorybookStory[]; @@ -47,7 +47,7 @@ export interface GetStorybookKind { // ClientApi (and StoreStore) are really singletons. However they are not created until the // relevant framework instanciates them via `start.js`. The good news is this happens right away. -let singleton: ClientApi; +let singleton: ClientApi; const warningAlternatives = { addDecorator: `Instead, use \`export const decorators = [];\` in your \`preview.js\`.`, @@ -91,7 +91,7 @@ const checkMethod = (method: string, deprecationWarning: boolean) => { }; export const addDecorator = ( - decorator: DecoratorFunction, + decorator: DecoratorFunction, deprecationWarning = true ) => { checkMethod('addDecorator', deprecationWarning); @@ -103,17 +103,17 @@ export const addParameters = (parameters: Parameters, deprecationWarning = true) singleton.addParameters(parameters); }; -export const addLoader = (loader: LoaderFunction, deprecationWarning = true) => { +export const addLoader = (loader: LoaderFunction, deprecationWarning = true) => { checkMethod('addLoader', deprecationWarning); singleton.addLoader(loader); }; -export const addArgsEnhancer = (enhancer: ArgsEnhancer) => { +export const addArgsEnhancer = (enhancer: ArgsEnhancer) => { checkMethod('addArgsEnhancer', false); singleton.addArgsEnhancer(enhancer); }; -export const addArgTypesEnhancer = (enhancer: ArgTypesEnhancer) => { +export const addArgTypesEnhancer = (enhancer: ArgTypesEnhancer) => { checkMethod('addArgTypesEnhancer', false); singleton.addArgTypesEnhancer(enhancer); }; @@ -123,13 +123,13 @@ export const getGlobalRender = () => { return singleton.globalAnnotations.render; }; -export const setGlobalRender = (render: StoryFn) => { +export const setGlobalRender = (render: StoryFn) => { checkMethod('setGlobalRender', false); singleton.globalAnnotations.render = render; }; const invalidStoryTypes = new Set(['string', 'number', 'boolean', 'symbol']); -export default class ClientApi { +export default class ClientApi { globalAnnotations: NormalizedGlobalAnnotations; storyStore?: StoryStore; diff --git a/lib/client-api/src/types.ts b/lib/client-api/src/types.ts index b038c9d8a82..2a3ae344882 100644 --- a/lib/client-api/src/types.ts +++ b/lib/client-api/src/types.ts @@ -13,7 +13,7 @@ import { LoaderFunction, StoryContext, } from '@storybook/addons'; -import { Framework, StoryIdentifier, GlobalAnnotations } from '@storybook/csf'; +import { AnyFramework, StoryIdentifier, GlobalAnnotations } from '@storybook/csf'; import { StoryStore, HooksContext } from '@storybook/store'; export type { @@ -74,7 +74,7 @@ export type StoreItem = StoryIdentifier & { runPlayFunction: () => Promise; storyFn: StoryFn; unboundStoryFn: StoryFn; - hooks: HooksContext; + hooks: HooksContext; args: Args; initialArgs: Args; argTypes: ArgTypes; @@ -89,8 +89,8 @@ export interface StoreData { } export interface ClientApiParams { - storyStore: StoryStore; - decorateStory?: GlobalAnnotations['applyDecorators']; + storyStore: StoryStore; + decorateStory?: GlobalAnnotations['applyDecorators']; noStoryModuleAddMethodHotDispose?: boolean; } diff --git a/lib/codemod/package.json b/lib/codemod/package.json index 0eeaae921bb..22fc5619055 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index 487e017d4c7..343776243b8 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/theming": "6.4.0-alpha.19", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index 58338e77666..4604a2c59fc 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "@storybook/ui": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", diff --git a/lib/core-client/src/preview/index.ts b/lib/core-client/src/preview/index.ts index b4505e71850..88fa36b2498 100644 --- a/lib/core-client/src/preview/index.ts +++ b/lib/core-client/src/preview/index.ts @@ -11,5 +11,3 @@ export default { }; export { start, toId, ClientApi, StoryStore }; - -export { inferArgTypes } from './inferArgTypes'; diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index fc8a71f1b23..605e261405d 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -1,7 +1,7 @@ import global from 'global'; import { ClientApi } from '@storybook/client-api'; import { WebGlobalAnnotations, WebPreview } from '@storybook/web-preview'; -import { Framework } from '@storybook/csf'; +import { AnyFramework } from '@storybook/csf'; import createChannel from '@storybook/channel-postmessage'; import { addons } from '@storybook/addons'; import Events from '@storybook/core-events'; @@ -12,7 +12,7 @@ import { executeLoadableForChanges } from './executeLoadable'; const { window: globalWindow } = global; -export function start( +export function start( renderToDOM: WebGlobalAnnotations['renderToDOM'], { decorateStory }: { decorateStory?: WebGlobalAnnotations['applyDecorators'] } = {} ) { diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index 2a3a2a67b0f..0ce799e2060 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index e30843220d4..e57d7d4ebe3 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -43,7 +43,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index 62331ab44c4..b50ac81ff50 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -1,4 +1,4 @@ -import { Framework, GlobalAnnotations } from '@storybook/csf'; +import { AnyFramework, GlobalAnnotations } from '@storybook/csf'; import { HooksContext } from '../../addons/dist/ts3.9/hooks'; import { prepareStory } from './prepareStory'; @@ -181,7 +181,7 @@ describe('StoryStore', () => { const story = await store.loadStory({ storyId: 'component-one--a' }); - const { hooks } = store.getStoryContext(story) as { hooks: HooksContext }; + const { hooks } = store.getStoryContext(story) as { hooks: HooksContext }; hooks.clean = jest.fn(); store.cleanupStory(story); expect(hooks.clean).toHaveBeenCalled(); diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 4e8d9a10cee..9697e6fbbab 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -3,7 +3,7 @@ import { Parameters, StoryId, StoryContextForLoaders, - Framework, + AnyFramework, GlobalAnnotations, ComponentTitle, } from '@storybook/csf'; @@ -32,7 +32,7 @@ import { inferControls } from './inferControls'; const CSF_CACHE_SIZE = 100; const STORY_CACHE_SIZE = 1000; -function normalizeGlobalAnnotations({ +function normalizeGlobalAnnotations({ argTypes, globalTypes, argTypesEnhancers, @@ -51,7 +51,7 @@ function normalizeGlobalAnnotations({ }; } -export class StoryStore { +export class StoryStore { storiesList: StoriesListStore; importFn: ModuleImportFn; diff --git a/lib/store/src/decorators.test.ts b/lib/store/src/decorators.test.ts index 4b57ff6ed54..9b0bba61e8c 100644 --- a/lib/store/src/decorators.test.ts +++ b/lib/store/src/decorators.test.ts @@ -1,8 +1,8 @@ -import { Framework, StoryContext } from '@storybook/csf'; +import { AnyFramework, StoryContext } from '@storybook/csf'; import { defaultDecorateStory } from './decorators'; -function makeContext(input: Record = {}): StoryContext { +function makeContext(input: Record = {}): StoryContext { return { id: 'id', kind: 'kind', @@ -10,7 +10,7 @@ function makeContext(input: Record = {}): StoryContext { viewMode: 'story', parameters: {}, ...input, - } as StoryContext; + } as StoryContext; } describe('client-api.decorators', () => { diff --git a/lib/store/src/decorators.ts b/lib/store/src/decorators.ts index 2772a0bf3ab..5dddb92ad42 100644 --- a/lib/store/src/decorators.ts +++ b/lib/store/src/decorators.ts @@ -4,10 +4,10 @@ import { StoryContextUpdate, PartialStoryFn, LegacyStoryFn, - Framework, + AnyFramework, } from '@storybook/csf'; -export function decorateStory( +export function decorateStory( storyFn: LegacyStoryFn, decorator: DecoratorFunction, bindWithContext: (storyFn: LegacyStoryFn) => PartialStoryFn @@ -20,7 +20,7 @@ export function decorateStory( return (context) => decorator(boundStoryFunction, context); } -type ContextStore = { value?: StoryContext }; +type ContextStore = { value?: StoryContext }; /** * Currently StoryContextUpdates are allowed to have any key in the type. @@ -44,7 +44,7 @@ export function sanitizeStoryContextUpdate({ return update; } -export function defaultDecorateStory( +export function defaultDecorateStory( storyFn: LegacyStoryFn, decorators: DecoratorFunction[] ): LegacyStoryFn { diff --git a/lib/store/src/inferArgTypes.ts b/lib/store/src/inferArgTypes.ts index 3abfb155383..5c0dd90605b 100644 --- a/lib/store/src/inferArgTypes.ts +++ b/lib/store/src/inferArgTypes.ts @@ -1,7 +1,7 @@ import mapValues from 'lodash/mapValues'; import dedent from 'ts-dedent'; import { logger } from '@storybook/client-logger'; -import { Framework, SBType, ArgTypesEnhancer } from '@storybook/csf'; +import { AnyFramework, SBType, ArgTypesEnhancer } from '@storybook/csf'; import { combineParameters } from './parameters'; const inferType = (value: any, name: string, visited: Set): SBType => { @@ -40,7 +40,7 @@ const inferType = (value: any, name: string, visited: Set): SBType => { return { name: 'object', value: {} }; }; -export const inferArgTypes: ArgTypesEnhancer = (context) => { +export const inferArgTypes: ArgTypesEnhancer = (context) => { const { id, argTypes: userArgTypes = {}, initialArgs = {} } = context; const argTypes = mapValues(initialArgs, (arg, key) => ({ name: key, diff --git a/lib/store/src/inferControls.ts b/lib/store/src/inferControls.ts index a84293e3dc3..701d868df79 100644 --- a/lib/store/src/inferControls.ts +++ b/lib/store/src/inferControls.ts @@ -1,6 +1,6 @@ import mapValues from 'lodash/mapValues'; import { logger } from '@storybook/client-logger'; -import { Framework, SBEnumType, StrictInputType, ArgTypesEnhancer } from '@storybook/csf'; +import { AnyFramework, SBEnumType, StrictInputType, ArgTypesEnhancer } from '@storybook/csf'; import { filterArgTypes } from './filterArgTypes'; import { combineParameters } from './parameters'; @@ -55,7 +55,7 @@ const inferControl = (argType: StrictInputType, name: string, matchers: Controls } }; -export const inferControls: ArgTypesEnhancer = (context) => { +export const inferControls: ArgTypesEnhancer = (context) => { const { argTypes, parameters: { __isArgsStory, controls: { include = null, exclude = null, matchers = {} } = {} }, diff --git a/lib/store/src/normalizeStory.test.ts b/lib/store/src/normalizeStory.test.ts index 5b0208f977d..a494c327be5 100644 --- a/lib/store/src/normalizeStory.test.ts +++ b/lib/store/src/normalizeStory.test.ts @@ -1,4 +1,4 @@ -import { Framework, StoryAnnotationsOrFn } from '@storybook/csf'; +import { AnyFramework, StoryAnnotationsOrFn } from '@storybook/csf'; import { normalizeStory } from './normalizeStory'; describe('normalizeStory', () => { @@ -104,7 +104,7 @@ describe('normalizeStory', () => { }); it('full annotations', () => { - const storyObj: StoryAnnotationsOrFn = { + const storyObj: StoryAnnotationsOrFn = { name: 'story name', parameters: { storyParam: 'val' }, decorators: [() => {}], diff --git a/lib/store/src/normalizeStory.ts b/lib/store/src/normalizeStory.ts index c1979ac1e45..dc5cc8bf027 100644 --- a/lib/store/src/normalizeStory.ts +++ b/lib/store/src/normalizeStory.ts @@ -2,7 +2,7 @@ import { storyNameFromExport, toId, ComponentAnnotations, - Framework, + AnyFramework, DecoratorFunction, ArgTypes, StoryAnnotationsOrFn, @@ -24,7 +24,7 @@ See https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#hoisted-csf- const deprecatedStoryAnnotationWarning = deprecate(() => {}, deprecatedStoryAnnotation); -export function normalizeStory( +export function normalizeStory( key: StoryId, storyAnnotations: StoryAnnotationsOrFn, meta: ComponentAnnotations diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 903a6f013a1..9f26c39108c 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -9,7 +9,7 @@ import { ArgsStoryFn, StoryContextForEnhancers, StoryContext, - Framework, + AnyFramework, StrictArgTypes, } from '@storybook/csf'; @@ -36,7 +36,7 @@ const argTypeDefaultValueWarning = deprecate( // // Note that this story function is *stateless* in the sense that it does not track args or globals // Instead, it is expected these are tracked separately (if necessary) and are passed into each invocation. -export function prepareStory( +export function prepareStory( storyAnnotations: NormalizedStoryAnnotations, componentAnnotations: NormalizedComponentAnnotations, globalAnnotations: NormalizedGlobalAnnotations diff --git a/lib/store/src/processCSFFile.ts b/lib/store/src/processCSFFile.ts index 15ebe990885..472ae990b8e 100644 --- a/lib/store/src/processCSFFile.ts +++ b/lib/store/src/processCSFFile.ts @@ -1,4 +1,4 @@ -import { isExportStory, sanitize, Parameters, Framework, ComponentTitle } from '@storybook/csf'; +import { isExportStory, sanitize, Parameters, AnyFramework, ComponentTitle } from '@storybook/csf'; import { logger } from '@storybook/client-logger'; import { ModuleExports, CSFFile, NormalizedComponentAnnotations } from './types'; @@ -32,7 +32,7 @@ const checkDisallowedParameters = (parameters: Parameters) => { }; // Given the raw exports of a CSF file, check and normalize it. -export function processCSFFile( +export function processCSFFile( moduleExports: ModuleExports, title: ComponentTitle ): CSFFile { diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index b4d76c8a1de..08ad4fe5307 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -10,7 +10,7 @@ import { StoryContextForLoaders, StoryContext, ComponentTitle, - Framework, + AnyFramework, GlobalAnnotations, ComponentAnnotations, StoryAnnotations, @@ -25,21 +25,21 @@ export type ModuleExports = Record; export type ModuleImportFn = (path: Path) => Promise | ModuleExports; export type NormalizedGlobalAnnotations< - TFramework extends Framework + TFramework extends AnyFramework > = GlobalAnnotations & { argTypes?: StrictArgTypes; globalTypes?: StrictGlobalTypes; }; export type NormalizedComponentAnnotations< - TFramework extends Framework + TFramework extends AnyFramework > = ComponentAnnotations & { // Useful to guarantee that id exists id: ComponentId; argTypes?: StrictArgTypes; }; -export type NormalizedStoryAnnotations = Omit< +export type NormalizedStoryAnnotations = Omit< StoryAnnotations, 'storyName' | 'story' > & { @@ -48,12 +48,12 @@ export type NormalizedStoryAnnotations = Omit< argTypes?: StrictArgTypes; }; -export type CSFFile = { +export type CSFFile = { meta: NormalizedComponentAnnotations; stories: Record>; }; -export type Story = StoryContextForEnhancers & { +export type Story = StoryContextForEnhancers & { originalStoryFn: StoryFn; undecoratedStoryFn: LegacyStoryFn; unboundStoryFn: LegacyStoryFn; @@ -61,11 +61,11 @@ export type Story = StoryContextForEnhancers Promise; }; -export type BoundStory = Story & { +export type BoundStory = Story & { storyFn: LegacyStoryFn; }; -export declare type RenderContext = StoryIdentifier & { +export declare type RenderContext = StoryIdentifier & { showMain: () => void; showError: (error: { title: string; description: string }) => void; showException: (err: Error) => void; @@ -100,7 +100,7 @@ export interface Selection { viewMode: ViewMode; } -export type DecoratorApplicator = ( +export type DecoratorApplicator = ( storyFn: LegacyStoryFn, decorators: DecoratorFunction[] ) => LegacyStoryFn; diff --git a/lib/web-preview/package.json b/lib/web-preview/package.json index 0d221f96dd5..0a2f6e61325 100644 --- a/lib/web-preview/package.json +++ b/lib/web-preview/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.c10361d.0", + "@storybook/csf": "0.0.2--canary.a1972cb.0", "@storybook/store": "6.4.0-alpha.19", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 8fe83fed0d3..761a13cd526 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -5,7 +5,7 @@ import { logger } from '@storybook/client-logger'; import global from 'global'; import { addons, Channel } from '@storybook/addons'; import { - Framework, + AnyFramework, StoryId, GlobalAnnotations, Args, @@ -39,7 +39,7 @@ function focusInInput(event: Event) { type InitialRenderPhase = 'init' | 'loaded' | 'rendered' | 'done'; -export class WebPreview { +export class WebPreview { channel: Channel; urlStore: UrlStore; diff --git a/lib/web-preview/src/composeConfigs.ts b/lib/web-preview/src/composeConfigs.ts index 4421bc7fef2..0ceb7751e7a 100644 --- a/lib/web-preview/src/composeConfigs.ts +++ b/lib/web-preview/src/composeConfigs.ts @@ -1,4 +1,4 @@ -import { Framework } from '@storybook/csf'; +import { AnyFramework } from '@storybook/csf'; import { combineParameters, ModuleExports } from '@storybook/store'; import { WebGlobalAnnotations } from './types'; @@ -18,7 +18,7 @@ function getSingletonField(moduleExportList: ModuleExports[], field: string): an return getField(moduleExportList, field)[0]; } -export function composeConfigs( +export function composeConfigs( moduleExportList: ModuleExports[] ): WebGlobalAnnotations { const allArgTypeEnhancers = getArrayField(moduleExportList, 'argTypesEnhancers'); diff --git a/lib/web-preview/src/types.ts b/lib/web-preview/src/types.ts index 957d9ab6d7c..d96f5242ae3 100644 --- a/lib/web-preview/src/types.ts +++ b/lib/web-preview/src/types.ts @@ -1,12 +1,14 @@ -import { StoryId, Framework, GlobalAnnotations, StoryContextForLoaders } from '@storybook/csf'; +import { StoryId, AnyFramework, GlobalAnnotations, StoryContextForLoaders } from '@storybook/csf'; import { RenderContext, DecoratorApplicator, Story } from '@storybook/store'; import { WebPreview } from './WebPreview'; -export type WebGlobalAnnotations = GlobalAnnotations & { +export type WebGlobalAnnotations< + TFramework extends AnyFramework +> = GlobalAnnotations & { renderToDOM?: (context: RenderContext, element: Element) => Promise | void; }; -export interface DocsContextProps { +export interface DocsContextProps { id: string; title: string; name: string; diff --git a/yarn.lock b/yarn.lock index 322e3cb2684..9783a923a6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5536,7 +5536,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/theming": 6.4.0-alpha.19 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -5567,7 +5567,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/theming": 6.4.0-alpha.19 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -5602,7 +5602,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/theming": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -5630,7 +5630,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 @@ -5673,7 +5673,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/postinstall": 6.4.0-alpha.19 @@ -5857,7 +5857,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/router": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -5887,7 +5887,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -5911,7 +5911,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -5946,7 +5946,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/node-logger": 6.4.0-alpha.19 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -5976,7 +5976,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-client": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/react": 6.4.0-alpha.19 "@storybook/vue": 6.4.0-alpha.19 "@storybook/vue3": 6.4.0-alpha.19 @@ -6139,7 +6139,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6172,7 +6172,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@types/autoprefixer": ^9.7.2 @@ -6241,7 +6241,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.19 @@ -6523,7 +6523,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -6559,7 +6559,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6581,7 +6581,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/theming": 6.4.0-alpha.19 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -6620,7 +6620,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 @@ -6818,12 +6818,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.c10361d.0": - version: 0.0.2--canary.c10361d.0 - resolution: "@storybook/csf@npm:0.0.2--canary.c10361d.0" +"@storybook/csf@npm:0.0.2--canary.a1972cb.0": + version: 0.0.2--canary.a1972cb.0 + resolution: "@storybook/csf@npm:0.0.2--canary.a1972cb.0" dependencies: lodash: ^4.17.15 - checksum: 9534f6c87d1e109c692a9202e228eed07f0508ea2bfee9e36214dcc8519e86f09d80a40ed435281fe1555ef5d682e02c4211900e5b3a7ff81017878e2a73c77c + checksum: 0e478f4c4733e7d597ca295a3474711cc65c2097e3c7933246d46ebcffde7b422a70bba1b5618d381b1067b193f39dc32156009d92be6c1b8bdce53e61b75f5b languageName: node linkType: hard @@ -6960,7 +6960,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 @@ -7162,7 +7162,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7243,7 +7243,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -7541,7 +7541,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 @@ -7570,7 +7570,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -7591,7 +7591,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -7609,7 +7609,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7709,7 +7709,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -7746,7 +7746,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -7789,7 +7789,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 @@ -7819,7 +7819,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.c10361d.0 + "@storybook/csf": 0.0.2--canary.a1972cb.0 "@storybook/store": 6.4.0-alpha.19 ansi-to-html: ^0.6.11 core-js: ^3.8.2 From 06fdc90c8be85afd6d209f1f688bd49f50a3084a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 16:22:35 +1000 Subject: [PATCH 149/285] Whoops this was supposed to be optional --- lib/core-common/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core-common/src/types.ts b/lib/core-common/src/types.ts index f13260887e4..a5da3a29a75 100644 --- a/lib/core-common/src/types.ts +++ b/lib/core-common/src/types.ts @@ -278,7 +278,7 @@ export interface StorybookConfig { /** * Enable a set of planned breaking changes for SB7.0 */ - breakingChangesV7: boolean; + breakingChangesV7?: boolean; }; /** * Tells Storybook where to find stories. From b9048d5b5cbf70484c953d11d0ba63f1c3777a47 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 16:49:13 +1000 Subject: [PATCH 150/285] Use breaking changes in store/preview tests --- lib/store/src/StoryStore.test.ts | 43 ++++++++++++++++++++++++++ lib/web-preview/src/WebPreview.test.ts | 1 + 2 files changed, 44 insertions(+) diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index b50ac81ff50..47665953600 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -14,6 +14,13 @@ jest.mock('./processCSFFile', () => ({ processCSFFile: jest.fn(jest.requireActual('./processCSFFile').processCSFFile), })); +jest.mock('global', () => ({ + ...(jest.requireActual('global') as any), + FEATURES: { + breakingChangesV7: true, + }, +})); + const componentOneExports = { default: { title: 'Component One' }, a: { args: { foo: 'a' } }, @@ -226,6 +233,12 @@ describe('StoryStore', () => { "name": "string", }, }, + "foo": Object { + "name": "foo", + "type": Object { + "name": "string", + }, + }, }, "component": undefined, "componentId": "component-one", @@ -250,6 +263,12 @@ describe('StoryStore', () => { "name": "string", }, }, + "foo": Object { + "name": "foo", + "type": Object { + "name": "string", + }, + }, }, "component": undefined, "componentId": "component-one", @@ -274,6 +293,12 @@ describe('StoryStore', () => { "name": "string", }, }, + "foo": Object { + "name": "foo", + "type": Object { + "name": "string", + }, + }, }, "component": undefined, "componentId": "component-two", @@ -320,6 +345,12 @@ describe('StoryStore', () => { "name": "string", }, }, + "foo": Object { + "name": "foo", + "type": Object { + "name": "string", + }, + }, }, "component": undefined, "componentId": "component-one", @@ -344,6 +375,12 @@ describe('StoryStore', () => { "name": "string", }, }, + "foo": Object { + "name": "foo", + "type": Object { + "name": "string", + }, + }, }, "component": undefined, "componentId": "component-one", @@ -368,6 +405,12 @@ describe('StoryStore', () => { "name": "string", }, }, + "foo": Object { + "name": "foo", + "type": Object { + "name": "string", + }, + }, }, "component": undefined, "componentId": "component-two", diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index a48aaea3892..068dd911169 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -33,6 +33,7 @@ jest.mock('global', () => ({ }, FEATURES: { storyStoreV7: true, + breakingChangesV7: true, }, })); From f13598338b3eabd87799ad452b53af872fadb7c5 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 3 Sep 2021 17:01:35 +1000 Subject: [PATCH 151/285] Fix withActions --- addons/actions/src/preview/withActions.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/actions/src/preview/withActions.ts b/addons/actions/src/preview/withActions.ts index 4a74a443868..1a1c121f930 100644 --- a/addons/actions/src/preview/withActions.ts +++ b/addons/actions/src/preview/withActions.ts @@ -1,10 +1,9 @@ // Based on http://backbonejs.org/docs/backbone.html#section-164 import global from 'global'; -import { useEffect } from '@storybook/client-api'; +import { useEffect, makeDecorator } from '@storybook/addons'; import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; -import { makeDecorator } from '@storybook/addons'; import { actions } from './actions'; import { PARAM_KEY } from '../constants'; From ec9c4b82275bd764f05c4e970359e661d2ac61d1 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 11:33:34 +1000 Subject: [PATCH 152/285] Simplified iframe-webpack.config.js thanks to @ndelangen's feedback --- lib/builder-webpack4/src/index.ts | 9 +- .../src/presets/preview-preset.ts | 1 - .../src/preview/entries.test.ts | 68 --------------- lib/builder-webpack4/src/preview/entries.ts | 85 ------------------- .../src/preview/iframe-webpack.config.ts | 52 ++++++------ 5 files changed, 26 insertions(+), 189 deletions(-) delete mode 100644 lib/builder-webpack4/src/preview/entries.test.ts delete mode 100644 lib/builder-webpack4/src/preview/entries.ts diff --git a/lib/builder-webpack4/src/index.ts b/lib/builder-webpack4/src/index.ts index 9a96ce359d5..44284581dde 100644 --- a/lib/builder-webpack4/src/index.ts +++ b/lib/builder-webpack4/src/index.ts @@ -10,7 +10,6 @@ import { checkWebpackVersion, Options, loadPreviewOrConfigFile, - normalizeStories, } from '@storybook/core-common'; let compilation: ReturnType; @@ -33,11 +32,7 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { const { presets } = options; const typescriptOptions = await presets.apply('typescript', {}, options); const babelOptions = await presets.apply('babel', {}, { ...options, typescriptOptions }); - const entries = await presets.apply('entries', [], options); - const stories = normalizeStories(await presets.apply('stories', [], options), { - configDir: options.configDir, - workingDir: process.cwd(), - }); + const frameworkOptions = await presets.apply(`${options.framework}Options`, {}, options); const configs = [ @@ -51,9 +46,7 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { { ...options, babelOptions, - entries, configs, - stories, typescriptOptions, [`${options.framework}Options`]: frameworkOptions, } diff --git a/lib/builder-webpack4/src/presets/preview-preset.ts b/lib/builder-webpack4/src/presets/preview-preset.ts index 2a341a446ba..de1bed3c45b 100644 --- a/lib/builder-webpack4/src/presets/preview-preset.ts +++ b/lib/builder-webpack4/src/presets/preview-preset.ts @@ -1,5 +1,4 @@ import webpackConfig from '../preview/iframe-webpack.config'; -import { createPreviewEntry } from '../preview/entries'; export const webpack = async (_: any, options: any) => webpackConfig(options); diff --git a/lib/builder-webpack4/src/preview/entries.test.ts b/lib/builder-webpack4/src/preview/entries.test.ts deleted file mode 100644 index cb1ee0a5d1d..00000000000 --- a/lib/builder-webpack4/src/preview/entries.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { sortEntries } from './entries'; - -describe('sortEntries', () => { - it('should do nothing', () => { - const input = ['a', 'b', 'c', 'aa', 'cc', '123', '8000']; - const output = sortEntries(input); - - expect(output).toEqual(['a', 'b', 'c', 'aa', 'cc', '123', '8000']); - }); - it('should move preview-type generated-config entries after all other generated entries', () => { - const input = [ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/web-components-kitchen-sink/.storybook/storybook-init-framework-entry.js', - 'examples/web-components-kitchen-sink/.storybook/preview.js-generated-config-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/web-components/config.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - ]; - const output = sortEntries(input); - expect(output).toEqual([ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/web-components-kitchen-sink/.storybook/storybook-init-framework-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/web-components/config.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - 'examples/web-components-kitchen-sink/.storybook/preview.js-generated-config-entry.js', - ]); - }); - it('should move stories-type after all other generated entries', () => { - const input = [ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/official-storybook/storybook-init-framework-entry.js', - 'examples/official-storybook/preview.js-generated-config-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/react/config.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/queryparams/dist/preset/addDecorator.js-generated-other-entry.js', - 'examples/official-storybook/generated-stories-entry.js', - ]; - const output = sortEntries(input); - expect(output).toEqual([ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/official-storybook/storybook-init-framework-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/react/config.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/queryparams/dist/preset/addDecorator.js-generated-other-entry.js', - 'examples/official-storybook/preview.js-generated-config-entry.js', - 'examples/official-storybook/generated-stories-entry.js', - ]); - }); -}); diff --git a/lib/builder-webpack4/src/preview/entries.ts b/lib/builder-webpack4/src/preview/entries.ts deleted file mode 100644 index a23fc97bd37..00000000000 --- a/lib/builder-webpack4/src/preview/entries.ts +++ /dev/null @@ -1,85 +0,0 @@ -import path from 'path'; -import { logger } from '@storybook/node-logger'; -import stable from 'stable'; -import dedent from 'ts-dedent'; -import glob from 'glob-promise'; -import { loadPreviewOrConfigFile, normalizeStories } from '@storybook/core-common'; - -export const sortEntries = (entries: string[]) => { - const isGenerated = /generated-(config|other)-entry/; - const isGeneratedConfig = /(?:preview|config)\..+-generated-config-entry/; - - return stable(entries.slice(0), (a, b) => { - // We need to ensure that all parameters and decorators that are added by preview entry-points added by addons happen before any configure() calls executed by the user's preview.js (or config.js), or by main.js:stories. - // As those addons will create generated entries, this means we need to ensure all generated entries come before all other entries (generated or otherwise). - - switch (true) { - case !!a.match(isGeneratedConfig) && !!b.match(isGenerated): { - return 1; - } - case !!b.match(isGeneratedConfig) && !!a.match(isGenerated): { - return -1; - } - default: { - return 0; - } - } - }); -}; - -const getMainConfigs = (options: { configDir: string }) => { - const previewPath = loadPreviewOrConfigFile(options); - return previewPath ? [previewPath] : []; -}; - -export async function createPreviewEntry(options: { configDir: string; presets: any }) { - const { configDir, presets } = options; - const entries = [ - ...(await presets.apply('previewEntries', [], options)), - path.resolve(path.join(configDir, 'storybook-init-framework-entry.js')), - ]; - - const configs = getMainConfigs(options); - const other: string[] = await presets.apply('config', [], options); - const stories = normalizeStories(await presets.apply('stories', [], options), { - configDir: options.configDir, - workingDir: process.cwd(), - }); - - if (configs.length > 0) { - const noun = configs.length === 1 ? 'file' : 'files'; - logger.info(`=> Loading ${configs.length} config ${noun} in "${configDir}"`); - entries.push(...configs.map((filename) => `${filename}-generated-config-entry.js`)); - } - - if (other && other.length > 0) { - const noun = other.length === 1 ? 'file' : 'files'; - logger.info(`=> Loading ${other.length} other ${noun} in "${configDir}"`); - entries.push(...other.map((filename: string) => `${filename}-generated-other-entry.js`)); - } - console.log(configs, other, entries); - - if (stories && stories.length) { - entries.push(path.resolve(path.join(configDir, `generated-stories-entry.js`))); - - const globs = stories.map((s) => s.glob); - const files = ( - await Promise.all(globs.map((g) => glob(path.isAbsolute(g) ? g : path.join(configDir, g)))) - ).reduce((a, b) => a.concat(b)); - - if (files.length === 0) { - logger.warn(dedent` - We found no files matching any of the following globs: - - ${globs.join('\n')} - - Maybe your glob was invalid? - see: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#correct-globs-in-mainjs - `); - } else { - logger.info(`=> Adding stories defined in "${path.join(configDir, 'main.js')}"`); - } - } - - return sortEntries(entries); -} diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index 3a1e9a1f03d..88ee0d5cf73 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -13,10 +13,8 @@ import PnpWebpackPlugin from 'pnp-webpack-plugin'; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; // @ts-ignore import FilterWarningsPlugin from 'webpack-filter-warnings-plugin'; -import dedent from 'ts-dedent'; import themingPaths from '@storybook/theming/paths'; - import { toRequireContextString, stringifyEnvs, @@ -27,6 +25,7 @@ import { Options, NormalizedStoriesEntry, toImportFn, + normalizeStories, } from '@storybook/core-common'; import { createBabelLoader } from './babel-loader-preview'; @@ -62,23 +61,22 @@ async function readTemplate(filename: string) { }); } -export default async ({ - configDir, - babelOptions, - entries, - configs, - stories, - outputDir = path.join('.', 'public'), - quiet, - packageJson, - configType, - framework, - frameworkPath, - presets, - typescriptOptions, - modern, - features, -}: Options & Record): Promise => { +export default async (options: Options & Record): Promise => { + const { + configDir, + babelOptions, + configs, + outputDir = path.join('.', 'public'), + quiet, + packageJson, + configType, + framework, + frameworkPath, + presets, + typescriptOptions, + modern, + features, + } = options; const logLevel = await presets.apply('logLevel', undefined); const frameworkOptions = await presets.apply(`${framework}Options`, {}); @@ -91,6 +89,12 @@ export default async ({ const isProd = configType === 'PRODUCTION'; const configEntryPath = path.resolve(path.join(configDir, 'storybook-config-entry.js')); + const entries = (await presets.apply('entries', [], options)) as string[]; + const stories = normalizeStories(await presets.apply('stories', [], options), { + configDir: options.configDir, + workingDir: process.cwd(), + }); + const virtualModuleMapping: Record = {}; if (features?.storyStoreV7) { const storiesFilename = 'storybook-stories.js'; @@ -145,12 +149,6 @@ export default async ({ } } - Object.entries(virtualModuleMapping).forEach(([filePath, file]) => { - console.log(filePath); - console.log(); - console.log(file); - }); - const shouldCheckTs = useBaseTsSupport(framework) && typescriptOptions.check; const tsCheckOptions = typescriptOptions.checkOptions || {}; @@ -182,10 +180,10 @@ export default async ({ chunksSortMode: 'none' as any, alwaysWriteToDisk: true, inject: false, - templateParameters: (compilation, files, options) => ({ + templateParameters: (compilation, files, templateOptions) => ({ compilation, files, - options, + options: templateOptions, version: packageJson.version, globals: { LOGLEVEL: logLevel, From 7eaf944bd98ee3c5f945f55ed1cf038745d498a2 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 11:42:02 +1000 Subject: [PATCH 153/285] Bring wp4 changes over to wp5 --- lib/builder-webpack4/package.json | 1 - lib/builder-webpack4/src/index.ts | 8 - .../src/preview/iframe-webpack.config.ts | 18 +-- lib/builder-webpack5/package.json | 1 - lib/builder-webpack5/src/index.ts | 12 -- .../src/presets/preview-preset.ts | 3 +- .../src/preview/entries.test.ts | 68 --------- lib/builder-webpack5/src/preview/entries.ts | 84 ----------- .../src/preview/iframe-webpack.config.ts | 137 +++++++++++------- lib/core-common/package.json | 1 + lib/core-common/src/index.ts | 1 + lib/core-common/src/utils/readTemplate.ts | 8 + yarn.lock | 3 +- 13 files changed, 101 insertions(+), 244 deletions(-) delete mode 100644 lib/builder-webpack5/src/preview/entries.test.ts delete mode 100644 lib/builder-webpack5/src/preview/entries.ts create mode 100644 lib/core-common/src/utils/readTemplate.ts diff --git a/lib/builder-webpack4/package.json b/lib/builder-webpack4/package.json index 2c02fe95321..96bca7a4aee 100644 --- a/lib/builder-webpack4/package.json +++ b/lib/builder-webpack4/package.json @@ -88,7 +88,6 @@ "file-loader": "^6.2.0", "find-up": "^5.0.0", "fork-ts-checker-webpack-plugin": "^4.1.6", - "fs-extra": "^9.0.1", "glob": "^7.1.6", "glob-promise": "^3.4.0", "global": "^4.4.0", diff --git a/lib/builder-webpack4/src/index.ts b/lib/builder-webpack4/src/index.ts index 44284581dde..57d8409affc 100644 --- a/lib/builder-webpack4/src/index.ts +++ b/lib/builder-webpack4/src/index.ts @@ -9,7 +9,6 @@ import { useProgressReporting, checkWebpackVersion, Options, - loadPreviewOrConfigFile, } from '@storybook/core-common'; let compilation: ReturnType; @@ -32,21 +31,14 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { const { presets } = options; const typescriptOptions = await presets.apply('typescript', {}, options); const babelOptions = await presets.apply('babel', {}, { ...options, typescriptOptions }); - const frameworkOptions = await presets.apply(`${options.framework}Options`, {}, options); - const configs = [ - loadPreviewOrConfigFile(options), - ...(await presets.apply('config', [], options)), - ].filter(Boolean); - return presets.apply( 'webpack', {}, { ...options, babelOptions, - configs, typescriptOptions, [`${options.framework}Options`]: frameworkOptions, } diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index 88ee0d5cf73..1d02f01ad3b 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -1,5 +1,4 @@ import path from 'path'; -import fse from 'fs-extra'; import { DefinePlugin, HotModuleReplacementPlugin, ProgressPlugin } from 'webpack'; import Dotenv from 'dotenv-webpack'; // @ts-ignore @@ -26,6 +25,8 @@ import { NormalizedStoriesEntry, toImportFn, normalizeStories, + loadPreviewOrConfigFile, + readTemplate, } from '@storybook/core-common'; import { createBabelLoader } from './babel-loader-preview'; @@ -54,18 +55,10 @@ const storybookPaths: Record = [ }), {} ); - -async function readTemplate(filename: string) { - return fse.readFile(path.join(__dirname, filename), { - encoding: 'utf8', - }); -} - export default async (options: Options & Record): Promise => { const { configDir, babelOptions, - configs, outputDir = path.join('.', 'public'), quiet, packageJson, @@ -87,7 +80,11 @@ export default async (options: Options & Record): Promise): Promise; @@ -20,14 +18,6 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { const { presets } = options; const typescriptOptions = await presets.apply('typescript', {}, options); const babelOptions = await presets.apply('babel', {}, { ...options, typescriptOptions }); - const entries = await presets.apply('entries', [], options); - const stories = normalizeStories( - (await presets.apply('stories', [], options)) as StoriesEntry[], - { - configDir: options.configDir, - workingDir: process.cwd(), - } - ); const frameworkOptions = await presets.apply(`${options.framework}Options`, {}, options); return presets.apply( @@ -36,8 +26,6 @@ export const getConfig: WebpackBuilder['getConfig'] = async (options) => { { ...options, babelOptions, - entries, - stories, typescriptOptions, [`${options.framework}Options`]: frameworkOptions, } diff --git a/lib/builder-webpack5/src/presets/preview-preset.ts b/lib/builder-webpack5/src/presets/preview-preset.ts index af6d14441e8..fa077fdc13e 100644 --- a/lib/builder-webpack5/src/presets/preview-preset.ts +++ b/lib/builder-webpack5/src/presets/preview-preset.ts @@ -1,12 +1,11 @@ import webpackConfig from '../preview/iframe-webpack.config'; -import { createPreviewEntry } from '../preview/entries'; export const webpack = async (_: unknown, options: any) => webpackConfig(options); export const entries = async (_: unknown, options: any) => { let result: string[] = []; - result = result.concat(await createPreviewEntry(options)); + result = result.concat(await options.presets.apply('previewEntries', [], options)); if (options.configType === 'DEVELOPMENT') { // Suppress informational messages when --quiet is specified. webpack-hot-middleware's quiet diff --git a/lib/builder-webpack5/src/preview/entries.test.ts b/lib/builder-webpack5/src/preview/entries.test.ts deleted file mode 100644 index cb1ee0a5d1d..00000000000 --- a/lib/builder-webpack5/src/preview/entries.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { sortEntries } from './entries'; - -describe('sortEntries', () => { - it('should do nothing', () => { - const input = ['a', 'b', 'c', 'aa', 'cc', '123', '8000']; - const output = sortEntries(input); - - expect(output).toEqual(['a', 'b', 'c', 'aa', 'cc', '123', '8000']); - }); - it('should move preview-type generated-config entries after all other generated entries', () => { - const input = [ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/web-components-kitchen-sink/.storybook/storybook-init-framework-entry.js', - 'examples/web-components-kitchen-sink/.storybook/preview.js-generated-config-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/web-components/config.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - ]; - const output = sortEntries(input); - expect(output).toEqual([ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/web-components-kitchen-sink/.storybook/storybook-init-framework-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/web-components/config.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - 'examples/web-components-kitchen-sink/.storybook/preview.js-generated-config-entry.js', - ]); - }); - it('should move stories-type after all other generated entries', () => { - const input = [ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/official-storybook/storybook-init-framework-entry.js', - 'examples/official-storybook/preview.js-generated-config-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/react/config.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/queryparams/dist/preset/addDecorator.js-generated-other-entry.js', - 'examples/official-storybook/generated-stories-entry.js', - ]; - const output = sortEntries(input); - expect(output).toEqual([ - 'lib/core-client/dist/esm/common/polyfills.js', - 'lib/core-client/dist/esm/preview/globals.js', - 'examples/official-storybook/storybook-init-framework-entry.js', - 'addons/docs/dist/frameworks/common/config.js-generated-other-entry.js', - 'addons/docs/dist/frameworks/react/config.js-generated-other-entry.js', - 'addons/actions/dist/preset/addArgs.js-generated-other-entry.js', - 'addons/links/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js', - 'addons/queryparams/dist/preset/addDecorator.js-generated-other-entry.js', - 'examples/official-storybook/preview.js-generated-config-entry.js', - 'examples/official-storybook/generated-stories-entry.js', - ]); - }); -}); diff --git a/lib/builder-webpack5/src/preview/entries.ts b/lib/builder-webpack5/src/preview/entries.ts deleted file mode 100644 index cfa8984b1a0..00000000000 --- a/lib/builder-webpack5/src/preview/entries.ts +++ /dev/null @@ -1,84 +0,0 @@ -import path from 'path'; -import { logger } from '@storybook/node-logger'; -import stable from 'stable'; -import dedent from 'ts-dedent'; -import glob from 'glob-promise'; -import { loadPreviewOrConfigFile, normalizeStories } from '@storybook/core-common'; - -export const sortEntries = (entries: string[]) => { - const isGenerated = /generated-(config|other)-entry/; - const isGeneratedConfig = /(?:preview|config)\..+-generated-config-entry/; - - return stable(entries.slice(0), (a, b) => { - // We need to ensure that all parameters and decorators that are added by preview entry-points added by addons happen before any configure() calls executed by the user's preview.js (or config.js), or by main.js:stories. - // As those addons will create generated entries, this means we need to ensure all generated entries come before all other entries (generated or otherwise). - - switch (true) { - case !!a.match(isGeneratedConfig) && !!b.match(isGenerated): { - return 1; - } - case !!b.match(isGeneratedConfig) && !!a.match(isGenerated): { - return -1; - } - default: { - return 0; - } - } - }); -}; - -const getMainConfigs = (options: { configDir: string }) => { - const previewPath = loadPreviewOrConfigFile(options); - return previewPath ? [previewPath] : []; -}; - -export async function createPreviewEntry(options: { configDir: string; presets: any }) { - const { configDir, presets } = options; - const entries = [ - ...(await presets.apply('previewEntries', [], options)), - path.resolve(path.join(configDir, 'storybook-init-framework-entry.js')), - ]; - - const configs = getMainConfigs(options); - const other: string[] = await presets.apply('config', [], options); - const stories = normalizeStories(await presets.apply('stories', [], options), { - configDir: options.configDir, - workingDir: process.cwd(), - }); - - if (configs.length > 0) { - const noun = configs.length === 1 ? 'file' : 'files'; - logger.info(`=> Loading ${configs.length} config ${noun} in "${configDir}"`); - entries.push(...configs.map((filename) => `${filename}-generated-config-entry.js`)); - } - - if (other && other.length > 0) { - const noun = other.length === 1 ? 'file' : 'files'; - logger.info(`=> Loading ${other.length} other ${noun} in "${configDir}"`); - entries.push(...other.map((filename: string) => `${filename}-generated-other-entry.js`)); - } - - if (stories && stories.length) { - entries.push(path.resolve(path.join(configDir, `generated-stories-entry.js`))); - - const globs = stories.map((s) => s.glob); - const files = ( - await Promise.all(globs.map((g) => glob(path.isAbsolute(g) ? g : path.join(configDir, g)))) - ).reduce((a, b) => a.concat(b)); - - if (files.length === 0) { - logger.warn(dedent` - We found no files matching any of the following globs: - - ${globs.join('\n')} - - Maybe your glob was invalid? - see: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#correct-globs-in-mainjs - `); - } else { - logger.info(`=> Adding stories defined in "${path.join(configDir, 'main.js')}"`); - } - } - - return sortEntries(entries); -} diff --git a/lib/builder-webpack5/src/preview/iframe-webpack.config.ts b/lib/builder-webpack5/src/preview/iframe-webpack.config.ts index 6a2b7618352..4ede2781c42 100644 --- a/lib/builder-webpack5/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack5/src/preview/iframe-webpack.config.ts @@ -1,5 +1,4 @@ import path from 'path'; -import fse from 'fs-extra'; import { Configuration, DefinePlugin, HotModuleReplacementPlugin, ProgressPlugin } from 'webpack'; import Dotenv from 'dotenv-webpack'; import HtmlWebpackPlugin from 'html-webpack-plugin'; @@ -16,10 +15,15 @@ import { es6Transpiler, stringifyEnvs, nodeModulesPaths, + handlebars, interpolate, Options, hasDotenv, NormalizedStoriesEntry, + toImportFn, + normalizeStories, + readTemplate, + loadPreviewOrConfigFile, } from '@storybook/core-common'; import { createBabelLoader } from './babel-loader-preview'; @@ -47,22 +51,21 @@ const storybookPaths: Record = [ {} ); -export default async ({ - configDir, - babelOptions, - entries, - stories, - outputDir = path.join('.', 'public'), - quiet, - packageJson, - configType, - framework, - frameworkPath, - presets, - typescriptOptions, - modern, - features, -}: Options & Record): Promise => { +export default async (options: Options & Record): Promise => { + const { + configDir, + babelOptions, + outputDir = path.join('.', 'public'), + quiet, + packageJson, + configType, + framework, + frameworkPath, + presets, + typescriptOptions, + modern, + features, + } = options; const envs = await presets.apply>('env'); const logLevel = await presets.apply('logLevel', undefined); const frameworkOptions = await presets.apply(`${framework}Options`, {}); @@ -73,48 +76,70 @@ export default async ({ const babelLoader = createBabelLoader(babelOptions, framework); const isProd = configType === 'PRODUCTION'; - // TODO FIX ME - does this need to be ESM? - const entryTemplate = await fse.readFile(path.join(__dirname, 'virtualModuleEntry.template.js'), { - encoding: 'utf8', - }); - const storyTemplate = await fse.readFile(path.join(__dirname, 'virtualModuleStory.template.js'), { - encoding: 'utf8', + + const configs = [ + loadPreviewOrConfigFile(options), + ...(await presets.apply('config', [], options)), + ].filter(Boolean); + const entries = (await presets.apply('entries', [], options)) as string[]; + const stories = normalizeStories(await presets.apply('stories', [], options), { + configDir: options.configDir, + workingDir: process.cwd(), }); - const frameworkInitEntry = path.resolve( - path.join(configDir, 'storybook-init-framework-entry.js') - ); - // Allows for custom frameworks that are not published under the @storybook namespace - const frameworkImportPath = frameworkPath || `@storybook/${framework}`; - const virtualModuleMapping = { - // Ensure that the client API is initialized by the framework before any other iframe code - // is loaded. That way our client-apis can assume the existence of the API+store - [frameworkInitEntry]: `import '${frameworkImportPath}';`, - }; - entries.forEach((entryFilename: any) => { - const match = entryFilename.match(/(.*)-generated-(config|other)-entry.js$/); - if (match) { - const configFilename = match[1]; + + const virtualModuleMapping: Record = {}; + if (features?.storyStoreV7) { + const storiesFilename = 'storybook-stories.js'; + const storiesPath = path.resolve(path.join(configDir, storiesFilename)); + + virtualModuleMapping[storiesPath] = toImportFn(stories); + const configEntryPath = path.resolve(path.join(configDir, 'storybook-config-entry.js')); + virtualModuleMapping[configEntryPath] = handlebars( + await readTemplate('virtualModuleModernEntry.js.handlebars'), + { + storiesFilename, + configs, + } + ); + entries.push(configEntryPath); + } else { + const frameworkInitEntry = path.resolve( + path.join(configDir, 'storybook-init-framework-entry.js') + ); + const frameworkImportPath = frameworkPath || `@storybook/${framework}`; + virtualModuleMapping[frameworkInitEntry] = `import '${frameworkImportPath}';`; + entries.push(frameworkInitEntry); + + const entryTemplate = await readTemplate('virtualModuleEntry.template.js'); + + configs.forEach((configFilename: any) => { const clientApi = storybookPaths['@storybook/client-api']; const clientLogger = storybookPaths['@storybook/client-logger']; - virtualModuleMapping[entryFilename] = interpolate(entryTemplate, { - configFilename, - clientApi, - clientLogger, - }); - } - }); - if (stories) { - const storiesFilename = path.resolve(path.join(configDir, `generated-stories-entry.js`)); - virtualModuleMapping[storiesFilename] = interpolate(storyTemplate, { frameworkImportPath }) - // Make sure we also replace quotes for this one - .replace( - "'{{stories}}'", - stories - .map((s: NormalizedStoriesEntry) => s.glob) - .map(toRequireContextString) - .join(',') + virtualModuleMapping[`${configFilename}-generated-config-entry.js`] = interpolate( + entryTemplate, + { + configFilename, + clientApi, + clientLogger, + } ); + entries.push(`${configFilename}-generated-config-entry.js`); + }); + if (stories) { + const storyTemplate = await readTemplate('virtualModuleStory.template.js'); + const storiesFilename = path.resolve(path.join(configDir, `generated-stories-entry.js`)); + virtualModuleMapping[storiesFilename] = interpolate(storyTemplate, { frameworkImportPath }) + // Make sure we also replace quotes for this one + .replace( + "'{{stories}}'", + stories + .map((s: NormalizedStoriesEntry) => s.glob) + .map(toRequireContextString) + .join(',') + ); + entries.push(storiesFilename); + } } const shouldCheckTs = useBaseTsSupport(framework) && typescriptOptions.check; @@ -153,10 +178,10 @@ export default async ({ chunksSortMode: 'none' as any, alwaysWriteToDisk: true, inject: false, - templateParameters: (compilation, files, options) => ({ + templateParameters: (compilation, files, templateOptions) => ({ compilation, files, - options, + options: templateOptions, version: packageJson.version, globals: { LOGLEVEL: logLevel, diff --git a/lib/core-common/package.json b/lib/core-common/package.json index 63bb9c98476..0eb714b89e1 100644 --- a/lib/core-common/package.json +++ b/lib/core-common/package.json @@ -76,6 +76,7 @@ "file-system-cache": "^1.0.5", "find-up": "^5.0.0", "fork-ts-checker-webpack-plugin": "^6.0.4", + "fs-extra": "^9.0.1", "glob": "^7.1.6", "glob-base": "^0.3.0", "handlebars": "^4.7.7", diff --git a/lib/core-common/src/index.ts b/lib/core-common/src/index.ts index aa612d9dd29..3c71fc62068 100644 --- a/lib/core-common/src/index.ts +++ b/lib/core-common/src/index.ts @@ -25,5 +25,6 @@ export * from './utils/to-require-context'; export * from './utils/has-dotenv'; export * from './utils/normalize-stories'; export * from './utils/to-importFn'; +export * from './utils/readTemplate'; export * from './types'; diff --git a/lib/core-common/src/utils/readTemplate.ts b/lib/core-common/src/utils/readTemplate.ts new file mode 100644 index 00000000000..b7485cf93b2 --- /dev/null +++ b/lib/core-common/src/utils/readTemplate.ts @@ -0,0 +1,8 @@ +import path from 'path'; +import fse from 'fs-extra'; + +export async function readTemplate(filename: string) { + return fse.readFile(path.join(__dirname, filename), { + encoding: 'utf8', + }); +} diff --git a/yarn.lock b/yarn.lock index 9783a923a6f..7ac6d4b0607 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6326,7 +6326,6 @@ __metadata: file-loader: ^6.2.0 find-up: ^5.0.0 fork-ts-checker-webpack-plugin: ^4.1.6 - fs-extra: ^9.0.1 glob: ^7.1.6 glob-promise: ^3.4.0 global: ^4.4.0 @@ -6410,7 +6409,6 @@ __metadata: css-loader: ^5.0.1 dotenv-webpack: ^7.0.0 fork-ts-checker-webpack-plugin: ^6.0.4 - fs-extra: ^9.0.1 glob: ^7.1.6 glob-promise: ^3.4.0 html-webpack-plugin: ^5.0.0 @@ -6687,6 +6685,7 @@ __metadata: file-system-cache: ^1.0.5 find-up: ^5.0.0 fork-ts-checker-webpack-plugin: ^6.0.4 + fs-extra: ^9.0.1 glob: ^7.1.6 glob-base: ^0.3.0 handlebars: ^4.7.7 From 0277d2d4b3f711db9052163c20f4352e6cc25bf3 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 11:44:01 +1000 Subject: [PATCH 154/285] Remove incomplete tests for `to-importFn` I want to revisit `to-importFn` as part of integrating the dynamic stories list server, and so will leave it without tests for now. --- .../src/utils/__tests__/require-test-cases.ts | 169 ----------------- .../src/utils/__tests__/to-importFn.test.ts | 28 --- .../__tests__/to-require-context.test.ts | 170 +++++++++++++++++- 3 files changed, 169 insertions(+), 198 deletions(-) delete mode 100644 lib/core-common/src/utils/__tests__/require-test-cases.ts delete mode 100644 lib/core-common/src/utils/__tests__/to-importFn.test.ts diff --git a/lib/core-common/src/utils/__tests__/require-test-cases.ts b/lib/core-common/src/utils/__tests__/require-test-cases.ts deleted file mode 100644 index b661d2bc523..00000000000 --- a/lib/core-common/src/utils/__tests__/require-test-cases.ts +++ /dev/null @@ -1,169 +0,0 @@ -export const testCases = [ - { - glob: '**/*.stories.tsx', - recursive: true, - validPaths: [ - './Icon.stories.tsx', - './src/Icon.stories.tsx', - './src/components/Icon.stories.tsx', - './src/components/Icon.stories/Icon.stories.tsx', - ], - invalidPaths: [ - './stories.tsx', - './Icon.stories.ts', - './Icon.stories.js', - './src/components/stories.tsx', - './src/components/Icon.stories/stories.tsx', - './src/components/Icon.stories.ts', - './src/components/Icon.stories.js', - ], - }, - // INVALID GLOB - { - glob: '../src/stories/**/*.stories.(js|mdx)', - recursive: true, - validPaths: [ - '../src/stories/components/Icon.stories.js', - '../src/stories/Icon.stories.js', - '../src/stories/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.js', - '../src/stories/components/Icon.stories/Icon.stories.mdx', - ], - invalidPaths: [ - './stories.js', - './src/stories/Icon.stories.js', - './Icon.stories.js', - '../src/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.mdx', - ], - }, - { - glob: 'dirname/../stories/*.stories.*', - recursive: false, - validPaths: [ - './dirname/../stories/App.stories.js', - './dirname/../stories/addon-centered.stories.js', - ], - invalidPaths: ['./dirname/../stories.js', './dirname/../App.stories.js'], - }, - { - glob: '../src/stories/**/@(*.stories.js|*.stories.mdx)', - recursive: true, - validPaths: [ - '../src/stories/components/Icon.stories.js', - '../src/stories/Icon.stories.js', - '../src/stories/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.js', - '../src/stories/components/Icon.stories/Icon.stories.mdx', - ], - invalidPaths: [ - './stories.js', - './src/stories/Icon.stories.js', - './Icon.stories.js', - '../src/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.mdx', - ], - }, - { - glob: '../src/stories/**/*.stories.+(js|mdx)', - recursive: true, - validPaths: [ - '../src/stories/components/Icon.stories.js', - '../src/stories/Icon.stories.js', - '../src/stories/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.js', - '../src/stories/components/Icon.stories/Icon.stories.mdx', - ], - invalidPaths: [ - './stories.js', - './src/stories/Icon.stories.js', - './Icon.stories.js', - '../src/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.mdx', - ], - }, - { - glob: '../src/stories/**/*.stories.*(js|mdx)', - recursive: true, - validPaths: [ - '../src/stories/components/Icon.stories.js', - '../src/stories/Icon.stories.js', - '../src/stories/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.js', - '../src/stories/components/Icon.stories/Icon.stories.mdx', - ], - invalidPaths: [ - './stories.js', - './src/stories/Icon.stories.js', - './Icon.stories.js', - '../src/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.mdx', - ], - }, - // DUMB GLOB - { - glob: '../src/stories/**/*.stories.[tj]sx', - recursive: true, - validPaths: [ - '../src/stories/components/Icon.stories.jsx', - '../src/stories/Icon.stories.jsx', - '../src/stories/Icon.stories.tsx', - '../src/stories/components/Icon/Icon.stories.jsx', - '../src/stories/components/Icon.stories/Icon.stories.tsx', - ], - invalidPaths: [ - './stories.jsx', - './src/stories/Icon.stories.jsx', - './Icon.stories.jsx', - '../src/Icon.stories.tsx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.tsx', - ], - }, - { - glob: '../components/*.stories.js', - recursive: false, - validPaths: ['../components/Icon.stories.js'], - invalidPaths: [ - '../components/icon/node_modules/icon/Icon.stories.js', - './stories.js', - './src/stories/Icon.stories.js', - './Icon.stories.js', - '../src/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.mdx', - ], - }, - { - glob: '../components/*/*.stories.js', - recursive: true, - validPaths: ['../components/icon/Icon.stories.js'], - invalidPaths: [ - '../components/icon/node_modules/icon/Icon.stories.js', - './stories.js', - './src/stories/Icon.stories.js', - './Icon.stories.js', - '../src/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.mdx', - ], - }, - { - glob: '../components/*/stories/*.js', - recursive: true, - validPaths: ['../components/icon/stories/Icon.js'], - invalidPaths: [ - '../components/icon/node_modules/icon/stories/Icon.js', - './stories.js', - './src/stories/Icon.stories.js', - './Icon.stories.js', - '../src/Icon.stories.mdx', - '../src/stories/components/Icon/Icon.stories.ts', - '../src/stories/components/Icon/Icon.mdx', - ], - }, -]; diff --git a/lib/core-common/src/utils/__tests__/to-importFn.test.ts b/lib/core-common/src/utils/__tests__/to-importFn.test.ts deleted file mode 100644 index 1db94705119..00000000000 --- a/lib/core-common/src/utils/__tests__/to-importFn.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createContext, runInContext } from 'vm'; - -import { toImportFn } from '../to-importFn'; -import { testCases } from './require-test-cases'; - -describe('toImportFn', () => { - testCases.forEach(({ glob, validPaths, invalidPaths }) => { - it(`matches only suitable paths - ${glob}`, () => { - const importFnString = toImportFn([{ glob }]); - - const code = ` - ${importFnString.replace('export', '').replace('import(', 'importMock(')}; - importFn(testCase) ; - `; - - validPaths.forEach((testCase) => { - const importMock = jest.fn(); - - eval(code); - - // const pathWithoutLeadingSlash = path.substring(2); - // const context = createContext({ import: importMock, testCase: pathWithoutLeadingSlash }); - // runInContext(code, context); - expect(importMock).toHaveBeenCalledWith(testCase); - }); - }); - }); -}); diff --git a/lib/core-common/src/utils/__tests__/to-require-context.test.ts b/lib/core-common/src/utils/__tests__/to-require-context.test.ts index 4ad7f1cfa46..21640243daa 100644 --- a/lib/core-common/src/utils/__tests__/to-require-context.test.ts +++ b/lib/core-common/src/utils/__tests__/to-require-context.test.ts @@ -1,7 +1,175 @@ import path from 'path'; import { toRequireContext } from '../to-require-context'; -import { testCases } from './require-test-cases'; +const testCases = [ + { + glob: '**/*.stories.tsx', + recursive: true, + validPaths: [ + './Icon.stories.tsx', + './src/Icon.stories.tsx', + './src/components/Icon.stories.tsx', + './src/components/Icon.stories/Icon.stories.tsx', + ], + invalidPaths: [ + './stories.tsx', + './Icon.stories.ts', + './Icon.stories.js', + './src/components/stories.tsx', + './src/components/Icon.stories/stories.tsx', + './src/components/Icon.stories.ts', + './src/components/Icon.stories.js', + ], + }, + // INVALID GLOB + { + glob: '../src/stories/**/*.stories.(js|mdx)', + recursive: true, + validPaths: [ + '../src/stories/components/Icon.stories.js', + '../src/stories/Icon.stories.js', + '../src/stories/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.js', + '../src/stories/components/Icon.stories/Icon.stories.mdx', + ], + invalidPaths: [ + './stories.js', + './src/stories/Icon.stories.js', + './Icon.stories.js', + '../src/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.mdx', + ], + }, + { + glob: 'dirname/../stories/*.stories.*', + recursive: false, + validPaths: [ + './dirname/../stories/App.stories.js', + './dirname/../stories/addon-centered.stories.js', + ], + invalidPaths: ['./dirname/../stories.js', './dirname/../App.stories.js'], + }, + { + glob: '../src/stories/**/@(*.stories.js|*.stories.mdx)', + recursive: true, + validPaths: [ + '../src/stories/components/Icon.stories.js', + '../src/stories/Icon.stories.js', + '../src/stories/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.js', + '../src/stories/components/Icon.stories/Icon.stories.mdx', + ], + invalidPaths: [ + './stories.js', + './src/stories/Icon.stories.js', + './Icon.stories.js', + '../src/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.mdx', + ], + }, + { + glob: '../src/stories/**/*.stories.+(js|mdx)', + recursive: true, + validPaths: [ + '../src/stories/components/Icon.stories.js', + '../src/stories/Icon.stories.js', + '../src/stories/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.js', + '../src/stories/components/Icon.stories/Icon.stories.mdx', + ], + invalidPaths: [ + './stories.js', + './src/stories/Icon.stories.js', + './Icon.stories.js', + '../src/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.mdx', + ], + }, + { + glob: '../src/stories/**/*.stories.*(js|mdx)', + recursive: true, + validPaths: [ + '../src/stories/components/Icon.stories.js', + '../src/stories/Icon.stories.js', + '../src/stories/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.js', + '../src/stories/components/Icon.stories/Icon.stories.mdx', + ], + invalidPaths: [ + './stories.js', + './src/stories/Icon.stories.js', + './Icon.stories.js', + '../src/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.mdx', + ], + }, + // DUMB GLOB + { + glob: '../src/stories/**/*.stories.[tj]sx', + recursive: true, + validPaths: [ + '../src/stories/components/Icon.stories.jsx', + '../src/stories/Icon.stories.jsx', + '../src/stories/Icon.stories.tsx', + '../src/stories/components/Icon/Icon.stories.jsx', + '../src/stories/components/Icon.stories/Icon.stories.tsx', + ], + invalidPaths: [ + './stories.jsx', + './src/stories/Icon.stories.jsx', + './Icon.stories.jsx', + '../src/Icon.stories.tsx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.tsx', + ], + }, + { + glob: '../components/*.stories.js', + recursive: false, + validPaths: ['../components/Icon.stories.js'], + invalidPaths: [ + '../components/icon/node_modules/icon/Icon.stories.js', + './stories.js', + './src/stories/Icon.stories.js', + './Icon.stories.js', + '../src/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.mdx', + ], + }, + { + glob: '../components/*/*.stories.js', + recursive: true, + validPaths: ['../components/icon/Icon.stories.js'], + invalidPaths: [ + '../components/icon/node_modules/icon/Icon.stories.js', + './stories.js', + './src/stories/Icon.stories.js', + './Icon.stories.js', + '../src/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.mdx', + ], + }, + { + glob: '../components/*/stories/*.js', + recursive: true, + validPaths: ['../components/icon/stories/Icon.js'], + invalidPaths: [ + '../components/icon/node_modules/icon/stories/Icon.js', + './stories.js', + './src/stories/Icon.stories.js', + './Icon.stories.js', + '../src/Icon.stories.mdx', + '../src/stories/components/Icon/Icon.stories.ts', + '../src/stories/components/Icon/Icon.mdx', + ], + }, +]; describe('toRequireContext', () => { testCases.forEach(({ glob, recursive, validPaths, invalidPaths }) => { From d28587dc0905142fec6fddba303a7fc4fd5fb473 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 11:46:34 +1000 Subject: [PATCH 155/285] Add a note about backcompat --- lib/store/src/StoryStore.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 9697e6fbbab..cfc04dc20de 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -44,7 +44,10 @@ function normalizeGlobalAnnotations({ argTypesEnhancers: [ ...(argTypesEnhancers || []), inferArgTypes, - // For backwards compatibilty reasons we add this, remove in 7.0 TODO -- explanation + // inferControls technically should only run if the user is using the controls addon, + // and so should be added by a preset there. However, as it seems some code relies on controls + // annotations (in particular the angular implementation's `cleanArgsDecorator`), for backwards + // compatibility reasons, we will leave this in the store until 7.0 inferControls, ], ...annotations, From c9e8fc3b8b8da376ca5789f91b92c31601187b01 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 11:47:12 +1000 Subject: [PATCH 156/285] Add template to wp5 builder --- .../virtualModuleModernEntry.js.handlebars | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars diff --git a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars new file mode 100644 index 00000000000..0e11ef12698 --- /dev/null +++ b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars @@ -0,0 +1,43 @@ +import { composeConfigs, WebPreview } from '@storybook/web-preview'; +import { importFn } from './{{storiesFilename}}'; +import { addons } from '@storybook/addons'; +import createChannel from '@storybook/channel-postmessage'; +import fetch from 'unfetch'; + +const getGlobalAnnotations = () => + composeConfigs([ + {{#each configs}} + require('{{this}}'), + {{/each}} + ]); + +const fetchStoriesList = async () => { + const result = await fetch('./stories.json'); + return result.json(); +} + +const channel = createChannel({ page: 'preview' }); +addons.setChannel(channel); +const preview = new WebPreview({ importFn, getGlobalAnnotations, fetchStoriesList }); + +window.__STORYBOOK_PREVIEW__ = preview; +window.__STORYBOOK_STORY_STORE__ = preview.storyStore; +window.__STORYBOOK_ADDONS_CHANNEL__ = channel; + +preview.initialize(); + +if (module.hot) { + module.hot.accept('./{{storiesFilename}}', () => { + console.log('configEntry HMR accept storybook-stories.js'); + console.log(arguments); + // importFn has changed so we need to patch the new one in + preview.onImportFnChanged({ importFn }); + }); + + module.hot.accept([{{#each configs}}'{{this}}',{{/each}}], () => { + console.log('configEntry HMR accept config file'); + console.log(arguments); + // getGlobalAnnotations has changed so we need to patch the new one in + preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations }); + }); +} From 3e3d2c050bd6d6c96e2121af234d43b1a5873eed Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 11:52:57 +1000 Subject: [PATCH 157/285] Add a test that `.extract()` filters docs-only --- lib/store/src/StoryStore.test.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index 47665953600..782bb9188be 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -1,3 +1,4 @@ +import { StoryId } from '@storybook/api'; import { AnyFramework, GlobalAnnotations } from '@storybook/csf'; import { HooksContext } from '../../addons/dist/ts3.9/hooks'; @@ -318,6 +319,33 @@ describe('StoryStore', () => { ] `); }); + + it('does not include docs only stories by default', async () => { + const docsOnlyImportFn = jest.fn(async (path) => { + return path === './src/ComponentOne.stories.js' + ? { + ...componentOneExports, + a: { ...componentOneExports.a, parameters: { docsOnly: true } }, + } + : componentTwoExports; + }); + const store = new StoryStore({ + importFn: docsOnlyImportFn, + globalAnnotations, + fetchStoriesList, + }); + await store.initialize(); + await store.cacheAllCSFFiles(); + + expect((store.extract() as { id: StoryId }[]).map((s) => s.id)).toEqual([ + 'component-one--b', + 'component-two--c', + ]); + + expect( + (store.extract({ includeDocsOnly: true }) as { id: StoryId }[]).map((s) => s.id) + ).toEqual(['component-one--a', 'component-one--b', 'component-two--c']); + }); }); describe('getSetStoriesPayload', () => { From 8abc869f07526b88ce0c7bbdb19df84b1d854585 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 11:55:22 +1000 Subject: [PATCH 158/285] Need to pick filenames carefully in configs --- .../src/preview/iframe-webpack.config.ts | 10 +++++++--- .../src/preview/iframe-webpack.config.ts | 10 +++++++--- lib/core-common/src/utils/readTemplate.ts | 3 +-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index 1d02f01ad3b..c94b8207b22 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -100,7 +100,7 @@ export default async (options: Options & Record): Promise): Promise { const clientApi = storybookPaths['@storybook/client-api']; @@ -132,7 +134,9 @@ export default async (options: Options & Record): Promise): Promise): Promise { const clientApi = storybookPaths['@storybook/client-api']; @@ -127,7 +129,9 @@ export default async (options: Options & Record): Promise Date: Sat, 4 Sep 2021 12:06:51 +1000 Subject: [PATCH 159/285] Added useStoryPrepared() hook --- lib/api/src/index.tsx | 5 +++++ lib/api/src/lib/stories.ts | 6 ++++-- lib/api/src/modules/stories.ts | 11 ++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/api/src/index.tsx b/lib/api/src/index.tsx index 99d68f98088..5cc04a32424 100644 --- a/lib/api/src/index.tsx +++ b/lib/api/src/index.tsx @@ -354,6 +354,11 @@ export const useChannel = (eventMap: EventMap, deps: any[] = []) => { return api.emit; }; +export function useStoryPrepared(storyId?: StoryId) { + const api = useStorybookApi(); + return api.isPrepared(storyId); +} + export function useParameter(parameterKey: string, defaultValue?: S) { const api = useStorybookApi(); diff --git a/lib/api/src/lib/stories.ts b/lib/api/src/lib/stories.ts index d0a11a3a143..db1bfc68b51 100644 --- a/lib/api/src/lib/stories.ts +++ b/lib/api/src/lib/stories.ts @@ -54,6 +54,7 @@ export interface Story { isRoot: false; isLeaf: true; renderLabel?: (item: Story) => React.ReactNode; + prepared: boolean; parameters?: { fileName: string; options: { @@ -178,12 +179,12 @@ export const transformStoriesListToStoriesHash = ( return acc; }, {} as StoriesRaw); - return transformStoriesRawToStoriesHash(input, { provider }); + return transformStoriesRawToStoriesHash(input, { provider, prepared: false }); }; export const transformStoriesRawToStoriesHash = ( input: StoriesRaw, - { provider }: { provider: Provider } + { provider, prepared = false }: { provider: Provider; prepared?: Story['prepared'] } ): StoriesHash => { const values = Object.values(input).filter(Boolean); const usesOldHierarchySeparator = values.some(({ kind }) => kind.match(/\.|\|/)); // dot or pipe @@ -272,6 +273,7 @@ export const transformStoriesRawToStoriesHash = ( isComponent: false, isRoot: false, renderLabel, + prepared, }; return acc; diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index 15399a262c2..fc36eaf396d 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -64,6 +64,7 @@ export interface SubAPI { jumpToComponent: (direction: Direction) => void; jumpToStory: (direction: Direction) => void; getData: (storyId: StoryId, refId?: string) => Story | Group; + isPrepared: (storyId: StoryId, refId?: string) => boolean; getParameters: ( storyId: StoryId | { storyId: StoryId; refId: string }, parameterName?: ParameterName @@ -126,6 +127,14 @@ export const init: ModuleFn = ({ return isRoot(result) ? undefined : result; }, + isPrepared: (storyId, refId) => { + const data = api.getData(storyId, refId); + if (data.isLeaf) { + return data.prepared; + } + // Groups are always prepared :shrug: + return true; + }, resolveStory: (storyId, refId) => { const { refs, storiesHash } = store.getState(); if (refId) { @@ -459,7 +468,7 @@ export const init: ModuleFn = ({ fullAPI.on(STORY_PREPARED, function handler({ id, ...update }) { const { ref } = getEventMetadata(this, fullAPI); - fullAPI.updateStory(id, update, ref); + fullAPI.updateStory(id, { ...update, prepared: true }, ref); }); fullAPI.on( From 8ec4124683ac0a7a6bd9d9003b3c9fdddccac10c Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 12:42:08 +1000 Subject: [PATCH 160/285] Fix global handling --- lib/api/src/modules/globals.ts | 19 ++++++------- lib/api/src/tests/globals.test.ts | 46 +++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/lib/api/src/modules/globals.ts b/lib/api/src/modules/globals.ts index 41b869fe944..da22e9c6290 100644 --- a/lib/api/src/modules/globals.ts +++ b/lib/api/src/modules/globals.ts @@ -1,14 +1,12 @@ import { SET_GLOBALS, UPDATE_GLOBALS, GLOBALS_UPDATED } from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; import deepEqual from 'fast-deep-equal'; +import { Globals, GlobalTypes } from '@storybook/csf'; -import { Args, ArgTypes, ModuleFn, useArgs } from '../index'; +import { ModuleFn } from '../index'; import { getEventMetadata } from '../lib/events'; -// TODO -- these types -type Globals = Args; -type GlobalTypes = ArgTypes; interface SetGlobalsPayload { globals: Globals; globalTypes: GlobalTypes; @@ -16,7 +14,7 @@ interface SetGlobalsPayload { export interface SubState { globals?: Globals; - globalArgs?: GlobalTypes; + globalTypes?: GlobalTypes; } export interface SubAPI { @@ -27,12 +25,11 @@ export interface SubAPI { export const init: ModuleFn = ({ store, fullAPI }) => { const api: SubAPI = { - // TODO -- should these be {} before they are set? getGlobals() { - return store.getState().globals || {}; + return store.getState().globals; }, getGlobalTypes() { - return store.getState().globalTypes || {}; + return store.getState().globalTypes; }, updateGlobals(newGlobals) { // Only emit the message to the local ref @@ -45,8 +42,10 @@ export const init: ModuleFn = ({ store, fullAPI }) => { }, }; - const state: SubState = {}; - + const state: SubState = { + globals: {}, + globalTypes: {}, + }; const updateGlobals = (globals: Globals) => { const currentGlobals = store.getState()?.globals; if (!deepEqual(globals, currentGlobals)) { diff --git a/lib/api/src/tests/globals.test.ts b/lib/api/src/tests/globals.test.ts index 1f8cec96029..b7b1ccc105b 100644 --- a/lib/api/src/tests/globals.test.ts +++ b/lib/api/src/tests/globals.test.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'events'; -import { SET_STORIES, UPDATE_GLOBALS, GLOBALS_UPDATED } from '@storybook/core-events'; +import { SET_STORIES, SET_GLOBALS, UPDATE_GLOBALS, GLOBALS_UPDATED } from '@storybook/core-events'; import { ModuleArgs, API } from '../index'; import { init as initModule, SubAPI } from '../modules/globals'; @@ -10,7 +10,7 @@ const { getEventMetadata } = require('../lib/events'); jest.mock('@storybook/client-logger'); jest.mock('../lib/events'); beforeEach(() => { - getEventMetadata.mockReturnValue({ sourceType: 'local' }); + getEventMetadata.mockReset().mockReturnValue({ sourceType: 'local' }); }); function createMockStore() { @@ -23,28 +23,31 @@ function createMockStore() { }; } -describe('stories API', () => { +describe('globals API', () => { it('sets a sensible initialState', () => { const store = createMockStore(); const { state } = initModule(({ store } as unknown) as ModuleArgs); expect(state).toEqual({ globals: {}, + globalTypes: {}, }); }); - it('set global args on SET_STORIES', () => { + it('set global args on SET_GLOBALS', () => { const api = Object.assign(new EventEmitter(), { findRef: jest.fn() }); const store = createMockStore(); const { state, init } = initModule(({ store, fullAPI: api } as unknown) as ModuleArgs); store.setState(state); init(); - api.emit(SET_STORIES, { globals: { a: 'b' } }); - expect(store.getState()).toEqual({ globals: { a: 'b' } }); - - expect(state).toEqual({ - globals: {}, + api.emit(SET_GLOBALS, { + globals: { a: 'b' }, + globalTypes: { a: { type: { name: 'string' } } }, + }); + expect(store.getState()).toEqual({ + globals: { a: 'b' }, + globalTypes: { a: { type: { name: 'string' } } }, }); }); @@ -57,7 +60,22 @@ describe('stories API', () => { getEventMetadata.mockReturnValueOnce({ sourceType: 'external', ref: { id: 'ref' } }); api.emit(SET_STORIES, { globals: { a: 'b' } }); - expect(store.getState()).toEqual({ globals: {} }); + expect(store.getState()).toEqual({ globals: {}, globalTypes: {} }); + }); + + it('ignores SET_GLOBALS from other refs', () => { + const api = Object.assign(new EventEmitter(), { findRef: jest.fn() }); + const store = createMockStore(); + const { state, init } = initModule(({ store, fullAPI: api } as unknown) as ModuleArgs); + store.setState(state); + init(); + + getEventMetadata.mockReturnValueOnce({ sourceType: 'external', ref: { id: 'ref' } }); + api.emit(SET_GLOBALS, { + globals: { a: 'b' }, + globalTypes: { a: { type: { name: 'string' } } }, + }); + expect(store.getState()).toEqual({ globals: {}, globalTypes: {} }); }); it('updates the state when the preview emits GLOBALS_UPDATED', () => { @@ -69,14 +87,14 @@ describe('stories API', () => { init(); api.emit(GLOBALS_UPDATED, { globals: { a: 'b' } }); - expect(store.getState()).toEqual({ globals: { a: 'b' } }); + expect(store.getState()).toEqual({ globals: { a: 'b' }, globalTypes: {} }); api.emit(GLOBALS_UPDATED, { globals: { a: 'c' } }); - expect(store.getState()).toEqual({ globals: { a: 'c' } }); + expect(store.getState()).toEqual({ globals: { a: 'c' }, globalTypes: {} }); // SHOULD NOT merge global args api.emit(GLOBALS_UPDATED, { globals: { d: 'e' } }); - expect(store.getState()).toEqual({ globals: { d: 'e' } }); + expect(store.getState()).toEqual({ globals: { d: 'e' }, globalTypes: {} }); }); it('ignores GLOBALS_UPDATED from other refs', () => { @@ -90,7 +108,7 @@ describe('stories API', () => { getEventMetadata.mockReturnValueOnce({ sourceType: 'external', ref: { id: 'ref' } }); logger.warn.mockClear(); api.emit(GLOBALS_UPDATED, { globals: { a: 'b' } }); - expect(store.getState()).toEqual({ globals: {} }); + expect(store.getState()).toEqual({ globals: {}, globalTypes: {} }); expect(logger.warn).toHaveBeenCalled(); }); From 7929292571ed9b21bd7f280a4135929c9728f58b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 13:04:45 +1000 Subject: [PATCH 161/285] Fix stories tests and added some for preparing --- lib/api/src/lib/stories.ts | 20 ++-- lib/api/src/modules/stories.ts | 21 ++++- lib/api/src/tests/stories.test.js | 152 +++++++++++++++++++++++++++--- 3 files changed, 171 insertions(+), 22 deletions(-) diff --git a/lib/api/src/lib/stories.ts b/lib/api/src/lib/stories.ts index db1bfc68b51..291403e5497 100644 --- a/lib/api/src/lib/stories.ts +++ b/lib/api/src/lib/stories.ts @@ -1,10 +1,19 @@ import React from 'react'; import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; -import { sanitize } from '@storybook/csf'; import mapValues from 'lodash/mapValues'; - -import { StoryId, StoryKind, Args, ArgTypes, Parameters, combineParameters } from '../index'; +import { + StoryId, + ComponentTitle, + StoryKind, + StoryName, + Args, + ArgTypes, + Parameters, + sanitize, +} from '@storybook/csf'; + +import { combineParameters } from '../index'; import merge from './merge'; import { Provider } from '../modules/provider'; import { ViewMode } from '../modules/addons'; @@ -99,9 +108,6 @@ export interface StoriesRaw { [id: string]: StoryInput; } -// TODO reconcile these types with the same ones in the frontend -type StoryName = string; -type ComponentTitle = StoryKind; type Path = string; export interface StoriesListStory { name: StoryName; @@ -184,7 +190,7 @@ export const transformStoriesListToStoriesHash = ( export const transformStoriesRawToStoriesHash = ( input: StoriesRaw, - { provider, prepared = false }: { provider: Provider; prepared?: Story['prepared'] } + { provider, prepared = true }: { provider: Provider; prepared?: Story['prepared'] } ): StoriesHash => { const values = Object.values(input).filter(Boolean); const usesOldHierarchySeparator = values.some(({ kind }) => kind.match(/\.|\|/)); // dot or pipe diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index fc36eaf396d..282ecb10797 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -391,9 +391,7 @@ export const init: ModuleFn = ({ }, }; - const initModule = () => { - fullAPI.fetchStoryList(); - + const initModule = async () => { // On initial load, the local iframe will select the first story (or other "selection specifier") // and emit STORY_SPECIFIED with the id. We need to ensure we respond to this change. fullAPI.on( @@ -439,7 +437,14 @@ export const init: ModuleFn = ({ const stories = data.v ? denormalizeStoryParameters(data) : data.stories; if (!ref) { + if (!data.v) { + throw new Error('Unexpected legacy SET_STORIES event from local source'); + } + fullAPI.setStories(stories); + const options = fullAPI.getCurrentParameter('options'); + checkDeprecatedOptionParameters(options); + fullAPI.setOptions(options); } else { fullAPI.setRef(ref.id, { ...ref, ...data, stories }, true); } @@ -469,6 +474,13 @@ export const init: ModuleFn = ({ fullAPI.on(STORY_PREPARED, function handler({ id, ...update }) { const { ref } = getEventMetadata(this, fullAPI); fullAPI.updateStory(id, { ...update, prepared: true }, ref); + + if (!store.getState().hasCalledSetOptions) { + const { options } = update.parameters; + checkDeprecatedOptionParameters(options); + fullAPI.setOptions(options); + store.setState({ hasCalledSetOptions: true }); + } }); fullAPI.on( @@ -478,6 +490,8 @@ export const init: ModuleFn = ({ fullAPI.updateStory(storyId, { args }, ref); } ); + + await fullAPI.fetchStoryList(); }; return { @@ -487,6 +501,7 @@ export const init: ModuleFn = ({ storyId: initialStoryId, viewMode: initialViewMode, storiesConfigured: false, + hasCalledSetOptions: false, }, init: initModule, }; diff --git a/lib/api/src/tests/stories.test.js b/lib/api/src/tests/stories.test.js index 0ff8d6bba87..96c0d24c1b8 100644 --- a/lib/api/src/tests/stories.test.js +++ b/lib/api/src/tests/stories.test.js @@ -4,6 +4,7 @@ import { RESET_STORY_ARGS, SET_STORIES, STORY_SPECIFIED, + STORY_PREPARED, } from '@storybook/core-events'; import { EventEmitter } from 'events'; @@ -11,14 +12,33 @@ import { getEventMetadata } from '../lib/events'; import { init as initStories } from '../modules/stories'; +const mockStories = jest.fn(); + jest.mock('../lib/events'); jest.mock('global', () => ({ ...jest.requireActual('global'), - fetch: jest.fn(() => ({ json: () => ({ v: 3, stories: {} }) })), + fetch: jest.fn(() => ({ json: () => ({ v: 3, stories: mockStories() }) })), })); beforeEach(() => { getEventMetadata.mockReturnValue({ sourceType: 'local' }); + mockStories.mockReset().mockReturnValue({ + 'component-a--story-1': { + title: 'Component A', + name: 'Story 1', + importPath: './path/to/component-a.ts', + }, + 'component-a--story-2': { + title: 'Component A', + name: 'Story 2', + importPath: './path/to/component-a.ts', + }, + 'component-b--story-3': { + title: 'Component B', + name: 'Story 3', + importPath: './path/to/component-b.ts', + }, + }); }); function createMockStore(initialState) { @@ -50,6 +70,7 @@ describe('stories API', () => { storiesHash: {}, storyId: 'id', viewMode: 'story', + hasCalledSetOptions: false, }); }); const parameters = {}; @@ -90,6 +111,10 @@ describe('stories API', () => { }, }; describe('setStories', () => { + beforeEach(() => { + mockStories.mockRejectedValue(new Error('Fetch failed')); + }); + it('stores basic kinds and stories w/ correct keys', () => { const navigate = jest.fn(); const store = createMockStore(); @@ -131,6 +156,7 @@ describe('stories API', () => { name: '1', parameters, args: {}, + prepared: true, }); expect(storedStoriesHash['a--2']).toMatchObject({ @@ -140,6 +166,7 @@ describe('stories API', () => { name: '2', parameters, args: {}, + prepared: true, }); expect(storedStoriesHash.b).toMatchObject({ @@ -164,6 +191,7 @@ describe('stories API', () => { name: '1', parameters, args: {}, + prepared: true, }); expect(storedStoriesHash['b-d']).toMatchObject({ @@ -181,6 +209,7 @@ describe('stories API', () => { name: '1', parameters, args: {}, + prepared: true, }); expect(storedStoriesHash['b-d--2']).toMatchObject({ @@ -190,6 +219,7 @@ describe('stories API', () => { name: '2', parameters, args: { a: 'b' }, + prepared: true, }); expect(storedStoriesHash['b-e']).toMatchObject({ @@ -207,6 +237,7 @@ describe('stories API', () => { name: '1', parameters, args: {}, + prepared: true, }); }); @@ -843,8 +874,109 @@ describe('stories API', () => { }); }); }); + + describe('fetchStoryList', () => { + it('sets the initial set of stories in the stories hash', async () => { + const navigate = jest.fn(); + const store = createMockStore(); + const fullAPI = Object.assign(new EventEmitter(), { + setStories: jest.fn(), + }); + + const { api, init } = initStories({ store, navigate, provider, fullAPI }); + Object.assign(fullAPI, api); + + await init(); + + const { storiesHash: storedStoriesHash } = store.getState(); + + // We need exact key ordering, even if in theory JS doesn't guarantee it + expect(Object.keys(storedStoriesHash)).toEqual([ + 'component-a', + 'component-a--story-1', + 'component-a--story-2', + 'component-b', + 'component-b--story-3', + ]); + expect(storedStoriesHash['component-a']).toMatchObject({ + id: 'component-a', + children: ['component-a--story-1', 'component-a--story-2'], + isRoot: false, + isComponent: true, + }); + + expect(storedStoriesHash['component-a--story-1']).toMatchObject({ + id: 'component-a--story-1', + parent: 'component-a', + kind: 'Component A', + name: 'Story 1', + prepared: false, + }); + expect(storedStoriesHash['component-a--story-1'].args).toBeUndefined(); + }); + }); + + describe('STORY_PREPARED', () => { + it('prepares the story', async () => { + const navigate = jest.fn(); + const store = createMockStore(); + const fullAPI = Object.assign(new EventEmitter(), { + setStories: jest.fn(), + setOptions: jest.fn(), + }); + + const { api, init } = initStories({ store, navigate, provider, fullAPI }); + Object.assign(fullAPI, api); + + await init(); + fullAPI.emit(STORY_PREPARED, { + id: 'component-a--story-1', + parameters: { a: 'b' }, + args: { c: 'd' }, + }); + + const { storiesHash: storedStoriesHash } = store.getState(); + expect(storedStoriesHash['component-a--story-1']).toMatchObject({ + id: 'component-a--story-1', + parent: 'component-a', + kind: 'Component A', + name: 'Story 1', + prepared: true, + parameters: { a: 'b' }, + args: { c: 'd' }, + }); + }); + it('sets options the first time it is called', async () => { + const navigate = jest.fn(); + const store = createMockStore(); + const fullAPI = Object.assign(new EventEmitter(), { + setStories: jest.fn(), + setOptions: jest.fn(), + }); + + const { api, init } = initStories({ store, navigate, provider, fullAPI }); + Object.assign(fullAPI, api); + + await init(); + fullAPI.emit(STORY_PREPARED, { + id: 'component-a--story-1', + parameters: { options: 'options' }, + }); + + expect(fullAPI.setOptions).toHaveBeenCalledWith('options'); + + fullAPI.setOptions.mockClear(); + fullAPI.emit(STORY_PREPARED, { + id: 'component-a--story-1', + parameters: { options: 'options2' }, + }); + + expect(fullAPI.setOptions).not.toHaveBeenCalled(); + }); + }); + describe('v2 SET_STORIES event', () => { - it.skip('normalizes parameters and calls setStories for local stories', () => { + it('normalizes parameters and calls setStories for local stories', () => { const fullAPI = Object.assign(new EventEmitter(), { setStories: jest.fn(), setOptions: jest.fn(), @@ -855,7 +987,7 @@ describe('stories API', () => { const store = createMockStore(); const { init, api } = initStories({ store, navigate, provider, fullAPI }); - Object.assign(fullAPI, api); + Object.assign(fullAPI, api, { setStories: jest.fn() }); init(); const setStoriesPayload = { @@ -866,12 +998,9 @@ describe('stories API', () => { }; fullAPI.emit(SET_STORIES, setStoriesPayload); - expect(fullAPI.setStories).toHaveBeenCalledWith( - { - 'a--1': { kind: 'a', parameters: { global: 'global', kind: 'kind', story: 'story' } }, - }, - undefined - ); + expect(fullAPI.setStories).toHaveBeenCalledWith({ + 'a--1': { kind: 'a', parameters: { global: 'global', kind: 'kind', story: 'story' } }, + }); }); it('normalizes parameters and calls setRef for external stories', () => { @@ -912,18 +1041,17 @@ describe('stories API', () => { ); }); - it.skip('calls setOptions w/ first story parameter', () => { + it('calls setOptions w/ first story parameter', () => { const fullAPI = Object.assign(new EventEmitter(), { setStories: jest.fn(), setOptions: jest.fn(), findRef: jest.fn(), - getCurrentParameter: jest.fn().mockReturnValue('options'), }); const navigate = jest.fn(); const store = createMockStore(); const { init, api } = initStories({ store, navigate, provider, fullAPI }); - Object.assign(fullAPI, api); + Object.assign(fullAPI, api, { getCurrentParameter: jest.fn().mockReturnValue('options') }); init(); store.setState({}); From 3b3d566255e70d735706a7c4e18c35dfc82cd09e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 4 Sep 2021 13:24:21 +1000 Subject: [PATCH 162/285] Fix ui mockdata --- .../src/components/sidebar/mockdata.large.ts | 1515 +++++++++++++++++ lib/ui/src/components/sidebar/mockdata.ts | 12 + 2 files changed, 1527 insertions(+) diff --git a/lib/ui/src/components/sidebar/mockdata.large.ts b/lib/ui/src/components/sidebar/mockdata.large.ts index 3ee99a3fb30..fdf77ec232a 100644 --- a/lib/ui/src/components/sidebar/mockdata.large.ts +++ b/lib/ui/src/components/sidebar/mockdata.large.ts @@ -42,6 +42,7 @@ export const stories = { depth: 1, isComponent: true, isLeaf: true, + prepared: true, isRoot: false, }, 'emails-buildnotification': { @@ -69,6 +70,7 @@ export const stories = { depth: 2, parent: 'emails-buildnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -83,6 +85,7 @@ export const stories = { depth: 2, parent: 'emails-buildnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -97,6 +100,7 @@ export const stories = { depth: 2, parent: 'emails-buildnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -128,6 +132,7 @@ export const stories = { depth: 2, parent: 'emails-commentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -142,6 +147,7 @@ export const stories = { depth: 2, parent: 'emails-commentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -156,6 +162,7 @@ export const stories = { depth: 2, parent: 'emails-commentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -170,6 +177,7 @@ export const stories = { depth: 2, parent: 'emails-commentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -184,6 +192,7 @@ export const stories = { depth: 2, parent: 'emails-commentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -198,6 +207,7 @@ export const stories = { depth: 2, parent: 'emails-commentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -227,6 +237,7 @@ export const stories = { depth: 2, parent: 'emails-paymentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -241,6 +252,7 @@ export const stories = { depth: 2, parent: 'emails-paymentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -255,6 +267,7 @@ export const stories = { depth: 2, parent: 'emails-paymentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -269,6 +282,7 @@ export const stories = { depth: 2, parent: 'emails-paymentnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -302,6 +316,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -316,6 +331,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -330,6 +346,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -344,6 +361,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -358,6 +376,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -372,6 +391,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -386,6 +406,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -400,6 +421,7 @@ export const stories = { depth: 2, parent: 'emails-reviewnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -427,6 +449,7 @@ export const stories = { depth: 2, parent: 'emails-snapshotnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -441,6 +464,7 @@ export const stories = { depth: 2, parent: 'emails-snapshotnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -472,6 +496,7 @@ export const stories = { depth: 1, parent: 'images', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -486,6 +511,7 @@ export const stories = { depth: 1, parent: 'images', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -500,6 +526,7 @@ export const stories = { depth: 1, parent: 'images', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -514,6 +541,7 @@ export const stories = { depth: 1, parent: 'images', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -528,6 +556,7 @@ export const stories = { depth: 1, parent: 'images', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -542,6 +571,7 @@ export const stories = { depth: 1, parent: 'images', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -556,6 +586,7 @@ export const stories = { depth: 1, parent: 'images', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -589,6 +620,7 @@ export const stories = { depth: 2, parent: 'tooltip-tooltipbuildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -603,6 +635,7 @@ export const stories = { depth: 2, parent: 'tooltip-tooltipbuildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -627,6 +660,7 @@ export const stories = { depth: 2, parent: 'tooltip-tooltipselect', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -766,6 +800,7 @@ export const stories = { depth: 2, parent: 'webapp-components-accountmenu', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -780,6 +815,7 @@ export const stories = { depth: 2, parent: 'webapp-components-accountmenu', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -816,6 +852,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -830,6 +867,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -844,6 +882,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -858,6 +897,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -872,6 +912,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -886,6 +927,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -900,6 +942,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -914,6 +957,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -928,6 +972,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -942,6 +987,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -956,6 +1002,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -985,6 +1032,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activitylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -999,6 +1047,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activitylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1013,6 +1062,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activitylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1027,6 +1077,7 @@ export const stories = { depth: 2, parent: 'webapp-components-activitylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1060,6 +1111,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1074,6 +1126,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1088,6 +1141,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1102,6 +1156,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1116,6 +1171,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1130,6 +1186,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1144,6 +1201,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1158,6 +1216,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1191,6 +1250,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1205,6 +1265,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1219,6 +1280,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1233,6 +1295,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1247,6 +1310,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1261,6 +1325,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1275,6 +1340,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1289,6 +1355,7 @@ export const stories = { depth: 2, parent: 'webapp-components-appownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1313,6 +1380,7 @@ export const stories = { depth: 2, parent: 'webapp-components-aspectratiopreserver', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1342,6 +1410,7 @@ export const stories = { depth: 2, parent: 'webapp-components-asynctextaction', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1356,6 +1425,7 @@ export const stories = { depth: 2, parent: 'webapp-components-asynctextaction', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1370,6 +1440,7 @@ export const stories = { depth: 2, parent: 'webapp-components-asynctextaction', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1384,6 +1455,7 @@ export const stories = { depth: 2, parent: 'webapp-components-asynctextaction', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1413,6 +1485,7 @@ export const stories = { depth: 2, parent: 'webapp-components-badgecount', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1427,6 +1500,7 @@ export const stories = { depth: 2, parent: 'webapp-components-badgecount', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1441,6 +1515,7 @@ export const stories = { depth: 2, parent: 'webapp-components-badgecount', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1455,6 +1530,7 @@ export const stories = { depth: 2, parent: 'webapp-components-badgecount', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1483,6 +1559,7 @@ export const stories = { depth: 2, parent: 'webapp-components-banner', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1497,6 +1574,7 @@ export const stories = { depth: 2, parent: 'webapp-components-banner', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1511,6 +1589,7 @@ export const stories = { depth: 2, parent: 'webapp-components-banner', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1544,6 +1623,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1558,6 +1638,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1572,6 +1653,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1586,6 +1668,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1600,6 +1683,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1614,6 +1698,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1628,6 +1713,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1642,6 +1728,7 @@ export const stories = { depth: 2, parent: 'webapp-components-baselinehistory', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1676,6 +1763,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1690,6 +1778,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1704,6 +1793,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1718,6 +1808,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1732,6 +1823,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1746,6 +1838,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1760,6 +1853,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1774,6 +1868,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1788,6 +1883,7 @@ export const stories = { depth: 2, parent: 'webapp-components-billingplans', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1812,6 +1908,7 @@ export const stories = { depth: 2, parent: 'webapp-components-branchpicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1840,6 +1937,7 @@ export const stories = { depth: 2, parent: 'webapp-components-breadcrumb', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1854,6 +1952,7 @@ export const stories = { depth: 2, parent: 'webapp-components-breadcrumb', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1868,6 +1967,7 @@ export const stories = { depth: 2, parent: 'webapp-components-breadcrumb', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1915,6 +2015,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1929,6 +2030,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1943,6 +2045,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1957,6 +2060,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1971,6 +2075,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -1985,6 +2090,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2016,6 +2122,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2030,6 +2137,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2044,6 +2152,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2058,6 +2167,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2072,6 +2182,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2086,6 +2197,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-buildcomponentlistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2120,6 +2232,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2134,6 +2247,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2148,6 +2262,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2162,6 +2277,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2176,6 +2292,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2190,6 +2307,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2204,6 +2322,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2218,6 +2337,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2232,6 +2352,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-groupitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2260,6 +2381,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-polymorphiclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2274,6 +2396,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-polymorphiclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2288,6 +2411,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-polymorphiclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2315,6 +2439,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-rootitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2329,6 +2454,7 @@ export const stories = { depth: 3, parent: 'webapp-components-buildcomponentlist-rootitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2365,6 +2491,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2379,6 +2506,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2393,6 +2521,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2407,6 +2536,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2421,6 +2551,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2435,6 +2566,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2449,6 +2581,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2463,6 +2596,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2477,6 +2611,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2491,6 +2626,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2505,6 +2641,7 @@ export const stories = { depth: 2, parent: 'webapp-components-builditem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2535,6 +2672,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2549,6 +2687,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2563,6 +2702,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2577,6 +2717,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2591,6 +2732,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2631,6 +2773,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2645,6 +2788,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2659,6 +2803,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2673,6 +2818,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2687,6 +2833,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2701,6 +2848,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2715,6 +2863,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2729,6 +2878,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2743,6 +2893,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2757,6 +2908,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2771,6 +2923,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2785,6 +2938,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2799,6 +2953,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2813,6 +2968,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2827,6 +2983,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buildstatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2851,6 +3008,7 @@ export const stories = { depth: 2, parent: 'webapp-components-button', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2875,6 +3033,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buttonmulti', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2905,6 +3064,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buttontoggle', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2919,6 +3079,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buttontoggle', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2933,6 +3094,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buttontoggle', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2947,6 +3109,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buttontoggle', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -2961,6 +3124,7 @@ export const stories = { depth: 2, parent: 'webapp-components-buttontoggle', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3010,6 +3174,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3024,6 +3189,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3038,6 +3204,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3052,6 +3219,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3066,6 +3234,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3080,6 +3249,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3094,6 +3264,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3108,6 +3279,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3122,6 +3294,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3136,6 +3309,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3150,6 +3324,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3164,6 +3339,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3178,6 +3354,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3192,6 +3369,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3206,6 +3384,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3220,6 +3399,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3234,6 +3414,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3248,6 +3429,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3262,6 +3444,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3276,6 +3459,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3290,6 +3474,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3304,6 +3489,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3318,6 +3504,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3332,6 +3519,7 @@ export const stories = { depth: 2, parent: 'webapp-components-canvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3370,6 +3558,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3384,6 +3573,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3398,6 +3588,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3412,6 +3603,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3426,6 +3618,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3440,6 +3633,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3454,6 +3648,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3468,6 +3663,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3482,6 +3678,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3496,6 +3693,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3510,6 +3708,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3524,6 +3723,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3538,6 +3738,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cardinal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3567,6 +3768,7 @@ export const stories = { depth: 2, parent: 'webapp-components-checkbox', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3581,6 +3783,7 @@ export const stories = { depth: 2, parent: 'webapp-components-checkbox', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3595,6 +3798,7 @@ export const stories = { depth: 2, parent: 'webapp-components-checkbox', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3609,6 +3813,7 @@ export const stories = { depth: 2, parent: 'webapp-components-checkbox', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3639,6 +3844,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cieyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3653,6 +3859,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cieyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3667,6 +3874,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cieyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3681,6 +3889,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cieyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3695,6 +3904,7 @@ export const stories = { depth: 2, parent: 'webapp-components-cieyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3722,6 +3932,7 @@ export const stories = { depth: 2, parent: 'webapp-components-clipboard', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3736,6 +3947,7 @@ export const stories = { depth: 2, parent: 'webapp-components-clipboard', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3763,6 +3975,7 @@ export const stories = { depth: 2, parent: 'webapp-components-clipboardcode', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3777,6 +3990,7 @@ export const stories = { depth: 2, parent: 'webapp-components-clipboardcode', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3801,6 +4015,7 @@ export const stories = { depth: 2, parent: 'webapp-components-clipboardicon', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3828,6 +4043,7 @@ export const stories = { depth: 2, parent: 'webapp-components-clipboardinput', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3842,6 +4058,7 @@ export const stories = { depth: 2, parent: 'webapp-components-clipboardinput', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3898,6 +4115,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-addcomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3912,6 +4130,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-addcomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3926,6 +4145,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-addcomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3940,6 +4160,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-addcomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3954,6 +4175,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-addcomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3968,6 +4190,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-addcomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -3982,6 +4205,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-addcomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4011,6 +4235,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-comment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4025,6 +4250,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-comment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4039,6 +4265,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-comment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4053,6 +4280,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-comment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4080,6 +4308,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentdate', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4094,6 +4323,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentdate', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4122,6 +4352,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentformmanager', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4136,6 +4367,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentformmanager', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4150,6 +4382,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentformmanager', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4174,6 +4407,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentheading', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4201,6 +4435,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4215,6 +4450,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4242,6 +4478,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commenttextarea', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4256,6 +4493,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commenttextarea', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4284,6 +4522,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4298,6 +4537,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4312,6 +4552,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-commentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4340,6 +4581,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-deletecomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4354,6 +4596,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-deletecomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4368,6 +4611,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-deletecomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4407,6 +4651,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4421,6 +4666,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4435,6 +4681,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4449,6 +4696,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4463,6 +4711,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4477,6 +4726,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4491,6 +4741,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4505,6 +4756,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4519,6 +4771,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4533,6 +4786,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4547,6 +4801,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4561,6 +4816,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4575,6 +4831,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4589,6 +4846,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-inlinecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4619,6 +4877,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-replytocomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4633,6 +4892,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-replytocomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4647,6 +4907,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-replytocomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4661,6 +4922,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-replytocomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4675,6 +4937,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-replytocomment', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4702,6 +4965,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-resolvecommentthreadbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4716,6 +4980,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-resolvecommentthreadbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4746,6 +5011,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-undoresolvecommentthreadbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4760,6 +5026,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-undoresolvecommentthreadbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4774,6 +5041,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-undoresolvecommentthreadbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4788,6 +5056,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-undoresolvecommentthreadbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4802,6 +5071,7 @@ export const stories = { depth: 3, parent: 'webapp-components-comment-undoresolvecommentthreadbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4829,6 +5099,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbranchlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4843,6 +5114,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbranchlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4870,6 +5142,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbuildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4884,6 +5157,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbuildlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4913,6 +5187,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbuildspicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4927,6 +5202,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbuildspicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4941,6 +5217,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbuildspicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4955,6 +5232,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentbuildspicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -4989,6 +5267,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5003,6 +5282,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5017,6 +5297,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5031,6 +5312,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5045,6 +5327,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5059,6 +5342,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5073,6 +5357,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5087,6 +5372,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5101,6 +5387,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5129,6 +5416,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5143,6 +5431,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5157,6 +5446,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5192,6 +5482,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5206,6 +5497,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5220,6 +5512,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5234,6 +5527,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5248,6 +5542,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5262,6 +5557,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5276,6 +5572,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5290,6 +5587,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5304,6 +5602,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5318,6 +5617,7 @@ export const stories = { depth: 2, parent: 'webapp-components-componentrepresentationimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5349,6 +5649,7 @@ export const stories = { depth: 2, parent: 'webapp-components-creditcardform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5363,6 +5664,7 @@ export const stories = { depth: 2, parent: 'webapp-components-creditcardform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5377,6 +5679,7 @@ export const stories = { depth: 2, parent: 'webapp-components-creditcardform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5391,6 +5694,7 @@ export const stories = { depth: 2, parent: 'webapp-components-creditcardform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5405,6 +5709,7 @@ export const stories = { depth: 2, parent: 'webapp-components-creditcardform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5419,6 +5724,7 @@ export const stories = { depth: 2, parent: 'webapp-components-creditcardform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5443,6 +5749,7 @@ export const stories = { depth: 2, parent: 'webapp-components-dateformatter', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5483,6 +5790,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5497,6 +5805,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5511,6 +5820,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5525,6 +5835,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5539,6 +5850,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5553,6 +5865,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5567,6 +5880,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5581,6 +5895,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5595,6 +5910,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5609,6 +5925,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5623,6 +5940,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5637,6 +5955,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5651,6 +5970,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5665,6 +5985,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5679,6 +6000,7 @@ export const stories = { depth: 2, parent: 'webapp-components-diffimage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5709,6 +6031,7 @@ export const stories = { depth: 2, parent: 'webapp-components-difftoggles', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5723,6 +6046,7 @@ export const stories = { depth: 2, parent: 'webapp-components-difftoggles', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5737,6 +6061,7 @@ export const stories = { depth: 2, parent: 'webapp-components-difftoggles', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5751,6 +6076,7 @@ export const stories = { depth: 2, parent: 'webapp-components-difftoggles', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5765,6 +6091,7 @@ export const stories = { depth: 2, parent: 'webapp-components-difftoggles', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5794,6 +6121,7 @@ export const stories = { depth: 2, parent: 'webapp-components-emptymessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5808,6 +6136,7 @@ export const stories = { depth: 2, parent: 'webapp-components-emptymessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5822,6 +6151,7 @@ export const stories = { depth: 2, parent: 'webapp-components-emptymessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5836,6 +6166,7 @@ export const stories = { depth: 2, parent: 'webapp-components-emptymessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5865,6 +6196,7 @@ export const stories = { depth: 2, parent: 'webapp-components-eyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5879,6 +6211,7 @@ export const stories = { depth: 2, parent: 'webapp-components-eyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5893,6 +6226,7 @@ export const stories = { depth: 2, parent: 'webapp-components-eyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5907,6 +6241,7 @@ export const stories = { depth: 2, parent: 'webapp-components-eyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5931,6 +6266,7 @@ export const stories = { depth: 2, parent: 'webapp-components-eyebrowonboarding', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5959,6 +6295,7 @@ export const stories = { depth: 2, parent: 'webapp-components-flexcenter', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5973,6 +6310,7 @@ export const stories = { depth: 2, parent: 'webapp-components-flexcenter', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -5987,6 +6325,7 @@ export const stories = { depth: 2, parent: 'webapp-components-flexcenter', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6011,6 +6350,7 @@ export const stories = { depth: 2, parent: 'webapp-components-form', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6050,6 +6390,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6064,6 +6405,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6078,6 +6420,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6092,6 +6435,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6106,6 +6450,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6120,6 +6465,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6134,6 +6480,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6148,6 +6495,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6162,6 +6510,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6176,6 +6525,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6190,6 +6540,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6204,6 +6555,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6218,6 +6570,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6232,6 +6585,7 @@ export const stories = { depth: 2, parent: 'webapp-components-header', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6260,6 +6614,7 @@ export const stories = { depth: 2, parent: 'webapp-components-heading', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6274,6 +6629,7 @@ export const stories = { depth: 2, parent: 'webapp-components-heading', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6288,6 +6644,7 @@ export const stories = { depth: 2, parent: 'webapp-components-heading', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6312,6 +6669,7 @@ export const stories = { depth: 2, parent: 'webapp-components-ignoredregions', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6347,6 +6705,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6361,6 +6720,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6375,6 +6735,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6389,6 +6750,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6403,6 +6765,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6417,6 +6780,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6431,6 +6795,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6445,6 +6810,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6459,6 +6825,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6473,6 +6840,7 @@ export const stories = { depth: 2, parent: 'webapp-components-imagetile', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6502,6 +6870,7 @@ export const stories = { depth: 2, parent: 'webapp-components-interstitial', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6516,6 +6885,7 @@ export const stories = { depth: 2, parent: 'webapp-components-interstitial', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6530,6 +6900,7 @@ export const stories = { depth: 2, parent: 'webapp-components-interstitial', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6544,6 +6915,7 @@ export const stories = { depth: 2, parent: 'webapp-components-interstitial', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6571,6 +6943,7 @@ export const stories = { depth: 2, parent: 'webapp-components-inviteeyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6585,6 +6958,7 @@ export const stories = { depth: 2, parent: 'webapp-components-inviteeyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6612,6 +6986,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isactiveelement', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6626,6 +7001,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isactiveelement', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6660,6 +7036,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6674,6 +7051,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6688,6 +7066,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6702,6 +7081,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6716,6 +7096,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6730,6 +7111,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6744,6 +7126,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6758,6 +7141,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6772,6 +7156,7 @@ export const stories = { depth: 2, parent: 'webapp-components-isolatorframe', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6803,6 +7188,7 @@ export const stories = { depth: 2, parent: 'webapp-components-linklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6817,6 +7203,7 @@ export const stories = { depth: 2, parent: 'webapp-components-linklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6831,6 +7218,7 @@ export const stories = { depth: 2, parent: 'webapp-components-linklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6845,6 +7233,7 @@ export const stories = { depth: 2, parent: 'webapp-components-linklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6859,6 +7248,7 @@ export const stories = { depth: 2, parent: 'webapp-components-linklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6873,6 +7263,7 @@ export const stories = { depth: 2, parent: 'webapp-components-linklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6897,6 +7288,7 @@ export const stories = { depth: 2, parent: 'webapp-components-linktabs', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6921,6 +7313,7 @@ export const stories = { depth: 2, parent: 'webapp-components-listheading', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6958,6 +7351,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6972,6 +7366,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -6986,6 +7381,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7000,6 +7396,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7014,6 +7411,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7028,6 +7426,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7042,6 +7441,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7056,6 +7456,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7070,6 +7471,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7084,6 +7486,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7098,6 +7501,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7112,6 +7516,7 @@ export const stories = { depth: 2, parent: 'webapp-components-liveview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7139,6 +7544,7 @@ export const stories = { depth: 2, parent: 'webapp-components-mailinglistsubscribeform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7153,6 +7559,7 @@ export const stories = { depth: 2, parent: 'webapp-components-mailinglistsubscribeform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7184,6 +7591,7 @@ export const stories = { depth: 2, parent: 'webapp-components-newappform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7198,6 +7606,7 @@ export const stories = { depth: 2, parent: 'webapp-components-newappform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7212,6 +7621,7 @@ export const stories = { depth: 2, parent: 'webapp-components-newappform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7226,6 +7636,7 @@ export const stories = { depth: 2, parent: 'webapp-components-newappform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7240,6 +7651,7 @@ export const stories = { depth: 2, parent: 'webapp-components-newappform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7254,6 +7666,7 @@ export const stories = { depth: 2, parent: 'webapp-components-newappform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7293,6 +7706,7 @@ export const stories = { depth: 3, parent: 'webapp-components-notifications-notification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7317,6 +7731,7 @@ export const stories = { depth: 3, parent: 'webapp-components-notifications-notifications', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7341,6 +7756,7 @@ export const stories = { depth: 3, parent: 'webapp-components-notifications-reviewsyncfailednotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7365,6 +7781,7 @@ export const stories = { depth: 3, parent: 'webapp-components-notifications-syncingnotification', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7393,6 +7810,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pageheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7407,6 +7825,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pageheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7421,6 +7840,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pageheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7449,6 +7869,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pagetitlebar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7463,6 +7884,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pagetitlebar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7477,6 +7899,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pagetitlebar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7501,6 +7924,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pagination', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7515,6 +7939,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pagination', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7539,6 +7964,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectcta', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7572,6 +7998,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7586,6 +8013,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7600,6 +8028,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7614,6 +8043,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7628,6 +8058,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7642,6 +8073,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7656,6 +8088,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7670,6 +8103,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymentcollectmodal', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7699,6 +8133,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymenteyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7713,6 +8148,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymenteyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7727,6 +8163,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymenteyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7741,6 +8178,7 @@ export const stories = { depth: 2, parent: 'webapp-components-paymenteyebrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7773,6 +8211,7 @@ export const stories = { depth: 2, parent: 'webapp-components-progressbar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7787,6 +8226,7 @@ export const stories = { depth: 2, parent: 'webapp-components-progressbar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7801,6 +8241,7 @@ export const stories = { depth: 2, parent: 'webapp-components-progressbar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7815,6 +8256,7 @@ export const stories = { depth: 2, parent: 'webapp-components-progressbar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7829,6 +8271,7 @@ export const stories = { depth: 2, parent: 'webapp-components-progressbar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7843,6 +8286,7 @@ export const stories = { depth: 2, parent: 'webapp-components-progressbar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7857,6 +8301,7 @@ export const stories = { depth: 2, parent: 'webapp-components-progressbar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7889,6 +8334,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7903,6 +8349,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7917,6 +8364,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7931,6 +8379,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7945,6 +8394,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7959,6 +8409,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -7973,6 +8424,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8001,6 +8453,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8015,6 +8468,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8029,6 +8483,7 @@ export const stories = { depth: 2, parent: 'webapp-components-projectlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8062,6 +8517,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8076,6 +8532,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8090,6 +8547,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8104,6 +8562,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8118,6 +8577,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8132,6 +8592,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8146,6 +8607,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8160,6 +8622,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8191,6 +8654,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8205,6 +8669,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8219,6 +8684,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8233,6 +8699,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8247,6 +8714,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8261,6 +8729,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequestlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8307,6 +8776,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8321,6 +8791,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8335,6 +8806,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8349,6 +8821,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8363,6 +8836,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8377,6 +8851,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8391,6 +8866,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8405,6 +8881,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8419,6 +8896,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8433,6 +8911,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8447,6 +8926,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8461,6 +8941,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8475,6 +8956,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8489,6 +8971,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8503,6 +8986,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8517,6 +9001,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8531,6 +9016,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8545,6 +9031,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8559,6 +9046,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8573,6 +9061,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8587,6 +9076,7 @@ export const stories = { depth: 2, parent: 'webapp-components-pullrequeststatuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8614,6 +9104,7 @@ export const stories = { depth: 2, parent: 'webapp-components-questiontooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8628,6 +9119,7 @@ export const stories = { depth: 2, parent: 'webapp-components-questiontooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8652,6 +9144,7 @@ export const stories = { depth: 2, parent: 'webapp-components-radar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8681,6 +9174,7 @@ export const stories = { depth: 2, parent: 'webapp-components-radio', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8695,6 +9189,7 @@ export const stories = { depth: 2, parent: 'webapp-components-radio', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8709,6 +9204,7 @@ export const stories = { depth: 2, parent: 'webapp-components-radio', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8723,6 +9219,7 @@ export const stories = { depth: 2, parent: 'webapp-components-radio', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8751,6 +9248,7 @@ export const stories = { depth: 2, parent: 'webapp-components-rawspeclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8765,6 +9263,7 @@ export const stories = { depth: 2, parent: 'webapp-components-rawspeclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8779,6 +9278,7 @@ export const stories = { depth: 2, parent: 'webapp-components-rawspeclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8803,6 +9303,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositoryitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8832,6 +9333,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8846,6 +9348,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8860,6 +9363,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8874,6 +9378,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorylist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8901,6 +9406,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositoryowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8915,6 +9421,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositoryowneritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8942,6 +9449,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositoryownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8956,6 +9464,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositoryownerlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -8986,6 +9495,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorypicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9000,6 +9510,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorypicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9014,6 +9525,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorypicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9028,6 +9540,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorypicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9042,6 +9555,7 @@ export const stories = { depth: 2, parent: 'webapp-components-repositorypicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9069,6 +9583,7 @@ export const stories = { depth: 2, parent: 'webapp-components-scrollintoview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9083,6 +9598,7 @@ export const stories = { depth: 2, parent: 'webapp-components-scrollintoview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9114,6 +9630,7 @@ export const stories = { depth: 2, parent: 'webapp-components-section', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9128,6 +9645,7 @@ export const stories = { depth: 2, parent: 'webapp-components-section', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9142,6 +9660,7 @@ export const stories = { depth: 2, parent: 'webapp-components-section', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9156,6 +9675,7 @@ export const stories = { depth: 2, parent: 'webapp-components-section', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9170,6 +9690,7 @@ export const stories = { depth: 2, parent: 'webapp-components-section', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9184,6 +9705,7 @@ export const stories = { depth: 2, parent: 'webapp-components-section', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9211,6 +9733,7 @@ export const stories = { depth: 2, parent: 'webapp-components-sharetooltipmessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9225,6 +9748,7 @@ export const stories = { depth: 2, parent: 'webapp-components-sharetooltipmessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9254,6 +9778,7 @@ export const stories = { depth: 2, parent: 'webapp-components-sidebarnav', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9268,6 +9793,7 @@ export const stories = { depth: 2, parent: 'webapp-components-sidebarnav', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9282,6 +9808,7 @@ export const stories = { depth: 2, parent: 'webapp-components-sidebarnav', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9296,6 +9823,7 @@ export const stories = { depth: 2, parent: 'webapp-components-sidebarnav', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9323,6 +9851,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshoterror', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9337,6 +9866,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshoterror', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9367,6 +9897,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshoterrormessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9381,6 +9912,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshoterrormessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9395,6 +9927,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshoterrormessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9409,6 +9942,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshoterrormessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9423,6 +9957,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshoterrormessage', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9452,6 +9987,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshotsizechanged', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9466,6 +10002,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshotsizechanged', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9480,6 +10017,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshotsizechanged', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9494,6 +10032,7 @@ export const stories = { depth: 2, parent: 'webapp-components-snapshotsizechanged', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9526,6 +10065,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9540,6 +10080,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9554,6 +10095,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9568,6 +10110,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9582,6 +10125,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9596,6 +10140,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9610,6 +10155,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9638,6 +10184,7 @@ export const stories = { depth: 2, parent: 'webapp-components-speclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9652,6 +10199,7 @@ export const stories = { depth: 2, parent: 'webapp-components-speclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9666,6 +10214,7 @@ export const stories = { depth: 2, parent: 'webapp-components-speclist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9695,6 +10244,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specname', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9709,6 +10259,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specname', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9723,6 +10274,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specname', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9737,6 +10289,7 @@ export const stories = { depth: 2, parent: 'webapp-components-specname', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9761,6 +10314,7 @@ export const stories = { depth: 2, parent: 'webapp-components-startchat', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9775,6 +10329,7 @@ export const stories = { depth: 2, parent: 'webapp-components-startchat', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9812,6 +10367,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9826,6 +10382,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9840,6 +10397,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9854,6 +10412,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9868,6 +10427,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9882,6 +10442,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9896,6 +10457,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9910,6 +10472,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9924,6 +10487,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9938,6 +10502,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9952,6 +10517,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9966,6 +10532,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statuslight', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -9995,6 +10562,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10009,6 +10577,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10023,6 +10592,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10037,6 +10607,7 @@ export const stories = { depth: 2, parent: 'webapp-components-statustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10066,6 +10637,7 @@ export const stories = { depth: 2, parent: 'webapp-components-subheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10080,6 +10652,7 @@ export const stories = { depth: 2, parent: 'webapp-components-subheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10094,6 +10667,7 @@ export const stories = { depth: 2, parent: 'webapp-components-subheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10108,6 +10682,7 @@ export const stories = { depth: 2, parent: 'webapp-components-subheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10139,6 +10714,7 @@ export const stories = { depth: 2, parent: 'webapp-components-table', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10153,6 +10729,7 @@ export const stories = { depth: 2, parent: 'webapp-components-table', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10167,6 +10744,7 @@ export const stories = { depth: 2, parent: 'webapp-components-table', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10181,6 +10759,7 @@ export const stories = { depth: 2, parent: 'webapp-components-table', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10195,6 +10774,7 @@ export const stories = { depth: 2, parent: 'webapp-components-table', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10209,6 +10789,7 @@ export const stories = { depth: 2, parent: 'webapp-components-table', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10233,6 +10814,7 @@ export const stories = { depth: 2, parent: 'webapp-components-tabledrawer', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10257,6 +10839,7 @@ export const stories = { depth: 2, parent: 'webapp-components-tooltipignore', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10286,6 +10869,7 @@ export const stories = { depth: 2, parent: 'webapp-components-useritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10300,6 +10884,7 @@ export const stories = { depth: 2, parent: 'webapp-components-useritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10314,6 +10899,7 @@ export const stories = { depth: 2, parent: 'webapp-components-useritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10328,6 +10914,7 @@ export const stories = { depth: 2, parent: 'webapp-components-useritem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10359,6 +10946,7 @@ export const stories = { depth: 2, parent: 'webapp-components-userlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10373,6 +10961,7 @@ export const stories = { depth: 2, parent: 'webapp-components-userlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10387,6 +10976,7 @@ export const stories = { depth: 2, parent: 'webapp-components-userlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10401,6 +10991,7 @@ export const stories = { depth: 2, parent: 'webapp-components-userlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10415,6 +11006,7 @@ export const stories = { depth: 2, parent: 'webapp-components-userlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10429,6 +11021,7 @@ export const stories = { depth: 2, parent: 'webapp-components-userlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10453,6 +11046,7 @@ export const stories = { depth: 2, parent: 'webapp-components-video', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10484,6 +11078,7 @@ export const stories = { depth: 2, parent: 'webapp-components-warning', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10498,6 +11093,7 @@ export const stories = { depth: 2, parent: 'webapp-components-warning', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10512,6 +11108,7 @@ export const stories = { depth: 2, parent: 'webapp-components-warning', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10526,6 +11123,7 @@ export const stories = { depth: 2, parent: 'webapp-components-warning', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10540,6 +11138,7 @@ export const stories = { depth: 2, parent: 'webapp-components-warning', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10554,6 +11153,7 @@ export const stories = { depth: 2, parent: 'webapp-components-warning', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10578,6 +11178,7 @@ export const stories = { depth: 2, parent: 'webapp-components-wobbler', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10615,6 +11216,7 @@ export const stories = { depth: 2, parent: 'webapp-containers-appbuildspaginated', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10629,6 +11231,7 @@ export const stories = { depth: 2, parent: 'webapp-containers-appbuildspaginated', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10643,6 +11246,7 @@ export const stories = { depth: 2, parent: 'webapp-containers-appbuildspaginated', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10671,6 +11275,7 @@ export const stories = { depth: 2, parent: 'webapp-containers-componentbuildspicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10685,6 +11290,7 @@ export const stories = { depth: 2, parent: 'webapp-containers-componentbuildspicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10699,6 +11305,7 @@ export const stories = { depth: 2, parent: 'webapp-containers-componentbuildspicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10749,6 +11356,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10763,6 +11371,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10777,6 +11386,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10791,6 +11401,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10805,6 +11416,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10819,6 +11431,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10833,6 +11446,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10847,6 +11461,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-account', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10883,6 +11498,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10897,6 +11513,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10911,6 +11528,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10925,6 +11543,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10939,6 +11558,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10953,6 +11573,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10967,6 +11588,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10981,6 +11603,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -10995,6 +11618,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11009,6 +11633,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11023,6 +11648,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-app', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11047,6 +11673,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-interstitial', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11076,6 +11703,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-marketing', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11090,6 +11718,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-marketing', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11104,6 +11733,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-marketing', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11118,6 +11748,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-marketing', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11147,6 +11778,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-onboarding', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11161,6 +11793,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-onboarding', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11175,6 +11808,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-onboarding', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11189,6 +11823,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-onboarding', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11223,6 +11858,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11237,6 +11873,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11251,6 +11888,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11265,6 +11903,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11279,6 +11918,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11293,6 +11933,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11307,6 +11948,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11321,6 +11963,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11335,6 +11978,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-page', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11366,6 +12010,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-setup', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11380,6 +12025,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-setup', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11394,6 +12040,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-setup', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11408,6 +12055,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-setup', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11422,6 +12070,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-setup', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11436,6 +12085,7 @@ export const stories = { depth: 2, parent: 'webapp-layouts-setup', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11508,6 +12158,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11522,6 +12173,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11536,6 +12188,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11550,6 +12203,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11564,6 +12218,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11578,6 +12233,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11592,6 +12248,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11606,6 +12263,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11620,6 +12278,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11634,6 +12293,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11648,6 +12308,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11662,6 +12323,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11676,6 +12338,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11690,6 +12353,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11704,6 +12368,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-appsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11754,6 +12419,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11768,6 +12434,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11782,6 +12449,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11796,6 +12464,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11810,6 +12479,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11824,6 +12494,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11838,6 +12509,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11852,6 +12524,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11866,6 +12539,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11880,6 +12554,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11894,6 +12569,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11908,6 +12584,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11922,6 +12599,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11936,6 +12614,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11950,6 +12629,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11964,6 +12644,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11978,6 +12659,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -11992,6 +12674,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12006,6 +12689,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12020,6 +12704,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12034,6 +12719,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12048,6 +12734,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12062,6 +12749,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-billingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12090,6 +12778,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-billingemailform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12104,6 +12793,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-billingemailform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12118,6 +12808,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-billingemailform', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12148,6 +12839,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-invoicelist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12162,6 +12854,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-invoicelist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12176,6 +12869,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-invoicelist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12190,6 +12884,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-invoicelist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12204,6 +12899,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-billingscreen-invoicelist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12255,6 +12951,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12269,6 +12966,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12283,6 +12981,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12297,6 +12996,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12311,6 +13011,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12344,6 +13045,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12358,6 +13060,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12372,6 +13075,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12386,6 +13090,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12400,6 +13105,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12414,6 +13120,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12428,6 +13135,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12442,6 +13150,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12487,6 +13196,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12501,6 +13211,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12515,6 +13226,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12529,6 +13241,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12543,6 +13256,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12557,6 +13271,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12571,6 +13286,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12585,6 +13301,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12599,6 +13316,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12613,6 +13331,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12627,6 +13346,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12641,6 +13361,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12655,6 +13376,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12669,6 +13391,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12683,6 +13406,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12697,6 +13421,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12711,6 +13436,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12725,6 +13451,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12739,6 +13466,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12753,6 +13481,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12790,6 +13519,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12804,6 +13534,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12818,6 +13549,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12832,6 +13564,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12846,6 +13579,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12860,6 +13594,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12874,6 +13609,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12888,6 +13624,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-buildsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12917,6 +13654,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-ancestors', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12931,6 +13669,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-ancestors', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12945,6 +13684,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-ancestors', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12959,6 +13699,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-ancestors', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -12986,6 +13727,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-commit', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13000,6 +13742,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-commit', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13031,6 +13774,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-pullrequests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13045,6 +13789,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-pullrequests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13059,6 +13804,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-pullrequests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13073,6 +13819,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-pullrequests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13087,6 +13834,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-pullrequests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13101,6 +13849,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-pullrequests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13140,6 +13889,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13154,6 +13904,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13168,6 +13919,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13182,6 +13934,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13196,6 +13949,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13210,6 +13964,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13224,6 +13979,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13238,6 +13994,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13252,6 +14009,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13266,6 +14024,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13280,6 +14039,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13294,6 +14054,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13308,6 +14069,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13322,6 +14084,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-build-buildsummary-tests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13362,6 +14125,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13376,6 +14140,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13390,6 +14155,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13404,6 +14170,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13418,6 +14185,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13432,6 +14200,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13446,6 +14215,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13460,6 +14230,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13474,6 +14245,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13488,6 +14260,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13502,6 +14275,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13516,6 +14290,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13530,6 +14305,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13544,6 +14320,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13558,6 +14335,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-componentrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13585,6 +14363,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-rowexpander', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13599,6 +14378,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-rowexpander', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13639,6 +14419,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13653,6 +14434,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13667,6 +14449,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13681,6 +14464,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13695,6 +14479,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13709,6 +14494,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13723,6 +14509,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13737,6 +14524,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13751,6 +14539,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13765,6 +14554,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13779,6 +14569,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13793,6 +14584,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13807,6 +14599,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13821,6 +14614,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13835,6 +14629,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13871,6 +14666,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13885,6 +14681,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13899,6 +14696,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13913,6 +14711,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13927,6 +14726,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13941,6 +14741,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13955,6 +14756,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13969,6 +14771,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13983,6 +14786,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -13997,6 +14801,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14011,6 +14816,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-snapshotstable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14047,6 +14853,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14061,6 +14868,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14075,6 +14883,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14089,6 +14898,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14103,6 +14913,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14117,6 +14928,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14131,6 +14943,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14145,6 +14958,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14159,6 +14973,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14173,6 +14988,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14187,6 +15003,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-specrow', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14235,6 +15052,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14249,6 +15067,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14263,6 +15082,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14277,6 +15097,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14291,6 +15112,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14305,6 +15127,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14319,6 +15142,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14333,6 +15157,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14347,6 +15172,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14361,6 +15187,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14375,6 +15202,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14389,6 +15217,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14403,6 +15232,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14417,6 +15247,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14431,6 +15262,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14445,6 +15277,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14459,6 +15292,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14473,6 +15307,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14487,6 +15322,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14501,6 +15337,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14515,6 +15352,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14529,6 +15367,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14543,6 +15382,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-build-testsummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14573,6 +15413,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-buildsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14587,6 +15428,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-buildsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14601,6 +15443,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-buildsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14615,6 +15458,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-buildsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14629,6 +15473,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-buildsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14682,6 +15527,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14696,6 +15542,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14710,6 +15557,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14724,6 +15572,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14738,6 +15587,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14752,6 +15602,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14766,6 +15617,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14780,6 +15632,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14794,6 +15647,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14808,6 +15662,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14822,6 +15677,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcanvas', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14859,6 +15715,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14873,6 +15730,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14887,6 +15745,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14901,6 +15760,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14915,6 +15775,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14929,6 +15790,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14943,6 +15805,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14957,6 +15820,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14971,6 +15835,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14985,6 +15850,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -14999,6 +15865,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15013,6 +15880,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15048,6 +15916,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15062,6 +15931,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15076,6 +15946,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15090,6 +15961,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15104,6 +15976,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15118,6 +15991,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15132,6 +16006,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15146,6 +16021,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15160,6 +16036,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15174,6 +16051,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentcommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15202,6 +16080,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15216,6 +16095,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15230,6 +16110,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15278,6 +16159,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15292,6 +16174,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15306,6 +16189,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15320,6 +16204,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15334,6 +16219,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15348,6 +16234,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15362,6 +16249,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15376,6 +16264,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15390,6 +16279,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15404,6 +16294,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15418,6 +16309,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15432,6 +16324,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15446,6 +16339,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15460,6 +16354,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15474,6 +16369,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15488,6 +16384,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15502,6 +16399,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15516,6 +16414,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15530,6 +16429,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15544,6 +16444,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15558,6 +16459,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15572,6 +16474,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15586,6 +16489,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15614,6 +16518,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentsidebar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15628,6 +16533,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentsidebar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15642,6 +16548,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-component-componentsidebar', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15682,6 +16589,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-componentsscreen-componentsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15696,6 +16604,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-componentsscreen-componentsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15710,6 +16619,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-componentsscreen-componentsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15724,6 +16634,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-componentsscreen-componentsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15738,6 +16649,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-componentsscreen-componentsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15783,6 +16695,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-errorscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15797,6 +16710,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-errorscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15811,6 +16725,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-errorscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15825,6 +16740,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-errorscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15839,6 +16755,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-errorscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15853,6 +16770,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-errorscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15877,6 +16795,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-noaccessscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15901,6 +16820,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-error-notfoundscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15925,6 +16845,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-installgithubappsuccessscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15953,6 +16874,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-installwebhookscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15967,6 +16889,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-installwebhookscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -15981,6 +16904,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-installwebhookscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16005,6 +16929,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-joinbetascreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16029,6 +16954,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-loadingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16059,6 +16985,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-loginscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16073,6 +17000,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-loginscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16087,6 +17015,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-loginscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16101,6 +17030,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-loginscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16129,6 +17059,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-loginscreen-loginbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16143,6 +17074,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-loginscreen-loginbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16157,6 +17089,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-loginscreen-loginbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16204,6 +17137,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-browserpicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16218,6 +17152,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-browserpicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16232,6 +17167,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-browserpicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16246,6 +17182,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-browserpicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16260,6 +17197,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-browserpicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16274,6 +17212,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-browserpicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16358,6 +17297,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16411,6 +17351,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16548,6 +17489,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16685,6 +17627,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16822,6 +17765,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -16963,6 +17907,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17100,6 +18045,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17237,6 +18183,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17378,6 +18325,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17411,6 +18359,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17425,6 +18374,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17439,6 +18389,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17453,6 +18404,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17467,6 +18419,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17481,6 +18434,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17495,6 +18449,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17509,6 +18464,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-managescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17548,6 +18504,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17562,6 +18519,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17576,6 +18534,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17590,6 +18549,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17604,6 +18564,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17618,6 +18579,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17632,6 +18594,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17646,6 +18609,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17660,6 +18624,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17674,6 +18639,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17688,6 +18654,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17702,6 +18669,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17716,6 +18684,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17730,6 +18699,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-uireview', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17774,6 +18744,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17788,6 +18759,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17802,6 +18774,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17816,6 +18789,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17830,6 +18804,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17844,6 +18819,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17858,6 +18834,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17872,6 +18849,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17886,6 +18864,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17900,6 +18879,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17914,6 +18894,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17928,6 +18909,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17942,6 +18924,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17956,6 +18939,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17970,6 +18954,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17984,6 +18969,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -17998,6 +18984,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18012,6 +18999,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18026,6 +19014,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-managescreen-visualtests', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18082,6 +19071,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-articles', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18119,6 +19109,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-companyscreen-aboutscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18143,6 +19134,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-companyscreen-jobsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18187,6 +19179,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparelayout', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18201,6 +19194,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparelayout', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18215,6 +19209,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparelayout', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18229,6 +19224,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparelayout', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18243,6 +19239,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparelayout', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18257,6 +19254,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparelayout', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18292,6 +19290,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18306,6 +19305,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18320,6 +19320,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18334,6 +19335,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18348,6 +19350,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18362,6 +19365,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18376,6 +19380,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18390,6 +19395,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18404,6 +19410,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18418,6 +19425,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-comparescreen-comparescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18442,6 +19450,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-cta', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18466,6 +19475,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-faq', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18493,6 +19503,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-feature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18507,6 +19518,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-feature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18531,6 +19543,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-featurecallout', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18575,6 +19588,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-featuresscreens-documentscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18605,6 +19619,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-componentexample', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18620,6 +19635,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-componentexample', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18634,6 +19650,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-componentexample', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18649,6 +19666,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-componentexample', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18663,6 +19681,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-componentexample', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18690,6 +19709,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-documentanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18704,6 +19724,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-documentanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18731,6 +19752,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-documentscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18746,6 +19768,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-documentscreen-documentscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18770,6 +19793,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-featuresscreens-featuresscreenshero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18799,6 +19823,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-featuresscreens-publishscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18827,6 +19852,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-publishscreen-feedbackanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18841,6 +19867,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-publishscreen-feedbackanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18855,6 +19882,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-publishscreen-feedbackanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18882,6 +19910,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-publishscreen-publishscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18897,6 +19926,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-publishscreen-publishscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18921,6 +19951,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-publishscreen-review', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18950,6 +19981,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-featuresscreens-testscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18978,6 +20010,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-testscreen-pinpointbugsanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -18992,6 +20025,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-testscreen-pinpointbugsanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19006,6 +20040,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-testscreen-pinpointbugsanimation', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19030,6 +20065,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-testscreen-snapshotexample', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19057,6 +20093,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-testscreen-testscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19071,6 +20108,7 @@ export const stories = { depth: 5, parent: 'webapp-screens-marketing-featuresscreens-testscreen-testscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19100,6 +20138,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-hero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19114,6 +20153,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-hero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19128,6 +20168,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-hero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19142,6 +20183,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-hero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19166,6 +20208,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-integrations', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19208,6 +20251,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-automatedworkflows', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19222,6 +20266,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-automatedworkflows', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19250,6 +20295,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-landingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19264,6 +20310,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-landingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19278,6 +20325,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-landingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19305,6 +20353,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-landingscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19319,6 +20368,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-landingscreenhero', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19343,6 +20393,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-landingscreen-notables', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19367,6 +20418,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingfooter', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19398,6 +20450,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19412,6 +20465,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19426,6 +20480,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19440,6 +20495,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19454,6 +20510,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19468,6 +20525,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19492,6 +20550,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-marketingpagetitle', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19532,6 +20591,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-personascreens-designsystemsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19556,6 +20616,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-personascreens-digitalagenciesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19580,6 +20641,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-personascreens-frontendteamsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19604,6 +20666,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-personascreens-personaheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19628,6 +20691,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-personascreens-storybookusersscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19667,6 +20731,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-pricingscreen-faqpricing', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19694,6 +20759,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-pricingscreen-prices', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19708,6 +20774,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-pricingscreen-prices', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19732,6 +20799,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-pricingscreen-pricingfeatures', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19759,6 +20827,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-pricingscreen-pricingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19773,6 +20842,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-marketing-pricingscreen-pricingscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19797,6 +20867,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-socialproof', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19824,6 +20895,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-testimonial', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19838,6 +20910,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-testimonial', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19862,6 +20935,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-testimonials', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19886,6 +20960,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-valueprop', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19914,6 +20989,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-workflows', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19928,6 +21004,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-workflows', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19942,6 +21019,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-marketing-workflows', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19971,6 +21049,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-notificationsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19985,6 +21064,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-notificationsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -19999,6 +21079,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-notificationsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20013,6 +21094,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-notificationsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20058,6 +21140,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-chooserepository', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20072,6 +21155,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-chooserepository', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20086,6 +21170,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-chooserepository', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20100,6 +21185,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-chooserepository', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20124,6 +21210,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-createproject', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20152,6 +21239,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-onboardingscreen-clickable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20166,6 +21254,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-onboardingscreen-clickable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20180,6 +21269,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-onboardingscreen-clickable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20208,6 +21298,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-projecttypepicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20222,6 +21313,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-projecttypepicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20236,6 +21328,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-projecttypepicker', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20265,6 +21358,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-setupprojectflow-clickable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20279,6 +21373,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-setupprojectflow-clickable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20293,6 +21388,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-setupprojectflow-clickable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20307,6 +21403,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-onboarding-setupprojectflow-clickable', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20331,6 +21428,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-preferencesupdatedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20409,6 +21507,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20423,6 +21522,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20437,6 +21537,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20451,6 +21552,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20465,6 +21567,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20479,6 +21582,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20493,6 +21597,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20507,6 +21612,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20534,6 +21640,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20548,6 +21655,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-activityitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20585,6 +21693,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20599,6 +21708,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20613,6 +21723,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20627,6 +21738,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20641,6 +21753,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20655,6 +21768,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20669,6 +21783,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20683,6 +21798,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20697,6 +21813,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20711,6 +21828,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20725,6 +21843,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20739,6 +21858,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-buildactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20782,6 +21902,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20796,6 +21917,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20810,6 +21932,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20824,6 +21947,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20838,6 +21962,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20852,6 +21977,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20866,6 +21992,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20880,6 +22007,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20894,6 +22022,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20908,6 +22037,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20922,6 +22052,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20936,6 +22067,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20950,6 +22082,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20964,6 +22097,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20978,6 +22112,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -20992,6 +22127,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21006,6 +22142,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21020,6 +22157,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-commentthreadactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21051,6 +22189,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-reviewactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21065,6 +22204,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-reviewactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21079,6 +22219,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-reviewactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21093,6 +22234,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-reviewactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21107,6 +22249,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-reviewactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21121,6 +22264,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-activity-reviewactivity', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21154,6 +22298,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21168,6 +22313,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21182,6 +22328,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21196,6 +22343,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21210,6 +22358,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21224,6 +22373,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21238,6 +22388,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21252,6 +22403,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-buildstatustooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21328,6 +22480,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21342,6 +22495,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21356,6 +22510,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21370,6 +22525,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21384,6 +22540,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21398,6 +22555,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21412,6 +22570,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21426,6 +22585,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21440,6 +22600,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21454,6 +22615,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21468,6 +22630,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21482,6 +22645,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21496,6 +22660,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21510,6 +22675,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21525,6 +22691,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21539,6 +22706,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21553,6 +22721,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21567,6 +22736,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21581,6 +22751,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21595,6 +22766,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21609,6 +22781,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21623,6 +22796,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21637,6 +22811,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21651,6 +22826,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21665,6 +22841,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21679,6 +22856,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21693,6 +22871,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21707,6 +22886,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21721,6 +22901,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21735,6 +22916,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21763,6 +22945,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21777,6 +22960,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21791,6 +22975,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21822,6 +23007,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthreads', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21836,6 +23022,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthreads', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21850,6 +23037,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthreads', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21864,6 +23052,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthreads', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21878,6 +23067,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthreads', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21892,6 +23082,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistactivecommentthreads', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21916,6 +23107,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistbuilderrors', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21944,6 +23136,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklisterroreddiffs', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21958,6 +23151,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklisterroreddiffs', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -21972,6 +23166,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklisterroreddiffs', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22008,6 +23203,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22022,6 +23218,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22036,6 +23233,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22050,6 +23248,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22064,6 +23263,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22078,6 +23278,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22092,6 +23293,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22106,6 +23308,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22120,6 +23323,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22134,6 +23338,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22149,6 +23354,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22176,6 +23382,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistitemheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22190,6 +23397,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistitemheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22221,6 +23429,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistpendingreviews', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22235,6 +23444,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistpendingreviews', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22249,6 +23459,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistpendingreviews', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22263,6 +23474,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistpendingreviews', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22277,6 +23489,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistpendingreviews', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22291,6 +23504,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistpendingreviews', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22319,6 +23533,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistspeccolumn', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22333,6 +23548,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistspeccolumn', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22347,6 +23563,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistspeccolumn', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22377,6 +23594,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistvisualchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22391,6 +23609,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistvisualchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22405,6 +23624,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistvisualchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22419,6 +23639,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistvisualchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22433,6 +23654,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-checklist-checklistvisualchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22473,6 +23695,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uireviewfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22487,6 +23710,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uireviewfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22529,6 +23753,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22543,6 +23768,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22557,6 +23783,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22571,6 +23798,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22585,6 +23813,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22599,6 +23828,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22613,6 +23843,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22627,6 +23858,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22641,6 +23873,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22655,6 +23888,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22669,6 +23903,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22683,6 +23918,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22698,6 +23934,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22713,6 +23950,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22727,6 +23965,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22741,6 +23980,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22755,6 +23995,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-pullrequest-features-uitestsfeature', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22788,6 +24029,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22802,6 +24044,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22816,6 +24059,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22830,6 +24074,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22844,6 +24089,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22858,6 +24104,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22872,6 +24119,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22886,6 +24134,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-nocomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22916,6 +24165,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22930,6 +24180,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22944,6 +24195,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22958,6 +24210,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -22972,6 +24225,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23001,6 +24255,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23015,6 +24270,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23029,6 +24285,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23043,6 +24300,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangecommentthread', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23084,6 +24342,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23098,6 +24357,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23112,6 +24372,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23126,6 +24387,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23140,6 +24402,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23154,6 +24417,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23168,6 +24432,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23182,6 +24447,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23196,6 +24462,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23210,6 +24477,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23224,6 +24492,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23238,6 +24507,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23252,6 +24522,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23266,6 +24537,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23280,6 +24552,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23294,6 +24567,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchangeitem', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23331,6 +24605,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23345,6 +24620,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23359,6 +24635,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23373,6 +24650,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23387,6 +24665,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23401,6 +24680,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23415,6 +24695,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23429,6 +24710,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23443,6 +24725,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23457,6 +24740,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23471,6 +24755,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23485,6 +24770,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchanges', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23527,6 +24813,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23541,6 +24828,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23555,6 +24843,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23569,6 +24858,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23583,6 +24873,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23597,6 +24888,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23611,6 +24903,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23625,6 +24918,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23639,6 +24933,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23653,6 +24948,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23667,6 +24963,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23681,6 +24978,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23695,6 +24993,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23709,6 +25008,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23723,6 +25023,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23737,6 +25038,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23751,6 +25053,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestchecktooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23782,6 +25085,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23796,6 +25100,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23810,6 +25115,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23824,6 +25130,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23838,6 +25145,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23852,6 +25160,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestcomponents', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23876,6 +25185,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestexplainer', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23907,6 +25217,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23921,6 +25232,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23935,6 +25247,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23949,6 +25262,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23963,6 +25277,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -23977,6 +25292,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24004,6 +25320,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestparticipants', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24018,6 +25335,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestparticipants', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24056,6 +25374,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24070,6 +25389,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24084,6 +25404,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24098,6 +25419,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24112,6 +25434,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24126,6 +25449,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24140,6 +25464,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24154,6 +25479,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24168,6 +25494,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24182,6 +25509,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24196,6 +25524,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24210,6 +25539,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24224,6 +25554,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24264,6 +25595,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24278,6 +25610,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24292,6 +25625,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24306,6 +25640,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24320,6 +25655,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24334,6 +25670,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24348,6 +25685,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24362,6 +25700,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24376,6 +25715,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24390,6 +25730,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24404,6 +25745,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24418,6 +25760,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24432,6 +25775,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24446,6 +25790,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24460,6 +25805,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-pullrequestscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24491,6 +25837,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-reviewbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24505,6 +25852,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-reviewbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24519,6 +25867,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-reviewbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24533,6 +25882,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-reviewbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24547,6 +25897,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-reviewbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24561,6 +25912,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-reviewbutton', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24590,6 +25942,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-selectreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24604,6 +25957,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-selectreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24618,6 +25972,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-selectreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24632,6 +25987,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-pullrequest-selectreviewers', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24661,6 +26017,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-pullrequestsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24675,6 +26032,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-pullrequestsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24689,6 +26047,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-pullrequestsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24703,6 +26062,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-pullrequestsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24732,6 +26092,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-settingsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24746,6 +26107,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-settingsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24760,6 +26122,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-settingsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24774,6 +26137,7 @@ export const stories = { depth: 2, parent: 'webapp-screens-settingsscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24833,6 +26197,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-catchchangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24847,6 +26212,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-catchchangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24861,6 +26227,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-catchchangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24875,6 +26242,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-catchchangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24903,6 +26271,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-changesspottedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24917,6 +26286,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-changesspottedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24931,6 +26301,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-changesspottedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24958,6 +26329,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-changessummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -24972,6 +26344,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-changessummary', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25000,6 +26373,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-instructions', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25014,6 +26388,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-instructions', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25028,6 +26403,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-catchchanges-instructions', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25072,6 +26448,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-builderrorlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25086,6 +26463,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-builderrorlist', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25116,6 +26494,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-confirmationsuccess', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25130,6 +26509,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-confirmationsuccess', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25144,6 +26524,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-confirmationsuccess', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25158,6 +26539,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-confirmationsuccess', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25172,6 +26554,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-confirmationsuccess', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25200,6 +26583,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-instructions', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25214,6 +26598,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-instructions', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25228,6 +26613,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-instructions', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25257,6 +26643,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishfailedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25271,6 +26658,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishfailedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25285,6 +26673,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishfailedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25299,6 +26688,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishfailedscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25327,6 +26717,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishstorybookscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25341,6 +26732,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishstorybookscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25355,6 +26747,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishstorybookscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25383,6 +26776,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishsuccessscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25397,6 +26791,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishsuccessscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25411,6 +26806,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-publishstorybook-publishsuccessscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25453,6 +26849,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-comparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25467,6 +26864,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-comparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25494,6 +26892,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-comparisoncomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25508,6 +26907,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-comparisoncomments', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25536,6 +26936,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-feedbackscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25550,6 +26951,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-feedbackscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25564,6 +26966,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-feedbackscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25593,6 +26996,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-verifychangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25607,6 +27011,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-verifychangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25621,6 +27026,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-verifychangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25635,6 +27041,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-verifychanges-verifychangesscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25676,6 +27083,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-wrapup-mergechecksscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25690,6 +27098,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-wrapup-mergechecksscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25704,6 +27113,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-wrapup-mergechecksscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25732,6 +27142,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-wrapup-setupcompletescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25746,6 +27157,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-wrapup-setupcompletescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25760,6 +27172,7 @@ export const stories = { depth: 4, parent: 'webapp-screens-setup-wrapup-setupcompletescreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25801,6 +27214,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-capturewarningtooltip', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25842,6 +27256,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25856,6 +27271,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25870,6 +27286,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25884,6 +27301,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25898,6 +27316,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25912,6 +27331,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25926,6 +27346,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25940,6 +27361,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25954,6 +27376,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25968,6 +27391,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25982,6 +27406,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -25996,6 +27421,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26010,6 +27436,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26024,6 +27451,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26038,6 +27466,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26052,6 +27481,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-reviewbuttons', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26107,6 +27537,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26121,6 +27552,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26135,6 +27567,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26149,6 +27582,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26163,6 +27597,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26177,6 +27612,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26191,6 +27627,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26206,6 +27643,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26220,6 +27658,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26234,6 +27673,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26248,6 +27688,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26262,6 +27703,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26276,6 +27718,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26290,6 +27733,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26304,6 +27748,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26318,6 +27763,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26332,6 +27778,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26346,6 +27793,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26360,6 +27808,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26374,6 +27823,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26388,6 +27838,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26403,6 +27854,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26417,6 +27869,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26431,6 +27884,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26445,6 +27899,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26459,6 +27914,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26473,6 +27929,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26487,6 +27944,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26501,6 +27959,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26515,6 +27974,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotcomparison', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26558,6 +28018,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26572,6 +28033,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26586,6 +28048,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26600,6 +28063,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26614,6 +28078,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26628,6 +28093,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26642,6 +28108,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26656,6 +28123,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26670,6 +28138,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26684,6 +28153,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26698,6 +28168,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26712,6 +28183,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26726,6 +28198,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26740,6 +28213,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26754,6 +28228,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26768,6 +28243,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26782,6 +28258,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26796,6 +28273,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotheader', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26829,6 +28307,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26843,6 +28322,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26857,6 +28337,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26871,6 +28352,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26885,6 +28367,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26899,6 +28382,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26913,6 +28397,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26927,6 +28412,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshothtmldiff', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26981,6 +28467,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -26995,6 +28482,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27009,6 +28497,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27023,6 +28512,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27037,6 +28527,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27051,6 +28542,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27065,6 +28557,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27079,6 +28572,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27093,6 +28587,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27107,6 +28602,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27121,6 +28617,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27135,6 +28632,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27149,6 +28647,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27163,6 +28662,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27177,6 +28677,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27191,6 +28692,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27205,6 +28707,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27219,6 +28722,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27233,6 +28737,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27247,6 +28752,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27261,6 +28767,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27275,6 +28782,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27289,6 +28797,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27303,6 +28812,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27317,6 +28827,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27331,6 +28842,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27345,6 +28857,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27359,6 +28872,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, @@ -27373,6 +28887,7 @@ export const stories = { depth: 3, parent: 'webapp-screens-snapshot-snapshotscreen', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, }, diff --git a/lib/ui/src/components/sidebar/mockdata.ts b/lib/ui/src/components/sidebar/mockdata.ts index 61bed943ac4..5e863f6cf7a 100644 --- a/lib/ui/src/components/sidebar/mockdata.ts +++ b/lib/ui/src/components/sidebar/mockdata.ts @@ -16,6 +16,7 @@ export const mockDataset: MockDataSet = { '2-21': { isRoot: false, isLeaf: true, + prepared: true, isComponent: false, id: '2-21', depth: 1, @@ -28,6 +29,7 @@ export const mockDataset: MockDataSet = { '2-22': { isRoot: false, isLeaf: true, + prepared: true, isComponent: false, id: '2-22', depth: 1, @@ -69,6 +71,7 @@ export const mockDataset: MockDataSet = { '1-12-121': { isRoot: false, isLeaf: true, + prepared: true, isComponent: false, id: '1-12-121', parent: '1-12', @@ -81,6 +84,7 @@ export const mockDataset: MockDataSet = { '1-12-122': { isRoot: false, isLeaf: true, + prepared: true, isComponent: false, id: '1-12-122', parent: '1-12', @@ -102,6 +106,7 @@ export const mockDataset: MockDataSet = { '3-31': { isRoot: false, isLeaf: true, + prepared: true, isComponent: false, id: '3-31', depth: 1, @@ -124,6 +129,7 @@ export const mockDataset: MockDataSet = { '3-32-321': { isRoot: false, isLeaf: true, + prepared: true, isComponent: false, id: '3-32-321', depth: 2, @@ -136,6 +142,7 @@ export const mockDataset: MockDataSet = { '3-32-322': { isRoot: false, isLeaf: true, + prepared: true, isComponent: false, id: '3-32-322', depth: 2, @@ -170,6 +177,7 @@ export const mockDataset: MockDataSet = { depth: 1, name: 'Child A1', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, parent: '1', @@ -182,6 +190,7 @@ export const mockDataset: MockDataSet = { depth: 2, name: 'GrandChild A1.1', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, parent: '1-12', @@ -194,6 +203,7 @@ export const mockDataset: MockDataSet = { depth: 2, name: 'GrandChild A1.2', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, parent: '1-12', @@ -216,6 +226,7 @@ export const mockDataset: MockDataSet = { depth: 1, name: 'Child B1', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, parent: '2', @@ -228,6 +239,7 @@ export const mockDataset: MockDataSet = { depth: 1, name: 'Child B2', isLeaf: true, + prepared: true, isComponent: false, isRoot: false, parent: '2', From 63e25364864c6f38996e5b6d05eabc988398061f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 5 Sep 2021 11:17:01 +1000 Subject: [PATCH 163/285] Update `prepareStory` tests --- lib/store/src/prepareStory.test.ts | 127 +++++++++++++++++++---------- 1 file changed, 85 insertions(+), 42 deletions(-) diff --git a/lib/store/src/prepareStory.test.ts b/lib/store/src/prepareStory.test.ts index e747f70697c..b30b6f52c7b 100644 --- a/lib/store/src/prepareStory.test.ts +++ b/lib/store/src/prepareStory.test.ts @@ -1,18 +1,44 @@ import addons, { HooksContext } from '@storybook/addons'; +import { AnyFramework, ArgsEnhancer, SBObjectType, SBScalarType } from '@storybook/csf'; import { prepareStory } from './prepareStory'; -import { ArgsEnhancer } from './types'; + +jest.mock('global', () => ({ + ...(jest.requireActual('global') as any), + FEATURES: { + breakingChangesV7: true, + }, +})); const id = 'id'; const name = 'name'; const title = 'title'; const render = (args: any) => {}; +const stringType: SBScalarType = { name: 'string' }; +const numberType: SBScalarType = { name: 'number' }; +const booleanType: SBScalarType = { name: 'boolean' }; +const complexType: SBObjectType = { + name: 'object', + value: { + complex: { + name: 'object', + value: { + object: { + name: 'array', + value: { name: 'string' }, + }, + }, + }, + }, +}; + describe('prepareStory', () => { describe('parameters', () => { it('are combined in the right order', () => { const { parameters } = prepareStory( { id, name, parameters: { a: 'story', nested: { z: 'story' } } }, { + id, title, parameters: { a: { name: 'component' }, @@ -41,7 +67,7 @@ describe('prepareStory', () => { }); it('sets a value even if metas do not have parameters', () => { - const { parameters } = prepareStory({ id, name }, { title }, { render }); + const { parameters } = prepareStory({ id, name }, { id, title }, { render }); expect(parameters).toEqual({ __isArgsStory: true }); }); @@ -49,7 +75,7 @@ describe('prepareStory', () => { it('does not set `__isArgsStory` if `passArgsFirst` is disabled', () => { const { parameters } = prepareStory( { id, name, parameters: { passArgsFirst: false } }, - { title }, + { id, title }, { render } ); @@ -57,7 +83,7 @@ describe('prepareStory', () => { }); it('does not set `__isArgsStory` if `render` does not take args', () => { - const { parameters } = prepareStory({ id, name }, { title }, { render: () => {} }); + const { parameters } = prepareStory({ id, name }, { id, title }, { render: () => {} }); expect(parameters).toEqual({ __isArgsStory: false }); }); @@ -68,6 +94,7 @@ describe('prepareStory', () => { const { initialArgs } = prepareStory( { id, name, args: { a: 'story', nested: { z: 'story' } } }, { + id, title, args: { a: 'component', @@ -95,7 +122,7 @@ describe('prepareStory', () => { }); it('sets a value even if metas do not have args', () => { - const { initialArgs } = prepareStory({ id, name }, { title }, { render }); + const { initialArgs } = prepareStory({ id, name }, { id, title }, { render }); expect(initialArgs).toEqual({}); }); @@ -111,15 +138,19 @@ describe('prepareStory', () => { arg7: false, }, argTypes: { - arg1: { defaultValue: 'arg1' }, - arg2: { defaultValue: 2 }, - arg3: { defaultValue: { complex: { object: ['type'] } } }, - arg4: {}, - arg5: {}, - arg6: { defaultValue: 0 }, // See https://github.com/storybookjs/storybook/issues/12767 } + arg1: { name: 'arg1', type: stringType, defaultValue: 'arg1' }, + arg2: { name: 'arg2', type: numberType, defaultValue: 2 }, + arg3: { + name: 'arg3', + type: complexType, + defaultValue: { complex: { object: ['type'] } }, + }, + arg4: { name: 'arg4', type: stringType }, + arg5: { name: 'arg5', type: stringType }, + arg6: { name: 'arg6', type: numberType, defaultValue: 0 }, // See https://github.com/storybookjs/storybook/issues/12767 } }, }, - { title }, + { id, title }, { render: () => {} } ); @@ -136,18 +167,18 @@ describe('prepareStory', () => { describe('argsEnhancers', () => { it('are applied in the right order', () => { const run = []; - const enhancerOne: ArgsEnhancer = () => { + const enhancerOne: ArgsEnhancer = () => { run.push(1); return {}; }; - const enhancerTwo: ArgsEnhancer = () => { + const enhancerTwo: ArgsEnhancer = () => { run.push(2); return {}; }; prepareStory( { id, name }, - { title }, + { id, title }, { render, argsEnhancers: [enhancerOne, enhancerTwo] } ); @@ -159,7 +190,7 @@ describe('prepareStory', () => { const { initialArgs } = prepareStory( { id, name, args: { a: 'b' } }, - { title }, + { id, title }, { render, argsEnhancers: [enhancer] } ); @@ -173,7 +204,7 @@ describe('prepareStory', () => { const { initialArgs } = prepareStory( { id, name, args: { a: 'b' } }, - { title }, + { id, title }, { render, argsEnhancers: [enhancerOne, enhancerTwo] } ); @@ -191,31 +222,39 @@ describe('prepareStory', () => { describe('argTypes', () => { it('are combined in the right order', () => { const { argTypes } = prepareStory( - { id, name, argTypes: { a: { name: 'story' }, nested: { z: { name: 'story' } } } }, { + id, + name, + argTypes: { + a: { name: 'a-story', type: booleanType }, + nested: { name: 'nested', type: booleanType, a: 'story' }, + }, + }, + { + id, title, argTypes: { - a: { name: 'component' }, - b: { name: 'component' }, - nested: { z: { name: 'component' }, y: { name: 'component' } }, + a: { name: 'a-component', type: stringType }, + b: { name: 'b-component', type: stringType }, + nested: { name: 'nested', type: booleanType, a: 'component', b: 'component' }, }, }, { render, argTypes: { - a: { name: 'global' }, - b: { name: 'global' }, - c: { name: 'global' }, - nested: { z: { name: 'global' }, x: { name: 'global' } }, + a: { name: 'a-global', type: numberType }, + b: { name: 'b-global', type: numberType }, + c: { name: 'c-global', type: numberType }, + nested: { name: 'nested', type: booleanType, a: 'global', b: 'global', c: 'global' }, }, } ); expect(argTypes).toEqual({ - a: { name: 'story' }, - b: { name: 'component' }, - c: { name: 'global' }, - nested: { z: { name: 'story' }, y: { name: 'component' }, x: { name: 'global' } }, + a: { name: 'a-story', type: booleanType }, + b: { name: 'b-component', type: stringType }, + c: { name: 'c-global', type: numberType }, + nested: { name: 'nested', type: booleanType, a: 'story', b: 'component', c: 'global' }, }); }); describe('argTypesEnhancers', () => { @@ -223,7 +262,7 @@ describe('prepareStory', () => { const enhancer = jest.fn((context) => ({ ...context.argTypes, c: { name: 'd' } })); const { argTypes } = prepareStory( { id, name, argTypes: { a: { name: 'b' } } }, - { title }, + { id, title }, { render, argTypesEnhancers: [enhancer] } ); @@ -237,7 +276,7 @@ describe('prepareStory', () => { const enhancer = jest.fn(() => ({ c: { name: 'd' } })); const { argTypes } = prepareStory( { id, name, argTypes: { a: { name: 'b' } } }, - { title }, + { id, title }, { render, argTypesEnhancers: [enhancer] } ); @@ -252,7 +291,7 @@ describe('prepareStory', () => { const secondEnhancer = jest.fn((context) => ({ ...context.argTypes, e: { name: 'f' } })); const { argTypes } = prepareStory( { id, name, argTypes: { a: { name: 'b' } } }, - { title }, + { id, title }, { render, argTypesEnhancers: [firstEnhancer, secondEnhancer] } ); @@ -270,7 +309,11 @@ describe('prepareStory', () => { describe('applyLoaders', () => { it('awaits the result of a loader', async () => { const loader = jest.fn(async () => new Promise((r) => setTimeout(() => r({ foo: 7 }), 100))); - const { applyLoaders } = prepareStory({ id, name, loaders: [loader] }, { title }, { render }); + const { applyLoaders } = prepareStory( + { id, name, loaders: [loader] }, + { id, title }, + { render } + ); const storyContext = { context: 'value' } as any; const loadedContext = await applyLoaders(storyContext); @@ -289,7 +332,7 @@ describe('prepareStory', () => { const { applyLoaders } = prepareStory( { id, name, loaders: [storyLoader] }, - { title, loaders: [componentLoader] }, + { id, title, loaders: [componentLoader] }, { render, loaders: [globalLoader] } ); @@ -308,7 +351,7 @@ describe('prepareStory', () => { async () => new Promise((r) => setTimeout(() => r({ foo: 3 }), 50)), ]; - const { applyLoaders } = prepareStory({ id, name, loaders }, { title }, { render }); + const { applyLoaders } = prepareStory({ id, name, loaders }, { id, title }, { render }); const storyContext = { context: 'value' } as any; const loadedContext = await applyLoaders(storyContext); @@ -328,12 +371,12 @@ describe('prepareStory', () => { id, name, argTypes: { - one: { mapping: { 1: 'mapped' } }, - two: { mapping: { 1: 'no match' } }, + one: { name: 'one', type: { name: 'string' }, mapping: { 1: 'mapped' } }, + two: { name: 'two', type: { name: 'string' }, mapping: { 1: 'no match' } }, }, args: { one: 1, two: 2, three: 3 }, }, - { title }, + { id, title }, { render: renderMock } ); @@ -349,7 +392,7 @@ describe('prepareStory', () => { const renderMock = jest.fn(); const firstStory = prepareStory( { id, name, args: { a: 1 }, parameters: { passArgsFirst: true } }, - { title }, + { id, title }, { render: renderMock } ); @@ -361,7 +404,7 @@ describe('prepareStory', () => { const secondStory = prepareStory( { id, name, args: { a: 1 }, parameters: { passArgsFirst: false } }, - { title }, + { id, title }, { render: renderMock } ); @@ -382,7 +425,7 @@ describe('prepareStory', () => { name, decorators: [storyDecorator], }, - { title, decorators: [componentDecorator] }, + { id, title, decorators: [componentDecorator] }, { render: renderMock, decorators: [globalDecorator] } ); @@ -406,7 +449,7 @@ describe('prepareStory', () => { await new Promise((r) => setTimeout(r, 0)); // Ensure this puts an async boundary in inner(); }); - const { runPlayFunction } = prepareStory({ id, name, play }, { title }, { render }); + const { runPlayFunction } = prepareStory({ id, name, play }, { id, title }, { render }); await runPlayFunction(); expect(play).toHaveBeenCalled(); From a154975ba31177b64d966245478759a99db34b3c Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 5 Sep 2021 11:18:07 +1000 Subject: [PATCH 164/285] Simplify start tests by turning on breaking v7 changes --- lib/core-client/src/preview/start.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index 871eee370ec..7593a3eb96d 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -23,6 +23,9 @@ jest.mock('global', () => ({ search: '?id=*', }, }, + FEATURES: { + breakingChangesV7: true, + }, })); jest.mock('@storybook/channel-postmessage', () => () => mockChannel); From e1b4d1a71a495292c21124cb4e06b7f87897907a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 5 Sep 2021 11:18:53 +1000 Subject: [PATCH 165/285] Update vue snapshots with backcompat parameters --- .../src/stories/__snapshots__/core.stories.storyshot | 5 ++++- .../__snapshots__/custom-decorators.stories.storyshot | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot index c5dce74f714..c6f10f6e74e 100644 --- a/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/core.stories.storyshot @@ -12,7 +12,10 @@ exports[`Storyshots Core/Parameters passed to story 1`] = ` "globalParameter": "globalParameter", "chapterParameter": "chapterParameter", "storyParameter": "storyParameter", - "__isArgsStory": true + "__isArgsStory": true, + "__id": "core-parameters--passed-to-story", + "args": {}, + "argTypes": {} } diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot index 975094a2635..737307a65ab 100644 --- a/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot @@ -57,7 +57,10 @@ exports[`Storyshots Custom/Decorator for Vue With Data 1`] = ` }, "framework": "vue", "globalParameter": "globalParameter", - "__isArgsStory": true + "__isArgsStory": true, + "__id": "custom-decorator-for-vue--with-data", + "args": {}, + "argTypes": {} }, "initialArgs": {}, "argTypes": {}, From d06b4a6c906aaeaf24593691b5fafae500fa8190 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 5 Sep 2021 11:23:24 +1000 Subject: [PATCH 166/285] Ensure user's config is last on the list. And update snapshots with cosmetic changes to entry points (and ordering HMR to the end, which I think is OK) --- .../src/preview/iframe-webpack.config.ts | 2 +- .../src/preview/iframe-webpack.config.ts | 2 +- .../cra-ts-essentials_preview-dev | 18 +++++++-------- .../cra-ts-essentials_preview-prod | 16 +++++++------- .../html-kitchen-sink_preview-dev | 20 ++++++++--------- .../html-kitchen-sink_preview-prod | 18 +++++++-------- .../src/__snapshots__/vue-3-cli_preview-dev | 22 ++++++++++--------- .../src/__snapshots__/vue-3-cli_preview-prod | 20 +++++++++-------- .../web-components-kitchen-sink_preview-dev | 20 ++++++++--------- .../web-components-kitchen-sink_preview-prod | 18 +++++++-------- 10 files changed, 80 insertions(+), 76 deletions(-) diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index c94b8207b22..49871c8e115 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -82,8 +82,8 @@ export default async (options: Options & Record): Promise): Promise Date: Mon, 6 Sep 2021 07:41:06 +1000 Subject: [PATCH 167/285] Updated `caniuse` --- yarn.lock | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7ac6d4b0607..039a216286a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14729,17 +14729,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001032, caniuse-lite@npm:^1.0.30001035, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001125, caniuse-lite@npm:^1.0.30001181": - version: 1.0.30001191 - resolution: "caniuse-lite@npm:1.0.30001191" - checksum: 278ef87e34ef4cf2d188153471999e86f1e55f3c5827fe81ef19ab18668ba921f0080a88d94f8d59e78c6e2e0e82e4fa55ca3b8923afda1dee4477ea12220080 - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001219": - version: 1.0.30001228 - resolution: "caniuse-lite@npm:1.0.30001228" - checksum: d6ab115abd93789fe0919773f108a2fbd2efb4b6abe802d29d68655756ec82e6b4dd9a2728a629ae39060eac3e3b094c7cb4899fc3454a274bc04e547d770c34 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001032, caniuse-lite@npm:^1.0.30001035, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001125, caniuse-lite@npm:^1.0.30001181, caniuse-lite@npm:^1.0.30001219": + version: 1.0.30001254 + resolution: "caniuse-lite@npm:1.0.30001254" + checksum: 204c183df2556bbd8d12c104c08dfa35952c7fe20afc9de23cd5898f5f30edddd80308f452b3d3c2c032730595f0dae46c863ef5c95ca94800a37cd6b41d240f languageName: node linkType: hard From afcd33d110539042ab56ec0901db773ccb6d5c14 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 07:44:19 +1000 Subject: [PATCH 168/285] Drop unused linting comments --- addons/docs/src/blocks/ArgsTable.tsx | 1 - app/react/src/client/preview/types.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index 5c77222f2c4..214b84e937f 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -1,4 +1,3 @@ -/* eslint-disable no-underscore-dangle */ import React, { FC, useContext, useEffect, useState, useCallback } from 'react'; import mapValues from 'lodash/mapValues'; import { diff --git a/app/react/src/client/preview/types.ts b/app/react/src/client/preview/types.ts index 1f7c93a7dbb..43774d0c8a7 100644 --- a/app/react/src/client/preview/types.ts +++ b/app/react/src/client/preview/types.ts @@ -1,6 +1,5 @@ import { ReactElement } from 'react'; -// eslint-disable-next-line import/no-extraneous-dependencies export type { RenderContext } from '@storybook/store'; export type { StoryContext } from '@storybook/csf'; From 37e7c8f9606d32feebedb2c4ab1d70bfc83cbb45 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 07:49:21 +1000 Subject: [PATCH 169/285] Add `StoryStore.getStoriesJsonData()` --- lib/store/src/StoryStore.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index cfc04dc20de..0f6619444ea 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -7,6 +7,8 @@ import { GlobalAnnotations, ComponentTitle, } from '@storybook/csf'; +import mapValues from 'lodash/mapValues'; +import pick from 'lodash/pick'; import { StoriesListStore } from './StoriesListStore'; import { ArgsStore } from './ArgsStore'; @@ -284,6 +286,22 @@ export class StoryStore { }; } + // TODO -- do we need this? + getStoriesJsonData = () => { + const value = this.getSetStoriesPayload(); + const allowedParameters = ['fileName', 'docsOnly', 'framework', '__id', '__isArgsStory']; + + return { + v: 2, + globalParameters: pick(value.globalParameters, allowedParameters), + kindParameters: mapValues(value.kindParameters, (v) => pick(v, allowedParameters)), + stories: mapValues(value.stories, (v: any) => ({ + ...pick(v, ['id', 'name', 'kind', 'story']), + parameters: pick(v.parameters, allowedParameters), + })), + }; + }; + raw() { return this.extract().map(({ id }: { id: StoryId }) => this.fromId(id)); } From 1567164519b1edfb7b50db304e8ff9bd81d4b27d Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 08:26:48 +1000 Subject: [PATCH 170/285] Remove a lot of TODOs, clean up --- addons/docs/src/blocks/Source.tsx | 12 +----------- .../storyshots-core/src/frameworks/Loader.ts | 1 - app/svelte/src/client/preview/render.ts | 1 - lib/api/src/lib/stories.ts | 2 -- lib/api/src/modules/stories.ts | 6 ++---- lib/client-api/src/ClientApi.ts | 1 - lib/core-server/src/utils/stories-json.ts | 1 - lib/store/src/StoryStore.ts | 1 - lib/store/src/index.ts | 1 - lib/web-preview/src/WebPreview.test.ts | 5 ----- 10 files changed, 3 insertions(+), 28 deletions(-) diff --git a/addons/docs/src/blocks/Source.tsx b/addons/docs/src/blocks/Source.tsx index add66360f8c..51012163380 100644 --- a/addons/docs/src/blocks/Source.tsx +++ b/addons/docs/src/blocks/Source.tsx @@ -44,17 +44,7 @@ type NoneProps = CommonProps; type SourceProps = SingleSourceProps | MultiSourceProps | CodeProps | NoneProps; const getStory = (storyId: StoryId, docsContext: DocsContextProps): Story | null => { - const { storyById } = docsContext; - const story = storyById(storyId); - - // TODO we could move this warning to docsContext.storyById() et al. - if (!story) { - // Fallback if we can't get the story data for this story - logger.warn(`Unable to find information for story ID '${storyId}'`); - return null; - } - - return story; + return docsContext.storyById(storyId); }; const getSourceState = (storyIds: string[], docsContext: DocsContextProps) => { diff --git a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts index f296bc0aa89..0d15defea34 100644 --- a/addons/storyshots/storyshots-core/src/frameworks/Loader.ts +++ b/addons/storyshots/storyshots-core/src/frameworks/Loader.ts @@ -18,7 +18,6 @@ export interface ClientApi raw: ClientApiClass['raw']; } -// TODO -- this is untyped for now, we could import each framework's AnyFramework type export interface Loader { load: ( options: StoryshotsOptions diff --git a/app/svelte/src/client/preview/render.ts b/app/svelte/src/client/preview/render.ts index 8e3a64cff02..aa1934a21c7 100644 --- a/app/svelte/src/client/preview/render.ts +++ b/app/svelte/src/client/preview/render.ts @@ -15,7 +15,6 @@ function cleanUpPreviousStory() { previousComponent = null; } -// TODO -- what is the type of storyFn result? export default function render( { storyFn, kind, name, showMain, showError }: RenderContext, domElement: HTMLElement diff --git a/lib/api/src/lib/stories.ts b/lib/api/src/lib/stories.ts index 291403e5497..eb01725e86e 100644 --- a/lib/api/src/lib/stories.ts +++ b/lib/api/src/lib/stories.ts @@ -178,8 +178,6 @@ export const transformStoriesListToStoriesHash = ( id, kind: title, name, - // TODO -- does the manager use this? Should we wait for this to come over with parameters - // and store `importPath` unchanged or not at all (given it is a preview "concern") parameters: { fileName: importPath, options: {} }, }; return acc; diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index 282ecb10797..27cda1c3a2a 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -161,8 +161,7 @@ export const init: ModuleFn = ({ return parameterName ? parameters[parameterName] : parameters; } - // TODO -- is this right? - return null; + return {}; } return null; @@ -350,9 +349,8 @@ export const init: ModuleFn = ({ }); }, fetchStoryList: async () => { - // TODO where to get endpoint from? + // This needs some fleshing out as part of the stories list server project const result = await global.fetch('/stories.json'); - // TODO deal with errors const storyList = (await result.json()) as StoriesListJson; await fullAPI.setStoryList(storyList); diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index b2351a609ac..95ee0385bda 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -413,7 +413,6 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m Object.entries(namedExports) .filter(([key]) => isExportStory(key, defaultExport)) .forEach(([key, storyExport]: [string, any]) => { - // TODO -- this little block of code is common with `processCSFFile` const exportName = storyNameFromExport(key); const id = storyExport.parameters?.__id || toId(componentId || title, exportName); const name = diff --git a/lib/core-server/src/utils/stories-json.ts b/lib/core-server/src/utils/stories-json.ts index b7d60e5edbf..11059fdefe4 100644 --- a/lib/core-server/src/utils/stories-json.ts +++ b/lib/core-server/src/utils/stories-json.ts @@ -5,7 +5,6 @@ import { logger } from '@storybook/node-logger'; import { resolvePathInStorybookCache, Options, normalizeStories } from '@storybook/core-common'; import { readCsfOrMdx } from '@storybook/csf-tools'; -// TODO -- use proper types for these? share with StoriesListStory? interface ExtractedStory { title: string; name: string; diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 0f6619444ea..574349e5cd0 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -286,7 +286,6 @@ export class StoryStore { }; } - // TODO -- do we need this? getStoriesJsonData = () => { const value = this.getSetStoriesPayload(); const allowedParameters = ['fileName', 'docsOnly', 'framework', '__id', '__isArgsStory']; diff --git a/lib/store/src/index.ts b/lib/store/src/index.ts index c0eec7f8d26..634d84422b1 100644 --- a/lib/store/src/index.ts +++ b/lib/store/src/index.ts @@ -7,7 +7,6 @@ export { inferControls } from './inferControls'; export * from './types'; -// TODO -- do we want to rexport everything here? What is actually used? export * from './hooks'; export * from './decorators'; export * from './args'; diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index 068dd911169..14c5c9427fe 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -123,9 +123,6 @@ describe('WebPreview', () => { foo: 'url', }); }); - - // TODO - // it('emits SET_STORIES if configured', async () => { }); }); describe('initial selection', () => { @@ -1387,7 +1384,6 @@ describe('WebPreview', () => { viewMode: 'story', }); - // TODO: not sure if thes event makes sense here either await waitForEvents([Events.STORY_PREPARED]); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_PREPARED, { id: 'component-one--a', @@ -1814,7 +1810,6 @@ describe('WebPreview', () => { }); }); - // TODO -- also we need test for when the CSF file no longer exists (story list changed) describe('if the story no longer exists', () => { const { a, ...componentOneExportsWithoutA } = componentOneExports; const newImportFn = jest.fn(async (path) => { From 263b005669b6e0ee785fb0e6e053509448a737cb Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 09:22:26 +1000 Subject: [PATCH 171/285] Don't use title exports in non v7 store --- examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx | 2 ++ lib/client-api/src/ClientApi.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx b/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx index 38a698e463a..aec839bc4e6 100644 --- a/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx +++ b/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx @@ -2,7 +2,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; import { Button } from './Button'; +console.log('HERE'); export default { + title: 'Button', component: Button, }; diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 95ee0385bda..fad8411a327 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -404,7 +404,9 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m const { id: componentId, title } = defaultExport || {}; if (!title) { throw new Error( - `Unexpected default export without title: ${JSON.stringify(fileExports.default)}` + `Unexpected default export without title in '${fileName}': ${JSON.stringify( + fileExports.default + )}` ); } From c6b1e5cd531eda38886f5a3143020c6ab3ca3f63 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 09:44:35 +1000 Subject: [PATCH 172/285] Didn't mean to commit this --- examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx b/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx index aec839bc4e6..f9cd3c5119d 100644 --- a/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx +++ b/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; import { Button } from './Button'; -console.log('HERE'); export default { title: 'Button', component: Button, From 9eb3afe5334f977cb58bdba559d08c366e795c64 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 10:17:48 +1000 Subject: [PATCH 173/285] Drop a couple FIXMEs that were fixed --- lib/core-server/typings.d.ts | 3 --- lib/store/src/args.ts | 2 -- 2 files changed, 5 deletions(-) diff --git a/lib/core-server/typings.d.ts b/lib/core-server/typings.d.ts index f49e612f7e4..4d6c70f7c70 100644 --- a/lib/core-server/typings.d.ts +++ b/lib/core-server/typings.d.ts @@ -34,6 +34,3 @@ declare module 'file-system-cache' { export = create; } - -// FIXME refactor in progress -declare module '@storybook/client-api/dist/esm/inferArgTypes'; diff --git a/lib/store/src/args.ts b/lib/store/src/args.ts index c4658a1fa5e..2efe576a64f 100644 --- a/lib/store/src/args.ts +++ b/lib/store/src/args.ts @@ -38,8 +38,6 @@ const map = (arg: unknown, type: SBType): any => { export const mapArgsToTypes = (args: Args, argTypes: ArgTypes): Args => { return Object.entries(args).reduce((acc, [key, value]) => { if (!argTypes[key]) return acc; - // FIXME: this is not typesafe. The type key is allowed to be a string and this is assuming - // it will be "enhanced" by docs by now, but the user doesn't have to use docs. const mapped = map(value, argTypes[key].type as SBType); return mapped === INCOMPATIBLE ? acc : Object.assign(acc, { [key]: mapped }); }, {}); From 67f882735ce9413c39d718471ce391de73203a10 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 10:39:03 +1000 Subject: [PATCH 174/285] Deal with multiple `storiesOf` in the same file --- lib/client-api/src/ClientApi.test.ts | 3 --- lib/client-api/src/ClientApi.ts | 11 ++++++++- lib/core-client/src/preview/start.test.ts | 27 ++++++++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/client-api/src/ClientApi.test.ts b/lib/client-api/src/ClientApi.test.ts index a834e550246..efae3141dfe 100644 --- a/lib/client-api/src/ClientApi.test.ts +++ b/lib/client-api/src/ClientApi.test.ts @@ -1,9 +1,6 @@ -import { Path, ModuleExports } from '@storybook/store'; import addons, { mockChannel } from '@storybook/addons'; import ClientApi from './ClientApi'; -const getExportChanges = () => ({ added: new Map(), removed: new Map() }); - beforeEach(() => { addons.setChannel(mockChannel()); }); diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index fad8411a327..77017579862 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -264,7 +264,16 @@ export default class ClientApi { } // eslint-disable-next-line no-plusplus - const fileName = m && m.id ? `${m.id}` : (this.lastFileName++).toString(); + const baseFilename = m && m.id ? `${m.id}` : (this.lastFileName++).toString(); + let fileName = baseFilename; + let i = 1; + // Deal with `storiesOf()` being called twice in the same file. + // On HMR, `this.csfExports[fileName]` will be reset to `{}`, so an empty object is due + // to this export, not a second call of `storiesOf()`. + while (this.csfExports[fileName] && Object.keys(this.csfExports[fileName]).length > 0) { + i += 1; + fileName = `${baseFilename}-${i}`; + } if (m && m.hot && m.hot.accept) { // This module used storiesOf(), so when it re-runs on HMR, it will reload diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index 7593a3eb96d..a8cc8a24857 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -8,11 +8,11 @@ import { mockChannel, } from '@storybook/web-preview/dist/cjs/WebPreview.mockdata'; +import { AnyFramework } from '@storybook/csf'; import { start } from './start'; jest.mock('@storybook/web-preview/dist/cjs/WebView'); -const { history, document } = global; jest.mock('global', () => ({ // @ts-ignore ...jest.requireActual('global'), @@ -149,6 +149,31 @@ describe('start', () => { expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_RENDERED, 'component-a--default'); }); + it('deals with storiesOf from the same file twice', async () => { + const render = jest.fn(); + + const { configure, clientApi } = start(render); + + configure('test', () => { + clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('default', jest.fn()); + clientApi.storiesOf('Component B', { id: 'file1' } as NodeModule).add('default', jest.fn()); + clientApi.storiesOf('Component C', { id: 'file1' } as NodeModule).add('default', jest.fn()); + }); + + await waitForEvents([Events.SET_STORIES]); + + expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_RENDERED, 'component-a--default'); + + const storiesOfData = mockChannel.emit.mock.calls.find( + (call: [string, any]) => call[0] === Events.SET_STORIES + )[1]; + expect(Object.values(storiesOfData.stories).map((s: any) => s.parameters.fileName)).toEqual([ + 'file1', + 'file1-2', + 'file1-3', + ]); + }); + it('allows global metadata via client-api', async () => { const render = jest.fn(({ storyFn }) => storyFn()); From f18d3b911a7409e2118aab6bf8355ef818795c6e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 10:49:44 +1000 Subject: [PATCH 175/285] Ensure `render` is used in legacy mode --- app/react/src/client/preview/config.tsx | 16 ++------------- app/react/src/client/preview/index.tsx | 4 ++-- app/react/src/client/preview/render.tsx | 26 ++++++++++++++++++++----- lib/core-client/src/preview/start.ts | 11 +++++++++-- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/app/react/src/client/preview/config.tsx b/app/react/src/client/preview/config.tsx index cc92571a601..575cb8584d2 100644 --- a/app/react/src/client/preview/config.tsx +++ b/app/react/src/client/preview/config.tsx @@ -1,17 +1,5 @@ -import React from 'react'; +import { Parameters } from './types-6-3'; -import { Story, Parameters } from './types-6-3'; -import renderToDOM from './render'; - -export const render: Story = (args, { id, component: Component }) => { - if (!Component) { - throw new Error( - `Unable to render story ${id} as the component annotation is missing from the default export` - ); - } - return ; -}; - -export { renderToDOM }; +export { render, renderToDOM } from './render'; export const parameters: Parameters = { framework: 'react' }; diff --git a/app/react/src/client/preview/index.tsx b/app/react/src/client/preview/index.tsx index 0f482624abf..a00a8fd6a42 100644 --- a/app/react/src/client/preview/index.tsx +++ b/app/react/src/client/preview/index.tsx @@ -4,7 +4,7 @@ import { start } from '@storybook/core/client'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import './globals'; -import render from './render'; +import { renderToDOM, render } from './render'; import { IStorybookSection } from './types'; import { ReactFramework } from './types-6-0'; @@ -18,7 +18,7 @@ interface ClientApi extends ClientStoryApi { } const framework = 'react'; -const api = start(render); +const api = start(renderToDOM, { render }); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ diff --git a/app/react/src/client/preview/render.tsx b/app/react/src/client/preview/render.tsx index bb60d46359b..d006aa4fdf3 100644 --- a/app/react/src/client/preview/render.tsx +++ b/app/react/src/client/preview/render.tsx @@ -1,19 +1,35 @@ import global from 'global'; -import React, { Component, FunctionComponent, ReactElement, StrictMode, Fragment } from 'react'; +import React, { + Component as ReactComponent, + FunctionComponent, + ReactElement, + StrictMode, + Fragment, +} from 'react'; import ReactDOM from 'react-dom'; import { RenderContext } from '@storybook/store'; +import { ArgsStoryFn } from '@storybook/csf'; import { StoryContext } from './types'; import { ReactFramework } from './types-6-0'; const { FRAMEWORK_OPTIONS } = global; -const render = async (node: ReactElement, el: Element) => +export const render: ArgsStoryFn = (args, { id, component: Component }) => { + if (!Component) { + throw new Error( + `Unable to render story ${id} as the component annotation is missing from the default export` + ); + } + return ; +}; + +const renderElement = async (node: ReactElement, el: Element) => new Promise((resolve) => { ReactDOM.render(node, el, () => resolve(null)); }); -class ErrorBoundary extends Component<{ +class ErrorBoundary extends ReactComponent<{ showException: (err: Error) => void; showMain: () => void; }> { @@ -47,7 +63,7 @@ class ErrorBoundary extends Component<{ const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment; -export default async function renderMain( +export async function renderToDOM( { storyContext, unboundStoryFn, @@ -77,5 +93,5 @@ export default async function renderMain( ReactDOM.unmountComponentAtNode(domElement); } - await render(element, domElement); + await renderElement(element, domElement); } diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 605e261405d..2a34baf9593 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -1,7 +1,7 @@ import global from 'global'; import { ClientApi } from '@storybook/client-api'; import { WebGlobalAnnotations, WebPreview } from '@storybook/web-preview'; -import { AnyFramework } from '@storybook/csf'; +import { AnyFramework, ArgsStoryFn } from '@storybook/csf'; import createChannel from '@storybook/channel-postmessage'; import { addons } from '@storybook/addons'; import Events from '@storybook/core-events'; @@ -14,7 +14,13 @@ const { window: globalWindow } = global; export function start( renderToDOM: WebGlobalAnnotations['renderToDOM'], - { decorateStory }: { decorateStory?: WebGlobalAnnotations['applyDecorators'] } = {} + { + decorateStory, + render, + }: { + decorateStory?: WebGlobalAnnotations['applyDecorators']; + render?: ArgsStoryFn; + } = {} ) { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); @@ -53,6 +59,7 @@ export function start( return { ...clientApi.globalAnnotations, + render, renderToDOM, applyDecorators: decorateStory, }; From d31cca366c74db0a432b9a240f1199c38a9ffcfd Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 12:13:30 +1000 Subject: [PATCH 176/285] Move sorting types back to addons --- lib/addons/src/types.ts | 33 +++++++++++++++++++++++++++++++-- lib/client-api/src/storySort.ts | 14 +------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/addons/src/types.ts b/lib/addons/src/types.ts index a24bef00740..24648408d80 100644 --- a/lib/addons/src/types.ts +++ b/lib/addons/src/types.ts @@ -1,7 +1,6 @@ import { AnyFramework, InputType, - Parameters, StoryContext as StoryContextForFramework, LegacyStoryFn as LegacyStoryFnForFramework, PartialStoryFn as PartialStoryFnForFramework, @@ -27,7 +26,6 @@ export type { StoryName, StoryIdentifier, ViewMode, - Parameters, Args, } from '@storybook/csf'; @@ -35,6 +33,37 @@ export type ArgTypes = { [key in keyof Partial]: InputType; }; +export type Comparator = ((a: T, b: T) => boolean) | ((a: T, b: T) => number); +export type StorySortMethod = 'configure' | 'alphabetical'; +export interface StorySortObjectParameter { + method?: StorySortMethod; + order?: any[]; + locales?: string; + includeNames?: boolean; +} +// The `any` here is the story store's `StoreItem` record. Ideally we should probably only +// pass a defined subset of that full data, but we pass it all so far :shrug: +export type StorySortComparator = Comparator<[StoryId, any, Parameters, Parameters]>; +export type StorySortParameter = StorySortComparator | StorySortObjectParameter; + +export interface OptionsParameter extends Object { + storySort?: StorySortParameter; + theme?: { + base: string; + brandTitle?: string; + }; + [key: string]: any; +} + +export interface Parameters { + fileName?: string; + options?: OptionsParameter; + /** The layout property defines basic styles added to the preview body where the story is rendered. If you pass 'none', no styles are applied. */ + layout?: 'centered' | 'fullscreen' | 'padded' | 'none'; + docsOnly?: boolean; + [key: string]: any; +} + export type StoryContext = StoryContextForFramework; export type StoryContextUpdate = Partial; diff --git a/lib/client-api/src/storySort.ts b/lib/client-api/src/storySort.ts index e5153e4068c..73f6eeb686c 100644 --- a/lib/client-api/src/storySort.ts +++ b/lib/client-api/src/storySort.ts @@ -1,16 +1,4 @@ -import { StoryId, Parameters } from '@storybook/csf'; - -// TODO -- these types were moved from lib/addons -type Comparator = ((a: T, b: T) => boolean) | ((a: T, b: T) => number); -type StorySortMethod = 'configure' | 'alphabetical'; -interface StorySortObjectParameter { - method?: StorySortMethod; - order?: any[]; - locales?: string; - includeNames?: boolean; -} - -type StorySortComparator = Comparator<[StoryId, any, Parameters, Parameters]>; +import { StorySortComparator, StorySortObjectParameter } from '@storybook/addons'; const STORY_KIND_PATH_SEPARATOR = /\s*\/\s*/; From 64724a21e1c2fc0c2af2552e39edc4d48aa3cc02 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 12:14:00 +1000 Subject: [PATCH 177/285] Add sorting to back-compat store --- lib/client-api/src/ClientApi.ts | 53 ++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 77017579862..63b16e64874 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -1,8 +1,10 @@ import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; import global from 'global'; +import stable from 'stable'; import { logger } from '@storybook/client-logger'; import { + StoryId, AnyFramework, toId, isExportStory, @@ -28,9 +30,11 @@ import { combineParameters, StoryStore, normalizeInputTypes, + NormalizedStoryAnnotations, } from '@storybook/store'; +import { ClientApiAddons, StoryApi, Comparator } from '@storybook/addons'; -import { ClientApiAddons, StoryApi } from '@storybook/addons'; +import { storySort } from './storySort'; const { FEATURES } = global; @@ -172,15 +176,50 @@ export default class ClientApi { getStoriesList() { const fileNameOrder = Object.keys(this.csfExports); - const sortedStoryEntries = Object.entries(this.stories).sort( - ([id1, story1], [id2, story2]) => - fileNameOrder.indexOf(story1.importPath) - fileNameOrder.indexOf(story2.importPath) - ); + const storySortParameter = this.globalAnnotations.parameters?.options?.storySort; + + const storyEntries = Object.entries(this.stories); + // Add the kind parameters and global parameters to each entry + const stories: [ + StoryId, + NormalizedStoryAnnotations, + Parameters, + Parameters + ][] = storyEntries.map(([storyId, { importPath }]) => { + const exports = this.csfExports[importPath]; + const csfFile = this.storyStore.processCSFFileWithCache( + exports, + exports.default.title + ); + return [ + storyId, + this.storyStore.storyFromCSFFile({ storyId, csfFile }), + csfFile.meta.parameters, + this.globalAnnotations.parameters, + ]; + }); + + if (storySortParameter) { + let sortFn: Comparator; + if (typeof storySortParameter === 'function') { + sortFn = storySortParameter; + } else { + sortFn = storySort(storySortParameter); + } + stable.inplace(stories, sortFn); + } else { + stable.inplace( + stories, + (s1, s2) => + fileNameOrder.indexOf(s1[1].parameters.fileName) - + fileNameOrder.indexOf(s2[1].parameters.fileName) + ); + } return { v: 3, - stories: sortedStoryEntries.reduce((acc, [id, entry]) => { - acc[id] = entry; + stories: stories.reduce((acc, [id]) => { + acc[id] = this.stories[id]; return acc; }, {} as StoriesList['stories']), }; From 816f3319a67c264a56f02bb10e8cc2176854d312 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 12:55:58 +1000 Subject: [PATCH 178/285] Update extract to wait for init --- lib/cli/src/extract.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/cli/src/extract.ts b/lib/cli/src/extract.ts index 5826c15d5b4..c88db2ade9c 100644 --- a/lib/cli/src/extract.ts +++ b/lib/cli/src/extract.ts @@ -11,6 +11,11 @@ const read = async (url: string) => { await page.goto(url); + // for v7 store. This may not be necessary ultimately as this store relies on a static stories.json + await page.waitForFunction( + 'window.__STORYBOOK_STORY_STORE__ && window.__STORYBOOK_STORY_STORE__.cacheAllCSFFiles && window.__STORYBOOK_STORY_STORE__.cacheAllCSFFiles()' + ); + await page.waitForFunction( 'window.__STORYBOOK_STORY_STORE__ && window.__STORYBOOK_STORY_STORE__.extract && window.__STORYBOOK_STORY_STORE__.extract()' ); From 4232e573fbc9facc4c0828d8a0417c5e7e425e8d Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 14:30:39 +1000 Subject: [PATCH 179/285] Undo extract change and fix up web-components-kitchen-sink --- examples/web-components-kitchen-sink/package.json | 2 ++ lib/cli/src/extract.ts | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/web-components-kitchen-sink/package.json b/examples/web-components-kitchen-sink/package.json index e0c4dd537b3..f530b71a019 100644 --- a/examples/web-components-kitchen-sink/package.json +++ b/examples/web-components-kitchen-sink/package.json @@ -46,9 +46,11 @@ "@storybook/postinstall": "portal:../../lib/postinstall", "@storybook/router": "portal:../../lib/router", "@storybook/source-loader": "portal:../../lib/source-loader", + "@storybook/store": "portal:../../lib/store", "@storybook/theming": "portal:../../lib/theming", "@storybook/ui": "portal:../../lib/ui", "@storybook/web-components": "portal:../../app/web-components", + "@storybook/web-preview": "portal:../../app/web-preview", "typescript": "4.2.4" }, "dependencies": { diff --git a/lib/cli/src/extract.ts b/lib/cli/src/extract.ts index c88db2ade9c..5826c15d5b4 100644 --- a/lib/cli/src/extract.ts +++ b/lib/cli/src/extract.ts @@ -11,11 +11,6 @@ const read = async (url: string) => { await page.goto(url); - // for v7 store. This may not be necessary ultimately as this store relies on a static stories.json - await page.waitForFunction( - 'window.__STORYBOOK_STORY_STORE__ && window.__STORYBOOK_STORY_STORE__.cacheAllCSFFiles && window.__STORYBOOK_STORY_STORE__.cacheAllCSFFiles()' - ); - await page.waitForFunction( 'window.__STORYBOOK_STORY_STORE__ && window.__STORYBOOK_STORY_STORE__.extract && window.__STORYBOOK_STORY_STORE__.extract()' ); From cc4a16f1205af0adf4b18bca09a5b92ce67eacde Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 14:49:37 +1000 Subject: [PATCH 180/285] Fix incorrect link --- examples/web-components-kitchen-sink/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/web-components-kitchen-sink/package.json b/examples/web-components-kitchen-sink/package.json index f530b71a019..483d0025d53 100644 --- a/examples/web-components-kitchen-sink/package.json +++ b/examples/web-components-kitchen-sink/package.json @@ -50,7 +50,7 @@ "@storybook/theming": "portal:../../lib/theming", "@storybook/ui": "portal:../../lib/ui", "@storybook/web-components": "portal:../../app/web-components", - "@storybook/web-preview": "portal:../../app/web-preview", + "@storybook/web-preview": "portal:../../lib/web-preview", "typescript": "4.2.4" }, "dependencies": { From eeb3708c163ca88dca8e529cf9520491a277ff2c Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 15:35:14 +1000 Subject: [PATCH 181/285] Update CSF version to pass Args through to stories --- addons/a11y/package.json | 2 +- addons/actions/package.json | 2 +- addons/backgrounds/package.json | 2 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/links/package.json | 2 +- addons/measure/package.json | 2 +- addons/outline/package.json | 2 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 2 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 2 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 2 +- lib/addons/package.json | 2 +- lib/api/package.json | 2 +- lib/client-api/package.json | 2 +- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- lib/web-preview/package.json | 2 +- yarn.lock | 64 +++++++++---------- 29 files changed, 61 insertions(+), 61 deletions(-) diff --git a/addons/a11y/package.json b/addons/a11y/package.json index 72e66369a4f..0c3ed830aa9 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/theming": "6.4.0-alpha.19", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/actions/package.json b/addons/actions/package.json index 6da1a2828db..3367b790cfc 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index eba042ac9ea..7c65b2c406a 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,7 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/controls/package.json b/addons/controls/package.json index 43145221039..db41b7c38a1 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", diff --git a/addons/docs/package.json b/addons/docs/package.json index 782dc90f52a..22e76a99a00 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/postinstall": "6.4.0-alpha.19", diff --git a/addons/links/package.json b/addons/links/package.json index 6b2ee209ee1..d74a14b2e3d 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/router": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/measure/package.json b/addons/measure/package.json index 8992539f8d8..8fc96799a9a 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,7 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/outline/package.json b/addons/outline/package.json index 2eb3f7a268b..1201b1d0316 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,7 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index b626983364e..6768b1e680d 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-client": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index 97d4ae8ad8e..3d4a0c8dbb5 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/node-logger": "6.4.0-alpha.19", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index 0e6f32579d5..e561d309a3b 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index 3eaf148dee5..a8f4c4c568e 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/app/preact/package.json b/app/preact/package.json index 30ee7e5b311..595ade0f848 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/react/package.json b/app/react/package.json index 0a71d0a79e7..35d6dd8f6a9 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index 75b40ca0f1a..1aea35a9750 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,7 +50,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", diff --git a/app/svelte/package.json b/app/svelte/package.json index a47804d977d..2cb25b7d64a 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index ae757e5c343..11146320856 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index 59c72065303..f75b83583ec 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index ff875b1123b..64558c0f2a7 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/lib/addons/package.json b/lib/addons/package.json index 9e592740961..6cfe677c096 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/api/package.json b/lib/api/package.json index ce6f36e8696..69920e50e4e 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.19", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index 4d97f60640a..3e22e9ec963 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -46,7 +46,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index 22fc5619055..6756446cfc2 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index 343776243b8..1def354ade7 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/theming": "6.4.0-alpha.19", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index 4604a2c59fc..dc3abb5fa15 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "@storybook/ui": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index 0ce799e2060..bdda82ac19f 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index e57d7d4ebe3..37db78318da 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -43,7 +43,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/lib/web-preview/package.json b/lib/web-preview/package.json index 0a2f6e61325..89a339554fa 100644 --- a/lib/web-preview/package.json +++ b/lib/web-preview/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.a1972cb.0", + "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/store": "6.4.0-alpha.19", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/yarn.lock b/yarn.lock index 039a216286a..822a2466228 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5536,7 +5536,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/theming": 6.4.0-alpha.19 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -5567,7 +5567,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/theming": 6.4.0-alpha.19 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -5602,7 +5602,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/theming": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -5630,7 +5630,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 @@ -5673,7 +5673,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/postinstall": 6.4.0-alpha.19 @@ -5857,7 +5857,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/router": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -5887,7 +5887,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -5911,7 +5911,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -5946,7 +5946,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/node-logger": 6.4.0-alpha.19 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -5976,7 +5976,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-client": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/react": 6.4.0-alpha.19 "@storybook/vue": 6.4.0-alpha.19 "@storybook/vue3": 6.4.0-alpha.19 @@ -6139,7 +6139,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6172,7 +6172,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@types/autoprefixer": ^9.7.2 @@ -6241,7 +6241,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.19 @@ -6521,7 +6521,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -6557,7 +6557,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6579,7 +6579,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/theming": 6.4.0-alpha.19 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -6618,7 +6618,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 @@ -6817,12 +6817,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.a1972cb.0": - version: 0.0.2--canary.a1972cb.0 - resolution: "@storybook/csf@npm:0.0.2--canary.a1972cb.0" +"@storybook/csf@npm:0.0.2--canary.d61cd6c.0": + version: 0.0.2--canary.d61cd6c.0 + resolution: "@storybook/csf@npm:0.0.2--canary.d61cd6c.0" dependencies: lodash: ^4.17.15 - checksum: 0e478f4c4733e7d597ca295a3474711cc65c2097e3c7933246d46ebcffde7b422a70bba1b5618d381b1067b193f39dc32156009d92be6c1b8bdce53e61b75f5b + checksum: 0423e195692b0f2063167fcc6a1a896af50aa3a02853e2f7cdf5bf7002613713476290e2a07c5543b0457cf3e21c7e0581274dce7a346a0322c7b12b61778078 languageName: node linkType: hard @@ -6959,7 +6959,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 @@ -7161,7 +7161,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7242,7 +7242,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -7540,7 +7540,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 @@ -7569,7 +7569,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -7590,7 +7590,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -7608,7 +7608,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7708,7 +7708,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -7745,7 +7745,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -7788,7 +7788,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 @@ -7818,7 +7818,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.a1972cb.0 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 ansi-to-html: ^0.6.11 core-js: ^3.8.2 From 9006d0b6eeec56de270d058c8798bdfb383438ee Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 15:38:26 +1000 Subject: [PATCH 182/285] Don't put a `StoryFn` onto `render` As it is supposed to be an `ArgsStoryFn` --- lib/store/src/normalizeStory.ts | 11 +++++++---- lib/store/src/prepareStory.ts | 7 ++++++- lib/store/src/types.ts | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/store/src/normalizeStory.ts b/lib/store/src/normalizeStory.ts index dc5cc8bf027..5536d245018 100644 --- a/lib/store/src/normalizeStory.ts +++ b/lib/store/src/normalizeStory.ts @@ -5,9 +5,10 @@ import { AnyFramework, DecoratorFunction, ArgTypes, - StoryAnnotationsOrFn, + LegacyStoryAnnotationsOrFn, StoryId, StoryAnnotations, + StoryFn, } from '@storybook/csf'; import dedent from 'ts-dedent'; import { logger } from '@storybook/client-logger'; @@ -26,13 +27,14 @@ const deprecatedStoryAnnotationWarning = deprecate(() => {}, deprecatedStoryAnno export function normalizeStory( key: StoryId, - storyAnnotations: StoryAnnotationsOrFn, + storyAnnotations: LegacyStoryAnnotationsOrFn, meta: ComponentAnnotations ): NormalizedStoryAnnotations { + let userStoryFn: StoryFn; let storyObject: StoryAnnotations; if (typeof storyAnnotations === 'function') { - // eslint-disable-next-line prefer-object-spread - storyObject = Object.assign({ render: storyAnnotations }, storyAnnotations); + userStoryFn = storyAnnotations; + storyObject = storyAnnotations; } else { storyObject = storyAnnotations; } @@ -62,6 +64,7 @@ export function normalizeStory( ...(argTypes && { argTypes: normalizeInputTypes(argTypes) }), ...(loaders && { loaders }), ...(render && { render }), + ...(userStoryFn && { userStoryFn }), ...(play && { play }), }; } diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 9f26c39108c..e5ecab8ef00 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -73,7 +73,12 @@ export function prepareStory( ...(storyAnnotations.loaders || []), ]; - const render = storyAnnotations.render || componentAnnotations.render || globalAnnotations.render; + // TODO make a note about what's happening here + const render = + storyAnnotations.userStoryFn || + storyAnnotations.render || + componentAnnotations.render || + globalAnnotations.render; const passedArgTypes: StrictArgTypes = combineParameters( globalAnnotations.argTypes, diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 08ad4fe5307..7c8a915f0d9 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -46,6 +46,7 @@ export type NormalizedStoryAnnotations = Omit< // You cannot actually set id on story annotations, but we normalize it to be there for convience id: StoryId; argTypes?: StrictArgTypes; + userStoryFn?: StoryFn; }; export type CSFFile = { From d9bb26e146ae8f5fefec7829f0325154f95876bd Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 16:37:19 +1000 Subject: [PATCH 183/285] Various fixes --- lib/client-api/src/ClientApi.test.ts | 7 +++ lib/client-api/src/ClientApi.ts | 46 +++++++++-------- lib/core-client/src/preview/start.test.ts | 61 ++++++++++++++++++++++- lib/store/src/StoryStore.ts | 2 +- lib/store/src/normalizeStory.test.ts | 2 +- lib/store/src/normalizeStory.ts | 6 ++- lib/web-preview/src/WebPreview.test.ts | 13 +++++ lib/web-preview/src/WebPreview.tsx | 6 +-- 8 files changed, 116 insertions(+), 27 deletions(-) diff --git a/lib/client-api/src/ClientApi.test.ts b/lib/client-api/src/ClientApi.test.ts index efae3141dfe..9e52caaac91 100644 --- a/lib/client-api/src/ClientApi.test.ts +++ b/lib/client-api/src/ClientApi.test.ts @@ -99,6 +99,13 @@ describe('ClientApi', () => { describe('getStoriesList', () => { it('should remember the order that files were added in', async () => { const clientApi = new ClientApi(); + const store = { + processCSFFileWithCache: jest.fn(() => ({ meta: { title: 'title' } })), + storyFromCSFFile: jest.fn(({ storyId }) => ({ + parameters: { fileName: storyId.split('-')[0].replace('kind', 'file') }, + })), + }; + clientApi.storyStore = store as any; let disposeCallback: () => void; const module1 = { diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 63b16e64874..53191c32a98 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -30,7 +30,7 @@ import { combineParameters, StoryStore, normalizeInputTypes, - NormalizedStoryAnnotations, + Story, } from '@storybook/store'; import { ClientApiAddons, StoryApi, Comparator } from '@storybook/addons'; @@ -180,24 +180,21 @@ export default class ClientApi { const storyEntries = Object.entries(this.stories); // Add the kind parameters and global parameters to each entry - const stories: [ - StoryId, - NormalizedStoryAnnotations, - Parameters, - Parameters - ][] = storyEntries.map(([storyId, { importPath }]) => { - const exports = this.csfExports[importPath]; - const csfFile = this.storyStore.processCSFFileWithCache( - exports, - exports.default.title - ); - return [ - storyId, - this.storyStore.storyFromCSFFile({ storyId, csfFile }), - csfFile.meta.parameters, - this.globalAnnotations.parameters, - ]; - }); + const stories: [StoryId, Story, Parameters, Parameters][] = storyEntries.map( + ([storyId, { importPath }]) => { + const exports = this.csfExports[importPath]; + const csfFile = this.storyStore.processCSFFileWithCache( + exports, + exports.default.title + ); + return [ + storyId, + this.storyStore.storyFromCSFFile({ storyId, csfFile }), + csfFile.meta.parameters, + this.globalAnnotations.parameters, + ]; + } + ); if (storySortParameter) { let sortFn: Comparator; @@ -458,7 +455,16 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m ); } - this.csfExports[fileName] = fileExports; + this.csfExports[fileName] = { + ...fileExports, + default: { + ...defaultExport, + parameters: { + ...defaultExport.parameters, + fileName, + }, + }, + }; Object.entries(namedExports) .filter(([key]) => isExportStory(key, defaultExport)) diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index a8cc8a24857..fc847b7b152 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -1,4 +1,3 @@ -import global from 'global'; import Events from '@storybook/core-events'; import { @@ -29,6 +28,7 @@ jest.mock('global', () => ({ })); jest.mock('@storybook/channel-postmessage', () => () => mockChannel); +jest.mock('react-dom'); beforeEach(() => { mockChannel.emit.mockClear(); @@ -135,6 +135,53 @@ describe('start', () => { ); }); + it('sends over docs only stories', async () => { + const render = jest.fn(); + + const { configure, clientApi } = start(render); + + configure('test', () => { + clientApi + .storiesOf('Component A', { id: 'file1' } as NodeModule) + .add('Story One', jest.fn(), { docsOnly: true, docs: {} }); + }); + + await waitForEvents([Events.SET_STORIES]); + expect( + mockChannel.emit.mock.calls.find((call: [string, any]) => call[0] === Events.SET_STORIES)[1] + ).toMatchInlineSnapshot(` + Object { + "globalParameters": Object {}, + "globals": Object {}, + "kindParameters": Object { + "Component A": Object {}, + }, + "stories": Array [ + Object { + "argTypes": Object {}, + "component": undefined, + "componentId": "component-a", + "id": "component-a--story-one", + "initialArgs": Object {}, + "kind": "Component A", + "name": "Story One", + "parameters": Object { + "__isArgsStory": false, + "docs": Object {}, + "docsOnly": true, + "fileName": "file1", + "framework": "test", + }, + "story": "Story One", + "subcomponents": undefined, + "title": "Component A", + }, + ], + "v": 2, + } + `); + }); + it('deals with stories with "default" name', async () => { const render = jest.fn(); @@ -483,6 +530,7 @@ describe('start', () => { "name": "Story One", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story One", @@ -499,6 +547,7 @@ describe('start', () => { "name": "Story Two", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story Two", @@ -611,6 +660,7 @@ describe('start', () => { "name": "Story One", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story One", @@ -627,6 +677,7 @@ describe('start', () => { "name": "Story Two", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story Two", @@ -643,6 +694,7 @@ describe('start', () => { "name": "Story Three", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story Three", @@ -698,6 +750,7 @@ describe('start', () => { "name": "Story One", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story One", @@ -714,6 +767,7 @@ describe('start', () => { "name": "Story Two", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story Two", @@ -730,6 +784,7 @@ describe('start', () => { "name": "Story Four", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-1", "framework": "test", }, "story": "Story Four", @@ -766,6 +821,7 @@ describe('start', () => { "name": "Story One", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story One", @@ -782,6 +838,7 @@ describe('start', () => { "name": "Story Two", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story Two", @@ -887,6 +944,7 @@ describe('start', () => { "name": "Story One", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story One", @@ -903,6 +961,7 @@ describe('start', () => { "name": "Story Two", "parameters": Object { "__isArgsStory": false, + "fileName": "exports-map-0", "framework": "test", }, "story": "Story Two", diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 574349e5cd0..aa1317d2b3c 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -267,7 +267,7 @@ export class StoryStore { } getSetStoriesPayload() { - const stories = this.extract(); + const stories = this.extract({ includeDocsOnly: true }); const kindParameters: Parameters = stories.reduce( (acc: Parameters, { title }: { title: ComponentTitle }) => { diff --git a/lib/store/src/normalizeStory.test.ts b/lib/store/src/normalizeStory.test.ts index a494c327be5..5bc5659148a 100644 --- a/lib/store/src/normalizeStory.test.ts +++ b/lib/store/src/normalizeStory.test.ts @@ -37,7 +37,7 @@ describe('normalizeStory', () => { Object { "id": "title--story-export", "name": "Story Export", - "render": [Function], + "userStoryFn": [Function], } `); }); diff --git a/lib/store/src/normalizeStory.ts b/lib/store/src/normalizeStory.ts index 5536d245018..569c398ccaf 100644 --- a/lib/store/src/normalizeStory.ts +++ b/lib/store/src/normalizeStory.ts @@ -47,7 +47,11 @@ export function normalizeStory( const exportName = storyNameFromExport(key); const id = toId(meta.id || meta.title, exportName); - const name = storyObject.name || storyObject.storyName || story?.name || exportName; + const name = + (typeof storyObject !== 'function' && storyObject.name) || + storyObject.storyName || + story?.name || + exportName; const decorators = storyObject.decorators || story?.decorators; const parameters = storyObject.parameters || story?.parameters; const args = storyObject.args || story?.args; diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index 14c5c9427fe..ee37022da27 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -102,6 +102,19 @@ describe('WebPreview', () => { }); }); + it('SET_GLOBALS sets globals and types even when undefined', async () => { + await new WebPreview({ + getGlobalAnnotations: () => ({}), + importFn, + fetchStoriesList, + }).initialize(); + + expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { + globals: {}, + globalTypes: {}, + }); + }); + it('emits the SET_GLOBALS event from the URL', async () => { document.location.search = '?id=*&globals=a:c'; diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 761a13cd526..976aeb7854d 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -113,8 +113,8 @@ export class WebPreview { this.storyStore.globals.updateFromPersisted(globals); } this.channel.emit(Events.SET_GLOBALS, { - globals: this.storyStore.globals.get(), - globalTypes: this.storyStore.globalAnnotations.globalTypes, + globals: this.storyStore.globals.get() || {}, + globalTypes: this.storyStore.globalAnnotations.globalTypes || {}, }); await this.selectSpecifiedStory(); @@ -285,7 +285,7 @@ export class WebPreview { this.previousSelection = selection; this.previousStory = story; - if (selection.viewMode === 'docs') { + if (selection.viewMode === 'docs' || story.parameters.docsOnly) { await this.renderDocs({ story }); } else { this.previousCleanup = this.renderStory({ story }); From c2ab7ea0378cd253661eeb8734a90acb338be5a2 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 16:40:39 +1000 Subject: [PATCH 184/285] Ensure we deal with cleaning up docs only too --- lib/web-preview/src/WebPreview.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 976aeb7854d..c072b35bb04 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -268,11 +268,14 @@ export class WebPreview { this.channel.emit(Events.STORY_UNCHANGED, selection.storyId); return; } - if (viewModeChanged && this.previousSelection?.viewMode === 'docs') { + const previousViewMode = this.previousStory?.parameters?.docsOnly + ? 'docs' + : this.previousSelection?.viewMode; + if (viewModeChanged && previousViewMode === 'docs') { ReactDOM.unmountComponentAtNode(this.view.docsRoot()); } - if (this.previousSelection?.viewMode === 'story') { + if (previousViewMode === 'story') { this.removePreviousStory(); } From 74da384ce040521bf63e2fa003114943e5478191 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 16:42:16 +1000 Subject: [PATCH 185/285] Don't generate stories.json if we don't have to --- scripts/build-storybooks.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/build-storybooks.js b/scripts/build-storybooks.js index 79944bf270d..3548e555da8 100755 --- a/scripts/build-storybooks.js +++ b/scripts/build-storybooks.js @@ -127,7 +127,11 @@ const handleExamples = async (deployables) => { } await exec(`yarn`, [`build-storybook`, `--output-dir=${out}`, '--quiet'], { cwd }); - await exec(`npx`, [`sb`, 'extract', out, `${out}/stories.json`], { cwd }); + + // If the example uses `storyStoreV7` or `buildStoriesJson`, stories.json already exists + if (!existsSync(`${out}/stories.json`)) { + await exec(`npx`, [`sb`, 'extract', out, `${out}/stories.json`], { cwd }); + } logger.log('-------'); logger.log(`✅ ${d} built`); From 013e12e1c43d23b3289c7313860b02058defd8c2 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 17:07:40 +1000 Subject: [PATCH 186/285] Re-add client-api to builder-webpack4 --- lib/builder-webpack4/package.json | 1 + yarn.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/builder-webpack4/package.json b/lib/builder-webpack4/package.json index 96bca7a4aee..1eafbc9fbfb 100644 --- a/lib/builder-webpack4/package.json +++ b/lib/builder-webpack4/package.json @@ -65,6 +65,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/channel-postmessage": "6.4.0-alpha.19", "@storybook/channels": "6.4.0-alpha.19", + "@storybook/client-api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", diff --git a/yarn.lock b/yarn.lock index 822a2466228..6f782859667 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6296,6 +6296,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/channel-postmessage": 6.4.0-alpha.19 "@storybook/channels": 6.4.0-alpha.19 + "@storybook/client-api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 From f0ae1331918be4472d56654b79b5f9dee627adc3 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 17:28:46 +1000 Subject: [PATCH 187/285] Ensure the user (i.e. storyshots) fileName wins --- lib/client-api/src/ClientApi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 53191c32a98..837aa05dc9b 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -460,8 +460,8 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m default: { ...defaultExport, parameters: { - ...defaultExport.parameters, fileName, + ...defaultExport.parameters, }, }, }; From 5a7516847e0435c10168c2d5b0b5cedcca4595fb Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 17:52:40 +1000 Subject: [PATCH 188/285] No idea why I need to update these angular snapshots --- .../welcome-storybook.stories.storyshot | 46 +++++++++---------- .../addon-actions.stories.storyshot | 12 ++--- .../addon-background.stories.storyshot | 12 ++--- .../addon-docs.stories.storyshot | 8 ++-- .../__snapshots__/simple.stories.storyshot | 4 +- .../__snapshots__/iframe.stories.storyshot | 4 +- .../addon-links.stories.storyshot | 4 +- .../all-parameters.stories.storyshot | 4 +- .../layout.parameters.stories.storyshot | 20 ++++---- .../story-styles.stories.storyshot | 12 ++--- .../component-in-story.stories.storyshot | 4 +- .../__snapshots__/storiesOf.stories.storyshot | 12 ++--- .../12009-unknown-component.stories.storyshot | 4 +- 13 files changed, 73 insertions(+), 73 deletions(-) diff --git a/examples/angular-cli/src/stories/__snapshots__/welcome-storybook.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/welcome-storybook.stories.storyshot index 9e2b2d1a9a2..047ca0c57ae 100644 --- a/examples/angular-cli/src/stories/__snapshots__/welcome-storybook.stories.storyshot +++ b/examples/angular-cli/src/stories/__snapshots__/welcome-storybook.stories.storyshot @@ -3,47 +3,47 @@ exports[`Storyshots Welcome/ To Storybook To Storybook 1`] = `

Welcome to storybook

This is a UI component dev environment for your app.

We've added some basic stories inside the src/stories directory.
A story is a single state of one or more UI components. You can have as many stories as you want.
(Basically a story is like a visual test case.)

See these sample @@ -51,7 +51,7 @@ exports[`Storyshots Welcome/ To Storybook To Storybook 1`] = ` for a component called Button @@ -59,26 +59,26 @@ exports[`Storyshots Welcome/ To Storybook To Storybook 1`] = ` .

Just like that, you can add your own components as stories.
You can also edit those components and see changes right away.
(Try editing the Button stories located at src/stories/index.js @@ -86,15 +86,15 @@ exports[`Storyshots Welcome/ To Storybook To Storybook 1`] = ` .)

Usually we create stories with smaller UI components in the app.
Have a look at the

NOTE:
Have a look at the .storybook/webpack.config.js diff --git a/examples/angular-cli/src/stories/addons/actions/__snapshots__/addon-actions.stories.storyshot b/examples/angular-cli/src/stories/addons/actions/__snapshots__/addon-actions.stories.storyshot index a45c0668b91..2a0c139d5c4 100644 --- a/examples/angular-cli/src/stories/addons/actions/__snapshots__/addon-actions.stories.storyshot +++ b/examples/angular-cli/src/stories/addons/actions/__snapshots__/addon-actions.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Addons/Actions Component Output with ArgsTypes 1`] = ` @@ -18,11 +18,11 @@ exports[`Storyshots Addons/Actions Component Output with ArgsTypes 1`] = ` exports[`Storyshots Addons/Actions Component Output with EventEmitter 1`] = ` @@ -41,11 +41,11 @@ exports[`Storyshots Addons/Actions Story with template 1`] = ` exports[`Storyshots Addons/Actions Use action in method 1`] = ` diff --git a/examples/angular-cli/src/stories/addons/backgrounds/__snapshots__/addon-background.stories.storyshot b/examples/angular-cli/src/stories/addons/backgrounds/__snapshots__/addon-background.stories.storyshot index 6390bf44b1d..e55171ef005 100644 --- a/examples/angular-cli/src/stories/addons/backgrounds/__snapshots__/addon-background.stories.storyshot +++ b/examples/angular-cli/src/stories/addons/backgrounds/__snapshots__/addon-background.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Addons / Backgrounds Overridden 1`] = ` @@ -18,11 +18,11 @@ exports[`Storyshots Addons / Backgrounds Overridden 1`] = ` exports[`Storyshots Addons / Backgrounds With Component 1`] = ` @@ -33,11 +33,11 @@ exports[`Storyshots Addons / Backgrounds With Component 1`] = ` exports[`Storyshots Addons / Backgrounds With Template 1`] = ` diff --git a/examples/angular-cli/src/stories/addons/docs/__snapshots__/addon-docs.stories.storyshot b/examples/angular-cli/src/stories/addons/docs/__snapshots__/addon-docs.stories.storyshot index 929844cd79e..45917881b1a 100644 --- a/examples/angular-cli/src/stories/addons/docs/__snapshots__/addon-docs.stories.storyshot +++ b/examples/angular-cli/src/stories/addons/docs/__snapshots__/addon-docs.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Addons/Docs with some emoji 1`] = ` @@ -18,11 +18,11 @@ exports[`Storyshots Addons/Docs with some emoji 1`] = ` exports[`Storyshots Addons/Docs with text 1`] = ` diff --git a/examples/angular-cli/src/stories/addons/docs/__snapshots__/simple.stories.storyshot b/examples/angular-cli/src/stories/addons/docs/__snapshots__/simple.stories.storyshot index 5ad62d257e6..ffcf6aebecc 100644 --- a/examples/angular-cli/src/stories/addons/docs/__snapshots__/simple.stories.storyshot +++ b/examples/angular-cli/src/stories/addons/docs/__snapshots__/simple.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Addons/Docs/SimpleButton with text 1`] = ` diff --git a/examples/angular-cli/src/stories/addons/docs/iframe/__snapshots__/iframe.stories.storyshot b/examples/angular-cli/src/stories/addons/docs/iframe/__snapshots__/iframe.stories.storyshot index 2689d15992b..5c412922328 100644 --- a/examples/angular-cli/src/stories/addons/docs/iframe/__snapshots__/iframe.stories.storyshot +++ b/examples/angular-cli/src/stories/addons/docs/iframe/__snapshots__/iframe.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Addons/Docs/Iframe Basic 1`] = ` diff --git a/examples/angular-cli/src/stories/addons/links/__snapshots__/addon-links.stories.storyshot b/examples/angular-cli/src/stories/addons/links/__snapshots__/addon-links.stories.storyshot index 0c5ee11ad0c..c390f20fc43 100644 --- a/examples/angular-cli/src/stories/addons/links/__snapshots__/addon-links.stories.storyshot +++ b/examples/angular-cli/src/stories/addons/links/__snapshots__/addon-links.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Addons/Links button with link to another story 1`] = ` diff --git a/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot b/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot index 5672a686aec..4409d0f68e4 100644 --- a/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot +++ b/examples/angular-cli/src/stories/core/parameters/__snapshots__/all-parameters.stories.storyshot @@ -3,13 +3,13 @@ exports[`Storyshots Core / Parameters / All parameters All parameters passed to story 1`] = ` @@ -18,11 +18,11 @@ exports[`Storyshots Core / Parameters / Layout Centered 1`] = ` exports[`Storyshots Core / Parameters / Layout Default 1`] = ` @@ -36,12 +36,12 @@ exports[`Storyshots Core / Parameters / Layout Fullscreen 1`] = ` style="background-color: yellow;" > @@ -54,11 +54,11 @@ exports[`Storyshots Core / Parameters / Layout Fullscreen 1`] = ` exports[`Storyshots Core / Parameters / Layout None 1`] = ` @@ -69,11 +69,11 @@ exports[`Storyshots Core / Parameters / Layout None 1`] = ` exports[`Storyshots Core / Parameters / Layout Padded 1`] = ` diff --git a/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot b/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot index 7307da48a79..7c6877920fa 100644 --- a/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot +++ b/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot @@ -3,12 +3,12 @@ exports[`Storyshots Core / Story host styles With Args 1`] = ` @@ -19,12 +19,12 @@ exports[`Storyshots Core / Story host styles With Args 1`] = ` exports[`Storyshots Core / Story host styles With story template 1`] = ` diff --git a/examples/angular-cli/src/stories/legacy/__snapshots__/component-in-story.stories.storyshot b/examples/angular-cli/src/stories/legacy/__snapshots__/component-in-story.stories.storyshot index 2537d54e03d..cfd33b230ee 100644 --- a/examples/angular-cli/src/stories/legacy/__snapshots__/component-in-story.stories.storyshot +++ b/examples/angular-cli/src/stories/legacy/__snapshots__/component-in-story.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Legacy / Component in Story Basic 1`] = ` diff --git a/examples/angular-cli/src/stories/legacy/__snapshots__/storiesOf.stories.storyshot b/examples/angular-cli/src/stories/legacy/__snapshots__/storiesOf.stories.storyshot index f50d0e65075..0a762f2b8cc 100644 --- a/examples/angular-cli/src/stories/legacy/__snapshots__/storiesOf.stories.storyshot +++ b/examples/angular-cli/src/stories/legacy/__snapshots__/storiesOf.stories.storyshot @@ -3,20 +3,20 @@ exports[`Storyshots Legacy / Story with storiesOf() with some emoji 1`] = ` @@ -27,11 +27,11 @@ exports[`Storyshots Legacy / Story with storiesOf() with some emoji 1`] = ` exports[`Storyshots Legacy / Story with storiesOf() with text 1`] = ` diff --git a/examples/angular-cli/src/stories/others/issues/__snapshots__/12009-unknown-component.stories.storyshot b/examples/angular-cli/src/stories/others/issues/__snapshots__/12009-unknown-component.stories.storyshot index f0385ce2672..380a4f509aa 100644 --- a/examples/angular-cli/src/stories/others/issues/__snapshots__/12009-unknown-component.stories.storyshot +++ b/examples/angular-cli/src/stories/others/issues/__snapshots__/12009-unknown-component.stories.storyshot @@ -3,11 +3,11 @@ exports[`Storyshots Others / Issues / 12009 unknown component Basic 1`] = ` From 319b1bb2942ed24cf2aaa152c231ca563f513ea8 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 17:55:22 +1000 Subject: [PATCH 189/285] Add store to builder-webpackX deps --- lib/builder-webpack4/package.json | 1 + lib/builder-webpack5/package.json | 1 + yarn.lock | 2 ++ 3 files changed, 4 insertions(+) diff --git a/lib/builder-webpack4/package.json b/lib/builder-webpack4/package.json index 1eafbc9fbfb..a6cd8caca46 100644 --- a/lib/builder-webpack4/package.json +++ b/lib/builder-webpack4/package.json @@ -73,6 +73,7 @@ "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/router": "6.4.0-alpha.19", "@storybook/semver": "^7.3.2", + "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "@storybook/ui": "6.4.0-alpha.19", "@storybook/web-preview": "6.4.0-alpha.19", diff --git a/lib/builder-webpack5/package.json b/lib/builder-webpack5/package.json index 200dda9deab..aea4bfdcfce 100644 --- a/lib/builder-webpack5/package.json +++ b/lib/builder-webpack5/package.json @@ -72,6 +72,7 @@ "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/router": "6.4.0-alpha.19", "@storybook/semver": "^7.3.2", + "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "@types/node": "^14.0.10", "babel-loader": "^8.2.2", diff --git a/yarn.lock b/yarn.lock index 6f782859667..8631fbecb2d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6304,6 +6304,7 @@ __metadata: "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/router": 6.4.0-alpha.19 "@storybook/semver": ^7.3.2 + "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 "@storybook/web-preview": 6.4.0-alpha.19 @@ -6393,6 +6394,7 @@ __metadata: "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/router": 6.4.0-alpha.19 "@storybook/semver": ^7.3.2 + "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 "@types/case-sensitive-paths-webpack-plugin": ^2.1.4 "@types/dotenv-webpack": ^5.0.0 From 474b6c56678872d6577107e380547e8772ca041a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 6 Sep 2021 19:31:00 +1000 Subject: [PATCH 190/285] Add regenerator to store and web-preview --- lib/store/package.json | 1 + lib/web-preview/package.json | 1 + yarn.lock | 2 ++ 3 files changed, 4 insertions(+) diff --git a/lib/store/package.json b/lib/store/package.json index 37db78318da..04645d4c16e 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -49,6 +49,7 @@ "global": "^4.4.0", "lodash": "^4.17.20", "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" }, diff --git a/lib/web-preview/package.json b/lib/web-preview/package.json index 89a339554fa..c542ec3355e 100644 --- a/lib/web-preview/package.json +++ b/lib/web-preview/package.json @@ -51,6 +51,7 @@ "global": "^4.4.0", "lodash": "^4.17.20", "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", "ts-dedent": "^2.0.0", "unfetch": "^4.2.0", "util-deprecate": "^1.0.2" diff --git a/yarn.lock b/yarn.lock index 8631fbecb2d..4ab2f4cb503 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7599,6 +7599,7 @@ __metadata: global: ^4.4.0 lodash: ^4.17.20 memoizerific: ^1.11.3 + regenerator-runtime: ^0.13.7 ts-dedent: ^2.0.0 util-deprecate: ^1.0.2 languageName: unknown @@ -7828,6 +7829,7 @@ __metadata: global: ^4.4.0 lodash: ^4.17.20 qs: ^6.10.0 + regenerator-runtime: ^0.13.7 ts-dedent: ^2.0.0 unfetch: ^4.2.0 util-deprecate: ^1.0.2 From 0f8432378fa5d972c09e5d2d38b6e3bc34e86a18 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 08:25:35 +1000 Subject: [PATCH 191/285] Fix issue with args memory over HMR applying in the wrong place --- lib/store/src/ArgsStore.test.ts | 16 +++++++++------- lib/store/src/ArgsStore.ts | 20 ++++++++++++-------- lib/web-preview/src/WebPreview.tsx | 3 ++- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/store/src/ArgsStore.test.ts b/lib/store/src/ArgsStore.test.ts index c2b78383fae..031a344015f 100644 --- a/lib/store/src/ArgsStore.test.ts +++ b/lib/store/src/ArgsStore.test.ts @@ -3,6 +3,7 @@ import { ArgsStore } from './ArgsStore'; jest.mock('@storybook/client-logger'); const stringType = { type: { name: 'string' } }; +const booleanType = { type: { name: 'boolean' } }; describe('ArgsStore', () => { describe('setInitial / get', () => { @@ -141,23 +142,24 @@ describe('ArgsStore', () => { const previousStory = { id: 'id', - initialArgs: { a: '1', b: '1' }, - argTypes: { a: stringType, b: stringType }, + initialArgs: { a: '1', b: false, c: 'unchanged' }, + argTypes: { a: stringType, b: booleanType, c: stringType }, } as any; store.setInitial('id', previousStory.initialArgs); - // NOTE: I'm not sure technically you should be allowed to set c here - store.update('id', { a: 'update', c: 'update' }); + // NOTE: I'm not sure technically you should be allowed to set d here, but + // let's make sure we behave sensibly if you do + store.update('id', { a: 'update', b: true, d: 'update' }); const story = { id: 'id', - initialArgs: { a: '1', b: '1' }, - argTypes: { a: stringType, b: stringType }, + initialArgs: { a: '1', b: false, c: 'unchanged' }, + argTypes: { a: stringType, b: booleanType, c: stringType }, } as any; store.resetOnImplementationChange(story, previousStory); // In any case c is not retained. - expect(store.get(story.id)).toEqual({ a: 'update', b: '1' }); + expect(store.get(story.id)).toEqual({ a: 'update', b: true, c: 'unchanged' }); }); }); diff --git a/lib/store/src/ArgsStore.ts b/lib/store/src/ArgsStore.ts index 5aefc0e903d..621a4e6f3f3 100644 --- a/lib/store/src/ArgsStore.ts +++ b/lib/store/src/ArgsStore.ts @@ -20,18 +20,22 @@ export class ArgsStore { } } - updateFromPersisted(story: Story, persisted: Args) { - // Use the argType to ensure we aren't persisting the wrong type of value to the type. - // For instance you could try and set a string-valued arg to a number by changing the URL - const mappedPersisted = mapArgsToTypes(persisted, story.argTypes); - + updateFromDelta(story: Story, delta: Args) { // Use the argType to ensure we setting a type with defined options to something outside of that - const validatedPersisted = validateOptions(mappedPersisted, story.argTypes); + const validatedDelta = validateOptions(delta, story.argTypes); // NOTE: we use `combineArgs` here rather than `combineParameters` because changes to arg // array values are persisted in the URL as sparse arrays, and we have to take that into // account when overriding the initialArgs (e.g. we patch [,'changed'] over ['initial', 'val']) - this.argsByStoryId[story.id] = combineArgs(this.argsByStoryId[story.id], validatedPersisted); + this.argsByStoryId[story.id] = combineArgs(this.argsByStoryId[story.id], validatedDelta); + } + + updateFromPersisted(story: Story, persisted: Args) { + // Use the argType to ensure we aren't persisting the wrong type of value to the type. + // For instance you could try and set a string-valued arg to a number by changing the URL + const mappedPersisted = mapArgsToTypes(persisted, story.argTypes); + + return this.updateFromDelta(story, mappedPersisted); } resetOnImplementationChange(story: Story, previousStory: Story) { @@ -39,7 +43,7 @@ export class ArgsStore { this.argsByStoryId[story.id] = story.initialArgs; if (delta !== DEEPLY_EQUAL) { - this.updateFromPersisted(story, delta); + this.updateFromDelta(story, delta); } } diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index c072b35bb04..7f806a5924c 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -255,7 +255,8 @@ export class WebPreview { const storyChanged = this.previousSelection?.storyId !== selection.storyId; const viewModeChanged = this.previousSelection?.viewMode !== selection.viewMode; - const implementationChanged = this.previousStory && story !== this.previousStory; + const implementationChanged = + !storyChanged && this.previousStory && story !== this.previousStory; if (persistedArgs) { this.storyStore.args.updateFromPersisted(story, persistedArgs); From 90d6eacd77932e855f7e80a9ac0371f97e7bf7ff Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 08:39:37 +1000 Subject: [PATCH 192/285] Ensure we reset args *before* re-rendering --- lib/web-preview/src/WebPreview.test.ts | 29 ++++++++++++++++++++++---- lib/web-preview/src/WebPreview.tsx | 9 +++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index ee37022da27..f41b180fffd 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -727,7 +727,7 @@ describe('WebPreview', () => { }); }); - it('resetStoryArgs resets a single arg', async () => { + it('resets a single arg', async () => { document.location.search = '?id=component-one--a'; await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); mockChannel.emit.mockClear(); @@ -742,7 +742,18 @@ describe('WebPreview', () => { argNames: ['foo'], }); - await waitForEvents([Events.STORY_ARGS_UPDATED]); + await waitForRender(); + + expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect.objectContaining({ + forceRemount: false, + storyContext: expect.objectContaining({ + initialArgs: { foo: 'a' }, + args: { foo: 'a', new: 'value' }, + }), + }), + undefined // this is coming from view.prepareForStory, not super important + ); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_ARGS_UPDATED, { storyId: 'component-one--a', @@ -750,7 +761,7 @@ describe('WebPreview', () => { }); }); - it('resetStoryArgs resets all args', async () => { + it('resets all args', async () => { document.location.search = '?id=component-one--a'; await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { @@ -763,8 +774,18 @@ describe('WebPreview', () => { storyId: 'component-one--a', }); - await waitForEvents([Events.STORY_ARGS_UPDATED]); + await waitForRender(); + expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect.objectContaining({ + forceRemount: false, + storyContext: expect.objectContaining({ + initialArgs: { foo: 'a' }, + args: { foo: 'a' }, + }), + }), + undefined // this is coming from view.prepareForStory, not super important + ); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_ARGS_UPDATED, { storyId: 'component-one--a', args: { foo: 'a' }, diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 7f806a5924c..32d3156eb46 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -190,7 +190,14 @@ export class WebPreview { } async onResetArgs({ storyId, argNames }: { storyId: string; argNames?: string[] }) { - const { initialArgs } = await this.storyStore.loadStory({ storyId }); + // NOTE: we have to be careful here and avoid await-ing when updating the current story's args. + // That's because below in `renderStoryToElement` we have also bound to this event and will + // render the story in the same tick. + // However, we can do that safely as the current story is available in `this.previousStory` + const { initialArgs } = + storyId === this.previousStory.id + ? this.previousStory + : await this.storyStore.loadStory({ storyId }); const argNamesToReset = argNames || Object.keys(this.storyStore.args.get(storyId)); const updatedArgs = argNamesToReset.reduce((acc, argName) => { From a576375553ddefe42f89d16fcf1ec0e99ca0aae5 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 08:40:06 +1000 Subject: [PATCH 193/285] Remove old comments --- .../src/preview/virtualModuleModernEntry.js.handlebars | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index 0e11ef12698..0f33ad11166 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -18,6 +18,7 @@ const fetchStoriesList = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); + const preview = new WebPreview({ importFn, getGlobalAnnotations, fetchStoriesList }); window.__STORYBOOK_PREVIEW__ = preview; @@ -28,15 +29,11 @@ preview.initialize(); if (module.hot) { module.hot.accept('./{{storiesFilename}}', () => { - console.log('configEntry HMR accept storybook-stories.js'); - console.log(arguments); // importFn has changed so we need to patch the new one in preview.onImportFnChanged({ importFn }); }); module.hot.accept([{{#each configs}}'{{this}}',{{/each}}], () => { - console.log('configEntry HMR accept config file'); - console.log(arguments); // getGlobalAnnotations has changed so we need to patch the new one in preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations }); }); From d8349ef00ffa288d5f3edc0d8007ca1502774cc9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 08:40:33 +1000 Subject: [PATCH 194/285] Use object freeze to ensure stories are not editable --- lib/store/src/prepareStory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index e5ecab8ef00..0f6d9e5db51 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -181,12 +181,12 @@ export function prepareStory( return undefined; }; - return { + return Object.freeze({ ...contextForEnhancers, originalStoryFn: render, undecoratedStoryFn, unboundStoryFn, applyLoaders, runPlayFunction, - }; + }); } From 438e726663045f19c2eec560f08c88e0ea02f222 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 08:41:10 +1000 Subject: [PATCH 195/285] Switch `createGate` to a hooks-like syntax --- lib/web-preview/src/WebPreview.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index f41b180fffd..c3c1454f2d8 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -40,12 +40,12 @@ jest.mock('global', () => ({ jest.mock('@storybook/client-logger'); jest.mock('react-dom'); -const createGate = () => { +const createGate = (): [Promise, (_?: any) => void] => { let openGate = (_?: any) => {}; const gate = new Promise((resolve) => { openGate = resolve; }); - return { gate, openGate }; + return [gate, openGate]; }; beforeEach(() => { @@ -585,7 +585,7 @@ describe('WebPreview', () => { describe('while story is still rendering', () => { it('silently changes args if still running loaders', async () => { - const { gate, openGate } = createGate(); + const [gate, openGate] = createGate(); document.location.search = '?id=component-one--a'; componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); @@ -615,7 +615,7 @@ describe('WebPreview', () => { }); it('does nothing and warns renderToDOM is running', async () => { - const { gate, openGate } = createGate(); + const [gate, openGate] = createGate(); document.location.search = '?id=component-one--a'; globalAnnotations.renderToDOM.mockImplementationOnce(async () => gate); @@ -646,7 +646,7 @@ describe('WebPreview', () => { }); it('warns and calls renderToDOM again if play function is running', async () => { - const { gate, openGate } = createGate(); + const [gate, openGate] = createGate(); componentOneExports.a.play.mockImplementationOnce(async () => gate); const renderToDOMCalled = new Promise((resolve) => { @@ -699,7 +699,7 @@ describe('WebPreview', () => { }); describe('onResetArgs', () => { - it('resetStoryArgs emits STORY_ARGS_UPDATED', async () => { + it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); mockChannel.emit.mockClear(); @@ -1133,7 +1133,7 @@ describe('WebPreview', () => { describe('while story is still rendering', () => { it('stops initial story after loaders if running', async () => { - const { gate, openGate } = createGate(); + const [gate, openGate] = createGate(); componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); document.location.search = '?id=component-one--a'; @@ -1164,7 +1164,7 @@ describe('WebPreview', () => { }); it('stops initial story after renderToDOM if running', async () => { - const { gate, openGate } = createGate(); + const [gate, openGate] = createGate(); document.location.search = '?id=component-one--a'; globalAnnotations.renderToDOM.mockImplementationOnce(async () => gate); @@ -1191,7 +1191,7 @@ describe('WebPreview', () => { }); it('stops initial story after runPlayFunction if running', async () => { - const { gate, openGate } = createGate(); + const [gate, openGate] = createGate(); componentOneExports.a.play.mockImplementationOnce(async () => gate); const renderToDOMCalled = new Promise((resolve) => { From dcf018bb9dee83eda0276304ffe6c4cd37a9ffd9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 08:46:25 +1000 Subject: [PATCH 196/285] Ensure we handle it if loaders or play throw --- lib/web-preview/src/WebPreview.test.ts | 32 ++++++++++++++++++++++++++ lib/web-preview/src/WebPreview.tsx | 13 +++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index c3c1454f2d8..97732a17f78 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -339,6 +339,22 @@ describe('WebPreview', () => { ); }); + it('renders exception if a loader throws', async () => { + const error = new Error('error'); + componentOneExports.default.loaders[0].mockImplementationOnce(() => { + throw error; + }); + + document.location.search = '?id=component-one--a'; + const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + await preview.initialize(); + + await waitForRender(); + + expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_THREW_EXCEPTION, error); + expect(preview.view.showErrorDisplay).toHaveBeenCalledWith(error); + }); + it('renders exception if renderToDOM throws', async () => { const error = new Error('error'); globalAnnotations.renderToDOM.mockImplementationOnce(() => { @@ -355,6 +371,22 @@ describe('WebPreview', () => { expect(preview.view.showErrorDisplay).toHaveBeenCalledWith(error); }); + it('renders exception if the play function throws', async () => { + const error = new Error('error'); + componentOneExports.a.play.mockImplementationOnce(() => { + throw error; + }); + + document.location.search = '?id=component-one--a'; + const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + await preview.initialize(); + + await waitForRender(); + + expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_THREW_EXCEPTION, error); + expect(preview.view.showErrorDisplay).toHaveBeenCalledWith(error); + }); + it('renders error if the story calls showError', async () => { const error = { title: 'title', description: 'description' }; globalAnnotations.renderToDOM.mockImplementationOnce((context) => context.showError(error)); diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 32d3156eb46..0e212bd50ac 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -412,12 +412,8 @@ export class WebPreview { storyFn: () => unboundStoryFn(updatedStoryContext), unboundStoryFn, }; - try { - await this.renderToDOM(renderContext, element); - } catch (err) { - renderContextWithoutStoryContext.showException(err); - return; - } + await this.renderToDOM(renderContext, element); + if (controller.signal.aborted) { return; } @@ -497,7 +493,10 @@ export class WebPreview { }; // Start the first render - initialRender().catch((err) => logger.error(`Error rendering story: ${err}`)); + // NOTE: we don't await here because we need to return the "cleanup" function below + // right away, so if the user changes story during the first render we can cancel + // it without having to first wait for it to finish. + initialRender().catch((err) => renderContextWithoutStoryContext.showException(err)); // Listen to events and re-render story this.channel.on(Events.UPDATE_GLOBALS, rerenderStory); From d2e713aa323e64f8cd9bc53c1ecade11457546e6 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 08:48:08 +1000 Subject: [PATCH 197/285] Fix old use of "Meta" (=> "Annotation") --- lib/store/src/StoryStore.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index aa1317d2b3c..a53fd928226 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -205,13 +205,17 @@ export class StoryStore { storyId: StoryId; csfFile: CSFFile; }): Story { - const storyMeta = csfFile.stories[storyId]; - if (!storyMeta) { + const storyAnnotations = csfFile.stories[storyId]; + if (!storyAnnotations) { throw new Error(`Didn't find '${storyId}' in CSF file, this is unexpected`); } - const componentMeta = csfFile.meta; + const componentAnnotations = csfFile.meta; - const story = this.prepareStoryWithCache(storyMeta, componentMeta, this.globalAnnotations); + const story = this.prepareStoryWithCache( + storyAnnotations, + componentAnnotations, + this.globalAnnotations + ); this.args.setInitial(story.id, story.initialArgs); this.hooks[story.id] = new HooksContext(); return story; From 1ad369c0af64c8f1f43d47057ab23ab96d33b3a1 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 14:30:46 +1000 Subject: [PATCH 198/285] Rename GlobalAnnotations => ProjectAnnotations --- .../virtualModuleModernEntry.js.handlebars | 8 +- .../virtualModuleModernEntry.js.handlebars | 8 +- lib/client-api/src/ClientApi.ts | 32 +- lib/client-api/src/types.ts | 4 +- lib/core-client/src/preview/start.ts | 16 +- lib/store/src/GlobalsStore.test.ts | 8 +- lib/store/src/GlobalsStore.ts | 2 +- lib/store/src/StoryStore.test.ts | 46 +-- lib/store/src/StoryStore.ts | 28 +- lib/store/src/prepareStory.ts | 20 +- lib/store/src/types.ts | 6 +- .../src/WebPreview.integration.test.ts | 36 +- lib/web-preview/src/WebPreview.mockdata.ts | 4 +- lib/web-preview/src/WebPreview.test.ts | 334 +++++++++--------- lib/web-preview/src/WebPreview.tsx | 46 +-- lib/web-preview/src/composeConfigs.ts | 4 +- lib/web-preview/src/types.ts | 6 +- 17 files changed, 308 insertions(+), 300 deletions(-) diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index 0f33ad11166..e24c395043e 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -4,7 +4,7 @@ import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; import fetch from 'unfetch'; -const getGlobalAnnotations = () => +const getProjectAnnotations = () => composeConfigs([ {{#each configs}} require('{{this}}'), @@ -19,7 +19,7 @@ const fetchStoriesList = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new WebPreview({ importFn, getGlobalAnnotations, fetchStoriesList }); +const preview = new WebPreview({ importFn, getProjectAnnotations, fetchStoriesList }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; @@ -34,7 +34,7 @@ if (module.hot) { }); module.hot.accept([{{#each configs}}'{{this}}',{{/each}}], () => { - // getGlobalAnnotations has changed so we need to patch the new one in - preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations }); + // getProjectAnnotations has changed so we need to patch the new one in + preview.onGetProjectAnnotationsChanged({ getProjectAnnotations }); }); } diff --git a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars index 0e11ef12698..cee6e249d1b 100644 --- a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars @@ -4,7 +4,7 @@ import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; import fetch from 'unfetch'; -const getGlobalAnnotations = () => +const getProjectAnnotations = () => composeConfigs([ {{#each configs}} require('{{this}}'), @@ -18,7 +18,7 @@ const fetchStoriesList = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new WebPreview({ importFn, getGlobalAnnotations, fetchStoriesList }); +const preview = new WebPreview({ importFn, getProjectAnnotations, fetchStoriesList }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; @@ -37,7 +37,7 @@ if (module.hot) { module.hot.accept([{{#each configs}}'{{this}}',{{/each}}], () => { console.log('configEntry HMR accept config file'); console.log(arguments); - // getGlobalAnnotations has changed so we need to patch the new one in - preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations }); + // getProjectAnnotations has changed so we need to patch the new one in + preview.onGetProjectAnnotationsChanged({ getProjectAnnotations }); }); } diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 837aa05dc9b..4a7b6aa286e 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -22,7 +22,7 @@ import { } from '@storybook/csf'; import { NormalizedComponentAnnotations, - NormalizedGlobalAnnotations, + NormalizedProjectAnnotations, Path, StoriesList, ModuleExports, @@ -124,17 +124,17 @@ export const addArgTypesEnhancer = (enhancer: ArgTypesEnhancer) => export const getGlobalRender = () => { checkMethod('getGlobalRender', false); - return singleton.globalAnnotations.render; + return singleton.projectAnnotations.render; }; export const setGlobalRender = (render: StoryFn) => { checkMethod('setGlobalRender', false); - singleton.globalAnnotations.render = render; + singleton.projectAnnotations.render = render; }; const invalidStoryTypes = new Set(['string', 'number', 'boolean', 'symbol']); export default class ClientApi { - globalAnnotations: NormalizedGlobalAnnotations; + projectAnnotations: NormalizedProjectAnnotations; storyStore?: StoryStore; @@ -151,7 +151,7 @@ export default class ClientApi { private lastFileName = 0; constructor() { - this.globalAnnotations = { + this.projectAnnotations = { loaders: [], decorators: [], parameters: {}, @@ -176,7 +176,7 @@ export default class ClientApi { getStoriesList() { const fileNameOrder = Object.keys(this.csfExports); - const storySortParameter = this.globalAnnotations.parameters?.options?.storySort; + const storySortParameter = this.projectAnnotations.parameters?.options?.storySort; const storyEntries = Object.entries(this.stories); // Add the kind parameters and global parameters to each entry @@ -191,7 +191,7 @@ export default class ClientApi { storyId, this.storyStore.storyFromCSFFile({ storyId, csfFile }), csfFile.meta.parameters, - this.globalAnnotations.parameters, + this.projectAnnotations.parameters, ]; } ); @@ -234,12 +234,12 @@ export default class ClientApi { ); addDecorator = (decorator: DecoratorFunction) => { - this.globalAnnotations.decorators.push(decorator); + this.projectAnnotations.decorators.push(decorator); }; clearDecorators = deprecate( () => { - this.globalAnnotations.decorators = []; + this.projectAnnotations.decorators = []; }, dedent` \`clearDecorators\` is deprecated and will be removed in Storybook 7.0. @@ -253,28 +253,28 @@ export default class ClientApi { globalTypes, ...parameters }: Parameters & { globals?: Globals; globalTypes?: GlobalTypes }) => { - this.globalAnnotations.parameters = combineParameters( - this.globalAnnotations.parameters, + this.projectAnnotations.parameters = combineParameters( + this.projectAnnotations.parameters, parameters ); if (globals) { - this.globalAnnotations.globals = globals; + this.projectAnnotations.globals = globals; } if (globalTypes) { - this.globalAnnotations.globalTypes = normalizeInputTypes(globalTypes); + this.projectAnnotations.globalTypes = normalizeInputTypes(globalTypes); } }; addLoader = (loader: LoaderFunction) => { - this.globalAnnotations.loaders.push(loader); + this.projectAnnotations.loaders.push(loader); }; addArgsEnhancer = (enhancer: ArgsEnhancer) => { - this.globalAnnotations.argsEnhancers.push(enhancer); + this.projectAnnotations.argsEnhancers.push(enhancer); }; addArgTypesEnhancer = (enhancer: ArgTypesEnhancer) => { - this.globalAnnotations.argTypesEnhancers.push(enhancer); + this.projectAnnotations.argTypesEnhancers.push(enhancer); }; // what are the occasions that "m" is a boolean vs an obj diff --git a/lib/client-api/src/types.ts b/lib/client-api/src/types.ts index 2a3ae344882..31e82c10451 100644 --- a/lib/client-api/src/types.ts +++ b/lib/client-api/src/types.ts @@ -13,7 +13,7 @@ import { LoaderFunction, StoryContext, } from '@storybook/addons'; -import { AnyFramework, StoryIdentifier, GlobalAnnotations } from '@storybook/csf'; +import { AnyFramework, StoryIdentifier, ProjectAnnotations } from '@storybook/csf'; import { StoryStore, HooksContext } from '@storybook/store'; export type { @@ -90,7 +90,7 @@ export interface StoreData { export interface ClientApiParams { storyStore: StoryStore; - decorateStory?: GlobalAnnotations['applyDecorators']; + decorateStory?: ProjectAnnotations['applyDecorators']; noStoryModuleAddMethodHotDispose?: boolean; } diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 2a34baf9593..c317c61a61d 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -1,6 +1,6 @@ import global from 'global'; import { ClientApi } from '@storybook/client-api'; -import { WebGlobalAnnotations, WebPreview } from '@storybook/web-preview'; +import { WebProjectAnnotations, WebPreview } from '@storybook/web-preview'; import { AnyFramework, ArgsStoryFn } from '@storybook/csf'; import createChannel from '@storybook/channel-postmessage'; import { addons } from '@storybook/addons'; @@ -13,12 +13,12 @@ import { executeLoadableForChanges } from './executeLoadable'; const { window: globalWindow } = global; export function start( - renderToDOM: WebGlobalAnnotations['renderToDOM'], + renderToDOM: WebProjectAnnotations['renderToDOM'], { decorateStory, render, }: { - decorateStory?: WebGlobalAnnotations['applyDecorators']; + decorateStory?: WebProjectAnnotations['applyDecorators']; render?: ArgsStoryFn; } = {} ) { @@ -44,9 +44,9 @@ export function start( configure(framework: string, loadable: Loadable, m?: NodeModule) { clientApi.addParameters({ framework }); - // We need to run the `executeLoadableForChanges` function *inside* the `getGlobalAnnotations + // We need to run the `executeLoadableForChanges` function *inside* the `getProjectAnnotations // function in case it throws. So we also need to process its output there also - const getGlobalAnnotations = () => { + const getProjectAnnotations = () => { const { added, removed } = executeLoadableForChanges(loadable, m); Array.from(added.entries()).forEach(([fileName, fileExports]) => @@ -58,7 +58,7 @@ export function start( ); return { - ...clientApi.globalAnnotations, + ...clientApi.projectAnnotations, render, renderToDOM, applyDecorators: decorateStory, @@ -68,7 +68,7 @@ export function start( if (!preview) { preview = new WebPreview({ importFn: (path: Path) => clientApi.importFn(path), - getGlobalAnnotations, + getProjectAnnotations, fetchStoriesList: () => clientApi.getStoriesList(), }); if (globalWindow) { @@ -84,7 +84,7 @@ export function start( preview.initializeSync({ cacheAllCSFFiles: true }); } else { - getGlobalAnnotations(); + getProjectAnnotations(); preview.onImportFnChanged({ importFn: (path: Path) => clientApi.importFn(path) }); } }, diff --git a/lib/store/src/GlobalsStore.test.ts b/lib/store/src/GlobalsStore.test.ts index 57292988c86..422d830c4b5 100644 --- a/lib/store/src/GlobalsStore.test.ts +++ b/lib/store/src/GlobalsStore.test.ts @@ -85,13 +85,13 @@ describe('GlobalsStore', () => { }); }); - describe('resetOnGlobalAnnotationsChange', () => { + describe('resetOnProjectAnnotationsChange', () => { it('is initialized to the (new) default values from globalTypes if the (new) global is unset', () => { const store = new GlobalsStore({ globals: {}, globalTypes: {} }); expect(store.get()).toEqual({}); - store.resetOnGlobalAnnotationsChange({ + store.resetOnProjectAnnotationsChange({ globals: { arg1: 'arg1', arg2: 2, @@ -130,7 +130,7 @@ describe('GlobalsStore', () => { // You can set undeclared values (currently, deprecated) expect(store.get()).toEqual({ arg1: 'new-arg1', arg2: 'new-arg2', arg3: 'new-arg3' }); - store.resetOnGlobalAnnotationsChange({ + store.resetOnProjectAnnotationsChange({ globals: { arg1: 'arg1', }, @@ -169,7 +169,7 @@ describe('GlobalsStore', () => { arg4: 'arg4', }); - store.resetOnGlobalAnnotationsChange({ + store.resetOnProjectAnnotationsChange({ globals: { arg1: 'edited-arg1', arg4: 'edited-arg4', diff --git a/lib/store/src/GlobalsStore.ts b/lib/store/src/GlobalsStore.ts index 8b451c4b152..181780edce6 100644 --- a/lib/store/src/GlobalsStore.ts +++ b/lib/store/src/GlobalsStore.ts @@ -56,7 +56,7 @@ export class GlobalsStore { this.globals = { ...this.globals, ...allowedUrlGlobals }; } - resetOnGlobalAnnotationsChange({ + resetOnProjectAnnotationsChange({ globals, globalTypes, }: { diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index 782bb9188be..d3ba43a93e6 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -1,5 +1,5 @@ import { StoryId } from '@storybook/api'; -import { AnyFramework, GlobalAnnotations } from '@storybook/csf'; +import { AnyFramework, ProjectAnnotations } from '@storybook/csf'; import { HooksContext } from '../../addons/dist/ts3.9/hooks'; import { prepareStory } from './prepareStory'; @@ -35,7 +35,7 @@ const importFn = jest.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? componentOneExports : componentTwoExports; }); -const globalAnnotations: GlobalAnnotations = { +const projectAnnotations: ProjectAnnotations = { globals: { a: 'b' }, globalTypes: { a: { type: 'string' } }, argTypes: { a: { type: 'string' } }, @@ -65,28 +65,28 @@ const storiesList: StoriesList = { const fetchStoriesList = async () => storiesList; describe('StoryStore', () => { - describe('globalAnnotations', () => { + describe('projectAnnotations', () => { it('normalizes on initialization', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); - expect(store.globalAnnotations.globalTypes).toEqual({ + expect(store.projectAnnotations.globalTypes).toEqual({ a: { name: 'a', type: { name: 'string' } }, }); - expect(store.globalAnnotations.argTypes).toEqual({ + expect(store.projectAnnotations.argTypes).toEqual({ a: { name: 'a', type: { name: 'string' } }, }); }); - it('normalizes on updateGlobalAnnotations', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + it('normalizes on updateProjectAnnotations', async () => { + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); - store.updateGlobalAnnotations(globalAnnotations); - expect(store.globalAnnotations.globalTypes).toEqual({ + store.updateProjectAnnotations(projectAnnotations); + expect(store.projectAnnotations.globalTypes).toEqual({ a: { name: 'a', type: { name: 'string' } }, }); - expect(store.globalAnnotations.argTypes).toEqual({ + expect(store.projectAnnotations.argTypes).toEqual({ a: { name: 'a', type: { name: 'string' } }, }); }); @@ -94,7 +94,7 @@ describe('StoryStore', () => { describe('loadStory', () => { it('pulls the story via the importFn', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); importFn.mockClear(); @@ -108,7 +108,7 @@ describe('StoryStore', () => { }); it('uses a cache', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -132,7 +132,7 @@ describe('StoryStore', () => { describe('componentStoriesFromCSFFile', () => { it('returns all the stories in the file', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); const csfFile = await store.loadCSFFileByStoryId('component-one--a'); @@ -145,7 +145,7 @@ describe('StoryStore', () => { describe('getStoryContext', () => { it('returns the args and globals correctly', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -157,7 +157,7 @@ describe('StoryStore', () => { }); it('returns the args and globals correctly when they change', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -172,7 +172,7 @@ describe('StoryStore', () => { }); it('returns the same hooks each time', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -184,7 +184,7 @@ describe('StoryStore', () => { describe('cleanupStory', () => { it('cleans the hooks from the context', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -198,7 +198,7 @@ describe('StoryStore', () => { describe('loadAllCSFFiles', () => { it('imports *all* csf files', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); importFn.mockClear(); @@ -213,14 +213,14 @@ describe('StoryStore', () => { describe('extract', () => { it('throws if you have not called cacheAllCSFFiles', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); expect(() => store.extract()).toThrow(/Cannot call extract/); }); it('produces objects with functions and hooks stripped', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); await store.cacheAllCSFFiles(); @@ -331,7 +331,7 @@ describe('StoryStore', () => { }); const store = new StoryStore({ importFn: docsOnlyImportFn, - globalAnnotations, + projectAnnotations, fetchStoriesList, }); await store.initialize(); @@ -350,7 +350,7 @@ describe('StoryStore', () => { describe('getSetStoriesPayload', () => { it('maps stories list to payload correctly', async () => { - const store = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); await store.initialize(); await store.cacheAllCSFFiles(); diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index a53fd928226..18b9f8391c3 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -4,7 +4,7 @@ import { StoryId, StoryContextForLoaders, AnyFramework, - GlobalAnnotations, + ProjectAnnotations, ComponentTitle, } from '@storybook/csf'; import mapValues from 'lodash/mapValues'; @@ -19,7 +19,7 @@ import { CSFFile, ModuleImportFn, Story, - NormalizedGlobalAnnotations, + NormalizedProjectAnnotations, Path, ExtractOptions, ModuleExports, @@ -34,12 +34,12 @@ import { inferControls } from './inferControls'; const CSF_CACHE_SIZE = 100; const STORY_CACHE_SIZE = 1000; -function normalizeGlobalAnnotations({ +function normalizeProjectAnnotations({ argTypes, globalTypes, argTypesEnhancers, ...annotations -}: GlobalAnnotations): NormalizedGlobalAnnotations { +}: ProjectAnnotations): NormalizedProjectAnnotations { return { ...(argTypes && { argTypes: normalizeInputTypes(argTypes) }), ...(globalTypes && { globalTypes: normalizeInputTypes(globalTypes) }), @@ -61,7 +61,7 @@ export class StoryStore { importFn: ModuleImportFn; - globalAnnotations: NormalizedGlobalAnnotations; + projectAnnotations: NormalizedProjectAnnotations; globals: GlobalsStore; @@ -77,18 +77,18 @@ export class StoryStore { constructor({ importFn, - globalAnnotations, + projectAnnotations, fetchStoriesList, }: { importFn: ModuleImportFn; - globalAnnotations: GlobalAnnotations; + projectAnnotations: ProjectAnnotations; fetchStoriesList: ConstructorParameters[0]['fetchStoriesList']; }) { this.storiesList = new StoriesListStore({ fetchStoriesList }); this.importFn = importFn; - this.globalAnnotations = normalizeGlobalAnnotations(globalAnnotations); + this.projectAnnotations = normalizeProjectAnnotations(projectAnnotations); - const { globals, globalTypes } = globalAnnotations; + const { globals, globalTypes } = projectAnnotations; this.globals = new GlobalsStore({ globals, globalTypes }); this.args = new ArgsStore(); this.hooks = {}; @@ -113,10 +113,10 @@ export class StoryStore { } } - updateGlobalAnnotations(globalAnnotations: GlobalAnnotations) { - this.globalAnnotations = normalizeGlobalAnnotations(globalAnnotations); - const { globals, globalTypes } = globalAnnotations; - this.globals.resetOnGlobalAnnotationsChange({ globals, globalTypes }); + updateProjectAnnotations(projectAnnotations: ProjectAnnotations) { + this.projectAnnotations = normalizeProjectAnnotations(projectAnnotations); + const { globals, globalTypes } = projectAnnotations; + this.globals.resetOnProjectAnnotationsChange({ globals, globalTypes }); } async onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { @@ -214,7 +214,7 @@ export class StoryStore { const story = this.prepareStoryWithCache( storyAnnotations, componentAnnotations, - this.globalAnnotations + this.projectAnnotations ); this.args.setInitial(story.id, story.initialArgs); this.hooks[story.id] = new HooksContext(); diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 0f6d9e5db51..fef1fa5cdeb 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -17,7 +17,7 @@ import { NormalizedComponentAnnotations, Story, NormalizedStoryAnnotations, - NormalizedGlobalAnnotations, + NormalizedProjectAnnotations, } from './types'; import { combineParameters } from './parameters'; import { applyHooks } from './hooks'; @@ -39,7 +39,7 @@ const argTypeDefaultValueWarning = deprecate( export function prepareStory( storyAnnotations: NormalizedStoryAnnotations, componentAnnotations: NormalizedComponentAnnotations, - globalAnnotations: NormalizedGlobalAnnotations + projectAnnotations: NormalizedProjectAnnotations ): Story { // NOTE: in the current implementation we are doing everything once, up front, rather than doing // anything at render time. The assumption is that as we don't load all the stories at once, this @@ -49,7 +49,7 @@ export function prepareStory( const { title } = componentAnnotations; const parameters: Parameters = combineParameters( - globalAnnotations.parameters, + projectAnnotations.parameters, componentAnnotations.parameters, storyAnnotations.parameters ); @@ -57,7 +57,7 @@ export function prepareStory( const decorators = [ ...(storyAnnotations.decorators || []), ...(componentAnnotations.decorators || []), - ...(globalAnnotations.decorators || []), + ...(projectAnnotations.decorators || []), ]; // Currently it is only possible to set these globally @@ -65,10 +65,10 @@ export function prepareStory( applyDecorators = defaultDecorateStory, argTypesEnhancers = [], argsEnhancers = [], - } = globalAnnotations; + } = projectAnnotations; const loaders = [ - ...(globalAnnotations.loaders || []), + ...(projectAnnotations.loaders || []), ...(componentAnnotations.loaders || []), ...(storyAnnotations.loaders || []), ]; @@ -78,10 +78,10 @@ export function prepareStory( storyAnnotations.userStoryFn || storyAnnotations.render || componentAnnotations.render || - globalAnnotations.render; + projectAnnotations.render; const passedArgTypes: StrictArgTypes = combineParameters( - globalAnnotations.argTypes, + projectAnnotations.argTypes, componentAnnotations.argTypes, storyAnnotations.argTypes ) as StrictArgTypes; @@ -92,7 +92,7 @@ export function prepareStory( // Pull out args[X] || argTypes[X].defaultValue into initialArgs const passedArgs: Args = combineParameters( - globalAnnotations.args, + projectAnnotations.args, componentAnnotations.args, storyAnnotations.args ) as Args; @@ -146,7 +146,7 @@ export function prepareStory( contextForEnhancers.parameters = { ...contextForEnhancers.parameters, __id: id, - globalTypes: globalAnnotations.globalTypes, + globalTypes: projectAnnotations.globalTypes, args: contextForEnhancers.initialArgs, argTypes: contextForEnhancers.argTypes, }; diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 7c8a915f0d9..654d66d7bc0 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -11,7 +11,7 @@ import { StoryContext, ComponentTitle, AnyFramework, - GlobalAnnotations, + ProjectAnnotations, ComponentAnnotations, StoryAnnotations, StoryFn, @@ -24,9 +24,9 @@ export type Path = string; export type ModuleExports = Record; export type ModuleImportFn = (path: Path) => Promise | ModuleExports; -export type NormalizedGlobalAnnotations< +export type NormalizedProjectAnnotations< TFramework extends AnyFramework -> = GlobalAnnotations & { +> = ProjectAnnotations & { argTypes?: StrictArgTypes; globalTypes?: StrictGlobalTypes; }; diff --git a/lib/web-preview/src/WebPreview.integration.test.ts b/lib/web-preview/src/WebPreview.integration.test.ts index aef86bf35e2..155bf1130c7 100644 --- a/lib/web-preview/src/WebPreview.integration.test.ts +++ b/lib/web-preview/src/WebPreview.integration.test.ts @@ -7,8 +7,8 @@ import { WebPreview } from './WebPreview'; import { componentOneExports, importFn, - globalAnnotations, - getGlobalAnnotations, + projectAnnotations, + getProjectAnnotations, fetchStoriesList, emitter, mockChannel, @@ -47,9 +47,9 @@ beforeEach(() => { componentOneExports.default.loaders[0].mockReset().mockImplementation(async () => ({ l: 7 })); componentOneExports.default.parameters.docs.container.mockClear(); componentOneExports.a.play.mockReset(); - globalAnnotations.renderToDOM.mockReset(); - globalAnnotations.render.mockClear(); - globalAnnotations.decorators[0].mockClear(); + projectAnnotations.renderToDOM.mockReset(); + projectAnnotations.render.mockClear(); + projectAnnotations.decorators[0].mockClear(); addons.setChannel(mockChannel as any); }); @@ -57,21 +57,21 @@ beforeEach(() => { describe('WebPreview', () => { describe('initial render', () => { it('renders story mode through the stack', async () => { - globalAnnotations.renderToDOM.mockImplementationOnce(({ storyFn }: RenderContext) => + projectAnnotations.renderToDOM.mockImplementationOnce(({ storyFn }: RenderContext) => storyFn() ); document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); - expect(globalAnnotations.decorators[0]).toHaveBeenCalled(); - expect(globalAnnotations.render).toHaveBeenCalled(); + expect(projectAnnotations.decorators[0]).toHaveBeenCalled(); + expect(projectAnnotations.render).toHaveBeenCalled(); }); it('renders docs mode through docs page', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); const docsRoot = window.document.createElement('div'); // @ts-ignore @@ -95,9 +95,9 @@ describe('WebPreview', () => { describe('onGetGlobalMeta changed (HMR)', () => { const newGlobalDecorator = jest.fn((s) => s()); - const newGetGlobalAnnotations = () => { + const newGetProjectAnnotations = () => { return { - ...globalAnnotations, + ...projectAnnotations, args: { a: 'second' }, globals: { a: 'second' }, decorators: [newGlobalDecorator], @@ -106,21 +106,21 @@ describe('WebPreview', () => { it('renders story mode through the updated stack', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); - globalAnnotations.renderToDOM.mockImplementationOnce(({ storyFn }: RenderContext) => + projectAnnotations.renderToDOM.mockImplementationOnce(({ storyFn }: RenderContext) => storyFn() ); - globalAnnotations.decorators[0].mockClear(); + projectAnnotations.decorators[0].mockClear(); mockChannel.emit.mockClear(); - preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations: newGetGlobalAnnotations }); + preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations }); await waitForRender(); - expect(globalAnnotations.decorators[0]).not.toHaveBeenCalled(); + expect(projectAnnotations.decorators[0]).not.toHaveBeenCalled(); expect(newGlobalDecorator).toHaveBeenCalled(); - expect(globalAnnotations.render).toHaveBeenCalled(); + expect(projectAnnotations.render).toHaveBeenCalled(); }); }); }); diff --git a/lib/web-preview/src/WebPreview.mockdata.ts b/lib/web-preview/src/WebPreview.mockdata.ts index c018db7d059..0a0ba09717f 100644 --- a/lib/web-preview/src/WebPreview.mockdata.ts +++ b/lib/web-preview/src/WebPreview.mockdata.ts @@ -24,14 +24,14 @@ export const importFn = jest.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? componentOneExports : componentTwoExports; }); -export const globalAnnotations = { +export const projectAnnotations = { globals: { a: 'b' }, globalTypes: {}, decorators: [jest.fn((s) => s())], render: jest.fn(), renderToDOM: jest.fn(), }; -export const getGlobalAnnotations = () => globalAnnotations; +export const getProjectAnnotations = () => projectAnnotations; export const storiesList: StoriesList = { v: 3, diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/web-preview/src/WebPreview.test.ts index 97732a17f78..ce8dcfd85b2 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/web-preview/src/WebPreview.test.ts @@ -10,8 +10,8 @@ import { componentOneExports, componentTwoExports, importFn, - globalAnnotations, - getGlobalAnnotations, + projectAnnotations, + getProjectAnnotations, fetchStoriesList, emitter, mockChannel, @@ -55,9 +55,9 @@ beforeEach(() => { componentOneExports.default.loaders[0].mockReset().mockImplementation(async () => ({ l: 7 })); componentOneExports.default.parameters.docs.container.mockClear(); componentOneExports.a.play.mockReset(); - globalAnnotations.renderToDOM.mockReset(); - globalAnnotations.render.mockClear(); - globalAnnotations.decorators[0].mockClear(); + projectAnnotations.renderToDOM.mockReset(); + projectAnnotations.render.mockClear(); + projectAnnotations.decorators[0].mockClear(); // @ts-ignore ReactDOM.render.mockReset().mockImplementation((_: any, _2: any, cb: () => any) => cb()); // @ts-ignore @@ -68,10 +68,10 @@ beforeEach(() => { describe('WebPreview', () => { describe('constructor', () => { - it('shows an error if getGlobalAnnotations throws', async () => { + it('shows an error if getProjectAnnotations throws', async () => { const err = new Error('meta error'); const preview = new WebPreview({ - getGlobalAnnotations: () => { + getProjectAnnotations: () => { throw err; }, importFn, @@ -87,14 +87,14 @@ describe('WebPreview', () => { it('sets globals from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.storyStore.globals.get()).toEqual({ a: 'c' }); }); it('emits the SET_GLOBALS event', async () => { - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'b' }, @@ -104,7 +104,7 @@ describe('WebPreview', () => { it('SET_GLOBALS sets globals and types even when undefined', async () => { await new WebPreview({ - getGlobalAnnotations: () => ({}), + getProjectAnnotations: () => ({}), importFn, fetchStoriesList, }).initialize(); @@ -118,7 +118,7 @@ describe('WebPreview', () => { it('emits the SET_GLOBALS event from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'c' }, @@ -129,7 +129,7 @@ describe('WebPreview', () => { it('sets args from the URL', async () => { document.location.search = '?id=component-one--a&args=foo:url'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.storyStore.args.get('component-one--a')).toEqual({ @@ -142,7 +142,7 @@ describe('WebPreview', () => { it('selects the story specified in the URL', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.urlStore.selection).toEqual({ @@ -159,7 +159,7 @@ describe('WebPreview', () => { it('emits the STORY_SPECIFIED event', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_SPECIFIED, { storyId: 'component-one--a', @@ -170,7 +170,7 @@ describe('WebPreview', () => { it('emits the CURRENT_STORY_WAS_SET event', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.CURRENT_STORY_WAS_SET, { storyId: 'component-one--a', @@ -182,7 +182,7 @@ describe('WebPreview', () => { it('renders missing', async () => { document.location.search = '?id=random'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -193,7 +193,7 @@ describe('WebPreview', () => { it.skip('tries again with a specifier if CSF file changes', async () => { document.location.search = '?id=component-one--d'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -220,7 +220,7 @@ describe('WebPreview', () => { it.skip('DOES NOT try again if CSF file changes if selection changed', async () => { document.location.search = '?id=component-one--d'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -250,7 +250,7 @@ describe('WebPreview', () => { it.skip('tries again with a specifier if stories list changes', async () => { document.location.search = '?id=component-three--d'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -265,7 +265,7 @@ describe('WebPreview', () => { }); it('renders missing if no selection', async () => { - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -276,7 +276,7 @@ describe('WebPreview', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.prepareForStory).toHaveBeenCalledWith( @@ -288,7 +288,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_PREPARED, { id: 'component-one--a', @@ -301,7 +301,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -318,11 +318,11 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -346,7 +346,7 @@ describe('WebPreview', () => { }); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -357,12 +357,12 @@ describe('WebPreview', () => { it('renders exception if renderToDOM throws', async () => { const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce(() => { + projectAnnotations.renderToDOM.mockImplementationOnce(() => { throw error; }); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -378,7 +378,7 @@ describe('WebPreview', () => { }); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -389,10 +389,12 @@ describe('WebPreview', () => { it('renders error if the story calls showError', async () => { const error = { title: 'title', description: 'description' }; - globalAnnotations.renderToDOM.mockImplementationOnce((context) => context.showError(error)); + projectAnnotations.renderToDOM.mockImplementationOnce((context) => + context.showError(error) + ); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -406,12 +408,12 @@ describe('WebPreview', () => { it('renders exception if the story calls showException', async () => { const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce((context) => + projectAnnotations.renderToDOM.mockImplementationOnce((context) => context.showException(error) ); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -422,7 +424,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -431,7 +433,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -443,7 +445,7 @@ describe('WebPreview', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.prepareForDocs).toHaveBeenCalled(); @@ -452,7 +454,7 @@ describe('WebPreview', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -475,7 +477,7 @@ describe('WebPreview', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -487,7 +489,7 @@ describe('WebPreview', () => { describe('onUpdateGlobals', () => { it('emits GLOBALS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -499,7 +501,7 @@ describe('WebPreview', () => { it('sets new globals on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -509,16 +511,16 @@ describe('WebPreview', () => { it('passes new globals in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: false, storyContext: expect.objectContaining({ @@ -531,7 +533,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -545,7 +547,7 @@ describe('WebPreview', () => { describe('onUpdateArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -560,7 +562,7 @@ describe('WebPreview', () => { it('sets new args on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { @@ -576,19 +578,19 @@ describe('WebPreview', () => { it('passes new args in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: false, storyContext: expect.objectContaining({ @@ -602,7 +604,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -621,7 +623,7 @@ describe('WebPreview', () => { document.location.search = '?id=component-one--a'; componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -633,8 +635,8 @@ describe('WebPreview', () => { await waitForRender(); // Story gets rendered with updated args - expect(globalAnnotations.renderToDOM).toHaveBeenCalledTimes(1); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(1); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -650,8 +652,8 @@ describe('WebPreview', () => { const [gate, openGate] = createGate(); document.location.search = '?id=component-one--a'; - globalAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -663,9 +665,9 @@ describe('WebPreview', () => { openGate(); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledTimes(1); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(1); // renderToDOM call happens with original args, does not get retried. - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -682,17 +684,17 @@ describe('WebPreview', () => { componentOneExports.a.play.mockImplementationOnce(async () => gate); const renderToDOMCalled = new Promise((resolve) => { - globalAnnotations.renderToDOM.mockImplementationOnce(() => { + projectAnnotations.renderToDOM.mockImplementationOnce(() => { resolve(null); }); }); document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await renderToDOMCalled; // Story gets rendered with original args - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -713,7 +715,7 @@ describe('WebPreview', () => { await waitForRender(); // Story gets rendered with updated args - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: false, storyContext: expect.objectContaining({ @@ -733,7 +735,7 @@ describe('WebPreview', () => { describe('onResetArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -761,7 +763,7 @@ describe('WebPreview', () => { it('resets a single arg', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -776,7 +778,7 @@ describe('WebPreview', () => { await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: false, storyContext: expect.objectContaining({ @@ -795,7 +797,7 @@ describe('WebPreview', () => { it('resets all args', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, @@ -808,7 +810,7 @@ describe('WebPreview', () => { await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: false, storyContext: expect.objectContaining({ @@ -828,16 +830,16 @@ describe('WebPreview', () => { describe('on FORCE_RE_RENDER', () => { it('rerenders the story with the same args', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.FORCE_RE_RENDER); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: false }), undefined // this is coming from view.prepareForStory, not super important ); @@ -847,7 +849,7 @@ describe('WebPreview', () => { describe('onSetCurrentStory', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -863,7 +865,7 @@ describe('WebPreview', () => { it('emits CURRENT_STORY_WAS_SET', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -878,7 +880,7 @@ describe('WebPreview', () => { it('renders missing if the story specified does not exist', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.SET_CURRENT_STORY, { @@ -894,7 +896,7 @@ describe('WebPreview', () => { describe('if the selection is unchanged', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.SET_CURRENT_STORY, { @@ -908,10 +910,10 @@ describe('WebPreview', () => { it('does NOT call renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -920,14 +922,14 @@ describe('WebPreview', () => { // The renderToDOM would have been async so we need to wait a tick. await waitForQuiescence(); - expect(globalAnnotations.renderToDOM).not.toHaveBeenCalled(); + expect(projectAnnotations.renderToDOM).not.toHaveBeenCalled(); }); }); describe('when changing story in story viewMode', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -943,7 +945,7 @@ describe('WebPreview', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -958,7 +960,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -979,7 +981,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1002,7 +1004,7 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1012,7 +1014,7 @@ describe('WebPreview', () => { }); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -1031,12 +1033,12 @@ describe('WebPreview', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce(() => { + projectAnnotations.renderToDOM.mockImplementationOnce(() => { throw error; }); @@ -1053,12 +1055,14 @@ describe('WebPreview', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); const error = { title: 'title', description: 'description' }; - globalAnnotations.renderToDOM.mockImplementationOnce((context) => context.showError(error)); + projectAnnotations.renderToDOM.mockImplementationOnce((context) => + context.showError(error) + ); mockChannel.emit.mockClear(); emitter.emit(Events.SET_CURRENT_STORY, { @@ -1076,12 +1080,12 @@ describe('WebPreview', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce((context) => + projectAnnotations.renderToDOM.mockImplementationOnce((context) => context.showException(error) ); @@ -1098,7 +1102,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1113,7 +1117,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1128,7 +1132,7 @@ describe('WebPreview', () => { it('retains any arg changes', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1169,7 +1173,7 @@ describe('WebPreview', () => { componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1182,8 +1186,8 @@ describe('WebPreview', () => { await waitForRender(); // Story gets rendered with updated args - expect(globalAnnotations.renderToDOM).toHaveBeenCalledTimes(1); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(1); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -1199,8 +1203,8 @@ describe('WebPreview', () => { const [gate, openGate] = createGate(); document.location.search = '?id=component-one--a'; - globalAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1211,7 +1215,7 @@ describe('WebPreview', () => { // Now let the renderToDOM call resolve openGate(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledTimes(2); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(2); expect(componentOneExports.a.play).not.toHaveBeenCalled(); expect(componentOneExports.b.play).toHaveBeenCalled(); @@ -1227,17 +1231,17 @@ describe('WebPreview', () => { componentOneExports.a.play.mockImplementationOnce(async () => gate); const renderToDOMCalled = new Promise((resolve) => { - globalAnnotations.renderToDOM.mockImplementationOnce(() => { + projectAnnotations.renderToDOM.mockImplementationOnce(() => { resolve(null); }); }); document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await renderToDOMCalled; // Story gets rendered with original args - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -1255,7 +1259,7 @@ describe('WebPreview', () => { await waitForRender(); // New story gets rendered, (play function is still running) - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -1282,7 +1286,7 @@ describe('WebPreview', () => { describe('when changing from story viewMode to docs', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1298,7 +1302,7 @@ describe('WebPreview', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1313,7 +1317,7 @@ describe('WebPreview', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1329,7 +1333,7 @@ describe('WebPreview', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1357,7 +1361,7 @@ describe('WebPreview', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1374,7 +1378,7 @@ describe('WebPreview', () => { describe('when changing from docs viewMode to story', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1390,7 +1394,7 @@ describe('WebPreview', () => { it('unmounts docs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1406,7 +1410,7 @@ describe('WebPreview', () => { // NOTE: I am not sure this entirely makes sense but this is the behaviour from 6.3 it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1421,7 +1425,7 @@ describe('WebPreview', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1441,7 +1445,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1462,7 +1466,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1485,7 +1489,7 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1495,7 +1499,7 @@ describe('WebPreview', () => { }); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -1514,12 +1518,12 @@ describe('WebPreview', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce(() => { + projectAnnotations.renderToDOM.mockImplementationOnce(() => { throw error; }); @@ -1536,10 +1540,12 @@ describe('WebPreview', () => { it('renders error if the story calls showError', async () => { const error = { title: 'title', description: 'description' }; - globalAnnotations.renderToDOM.mockImplementationOnce((context) => context.showError(error)); + projectAnnotations.renderToDOM.mockImplementationOnce((context) => + context.showError(error) + ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1559,12 +1565,12 @@ describe('WebPreview', () => { it('renders exception if the story calls showException', async () => { const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce((context) => + projectAnnotations.renderToDOM.mockImplementationOnce((context) => context.showException(error) ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1581,7 +1587,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1596,7 +1602,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }).initialize(); + await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1624,7 +1630,7 @@ describe('WebPreview', () => { it('does not emit STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1640,7 +1646,7 @@ describe('WebPreview', () => { it('does not emit STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1653,7 +1659,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED with new annotations', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1672,7 +1678,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1694,16 +1700,16 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); preview.onImportFnChanged({ importFn: newImportFn }); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -1722,7 +1728,7 @@ describe('WebPreview', () => { it('retains the same delta to the args', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1733,11 +1739,11 @@ describe('WebPreview', () => { await waitForRender(); mockChannel.emit.mockClear(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); preview.onImportFnChanged({ importFn: newImportFn }); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, storyContext: expect.objectContaining({ @@ -1751,12 +1757,12 @@ describe('WebPreview', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce(() => { + projectAnnotations.renderToDOM.mockImplementationOnce(() => { throw error; }); @@ -1770,12 +1776,14 @@ describe('WebPreview', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); const error = { title: 'title', description: 'description' }; - globalAnnotations.renderToDOM.mockImplementationOnce((context) => context.showError(error)); + projectAnnotations.renderToDOM.mockImplementationOnce((context) => + context.showError(error) + ); mockChannel.emit.mockClear(); preview.onImportFnChanged({ importFn: newImportFn }); @@ -1790,12 +1798,12 @@ describe('WebPreview', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); const error = new Error('error'); - globalAnnotations.renderToDOM.mockImplementationOnce((context) => + projectAnnotations.renderToDOM.mockImplementationOnce((context) => context.showException(error) ); @@ -1809,7 +1817,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1823,7 +1831,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1845,7 +1853,7 @@ describe('WebPreview', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1859,16 +1867,16 @@ describe('WebPreview', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); preview.onImportFnChanged({ importFn: newImportFn }); await waitForQuiescence(); - expect(globalAnnotations.renderToDOM).not.toHaveBeenCalled(); + expect(projectAnnotations.renderToDOM).not.toHaveBeenCalled(); expect(mockChannel.emit).not.toHaveBeenCalledWith( Events.STORY_RENDERED, 'component-one--a' @@ -1886,7 +1894,7 @@ describe('WebPreview', () => { it('renders story missing', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1900,16 +1908,16 @@ describe('WebPreview', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); preview.onImportFnChanged({ importFn: newImportFn }); await waitForQuiescence(); - expect(globalAnnotations.renderToDOM).not.toHaveBeenCalled(); + expect(projectAnnotations.renderToDOM).not.toHaveBeenCalled(); expect(mockChannel.emit).not.toHaveBeenCalledWith( Events.STORY_RENDERED, 'component-one--a' @@ -1918,17 +1926,17 @@ describe('WebPreview', () => { }); }); - describe('onGetGlobalAnnotationsChanged', () => { + describe('onGetProjectAnnotationsChanged', () => { it('shows an error the new value throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); const err = new Error('error getting meta'); - preview.onGetGlobalAnnotationsChanged({ - getGlobalAnnotations: () => { + preview.onGetProjectAnnotationsChanged({ + getProjectAnnotations: () => { throw err; }, }); @@ -1940,7 +1948,7 @@ describe('WebPreview', () => { const newGlobalDecorator = jest.fn((s) => s()); const newGetGlobalMeta = () => { return { - ...globalAnnotations, + ...projectAnnotations, args: { global: 'added' }, globals: { a: 'edited' }, decorators: [newGlobalDecorator], @@ -1949,12 +1957,12 @@ describe('WebPreview', () => { it('updates globals to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations: newGetGlobalMeta }); + preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetGlobalMeta }); await waitForRender(); expect(preview.storyStore.globals.get()).toEqual({ a: 'edited' }); @@ -1962,12 +1970,12 @@ describe('WebPreview', () => { it('updates args to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); - preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations: newGetGlobalMeta }); + preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetGlobalMeta }); await waitForRender(); @@ -1979,16 +1987,16 @@ describe('WebPreview', () => { it('rerenders the current story with new global meta-generated context', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); - globalAnnotations.renderToDOM.mockClear(); + projectAnnotations.renderToDOM.mockClear(); mockChannel.emit.mockClear(); - preview.onGetGlobalAnnotationsChanged({ getGlobalAnnotations: newGetGlobalMeta }); + preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetGlobalMeta }); await waitForRender(); - expect(globalAnnotations.renderToDOM).toHaveBeenCalledWith( + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ storyContext: expect.objectContaining({ args: { foo: 'a', global: 'added' }, @@ -2003,7 +2011,7 @@ describe('WebPreview', () => { describe('onKeydown', () => { it('emits PREVIEW_KEYDOWN for regular elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); preview.onKeydown({ @@ -2018,7 +2026,7 @@ describe('WebPreview', () => { it('does not emit PREVIEW_KEYDOWN for input elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getGlobalAnnotations, importFn, fetchStoriesList }); + const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); preview.onKeydown({ diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/web-preview/src/WebPreview.tsx index 0e212bd50ac..f556419425d 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/web-preview/src/WebPreview.tsx @@ -7,7 +7,7 @@ import { addons, Channel } from '@storybook/addons'; import { AnyFramework, StoryId, - GlobalAnnotations, + ProjectAnnotations, Args, Globals, ViewMode, @@ -24,7 +24,7 @@ import { StoriesList, } from '@storybook/store'; -import { WebGlobalAnnotations, DocsContextProps } from './types'; +import { WebProjectAnnotations, DocsContextProps } from './types'; import { UrlStore } from './UrlStore'; import { WebView } from './WebView'; @@ -48,7 +48,7 @@ export class WebPreview { view: WebView; - renderToDOM: WebGlobalAnnotations['renderToDOM']; + renderToDOM: WebProjectAnnotations['renderToDOM']; previousSelection: Selection; @@ -57,37 +57,37 @@ export class WebPreview { previousCleanup: () => void; constructor({ - getGlobalAnnotations, + getProjectAnnotations, importFn, fetchStoriesList, }: { - getGlobalAnnotations: () => WebGlobalAnnotations; + getProjectAnnotations: () => WebProjectAnnotations; importFn: ModuleImportFn; fetchStoriesList: ConstructorParameters[0]['fetchStoriesList']; }) { this.channel = addons.getChannel(); this.view = new WebView(); - const globalAnnotations = this.getGlobalAnnotationsOrRenderError(getGlobalAnnotations); - if (!globalAnnotations) { + const projectAnnotations = this.getProjectAnnotationsOrRenderError(getProjectAnnotations); + if (!projectAnnotations) { return; } this.urlStore = new UrlStore(); - this.storyStore = new StoryStore({ importFn, globalAnnotations, fetchStoriesList }); + this.storyStore = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); } - getGlobalAnnotationsOrRenderError( - getGlobalAnnotations: () => WebGlobalAnnotations - ): GlobalAnnotations | undefined { - let globalAnnotations; + getProjectAnnotationsOrRenderError( + getProjectAnnotations: () => WebProjectAnnotations + ): ProjectAnnotations | undefined { + let projectAnnotations; try { - globalAnnotations = getGlobalAnnotations(); - this.renderToDOM = globalAnnotations.renderToDOM; - return globalAnnotations; + projectAnnotations = getProjectAnnotations(); + this.renderToDOM = projectAnnotations.renderToDOM; + return projectAnnotations; } catch (err) { logger.warn(err); - // This is an error extracting the globalAnnotations (i.e. evaluating the previewEntries) and + // This is an error extracting the projectAnnotations (i.e. evaluating the previewEntries) and // needs to be show to the user as a simple error this.renderPreviewEntryError(err); return undefined; @@ -114,7 +114,7 @@ export class WebPreview { } this.channel.emit(Events.SET_GLOBALS, { globals: this.storyStore.globals.get() || {}, - globalTypes: this.storyStore.globalAnnotations.globalTypes || {}, + globalTypes: this.storyStore.projectAnnotations.globalTypes || {}, }); await this.selectSpecifiedStory(); @@ -224,17 +224,17 @@ export class WebPreview { } // This happens when a config file gets reloade - onGetGlobalAnnotationsChanged({ - getGlobalAnnotations, + onGetProjectAnnotationsChanged({ + getProjectAnnotations, }: { - getGlobalAnnotations: () => GlobalAnnotations; + getProjectAnnotations: () => ProjectAnnotations; }) { - const globalAnnotations = this.getGlobalAnnotationsOrRenderError(getGlobalAnnotations); - if (!globalAnnotations) { + const projectAnnotations = this.getProjectAnnotationsOrRenderError(getProjectAnnotations); + if (!projectAnnotations) { return; } - this.storyStore.updateGlobalAnnotations(globalAnnotations); + this.storyStore.updateProjectAnnotations(projectAnnotations); this.renderSelection(); } diff --git a/lib/web-preview/src/composeConfigs.ts b/lib/web-preview/src/composeConfigs.ts index 0ceb7751e7a..f03de9b10ed 100644 --- a/lib/web-preview/src/composeConfigs.ts +++ b/lib/web-preview/src/composeConfigs.ts @@ -1,6 +1,6 @@ import { AnyFramework } from '@storybook/csf'; import { combineParameters, ModuleExports } from '@storybook/store'; -import { WebGlobalAnnotations } from './types'; +import { WebProjectAnnotations } from './types'; function getField(moduleExportList: ModuleExports[], field: string): any[] { return moduleExportList.map((xs) => xs[field]).filter(Boolean); @@ -20,7 +20,7 @@ function getSingletonField(moduleExportList: ModuleExports[], field: string): an export function composeConfigs( moduleExportList: ModuleExports[] -): WebGlobalAnnotations { +): WebProjectAnnotations { const allArgTypeEnhancers = getArrayField(moduleExportList, 'argTypesEnhancers'); return { diff --git a/lib/web-preview/src/types.ts b/lib/web-preview/src/types.ts index d96f5242ae3..535e0ee513a 100644 --- a/lib/web-preview/src/types.ts +++ b/lib/web-preview/src/types.ts @@ -1,10 +1,10 @@ -import { StoryId, AnyFramework, GlobalAnnotations, StoryContextForLoaders } from '@storybook/csf'; +import { StoryId, AnyFramework, ProjectAnnotations, StoryContextForLoaders } from '@storybook/csf'; import { RenderContext, DecoratorApplicator, Story } from '@storybook/store'; import { WebPreview } from './WebPreview'; -export type WebGlobalAnnotations< +export type WebProjectAnnotations< TFramework extends AnyFramework -> = GlobalAnnotations & { +> = ProjectAnnotations & { renderToDOM?: (context: RenderContext, element: Element) => Promise | void; }; From 1fa95a007bf2677309c8d2e2bb8a8057885b4851 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 14:41:20 +1000 Subject: [PATCH 199/285] Rename `WebPreview` to `PreviewWeb` --- addons/docs/package.json | 2 +- addons/docs/src/blocks/DocsContext.ts | 2 +- app/html/package.json | 2 +- app/html/src/client/preview/render.ts | 2 +- app/server/package.json | 2 +- app/server/src/client/preview/render.ts | 2 +- app/web-components/package.json | 2 +- .../src/client/preview/render.ts | 2 +- .../web-components-kitchen-sink/package.json | 2 +- lib/builder-webpack4/package.json | 2 +- .../src/preview/iframe-webpack.config.ts | 2 +- .../virtualModuleModernEntry.js.handlebars | 4 +- .../virtualModuleModernEntry.js.handlebars | 4 +- lib/core-client/package.json | 2 +- lib/core-client/src/preview/start.test.ts | 6 +- lib/core-client/src/preview/start.ts | 8 +- lib/core-client/typings.d.ts | 2 +- .../src/__snapshots__/vue-3-cli_preview-dev | 2 +- .../src/__snapshots__/vue-3-cli_preview-prod | 2 +- lib/{web-preview => preview-web}/README.md | 0 lib/{web-preview => preview-web}/package.json | 6 +- .../src/NoDocs.tsx | 0 .../src/PreviewWeb.integration.test.ts} | 14 +- .../src/PreviewWeb.mockdata.ts} | 0 .../src/PreviewWeb.test.ts} | 206 +++++++++--------- .../src/PreviewWeb.tsx} | 2 +- .../src/UrlStore.test.ts | 0 .../src/UrlStore.ts | 0 .../src/WebView.ts | 0 .../src/composeConfigs.test.ts | 0 .../src/composeConfigs.ts | 0 lib/{web-preview => preview-web}/src/index.ts | 2 +- .../src/parseArgsParam.test.ts | 0 .../src/parseArgsParam.ts | 0 .../src/simulate-pageload.ts | 0 lib/{web-preview => preview-web}/src/types.ts | 4 +- .../src/typings.d.ts | 0 .../tsconfig.json | 0 nx.json | 2 +- package.json | 2 +- workspace.json | 4 +- yarn.lock | 18 +- 42 files changed, 156 insertions(+), 156 deletions(-) rename lib/{web-preview => preview-web}/README.md (100%) rename lib/{web-preview => preview-web}/package.json (94%) rename lib/{web-preview => preview-web}/src/NoDocs.tsx (100%) rename lib/{web-preview/src/WebPreview.integration.test.ts => preview-web/src/PreviewWeb.integration.test.ts} (91%) rename lib/{web-preview/src/WebPreview.mockdata.ts => preview-web/src/PreviewWeb.mockdata.ts} (100%) rename lib/{web-preview/src/WebPreview.test.ts => preview-web/src/PreviewWeb.test.ts} (91%) rename lib/{web-preview/src/WebPreview.tsx => preview-web/src/PreviewWeb.tsx} (99%) rename lib/{web-preview => preview-web}/src/UrlStore.test.ts (100%) rename lib/{web-preview => preview-web}/src/UrlStore.ts (100%) rename lib/{web-preview => preview-web}/src/WebView.ts (100%) rename lib/{web-preview => preview-web}/src/composeConfigs.test.ts (100%) rename lib/{web-preview => preview-web}/src/composeConfigs.ts (100%) rename lib/{web-preview => preview-web}/src/index.ts (78%) rename lib/{web-preview => preview-web}/src/parseArgsParam.test.ts (100%) rename lib/{web-preview => preview-web}/src/parseArgsParam.ts (100%) rename lib/{web-preview => preview-web}/src/simulate-pageload.ts (100%) rename lib/{web-preview => preview-web}/src/types.ts (90%) rename lib/{web-preview => preview-web}/src/typings.d.ts (100%) rename lib/{web-preview => preview-web}/tsconfig.json (100%) diff --git a/addons/docs/package.json b/addons/docs/package.json index 22e76a99a00..7d1464c897a 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -75,10 +75,10 @@ "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/postinstall": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/source-loader": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", - "@storybook/web-preview": "6.4.0-alpha.19", "acorn": "^7.4.1", "acorn-jsx": "^5.3.1", "acorn-walk": "^7.2.0", diff --git a/addons/docs/src/blocks/DocsContext.ts b/addons/docs/src/blocks/DocsContext.ts index f9963f53bb7..3fada361a32 100644 --- a/addons/docs/src/blocks/DocsContext.ts +++ b/addons/docs/src/blocks/DocsContext.ts @@ -1,7 +1,7 @@ import { Context, createContext } from 'react'; import { window as globalWindow } from 'global'; -import { DocsContextProps } from '@storybook/web-preview'; +import { DocsContextProps } from '@storybook/preview-web'; import { AnyFramework } from '@storybook/csf'; export type { DocsContextProps }; diff --git a/app/html/package.json b/app/html/package.json index a8f4c4c568e..f37ccc36647 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -50,8 +50,8 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", - "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/html/src/client/preview/render.ts b/app/html/src/client/preview/render.ts index a073bf8912d..411a745a0dd 100644 --- a/app/html/src/client/preview/render.ts +++ b/app/html/src/client/preview/render.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import global from 'global'; import dedent from 'ts-dedent'; -import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; +import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/preview-web'; import { RenderContext } from '@storybook/store'; import { HtmlFramework } from './types-6-0'; diff --git a/app/server/package.json b/app/server/package.json index 1aea35a9750..6a93519e620 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -52,8 +52,8 @@ "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.d61cd6c.0", "@storybook/node-logger": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", - "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/server/src/client/preview/render.ts b/app/server/src/client/preview/render.ts index 4420c9bc91b..f7a0b62df15 100644 --- a/app/server/src/client/preview/render.ts +++ b/app/server/src/client/preview/render.ts @@ -3,7 +3,7 @@ import global from 'global'; import dedent from 'ts-dedent'; import { Args, ArgTypes } from '@storybook/api'; import { RenderContext } from '@storybook/store'; -import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; +import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/preview-web'; import { FetchStoryHtmlType, ServerFramework } from './types'; const { fetch, Node } = global; diff --git a/app/web-components/package.json b/app/web-components/package.json index 64558c0f2a7..879e91de2ca 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -55,8 +55,8 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", - "@storybook/web-preview": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "babel-plugin-bundled-import-meta": "^0.3.1", "core-js": "^3.8.2", diff --git a/app/web-components/src/client/preview/render.ts b/app/web-components/src/client/preview/render.ts index 22eac448b3b..1ee5b263792 100644 --- a/app/web-components/src/client/preview/render.ts +++ b/app/web-components/src/client/preview/render.ts @@ -5,7 +5,7 @@ import { render, TemplateResult } from 'lit-html'; // Keep `.js` extension to avoid issue with Webpack (related to export map?) // eslint-disable-next-line import/extensions import { isTemplateResult } from 'lit-html/directive-helpers.js'; -import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/web-preview'; +import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/preview-web'; import { RenderContext } from '@storybook/store'; import { WebComponentsFramework } from './types-6-0'; diff --git a/examples/web-components-kitchen-sink/package.json b/examples/web-components-kitchen-sink/package.json index 483d0025d53..88dca924197 100644 --- a/examples/web-components-kitchen-sink/package.json +++ b/examples/web-components-kitchen-sink/package.json @@ -44,13 +44,13 @@ "@storybook/manager-webpack5": "portal:../../lib/manager-webpack5", "@storybook/node-logger": "portal:../../lib/node-logger", "@storybook/postinstall": "portal:../../lib/postinstall", + "@storybook/preview-web": "portal:../../lib/preview-web", "@storybook/router": "portal:../../lib/router", "@storybook/source-loader": "portal:../../lib/source-loader", "@storybook/store": "portal:../../lib/store", "@storybook/theming": "portal:../../lib/theming", "@storybook/ui": "portal:../../lib/ui", "@storybook/web-components": "portal:../../app/web-components", - "@storybook/web-preview": "portal:../../lib/web-preview", "typescript": "4.2.4" }, "dependencies": { diff --git a/lib/builder-webpack4/package.json b/lib/builder-webpack4/package.json index a6cd8caca46..aac93ef111b 100644 --- a/lib/builder-webpack4/package.json +++ b/lib/builder-webpack4/package.json @@ -71,12 +71,12 @@ "@storybook/core-common": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/router": "6.4.0-alpha.19", "@storybook/semver": "^7.3.2", "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "@storybook/ui": "6.4.0-alpha.19", - "@storybook/web-preview": "6.4.0-alpha.19", "@types/node": "^14.0.10", "@types/webpack": "^4.41.26", "autoprefixer": "^9.8.6", diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index 49871c8e115..5e6eba80088 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -44,7 +44,7 @@ const storybookPaths: Record = [ 'semver', 'client-api', 'client-logger', - 'web-preview', + 'preview-web', 'store', ].reduce( (acc, sbPackage) => ({ diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index e24c395043e..a0f9c4779f6 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -1,4 +1,4 @@ -import { composeConfigs, WebPreview } from '@storybook/web-preview'; +import { composeConfigs, PreviewWeb } from '@storybook/preview-web'; import { importFn } from './{{storiesFilename}}'; import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; @@ -19,7 +19,7 @@ const fetchStoriesList = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new WebPreview({ importFn, getProjectAnnotations, fetchStoriesList }); +const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoriesList }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; diff --git a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars index cee6e249d1b..2688f38cc2c 100644 --- a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars @@ -1,4 +1,4 @@ -import { composeConfigs, WebPreview } from '@storybook/web-preview'; +import { composeConfigs, PreviewWeb } from '@storybook/preview-web'; import { importFn } from './{{storiesFilename}}'; import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; @@ -18,7 +18,7 @@ const fetchStoriesList = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new WebPreview({ importFn, getProjectAnnotations, fetchStoriesList }); +const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoriesList }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; diff --git a/lib/core-client/package.json b/lib/core-client/package.json index dc3abb5fa15..c89bfe6eadd 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -46,9 +46,9 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/ui": "6.4.0-alpha.19", - "@storybook/web-preview": "6.4.0-alpha.19", "airbnb-js-shims": "^2.2.1", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index fc847b7b152..bdc03b531e8 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -5,12 +5,12 @@ import { waitForEvents, emitter, mockChannel, -} from '@storybook/web-preview/dist/cjs/WebPreview.mockdata'; + // eslint-disable-next-line import/extensions +} from '@storybook/preview-web/dist/cjs/PreviewWeb.mockdata'; -import { AnyFramework } from '@storybook/csf'; import { start } from './start'; -jest.mock('@storybook/web-preview/dist/cjs/WebView'); +jest.mock('@storybook/preview-web/dist/cjs/WebView'); jest.mock('global', () => ({ // @ts-ignore diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index c317c61a61d..71e382cb889 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -1,6 +1,6 @@ import global from 'global'; import { ClientApi } from '@storybook/client-api'; -import { WebProjectAnnotations, WebPreview } from '@storybook/web-preview'; +import { WebProjectAnnotations, PreviewWeb } from '@storybook/preview-web'; import { AnyFramework, ArgsStoryFn } from '@storybook/csf'; import createChannel from '@storybook/channel-postmessage'; import { addons } from '@storybook/addons'; @@ -25,7 +25,7 @@ export function start( const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); - let preview: WebPreview; + let preview: PreviewWeb; const clientApi = new ClientApi(); if (globalWindow) { @@ -66,7 +66,7 @@ export function start( }; if (!preview) { - preview = new WebPreview({ + preview = new PreviewWeb({ importFn: (path: Path) => clientApi.importFn(path), getProjectAnnotations, fetchStoriesList: () => clientApi.getStoriesList(), @@ -78,7 +78,7 @@ export function start( } // These two bits are a bit ugly, but due to dependencies, `ClientApi` cannot have - // direct reference to `WebPreview`, so we need to patch in bits + // direct reference to `PreviewWeb`, so we need to patch in bits clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); clientApi.storyStore = preview.storyStore; diff --git a/lib/core-client/typings.d.ts b/lib/core-client/typings.d.ts index 93d506c6280..87e788474ea 100644 --- a/lib/core-client/typings.d.ts +++ b/lib/core-client/typings.d.ts @@ -1,5 +1,5 @@ declare module 'ansi-to-html'; -declare module '@storybook/web-preview/dist/cjs/WebPreview.mockdata'; +declare module '@storybook/preview-web/dist/cjs/PreviewWeb.mockdata'; declare class AnsiToHtml { constructor(options: { escapeHtml: boolean }); diff --git a/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev b/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev index 5748f5ccd53..5b8fea9b902 100644 --- a/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev +++ b/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev @@ -478,7 +478,7 @@ Object { "@storybook/semver": "NODE_MODULES/@storybook/semver", "@storybook/store": "ROOT/lib/store", "@storybook/theming": "ROOT/lib/theming", - "@storybook/web-preview": "ROOT/lib/web-preview", + "@storybook/preview-web": "ROOT/lib/preview-web", "emotion-theming": "NODE_MODULES/emotion-theming", "react": "NODE_MODULES/react", "react-dom": "NODE_MODULES/react-dom", diff --git a/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod b/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod index a8c10ba1f30..1df083b1076 100644 --- a/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod +++ b/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod @@ -477,7 +477,7 @@ Object { "@storybook/semver": "NODE_MODULES/@storybook/semver", "@storybook/store": "ROOT/lib/store", "@storybook/theming": "ROOT/lib/theming", - "@storybook/web-preview": "ROOT/lib/web-preview", + "@storybook/preview-web": "ROOT/lib/preview-web", "emotion-theming": "NODE_MODULES/emotion-theming", "react": "NODE_MODULES/react", "react-dom": "NODE_MODULES/react-dom", diff --git a/lib/web-preview/README.md b/lib/preview-web/README.md similarity index 100% rename from lib/web-preview/README.md rename to lib/preview-web/README.md diff --git a/lib/web-preview/package.json b/lib/preview-web/package.json similarity index 94% rename from lib/web-preview/package.json rename to lib/preview-web/package.json index c542ec3355e..339812745ca 100644 --- a/lib/web-preview/package.json +++ b/lib/preview-web/package.json @@ -1,18 +1,18 @@ { - "name": "@storybook/web-preview", + "name": "@storybook/preview-web", "version": "6.4.0-alpha.19", "description": "", "keywords": [ "storybook" ], - "homepage": "https://github.com/storybookjs/storybook/tree/main/lib/web-preview", + "homepage": "https://github.com/storybookjs/storybook/tree/main/lib/preview-web", "bugs": { "url": "https://github.com/storybookjs/storybook/issues" }, "repository": { "type": "git", "url": "https://github.com/storybookjs/storybook.git", - "directory": "lib/web-preview" + "directory": "lib/preview-web" }, "funding": { "type": "opencollective", diff --git a/lib/web-preview/src/NoDocs.tsx b/lib/preview-web/src/NoDocs.tsx similarity index 100% rename from lib/web-preview/src/NoDocs.tsx rename to lib/preview-web/src/NoDocs.tsx diff --git a/lib/web-preview/src/WebPreview.integration.test.ts b/lib/preview-web/src/PreviewWeb.integration.test.ts similarity index 91% rename from lib/web-preview/src/WebPreview.integration.test.ts rename to lib/preview-web/src/PreviewWeb.integration.test.ts index 155bf1130c7..4b18d6e9fb8 100644 --- a/lib/web-preview/src/WebPreview.integration.test.ts +++ b/lib/preview-web/src/PreviewWeb.integration.test.ts @@ -3,7 +3,7 @@ import global from 'global'; import { RenderContext } from '@storybook/store'; import addons from '@storybook/addons'; -import { WebPreview } from './WebPreview'; +import { PreviewWeb } from './PreviewWeb'; import { componentOneExports, importFn, @@ -13,9 +13,9 @@ import { emitter, mockChannel, waitForRender, -} from './WebPreview.mockdata'; +} from './PreviewWeb.mockdata'; -// WebPreview.test mocks out all rendering +// PreviewWeb.test mocks out all rendering // - ie. from`renderToDOM()` (stories) or`ReactDOM.render()` (docs) in. // This file lets them rip. @@ -54,14 +54,14 @@ beforeEach(() => { addons.setChannel(mockChannel as any); }); -describe('WebPreview', () => { +describe('PreviewWeb', () => { describe('initial render', () => { it('renders story mode through the stack', async () => { projectAnnotations.renderToDOM.mockImplementationOnce(({ storyFn }: RenderContext) => storyFn() ); document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -71,7 +71,7 @@ describe('WebPreview', () => { it('renders docs mode through docs page', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); const docsRoot = window.document.createElement('div'); // @ts-ignore @@ -106,7 +106,7 @@ describe('WebPreview', () => { it('renders story mode through the updated stack', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); diff --git a/lib/web-preview/src/WebPreview.mockdata.ts b/lib/preview-web/src/PreviewWeb.mockdata.ts similarity index 100% rename from lib/web-preview/src/WebPreview.mockdata.ts rename to lib/preview-web/src/PreviewWeb.mockdata.ts diff --git a/lib/web-preview/src/WebPreview.test.ts b/lib/preview-web/src/PreviewWeb.test.ts similarity index 91% rename from lib/web-preview/src/WebPreview.test.ts rename to lib/preview-web/src/PreviewWeb.test.ts index ce8dcfd85b2..ec717d837ba 100644 --- a/lib/web-preview/src/WebPreview.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -5,7 +5,7 @@ import { logger } from '@storybook/client-logger'; import merge from 'lodash/merge'; import addons from '@storybook/addons'; -import { WebPreview } from './WebPreview'; +import { PreviewWeb } from './PreviewWeb'; import { componentOneExports, componentTwoExports, @@ -18,7 +18,7 @@ import { waitForEvents, waitForRender, waitForQuiescence, -} from './WebPreview.mockdata'; +} from './PreviewWeb.mockdata'; jest.mock('./WebView'); const { history, document } = global; @@ -66,11 +66,11 @@ beforeEach(() => { addons.setChannel(mockChannel as any); }); -describe('WebPreview', () => { +describe('PreviewWeb', () => { describe('constructor', () => { it('shows an error if getProjectAnnotations throws', async () => { const err = new Error('meta error'); - const preview = new WebPreview({ + const preview = new PreviewWeb({ getProjectAnnotations: () => { throw err; }, @@ -87,14 +87,14 @@ describe('WebPreview', () => { it('sets globals from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.storyStore.globals.get()).toEqual({ a: 'c' }); }); it('emits the SET_GLOBALS event', async () => { - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'b' }, @@ -103,7 +103,7 @@ describe('WebPreview', () => { }); it('SET_GLOBALS sets globals and types even when undefined', async () => { - await new WebPreview({ + await new PreviewWeb({ getProjectAnnotations: () => ({}), importFn, fetchStoriesList, @@ -118,7 +118,7 @@ describe('WebPreview', () => { it('emits the SET_GLOBALS event from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'c' }, @@ -129,7 +129,7 @@ describe('WebPreview', () => { it('sets args from the URL', async () => { document.location.search = '?id=component-one--a&args=foo:url'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.storyStore.args.get('component-one--a')).toEqual({ @@ -142,7 +142,7 @@ describe('WebPreview', () => { it('selects the story specified in the URL', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.urlStore.selection).toEqual({ @@ -159,7 +159,7 @@ describe('WebPreview', () => { it('emits the STORY_SPECIFIED event', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_SPECIFIED, { storyId: 'component-one--a', @@ -170,7 +170,7 @@ describe('WebPreview', () => { it('emits the CURRENT_STORY_WAS_SET event', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.CURRENT_STORY_WAS_SET, { storyId: 'component-one--a', @@ -182,7 +182,7 @@ describe('WebPreview', () => { it('renders missing', async () => { document.location.search = '?id=random'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -193,7 +193,7 @@ describe('WebPreview', () => { it.skip('tries again with a specifier if CSF file changes', async () => { document.location.search = '?id=component-one--d'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -220,7 +220,7 @@ describe('WebPreview', () => { it.skip('DOES NOT try again if CSF file changes if selection changed', async () => { document.location.search = '?id=component-one--d'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -250,7 +250,7 @@ describe('WebPreview', () => { it.skip('tries again with a specifier if stories list changes', async () => { document.location.search = '?id=component-three--d'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -265,7 +265,7 @@ describe('WebPreview', () => { }); it('renders missing if no selection', async () => { - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -276,7 +276,7 @@ describe('WebPreview', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.prepareForStory).toHaveBeenCalledWith( @@ -288,7 +288,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_PREPARED, { id: 'component-one--a', @@ -301,7 +301,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -318,7 +318,7 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -346,7 +346,7 @@ describe('WebPreview', () => { }); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -362,7 +362,7 @@ describe('WebPreview', () => { }); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -378,7 +378,7 @@ describe('WebPreview', () => { }); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -394,7 +394,7 @@ describe('WebPreview', () => { ); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -413,7 +413,7 @@ describe('WebPreview', () => { ); document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -424,7 +424,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -433,7 +433,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -445,7 +445,7 @@ describe('WebPreview', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); expect(preview.view.prepareForDocs).toHaveBeenCalled(); @@ -454,7 +454,7 @@ describe('WebPreview', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -477,7 +477,7 @@ describe('WebPreview', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); @@ -489,7 +489,7 @@ describe('WebPreview', () => { describe('onUpdateGlobals', () => { it('emits GLOBALS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -501,7 +501,7 @@ describe('WebPreview', () => { it('sets new globals on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -511,7 +511,7 @@ describe('WebPreview', () => { it('passes new globals in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -533,7 +533,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -547,7 +547,7 @@ describe('WebPreview', () => { describe('onUpdateArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -562,7 +562,7 @@ describe('WebPreview', () => { it('sets new args on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { @@ -578,7 +578,7 @@ describe('WebPreview', () => { it('passes new args in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -604,7 +604,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -623,7 +623,7 @@ describe('WebPreview', () => { document.location.search = '?id=component-one--a'; componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -653,7 +653,7 @@ describe('WebPreview', () => { document.location.search = '?id=component-one--a'; projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -690,7 +690,7 @@ describe('WebPreview', () => { }); document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await renderToDOMCalled; // Story gets rendered with original args @@ -735,7 +735,7 @@ describe('WebPreview', () => { describe('onResetArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -763,7 +763,7 @@ describe('WebPreview', () => { it('resets a single arg', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -797,7 +797,7 @@ describe('WebPreview', () => { it('resets all args', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, @@ -830,7 +830,7 @@ describe('WebPreview', () => { describe('on FORCE_RE_RENDER', () => { it('rerenders the story with the same args', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -849,7 +849,7 @@ describe('WebPreview', () => { describe('onSetCurrentStory', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -865,7 +865,7 @@ describe('WebPreview', () => { it('emits CURRENT_STORY_WAS_SET', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -880,7 +880,7 @@ describe('WebPreview', () => { it('renders missing if the story specified does not exist', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.SET_CURRENT_STORY, { @@ -896,7 +896,7 @@ describe('WebPreview', () => { describe('if the selection is unchanged', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); emitter.emit(Events.SET_CURRENT_STORY, { @@ -910,7 +910,7 @@ describe('WebPreview', () => { it('does NOT call renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); projectAnnotations.renderToDOM.mockClear(); @@ -929,7 +929,7 @@ describe('WebPreview', () => { describe('when changing story in story viewMode', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -945,7 +945,7 @@ describe('WebPreview', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -960,7 +960,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -981,7 +981,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1004,7 +1004,7 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1033,7 +1033,7 @@ describe('WebPreview', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1055,7 +1055,7 @@ describe('WebPreview', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1080,7 +1080,7 @@ describe('WebPreview', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1102,7 +1102,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1117,7 +1117,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1132,7 +1132,7 @@ describe('WebPreview', () => { it('retains any arg changes', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1173,7 +1173,7 @@ describe('WebPreview', () => { componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1204,7 +1204,7 @@ describe('WebPreview', () => { document.location.search = '?id=component-one--a'; projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1237,7 +1237,7 @@ describe('WebPreview', () => { }); document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await renderToDOMCalled; // Story gets rendered with original args @@ -1286,7 +1286,7 @@ describe('WebPreview', () => { describe('when changing from story viewMode to docs', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1302,7 +1302,7 @@ describe('WebPreview', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1317,7 +1317,7 @@ describe('WebPreview', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1333,7 +1333,7 @@ describe('WebPreview', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1361,7 +1361,7 @@ describe('WebPreview', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1378,7 +1378,7 @@ describe('WebPreview', () => { describe('when changing from docs viewMode to story', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1394,7 +1394,7 @@ describe('WebPreview', () => { it('unmounts docs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1410,7 +1410,7 @@ describe('WebPreview', () => { // NOTE: I am not sure this entirely makes sense but this is the behaviour from 6.3 it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1425,7 +1425,7 @@ describe('WebPreview', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1445,7 +1445,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1466,7 +1466,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1489,7 +1489,7 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1518,7 +1518,7 @@ describe('WebPreview', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1545,7 +1545,7 @@ describe('WebPreview', () => { ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1570,7 +1570,7 @@ describe('WebPreview', () => { ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1587,7 +1587,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1602,7 +1602,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1630,7 +1630,7 @@ describe('WebPreview', () => { it('does not emit STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1646,7 +1646,7 @@ describe('WebPreview', () => { it('does not emit STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1659,7 +1659,7 @@ describe('WebPreview', () => { it('emits STORY_PREPARED with new annotations', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1678,7 +1678,7 @@ describe('WebPreview', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1700,7 +1700,7 @@ describe('WebPreview', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1728,7 +1728,7 @@ describe('WebPreview', () => { it('retains the same delta to the args', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1757,7 +1757,7 @@ describe('WebPreview', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1776,7 +1776,7 @@ describe('WebPreview', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1798,7 +1798,7 @@ describe('WebPreview', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1817,7 +1817,7 @@ describe('WebPreview', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1831,7 +1831,7 @@ describe('WebPreview', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1853,7 +1853,7 @@ describe('WebPreview', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1867,7 +1867,7 @@ describe('WebPreview', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1894,7 +1894,7 @@ describe('WebPreview', () => { it('renders story missing', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1908,7 +1908,7 @@ describe('WebPreview', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1929,7 +1929,7 @@ describe('WebPreview', () => { describe('onGetProjectAnnotationsChanged', () => { it('shows an error the new value throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1957,7 +1957,7 @@ describe('WebPreview', () => { it('updates globals to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1970,7 +1970,7 @@ describe('WebPreview', () => { it('updates args to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -1987,7 +1987,7 @@ describe('WebPreview', () => { it('rerenders the current story with new global meta-generated context', async () => { document.location.search = '?id=component-one--a'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); await waitForRender(); @@ -2011,7 +2011,7 @@ describe('WebPreview', () => { describe('onKeydown', () => { it('emits PREVIEW_KEYDOWN for regular elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); preview.onKeydown({ @@ -2026,7 +2026,7 @@ describe('WebPreview', () => { it('does not emit PREVIEW_KEYDOWN for input elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new WebPreview({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); await preview.initialize(); preview.onKeydown({ diff --git a/lib/web-preview/src/WebPreview.tsx b/lib/preview-web/src/PreviewWeb.tsx similarity index 99% rename from lib/web-preview/src/WebPreview.tsx rename to lib/preview-web/src/PreviewWeb.tsx index f556419425d..2f3fc504f89 100644 --- a/lib/web-preview/src/WebPreview.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -39,7 +39,7 @@ function focusInInput(event: Event) { type InitialRenderPhase = 'init' | 'loaded' | 'rendered' | 'done'; -export class WebPreview { +export class PreviewWeb { channel: Channel; urlStore: UrlStore; diff --git a/lib/web-preview/src/UrlStore.test.ts b/lib/preview-web/src/UrlStore.test.ts similarity index 100% rename from lib/web-preview/src/UrlStore.test.ts rename to lib/preview-web/src/UrlStore.test.ts diff --git a/lib/web-preview/src/UrlStore.ts b/lib/preview-web/src/UrlStore.ts similarity index 100% rename from lib/web-preview/src/UrlStore.ts rename to lib/preview-web/src/UrlStore.ts diff --git a/lib/web-preview/src/WebView.ts b/lib/preview-web/src/WebView.ts similarity index 100% rename from lib/web-preview/src/WebView.ts rename to lib/preview-web/src/WebView.ts diff --git a/lib/web-preview/src/composeConfigs.test.ts b/lib/preview-web/src/composeConfigs.test.ts similarity index 100% rename from lib/web-preview/src/composeConfigs.test.ts rename to lib/preview-web/src/composeConfigs.test.ts diff --git a/lib/web-preview/src/composeConfigs.ts b/lib/preview-web/src/composeConfigs.ts similarity index 100% rename from lib/web-preview/src/composeConfigs.ts rename to lib/preview-web/src/composeConfigs.ts diff --git a/lib/web-preview/src/index.ts b/lib/preview-web/src/index.ts similarity index 78% rename from lib/web-preview/src/index.ts rename to lib/preview-web/src/index.ts index 14be448affc..78f8cd58974 100644 --- a/lib/web-preview/src/index.ts +++ b/lib/preview-web/src/index.ts @@ -1,4 +1,4 @@ -export { WebPreview } from './WebPreview'; +export { PreviewWeb } from './PreviewWeb'; export { composeConfigs } from './composeConfigs'; export { simulatePageLoad, simulateDOMContentLoaded } from './simulate-pageload'; diff --git a/lib/web-preview/src/parseArgsParam.test.ts b/lib/preview-web/src/parseArgsParam.test.ts similarity index 100% rename from lib/web-preview/src/parseArgsParam.test.ts rename to lib/preview-web/src/parseArgsParam.test.ts diff --git a/lib/web-preview/src/parseArgsParam.ts b/lib/preview-web/src/parseArgsParam.ts similarity index 100% rename from lib/web-preview/src/parseArgsParam.ts rename to lib/preview-web/src/parseArgsParam.ts diff --git a/lib/web-preview/src/simulate-pageload.ts b/lib/preview-web/src/simulate-pageload.ts similarity index 100% rename from lib/web-preview/src/simulate-pageload.ts rename to lib/preview-web/src/simulate-pageload.ts diff --git a/lib/web-preview/src/types.ts b/lib/preview-web/src/types.ts similarity index 90% rename from lib/web-preview/src/types.ts rename to lib/preview-web/src/types.ts index 535e0ee513a..b56056b88b8 100644 --- a/lib/web-preview/src/types.ts +++ b/lib/preview-web/src/types.ts @@ -1,6 +1,6 @@ import { StoryId, AnyFramework, ProjectAnnotations, StoryContextForLoaders } from '@storybook/csf'; import { RenderContext, DecoratorApplicator, Story } from '@storybook/store'; -import { WebPreview } from './WebPreview'; +import { PreviewWeb } from './PreviewWeb'; export type WebProjectAnnotations< TFramework extends AnyFramework @@ -14,7 +14,7 @@ export interface DocsContextProps { name: string; storyById: (id: StoryId) => Story; componentStories: () => Story[]; - renderStoryToElement: WebPreview['renderStoryToElement']; + renderStoryToElement: PreviewWeb['renderStoryToElement']; getStoryContext: (story: Story) => StoryContextForLoaders; /** diff --git a/lib/web-preview/src/typings.d.ts b/lib/preview-web/src/typings.d.ts similarity index 100% rename from lib/web-preview/src/typings.d.ts rename to lib/preview-web/src/typings.d.ts diff --git a/lib/web-preview/tsconfig.json b/lib/preview-web/tsconfig.json similarity index 100% rename from lib/web-preview/tsconfig.json rename to lib/preview-web/tsconfig.json diff --git a/nx.json b/nx.json index cc2621bc8c1..46f40be51ad 100644 --- a/nx.json +++ b/nx.json @@ -235,7 +235,7 @@ "@storybook/ui": { "implicitDependencies": [] }, - "@storybook/web-preview": { + "@storybook/preview-web": { "implicitDependencies": [] } }, diff --git a/package.json b/package.json index 5902b9ec363..0be7a90d883 100644 --- a/package.json +++ b/package.json @@ -162,6 +162,7 @@ "@storybook/node-logger": "workspace:*", "@storybook/postinstall": "workspace:*", "@storybook/preact": "workspace:*", + "@storybook/preview-web": "workspace:*", "@storybook/react": "workspace:*", "@storybook/root": "workspace:*", "@storybook/router": "workspace:*", @@ -174,7 +175,6 @@ "@storybook/ui": "workspace:*", "@storybook/vue": "workspace:*", "@storybook/web-components": "workspace:*", - "@storybook/web-preview": "workspace:*", "@testing-library/dom": "^7.29.4", "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.2", diff --git a/workspace.json b/workspace.json index 5db82a5fca5..09b910e6528 100644 --- a/workspace.json +++ b/workspace.json @@ -289,8 +289,8 @@ "root": "lib/ui", "type": "library" }, - "@storybook/web-preview": { - "root": "lib/web-preview", + "@storybook/preview-web": { + "root": "lib/preview-web", "type": "library" } } diff --git a/yarn.lock b/yarn.lock index 4ab2f4cb503..d38581bf3b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5683,7 +5683,7 @@ __metadata: "@storybook/theming": 6.4.0-alpha.19 "@storybook/vue": 6.4.0-alpha.19 "@storybook/web-components": 6.4.0-alpha.19 - "@storybook/web-preview": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 "@types/cross-spawn": ^6.0.2 "@types/doctrine": ^0.0.3 "@types/enzyme": ^3.10.8 @@ -6307,7 +6307,7 @@ __metadata: "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 - "@storybook/web-preview": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 "@types/case-sensitive-paths-webpack-plugin": ^2.1.4 "@types/dotenv-webpack": ^3.0.0 "@types/node": ^14.0.10 @@ -6624,7 +6624,7 @@ __metadata: "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 - "@storybook/web-preview": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 airbnb-js-shims: ^2.2.1 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -6964,7 +6964,7 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 - "@storybook/web-preview": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7359,7 +7359,7 @@ __metadata: "@storybook/ui": "workspace:*" "@storybook/vue": "workspace:*" "@storybook/web-components": "workspace:*" - "@storybook/web-preview": "workspace:*" + "@storybook/preview-web": "workspace:*" "@testing-library/dom": ^7.29.4 "@testing-library/jest-dom": ^5.11.9 "@testing-library/react": ^11.2.2 @@ -7546,7 +7546,7 @@ __metadata: "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 - "@storybook/web-preview": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -7794,7 +7794,7 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/store": 6.4.0-alpha.19 - "@storybook/web-preview": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 babel-plugin-bundled-import-meta: ^0.3.1 core-js: ^3.8.2 @@ -7814,9 +7814,9 @@ __metadata: languageName: unknown linkType: soft -"@storybook/web-preview@6.4.0-alpha.19, @storybook/web-preview@workspace:*, @storybook/web-preview@workspace:lib/web-preview": +"@storybook/preview-web@6.4.0-alpha.19, @storybook/preview-web@workspace:*, @storybook/preview-web@workspace:lib/preview-web": version: 0.0.0-use.local - resolution: "@storybook/web-preview@workspace:lib/web-preview" + resolution: "@storybook/preview-web@workspace:lib/preview-web" dependencies: "@storybook/addons": 6.4.0-alpha.19 "@storybook/channel-postmessage": 6.4.0-alpha.19 From 4e12e81e7585f421f9bb75a3c4e37fd6af85d317 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 14:54:29 +1000 Subject: [PATCH 200/285] Rename `StoriesList` => `StoryIndex` --- .../virtualModuleModernEntry.js.handlebars | 4 +- .../virtualModuleModernEntry.js.handlebars | 4 +- lib/client-api/src/ClientApi.ts | 4 +- lib/core-client/src/preview/start.ts | 2 +- .../src/PreviewWeb.integration.test.ts | 8 +- lib/preview-web/src/PreviewWeb.mockdata.ts | 4 +- lib/preview-web/src/PreviewWeb.test.ts | 202 +++++++++--------- lib/preview-web/src/PreviewWeb.tsx | 9 +- lib/store/src/StoriesListStore.ts | 75 ------- ...tStore.test.ts => StoryIndexStore.test.ts} | 52 ++--- lib/store/src/StoryIndexStore.ts | 80 +++++++ lib/store/src/StoryStore.test.ts | 34 +-- lib/store/src/StoryStore.ts | 28 +-- lib/store/src/types.ts | 6 +- yarn.lock | 64 +++--- 15 files changed, 290 insertions(+), 286 deletions(-) delete mode 100644 lib/store/src/StoriesListStore.ts rename lib/store/src/{StoriesListStore.test.ts => StoryIndexStore.test.ts} (72%) create mode 100644 lib/store/src/StoryIndexStore.ts diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index a0f9c4779f6..8bc5e77d568 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -11,7 +11,7 @@ const getProjectAnnotations = () => {{/each}} ]); -const fetchStoriesList = async () => { +const fetchStoryIndex = async () => { const result = await fetch('./stories.json'); return result.json(); } @@ -19,7 +19,7 @@ const fetchStoriesList = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoriesList }); +const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoryIndex }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; diff --git a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars index 2688f38cc2c..12823e4c07a 100644 --- a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars @@ -11,14 +11,14 @@ const getProjectAnnotations = () => {{/each}} ]); -const fetchStoriesList = async () => { +const fetchStoryIndex = async () => { const result = await fetch('./stories.json'); return result.json(); } const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoriesList }); +const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoryIndex }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 4a7b6aa286e..e67802e2b2a 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -486,10 +486,10 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m } getStorybook = (): GetStorybookKind[] => { - const storiesList = this.getStoriesList(); + const storyIndex = this.getStoriesList(); const kinds: Record> = {}; - Object.entries(storiesList.stories).forEach(([storyId, { title, name, importPath }]) => { + Object.entries(storyIndex.stories).forEach(([storyId, { title, name, importPath }]) => { if (!kinds[title]) { kinds[title] = { kind: title, fileName: importPath, stories: [] }; } diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 71e382cb889..4ab893b1043 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -69,7 +69,7 @@ export function start( preview = new PreviewWeb({ importFn: (path: Path) => clientApi.importFn(path), getProjectAnnotations, - fetchStoriesList: () => clientApi.getStoriesList(), + fetchStoryIndex: () => clientApi.getStoriesList(), }); if (globalWindow) { // eslint-disable-next-line no-underscore-dangle diff --git a/lib/preview-web/src/PreviewWeb.integration.test.ts b/lib/preview-web/src/PreviewWeb.integration.test.ts index 4b18d6e9fb8..6fd4070e48e 100644 --- a/lib/preview-web/src/PreviewWeb.integration.test.ts +++ b/lib/preview-web/src/PreviewWeb.integration.test.ts @@ -9,7 +9,7 @@ import { importFn, projectAnnotations, getProjectAnnotations, - fetchStoriesList, + fetchStoryIndex, emitter, mockChannel, waitForRender, @@ -61,7 +61,7 @@ describe('PreviewWeb', () => { storyFn() ); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); @@ -71,7 +71,7 @@ describe('PreviewWeb', () => { it('renders docs mode through docs page', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); const docsRoot = window.document.createElement('div'); // @ts-ignore @@ -106,7 +106,7 @@ describe('PreviewWeb', () => { it('renders story mode through the updated stack', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); diff --git a/lib/preview-web/src/PreviewWeb.mockdata.ts b/lib/preview-web/src/PreviewWeb.mockdata.ts index 0a0ba09717f..a4d1d5259ab 100644 --- a/lib/preview-web/src/PreviewWeb.mockdata.ts +++ b/lib/preview-web/src/PreviewWeb.mockdata.ts @@ -33,7 +33,7 @@ export const projectAnnotations = { }; export const getProjectAnnotations = () => projectAnnotations; -export const storiesList: StoriesList = { +export const storyIndex: StoriesList = { v: 3, stories: { 'component-one--a': { @@ -53,7 +53,7 @@ export const storiesList: StoriesList = { }, }, }; -export const fetchStoriesList = async () => storiesList; +export const fetchStoryIndex = async () => storyIndex; export const emitter = new EventEmitter(); export const mockChannel = { diff --git a/lib/preview-web/src/PreviewWeb.test.ts b/lib/preview-web/src/PreviewWeb.test.ts index ec717d837ba..87f4cc501c6 100644 --- a/lib/preview-web/src/PreviewWeb.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -12,7 +12,7 @@ import { importFn, projectAnnotations, getProjectAnnotations, - fetchStoriesList, + fetchStoryIndex, emitter, mockChannel, waitForEvents, @@ -75,7 +75,7 @@ describe('PreviewWeb', () => { throw err; }, importFn, - fetchStoriesList, + fetchStoryIndex, }); expect(preview.view.showErrorDisplay).toHaveBeenCalled(); @@ -87,14 +87,14 @@ describe('PreviewWeb', () => { it('sets globals from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.storyStore.globals.get()).toEqual({ a: 'c' }); }); it('emits the SET_GLOBALS event', async () => { - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'b' }, @@ -106,7 +106,7 @@ describe('PreviewWeb', () => { await new PreviewWeb({ getProjectAnnotations: () => ({}), importFn, - fetchStoriesList, + fetchStoryIndex, }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { @@ -118,7 +118,7 @@ describe('PreviewWeb', () => { it('emits the SET_GLOBALS event from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'c' }, @@ -129,7 +129,7 @@ describe('PreviewWeb', () => { it('sets args from the URL', async () => { document.location.search = '?id=component-one--a&args=foo:url'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.storyStore.args.get('component-one--a')).toEqual({ @@ -142,7 +142,7 @@ describe('PreviewWeb', () => { it('selects the story specified in the URL', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.urlStore.selection).toEqual({ @@ -159,7 +159,7 @@ describe('PreviewWeb', () => { it('emits the STORY_SPECIFIED event', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_SPECIFIED, { storyId: 'component-one--a', @@ -170,7 +170,7 @@ describe('PreviewWeb', () => { it('emits the CURRENT_STORY_WAS_SET event', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.CURRENT_STORY_WAS_SET, { storyId: 'component-one--a', @@ -182,7 +182,7 @@ describe('PreviewWeb', () => { it('renders missing', async () => { document.location.search = '?id=random'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -193,7 +193,7 @@ describe('PreviewWeb', () => { it.skip('tries again with a specifier if CSF file changes', async () => { document.location.search = '?id=component-one--d'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -220,7 +220,7 @@ describe('PreviewWeb', () => { it.skip('DOES NOT try again if CSF file changes if selection changed', async () => { document.location.search = '?id=component-one--d'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -250,7 +250,7 @@ describe('PreviewWeb', () => { it.skip('tries again with a specifier if stories list changes', async () => { document.location.search = '?id=component-three--d'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -265,7 +265,7 @@ describe('PreviewWeb', () => { }); it('renders missing if no selection', async () => { - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.view.showNoPreview).toHaveBeenCalled(); @@ -276,7 +276,7 @@ describe('PreviewWeb', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.view.prepareForStory).toHaveBeenCalledWith( @@ -288,7 +288,7 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_PREPARED, { id: 'component-one--a', @@ -301,7 +301,7 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); @@ -318,7 +318,7 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); @@ -346,7 +346,7 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -362,7 +362,7 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -378,7 +378,7 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -394,7 +394,7 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -413,7 +413,7 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -424,7 +424,7 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); @@ -433,7 +433,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); @@ -445,7 +445,7 @@ describe('PreviewWeb', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); expect(preview.view.prepareForDocs).toHaveBeenCalled(); @@ -454,7 +454,7 @@ describe('PreviewWeb', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); @@ -477,7 +477,7 @@ describe('PreviewWeb', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); @@ -489,7 +489,7 @@ describe('PreviewWeb', () => { describe('onUpdateGlobals', () => { it('emits GLOBALS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -501,7 +501,7 @@ describe('PreviewWeb', () => { it('sets new globals on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -511,7 +511,7 @@ describe('PreviewWeb', () => { it('passes new globals in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -533,7 +533,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -547,7 +547,7 @@ describe('PreviewWeb', () => { describe('onUpdateArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -562,7 +562,7 @@ describe('PreviewWeb', () => { it('sets new args on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { @@ -578,7 +578,7 @@ describe('PreviewWeb', () => { it('passes new args in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -604,7 +604,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -623,7 +623,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -653,7 +653,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -690,7 +690,7 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await renderToDOMCalled; // Story gets rendered with original args @@ -735,7 +735,7 @@ describe('PreviewWeb', () => { describe('onResetArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -763,7 +763,7 @@ describe('PreviewWeb', () => { it('resets a single arg', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -797,7 +797,7 @@ describe('PreviewWeb', () => { it('resets all args', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, @@ -830,7 +830,7 @@ describe('PreviewWeb', () => { describe('on FORCE_RE_RENDER', () => { it('rerenders the story with the same args', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -849,7 +849,7 @@ describe('PreviewWeb', () => { describe('onSetCurrentStory', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -865,7 +865,7 @@ describe('PreviewWeb', () => { it('emits CURRENT_STORY_WAS_SET', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -880,7 +880,7 @@ describe('PreviewWeb', () => { it('renders missing if the story specified does not exist', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); emitter.emit(Events.SET_CURRENT_STORY, { @@ -896,7 +896,7 @@ describe('PreviewWeb', () => { describe('if the selection is unchanged', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); emitter.emit(Events.SET_CURRENT_STORY, { @@ -910,7 +910,7 @@ describe('PreviewWeb', () => { it('does NOT call renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); projectAnnotations.renderToDOM.mockClear(); @@ -929,7 +929,7 @@ describe('PreviewWeb', () => { describe('when changing story in story viewMode', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -945,7 +945,7 @@ describe('PreviewWeb', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -960,7 +960,7 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -981,7 +981,7 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1004,7 +1004,7 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1033,7 +1033,7 @@ describe('PreviewWeb', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1055,7 +1055,7 @@ describe('PreviewWeb', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1080,7 +1080,7 @@ describe('PreviewWeb', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1102,7 +1102,7 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1117,7 +1117,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1132,7 +1132,7 @@ describe('PreviewWeb', () => { it('retains any arg changes', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1173,7 +1173,7 @@ describe('PreviewWeb', () => { componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1204,7 +1204,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1237,7 +1237,7 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await renderToDOMCalled; // Story gets rendered with original args @@ -1286,7 +1286,7 @@ describe('PreviewWeb', () => { describe('when changing from story viewMode to docs', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1302,7 +1302,7 @@ describe('PreviewWeb', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1317,7 +1317,7 @@ describe('PreviewWeb', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1333,7 +1333,7 @@ describe('PreviewWeb', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1361,7 +1361,7 @@ describe('PreviewWeb', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1378,7 +1378,7 @@ describe('PreviewWeb', () => { describe('when changing from docs viewMode to story', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1394,7 +1394,7 @@ describe('PreviewWeb', () => { it('unmounts docs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1410,7 +1410,7 @@ describe('PreviewWeb', () => { // NOTE: I am not sure this entirely makes sense but this is the behaviour from 6.3 it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1425,7 +1425,7 @@ describe('PreviewWeb', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1445,7 +1445,7 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1466,7 +1466,7 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1489,7 +1489,7 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1518,7 +1518,7 @@ describe('PreviewWeb', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1545,7 +1545,7 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1570,7 +1570,7 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1587,7 +1587,7 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1602,7 +1602,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }).initialize(); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1630,7 +1630,7 @@ describe('PreviewWeb', () => { it('does not emit STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1646,7 +1646,7 @@ describe('PreviewWeb', () => { it('does not emit STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1659,7 +1659,7 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED with new annotations', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); mockChannel.emit.mockClear(); @@ -1678,7 +1678,7 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1700,7 +1700,7 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1728,7 +1728,7 @@ describe('PreviewWeb', () => { it('retains the same delta to the args', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1757,7 +1757,7 @@ describe('PreviewWeb', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1776,7 +1776,7 @@ describe('PreviewWeb', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1798,7 +1798,7 @@ describe('PreviewWeb', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1817,7 +1817,7 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1831,7 +1831,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1853,7 +1853,7 @@ describe('PreviewWeb', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1867,7 +1867,7 @@ describe('PreviewWeb', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1894,7 +1894,7 @@ describe('PreviewWeb', () => { it('renders story missing', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1908,7 +1908,7 @@ describe('PreviewWeb', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1929,7 +1929,7 @@ describe('PreviewWeb', () => { describe('onGetProjectAnnotationsChanged', () => { it('shows an error the new value throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1957,7 +1957,7 @@ describe('PreviewWeb', () => { it('updates globals to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1970,7 +1970,7 @@ describe('PreviewWeb', () => { it('updates args to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -1987,7 +1987,7 @@ describe('PreviewWeb', () => { it('rerenders the current story with new global meta-generated context', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); await waitForRender(); @@ -2011,7 +2011,7 @@ describe('PreviewWeb', () => { describe('onKeydown', () => { it('emits PREVIEW_KEYDOWN for regular elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); preview.onKeydown({ @@ -2026,7 +2026,7 @@ describe('PreviewWeb', () => { it('does not emit PREVIEW_KEYDOWN for input elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoriesList }); + const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); await preview.initialize(); preview.onKeydown({ diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 2f3fc504f89..3df3b65135a 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -21,7 +21,6 @@ import { CSFFile, StoryStore, StorySpecifier, - StoriesList, } from '@storybook/store'; import { WebProjectAnnotations, DocsContextProps } from './types'; @@ -59,11 +58,11 @@ export class PreviewWeb { constructor({ getProjectAnnotations, importFn, - fetchStoriesList, + fetchStoryIndex, }: { getProjectAnnotations: () => WebProjectAnnotations; importFn: ModuleImportFn; - fetchStoriesList: ConstructorParameters[0]['fetchStoriesList']; + fetchStoryIndex: ConstructorParameters[0]['fetchStoryIndex']; }) { this.channel = addons.getChannel(); this.view = new WebView(); @@ -74,7 +73,7 @@ export class PreviewWeb { } this.urlStore = new UrlStore(); - this.storyStore = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + this.storyStore = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); } getProjectAnnotationsOrRenderError( @@ -141,7 +140,7 @@ export class PreviewWeb { } const { storySpecifier, viewMode, args } = this.urlStore.selectionSpecifier; - const storyId = this.storyStore.storiesList.storyIdFromSpecifier(storySpecifier); + const storyId = this.storyStore.storyIndex.storyIdFromSpecifier(storySpecifier); if (!storyId) { this.renderMissingStory(storySpecifier); diff --git a/lib/store/src/StoriesListStore.ts b/lib/store/src/StoriesListStore.ts deleted file mode 100644 index 5f4b93389ec..00000000000 --- a/lib/store/src/StoriesListStore.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Channel } from '@storybook/addons'; -import { StoryId } from '@storybook/csf'; - -import { StorySpecifier, Path, StoriesList, StoriesListStory } from './types'; - -export class StoriesListStore { - fetchStoriesList: () => Promise | StoriesList; - - channel: Channel; - - storiesList: StoriesList; - - constructor({ fetchStoriesList }: { fetchStoriesList: StoriesListStore['fetchStoriesList'] }) { - this.fetchStoriesList = fetchStoriesList; - } - - async initialize() { - return this.cacheStoriesList(); - } - - initializeSync() { - return this.cacheStoriesListSync(); - } - - async onStoriesChanged() { - this.storiesList = await this.fetchStoriesList(); - } - - async cacheStoriesList() { - this.storiesList = await this.fetchStoriesList(); - } - - async cacheStoriesListSync() { - this.storiesList = this.fetchStoriesList() as StoriesList; - if (!this.storiesList.v) { - throw new Error( - `fetchStoriesList() didn't return a stories list, did you pass an async version then call initializeSync()?` - ); - } - } - - storyIdFromSpecifier(specifier: StorySpecifier) { - const storyIds = Object.keys(this.storiesList.stories); - if (specifier === '*') { - // '*' means select the first story. If there is none, we have no selection. - return storyIds[0]; - } - - if (typeof specifier === 'string') { - // Find the story with the exact id that matches the specifier (see #11571) - if (storyIds.indexOf(specifier) >= 0) { - return specifier; - } - // Fallback to the first story that starts with the specifier - return storyIds.find((storyId) => storyId.startsWith(specifier)); - } - - // Try and find a story matching the name/kind, setting no selection if they don't exist. - const { name, title } = specifier; - const match = Object.entries(this.storiesList.stories).find( - ([id, story]) => story.name === name && story.title === title - ); - - return match && match[0]; - } - - storyIdToMetadata(storyId: StoryId): StoriesListStory { - const storyMetadata = this.storiesList.stories[storyId]; - if (!storyMetadata) { - throw new Error(`Didn't find '${storyId}' in story metadata (\`stories.json\`)`); - } - - return storyMetadata; - } -} diff --git a/lib/store/src/StoriesListStore.test.ts b/lib/store/src/StoryIndexStore.test.ts similarity index 72% rename from lib/store/src/StoriesListStore.test.ts rename to lib/store/src/StoryIndexStore.test.ts index 584e993037a..165c6af3734 100644 --- a/lib/store/src/StoriesListStore.test.ts +++ b/lib/store/src/StoryIndexStore.test.ts @@ -1,9 +1,9 @@ -import { StoriesListStore } from './StoriesListStore'; -import { StoriesList } from './types'; +import { StoryIndexStore } from './StoryIndexStore'; +import { StoryIndex } from './types'; jest.mock('@storybook/channel-websocket', () => () => ({ on: jest.fn() })); -const stories: StoriesList = { +const stories: StoryIndex = { v: 3, stories: { 'component-one--a': { @@ -23,9 +23,9 @@ const stories: StoriesList = { }, }, }; -const fetchStoriesList = async () => stories; +const fetchStoryIndex = async () => stories; -const makeFetchStoriesList = (titlesAndNames) => { +const makeFetchStoryIndex = (titlesAndNames) => { return async () => ({ v: 3, stories: Object.fromEntries( @@ -41,19 +41,19 @@ const makeFetchStoriesList = (titlesAndNames) => { }); }; -describe('StoriesListStore', () => { +describe('StoryIndexStore', () => { describe('storyIdFromSpecifier', () => { describe('if you use *', () => { it('selects the first story in the store', async () => { - const store = new StoriesListStore({ fetchStoriesList }); + const store = new StoryIndexStore({ fetchStoryIndex }); await store.initialize(); expect(store.storyIdFromSpecifier('*')).toEqual('component-one--a'); }); it('selects nothing if there are no stories', async () => { - const store = new StoriesListStore({ - fetchStoriesList: makeFetchStoriesList([]), + const store = new StoryIndexStore({ + fetchStoryIndex: makeFetchStoryIndex([]), }); await store.initialize(); @@ -63,15 +63,15 @@ describe('StoriesListStore', () => { describe('if you use a component or group id', () => { it('selects the first story for the component', async () => { - const store = new StoriesListStore({ fetchStoriesList }); + const store = new StoryIndexStore({ fetchStoryIndex }); await store.initialize(); expect(store.storyIdFromSpecifier('component-two')).toEqual('component-two--c'); }); it('selects the first story for the group', async () => { - const store = new StoriesListStore({ - fetchStoriesList: makeFetchStoriesList([ + const store = new StoryIndexStore({ + fetchStoryIndex: makeFetchStoryIndex([ ['g1/a', '1'], ['g2/a', '1'], ['g2/b', '1'], @@ -84,8 +84,8 @@ describe('StoriesListStore', () => { // Making sure the fix #11571 doesn't break this it('selects the first story if there are two stories in the group of different lengths', async () => { - const store = new StoriesListStore({ - fetchStoriesList: makeFetchStoriesList([ + const store = new StoryIndexStore({ + fetchStoryIndex: makeFetchStoryIndex([ ['a', 'long-long-long'], ['a', 'short'], ]), @@ -96,7 +96,7 @@ describe('StoriesListStore', () => { }); it('selects nothing if the component or group does not exist', async () => { - const store = new StoriesListStore({ fetchStoriesList }); + const store = new StoryIndexStore({ fetchStoryIndex }); await store.initialize(); expect(store.storyIdFromSpecifier('random')).toBeUndefined(); @@ -104,14 +104,14 @@ describe('StoriesListStore', () => { }); describe('if you use a storyId', () => { it('selects a specific story', async () => { - const store = new StoriesListStore({ fetchStoriesList }); + const store = new StoryIndexStore({ fetchStoryIndex }); await store.initialize(); expect(store.storyIdFromSpecifier('component-one--a')).toEqual('component-one--a'); }); it('selects nothing if you the story does not exist', async () => { - const store = new StoriesListStore({ fetchStoriesList }); + const store = new StoryIndexStore({ fetchStoryIndex }); await store.initialize(); expect(store.storyIdFromSpecifier('component-one--c')).toBeUndefined(); @@ -119,8 +119,8 @@ describe('StoriesListStore', () => { // See #11571 it('does NOT select an earlier story that this story id is a prefix of', async () => { - const store = new StoriesListStore({ - fetchStoriesList: makeFetchStoriesList([ + const store = new StoryIndexStore({ + fetchStoryIndex: makeFetchStoryIndex([ ['a', '31'], ['a', '3'], ]), @@ -132,24 +132,24 @@ describe('StoriesListStore', () => { }); }); - describe('storyIdToMetadata', () => { + describe('storyIdToEntry', () => { it('works when the story exists', async () => { - const store = new StoriesListStore({ fetchStoriesList }); + const store = new StoryIndexStore({ fetchStoryIndex }); await store.initialize(); - expect(store.storyIdToMetadata('component-one--a')).toEqual({ + expect(store.storyIdToEntry('component-one--a')).toEqual({ name: 'A', title: 'Component One', importPath: './src/ComponentOne.stories.js', }); - expect(store.storyIdToMetadata('component-one--b')).toEqual({ + expect(store.storyIdToEntry('component-one--b')).toEqual({ name: 'B', title: 'Component One', importPath: './src/ComponentOne.stories.js', }); - expect(store.storyIdToMetadata('component-two--c')).toEqual({ + expect(store.storyIdToEntry('component-two--c')).toEqual({ name: 'C', title: 'Component Two', importPath: './src/ComponentTwo.stories.js', @@ -157,10 +157,10 @@ describe('StoriesListStore', () => { }); it('throws when the story does not', async () => { - const store = new StoriesListStore({ fetchStoriesList }); + const store = new StoryIndexStore({ fetchStoryIndex }); await store.initialize(); - expect(() => store.storyIdToMetadata('random')).toThrow(/Didn't find 'random'/); + expect(() => store.storyIdToEntry('random')).toThrow(/Didn't find 'random'/); }); }); }); diff --git a/lib/store/src/StoryIndexStore.ts b/lib/store/src/StoryIndexStore.ts new file mode 100644 index 00000000000..f5487f51e18 --- /dev/null +++ b/lib/store/src/StoryIndexStore.ts @@ -0,0 +1,80 @@ +import { Channel } from '@storybook/addons'; +import { StoryId } from '@storybook/csf'; + +import { StorySpecifier, StoryIndex, StoryIndexEntry } from './types'; + +type MaybePromise = Promise | T; + +export class StoryIndexStore { + fetchStoryIndex: () => MaybePromise; + + channel: Channel; + + stories: Record; + + constructor({ fetchStoryIndex }: { fetchStoryIndex: StoryIndexStore['fetchStoryIndex'] }) { + this.fetchStoryIndex = fetchStoryIndex; + } + + async initialize() { + return this.cache(); + } + + initializeSync() { + return this.cacheSync(); + } + + async onStoriesChanged() { + const { stories } = await this.fetchStoryIndex(); + this.stories = stories; + } + + async cache() { + const { stories } = await this.fetchStoryIndex(); + this.stories = stories; + } + + async cacheSync() { + const data = this.fetchStoryIndex() as StoryIndex; + if (!data.v) { + throw new Error( + `fetchStoryIndex() didn't return a stories list, did you pass an async version then call initializeSync()?` + ); + } + this.stories = data.stories; + } + + storyIdFromSpecifier(specifier: StorySpecifier) { + const storyIds = Object.keys(this.stories); + if (specifier === '*') { + // '*' means select the first story. If there is none, we have no selection. + return storyIds[0]; + } + + if (typeof specifier === 'string') { + // Find the story with the exact id that matches the specifier (see #11571) + if (storyIds.indexOf(specifier) >= 0) { + return specifier; + } + // Fallback to the first story that starts with the specifier + return storyIds.find((storyId) => storyId.startsWith(specifier)); + } + + // Try and find a story matching the name/kind, setting no selection if they don't exist. + const { name, title } = specifier; + const match = Object.entries(this.stories).find( + ([id, story]) => story.name === name && story.title === title + ); + + return match && match[0]; + } + + storyIdToEntry(storyId: StoryId): StoryIndexEntry { + const storyEntry = this.stories[storyId]; + if (!storyEntry) { + throw new Error(`Didn't find '${storyId}' in story index (\`stories.json\`)`); + } + + return storyEntry; + } +} diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index d3ba43a93e6..7570099cba3 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -5,7 +5,7 @@ import { HooksContext } from '../../addons/dist/ts3.9/hooks'; import { prepareStory } from './prepareStory'; import { processCSFFile } from './processCSFFile'; import { StoryStore } from './StoryStore'; -import { StoriesList } from './types'; +import { StoryIndex } from './types'; // Spy on prepareStory/processCSFFile jest.mock('./prepareStory', () => ({ @@ -42,7 +42,7 @@ const projectAnnotations: ProjectAnnotations = { render: jest.fn(), }; -const storiesList: StoriesList = { +const storyIndex: StoryIndex = { v: 3, stories: { 'component-one--a': { @@ -62,12 +62,12 @@ const storiesList: StoriesList = { }, }, }; -const fetchStoriesList = async () => storiesList; +const fetchStoryIndex = async () => storyIndex; describe('StoryStore', () => { describe('projectAnnotations', () => { it('normalizes on initialization', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); expect(store.projectAnnotations.globalTypes).toEqual({ @@ -79,7 +79,7 @@ describe('StoryStore', () => { }); it('normalizes on updateProjectAnnotations', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); store.updateProjectAnnotations(projectAnnotations); @@ -94,7 +94,7 @@ describe('StoryStore', () => { describe('loadStory', () => { it('pulls the story via the importFn', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); importFn.mockClear(); @@ -108,7 +108,7 @@ describe('StoryStore', () => { }); it('uses a cache', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -132,7 +132,7 @@ describe('StoryStore', () => { describe('componentStoriesFromCSFFile', () => { it('returns all the stories in the file', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); const csfFile = await store.loadCSFFileByStoryId('component-one--a'); @@ -145,7 +145,7 @@ describe('StoryStore', () => { describe('getStoryContext', () => { it('returns the args and globals correctly', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -157,7 +157,7 @@ describe('StoryStore', () => { }); it('returns the args and globals correctly when they change', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -172,7 +172,7 @@ describe('StoryStore', () => { }); it('returns the same hooks each time', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -184,7 +184,7 @@ describe('StoryStore', () => { describe('cleanupStory', () => { it('cleans the hooks from the context', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -198,7 +198,7 @@ describe('StoryStore', () => { describe('loadAllCSFFiles', () => { it('imports *all* csf files', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); importFn.mockClear(); @@ -213,14 +213,14 @@ describe('StoryStore', () => { describe('extract', () => { it('throws if you have not called cacheAllCSFFiles', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); expect(() => store.extract()).toThrow(/Cannot call extract/); }); it('produces objects with functions and hooks stripped', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); await store.cacheAllCSFFiles(); @@ -332,7 +332,7 @@ describe('StoryStore', () => { const store = new StoryStore({ importFn: docsOnlyImportFn, projectAnnotations, - fetchStoriesList, + fetchStoryIndex, }); await store.initialize(); await store.cacheAllCSFFiles(); @@ -350,7 +350,7 @@ describe('StoryStore', () => { describe('getSetStoriesPayload', () => { it('maps stories list to payload correctly', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoriesList }); + const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); await store.initialize(); await store.cacheAllCSFFiles(); diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 18b9f8391c3..21be7dc4301 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -10,7 +10,7 @@ import { import mapValues from 'lodash/mapValues'; import pick from 'lodash/pick'; -import { StoriesListStore } from './StoriesListStore'; +import { StoryIndexStore } from './StoryIndexStore'; import { ArgsStore } from './ArgsStore'; import { GlobalsStore } from './GlobalsStore'; import { processCSFFile } from './processCSFFile'; @@ -57,7 +57,7 @@ function normalizeProjectAnnotations({ } export class StoryStore { - storiesList: StoriesListStore; + storyIndex: StoryIndexStore; importFn: ModuleImportFn; @@ -78,13 +78,13 @@ export class StoryStore { constructor({ importFn, projectAnnotations, - fetchStoriesList, + fetchStoryIndex, }: { importFn: ModuleImportFn; projectAnnotations: ProjectAnnotations; - fetchStoriesList: ConstructorParameters[0]['fetchStoriesList']; + fetchStoryIndex: ConstructorParameters[0]['fetchStoryIndex']; }) { - this.storiesList = new StoriesListStore({ fetchStoriesList }); + this.storyIndex = new StoryIndexStore({ fetchStoryIndex }); this.importFn = importFn; this.projectAnnotations = normalizeProjectAnnotations(projectAnnotations); @@ -98,7 +98,7 @@ export class StoryStore { } async initialize({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { - await this.storiesList.initialize(); + await this.storyIndex.initialize(); if (cacheAllCSFFiles) { await this.cacheAllCSFFiles(); @@ -106,7 +106,7 @@ export class StoryStore { } initializeSync({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { - this.storiesList.initializeSync(); + this.storyIndex.initializeSync(); if (cacheAllCSFFiles) { this.cacheAllCSFFilesSync(); @@ -123,7 +123,7 @@ export class StoryStore { this.importFn = importFn; // We need to refetch the stories list as it may have changed too - await this.storiesList.cacheStoriesList(); + await this.storyIndex.cache(); if (this.cachedCSFFiles) { await this.cacheAllCSFFiles(); @@ -131,13 +131,13 @@ export class StoryStore { } async loadCSFFileByStoryId(storyId: StoryId): Promise> { - const { importPath, title } = this.storiesList.storyIdToMetadata(storyId); + const { importPath, title } = this.storyIndex.storyIdToEntry(storyId); const moduleExports = await this.importFn(importPath); return this.processCSFFileWithCache(moduleExports, title); } loadCSFFileByStoryIdSync(storyId: StoryId): CSFFile { - const { importPath, title } = this.storiesList.storyIdToMetadata(storyId); + const { importPath, title } = this.storyIndex.storyIdToEntry(storyId); const moduleExports = this.importFn(importPath); if (Promise.resolve(moduleExports) === moduleExports) { throw new Error( @@ -149,7 +149,7 @@ export class StoryStore { async loadAllCSFFiles(): Promise>> { const importPaths: Record = {}; - Object.entries(this.storiesList.storiesList.stories).forEach(([storyId, { importPath }]) => { + Object.entries(this.storyIndex.stories).forEach(([storyId, { importPath }]) => { importPaths[importPath] = storyId; }); @@ -170,7 +170,7 @@ export class StoryStore { loadAllCSFFilesSync(): Record> { const importPaths: Record = {}; - Object.entries(this.storiesList.storiesList.stories).forEach(([storyId, { importPath }]) => { + Object.entries(this.storyIndex.stories).forEach(([storyId, { importPath }]) => { importPaths[importPath] = storyId; }); @@ -245,7 +245,7 @@ export class StoryStore { throw new Error('Cannot call extract() unless you call cacheAllCSFFiles() first.'); } - return Object.entries(this.storiesList.storiesList.stories) + return Object.entries(this.storyIndex.stories) .map(([storyId, { importPath }]) => { const csfFile = this.cachedCSFFiles[importPath]; const story = this.storyFromCSFFile({ storyId, csfFile }); @@ -314,7 +314,7 @@ export class StoryStore { throw new Error('Cannot call fromId/raw() unless you call cacheAllCSFFiles() first.'); } - const { importPath } = this.storiesList.storyIdToMetadata(storyId); + const { importPath } = this.storyIndex.storyIdToEntry(storyId); if (!importPath) { throw new Error(`Unknown storyId ${storyId}`); } diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 654d66d7bc0..1acbd0d4cc8 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -76,15 +76,15 @@ export declare type RenderContext = StoryIdenti unboundStoryFn: LegacyStoryFn; }; -export interface StoriesListStory { +export interface StoryIndexEntry { name: StoryName; title: ComponentTitle; importPath: Path; } -export interface StoriesList { +export interface StoryIndex { v: number; - stories: Record; + stories: Record; } export type StorySpecifier = StoryId | { name: StoryName; title: ComponentTitle } | '*'; diff --git a/yarn.lock b/yarn.lock index d38581bf3b8..1f322727ff9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5677,13 +5677,13 @@ __metadata: "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/postinstall": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 "@storybook/react": 6.4.0-alpha.19 "@storybook/source-loader": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 "@storybook/vue": 6.4.0-alpha.19 "@storybook/web-components": 6.4.0-alpha.19 - "@storybook/preview-web": 6.4.0-alpha.19 "@types/cross-spawn": ^6.0.2 "@types/doctrine": ^0.0.3 "@types/enzyme": ^3.10.8 @@ -6302,12 +6302,12 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.19 "@storybook/router": 6.4.0-alpha.19 "@storybook/semver": ^7.3.2 "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 - "@storybook/preview-web": 6.4.0-alpha.19 "@types/case-sensitive-paths-webpack-plugin": ^2.1.4 "@types/dotenv-webpack": ^3.0.0 "@types/node": ^14.0.10 @@ -6622,9 +6622,9 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/preview-web": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 - "@storybook/preview-web": 6.4.0-alpha.19 airbnb-js-shims: ^2.2.1 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -6963,8 +6963,8 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.d61cd6c.0 - "@storybook/store": 6.4.0-alpha.19 "@storybook/preview-web": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7216,6 +7216,31 @@ __metadata: languageName: node linkType: hard +"@storybook/preview-web@6.4.0-alpha.19, @storybook/preview-web@workspace:*, @storybook/preview-web@workspace:lib/preview-web": + version: 0.0.0-use.local + resolution: "@storybook/preview-web@workspace:lib/preview-web" + dependencies: + "@storybook/addons": 6.4.0-alpha.19 + "@storybook/channel-postmessage": 6.4.0-alpha.19 + "@storybook/client-logger": 6.4.0-alpha.19 + "@storybook/core-events": 6.4.0-alpha.19 + "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/store": 6.4.0-alpha.19 + ansi-to-html: ^0.6.11 + core-js: ^3.8.2 + global: ^4.4.0 + lodash: ^4.17.20 + qs: ^6.10.0 + regenerator-runtime: ^0.13.7 + ts-dedent: ^2.0.0 + unfetch: ^4.2.0 + util-deprecate: ^1.0.2 + peerDependencies: + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + languageName: unknown + linkType: soft + "@storybook/react-docgen-typescript-plugin@npm:1.0.2-canary.253f8c1.0": version: 1.0.2-canary.253f8c1.0 resolution: "@storybook/react-docgen-typescript-plugin@npm:1.0.2-canary.253f8c1.0" @@ -7347,6 +7372,7 @@ __metadata: "@storybook/node-logger": "workspace:*" "@storybook/postinstall": "workspace:*" "@storybook/preact": "workspace:*" + "@storybook/preview-web": "workspace:*" "@storybook/react": "workspace:*" "@storybook/root": "workspace:*" "@storybook/router": "workspace:*" @@ -7359,7 +7385,6 @@ __metadata: "@storybook/ui": "workspace:*" "@storybook/vue": "workspace:*" "@storybook/web-components": "workspace:*" - "@storybook/preview-web": "workspace:*" "@testing-library/dom": ^7.29.4 "@testing-library/jest-dom": ^5.11.9 "@testing-library/react": ^11.2.2 @@ -7545,8 +7570,8 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.d61cd6c.0 "@storybook/node-logger": 6.4.0-alpha.19 - "@storybook/store": 6.4.0-alpha.19 "@storybook/preview-web": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -7793,8 +7818,8 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/csf": 0.0.2--canary.d61cd6c.0 - "@storybook/store": 6.4.0-alpha.19 "@storybook/preview-web": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 babel-plugin-bundled-import-meta: ^0.3.1 core-js: ^3.8.2 @@ -7814,31 +7839,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/preview-web@6.4.0-alpha.19, @storybook/preview-web@workspace:*, @storybook/preview-web@workspace:lib/preview-web": - version: 0.0.0-use.local - resolution: "@storybook/preview-web@workspace:lib/preview-web" - dependencies: - "@storybook/addons": 6.4.0-alpha.19 - "@storybook/channel-postmessage": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 - "@storybook/store": 6.4.0-alpha.19 - ansi-to-html: ^0.6.11 - core-js: ^3.8.2 - global: ^4.4.0 - lodash: ^4.17.20 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - unfetch: ^4.2.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - languageName: unknown - linkType: soft - "@stroncium/procfs@npm:^1.2.1": version: 1.2.1 resolution: "@stroncium/procfs@npm:1.2.1" From 4c69483f77bec5dff7179f44fe706d846bcee99b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 15:20:22 +1000 Subject: [PATCH 201/285] Small fixes to get boostrapping --- lib/client-api/src/ClientApi.ts | 12 ++++++------ lib/core-client/src/preview/start.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index e67802e2b2a..de9394b188b 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -24,7 +24,7 @@ import { NormalizedComponentAnnotations, NormalizedProjectAnnotations, Path, - StoriesList, + StoryIndex, ModuleExports, ModuleImportFn, combineParameters, @@ -140,7 +140,7 @@ export default class ClientApi { onImportFnChanged?: ({ importFn }: { importFn: ModuleImportFn }) => void; - private stories: StoriesList['stories']; + private stories: StoryIndex['stories']; private csfExports: Record; @@ -174,7 +174,7 @@ export default class ClientApi { return this.csfExports[path]; } - getStoriesList() { + getStoryIndex() { const fileNameOrder = Object.keys(this.csfExports); const storySortParameter = this.projectAnnotations.parameters?.options?.storySort; @@ -218,7 +218,7 @@ export default class ClientApi { stories: stories.reduce((acc, [id]) => { acc[id] = this.stories[id]; return acc; - }, {} as StoriesList['stories']), + }, {} as StoryIndex['stories']), }; } @@ -486,10 +486,10 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m } getStorybook = (): GetStorybookKind[] => { - const storyIndex = this.getStoriesList(); + const storiesList = this.getStoryIndex(); const kinds: Record> = {}; - Object.entries(storyIndex.stories).forEach(([storyId, { title, name, importPath }]) => { + Object.entries(storiesList.stories).forEach(([storyId, { title, name, importPath }]) => { if (!kinds[title]) { kinds[title] = { kind: title, fileName: importPath, stories: [] }; } diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 4ab893b1043..8e95d68d3d6 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -69,7 +69,7 @@ export function start( preview = new PreviewWeb({ importFn: (path: Path) => clientApi.importFn(path), getProjectAnnotations, - fetchStoryIndex: () => clientApi.getStoriesList(), + fetchStoryIndex: () => clientApi.getStoryIndex(), }); if (globalWindow) { // eslint-disable-next-line no-underscore-dangle From e61c1015b202d6b3cc7fa0e3643fce298cc21722 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 15:46:34 +1000 Subject: [PATCH 202/285] Split ClientApi facade into its own class --- lib/client-api/src/ClientApi.test.ts | 8 +- lib/client-api/src/ClientApi.ts | 183 ++++------------------ lib/client-api/src/StoryStoreFacade.ts | 171 ++++++++++++++++++++ lib/client-api/src/index.ts | 3 +- lib/core-client/src/preview/start.test.ts | 16 +- lib/core-client/src/preview/start.ts | 8 +- 6 files changed, 221 insertions(+), 168 deletions(-) create mode 100644 lib/client-api/src/StoryStoreFacade.ts diff --git a/lib/client-api/src/ClientApi.test.ts b/lib/client-api/src/ClientApi.test.ts index 9e52caaac91..e7a64b67d05 100644 --- a/lib/client-api/src/ClientApi.test.ts +++ b/lib/client-api/src/ClientApi.test.ts @@ -1,5 +1,5 @@ import addons, { mockChannel } from '@storybook/addons'; -import ClientApi from './ClientApi'; +import { ClientApi } from './ClientApi'; beforeEach(() => { addons.setChannel(mockChannel()); @@ -96,7 +96,7 @@ describe('ClientApi', () => { }); }); - describe('getStoriesList', () => { + describe('fetchStoryIndex', () => { it('should remember the order that files were added in', async () => { const clientApi = new ClientApi(); const store = { @@ -124,14 +124,14 @@ describe('ClientApi', () => { clientApi.storiesOf('kind1', (module1 as unknown) as NodeModule).add('story1', jest.fn()); clientApi.storiesOf('kind2', (module2 as unknown) as NodeModule).add('story2', jest.fn()); - expect(Object.keys(clientApi.getStoriesList().stories)).toEqual([ + expect(Object.keys(clientApi.fetchStoryIndex().stories)).toEqual([ 'kind1--story1', 'kind2--story2', ]); disposeCallback(); clientApi.storiesOf('kind1', (module1 as unknown) as NodeModule).add('story1', jest.fn()); - expect(Object.keys(clientApi.getStoriesList().stories)).toEqual([ + expect(Object.keys(clientApi.fetchStoryIndex().stories)).toEqual([ 'kind1--story1', 'kind2--story2', ]); diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index de9394b188b..e6da877a478 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -34,7 +34,7 @@ import { } from '@storybook/store'; import { ClientApiAddons, StoryApi, Comparator } from '@storybook/addons'; -import { storySort } from './storySort'; +import { StoryStoreFacade } from './StoryStoreFacade'; const { FEATURES } = global; @@ -124,102 +124,45 @@ export const addArgTypesEnhancer = (enhancer: ArgTypesEnhancer) => export const getGlobalRender = () => { checkMethod('getGlobalRender', false); - return singleton.projectAnnotations.render; + return singleton.facade.projectAnnotations.render; }; export const setGlobalRender = (render: StoryFn) => { checkMethod('setGlobalRender', false); - singleton.projectAnnotations.render = render; + singleton.facade.projectAnnotations.render = render; }; const invalidStoryTypes = new Set(['string', 'number', 'boolean', 'symbol']); -export default class ClientApi { - projectAnnotations: NormalizedProjectAnnotations; +export class ClientApi { + facade: StoryStoreFacade; storyStore?: StoryStore; - onImportFnChanged?: ({ importFn }: { importFn: ModuleImportFn }) => void; - - private stories: StoryIndex['stories']; - - private csfExports: Record; - private addons: ClientApiAddons; + onImportFnChanged?: ({ importFn }: { importFn: ModuleImportFn }) => void; + // If we don't get passed modules so don't know filenames, we can // just use numeric indexes private lastFileName = 0; constructor() { - this.projectAnnotations = { - loaders: [], - decorators: [], - parameters: {}, - argsEnhancers: [], - argTypesEnhancers: [], - }; - - this.stories = {}; - - this.csfExports = {}; + this.facade = new StoryStoreFacade(); this.addons = {}; singleton = this; } - // This doesn't actually import anything because the client-api loads fully - // on startup, but this is a shim after all. importFn(path: Path) { - return this.csfExports[path]; + return this.facade.importFn(path); } - getStoryIndex() { - const fileNameOrder = Object.keys(this.csfExports); - const storySortParameter = this.projectAnnotations.parameters?.options?.storySort; - - const storyEntries = Object.entries(this.stories); - // Add the kind parameters and global parameters to each entry - const stories: [StoryId, Story, Parameters, Parameters][] = storyEntries.map( - ([storyId, { importPath }]) => { - const exports = this.csfExports[importPath]; - const csfFile = this.storyStore.processCSFFileWithCache( - exports, - exports.default.title - ); - return [ - storyId, - this.storyStore.storyFromCSFFile({ storyId, csfFile }), - csfFile.meta.parameters, - this.projectAnnotations.parameters, - ]; - } - ); - - if (storySortParameter) { - let sortFn: Comparator; - if (typeof storySortParameter === 'function') { - sortFn = storySortParameter; - } else { - sortFn = storySort(storySortParameter); - } - stable.inplace(stories, sortFn); - } else { - stable.inplace( - stories, - (s1, s2) => - fileNameOrder.indexOf(s1[1].parameters.fileName) - - fileNameOrder.indexOf(s2[1].parameters.fileName) - ); + fetchStoryIndex() { + if (!this.storyStore) { + throw new Error('Cannot fetch story index before setting storyStore'); } - - return { - v: 3, - stories: stories.reduce((acc, [id]) => { - acc[id] = this.stories[id]; - return acc; - }, {} as StoryIndex['stories']), - }; + return this.facade.fetchStoryIndex(this.storyStore); } setAddon = deprecate( @@ -234,12 +177,12 @@ export default class ClientApi { ); addDecorator = (decorator: DecoratorFunction) => { - this.projectAnnotations.decorators.push(decorator); + this.facade.projectAnnotations.decorators.push(decorator); }; clearDecorators = deprecate( () => { - this.projectAnnotations.decorators = []; + this.facade.projectAnnotations.decorators = []; }, dedent` \`clearDecorators\` is deprecated and will be removed in Storybook 7.0. @@ -253,28 +196,28 @@ export default class ClientApi { globalTypes, ...parameters }: Parameters & { globals?: Globals; globalTypes?: GlobalTypes }) => { - this.projectAnnotations.parameters = combineParameters( - this.projectAnnotations.parameters, + this.facade.projectAnnotations.parameters = combineParameters( + this.facade.projectAnnotations.parameters, parameters ); if (globals) { - this.projectAnnotations.globals = globals; + this.facade.projectAnnotations.globals = globals; } if (globalTypes) { - this.projectAnnotations.globalTypes = normalizeInputTypes(globalTypes); + this.facade.projectAnnotations.globalTypes = normalizeInputTypes(globalTypes); } }; addLoader = (loader: LoaderFunction) => { - this.projectAnnotations.loaders.push(loader); + this.facade.projectAnnotations.loaders.push(loader); }; addArgsEnhancer = (enhancer: ArgsEnhancer) => { - this.projectAnnotations.argsEnhancers.push(enhancer); + this.facade.projectAnnotations.argsEnhancers.push(enhancer); }; addArgTypesEnhancer = (enhancer: ArgTypesEnhancer) => { - this.projectAnnotations.argTypesEnhancers.push(enhancer); + this.facade.projectAnnotations.argTypesEnhancers.push(enhancer); }; // what are the occasions that "m" is a boolean vs an obj @@ -306,7 +249,10 @@ export default class ClientApi { // Deal with `storiesOf()` being called twice in the same file. // On HMR, `this.csfExports[fileName]` will be reset to `{}`, so an empty object is due // to this export, not a second call of `storiesOf()`. - while (this.csfExports[fileName] && Object.keys(this.csfExports[fileName]).length > 0) { + while ( + this.facade.csfExports[fileName] && + Object.keys(this.facade.csfExports[fileName]).length > 0 + ) { i += 1; fileName = `${baseFilename}-${i}`; } @@ -316,7 +262,7 @@ export default class ClientApi { // itself automatically without us needing to look at our imports m.hot.accept(); m.hot.dispose(() => { - this.clearFilenameExports(fileName); + this.facade.clearFilenameExports(fileName); // We need to update the importFn as soon as the module re-evaluates // (and calls storiesOf() again, etc). We could call `onImportFnChanged()` @@ -355,7 +301,7 @@ export default class ClientApi { parameters: {}, }; // We map these back to a simple default export, even though we have type guarantees at this point - this.csfExports[fileName] = { default: meta }; + this.facade.csfExports[fileName] = { default: meta }; api.add = (storyName: string, storyFn: StoryFn, parameters: Parameters = {}) => { hasAdded = true; @@ -372,7 +318,7 @@ export default class ClientApi { const { decorators, loaders, ...storyParameters } = parameters; - const csfExports = this.csfExports[fileName]; + const csfExports = this.facade.csfExports[fileName]; // Whack a _ on the front incase it is "default" csfExports[`_${sanitize(storyName)}`] = { name: storyName, @@ -383,7 +329,7 @@ export default class ClientApi { }; const storyId = parameters?.__id || toId(kind, storyName); - this.stories[storyId] = { + this.facade.stories[storyId] = { title: csfExports.default.title, name: storyName, importPath: fileName, @@ -420,76 +366,11 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m return api; }; - clearFilenameExports(fileName: Path) { - if (!this.csfExports[fileName]) { - return; - } - - // Clear this module's stories from the storyList and existing exports - Object.entries(this.stories).forEach(([id, { importPath }]) => { - if (importPath === fileName) { - delete this.stories[id]; - } - }); - - // We keep this as an empty record so we can use it to maintain component order - this.csfExports[fileName] = {}; - } - - // NOTE: we could potentially share some of this code with the stories.json generation - addStoriesFromExports(fileName: Path, fileExports: ModuleExports) { - // if the export haven't changed since last time we added them, this is a no-op - if (this.csfExports[fileName] === fileExports) { - return; - } - // OTOH, if they have changed, let's clear them out first - this.clearFilenameExports(fileName); - - const { default: defaultExport, __namedExportsOrder, ...namedExports } = fileExports; - const { id: componentId, title } = defaultExport || {}; - if (!title) { - throw new Error( - `Unexpected default export without title in '${fileName}': ${JSON.stringify( - fileExports.default - )}` - ); - } - - this.csfExports[fileName] = { - ...fileExports, - default: { - ...defaultExport, - parameters: { - fileName, - ...defaultExport.parameters, - }, - }, - }; - - Object.entries(namedExports) - .filter(([key]) => isExportStory(key, defaultExport)) - .forEach(([key, storyExport]: [string, any]) => { - const exportName = storyNameFromExport(key); - const id = storyExport.parameters?.__id || toId(componentId || title, exportName); - const name = - (typeof storyExport !== 'function' && storyExport.name) || - storyExport.storyName || - storyExport.story?.name || - exportName; - - this.stories[id] = { - name, - title, - importPath: fileName, - }; - }); - } - getStorybook = (): GetStorybookKind[] => { - const storiesList = this.getStoryIndex(); + const { stories } = this.storyStore.storyIndex; const kinds: Record> = {}; - Object.entries(storiesList.stories).forEach(([storyId, { title, name, importPath }]) => { + Object.entries(stories).forEach(([storyId, { title, name, importPath }]) => { if (!kinds[title]) { kinds[title] = { kind: title, fileName: importPath, stories: [] }; } diff --git a/lib/client-api/src/StoryStoreFacade.ts b/lib/client-api/src/StoryStoreFacade.ts new file mode 100644 index 00000000000..7356e84481d --- /dev/null +++ b/lib/client-api/src/StoryStoreFacade.ts @@ -0,0 +1,171 @@ +import global from 'global'; +import stable from 'stable'; +import { + StoryId, + AnyFramework, + toId, + isExportStory, + Parameters, + StoryFn, + storyNameFromExport, +} from '@storybook/csf'; +import { + NormalizedProjectAnnotations, + Path, + StoryIndex, + ModuleExports, + StoryStore, + Story, +} from '@storybook/store'; +import { Comparator } from '@storybook/addons'; + +import { storySort } from './storySort'; + +export interface GetStorybookStory { + name: string; + render: StoryFn; +} + +export interface GetStorybookKind { + kind: string; + fileName: string; + stories: GetStorybookStory[]; +} + +export class StoryStoreFacade { + projectAnnotations: NormalizedProjectAnnotations; + + stories: StoryIndex['stories']; + + csfExports: Record; + + constructor() { + this.projectAnnotations = { + loaders: [], + decorators: [], + parameters: {}, + argsEnhancers: [], + argTypesEnhancers: [], + }; + + this.stories = {}; + + this.csfExports = {}; + } + + // This doesn't actually import anything because the client-api loads fully + // on startup, but this is a shim after all. + importFn(path: Path) { + return this.csfExports[path]; + } + + fetchStoryIndex(store: StoryStore) { + const fileNameOrder = Object.keys(this.csfExports); + const storySortParameter = this.projectAnnotations.parameters?.options?.storySort; + + const storyEntries = Object.entries(this.stories); + // Add the kind parameters and global parameters to each entry + const stories: [StoryId, Story, Parameters, Parameters][] = storyEntries.map( + ([storyId, { importPath }]) => { + const exports = this.csfExports[importPath]; + const csfFile = store.processCSFFileWithCache(exports, exports.default.title); + return [ + storyId, + store.storyFromCSFFile({ storyId, csfFile }), + csfFile.meta.parameters, + this.projectAnnotations.parameters, + ]; + } + ); + + if (storySortParameter) { + let sortFn: Comparator; + if (typeof storySortParameter === 'function') { + sortFn = storySortParameter; + } else { + sortFn = storySort(storySortParameter); + } + stable.inplace(stories, sortFn); + } else { + stable.inplace( + stories, + (s1, s2) => + fileNameOrder.indexOf(s1[1].parameters.fileName) - + fileNameOrder.indexOf(s2[1].parameters.fileName) + ); + } + + return { + v: 3, + stories: stories.reduce((acc, [id]) => { + acc[id] = this.stories[id]; + return acc; + }, {} as StoryIndex['stories']), + }; + } + + clearFilenameExports(fileName: Path) { + if (!this.csfExports[fileName]) { + return; + } + + // Clear this module's stories from the storyList and existing exports + Object.entries(this.stories).forEach(([id, { importPath }]) => { + if (importPath === fileName) { + delete this.stories[id]; + } + }); + + // We keep this as an empty record so we can use it to maintain component order + this.csfExports[fileName] = {}; + } + + // NOTE: we could potentially share some of this code with the stories.json generation + addStoriesFromExports(fileName: Path, fileExports: ModuleExports) { + // if the export haven't changed since last time we added them, this is a no-op + if (this.csfExports[fileName] === fileExports) { + return; + } + // OTOH, if they have changed, let's clear them out first + this.clearFilenameExports(fileName); + + const { default: defaultExport, __namedExportsOrder, ...namedExports } = fileExports; + const { id: componentId, title } = defaultExport || {}; + if (!title) { + throw new Error( + `Unexpected default export without title in '${fileName}': ${JSON.stringify( + fileExports.default + )}` + ); + } + + this.csfExports[fileName] = { + ...fileExports, + default: { + ...defaultExport, + parameters: { + fileName, + ...defaultExport.parameters, + }, + }, + }; + + Object.entries(namedExports) + .filter(([key]) => isExportStory(key, defaultExport)) + .forEach(([key, storyExport]: [string, any]) => { + const exportName = storyNameFromExport(key); + const id = storyExport.parameters?.__id || toId(componentId || title, exportName); + const name = + (typeof storyExport !== 'function' && storyExport.name) || + storyExport.storyName || + storyExport.story?.name || + exportName; + + this.stories[id] = { + name, + title, + importPath: fileName, + }; + }); + } +} diff --git a/lib/client-api/src/index.ts b/lib/client-api/src/index.ts index 6107177e0e7..512bf6f64ac 100644 --- a/lib/client-api/src/index.ts +++ b/lib/client-api/src/index.ts @@ -1,4 +1,5 @@ -import ClientApi, { +import { + ClientApi, addDecorator, addParameters, addLoader, diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index bdc03b531e8..b3051ad6ea5 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -5,7 +5,6 @@ import { waitForEvents, emitter, mockChannel, - // eslint-disable-next-line import/extensions } from '@storybook/preview-web/dist/cjs/PreviewWeb.mockdata'; import { start } from './start'; @@ -990,15 +989,17 @@ describe('start', () => { // These tests need to be in here, as they require a convoluted hookup between // a ClientApi and a StoryStore describe('ClientApi.getStorybook', () => { - it('should transform the storybook to an array with filenames', async () => { + it('should transform the storybook to an array with filenames, empty', () => { const { configure, clientApi } = start(jest.fn()); - let book; + configure('test', () => {}); + expect(clientApi.getStorybook()).toEqual([]); + }); - book = clientApi.getStorybook(); - expect(book).toEqual([]); + it('should transform the storybook to an array with filenames, full', () => { + const { configure, clientApi } = start(jest.fn()); - await configure('test', () => { + configure('test', () => { clientApi .storiesOf('kind 1', { id: 'file1' } as any) .add('name 1', () => '1') @@ -1009,9 +1010,8 @@ describe('start', () => { .add('name 1', () => '1') .add('name 2', () => '2'); }); - book = clientApi.getStorybook(); - expect(book).toEqual([ + expect(clientApi.getStorybook()).toEqual([ expect.objectContaining({ fileName: expect.any(String), kind: 'kind 1', diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 8e95d68d3d6..4a87b15cbcd 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -50,15 +50,15 @@ export function start( const { added, removed } = executeLoadableForChanges(loadable, m); Array.from(added.entries()).forEach(([fileName, fileExports]) => - clientApi.addStoriesFromExports(fileName, fileExports) + clientApi.facade.addStoriesFromExports(fileName, fileExports) ); Array.from(removed.entries()).forEach(([fileName]) => - clientApi.clearFilenameExports(fileName) + clientApi.facade.clearFilenameExports(fileName) ); return { - ...clientApi.projectAnnotations, + ...clientApi.facade.projectAnnotations, render, renderToDOM, applyDecorators: decorateStory, @@ -69,7 +69,7 @@ export function start( preview = new PreviewWeb({ importFn: (path: Path) => clientApi.importFn(path), getProjectAnnotations, - fetchStoryIndex: () => clientApi.getStoryIndex(), + fetchStoryIndex: () => clientApi.fetchStoryIndex(), }); if (globalWindow) { // eslint-disable-next-line no-underscore-dangle From 7d45c074a40f62eb2d96c9430793d986f3377ecd Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 16:07:04 +1000 Subject: [PATCH 203/285] Add a "back-compat" API for `__STORYBOOK_CLIENT_API` (Although it isn't backwards compatible, as it requires you call `cacheAllCSFFiles()` first) --- .../preview/virtualModuleModernEntry.js.handlebars | 2 ++ .../preview/virtualModuleModernEntry.js.handlebars | 2 ++ lib/client-api/src/ClientApi.ts | 14 ++++---------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index 8bc5e77d568..de95beac236 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -1,4 +1,5 @@ import { composeConfigs, PreviewWeb } from '@storybook/preview-web'; +import { ClientApi } from '@storybook/client-api'; import { importFn } from './{{storiesFilename}}'; import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; @@ -24,6 +25,7 @@ const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoryInde window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; window.__STORYBOOK_ADDONS_CHANNEL__ = channel; +window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore }); preview.initialize(); diff --git a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars index 12823e4c07a..ad889eb0b46 100644 --- a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars @@ -1,4 +1,5 @@ import { composeConfigs, PreviewWeb } from '@storybook/preview-web'; +import { ClientApi } from '@storybook/client-api'; import { importFn } from './{{storiesFilename}}'; import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; @@ -23,6 +24,7 @@ const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoryInde window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; window.__STORYBOOK_ADDONS_CHANNEL__ = channel; +window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore }); preview.initialize(); diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index e6da877a478..b4c824a520b 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -1,13 +1,10 @@ import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; import global from 'global'; -import stable from 'stable'; import { logger } from '@storybook/client-logger'; import { - StoryId, AnyFramework, toId, - isExportStory, DecoratorFunction, Parameters, ArgTypesEnhancer, @@ -15,24 +12,19 @@ import { LoaderFunction, StoryFn, sanitize, - storyNameFromExport, ComponentTitle, Globals, GlobalTypes, } from '@storybook/csf'; import { NormalizedComponentAnnotations, - NormalizedProjectAnnotations, Path, - StoryIndex, - ModuleExports, ModuleImportFn, combineParameters, StoryStore, normalizeInputTypes, - Story, } from '@storybook/store'; -import { ClientApiAddons, StoryApi, Comparator } from '@storybook/addons'; +import { ClientApiAddons, StoryApi } from '@storybook/addons'; import { StoryStoreFacade } from './StoryStoreFacade'; @@ -146,11 +138,13 @@ export class ClientApi { // just use numeric indexes private lastFileName = 0; - constructor() { + constructor({ storyStore }: { storyStore?: StoryStore } = {}) { this.facade = new StoryStoreFacade(); this.addons = {}; + this.storyStore = storyStore; + singleton = this; } From 1f9e6ad3d4cafd6234c009f13a7b0239103eb04f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 16:07:35 +1000 Subject: [PATCH 204/285] Cleanup --- .../preview/virtualModuleModernEntry.js.handlebars | 6 ++++-- .../preview/virtualModuleModernEntry.js.handlebars | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index de95beac236..d10128be22b 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -1,9 +1,11 @@ +import fetch from 'unfetch'; + import { composeConfigs, PreviewWeb } from '@storybook/preview-web'; import { ClientApi } from '@storybook/client-api'; -import { importFn } from './{{storiesFilename}}'; import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; -import fetch from 'unfetch'; + +import { importFn } from './{{storiesFilename}}'; const getProjectAnnotations = () => composeConfigs([ diff --git a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars index ad889eb0b46..7c4d3ab6d5a 100644 --- a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars @@ -1,9 +1,12 @@ +import fetch from 'unfetch'; + import { composeConfigs, PreviewWeb } from '@storybook/preview-web'; import { ClientApi } from '@storybook/client-api'; -import { importFn } from './{{storiesFilename}}'; import { addons } from '@storybook/addons'; import createChannel from '@storybook/channel-postmessage'; -import fetch from 'unfetch'; + +import { importFn } from './{{storiesFilename}}'; + const getProjectAnnotations = () => composeConfigs([ @@ -19,6 +22,7 @@ const fetchStoryIndex = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); + const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoryIndex }); window.__STORYBOOK_PREVIEW__ = preview; @@ -30,15 +34,11 @@ preview.initialize(); if (module.hot) { module.hot.accept('./{{storiesFilename}}', () => { - console.log('configEntry HMR accept storybook-stories.js'); - console.log(arguments); // importFn has changed so we need to patch the new one in preview.onImportFnChanged({ importFn }); }); module.hot.accept([{{#each configs}}'{{this}}',{{/each}}], () => { - console.log('configEntry HMR accept config file'); - console.log(arguments); // getProjectAnnotations has changed so we need to patch the new one in preview.onGetProjectAnnotationsChanged({ getProjectAnnotations }); }); From 8d320c2cdd17e46103ccc970b80b30922ba831b6 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 16:11:33 +1000 Subject: [PATCH 205/285] Deal with initial preview error --- lib/preview-web/src/PreviewWeb.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 3df3b65135a..6cb3887e25e 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -67,10 +67,7 @@ export class PreviewWeb { this.channel = addons.getChannel(); this.view = new WebView(); - const projectAnnotations = this.getProjectAnnotationsOrRenderError(getProjectAnnotations); - if (!projectAnnotations) { - return; - } + const projectAnnotations = this.getProjectAnnotationsOrRenderError(getProjectAnnotations) || {}; this.urlStore = new UrlStore(); this.storyStore = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); From 306029b6d1356860271a81615171d738c1a6d3fb Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 16:31:59 +1000 Subject: [PATCH 206/285] Add async-ness to Story+ArgsTable blocks --- addons/docs/src/blocks/ArgsTable.tsx | 18 +++++++++--------- addons/docs/src/blocks/Story.tsx | 17 ++++++++++------- addons/docs/src/blocks/useStory.ts | 18 ++++++++++++++++++ lib/preview-web/src/PreviewWeb.tsx | 1 + lib/preview-web/src/types.ts | 3 ++- 5 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 addons/docs/src/blocks/useStory.ts diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index 214b84e937f..838bd0d356b 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -17,6 +17,7 @@ import { Component, CURRENT_SELECTION, PRIMARY_STORY } from './types'; import { getComponentName } from './utils'; import { ArgTypesExtractor } from '../lib/docgen/types'; import { lookupStoryId } from './Story'; +import { useStory } from './useStory'; interface BaseProps { include?: PropDescriptor; @@ -141,41 +142,40 @@ export const StoryTable: FC< exclude, sort, } = props; - const { argTypes, parameters } = storyById(currentId); - let storyArgTypes: StrictArgTypes; try { let storyId; switch (storyName) { case CURRENT_SELECTION: { storyId = currentId; - storyArgTypes = argTypes; break; } case PRIMARY_STORY: { const primaryStory = componentStories()[0]; storyId = primaryStory.id; - storyArgTypes = primaryStory.argTypes; break; } default: { storyId = lookupStoryId(storyName, context); - storyArgTypes = storyById(storyId).argTypes; } } - storyArgTypes = filterArgTypes(storyArgTypes, include, exclude); + const story = useStory(storyId, context); + if (!story) { + return

; + } + + const argTypes = filterArgTypes(story.argTypes, include, exclude); const mainLabel = getComponentName(component) || 'Story'; // eslint-disable-next-line prefer-const let [args, updateArgs, resetArgs] = useArgs(storyId, context); - let tabs = { [mainLabel]: { rows: storyArgTypes, args, updateArgs, resetArgs } } as Record< + let tabs = { [mainLabel]: { rows: argTypes, args, updateArgs, resetArgs } } as Record< string, PureArgsTableProps >; // Use the dynamically generated component tabs if there are no controls - const storyHasArgsWithControls = - storyArgTypes && Object.values(storyArgTypes).find((v) => !!v?.control); + const storyHasArgsWithControls = argTypes && Object.values(argTypes).find((v) => !!v?.control); if (!storyHasArgsWithControls) { updateArgs = null; diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 044d5cf188a..a99c04418c9 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -12,9 +12,10 @@ import { resetComponents, Story as PureStory } from '@storybook/components'; import { toId, storyNameFromExport, StoryAnnotations, AnyFramework } from '@storybook/csf'; import { Story as StoryType } from '@storybook/store'; import global from 'global'; -import { CURRENT_SELECTION } from './types'; +import { CURRENT_SELECTION } from './types'; import { DocsContext, DocsContextProps } from './DocsContext'; +import { useStory } from './useStory'; export const storyBlockIdFromId = (storyId: string) => `story--${storyId}`; @@ -54,13 +55,11 @@ export const lookupStoryId = ( storyNameFromExport(mdxStoryNameToKey[storyName]) ); -// TODO -- this can be async -export const getStory = (props: StoryProps, context: DocsContextProps): StoryType => { +export const getStoryId = (props: StoryProps, context: DocsContextProps): StoryId => { const { id } = props as StoryRefProps; const { name } = props as StoryDefProps; const inputId = id === CURRENT_SELECTION ? context.id : id; - const previewId = inputId || lookupStoryId(name, context); - return context.storyById(previewId); + return inputId || lookupStoryId(name, context); }; export const getStoryProps = ( @@ -95,7 +94,6 @@ export const getStoryProps = ( ); } - // TODO -- loaders ? const boundStoryFn = () => story.unboundStoryFn({ ...context.getStoryContext(story), @@ -114,7 +112,12 @@ export const getStoryProps = ( const Story: FunctionComponent = (props) => { const context = useContext(DocsContext); const ref = useRef(); - const story = getStory(props, context); + const story = useStory(getStoryId(props, context), context); + + if (!story) { + return
Loading...
; + } + const { componentId, id, title, name } = story; const renderContext = { componentId, diff --git a/addons/docs/src/blocks/useStory.ts b/addons/docs/src/blocks/useStory.ts new file mode 100644 index 00000000000..6c785247fe9 --- /dev/null +++ b/addons/docs/src/blocks/useStory.ts @@ -0,0 +1,18 @@ +import { useState, useEffect } from 'react'; +import { StoryId, AnyFramework } from '@storybook/csf'; +import { Story } from '@storybook/store'; + +import { DocsContextProps } from './DocsContext'; + +export function useStory( + storyId: StoryId, + context: DocsContextProps +): Story | void { + const [story, setStory] = useState(null); + + useEffect(() => { + context.loadStory(storyId).then((s) => setStory(s)); + }); + + return story; +} diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 6cb3887e25e..4475e7354b5 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -310,6 +310,7 @@ export class PreviewWeb { // NOTE: these two functions are *sync* so cannot access stories from other CSF files storyById: (storyId: StoryId) => this.storyStore.storyFromCSFFile({ storyId, csfFile }), componentStories: () => this.storyStore.componentStoriesFromCSFFile({ csfFile }), + loadStory: (storyId: StoryId) => this.storyStore.loadStory({ storyId }), renderStoryToElement: this.renderStoryToElement.bind(this), getStoryContext: (renderedStory: Story) => ({ diff --git a/lib/preview-web/src/types.ts b/lib/preview-web/src/types.ts index b56056b88b8..db389e2518a 100644 --- a/lib/preview-web/src/types.ts +++ b/lib/preview-web/src/types.ts @@ -1,5 +1,5 @@ import { StoryId, AnyFramework, ProjectAnnotations, StoryContextForLoaders } from '@storybook/csf'; -import { RenderContext, DecoratorApplicator, Story } from '@storybook/store'; +import { RenderContext, Story } from '@storybook/store'; import { PreviewWeb } from './PreviewWeb'; export type WebProjectAnnotations< @@ -14,6 +14,7 @@ export interface DocsContextProps { name: string; storyById: (id: StoryId) => Story; componentStories: () => Story[]; + loadStory: (id: StoryId) => Promise>; renderStoryToElement: PreviewWeb['renderStoryToElement']; getStoryContext: (story: Story) => StoryContextForLoaders; From c2236dabf9f322f197d8840408e8d5cf8754900b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 17:00:30 +1000 Subject: [PATCH 207/285] Update CSF version (projectAnnotations) --- addons/a11y/package.json | 2 +- addons/actions/package.json | 2 +- addons/backgrounds/package.json | 2 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/links/package.json | 2 +- addons/measure/package.json | 2 +- addons/outline/package.json | 2 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 2 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 2 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 2 +- lib/addons/package.json | 2 +- lib/api/package.json | 2 +- lib/client-api/package.json | 2 +- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/preview-web/package.json | 2 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- yarn.lock | 64 +++++++++---------- 29 files changed, 61 insertions(+), 61 deletions(-) diff --git a/addons/a11y/package.json b/addons/a11y/package.json index 0c3ed830aa9..dd1af2aa2e3 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/theming": "6.4.0-alpha.19", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/actions/package.json b/addons/actions/package.json index 3367b790cfc..faa3f350045 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index 7c65b2c406a..375cdb98a57 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,7 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/controls/package.json b/addons/controls/package.json index db41b7c38a1..09cb18354b5 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", diff --git a/addons/docs/package.json b/addons/docs/package.json index 7d1464c897a..0f9534fda12 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/postinstall": "6.4.0-alpha.19", diff --git a/addons/links/package.json b/addons/links/package.json index d74a14b2e3d..f2c869bf668 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/router": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/measure/package.json b/addons/measure/package.json index 8fc96799a9a..53b9e23e6ce 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,7 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/outline/package.json b/addons/outline/package.json index 1201b1d0316..124c1034a41 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,7 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/components": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index 6768b1e680d..f2421e48aac 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-client": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index 3d4a0c8dbb5..b73e4356e14 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.19", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index e561d309a3b..ac9894592e7 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index f37ccc36647..14f0b20ac51 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/app/preact/package.json b/app/preact/package.json index 595ade0f848..cdc688138a0 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/react/package.json b/app/react/package.json index 35d6dd8f6a9..fd8f2f9ba8c 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index 6a93519e620..132d381c614 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,7 +50,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.19", "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", diff --git a/app/svelte/package.json b/app/svelte/package.json index 2cb25b7d64a..58ca0adb998 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/store": "6.4.0-alpha.19", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index 11146320856..74ab366511b 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index f75b83583ec..38433ed18b8 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index 879e91de2ca..48e94e2d8cf 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/core": "6.4.0-alpha.19", "@storybook/core-common": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@types/webpack-env": "^1.16.0", diff --git a/lib/addons/package.json b/lib/addons/package.json index 6cfe677c096..ed4d1a591a5 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/theming": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/api/package.json b/lib/api/package.json index 69920e50e4e..d361046c27f 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/router": "6.4.0-alpha.19", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.19", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index 3e22e9ec963..39de6bfb7ec 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -46,7 +46,7 @@ "@storybook/channels": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/store": "6.4.0-alpha.19", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index 6756446cfc2..a07cefff784 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/csf-tools": "6.4.0-alpha.19", "@storybook/node-logger": "6.4.0-alpha.19", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index 1def354ade7..74b23fec607 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/theming": "6.4.0-alpha.19", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index c89bfe6eadd..48141b40474 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/preview-web": "6.4.0-alpha.19", "@storybook/store": "6.4.0-alpha.19", "@storybook/ui": "6.4.0-alpha.19", diff --git a/lib/preview-web/package.json b/lib/preview-web/package.json index 339812745ca..59314f638dc 100644 --- a/lib/preview-web/package.json +++ b/lib/preview-web/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/store": "6.4.0-alpha.19", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index bdda82ac19f..7adf6135ded 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index 04645d4c16e..cb829330a62 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -43,7 +43,7 @@ "@storybook/addons": "6.4.0-alpha.19", "@storybook/client-logger": "6.4.0-alpha.19", "@storybook/core-events": "6.4.0-alpha.19", - "@storybook/csf": "0.0.2--canary.d61cd6c.0", + "@storybook/csf": "0.0.2--canary.a925d24.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/yarn.lock b/yarn.lock index 1f322727ff9..bc1271455da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5536,7 +5536,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/theming": 6.4.0-alpha.19 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -5567,7 +5567,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/theming": 6.4.0-alpha.19 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -5602,7 +5602,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/theming": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -5630,7 +5630,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 @@ -5673,7 +5673,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/postinstall": 6.4.0-alpha.19 @@ -5857,7 +5857,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/router": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -5887,7 +5887,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -5911,7 +5911,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/components": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -5946,7 +5946,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.19 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -5976,7 +5976,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-client": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/react": 6.4.0-alpha.19 "@storybook/vue": 6.4.0-alpha.19 "@storybook/vue3": 6.4.0-alpha.19 @@ -6139,7 +6139,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/theming": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6172,7 +6172,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@types/autoprefixer": ^9.7.2 @@ -6241,7 +6241,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/router": 6.4.0-alpha.19 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.19 @@ -6524,7 +6524,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/store": 6.4.0-alpha.19 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -6560,7 +6560,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/csf-tools": 6.4.0-alpha.19 "@storybook/node-logger": 6.4.0-alpha.19 core-js: ^3.8.2 @@ -6582,7 +6582,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/theming": 6.4.0-alpha.19 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -6621,7 +6621,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/preview-web": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@storybook/ui": 6.4.0-alpha.19 @@ -6820,12 +6820,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.d61cd6c.0": - version: 0.0.2--canary.d61cd6c.0 - resolution: "@storybook/csf@npm:0.0.2--canary.d61cd6c.0" +"@storybook/csf@npm:0.0.2--canary.a925d24.0": + version: 0.0.2--canary.a925d24.0 + resolution: "@storybook/csf@npm:0.0.2--canary.a925d24.0" dependencies: lodash: ^4.17.15 - checksum: 0423e195692b0f2063167fcc6a1a896af50aa3a02853e2f7cdf5bf7002613713476290e2a07c5543b0457cf3e21c7e0581274dce7a346a0322c7b12b61778078 + checksum: 28f528e874a0db0e5d9a1c548969a0c0d92d90b044eda495eb25afa5f76be483bef8310d77cc19106ed22d4d00b39e9b3e63eee2d0fbec0596446389768612a0 languageName: node linkType: hard @@ -6962,7 +6962,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/preview-web": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 @@ -7164,7 +7164,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7224,7 +7224,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/store": 6.4.0-alpha.19 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -7270,7 +7270,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -7568,7 +7568,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.19 "@storybook/preview-web": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 @@ -7597,7 +7597,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -7618,7 +7618,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/client-logger": 6.4.0-alpha.19 "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -7637,7 +7637,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7737,7 +7737,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -7774,7 +7774,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/store": 6.4.0-alpha.19 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -7817,7 +7817,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.19 "@storybook/core": 6.4.0-alpha.19 "@storybook/core-common": 6.4.0-alpha.19 - "@storybook/csf": 0.0.2--canary.d61cd6c.0 + "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/preview-web": 6.4.0-alpha.19 "@storybook/store": 6.4.0-alpha.19 "@types/webpack-env": ^1.16.0 From 6432f6cafea86f3e01fab356304ac099dee20d81 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 17:12:32 +1000 Subject: [PATCH 208/285] Fix bootstrap --- addons/docs/src/blocks/Story.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index a99c04418c9..0f1f89d902f 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -9,7 +9,7 @@ import React, { } from 'react'; import { MDXProvider } from '@mdx-js/react'; import { resetComponents, Story as PureStory } from '@storybook/components'; -import { toId, storyNameFromExport, StoryAnnotations, AnyFramework } from '@storybook/csf'; +import { StoryId, toId, storyNameFromExport, StoryAnnotations, AnyFramework } from '@storybook/csf'; import { Story as StoryType } from '@storybook/store'; import global from 'global'; From 5982475373a7a7beccacf9dc14b552e0208f4254 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 17:21:06 +1000 Subject: [PATCH 209/285] Deepscan cleanups --- addons/docs/src/blocks/ArgsTable.tsx | 2 +- addons/docs/src/blocks/Source.tsx | 1 - addons/docs/src/blocks/Story.tsx | 11 ----------- .../src/frameworks/common/enhanceArgTypes.test.ts | 2 +- addons/docs/src/frameworks/common/enhanceArgTypes.ts | 1 - addons/docs/src/frameworks/svelte/extractArgTypes.ts | 2 +- .../client/preview/angular-beta/StorybookModule.ts | 1 - app/html/src/client/preview/index.ts | 2 +- app/react/src/client/preview/index.tsx | 1 - app/svelte/src/client/preview/decorators.ts | 2 +- app/vue/src/client/preview/index.ts | 2 +- app/vue/src/client/preview/render.ts | 2 +- app/vue3/src/client/preview/index.ts | 10 ++-------- app/web-components/src/client/preview/render.ts | 2 +- lib/addons/src/hooks.ts | 1 - lib/client-api/src/ClientApi.ts | 3 ++- lib/client-api/src/StoryStoreFacade.ts | 1 - lib/core-client/src/preview/start.test.ts | 4 ++-- lib/preview-web/src/WebView.ts | 2 +- lib/store/src/normalizeStory.ts | 2 -- lib/store/src/processCSFFile.test.ts | 2 -- 21 files changed, 15 insertions(+), 41 deletions(-) diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index 838bd0d356b..7db03289d8e 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -132,7 +132,7 @@ export const StoryTable: FC< StoryProps & { component: Component; subcomponents: Record } > = (props) => { const context = useContext(DocsContext); - const { id: currentId, storyById, componentStories } = context; + const { id: currentId, componentStories } = context; const { story: storyName, component, diff --git a/addons/docs/src/blocks/Source.tsx b/addons/docs/src/blocks/Source.tsx index 51012163380..0b23310cd8f 100644 --- a/addons/docs/src/blocks/Source.tsx +++ b/addons/docs/src/blocks/Source.tsx @@ -5,7 +5,6 @@ import { SourceProps as PureSourceProps, } from '@storybook/components'; import { StoryId } from '@storybook/api'; -import { logger } from '@storybook/client-logger'; import { Story } from '@storybook/store'; import { DocsContext, DocsContextProps } from './DocsContext'; diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 0f1f89d902f..c99cefb80c2 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -67,17 +67,6 @@ export const getStoryProps = ( story: StoryType, context: DocsContextProps ): PureStoryProps => { - const defaultIframeHeight = 100; - - if (!story) { - return { - id: story.id, - inline: false, - height: height || defaultIframeHeight.toString(), - title: undefined, - }; - } - const { name: storyName, parameters } = story; const { docs = {} } = parameters; diff --git a/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts b/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts index 50a03e483df..43e0da96710 100644 --- a/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts +++ b/addons/docs/src/frameworks/common/enhanceArgTypes.test.ts @@ -1,4 +1,4 @@ -import { ArgType, ArgTypes } from '@storybook/api'; +import { ArgTypes } from '@storybook/api'; import { StrictInputType } from '@storybook/csf'; import { enhanceArgTypes } from './enhanceArgTypes'; diff --git a/addons/docs/src/frameworks/common/enhanceArgTypes.ts b/addons/docs/src/frameworks/common/enhanceArgTypes.ts index 80493bbcd03..540b80e56b4 100644 --- a/addons/docs/src/frameworks/common/enhanceArgTypes.ts +++ b/addons/docs/src/frameworks/common/enhanceArgTypes.ts @@ -1,4 +1,3 @@ -import mapValues from 'lodash/mapValues'; import { AnyFramework, StoryContextForEnhancers } from '@storybook/csf'; import { combineParameters } from '@storybook/store'; diff --git a/addons/docs/src/frameworks/svelte/extractArgTypes.ts b/addons/docs/src/frameworks/svelte/extractArgTypes.ts index e4b0dcdf581..ca1ee3e3152 100644 --- a/addons/docs/src/frameworks/svelte/extractArgTypes.ts +++ b/addons/docs/src/frameworks/svelte/extractArgTypes.ts @@ -1,4 +1,4 @@ -import { SBScalarType, SBType, StrictArgTypes } from '@storybook/csf'; +import { SBScalarType, StrictArgTypes } from '@storybook/csf'; import { logger } from '@storybook/client-logger'; import type { SvelteComponentDoc, diff --git a/app/angular/src/client/preview/angular-beta/StorybookModule.ts b/app/angular/src/client/preview/angular-beta/StorybookModule.ts index 67d851a6585..68c443375a8 100644 --- a/app/angular/src/client/preview/angular-beta/StorybookModule.ts +++ b/app/angular/src/client/preview/angular-beta/StorybookModule.ts @@ -5,7 +5,6 @@ import dedent from 'ts-dedent'; import { Subject } from 'rxjs'; import deprecate from 'util-deprecate'; import { ICollection, StoryFnAngularReturnType } from '../types'; -import { Parameters } from '../types-6-0'; import { storyPropsProvider } from './StorybookProvider'; import { isComponentAlreadyDeclaredInModules } from './utils/NgModulesAnalyzer'; import { isDeclarable } from './utils/NgComponentAnalyzer'; diff --git a/app/html/src/client/preview/index.ts b/app/html/src/client/preview/index.ts index e0fd7fdbdff..50450304f66 100644 --- a/app/html/src/client/preview/index.ts +++ b/app/html/src/client/preview/index.ts @@ -5,7 +5,7 @@ import { HtmlFramework } from './types-6-0'; import './globals'; import render from './render'; -import { StoryFnHtmlReturnType, IStorybookSection } from './types'; +import { IStorybookSection } from './types'; const framework = 'html'; diff --git a/app/react/src/client/preview/index.tsx b/app/react/src/client/preview/index.tsx index a00a8fd6a42..4f47993c671 100644 --- a/app/react/src/client/preview/index.tsx +++ b/app/react/src/client/preview/index.tsx @@ -1,5 +1,4 @@ /* eslint-disable prefer-destructuring */ -import React from 'react'; import { start } from '@storybook/core/client'; import { ClientStoryApi, Loadable } from '@storybook/addons'; diff --git a/app/svelte/src/client/preview/decorators.ts b/app/svelte/src/client/preview/decorators.ts index 71fbde66abb..f1ca5fa71f6 100644 --- a/app/svelte/src/client/preview/decorators.ts +++ b/app/svelte/src/client/preview/decorators.ts @@ -1,4 +1,4 @@ -import { StoryFn, DecoratorFunction, StoryContext, StoryContextUpdate } from '@storybook/csf'; +import { StoryFn, DecoratorFunction, StoryContext } from '@storybook/csf'; import { sanitizeStoryContextUpdate } from '@storybook/store'; import SlotDecorator from './SlotDecorator.svelte'; import { SvelteFramework } from './types'; diff --git a/app/vue/src/client/preview/index.ts b/app/vue/src/client/preview/index.ts index 52e98b3cfde..bf064f37553 100644 --- a/app/vue/src/client/preview/index.ts +++ b/app/vue/src/client/preview/index.ts @@ -1,7 +1,7 @@ /* eslint-disable prefer-destructuring */ import Vue, { VueConstructor, ComponentOptions } from 'vue'; import { start } from '@storybook/core/client'; -import { StoryFn, DecoratorFunction, StoryContext, StoryContextUpdate } from '@storybook/csf'; +import { StoryFn, DecoratorFunction, StoryContext } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import { sanitizeStoryContextUpdate } from '@storybook/store'; diff --git a/app/vue/src/client/preview/render.ts b/app/vue/src/client/preview/render.ts index 5da7594f79d..c1328c2719a 100644 --- a/app/vue/src/client/preview/render.ts +++ b/app/vue/src/client/preview/render.ts @@ -1,5 +1,5 @@ import dedent from 'ts-dedent'; -import Vue, { VNode } from 'vue'; +import Vue from 'vue'; import { RenderContext } from '@storybook/store'; import { VueFramework } from './types-6-0'; diff --git a/app/vue3/src/client/preview/index.ts b/app/vue3/src/client/preview/index.ts index 778fe899bc0..7c8fdac5e93 100644 --- a/app/vue3/src/client/preview/index.ts +++ b/app/vue3/src/client/preview/index.ts @@ -1,18 +1,12 @@ import type { ConcreteComponent, Component, ComponentOptions, App } from 'vue'; import { h } from 'vue'; import { start } from '@storybook/core/client'; -import { - StoryFn, - DecoratorFunction, - StoryContext, - StoryContextUpdate, - LegacyStoryFn, -} from '@storybook/csf'; +import { StoryFn, DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import { sanitizeStoryContextUpdate } from '@storybook/store'; import './globals'; -import { IStorybookSection, StoryFnVueReturnType } from './types'; +import { IStorybookSection } from './types'; import { VueFramework } from './types-6-0'; import render, { storybookApp } from './render'; diff --git a/app/web-components/src/client/preview/render.ts b/app/web-components/src/client/preview/render.ts index 1ee5b263792..3b4662c1ec8 100644 --- a/app/web-components/src/client/preview/render.ts +++ b/app/web-components/src/client/preview/render.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import global from 'global'; import dedent from 'ts-dedent'; -import { render, TemplateResult } from 'lit-html'; +import { render } from 'lit-html'; // Keep `.js` extension to avoid issue with Webpack (related to export map?) // eslint-disable-next-line import/extensions import { isTemplateResult } from 'lit-html/directive-helpers.js'; diff --git a/lib/addons/src/hooks.ts b/lib/addons/src/hooks.ts index 19d05e5ba85..f7710b9dbae 100644 --- a/lib/addons/src/hooks.ts +++ b/lib/addons/src/hooks.ts @@ -6,7 +6,6 @@ import { DecoratorApplicator, StoryContext, Args, - PartialStoryFn, LegacyStoryFn, } from '@storybook/csf'; import { diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index b4c824a520b..285f418c14a 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -322,7 +322,8 @@ export class ClientApi { render: storyFn, }; - const storyId = parameters?.__id || toId(kind, storyName); + // eslint-disable-next-line no-underscore-dangle + const storyId = parameters.__id || toId(kind, storyName); this.facade.stories[storyId] = { title: csfExports.default.title, name: storyName, diff --git a/lib/client-api/src/StoryStoreFacade.ts b/lib/client-api/src/StoryStoreFacade.ts index 7356e84481d..7ea75e432fd 100644 --- a/lib/client-api/src/StoryStoreFacade.ts +++ b/lib/client-api/src/StoryStoreFacade.ts @@ -1,4 +1,3 @@ -import global from 'global'; import stable from 'stable'; import { StoryId, diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index b3051ad6ea5..785eeb00bf5 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -1047,7 +1047,7 @@ describe('start', () => { const { configure, clientApi } = start(jest.fn()); const fn = jest.fn(); - await configure('test', () => { + configure('test', () => { clientApi.storiesOf('kind', { id: 'foo.js' } as NodeModule).add('name', fn); }); @@ -1071,7 +1071,7 @@ describe('start', () => { const { configure, clientApi } = start(jest.fn()); const fn = jest.fn(); - await configure('test', () => { + configure('test', () => { clientApi.storiesOf('kind', { id: 1211 } as any).add('name', fn); }); diff --git a/lib/preview-web/src/WebView.ts b/lib/preview-web/src/WebView.ts index a8b404fae4c..5938b581afd 100644 --- a/lib/preview-web/src/WebView.ts +++ b/lib/preview-web/src/WebView.ts @@ -5,7 +5,7 @@ import dedent from 'ts-dedent'; import { Story } from '@storybook/store'; -const { document, FEATURES = {} } = global; +const { document } = global; const layoutClassMap = { centered: 'sb-main-centered', diff --git a/lib/store/src/normalizeStory.ts b/lib/store/src/normalizeStory.ts index 569c398ccaf..9d2cfe153ee 100644 --- a/lib/store/src/normalizeStory.ts +++ b/lib/store/src/normalizeStory.ts @@ -3,8 +3,6 @@ import { toId, ComponentAnnotations, AnyFramework, - DecoratorFunction, - ArgTypes, LegacyStoryAnnotationsOrFn, StoryId, StoryAnnotations, diff --git a/lib/store/src/processCSFFile.test.ts b/lib/store/src/processCSFFile.test.ts index 5e10415ac54..96c5195df03 100644 --- a/lib/store/src/processCSFFile.test.ts +++ b/lib/store/src/processCSFFile.test.ts @@ -1,7 +1,5 @@ import { processCSFFile } from './processCSFFile'; -const entries = [{ specifier: { directory: './path/', titlePrefix: 'Prefix' } }]; - describe('processCSFFile', () => { it('returns a CSFFile object with meta and stories', () => { const { meta, stories } = processCSFFile( From 4884f786a90d0f9f5f064908c1343bbdfacc3a6c Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 17:22:49 +1000 Subject: [PATCH 210/285] Update snapshots due to WP => PW change --- lib/core-server/src/__snapshots__/vue-3-cli_preview-dev | 2 +- lib/core-server/src/__snapshots__/vue-3-cli_preview-prod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev b/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev index 5b8fea9b902..2ceeb9d70d3 100644 --- a/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev +++ b/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev @@ -474,11 +474,11 @@ Object { "@storybook/client-logger": "ROOT/lib/client-logger", "@storybook/components": "ROOT/lib/components", "@storybook/core-events": "ROOT/lib/core-events", + "@storybook/preview-web": "ROOT/lib/preview-web", "@storybook/router": "ROOT/lib/router", "@storybook/semver": "NODE_MODULES/@storybook/semver", "@storybook/store": "ROOT/lib/store", "@storybook/theming": "ROOT/lib/theming", - "@storybook/preview-web": "ROOT/lib/preview-web", "emotion-theming": "NODE_MODULES/emotion-theming", "react": "NODE_MODULES/react", "react-dom": "NODE_MODULES/react-dom", diff --git a/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod b/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod index 1df083b1076..258777939a5 100644 --- a/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod +++ b/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod @@ -473,11 +473,11 @@ Object { "@storybook/client-logger": "ROOT/lib/client-logger", "@storybook/components": "ROOT/lib/components", "@storybook/core-events": "ROOT/lib/core-events", + "@storybook/preview-web": "ROOT/lib/preview-web", "@storybook/router": "ROOT/lib/router", "@storybook/semver": "NODE_MODULES/@storybook/semver", "@storybook/store": "ROOT/lib/store", "@storybook/theming": "ROOT/lib/theming", - "@storybook/preview-web": "ROOT/lib/preview-web", "emotion-theming": "NODE_MODULES/emotion-theming", "react": "NODE_MODULES/react", "react-dom": "NODE_MODULES/react-dom", From cb1c5231181e09455c072e485f3bae203b6f2246 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 17:25:00 +1000 Subject: [PATCH 211/285] Remove unusued function arg (deepscan) --- addons/docs/src/frameworks/angular/compodoc.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/docs/src/frameworks/angular/compodoc.ts b/addons/docs/src/frameworks/angular/compodoc.ts index 8d76ee810ba..7598418b887 100644 --- a/addons/docs/src/frameworks/angular/compodoc.ts +++ b/addons/docs/src/frameworks/angular/compodoc.ts @@ -42,7 +42,7 @@ export const checkValidCompodocJson = (compodocJson: CompodocJson) => { const hasDecorator = (item: Property, decoratorName: string) => item.decorators && item.decorators.find((x: any) => x.name === decoratorName); -const mapPropertyToSection = (key: string, item: Property) => { +const mapPropertyToSection = (item: Property) => { if (hasDecorator(item, 'ViewChild')) { return 'view child'; } @@ -72,7 +72,7 @@ const mapItemToSection = (key: string, item: Method | Property): string => { if (isMethod(item)) { throw new Error("Cannot be of type Method if key === 'propertiesClass'"); } - return mapPropertyToSection(key, item); + return mapPropertyToSection(item); default: throw new Error(`Unknown key: ${key}`); } From c4497134a589157ac376fab89d8947f50fb6df96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Tue, 10 Aug 2021 21:20:08 +0200 Subject: [PATCH 212/285] Revert "fix(ArgControl): unbox the value to simplify the code" This reverts commit e42fcf0d3d5d25e1abab021c7c28a160b017387b. --- lib/components/src/blocks/ArgsTable/ArgControl.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/components/src/blocks/ArgsTable/ArgControl.tsx b/lib/components/src/blocks/ArgsTable/ArgControl.tsx index eed086327b7..ca5eccee3ce 100644 --- a/lib/components/src/blocks/ArgsTable/ArgControl.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgControl.tsx @@ -42,15 +42,16 @@ export const ArgControl: FC = ({ row, arg, updateArgs }) => { const { key, control } = row; const [isFocused, setFocused] = useState(false); - const [value, setValue] = useState(() => arg); + // box because arg can be a fn (e.g. actions) and useState calls fn's + const [boxedValue, setBoxedValue] = useState({ value: arg }); useEffect(() => { - if (!isFocused) setValue(arg); + if (!isFocused) setBoxedValue({ value: arg }); }, [isFocused, arg]); const onChange = useCallback( (argVal: any) => { - setValue(argVal); + setBoxedValue({ value: argVal }); updateArgs({ [key]: argVal }); return argVal; }, @@ -64,7 +65,7 @@ export const ArgControl: FC = ({ row, arg, updateArgs }) => { // row.name is a display name and not a suitable DOM input id or name - i might contain whitespace etc. // row.key is a hash key and therefore a much safer choice - const props = { name: key, argType: row, value, onChange, onBlur, onFocus }; + const props = { name: key, argType: row, value: boxedValue.value, onChange, onBlur, onFocus }; const Control = Controls[control.type] || NoControl; return ; }; From 82763973b945c56c9ae1d35a60e8accc0e8178b8 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 22:54:25 +1000 Subject: [PATCH 213/285] Get it bootstrapping again --- addons/controls/package.json | 2 +- addons/docs/package.json | 6 +- .../src/frameworks/html/sourceDecorator.ts | 16 +- .../storyshots/storyshots-core/package.json | 2 +- app/angular/package.json | 2 +- app/ember/package.json | 2 +- app/html/package.json | 4 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 4 +- app/server/src/client/preview/index.ts | 7 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 4 +- lib/builder-webpack4/package.json | 4 +- lib/builder-webpack5/package.json | 4 +- lib/client-api/package.json | 2 +- lib/core-client/package.json | 4 +- lib/core-common/src/utils/to-importFn.ts | 10 +- lib/preview-web/package.json | 12 +- lib/store/package.json | 8 +- yarn.lock | 385 ++---------------- 23 files changed, 99 insertions(+), 389 deletions(-) diff --git a/addons/controls/package.json b/addons/controls/package.json index 60898a24739..7ae190935f3 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -51,7 +51,7 @@ "@storybook/components": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.34", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "lodash": "^4.17.20", diff --git a/addons/docs/package.json b/addons/docs/package.json index d932bfb050c..aea35bd5195 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -75,9 +75,9 @@ "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/postinstall": "6.4.0-alpha.34", - "@storybook/preview-web": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/source-loader": "6.4.0-alpha.34", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "acorn": "^7.4.1", "acorn-jsx": "^5.3.1", @@ -108,6 +108,7 @@ "@emotion/core": "^10.1.1", "@emotion/styled": "^10.0.27", "@storybook/angular": "6.4.0-alpha.34", + "@storybook/html": "6.4.0-alpha.34", "@storybook/react": "6.4.0-alpha.34", "@storybook/vue": "6.4.0-alpha.34", "@storybook/web-components": "6.4.0-alpha.34", @@ -141,6 +142,7 @@ }, "peerDependencies": { "@storybook/angular": "6.4.0-alpha.34", + "@storybook/html": "6.4.0-alpha.34", "@storybook/react": "6.4.0-alpha.34", "@storybook/vue": "6.4.0-alpha.34", "@storybook/vue3": "6.4.0-alpha.34", diff --git a/addons/docs/src/frameworks/html/sourceDecorator.ts b/addons/docs/src/frameworks/html/sourceDecorator.ts index fa45e820ed4..97f3a15e862 100644 --- a/addons/docs/src/frameworks/html/sourceDecorator.ts +++ b/addons/docs/src/frameworks/html/sourceDecorator.ts @@ -1,9 +1,12 @@ /* global window */ -import { addons, StoryContext, StoryFn } from '@storybook/addons'; +import { addons } from '@storybook/addons'; +import { ArgsStoryFn, StoryContext, StoryFn } from '@storybook/csf'; import dedent from 'ts-dedent'; +import { HtmlFramework } from '@storybook/html'; + import { SNIPPET_RENDERED, SourceType } from '../../shared'; -function skipSourceRender(context: StoryContext) { +function skipSourceRender(context: StoryContext) { const sourceParams = context?.parameters.docs?.source; const isArgsStory = context?.parameters.__isArgsStory; @@ -23,15 +26,18 @@ function defaultTransformSource(source: string) { return dedent(source); } -function applyTransformSource(source: string, context: StoryContext): string { +function applyTransformSource(source: string, context: StoryContext): string { const docs = context.parameters.docs ?? {}; const transformSource = docs.transformSource ?? defaultTransformSource; return transformSource(source, context); } -export function sourceDecorator(storyFn: StoryFn, context: StoryContext) { +export function sourceDecorator( + storyFn: StoryFn, + context: StoryContext +) { const story = context?.parameters.docs?.source?.excludeDecorators - ? context.originalStoryFn(context.args) + ? (context.originalStoryFn as ArgsStoryFn)(context.args, context) : storyFn(); if (typeof story === 'string' && !skipSourceRender(context)) { diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index 45e78549fa3..bcd425be183 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", - "@storybook/core-client": "6.4.0-alpha.19", + "@storybook/core-client": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", "@types/glob": "^7.1.3", diff --git a/app/angular/package.json b/app/angular/package.json index b8613f173a6..50cc875dfe1 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -52,7 +52,7 @@ "@storybook/core-events": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.34", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "autoprefixer": "^9.8.6", "core-js": "^3.8.2", diff --git a/app/ember/package.json b/app/ember/package.json index 610714cc1b1..a3ca37fa29b 100644 --- a/app/ember/package.json +++ b/app/ember/package.json @@ -45,7 +45,7 @@ "@ember/test-helpers": "^2.1.4", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", "react": "16.14.0", diff --git a/app/html/package.json b/app/html/package.json index 1936e123e72..5bf675de8d2 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -50,8 +50,8 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/preview-web": "6.4.0-alpha.19", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.34", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/preact/package.json b/app/preact/package.json index 8745edfbcd1..2dc226856b3 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/react/package.json b/app/react/package.json index 537cb61d898..a06c2241fc2 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -56,7 +56,7 @@ "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "babel-plugin-add-react-displayname": "^0.0.5", "babel-plugin-named-asset-import": "^0.3.1", diff --git a/app/server/package.json b/app/server/package.json index 97a4c6e9a60..0959ab649ba 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -52,8 +52,8 @@ "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", "@storybook/node-logger": "6.4.0-alpha.34", - "@storybook/preview-web": "6.4.0-alpha.19", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.34", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/server/src/client/preview/index.ts b/app/server/src/client/preview/index.ts index 89221f3d5a4..e77650e889a 100644 --- a/app/server/src/client/preview/index.ts +++ b/app/server/src/client/preview/index.ts @@ -2,7 +2,7 @@ import { start } from '@storybook/core/client'; import { ClientStoryApi, Loadable, StoryFn, Args } from '@storybook/addons'; import './globals'; -import { renderMain as render } from './render'; +import { renderMain as renderToDOM } from './render'; import { IStorybookSection, ServerFramework } from './types'; const framework = 'server'; @@ -16,10 +16,9 @@ interface ClientApi extends ClientStoryApi { raw: () => any; // todo add type } -const globalRender: StoryFn = (args: Args) => {}; +const render: StoryFn = (args: Args) => {}; -const api = start(render); -api.clientApi.globalRender = globalRender; +const api = start(renderToDOM, { render }); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ diff --git a/app/svelte/package.json b/app/svelte/package.json index 2bb82b7afaf..229b416a5f2 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -49,7 +49,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", "react": "16.14.0", diff --git a/app/vue/package.json b/app/vue/package.json index 69f4a87f163..4945a784c1a 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -49,7 +49,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue3/package.json b/app/vue3/package.json index 5ee8083ae6c..ea35f8acff1 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -49,7 +49,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/web-components/package.json b/app/web-components/package.json index e2093a7e4a0..04d6747d897 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -55,8 +55,8 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/preview-web": "6.4.0-alpha.19", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.34", + "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "babel-plugin-bundled-import-meta": "^0.3.1", "core-js": "^3.8.2", diff --git a/lib/builder-webpack4/package.json b/lib/builder-webpack4/package.json index 3fcaa515130..cfd03d2fa19 100644 --- a/lib/builder-webpack4/package.json +++ b/lib/builder-webpack4/package.json @@ -71,10 +71,10 @@ "@storybook/core-common": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", - "@storybook/preview-web": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/router": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "@storybook/ui": "6.4.0-alpha.34", "@types/node": "^14.0.10", diff --git a/lib/builder-webpack5/package.json b/lib/builder-webpack5/package.json index 67338929459..52171096b58 100644 --- a/lib/builder-webpack5/package.json +++ b/lib/builder-webpack5/package.json @@ -70,10 +70,10 @@ "@storybook/core-common": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", - "@storybook/preview-web": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/router": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "@types/node": "^14.0.10", "babel-loader": "^8.0.0", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index eb9dca15da1..5ff93197c99 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -46,7 +46,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index 0d64f13d0d5..d6cbf314fa2 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -46,8 +46,8 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/preview-web": "6.4.0-alpha.19", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/preview-web": "6.4.0-alpha.34", + "@storybook/store": "6.4.0-alpha.34", "@storybook/ui": "6.4.0-alpha.34", "airbnb-js-shims": "^2.2.1", "ansi-to-html": "^0.6.11", diff --git a/lib/core-common/src/utils/to-importFn.ts b/lib/core-common/src/utils/to-importFn.ts index 7310bc904e8..58401063486 100644 --- a/lib/core-common/src/utils/to-importFn.ts +++ b/lib/core-common/src/utils/to-importFn.ts @@ -1,21 +1,19 @@ -import globBase from 'glob-base'; -import { makeRe } from 'micromatch'; import dedent from 'ts-dedent'; import type { NormalizedStoriesEntry } from '../types'; +import { toRequireContext } from './to-require-context'; export function toImportFnPart(entry: NormalizedStoriesEntry) { - const { base } = globBase(entry.glob); - const regex = makeRe(entry.glob, { fastpaths: false, noglobstar: false, bash: false }); + const { path: base, match } = toRequireContext(entry.glob); - const webpackIncludeRegex = new RegExp(regex.source.substring(1)); + const webpackIncludeRegex = new RegExp(match.source.substring(1)); // NOTE: `base` looks like './src' but `path`, (and what micromatch expects) // is something that starts with `src/`. So to strip off base from path, we // need to drop `base.length - 1` chars. return dedent` async (path) => { - if (!${regex}.exec(path)) { + if (!${match}.exec(path)) { return; } const remainder = path.substring(${base.length - 1}); diff --git a/lib/preview-web/package.json b/lib/preview-web/package.json index 59314f638dc..e00a0533a0e 100644 --- a/lib/preview-web/package.json +++ b/lib/preview-web/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview-web", - "version": "6.4.0-alpha.19", + "version": "6.4.0-alpha.34", "description": "", "keywords": [ "storybook" @@ -40,12 +40,12 @@ "prepare": "node ../../scripts/prepare.js" }, "dependencies": { - "@storybook/addons": "6.4.0-alpha.19", - "@storybook/channel-postmessage": "6.4.0-alpha.19", - "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/core-events": "6.4.0-alpha.19", + "@storybook/addons": "6.4.0-alpha.34", + "@storybook/channel-postmessage": "6.4.0-alpha.34", + "@storybook/client-logger": "6.4.0-alpha.34", + "@storybook/core-events": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", - "@storybook/store": "6.4.0-alpha.19", + "@storybook/store": "6.4.0-alpha.34", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index cb829330a62..244e636dafc 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/store", - "version": "6.4.0-alpha.19", + "version": "6.4.0-alpha.34", "description": "", "keywords": [ "storybook" @@ -40,9 +40,9 @@ "prepare": "node ../../scripts/prepare.js" }, "dependencies": { - "@storybook/addons": "6.4.0-alpha.19", - "@storybook/client-logger": "6.4.0-alpha.19", - "@storybook/core-events": "6.4.0-alpha.19", + "@storybook/addons": "6.4.0-alpha.34", + "@storybook/client-logger": "6.4.0-alpha.34", + "@storybook/core-events": "6.4.0-alpha.34", "@storybook/csf": "0.0.2--canary.a925d24.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/yarn.lock b/yarn.lock index 45f39c4e2f6..806022c9735 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6930,7 +6930,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.34 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 lodash: ^4.17.20 @@ -6973,12 +6973,13 @@ __metadata: "@storybook/core-events": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/csf-tools": 6.4.0-alpha.34 + "@storybook/html": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/postinstall": 6.4.0-alpha.34 - "@storybook/preview-web": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/react": 6.4.0-alpha.34 "@storybook/source-loader": 6.4.0-alpha.34 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 "@storybook/vue": 6.4.0-alpha.34 "@storybook/web-components": 6.4.0-alpha.34 @@ -7033,6 +7034,7 @@ __metadata: zone.js: ^0.11.3 peerDependencies: "@storybook/angular": 6.4.0-alpha.34 + "@storybook/html": 6.4.0-alpha.34 "@storybook/react": 6.4.0-alpha.34 "@storybook/vue": 6.4.0-alpha.34 "@storybook/vue3": 6.4.0-alpha.34 @@ -7288,7 +7290,7 @@ __metadata: "@storybook/angular": 6.4.0-alpha.34 "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 - "@storybook/core-client": 6.4.0-alpha.19 + "@storybook/core-client": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/react": 6.4.0-alpha.34 @@ -7465,26 +7467,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/addons@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/addons@npm:6.4.0-alpha.19" - dependencies: - "@storybook/api": 6.4.0-alpha.19 - "@storybook/channels": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/router": 6.4.0-alpha.19 - "@storybook/theming": 6.4.0-alpha.19 - core-js: ^3.8.2 - global: ^4.4.0 - regenerator-runtime: ^0.13.7 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - checksum: ed2d3fb3347a91388eb79bde699944b033894d583f8ec4d56e4716b9885bcaa017892f98e7f366c84ba8c92bf7e1c86d7cb3333c797409fb5a0c6dfce4f7ba59 - languageName: node - linkType: hard - "@storybook/angular@6.4.0-alpha.34, @storybook/angular@workspace:*, @storybook/angular@workspace:app/angular": version: 0.0.0-use.local resolution: "@storybook/angular@workspace:app/angular" @@ -7508,7 +7490,7 @@ __metadata: "@storybook/core-events": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.34 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@types/autoprefixer": ^9.7.2 "@types/jest": ^26.0.16 "@types/webpack-env": ^1.16.0 @@ -7601,37 +7583,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/api@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/api@npm:6.4.0-alpha.19" - dependencies: - "@reach/router": ^1.3.4 - "@storybook/channels": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.1 - "@storybook/router": 6.4.0-alpha.19 - "@storybook/semver": ^7.3.2 - "@storybook/theming": 6.4.0-alpha.19 - "@types/reach__router": ^1.3.7 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 - lodash: ^4.17.20 - memoizerific: ^1.11.3 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - store2: ^2.12.0 - telejson: ^5.3.2 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - checksum: 8d146e7242bb9fb849d16902cca76c06f1ef8a24c62b192e6a5e88ed0d321d46be7aaf8890ec794beffb479fdca50dd0a9b2be007b73db50908ed9d07df29a19 - languageName: node - linkType: hard - "@storybook/builder-webpack4@6.4.0-alpha.34, @storybook/builder-webpack4@workspace:lib/builder-webpack4": version: 0.0.0-use.local resolution: "@storybook/builder-webpack4@workspace:lib/builder-webpack4" @@ -7667,10 +7618,10 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 - "@storybook/preview-web": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 "@storybook/ui": 6.4.0-alpha.34 "@types/case-sensitive-paths-webpack-plugin": ^2.1.4 @@ -7757,10 +7708,10 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 - "@storybook/preview-web": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 "@types/case-sensitive-paths-webpack-plugin": ^2.1.4 "@types/dotenv-webpack": ^5.0.0 @@ -7814,21 +7765,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/channel-postmessage@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/channel-postmessage@npm:6.4.0-alpha.19" - dependencies: - "@storybook/channels": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 - core-js: ^3.8.2 - global: ^4.4.0 - qs: ^6.10.0 - telejson: ^5.3.2 - checksum: 7e9b036993089dfcd1d3dc035915cd0539e5964a5ab9be0ec38642c0930aa9d49b24e4f2df5db0d5ec3b2607466187ecab932d034ecde236a843721c2be389a5 - languageName: node - linkType: hard - "@storybook/channel-websocket@workspace:*, @storybook/channel-websocket@workspace:lib/channel-websocket": version: 0.0.0-use.local resolution: "@storybook/channel-websocket@workspace:lib/channel-websocket" @@ -7850,17 +7786,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/channels@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/channels@npm:6.4.0-alpha.19" - dependencies: - core-js: ^3.8.2 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - checksum: f81d60c61ac3948663078a75fc6b0892cf921ab4d69e0f7700c5009a57c0535905f4147173f922acb2c2b2ecf7186054208d777e4f5446d34648477792b81ed0 - languageName: node - linkType: hard - "@storybook/cli@6.4.0-alpha.34, @storybook/cli@workspace:*, @storybook/cli@workspace:lib/cli": version: 0.0.0-use.local resolution: "@storybook/cli@workspace:lib/cli" @@ -7917,7 +7842,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -7937,35 +7862,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/client-api@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/client-api@npm:6.4.0-alpha.19" - dependencies: - "@storybook/addons": 6.4.0-alpha.19 - "@storybook/channel-postmessage": 6.4.0-alpha.19 - "@storybook/channels": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.1 - "@types/qs": ^6.9.5 - "@types/webpack-env": ^1.16.0 - core-js: ^3.8.2 - global: ^4.4.0 - lodash: ^4.17.20 - memoizerific: ^1.11.3 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - stable: ^0.1.8 - store2: ^2.12.0 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - checksum: 4d63a2f32b2d1a5d64153e3cebcbea9f372755b59853136fc1db8d3a4efa1cf87a984cf3af027cd9c2060486d5c0a6fc80f7d70366d699b904805023b7aff677 - languageName: node - linkType: hard - "@storybook/client-logger@6.4.0-alpha.34, @storybook/client-logger@workspace:*, @storybook/client-logger@workspace:lib/client-logger": version: 0.0.0-use.local resolution: "@storybook/client-logger@workspace:lib/client-logger" @@ -7975,16 +7871,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/client-logger@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/client-logger@npm:6.4.0-alpha.19" - dependencies: - core-js: ^3.8.2 - global: ^4.4.0 - checksum: cb4a70a066ef9b3ed4f07a5615710c60dd7495d565570640b4f8cbc75282a251c946892c245939b95f63d6bbc15f5e51652ec85924ff929405ae6aa11268fc5b - languageName: node - linkType: hard - "@storybook/codemod@6.4.0-alpha.34, @storybook/codemod@workspace:*, @storybook/codemod@workspace:lib/codemod": version: 0.0.0-use.local resolution: "@storybook/codemod@workspace:lib/codemod" @@ -8043,41 +7929,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/components@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/components@npm:6.4.0-alpha.19" - dependencies: - "@popperjs/core": ^2.6.0 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/csf": 0.0.1 - "@storybook/theming": 6.4.0-alpha.19 - "@types/color-convert": ^2.0.0 - "@types/overlayscrollbars": ^1.12.0 - "@types/react-syntax-highlighter": 11.0.5 - color-convert: ^2.0.1 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 - lodash: ^4.17.20 - markdown-to-jsx: ^7.1.3 - memoizerific: ^1.11.3 - overlayscrollbars: ^1.13.1 - polished: ^4.0.5 - prop-types: ^15.7.2 - react-colorful: ^5.1.2 - react-popper-tooltip: ^3.1.1 - react-syntax-highlighter: ^13.5.3 - react-textarea-autosize: ^8.3.0 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - checksum: 40b07098309939ac44995c8ff35a848f549cacb7a2d3386b37a6d187edf476934b1a412a5592263f788c2a5f917e3714c03fef8ab88280c2eb64b30366272084 - languageName: node - linkType: hard - "@storybook/core-client@6.4.0-alpha.34, @storybook/core-client@workspace:lib/core-client": version: 0.0.0-use.local resolution: "@storybook/core-client@workspace:lib/core-client" @@ -8088,8 +7939,8 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/preview-web": 6.4.0-alpha.19 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 "@storybook/ui": 6.4.0-alpha.34 airbnb-js-shims: ^2.2.1 ansi-to-html: ^0.6.11 @@ -8112,38 +7963,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/core-client@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/core-client@npm:6.4.0-alpha.19" - dependencies: - "@storybook/addons": 6.4.0-alpha.19 - "@storybook/channel-postmessage": 6.4.0-alpha.19 - "@storybook/client-api": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/csf": 0.0.1 - "@storybook/ui": 6.4.0-alpha.19 - airbnb-js-shims: ^2.2.1 - ansi-to-html: ^0.6.11 - core-js: ^3.8.2 - global: ^4.4.0 - lodash: ^4.17.20 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - unfetch: ^4.2.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - webpack: "*" - peerDependenciesMeta: - typescript: - optional: true - checksum: 038fbbec7650e41d838c7243b542aa88fcb6e07441bc2fa19c75f911b9b0be3933ae75f29f8bc3e88a0392b731c63ec71be9699bc4a2174005064a1bd25f61c7 - languageName: node - linkType: hard - "@storybook/core-common@6.4.0-alpha.34, @storybook/core-common@workspace:lib/core-common": version: 0.0.0-use.local resolution: "@storybook/core-common@workspace:lib/core-common" @@ -8216,15 +8035,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/core-events@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/core-events@npm:6.4.0-alpha.19" - dependencies: - core-js: ^3.8.2 - checksum: 35a265f77565cd8812bcdd0262edb6bb3c04b2d157e2dbb87d3656a5b19509f18d0e08919fd76812bfa0bcb0b5520ca9cec429b8c567c1a0f9a7e1091a45ca40 - languageName: node - linkType: hard - "@storybook/core-server@6.4.0-alpha.34, @storybook/core-server@workspace:lib/core-server": version: 0.0.0-use.local resolution: "@storybook/core-server@workspace:lib/core-server" @@ -8328,21 +8138,21 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.1, @storybook/csf@npm:^0.0.1": - version: 0.0.1 - resolution: "@storybook/csf@npm:0.0.1" +"@storybook/csf@npm:0.0.2--canary.a925d24.0": + version: 0.0.2--canary.a925d24.0 + resolution: "@storybook/csf@npm:0.0.2--canary.a925d24.0" dependencies: lodash: ^4.17.15 - checksum: 7b0f75763415f9147692a460b44417ee56ea9639433716a1fd4d1df4c8b0221cbc71b8da0fbed4dcecb3ccd6c7ed64be39f5c255c713539a6088a1d6488aaa24 + checksum: 28f528e874a0db0e5d9a1c548969a0c0d92d90b044eda495eb25afa5f76be483bef8310d77cc19106ed22d4d00b39e9b3e63eee2d0fbec0596446389768612a0 languageName: node linkType: hard -"@storybook/csf@npm:0.0.2--canary.a925d24.0": - version: 0.0.2--canary.a925d24.0 - resolution: "@storybook/csf@npm:0.0.2--canary.a925d24.0" +"@storybook/csf@npm:^0.0.1": + version: 0.0.1 + resolution: "@storybook/csf@npm:0.0.1" dependencies: lodash: ^4.17.15 - checksum: 28f528e874a0db0e5d9a1c548969a0c0d92d90b044eda495eb25afa5f76be483bef8310d77cc19106ed22d4d00b39e9b3e63eee2d0fbec0596446389768612a0 + checksum: 7b0f75763415f9147692a460b44417ee56ea9639433716a1fd4d1df4c8b0221cbc71b8da0fbed4dcecb3ccd6c7ed64be39f5c255c713539a6088a1d6488aaa24 languageName: node linkType: hard @@ -8387,7 +8197,7 @@ __metadata: "@ember/test-helpers": ^2.1.4 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 core-js: ^3.8.2 global: ^4.4.0 react: 16.14.0 @@ -8471,8 +8281,8 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/preview-web": 6.4.0-alpha.19 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -8686,7 +8496,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -8737,16 +8547,16 @@ __metadata: languageName: node linkType: hard -"@storybook/preview-web@6.4.0-alpha.19, @storybook/preview-web@workspace:*, @storybook/preview-web@workspace:lib/preview-web": +"@storybook/preview-web@6.4.0-alpha.34, @storybook/preview-web@workspace:*, @storybook/preview-web@workspace:lib/preview-web": version: 0.0.0-use.local resolution: "@storybook/preview-web@workspace:lib/preview-web" dependencies: - "@storybook/addons": 6.4.0-alpha.19 - "@storybook/channel-postmessage": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/channel-postmessage": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 ansi-to-html: ^0.6.11 core-js: ^3.8.2 global: ^4.4.0 @@ -8795,7 +8605,7 @@ __metadata: "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/prompts": ^2.0.9 "@types/webpack-env": ^1.16.0 @@ -9069,27 +8879,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/router@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/router@npm:6.4.0-alpha.19" - dependencies: - "@reach/router": ^1.3.4 - "@storybook/client-logger": 6.4.0-alpha.19 - "@types/reach__router": ^1.3.7 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 - lodash: ^4.17.20 - memoizerific: ^1.11.3 - qs: ^6.10.0 - ts-dedent: ^2.0.0 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - checksum: ee85b85187d8e164e50f4de3d0f5fb4b1c8c96edebee2676ced861b5601896af21fc5cd0ed34aded6c255fa0efcf7c7be318cf5ded5bef4520085e1748973d6b - languageName: node - linkType: hard - "@storybook/semver@npm:^7.3.2": version: 7.3.2 resolution: "@storybook/semver@npm:7.3.2" @@ -9113,8 +8902,8 @@ __metadata: "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 "@storybook/node-logger": 6.4.0-alpha.34 - "@storybook/preview-web": 6.4.0-alpha.19 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -9154,13 +8943,13 @@ __metadata: languageName: unknown linkType: soft -"@storybook/store@6.4.0-alpha.19, @storybook/store@workspace:*, @storybook/store@workspace:lib/store": +"@storybook/store@6.4.0-alpha.34, @storybook/store@workspace:*, @storybook/store@workspace:lib/store": version: 0.0.0-use.local resolution: "@storybook/store@workspace:lib/store" dependencies: - "@storybook/addons": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 @@ -9181,7 +8970,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -9226,29 +9015,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/theming@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/theming@npm:6.4.0-alpha.19" - dependencies: - "@emotion/core": ^10.1.1 - "@emotion/is-prop-valid": ^0.8.6 - "@emotion/styled": ^10.0.27 - "@storybook/client-logger": 6.4.0-alpha.19 - core-js: ^3.8.2 - deep-object-diff: ^1.1.0 - emotion-theming: ^10.0.27 - global: ^4.4.0 - memoizerific: ^1.11.3 - polished: ^4.0.5 - resolve-from: ^5.0.0 - ts-dedent: ^2.0.0 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - checksum: 70de4e87ca9ea7e5886ecfed7e53dfb7d7f349ebaaefb0da9bc5d938f85d89b44e103328153a2683cead602aba105547a62eb796d9695378a17f5a05e4f95673 - languageName: node - linkType: hard - "@storybook/ui@6.4.0-alpha.34, @storybook/ui@workspace:*, @storybook/ui@workspace:lib/ui": version: 0.0.0-use.local resolution: "@storybook/ui@workspace:lib/ui" @@ -9295,46 +9061,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/ui@npm:6.4.0-alpha.19": - version: 6.4.0-alpha.19 - resolution: "@storybook/ui@npm:6.4.0-alpha.19" - dependencies: - "@emotion/core": ^10.1.1 - "@storybook/addons": 6.4.0-alpha.19 - "@storybook/api": 6.4.0-alpha.19 - "@storybook/channels": 6.4.0-alpha.19 - "@storybook/client-logger": 6.4.0-alpha.19 - "@storybook/components": 6.4.0-alpha.19 - "@storybook/core-events": 6.4.0-alpha.19 - "@storybook/router": 6.4.0-alpha.19 - "@storybook/semver": ^7.3.2 - "@storybook/theming": 6.4.0-alpha.19 - "@types/markdown-to-jsx": ^6.11.3 - copy-to-clipboard: ^3.3.1 - core-js: ^3.8.2 - core-js-pure: ^3.8.2 - downshift: ^6.0.15 - emotion-theming: ^10.0.27 - fuse.js: ^3.6.1 - global: ^4.4.0 - lodash: ^4.17.20 - markdown-to-jsx: ^6.11.4 - memoizerific: ^1.11.3 - polished: ^4.0.5 - qs: ^6.10.0 - react-draggable: ^4.4.3 - react-helmet-async: ^1.0.7 - react-sizeme: ^3.0.1 - regenerator-runtime: ^0.13.7 - resolve-from: ^5.0.0 - store2: ^2.12.0 - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - checksum: ad6d13b586ff3ceadc0d3ab874c76e26ed4af69bccd896352190747784dd53204f2cb40bccd6b39f453290f748293e36d463f6b73fd864fc6c91cd4dce319495 - languageName: node - linkType: hard - "@storybook/vue3@6.4.0-alpha.34, @storybook/vue3@workspace:app/vue3": version: 0.0.0-use.local resolution: "@storybook/vue3@workspace:app/vue3" @@ -9343,7 +9069,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 "@vue/compiler-sfc": ^3.0.0 @@ -9380,7 +9106,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -9423,8 +9149,8 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/csf": 0.0.2--canary.a925d24.0 - "@storybook/preview-web": 6.4.0-alpha.19 - "@storybook/store": 6.4.0-alpha.19 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 babel-plugin-bundled-import-meta: ^0.3.1 core-js: ^3.8.2 @@ -10435,15 +10161,6 @@ __metadata: languageName: node linkType: hard -"@types/markdown-to-jsx@npm:^6.11.3": - version: 6.11.3 - resolution: "@types/markdown-to-jsx@npm:6.11.3" - dependencies: - "@types/react": "*" - checksum: a14520d501430beb22e429ce330605aa84f3f3344e00d2329ff0724e876864c75c841354b503afcb99e2b79f71af85dfcfefc0f63b145b375ec0588e884764b4 - languageName: node - linkType: hard - "@types/mdast@npm:^3.0.0": version: 3.0.3 resolution: "@types/mdast@npm:3.0.3" @@ -31365,18 +31082,6 @@ fsevents@^1.2.7: languageName: node linkType: hard -"markdown-to-jsx@npm:^6.11.4": - version: 6.11.4 - resolution: "markdown-to-jsx@npm:6.11.4" - dependencies: - prop-types: ^15.6.2 - unquote: ^1.1.0 - peerDependencies: - react: ">= 0.14.0" - checksum: 72b9f877f001604413ec089e4873bc034f8e1c17042f1421ab75938c97a1ad53ef8948656eeec234e3b1621613c37b13daad81db4fa895ac6b7f4cc4720dfcc6 - languageName: node - linkType: hard - "markdown-to-jsx@npm:^7.1.3": version: 7.1.3 resolution: "markdown-to-jsx@npm:7.1.3" @@ -44531,7 +44236,7 @@ resolve@1.19.0: languageName: node linkType: hard -"unquote@npm:^1.1.0, unquote@npm:~1.1.1": +"unquote@npm:~1.1.1": version: 1.1.1 resolution: "unquote@npm:1.1.1" checksum: de59fb48cbaadc636002c6563dcb6b1bce95c91ebecb92addbc9bb47982cb03e7d8a8371c9617267b9e5746bbcb4403394139bc1310106b9ac4c26790ed57859 From c2bc484ce8e0b5220b0d90c723aee8414276382a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 23:21:21 +1000 Subject: [PATCH 214/285] Update CSF --- addons/a11y/package.json | 2 +- addons/actions/package.json | 2 +- addons/backgrounds/package.json | 2 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/links/package.json | 2 +- addons/measure/package.json | 2 +- addons/outline/package.json | 2 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 2 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 2 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 2 +- lib/addons/package.json | 2 +- lib/api/package.json | 2 +- lib/client-api/package.json | 2 +- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/preview-web/package.json | 2 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- yarn.lock | 64 +++++++++---------- 29 files changed, 61 insertions(+), 61 deletions(-) diff --git a/addons/a11y/package.json b/addons/a11y/package.json index 79294e737ef..28d071f17a3 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/theming": "6.4.0-alpha.34", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/actions/package.json b/addons/actions/package.json index e6201d83723..6027fbd3052 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index abc4a7d009b..a27fc0ba1c1 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,7 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/controls/package.json b/addons/controls/package.json index 7ae190935f3..9510dd6763e 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", diff --git a/addons/docs/package.json b/addons/docs/package.json index aea35bd5195..be205863aaa 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/postinstall": "6.4.0-alpha.34", diff --git a/addons/links/package.json b/addons/links/package.json index 09566bb9e31..b3a19608a7f 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/router": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/measure/package.json b/addons/measure/package.json index f11e033f12b..d246c59f62d 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,7 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/outline/package.json b/addons/outline/package.json index 889686560f3..473b931351d 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,7 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index bcd425be183..818534caeb6 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-client": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index ebab3089027..98fd9050811 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/node-logger": "6.4.0-alpha.34", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index 50cc875dfe1..7f2b561d244 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index 5bf675de8d2..c3b75ec2cb0 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/preact/package.json b/app/preact/package.json index 2dc226856b3..5ae44e63489 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/react/package.json b/app/react/package.json index a06c2241fc2..a8fa318c370 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index 0959ab649ba..9e2e3160a95 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,7 +50,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", diff --git a/app/svelte/package.json b/app/svelte/package.json index 229b416a5f2..56c75f96ec1 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/store": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index 4945a784c1a..dd50091d8b2 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index ea35f8acff1..c24c5f69074 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index 04d6747d897..73e58dc0d85 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/lib/addons/package.json b/lib/addons/package.json index 62803ca6ac4..e412d0ca884 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/api/package.json b/lib/api/package.json index f433d41aa77..aac7d09f092 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.34", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index 5ff93197c99..7a1e447da59 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -45,7 +45,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/store": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index aa3f8a1e646..e6d84c48679 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index 2a68d1625ae..ac97bd4201d 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/theming": "6.4.0-alpha.34", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index d6cbf314fa2..1dbee39c58d 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/ui": "6.4.0-alpha.34", diff --git a/lib/preview-web/package.json b/lib/preview-web/package.json index e00a0533a0e..32494bc7a17 100644 --- a/lib/preview-web/package.json +++ b/lib/preview-web/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "@storybook/store": "6.4.0-alpha.34", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index 9d7a5dccd91..fc0b98ed491 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index 244e636dafc..4efb1f27b9b 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -43,7 +43,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.a925d24.0", + "@storybook/csf": "0.0.2--canary.5459c65.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/yarn.lock b/yarn.lock index 806022c9735..c3eb6ddf3b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6834,7 +6834,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/theming": 6.4.0-alpha.34 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -6865,7 +6865,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/theming": 6.4.0-alpha.34 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -6900,7 +6900,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/theming": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -6928,7 +6928,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 @@ -6971,7 +6971,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/html": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 @@ -7173,7 +7173,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/router": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7203,7 +7203,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7227,7 +7227,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7262,7 +7262,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/node-logger": 6.4.0-alpha.34 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -7292,7 +7292,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-client": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/react": 6.4.0-alpha.34 "@storybook/vue": 6.4.0-alpha.34 "@storybook/vue3": 6.4.0-alpha.34 @@ -7455,7 +7455,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7488,7 +7488,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/autoprefixer": ^9.7.2 @@ -7557,7 +7557,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.34 @@ -7841,7 +7841,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/store": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7877,7 +7877,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7899,7 +7899,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/theming": 6.4.0-alpha.34 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -7938,7 +7938,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/ui": 6.4.0-alpha.34 @@ -8138,12 +8138,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.a925d24.0": - version: 0.0.2--canary.a925d24.0 - resolution: "@storybook/csf@npm:0.0.2--canary.a925d24.0" +"@storybook/csf@npm:0.0.2--canary.5459c65.0": + version: 0.0.2--canary.5459c65.0 + resolution: "@storybook/csf@npm:0.0.2--canary.5459c65.0" dependencies: lodash: ^4.17.15 - checksum: 28f528e874a0db0e5d9a1c548969a0c0d92d90b044eda495eb25afa5f76be483bef8310d77cc19106ed22d4d00b39e9b3e63eee2d0fbec0596446389768612a0 + checksum: 67e8adfddbc4eb96f6cfdca0fe03cfcac460302489bde3b99d31f88eab14759d7d856592871434cd2d8caffebb465f8b81c87576ecb9da755baace09f83b5c57 languageName: node linkType: hard @@ -8280,7 +8280,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 @@ -8495,7 +8495,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -8555,7 +8555,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/store": 6.4.0-alpha.34 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -8601,7 +8601,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -8900,7 +8900,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 @@ -8929,7 +8929,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -8950,7 +8950,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -8969,7 +8969,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -9068,7 +9068,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9105,7 +9105,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9148,7 +9148,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.a925d24.0 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 From 674e26f4598fe106feb0b62ec3840c2d557c112b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 23:22:41 +1000 Subject: [PATCH 215/285] Tweak `ArgTypes` --- lib/addons/src/types.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/addons/src/types.ts b/lib/addons/src/types.ts index 58254abb7b8..293be7ec354 100644 --- a/lib/addons/src/types.ts +++ b/lib/addons/src/types.ts @@ -29,11 +29,8 @@ export type { Args, } from '@storybook/csf'; -export interface ArgType { - name?: string; - description?: string; +export interface ArgType extends InputType { defaultValue?: TArg; - [key: string]: any; } export type ArgTypes = { From 4702cf07574f3febd25803ac7e9c70e4c232dae4 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 23:26:43 +1000 Subject: [PATCH 216/285] Fix handlebars dep --- lib/core-common/package.json | 1 + yarn.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/core-common/package.json b/lib/core-common/package.json index c70022045e8..e3c40e7011a 100644 --- a/lib/core-common/package.json +++ b/lib/core-common/package.json @@ -77,6 +77,7 @@ "fork-ts-checker-webpack-plugin": "^6.0.4", "fs-extra": "^9.0.1", "glob": "^7.1.6", + "handlebars": "^4.7.7", "interpret": "^2.2.0", "json5": "^2.1.3", "lazy-universal-dotenv": "^3.0.1", diff --git a/yarn.lock b/yarn.lock index c3eb6ddf3b3..e9fe5cc12c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8007,6 +8007,7 @@ __metadata: fork-ts-checker-webpack-plugin: ^6.0.4 fs-extra: ^9.0.1 glob: ^7.1.6 + handlebars: ^4.7.7 interpret: ^2.2.0 json5: ^2.1.3 lazy-universal-dotenv: ^3.0.1 From a504ad3a327905c84ce8db3a0e8e2d4be496590a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 23:30:31 +1000 Subject: [PATCH 217/285] Improve types flushed out by CSF changes --- addons/backgrounds/src/decorators/withBackground.ts | 2 +- addons/backgrounds/src/decorators/withGrid.ts | 2 +- addons/measure/src/withMeasure.ts | 2 +- addons/outline/src/withOutline.ts | 2 +- app/angular/src/client/preview/types.ts | 2 +- app/html/src/client/preview/types.ts | 2 +- app/preact/src/client/preview/types.ts | 2 +- app/react/src/client/preview/types.ts | 2 +- app/server/src/client/preview/types.ts | 2 +- app/vue/src/client/preview/types.ts | 2 +- app/vue3/src/client/preview/types.ts | 2 +- app/web-components/src/client/preview/types.ts | 2 +- lib/addons/src/types.ts | 2 +- lib/client-api/src/ClientApi.ts | 3 ++- 14 files changed, 15 insertions(+), 14 deletions(-) diff --git a/addons/backgrounds/src/decorators/withBackground.ts b/addons/backgrounds/src/decorators/withBackground.ts index e86378bf96c..b5d72d4cbcb 100644 --- a/addons/backgrounds/src/decorators/withBackground.ts +++ b/addons/backgrounds/src/decorators/withBackground.ts @@ -1,5 +1,5 @@ import { useMemo, useEffect } from '@storybook/addons'; -import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, PartialStoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; import { diff --git a/addons/backgrounds/src/decorators/withGrid.ts b/addons/backgrounds/src/decorators/withGrid.ts index b7c0422cebf..294f9df818a 100644 --- a/addons/backgrounds/src/decorators/withGrid.ts +++ b/addons/backgrounds/src/decorators/withGrid.ts @@ -1,7 +1,7 @@ import dedent from 'ts-dedent'; import deprecate from 'util-deprecate'; import { useMemo, useEffect } from '@storybook/addons'; -import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, PartialStoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { clearStyles, addGridStyle } from '../helpers'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; diff --git a/addons/measure/src/withMeasure.ts b/addons/measure/src/withMeasure.ts index 7ef5ba92101..b8c78b7109f 100644 --- a/addons/measure/src/withMeasure.ts +++ b/addons/measure/src/withMeasure.ts @@ -1,6 +1,6 @@ /* eslint-env browser */ import { useEffect } from '@storybook/addons'; -import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, PartialStoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { drawSelectedElement } from './box-model/visualizer'; import { init, rescale, destroy } from './box-model/canvas'; import { deepElementFromPoint } from './util'; diff --git a/addons/outline/src/withOutline.ts b/addons/outline/src/withOutline.ts index de3878f57e4..818ce5acee5 100644 --- a/addons/outline/src/withOutline.ts +++ b/addons/outline/src/withOutline.ts @@ -1,5 +1,5 @@ import { useMemo, useEffect } from '@storybook/addons'; -import { AnyFramework, StoryFn as StoryFunction, StoryContext } from '@storybook/csf'; +import { AnyFramework, PartialStoryFn as StoryFunction, StoryContext } from '@storybook/csf'; import { clearStyles, addOutlineStyles } from './helpers'; import { PARAM_KEY } from './constants'; diff --git a/app/angular/src/client/preview/types.ts b/app/angular/src/client/preview/types.ts index f8829b60ae6..1ce3b4294c3 100644 --- a/app/angular/src/client/preview/types.ts +++ b/app/angular/src/client/preview/types.ts @@ -11,7 +11,7 @@ export interface ICollection { export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/app/html/src/client/preview/types.ts b/app/html/src/client/preview/types.ts index 6de091931ba..21ed344197c 100644 --- a/app/html/src/client/preview/types.ts +++ b/app/html/src/client/preview/types.ts @@ -4,7 +4,7 @@ export type StoryFnHtmlReturnType = string | Node; export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/app/preact/src/client/preview/types.ts b/app/preact/src/client/preview/types.ts index d827a97b1b3..430cf781230 100644 --- a/app/preact/src/client/preview/types.ts +++ b/app/preact/src/client/preview/types.ts @@ -9,7 +9,7 @@ export interface ShowErrorArgs { export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/app/react/src/client/preview/types.ts b/app/react/src/client/preview/types.ts index 43774d0c8a7..af48265c404 100644 --- a/app/react/src/client/preview/types.ts +++ b/app/react/src/client/preview/types.ts @@ -12,7 +12,7 @@ export type StoryFnReactReturnType = ReactElement; export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/app/server/src/client/preview/types.ts b/app/server/src/client/preview/types.ts index 40be7af10e2..0f8ddc25f54 100644 --- a/app/server/src/client/preview/types.ts +++ b/app/server/src/client/preview/types.ts @@ -18,7 +18,7 @@ export type FetchStoryHtmlType = ( export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/app/vue/src/client/preview/types.ts b/app/vue/src/client/preview/types.ts index b2e8b22ec0c..750260ba95d 100644 --- a/app/vue/src/client/preview/types.ts +++ b/app/vue/src/client/preview/types.ts @@ -12,7 +12,7 @@ export type StoryFnVueReturnType = string | Component; export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/app/vue3/src/client/preview/types.ts b/app/vue3/src/client/preview/types.ts index b25133f953e..e613aa482d7 100644 --- a/app/vue3/src/client/preview/types.ts +++ b/app/vue3/src/client/preview/types.ts @@ -11,7 +11,7 @@ export type StoryFnVueReturnType = ConcreteComponent; export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/app/web-components/src/client/preview/types.ts b/app/web-components/src/client/preview/types.ts index 039a835cfc0..2a9e2564c6e 100644 --- a/app/web-components/src/client/preview/types.ts +++ b/app/web-components/src/client/preview/types.ts @@ -7,7 +7,7 @@ export type StoryFnHtmlReturnType = string | Node | TemplateResult | SVGTemplate export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/lib/addons/src/types.ts b/lib/addons/src/types.ts index 293be7ec354..96783fb9194 100644 --- a/lib/addons/src/types.ts +++ b/lib/addons/src/types.ts @@ -140,7 +140,7 @@ export interface ClientApiAddons { // Old types for getStorybook() export interface IStorybookStory { name: string; - render: () => any; + render: (context: any) => any; } export interface IStorybookSection { diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 285f418c14a..c2ae777b6b5 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -15,6 +15,7 @@ import { ComponentTitle, Globals, GlobalTypes, + LegacyStoryFn, } from '@storybook/csf'; import { NormalizedComponentAnnotations, @@ -32,7 +33,7 @@ const { FEATURES } = global; export interface GetStorybookStory { name: string; - render: StoryFn; + render: LegacyStoryFn; } export interface GetStorybookKind { From 08301a37b07f94dcbf272fdebd73864eb8e03639 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 00:01:14 +1000 Subject: [PATCH 218/285] Fix a bunch of types --- .../docs/src/frameworks/angular/prepareForInline.ts | 4 ++-- addons/docs/src/frameworks/angular/sourceDecorator.ts | 7 +++++-- addons/docs/src/frameworks/html/prepareForInline.tsx | 4 ++-- addons/docs/src/frameworks/html/sourceDecorator.ts | 4 ++-- addons/docs/src/frameworks/react/config.ts | 4 ++-- addons/docs/src/frameworks/react/jsxDecorator.tsx | 4 ++-- addons/docs/src/frameworks/vue/prepareForInline.ts | 4 ++-- addons/docs/src/frameworks/vue3/prepareForInline.ts | 4 ++-- .../src/frameworks/web-components/prepareForInline.ts | 4 ++-- .../src/frameworks/web-components/sourceDecorator.ts | 4 ++-- app/angular/src/client/preview/angular/helpers.ts | 6 +++--- app/angular/src/client/preview/decorateStory.ts | 8 ++++---- app/svelte/src/client/preview/decorators.ts | 9 +++++---- app/vue/src/client/preview/index.ts | 10 ++++++---- app/vue3/src/client/preview/index.ts | 4 ++-- lib/store/src/StoryStore.ts | 11 +++++++---- lib/store/src/types.ts | 5 +++-- 17 files changed, 53 insertions(+), 43 deletions(-) diff --git a/addons/docs/src/frameworks/angular/prepareForInline.ts b/addons/docs/src/frameworks/angular/prepareForInline.ts index 8fd22423dca..76be79a3f4a 100644 --- a/addons/docs/src/frameworks/angular/prepareForInline.ts +++ b/addons/docs/src/frameworks/angular/prepareForInline.ts @@ -4,7 +4,7 @@ import { nanoid } from 'nanoid'; import { AngularFramework, StoryContext } from '@storybook/angular'; import { rendererFactory } from '@storybook/angular/renderer'; -import { StoryFn } from '@storybook/csf'; +import { PartialStoryFn } from '@storybook/csf'; const limit = pLimit(1); @@ -12,7 +12,7 @@ const limit = pLimit(1); * Uses the angular renderer to generate a story. Uses p-limit to run synchronously */ export const prepareForInline = ( - storyFn: StoryFn, + storyFn: PartialStoryFn, { id, parameters }: StoryContext ) => { return React.createElement('div', { diff --git a/addons/docs/src/frameworks/angular/sourceDecorator.ts b/addons/docs/src/frameworks/angular/sourceDecorator.ts index 0f624f0029c..496a316f55c 100644 --- a/addons/docs/src/frameworks/angular/sourceDecorator.ts +++ b/addons/docs/src/frameworks/angular/sourceDecorator.ts @@ -1,5 +1,5 @@ import { addons } from '@storybook/addons'; -import { StoryFn } from '@storybook/csf'; +import { PartialStoryFn } from '@storybook/csf'; import { StoryContext, AngularFramework } from '@storybook/angular'; import { computesTemplateSourceFromComponent } from '@storybook/angular/renderer'; import prettierHtml from 'prettier/parser-html'; @@ -31,7 +31,10 @@ const prettyUp = (source: string) => { * @param storyFn Fn * @param context StoryContext */ -export const sourceDecorator = (storyFn: StoryFn, context: StoryContext) => { +export const sourceDecorator = ( + storyFn: PartialStoryFn, + context: StoryContext +) => { const story = storyFn(); if (skipSourceRender(context)) { return story; diff --git a/addons/docs/src/frameworks/html/prepareForInline.tsx b/addons/docs/src/frameworks/html/prepareForInline.tsx index bac3077faa7..421b9625f68 100644 --- a/addons/docs/src/frameworks/html/prepareForInline.tsx +++ b/addons/docs/src/frameworks/html/prepareForInline.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { StoryFn } from '@storybook/csf'; +import { PartialStoryFn } from '@storybook/csf'; -export function prepareForInline(storyFn: StoryFn) { +export function prepareForInline(storyFn: PartialStoryFn) { const html = storyFn(); if (typeof html === 'string') { // eslint-disable-next-line react/no-danger diff --git a/addons/docs/src/frameworks/html/sourceDecorator.ts b/addons/docs/src/frameworks/html/sourceDecorator.ts index 97f3a15e862..c37143f4ee2 100644 --- a/addons/docs/src/frameworks/html/sourceDecorator.ts +++ b/addons/docs/src/frameworks/html/sourceDecorator.ts @@ -1,6 +1,6 @@ /* global window */ import { addons } from '@storybook/addons'; -import { ArgsStoryFn, StoryContext, StoryFn } from '@storybook/csf'; +import { ArgsStoryFn, PartialStoryFn, StoryContext } from '@storybook/csf'; import dedent from 'ts-dedent'; import { HtmlFramework } from '@storybook/html'; @@ -33,7 +33,7 @@ function applyTransformSource(source: string, context: StoryContext, + storyFn: PartialStoryFn, context: StoryContext ) { const story = context?.parameters.docs?.source?.excludeDecorators diff --git a/addons/docs/src/frameworks/react/config.ts b/addons/docs/src/frameworks/react/config.ts index e6ab614d006..28ef4afc0e4 100644 --- a/addons/docs/src/frameworks/react/config.ts +++ b/addons/docs/src/frameworks/react/config.ts @@ -1,4 +1,4 @@ -import { StoryFn } from '@storybook/csf'; +import { PartialStoryFn } from '@storybook/csf'; import { ReactFramework } from '@storybook/react'; import { extractArgTypes } from './extractArgTypes'; @@ -9,7 +9,7 @@ export const parameters = { docs: { inlineStories: true, // NOTE: that the result is a react element. Hooks support is provided by the outer code. - prepareForInline: (storyFn: StoryFn) => storyFn(), + prepareForInline: (storyFn: PartialStoryFn) => storyFn(), extractArgTypes, extractComponentDescription, }, diff --git a/addons/docs/src/frameworks/react/jsxDecorator.tsx b/addons/docs/src/frameworks/react/jsxDecorator.tsx index d5730e7d55a..e3a3cc88846 100644 --- a/addons/docs/src/frameworks/react/jsxDecorator.tsx +++ b/addons/docs/src/frameworks/react/jsxDecorator.tsx @@ -4,7 +4,7 @@ import dedent from 'ts-dedent'; import deprecate from 'util-deprecate'; import { addons } from '@storybook/addons'; -import { StoryContext, StoryFn, ArgsStoryFn } from '@storybook/csf'; +import { StoryContext, ArgsStoryFn, PartialStoryFn } from '@storybook/csf'; import { logger } from '@storybook/client-logger'; import { ReactFramework } from '@storybook/react'; @@ -172,7 +172,7 @@ const mdxToJsx = (node: any) => { }; export const jsxDecorator = ( - storyFn: StoryFn, + storyFn: PartialStoryFn, context: StoryContext ) => { const story = storyFn(); diff --git a/addons/docs/src/frameworks/vue/prepareForInline.ts b/addons/docs/src/frameworks/vue/prepareForInline.ts index f96344116b9..6627db5ec96 100644 --- a/addons/docs/src/frameworks/vue/prepareForInline.ts +++ b/addons/docs/src/frameworks/vue/prepareForInline.ts @@ -1,6 +1,6 @@ import React from 'react'; import Vue from 'vue'; -import { StoryFn, StoryContext } from '@storybook/csf'; +import { StoryContext, PartialStoryFn } from '@storybook/csf'; import { VueFramework } from '@storybook/vue'; // Inspired by https://github.com/egoist/vue-to-react, @@ -11,7 +11,7 @@ const COMPONENT = 'STORYBOOK_COMPONENT'; const VALUES = 'STORYBOOK_VALUES'; export const prepareForInline = ( - storyFn: StoryFn, + storyFn: PartialStoryFn, { args }: StoryContext ) => { const component = storyFn(); diff --git a/addons/docs/src/frameworks/vue3/prepareForInline.ts b/addons/docs/src/frameworks/vue3/prepareForInline.ts index ba86c7c1cb9..2f414504289 100644 --- a/addons/docs/src/frameworks/vue3/prepareForInline.ts +++ b/addons/docs/src/frameworks/vue3/prepareForInline.ts @@ -1,13 +1,13 @@ import React from 'react'; import * as Vue from 'vue'; -import { StoryFn, StoryContext } from '@storybook/csf'; +import { StoryContext, PartialStoryFn } from '@storybook/csf'; import { app, VueFramework } from '@storybook/vue3'; // This is cast as `any` to workaround type errors caused by Vue 2 types const { render, h } = Vue as any; export const prepareForInline = ( - storyFn: StoryFn, + storyFn: PartialStoryFn, { args }: StoryContext ) => { const component = storyFn(); diff --git a/addons/docs/src/frameworks/web-components/prepareForInline.ts b/addons/docs/src/frameworks/web-components/prepareForInline.ts index ccc92d6f139..dcdb86c3432 100644 --- a/addons/docs/src/frameworks/web-components/prepareForInline.ts +++ b/addons/docs/src/frameworks/web-components/prepareForInline.ts @@ -1,10 +1,10 @@ -import type { StoryFn } from '@storybook/csf'; +import type { PartialStoryFn } from '@storybook/csf'; import { WebComponentsFramework } from '@storybook/web-components'; import React from 'react'; import { render } from 'lit-html'; -export const prepareForInline = (storyFn: StoryFn) => { +export const prepareForInline = (storyFn: PartialStoryFn) => { class Story extends React.Component { wrapperRef = React.createRef(); diff --git a/addons/docs/src/frameworks/web-components/sourceDecorator.ts b/addons/docs/src/frameworks/web-components/sourceDecorator.ts index cfe8e745185..a6df7744944 100644 --- a/addons/docs/src/frameworks/web-components/sourceDecorator.ts +++ b/addons/docs/src/frameworks/web-components/sourceDecorator.ts @@ -1,6 +1,6 @@ /* global window */ import { render } from 'lit-html'; -import { ArgsStoryFn, StoryContext, StoryFn } from '@storybook/csf'; +import { ArgsStoryFn, PartialStoryFn, StoryContext } from '@storybook/csf'; import { addons } from '@storybook/addons'; import { WebComponentsFramework } from '@storybook/web-components'; @@ -30,7 +30,7 @@ function applyTransformSource( } export function sourceDecorator( - storyFn: StoryFn, + storyFn: PartialStoryFn, context: StoryContext ) { const story = context?.parameters.docs?.source?.excludeDecorators diff --git a/app/angular/src/client/preview/angular/helpers.ts b/app/angular/src/client/preview/angular/helpers.ts index 3bf7a108d93..bad80b39bf9 100644 --- a/app/angular/src/client/preview/angular/helpers.ts +++ b/app/angular/src/client/preview/angular/helpers.ts @@ -5,7 +5,7 @@ import { FormsModule } from '@angular/forms'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { Observable, ReplaySubject, Subscriber } from 'rxjs'; -import { StoryFn } from '@storybook/csf'; +import { PartialStoryFn } from '@storybook/csf'; import { AppComponent } from './components/app.component'; import { STORY } from './app.token'; import { NgModuleMetadata, StoryFnAngularReturnType } from '../types'; @@ -133,7 +133,7 @@ const getExistenceOfComponentInModules = ( }); }; -const initModule = (storyFn: StoryFn) => { +const initModule = (storyFn: PartialStoryFn) => { const storyObj = storyFn(); const { component, template, props, styles, moduleMetadata = {} } = storyObj; @@ -201,7 +201,7 @@ const draw = (newModule: DynamicComponentType): void => { } }; -export const renderNgApp = (storyFn: StoryFn, forced: boolean) => { +export const renderNgApp = (storyFn: PartialStoryFn, forced: boolean) => { if (!forced) { draw(initModule(storyFn)); } else { diff --git a/app/angular/src/client/preview/decorateStory.ts b/app/angular/src/client/preview/decorateStory.ts index a64238706e3..0b90512d4dd 100644 --- a/app/angular/src/client/preview/decorateStory.ts +++ b/app/angular/src/client/preview/decorateStory.ts @@ -1,15 +1,15 @@ -import { DecoratorFunction, StoryContext, StoryFn } from '@storybook/csf'; +import { DecoratorFunction, LegacyStoryFn, StoryContext, StoryFn } from '@storybook/csf'; import { sanitizeStoryContextUpdate } from '@storybook/store'; import { computesTemplateFromComponent } from './angular-beta/ComputesTemplateFromComponent'; import { AngularFramework } from './types-6-0'; export default function decorateStory( - mainStoryFn: StoryFn, + mainStoryFn: LegacyStoryFn, decorators: DecoratorFunction[] -): StoryFn { +): LegacyStoryFn { const returnDecorators = [cleanArgsDecorator, ...decorators].reduce( - (previousStoryFn: StoryFn, decorator) => ( + (previousStoryFn: LegacyStoryFn, decorator) => ( context: StoryContext ) => { const decoratedStory = decorator((update) => { diff --git a/app/svelte/src/client/preview/decorators.ts b/app/svelte/src/client/preview/decorators.ts index f1ca5fa71f6..5c81c5354cc 100644 --- a/app/svelte/src/client/preview/decorators.ts +++ b/app/svelte/src/client/preview/decorators.ts @@ -1,4 +1,4 @@ -import { StoryFn, DecoratorFunction, StoryContext } from '@storybook/csf'; +import { DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/csf'; import { sanitizeStoryContextUpdate } from '@storybook/store'; import SlotDecorator from './SlotDecorator.svelte'; import { SvelteFramework } from './types'; @@ -65,9 +65,10 @@ function prepareStory(context: StoryContext, story: any, origin export function decorateStory(storyFn: any, decorators: any[]) { return decorators.reduce( - (previousStoryFn: StoryFn, decorator: DecoratorFunction) => ( - context: StoryContext - ) => { + ( + previousStoryFn: LegacyStoryFn, + decorator: DecoratorFunction + ) => (context: StoryContext) => { let story; const decoratedStory = decorator((update) => { story = previousStoryFn({ diff --git a/app/vue/src/client/preview/index.ts b/app/vue/src/client/preview/index.ts index bf064f37553..f733d2b44a7 100644 --- a/app/vue/src/client/preview/index.ts +++ b/app/vue/src/client/preview/index.ts @@ -1,7 +1,7 @@ /* eslint-disable prefer-destructuring */ import Vue, { VueConstructor, ComponentOptions } from 'vue'; import { start } from '@storybook/core/client'; -import { StoryFn, DecoratorFunction, StoryContext } from '@storybook/csf'; +import { DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import { sanitizeStoryContextUpdate } from '@storybook/store'; @@ -61,11 +61,13 @@ function prepare( } function decorateStory( - storyFn: StoryFn, + storyFn: LegacyStoryFn, decorators: DecoratorFunction[] -): StoryFn { +): LegacyStoryFn { return decorators.reduce( - (decorated: StoryFn, decorator) => (context: StoryContext) => { + (decorated: LegacyStoryFn, decorator) => ( + context: StoryContext + ) => { let story; const decoratedStory = decorator((update) => { diff --git a/app/vue3/src/client/preview/index.ts b/app/vue3/src/client/preview/index.ts index 7c8fdac5e93..e8302827ab0 100644 --- a/app/vue3/src/client/preview/index.ts +++ b/app/vue3/src/client/preview/index.ts @@ -1,7 +1,7 @@ import type { ConcreteComponent, Component, ComponentOptions, App } from 'vue'; import { h } from 'vue'; import { start } from '@storybook/core/client'; -import { StoryFn, DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/csf'; +import { DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/csf'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import { sanitizeStoryContextUpdate } from '@storybook/store'; @@ -47,7 +47,7 @@ function prepare( } function decorateStory( - storyFn: StoryFn, + storyFn: LegacyStoryFn, decorators: DecoratorFunction[] ): LegacyStoryFn { return decorators.reduce( diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 21be7dc4301..2df7deacd3e 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -6,6 +6,7 @@ import { AnyFramework, ProjectAnnotations, ComponentTitle, + StoryContext, } from '@storybook/csf'; import mapValues from 'lodash/mapValues'; import pick from 'lodash/pick'; @@ -322,12 +323,14 @@ export class StoryStore { const story = this.storyFromCSFFile({ storyId, csfFile }); return { ...story, - storyFn: (context) => - story.unboundStoryFn({ + storyFn: (update) => { + const context = { ...this.getStoryContext(story), viewMode: 'story', - ...context, - }), + } as StoryContext; + + return story.unboundStoryFn({ ...context, ...update }); + }, }; } } diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index 1acbd0d4cc8..fb8d4d4f953 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -18,6 +18,7 @@ import { StrictArgTypes, StrictGlobalTypes, ComponentId, + PartialStoryFn, } from '@storybook/csf'; export type Path = string; @@ -63,7 +64,7 @@ export type Story = StoryContextForEnhancers = Story & { - storyFn: LegacyStoryFn; + storyFn: PartialStoryFn; }; export declare type RenderContext = StoryIdentifier & { @@ -72,7 +73,7 @@ export declare type RenderContext = StoryIdenti showException: (err: Error) => void; forceRemount: boolean; storyContext: StoryContext; - storyFn: LegacyStoryFn; + storyFn: PartialStoryFn; unboundStoryFn: LegacyStoryFn; }; From f67d9e8a8c26cf05b2a2461202158383ef5b1e8f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 00:10:17 +1000 Subject: [PATCH 219/285] Remove autotitle story from angular --- .../src/stories/preview/csf3/story-with-autotitle.stories.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts b/examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts index b5eab909f9f..b4bd204c6a1 100644 --- a/examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts +++ b/examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts @@ -1,6 +1,8 @@ import { AppComponent } from '../../../app/app.component'; export default { + // Autotitle not currently supported outside of v7 store> + title: 'Preview/CSF3/Autotitle', component: AppComponent, }; From 20bc63eacc06e51015167bdf7ab2007a1e9e1eb7 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 00:15:21 +1000 Subject: [PATCH 220/285] Fix broken `core-server` tests --- .../story-with-autotitle.stories.storyshot | 61 +++++++++++++++++++ lib/core-common/src/utils/to-importFn.ts | 4 +- 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot diff --git a/examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot b/examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot new file mode 100644 index 00000000000..b0944eece40 --- /dev/null +++ b/examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot @@ -0,0 +1,61 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Preview/CSF3/Autotitle Default 1`] = ` + + +
+ This should be hidden, if not - scss is not loaded as needed. + +
+
+

+ Welcome to app! +

+ +
+

+ Here are some links to help you start: +

+
+ + +`; diff --git a/lib/core-common/src/utils/to-importFn.ts b/lib/core-common/src/utils/to-importFn.ts index 58401063486..35a4f5c764c 100644 --- a/lib/core-common/src/utils/to-importFn.ts +++ b/lib/core-common/src/utils/to-importFn.ts @@ -6,14 +6,14 @@ import { toRequireContext } from './to-require-context'; export function toImportFnPart(entry: NormalizedStoriesEntry) { const { path: base, match } = toRequireContext(entry.glob); - const webpackIncludeRegex = new RegExp(match.source.substring(1)); + const webpackIncludeRegex = new RegExp(match.substring(1)); // NOTE: `base` looks like './src' but `path`, (and what micromatch expects) // is something that starts with `src/`. So to strip off base from path, we // need to drop `base.length - 1` chars. return dedent` async (path) => { - if (!${match}.exec(path)) { + if (!/${match}/.exec(path)) { return; } const remainder = path.substring(${base.length - 1}); From eb8ea01f879dfd6bc11eaed1a6bc6ca017d60d51 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 00:15:45 +1000 Subject: [PATCH 221/285] Update two angular snapshots --- .../core/styles/__snapshots__/story-styles.stories.storyshot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot b/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot index 7c6877920fa..83333a30b97 100644 --- a/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot +++ b/examples/angular-cli/src/stories/core/styles/__snapshots__/story-styles.stories.storyshot @@ -3,7 +3,7 @@ exports[`Storyshots Core / Story host styles With Args 1`] = ` @@ -19,7 +19,7 @@ exports[`Storyshots Core / Story host styles With Args 1`] = ` exports[`Storyshots Core / Story host styles With story template 1`] = ` From 26f83f56c9be22bcd09f8932a402b165a9454b9b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 00:30:52 +1000 Subject: [PATCH 222/285] Fix types in a couple of angular tests --- app/angular/src/client/preview/decorateStory.test.ts | 6 +++--- app/angular/src/client/preview/decorators.test.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/angular/src/client/preview/decorateStory.test.ts b/app/angular/src/client/preview/decorateStory.test.ts index 4ee79020eee..316c79b0628 100644 --- a/app/angular/src/client/preview/decorateStory.test.ts +++ b/app/angular/src/client/preview/decorateStory.test.ts @@ -154,7 +154,7 @@ describe('decorateStory', () => { ]; const decorated = decorateStory(() => ({ template: '' }), decorators); - expect(decorated()).toEqual({ + expect(decorated(makeContext({}))).toEqual({ template: '', userDefinedTemplate: true, @@ -220,7 +220,7 @@ describe('decorateStory', () => { ]; const decorated = decorateStory(() => ({ component: FooComponent }), decorators); - expect(decorated()).toEqual({ + expect(decorated(makeContext({}))).toEqual({ template: '', component: FooComponent, @@ -288,7 +288,7 @@ describe('decorateStory', () => { ]; const decorated = decorateStory(() => ({ props: { a: [0] } }), decorators); - expect(decorated()).toEqual({ props: { a: [0, 1, 2, 3] } }); + expect(decorated(makeContext({}))).toEqual({ props: { a: [0, 1, 2, 3] } }); }); it('passes context through to sub decorators', () => { diff --git a/app/angular/src/client/preview/decorators.test.ts b/app/angular/src/client/preview/decorators.test.ts index 58d008b3780..ed72890e860 100644 --- a/app/angular/src/client/preview/decorators.test.ts +++ b/app/angular/src/client/preview/decorators.test.ts @@ -120,7 +120,7 @@ describe('moduleMetadata', () => { const [storybook] = getStorybook(); - expect(storybook.stories[0].render().moduleMetadata).toEqual({ + expect(storybook.stories[0].render({}).moduleMetadata).toEqual({ declarations: [MockComponent], providers: [MockService], entryComponents: [MockComponent], From d83104c6fb396f0681739bfd9d2d2855fe8d8382 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 00:31:06 +1000 Subject: [PATCH 223/285] Remove unused import --- app/angular/src/client/preview/decorateStory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/angular/src/client/preview/decorateStory.ts b/app/angular/src/client/preview/decorateStory.ts index 0b90512d4dd..fbd70c8285d 100644 --- a/app/angular/src/client/preview/decorateStory.ts +++ b/app/angular/src/client/preview/decorateStory.ts @@ -1,4 +1,4 @@ -import { DecoratorFunction, LegacyStoryFn, StoryContext, StoryFn } from '@storybook/csf'; +import { DecoratorFunction, LegacyStoryFn, StoryContext } from '@storybook/csf'; import { sanitizeStoryContextUpdate } from '@storybook/store'; import { computesTemplateFromComponent } from './angular-beta/ComputesTemplateFromComponent'; From b4b59dfea1a02aef297ef027134112c723c79668 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 00:38:06 +1000 Subject: [PATCH 224/285] Update csf dep in csf-tools --- .../web-components-kitchen-sink/yarn.lock | 442 +++++++++++------- lib/csf-tools/package.json | 2 +- yarn.lock | 11 +- 3 files changed, 278 insertions(+), 177 deletions(-) diff --git a/examples/web-components-kitchen-sink/yarn.lock b/examples/web-components-kitchen-sink/yarn.lock index 4b37021182b..a50b3e71c34 100644 --- a/examples/web-components-kitchen-sink/yarn.lock +++ b/examples/web-components-kitchen-sink/yarn.lock @@ -1529,6 +1529,13 @@ __metadata: languageName: node linkType: hard +"@discoveryjs/json-ext@npm:^0.5.3": + version: 0.5.3 + resolution: "@discoveryjs/json-ext@npm:0.5.3" + checksum: 73789df18a61dfd91d839b95c403af9ba32b897c5b419d9a724de588099ce6cefc379ada7617a77dad967b6a026927faa65f55154205cfe88da8c0fca3da2986 + languageName: node + linkType: hard + "@emotion/cache@npm:^10.0.27": version: 10.0.29 resolution: "@emotion/cache@npm:10.0.29" @@ -2083,14 +2090,14 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addon-a11y@portal:../../addons/a11y::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/channels": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/channels": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/theming": 6.4.0-alpha.34 axe-core: ^4.2.0 core-js: ^3.8.2 global: ^4.4.0 @@ -2114,12 +2121,12 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addon-actions@portal:../../addons/actions::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -2146,12 +2153,13 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addon-backgrounds@portal:../../addons/backgrounds::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 global: ^4.4.0 memoizerific: ^1.11.3 @@ -2173,13 +2181,16 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addon-controls@portal:../../addons/controls::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/node-logger": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/node-logger": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 + "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 + lodash: ^4.17.20 ts-dedent: ^2.0.0 peerDependencies: react: ^16.8.0 || ^17.0.0 @@ -2205,20 +2216,22 @@ __metadata: "@mdx-js/loader": ^1.6.22 "@mdx-js/mdx": ^1.6.22 "@mdx-js/react": ^1.6.22 - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/builder-webpack4": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/core": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/csf": 0.0.1 - "@storybook/csf-tools": 6.4.0-alpha.22 - "@storybook/node-logger": 6.4.0-alpha.22 - "@storybook/postinstall": 6.4.0-alpha.22 - "@storybook/source-loader": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/builder-webpack4": 6.4.0-alpha.34 + "@storybook/client-api": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/core": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf-tools": 6.4.0-alpha.34 + "@storybook/node-logger": 6.4.0-alpha.34 + "@storybook/postinstall": 6.4.0-alpha.34 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/source-loader": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 + "@storybook/theming": 6.4.0-alpha.34 acorn: ^7.4.1 acorn-jsx: ^5.3.1 acorn-walk: ^7.2.0 @@ -2233,7 +2246,7 @@ __metadata: lodash: ^4.17.20 nanoid: ^3.1.23 p-limit: ^3.1.0 - prettier: ~2.2.1 + prettier: ^2.2.1 prop-types: ^15.7.2 react-element-to-jsx-string: ^14.3.2 regenerator-runtime: ^0.13.7 @@ -2242,10 +2255,12 @@ __metadata: ts-dedent: ^2.0.0 util-deprecate: ^1.0.2 peerDependencies: - "@storybook/angular": 6.4.0-alpha.22 - "@storybook/vue": 6.4.0-alpha.22 - "@storybook/vue3": 6.4.0-alpha.22 - "@storybook/web-components": 6.4.0-alpha.22 + "@storybook/angular": 6.4.0-alpha.34 + "@storybook/html": 6.4.0-alpha.34 + "@storybook/react": 6.4.0-alpha.34 + "@storybook/vue": 6.4.0-alpha.34 + "@storybook/vue3": 6.4.0-alpha.34 + "@storybook/web-components": 6.4.0-alpha.34 lit: ^2.0.0-rc.1 lit-html: ^1.4.1 || ^2.0.0-rc.3 react: ^16.8.0 || ^17.0.0 @@ -2257,6 +2272,8 @@ __metadata: peerDependenciesMeta: "@storybook/angular": optional: true + "@storybook/react": + optional: true "@storybook/vue": optional: true "@storybook/vue3": @@ -2312,11 +2329,11 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addon-links@portal:../../addons/links::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/csf": 0.0.1 - "@storybook/router": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/router": 6.4.0-alpha.34 "@types/qs": ^6.9.5 core-js: ^3.8.2 global: ^4.4.0 @@ -2340,10 +2357,12 @@ __metadata: resolution: "@storybook/addon-storyshots@portal:../../addons/storyshots/storyshots-core::locator=web-components-kitchen-sink%40workspace%3A." dependencies: "@jest/transform": ^26.6.2 - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/core": 6.4.0-alpha.22 - "@storybook/core-common": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/client-api": 6.4.0-alpha.34 + "@storybook/core": 6.4.0-alpha.34 + "@storybook/core-client": 6.4.0-alpha.34 + "@storybook/core-common": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@types/glob": ^7.1.3 "@types/jest": ^26.0.16 "@types/jest-specific-snapshot": ^0.5.3 @@ -2413,17 +2432,17 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addon-storysource@portal:../../addons/storysource::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/router": 6.4.0-alpha.22 - "@storybook/source-loader": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/router": 6.4.0-alpha.34 + "@storybook/source-loader": 6.4.0-alpha.34 + "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 estraverse: ^5.2.0 loader-utils: ^2.0.0 - prettier: ~2.2.1 + prettier: ^2.2.1 prop-types: ^15.7.2 react-syntax-highlighter: ^13.5.3 regenerator-runtime: ^0.13.7 @@ -2442,12 +2461,12 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addon-viewport@portal:../../addons/viewport::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 global: ^4.4.0 memoizerific: ^1.11.3 @@ -2468,12 +2487,13 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/addons@portal:../../lib/addons::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/api": 6.4.0-alpha.22 - "@storybook/channels": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/router": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/channels": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/router": 6.4.0-alpha.34 + "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 global: ^4.4.0 regenerator-runtime: ^0.13.7 @@ -2488,13 +2508,13 @@ __metadata: resolution: "@storybook/api@portal:../../lib/api::locator=web-components-kitchen-sink%40workspace%3A." dependencies: "@reach/router": ^1.3.4 - "@storybook/channels": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/csf": 0.0.1 - "@storybook/router": 6.4.0-alpha.22 + "@storybook/channels": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/theming": 6.4.0-alpha.34 "@types/reach__router": ^1.3.7 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 @@ -2538,24 +2558,26 @@ __metadata: "@babel/preset-env": ^7.12.11 "@babel/preset-react": ^7.12.10 "@babel/preset-typescript": ^7.12.7 - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/channel-postmessage": 6.4.0-alpha.22 - "@storybook/channels": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/core-common": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/node-logger": 6.4.0-alpha.22 - "@storybook/router": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/channel-postmessage": 6.4.0-alpha.34 + "@storybook/channels": 6.4.0-alpha.34 + "@storybook/client-api": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/core-common": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/node-logger": 6.4.0-alpha.34 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 - "@storybook/theming": 6.4.0-alpha.22 - "@storybook/ui": 6.4.0-alpha.22 + "@storybook/store": 6.4.0-alpha.34 + "@storybook/theming": 6.4.0-alpha.34 + "@storybook/ui": 6.4.0-alpha.34 "@types/node": ^14.0.10 "@types/webpack": ^4.41.26 autoprefixer: ^9.8.6 - babel-loader: ^8.2.2 + babel-loader: ^8.0.0 babel-plugin-macros: ^2.8.0 babel-plugin-polyfill-corejs3: ^0.1.0 case-sensitive-paths-webpack-plugin: ^2.3.0 @@ -2565,7 +2587,6 @@ __metadata: file-loader: ^6.2.0 find-up: ^5.0.0 fork-ts-checker-webpack-plugin: ^4.1.6 - fs-extra: ^9.0.1 glob: ^7.1.6 glob-promise: ^3.4.0 global: ^4.4.0 @@ -2600,9 +2621,9 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/channel-postmessage@portal:../../lib/channel-postmessage::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/channels": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 + "@storybook/channels": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 core-js: ^3.8.2 global: ^4.4.0 qs: ^6.10.0 @@ -2624,15 +2645,17 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/client-api@portal:../../lib/client-api::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/channel-postmessage": 6.4.0-alpha.22 - "@storybook/channels": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/csf": 0.0.1 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/channel-postmessage": 6.4.0-alpha.34 + "@storybook/channels": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/store": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 + fast-deep-equal: ^3.1.3 global: ^4.4.0 lodash: ^4.17.20 memoizerific: ^1.11.3 @@ -2662,9 +2685,9 @@ __metadata: resolution: "@storybook/components@portal:../../lib/components::locator=web-components-kitchen-sink%40workspace%3A." dependencies: "@popperjs/core": ^2.6.0 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/csf": 0.0.1 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/theming": 6.4.0-alpha.34 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 "@types/react-syntax-highlighter": 11.0.5 @@ -2695,13 +2718,15 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/core-client@portal:../../lib/core-client::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/channel-postmessage": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/csf": 0.0.1 - "@storybook/ui": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/channel-postmessage": 6.4.0-alpha.34 + "@storybook/client-api": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 + "@storybook/ui": 6.4.0-alpha.34 airbnb-js-shims: ^2.2.1 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -2709,6 +2734,7 @@ __metadata: lodash: ^4.17.20 qs: ^6.10.0 regenerator-runtime: ^0.13.7 + slash: ^3.0.0 ts-dedent: ^2.0.0 unfetch: ^4.2.0 util-deprecate: ^1.0.2 @@ -2747,12 +2773,12 @@ __metadata: "@babel/preset-react": ^7.12.10 "@babel/preset-typescript": ^7.12.7 "@babel/register": ^7.12.1 - "@storybook/node-logger": 6.4.0-alpha.22 + "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 "@types/micromatch": ^4.0.1 "@types/node": ^14.0.10 "@types/pretty-hrtime": ^1.0.0 - babel-loader: ^8.2.2 + babel-loader: ^8.0.0 babel-plugin-macros: ^3.0.1 babel-plugin-polyfill-corejs3: ^0.1.0 chalk: ^4.1.0 @@ -2761,7 +2787,9 @@ __metadata: file-system-cache: ^1.0.5 find-up: ^5.0.0 fork-ts-checker-webpack-plugin: ^6.0.4 + fs-extra: ^9.0.1 glob: ^7.1.6 + handlebars: ^4.7.7 interpret: ^2.2.0 json5: ^2.1.3 lazy-universal-dotenv: ^3.0.1 @@ -2793,12 +2821,13 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/core-server@portal:../../lib/core-server::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/builder-webpack4": 6.4.0-alpha.22 - "@storybook/core-client": 6.4.0-alpha.22 - "@storybook/core-common": 6.4.0-alpha.22 - "@storybook/csf-tools": 6.4.0-alpha.22 - "@storybook/manager-webpack4": 6.4.0-alpha.22 - "@storybook/node-logger": 6.4.0-alpha.22 + "@discoveryjs/json-ext": ^0.5.3 + "@storybook/builder-webpack4": 6.4.0-alpha.34 + "@storybook/core-client": 6.4.0-alpha.34 + "@storybook/core-common": 6.4.0-alpha.34 + "@storybook/csf-tools": 6.4.0-alpha.34 + "@storybook/manager-webpack4": 6.4.0-alpha.34 + "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 "@types/node": ^14.0.10 "@types/node-fetch": ^2.5.7 @@ -2811,7 +2840,7 @@ __metadata: commander: ^6.2.1 compression: ^1.7.4 core-js: ^3.8.2 - cpy: ^8.1.1 + cpy: ^8.1.2 detect-port: ^1.3.0 express: ^4.17.1 file-system-cache: ^1.0.5 @@ -2827,8 +2856,8 @@ __metadata: util-deprecate: ^1.0.2 webpack: 4 peerDependencies: - "@storybook/builder-webpack5": 6.4.0-alpha.22 - "@storybook/manager-webpack5": 6.4.0-alpha.22 + "@storybook/builder-webpack5": 6.4.0-alpha.34 + "@storybook/manager-webpack5": 6.4.0-alpha.34 react: ^16.8.0 || ^17.0.0 react-dom: ^16.8.0 || ^17.0.0 peerDependenciesMeta: @@ -2845,10 +2874,10 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/core@portal:../../lib/core::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/core-client": 6.4.0-alpha.22 - "@storybook/core-server": 6.4.0-alpha.22 + "@storybook/core-client": 6.4.0-alpha.34 + "@storybook/core-server": 6.4.0-alpha.34 peerDependencies: - "@storybook/builder-webpack5": 6.4.0-alpha.22 + "@storybook/builder-webpack5": 6.4.0-alpha.34 react: ^16.8.0 || ^17.0.0 react-dom: ^16.8.0 || ^17.0.0 webpack: "*" @@ -2872,23 +2901,23 @@ __metadata: "@babel/traverse": ^7.12.11 "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": ^0.0.1 + "@storybook/csf": 0.0.2--canary.5459c65.0 core-js: ^3.8.2 fs-extra: ^9.0.1 global: ^4.4.0 js-string-escape: ^1.0.1 lodash: ^4.17.20 - prettier: ~2.2.1 + prettier: ^2.2.1 regenerator-runtime: ^0.13.7 languageName: node linkType: soft -"@storybook/csf@npm:0.0.1, @storybook/csf@npm:^0.0.1": - version: 0.0.1 - resolution: "@storybook/csf@npm:0.0.1" +"@storybook/csf@npm:0.0.2--canary.5459c65.0": + version: 0.0.2--canary.5459c65.0 + resolution: "@storybook/csf@npm:0.0.2--canary.5459c65.0" dependencies: lodash: ^4.17.15 - checksum: 7b0f75763415f9147692a460b44417ee56ea9639433716a1fd4d1df4c8b0221cbc71b8da0fbed4dcecb3ccd6c7ed64be39f5c255c713539a6088a1d6488aaa24 + checksum: 67e8adfddbc4eb96f6cfdca0fe03cfcac460302489bde3b99d31f88eab14759d7d856592871434cd2d8caffebb465f8b81c87576ecb9da755baace09f83b5c57 languageName: node linkType: hard @@ -2899,15 +2928,15 @@ __metadata: "@babel/core": ^7.12.10 "@babel/plugin-transform-template-literals": ^7.12.1 "@babel/preset-react": ^7.12.10 - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/core-client": 6.4.0-alpha.22 - "@storybook/core-common": 6.4.0-alpha.22 - "@storybook/node-logger": 6.4.0-alpha.22 - "@storybook/theming": 6.4.0-alpha.22 - "@storybook/ui": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/core-client": 6.4.0-alpha.34 + "@storybook/core-common": 6.4.0-alpha.34 + "@storybook/node-logger": 6.4.0-alpha.34 + "@storybook/theming": 6.4.0-alpha.34 + "@storybook/ui": 6.4.0-alpha.34 "@types/node": ^14.0.10 "@types/webpack": ^4.41.26 - babel-loader: ^8.2.2 + babel-loader: ^8.0.0 case-sensitive-paths-webpack-plugin: ^2.3.0 chalk: ^4.1.0 core-js: ^3.8.2 @@ -2962,12 +2991,37 @@ __metadata: languageName: node linkType: soft +"@storybook/preview-web@portal:../../lib/preview-web::locator=web-components-kitchen-sink%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@storybook/preview-web@portal:../../lib/preview-web::locator=web-components-kitchen-sink%40workspace%3A." + dependencies: + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/channel-postmessage": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/store": 6.4.0-alpha.34 + ansi-to-html: ^0.6.11 + core-js: ^3.8.2 + global: ^4.4.0 + lodash: ^4.17.20 + qs: ^6.10.0 + regenerator-runtime: ^0.13.7 + ts-dedent: ^2.0.0 + unfetch: ^4.2.0 + util-deprecate: ^1.0.2 + peerDependencies: + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + languageName: node + linkType: soft + "@storybook/router@portal:../../lib/router::locator=web-components-kitchen-sink%40workspace%3A.": version: 0.0.0-use.local resolution: "@storybook/router@portal:../../lib/router::locator=web-components-kitchen-sink%40workspace%3A." dependencies: "@reach/router": ^1.3.4 - "@storybook/client-logger": 6.4.0-alpha.22 + "@storybook/client-logger": 6.4.0-alpha.34 "@types/reach__router": ^1.3.7 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 @@ -2998,15 +3052,15 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/source-loader@portal:../../lib/source-loader::locator=web-components-kitchen-sink%40workspace%3A." dependencies: - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/csf": 0.0.1 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 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 + prettier: ^2.2.1 regenerator-runtime: ^0.13.7 peerDependencies: react: ^16.8.0 || ^17.0.0 @@ -3014,6 +3068,25 @@ __metadata: languageName: node linkType: soft +"@storybook/store@portal:../../lib/store::locator=web-components-kitchen-sink%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@storybook/store@portal:../../lib/store::locator=web-components-kitchen-sink%40workspace%3A." + dependencies: + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + core-js: ^3.8.2 + fast-deep-equal: ^3.1.3 + global: ^4.4.0 + lodash: ^4.17.20 + memoizerific: ^1.11.3 + regenerator-runtime: ^0.13.7 + ts-dedent: ^2.0.0 + util-deprecate: ^1.0.2 + languageName: node + linkType: soft + "@storybook/theming@portal:../../lib/theming::locator=web-components-kitchen-sink%40workspace%3A.": version: 0.0.0-use.local resolution: "@storybook/theming@portal:../../lib/theming::locator=web-components-kitchen-sink%40workspace%3A." @@ -3021,7 +3094,7 @@ __metadata: "@emotion/core": ^10.1.1 "@emotion/is-prop-valid": ^0.8.6 "@emotion/styled": ^10.0.27 - "@storybook/client-logger": 6.4.0-alpha.22 + "@storybook/client-logger": 6.4.0-alpha.34 core-js: ^3.8.2 deep-object-diff: ^1.1.0 emotion-theming: ^10.0.27 @@ -3041,15 +3114,15 @@ __metadata: resolution: "@storybook/ui@portal:../../lib/ui::locator=web-components-kitchen-sink%40workspace%3A." dependencies: "@emotion/core": ^10.1.1 - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/api": 6.4.0-alpha.22 - "@storybook/channels": 6.4.0-alpha.22 - "@storybook/client-logger": 6.4.0-alpha.22 - "@storybook/components": 6.4.0-alpha.22 - "@storybook/core-events": 6.4.0-alpha.22 - "@storybook/router": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/api": 6.4.0-alpha.34 + "@storybook/channels": 6.4.0-alpha.34 + "@storybook/client-logger": 6.4.0-alpha.34 + "@storybook/components": 6.4.0-alpha.34 + "@storybook/core-events": 6.4.0-alpha.34 + "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 - "@storybook/theming": 6.4.0-alpha.22 + "@storybook/theming": 6.4.0-alpha.34 copy-to-clipboard: ^3.3.1 core-js: ^3.8.2 core-js-pure: ^3.8.2 @@ -3081,10 +3154,13 @@ __metadata: "@babel/plugin-syntax-dynamic-import": ^7.8.3 "@babel/plugin-syntax-import-meta": ^7.10.4 "@babel/preset-env": ^7.12.11 - "@storybook/addons": 6.4.0-alpha.22 - "@storybook/client-api": 6.4.0-alpha.22 - "@storybook/core": 6.4.0-alpha.22 - "@storybook/core-common": 6.4.0-alpha.22 + "@storybook/addons": 6.4.0-alpha.34 + "@storybook/client-api": 6.4.0-alpha.34 + "@storybook/core": 6.4.0-alpha.34 + "@storybook/core-common": 6.4.0-alpha.34 + "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/preview-web": 6.4.0-alpha.34 + "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 babel-plugin-bundled-import-meta: ^0.3.1 core-js: ^3.8.2 @@ -4262,7 +4338,7 @@ __metadata: languageName: node linkType: hard -"babel-loader@npm:^8.2.2": +"babel-loader@npm:^8.0.0": version: 8.2.2 resolution: "babel-loader@npm:8.2.2" dependencies: @@ -5565,7 +5641,7 @@ __metadata: languageName: node linkType: hard -"cpy@npm:^8.1.1": +"cpy@npm:^8.1.2": version: 8.1.2 resolution: "cpy@npm:8.1.2" dependencies: @@ -7405,6 +7481,24 @@ fsevents@^1.2.7: languageName: node linkType: hard +"handlebars@npm:^4.7.7": + version: 4.7.7 + resolution: "handlebars@npm:4.7.7" + dependencies: + minimist: ^1.2.5 + neo-async: ^2.6.0 + source-map: ^0.6.1 + uglify-js: ^3.1.4 + wordwrap: ^1.0.0 + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 4c0913fc0018a2a2e358ee94e4fe83f071762b8bec51a473d187e6642e94e569843adcf550ffe329554c63ad450c062f3a05447bd2e3fff5ebfe698e214225c6 + languageName: node + linkType: hard + "has-bigints@npm:^1.0.1": version: 1.0.1 resolution: "has-bigints@npm:1.0.1" @@ -10226,7 +10320,7 @@ fsevents@^1.2.7: languageName: node linkType: hard -"neo-async@npm:^2.5.0, neo-async@npm:^2.6.1": +"neo-async@npm:^2.5.0, neo-async@npm:^2.6.0, neo-async@npm:^2.6.1": version: 2.6.2 resolution: "neo-async@npm:2.6.2" checksum: c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d @@ -11150,12 +11244,12 @@ fsevents@^1.2.7: languageName: node linkType: hard -"prettier@npm:~2.2.1": - version: 2.2.1 - resolution: "prettier@npm:2.2.1" +"prettier@npm:^2.2.1": + version: 2.3.2 + resolution: "prettier@npm:2.3.2" bin: prettier: bin-prettier.js - checksum: 4041ff87d6cba9134a8e0eb74a9e7f50f7091de6b95f5a6fb1928795c7d0584ae46806e0d75588fbc912b2cda2439d28a14fb84416946384cf71d60f5a0a68a6 + checksum: 40f159f05808966ff4c57e147651cf038adb7f5af3fbca8d999b87ccbaeff7d73cf9038a45f667a8c18cbb049c1a980a752fa8987dfd3dcdd66e932e366f40be languageName: node linkType: hard @@ -13519,6 +13613,15 @@ fsevents@^1.2.7: languageName: node linkType: hard +"uglify-js@npm:^3.1.4": + version: 3.14.1 + resolution: "uglify-js@npm:3.14.1" + bin: + uglifyjs: bin/uglifyjs + checksum: 7f94f30606264236e141b0071051f3541df0392a3614001234d220181738e732d661e14e1b7ab28632c8533e035b144464730f96a4707e8d729413087c367417 + languageName: node + linkType: hard + "unbox-primitive@npm:^1.0.1": version: 1.0.1 resolution: "unbox-primitive@npm:1.0.1" @@ -14249,6 +14352,13 @@ fsevents@^1.2.7: languageName: node linkType: hard +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92 + languageName: node + linkType: hard + "worker-farm@npm:^1.7.0": version: 1.7.0 resolution: "worker-farm@npm:1.7.0" diff --git a/lib/csf-tools/package.json b/lib/csf-tools/package.json index 8556870a2f4..5a099423706 100644 --- a/lib/csf-tools/package.json +++ b/lib/csf-tools/package.json @@ -48,7 +48,7 @@ "@babel/traverse": "^7.12.11", "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "^0.0.1", + "@storybook/csf": "0.0.2--canary.5459c65.0", "core-js": "^3.8.2", "fs-extra": "^9.0.1", "global": "^4.4.0", diff --git a/yarn.lock b/yarn.lock index e9fe5cc12c6..7fcf8cc66eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8125,7 +8125,7 @@ __metadata: "@babel/traverse": ^7.12.11 "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": ^0.0.1 + "@storybook/csf": 0.0.2--canary.5459c65.0 "@types/fs-extra": ^9.0.6 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -8148,15 +8148,6 @@ __metadata: languageName: node linkType: hard -"@storybook/csf@npm:^0.0.1": - version: 0.0.1 - resolution: "@storybook/csf@npm:0.0.1" - dependencies: - lodash: ^4.17.15 - checksum: 7b0f75763415f9147692a460b44417ee56ea9639433716a1fd4d1df4c8b0221cbc71b8da0fbed4dcecb3ccd6c7ed64be39f5c255c713539a6088a1d6488aaa24 - languageName: node - linkType: hard - "@storybook/design-system@npm:^5.4.7": version: 5.4.8 resolution: "@storybook/design-system@npm:5.4.8" From 0536851a7dbdd5f7db53d8c8e544eba5234c544e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 08:47:13 +1000 Subject: [PATCH 225/285] Switch order of args / argTypes enhancers --- lib/store/src/prepareStory.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index fef1fa5cdeb..495a85a96c0 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -124,6 +124,12 @@ export function prepareStory( argTypes: passedArgTypes, }; + contextForEnhancers.argTypes = argTypesEnhancers.reduce( + (accumulatedArgTypes, enhancer) => + enhancer({ ...contextForEnhancers, argTypes: accumulatedArgTypes }), + contextForEnhancers.argTypes + ); + contextForEnhancers.initialArgs = argsEnhancers.reduce( (accumulatedArgs: Args, enhancer) => ({ ...accumulatedArgs, @@ -135,12 +141,6 @@ export function prepareStory( initialArgsBeforeEnhancers ); - contextForEnhancers.argTypes = argTypesEnhancers.reduce( - (accumulatedArgTypes, enhancer) => - enhancer({ ...contextForEnhancers, argTypes: accumulatedArgTypes }), - contextForEnhancers.argTypes - ); - // Add some of our metadata into parameters as we used to do this in 6.x and users may be relying on it if (!global.FEATURES?.breakingChangesV7) { contextForEnhancers.parameters = { From b4a75b39ffc9b7a194fd23a0feee157b2f183bae Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 09:59:06 +1000 Subject: [PATCH 226/285] Add getter for `_storyStore` (back compat) --- lib/client-api/src/ClientApi.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index c2ae777b6b5..8c13b7cde47 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -383,4 +383,9 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m raw = () => { return this.storyStore.raw(); }; + + // @deprecated + get _storyStore() { + return this.storyStore; + } } From 0bb2347caef488a66701577f0512552fc4347c2b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 11:13:05 +1000 Subject: [PATCH 227/285] Fix mdx-in-story story --- .../stories/addon-docs/mdx.stories.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/official-storybook/stories/addon-docs/mdx.stories.js b/examples/official-storybook/stories/addon-docs/mdx.stories.js index 49db83e96aa..7142e9c2e35 100644 --- a/examples/official-storybook/stories/addon-docs/mdx.stories.js +++ b/examples/official-storybook/stories/addon-docs/mdx.stories.js @@ -5,7 +5,11 @@ import markdown from './markdown.stories.mdx'; export default { title: 'Addons/Docs/mdx-in-story', - decorators: [(storyFn) => {storyFn()}], + decorators: [ + (storyFn) => ( + ({ parameters: {} }) }}>{storyFn()} + ), + ], parameters: { layout: 'fullscreen', }, @@ -24,7 +28,9 @@ export const DarkModeDocs = () => { DarkModeDocs.decorators = [ (storyFn) => ( - + ({ parameters: { docs: { theme: themes.dark } } }) }} + > {storyFn()} ), From e6698c529a99b525e7ac1d068a6d3cb06f572164 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 14:38:52 +1000 Subject: [PATCH 228/285] Fix argtypes stories --- addons/docs/src/frameworks/react/react-argtypes.stories.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/docs/src/frameworks/react/react-argtypes.stories.tsx b/addons/docs/src/frameworks/react/react-argtypes.stories.tsx index 4006962f1fe..8c576433113 100644 --- a/addons/docs/src/frameworks/react/react-argtypes.stories.tsx +++ b/addons/docs/src/frameworks/react/react-argtypes.stories.tsx @@ -10,8 +10,8 @@ import { Component } from '../../blocks'; const argsTableProps = (component: Component) => { const argTypes = extractArgTypes(component); - const parameters = { __isArgsStory: true, argTypes }; - const rows = inferControls(({ parameters } as unknown) as StoryContext); + const parameters = { __isArgsStory: true }; + const rows = inferControls(({ argTypes, parameters } as unknown) as StoryContext); return { rows }; }; From d2e837a1c631d27ea08a1f5ddc82f9feab302b15 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 14:40:21 +1000 Subject: [PATCH 229/285] Fix ember --- app/ember/src/client/preview/render.ts | 6 +++--- app/ember/src/client/preview/types.ts | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/ember/src/client/preview/render.ts b/app/ember/src/client/preview/render.ts index adc1fc01a8d..afb49e565f0 100644 --- a/app/ember/src/client/preview/render.ts +++ b/app/ember/src/client/preview/render.ts @@ -1,7 +1,7 @@ import global from 'global'; import dedent from 'ts-dedent'; import { RenderContext } from '@storybook/store'; -import { ElementArgs, OptionsArgs, EmberFramework } from './types'; +import { OptionsArgs, EmberFramework } from './types'; const { window: globalWindow, document } = global; @@ -20,7 +20,7 @@ let lastPromise = app.boot(); let hasRendered = false; let isRendering = false; -function render(options: OptionsArgs, el: ElementArgs) { +function render(options: OptionsArgs, el: HTMLElement) { if (isRendering) return; isRendering = true; @@ -80,5 +80,5 @@ export default function renderMain( } showMain(); - render(element, { el: domElement }); + render(element, domElement); } diff --git a/app/ember/src/client/preview/types.ts b/app/ember/src/client/preview/types.ts index e948eed9127..15b8caa9a7e 100644 --- a/app/ember/src/client/preview/types.ts +++ b/app/ember/src/client/preview/types.ts @@ -5,10 +5,6 @@ export interface ShowErrorArgs { description: string; } -export interface ElementArgs { - el: HTMLElement; -} - export interface OptionsArgs { template: any; context: any; From c24a980547ee8c32af648d3d0ccc3b243275152a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 14:42:28 +1000 Subject: [PATCH 230/285] Remove autotitle story from angular SB / fix other --- .../preview/csf3/story-with-autotitle.stories.ts | 11 ----------- .../src/stories/1-Button.stories.tsx | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts diff --git a/examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts b/examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts deleted file mode 100644 index b4bd204c6a1..00000000000 --- a/examples/angular-cli/src/stories/preview/csf3/story-with-autotitle.stories.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { AppComponent } from '../../../app/app.component'; - -export default { - // Autotitle not currently supported outside of v7 store> - title: 'Preview/CSF3/Autotitle', - component: AppComponent, -}; - -export const Default = { - render: (props) => ({ props }), -}; diff --git a/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx b/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx index f9cd3c5119d..6b9a2d25e80 100644 --- a/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx +++ b/examples/cra-ts-kitchen-sink/src/stories/1-Button.stories.tsx @@ -3,7 +3,7 @@ import { action } from '@storybook/addon-actions'; import { Button } from './Button'; export default { - title: 'Button', + title: '1-Button', component: Button, }; From ec23d8c2f7e707c0f1a1b3d494fcaaf74c958ba8 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 14:43:58 +1000 Subject: [PATCH 231/285] Ensure we run argTypes enhancers before pulling defaultValues --- lib/store/src/prepareStory.ts | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 495a85a96c0..39399a69b97 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -90,26 +90,13 @@ export function prepareStory( // eslint-disable-next-line no-underscore-dangle parameters.__isArgsStory = passArgsFirst && render.length > 0; - // Pull out args[X] || argTypes[X].defaultValue into initialArgs + // Pull out args[X] into initialArgs for argTypes enhancers const passedArgs: Args = combineParameters( projectAnnotations.args, componentAnnotations.args, storyAnnotations.args ) as Args; - const defaultArgs: Args = Object.entries( - passedArgTypes as Record - ).reduce((acc, [arg, { defaultValue }]) => { - if (typeof defaultValue !== 'undefined') { - acc[arg] = defaultValue; - } - return acc; - }, {} as Args); - if (Object.keys(defaultArgs).length > 0) { - argTypeDefaultValueWarning(); - } - - const initialArgsBeforeEnhancers = { ...defaultArgs, ...passedArgs }; const contextForEnhancers: StoryContextForEnhancers = { componentId: componentAnnotations.id, title, @@ -120,7 +107,7 @@ export function prepareStory( component: componentAnnotations.component, subcomponents: componentAnnotations.subcomponents, parameters, - initialArgs: initialArgsBeforeEnhancers, + initialArgs: passedArgs, argTypes: passedArgTypes, }; @@ -130,6 +117,23 @@ export function prepareStory( contextForEnhancers.argTypes ); + // Add argTypes[X].defaultValue to initial args (note this deprecated) + // We need to do this *after* the argTypesEnhancers as they may add defaultValues + const defaultArgs: Args = Object.entries(contextForEnhancers.argTypes).reduce( + (acc, [arg, { defaultValue }]) => { + if (typeof defaultValue !== 'undefined') { + acc[arg] = defaultValue; + } + return acc; + }, + {} as Args + ); + if (Object.keys(defaultArgs).length > 0) { + argTypeDefaultValueWarning(); + } + + const initialArgsBeforeEnhancers = { ...defaultArgs, ...passedArgs }; + contextForEnhancers.initialArgs = argsEnhancers.reduce( (accumulatedArgs: Args, enhancer) => ({ ...accumulatedArgs, From 23254408d16d3357b72a05903a85e76b1639e663 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 15:02:34 +1000 Subject: [PATCH 232/285] Wait a tick before apply arg changes and other re-renders. This allows users to update args or re-render the story from *inside* decorators or story functions, for better or worse. --- lib/preview-web/src/PreviewWeb.mockdata.ts | 1 + lib/preview-web/src/PreviewWeb.test.ts | 51 +++++++++++++++++++++- lib/preview-web/src/PreviewWeb.tsx | 9 ++-- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.mockdata.ts b/lib/preview-web/src/PreviewWeb.mockdata.ts index a4d1d5259ab..4c8b9c267d3 100644 --- a/lib/preview-web/src/PreviewWeb.mockdata.ts +++ b/lib/preview-web/src/PreviewWeb.mockdata.ts @@ -95,3 +95,4 @@ export const waitForRender = () => ]); export const waitForQuiescence = async () => new Promise((r) => setTimeout(r, 100)); +export const waitForTick = async () => new Promise((r) => setTimeout(r, 0)); diff --git a/lib/preview-web/src/PreviewWeb.test.ts b/lib/preview-web/src/PreviewWeb.test.ts index 87f4cc501c6..391ad6393ca 100644 --- a/lib/preview-web/src/PreviewWeb.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -18,6 +18,7 @@ import { waitForEvents, waitForRender, waitForQuiescence, + waitForTick, } from './PreviewWeb.mockdata'; jest.mock('./WebView'); @@ -48,7 +49,7 @@ const createGate = (): [Promise, (_?: any) => void] => { return [gate, openGate]; }; -beforeEach(() => { +beforeEach(async () => { document.location.search = ''; mockChannel.emit.mockClear(); emitter.removeAllListeners(); @@ -64,6 +65,9 @@ beforeEach(() => { logger.warn.mockClear(); addons.setChannel(mockChannel as any); + + // Some events happen in the next tick + await waitForTick(); }); describe('PreviewWeb', () => { @@ -629,6 +633,7 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); + await waitForTick(); // Now let the loader resolve openGate({ l: 8 }); @@ -659,6 +664,7 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); + await waitForTick(); expect(logger.warn).toHaveBeenCalled(); // Now let the renderToDOM call resolve @@ -679,6 +685,44 @@ describe('PreviewWeb', () => { ); }); + it('works if it is called directly from inside non async renderToDOM', async () => { + document.location.search = '?id=component-one--a'; + projectAnnotations.renderToDOM.mockImplementationOnce(() => { + emitter.emit(Events.UPDATE_STORY_ARGS, { + storyId: 'component-one--a', + updatedArgs: { new: 'arg' }, + }); + }); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + + await waitForRender(); + mockChannel.emit.mockClear(); + await waitForRender(); + expect(logger.warn).not.toHaveBeenCalled(); + + expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(2); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( + expect.objectContaining({ + forceRemount: true, + storyContext: expect.objectContaining({ + loaded: { l: 7 }, + args: { foo: 'a' }, + }), + }), + undefined // this is coming from view.prepareForStory, not super important + ); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( + expect.objectContaining({ + forceRemount: false, + storyContext: expect.objectContaining({ + loaded: { l: 7 }, + args: { foo: 'a', new: 'arg' }, + }), + }), + undefined // this is coming from view.prepareForStory, not super important + ); + }); + it('warns and calls renderToDOM again if play function is running', async () => { const [gate, openGate] = createGate(); componentOneExports.a.play.mockImplementationOnce(async () => gate); @@ -709,6 +753,7 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); + await waitForTick(); expect(logger.warn).toHaveBeenCalled(); // The second call should emit STORY_RENDERED @@ -769,8 +814,10 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, }); + await waitForRender(); mockChannel.emit.mockClear(); + projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.RESET_STORY_ARGS, { storyId: 'component-one--a', argNames: ['foo'], @@ -802,8 +849,10 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, }); + await waitForRender(); mockChannel.emit.mockClear(); + projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.RESET_STORY_ARGS, { storyId: 'component-one--a', }); diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 4475e7354b5..a79020df9ae 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -488,6 +488,9 @@ export class PreviewWeb { } this.channel.emit(Events.STORY_RENDERED, id); }; + // We wait a moment to re-render the story in case users are doing things like force + // rerender or updating args from inside story functions. + const rerenderStoryOnTick = () => setTimeout(rerenderStory, 0); // Start the first render // NOTE: we don't await here because we need to return the "cleanup" function below @@ -496,10 +499,10 @@ export class PreviewWeb { initialRender().catch((err) => renderContextWithoutStoryContext.showException(err)); // Listen to events and re-render story - this.channel.on(Events.UPDATE_GLOBALS, rerenderStory); - this.channel.on(Events.FORCE_RE_RENDER, rerenderStory); + this.channel.on(Events.UPDATE_GLOBALS, rerenderStoryOnTick); + this.channel.on(Events.FORCE_RE_RENDER, rerenderStoryOnTick); const rerenderStoryIfMatches = async ({ storyId }: { storyId: StoryId }) => { - if (storyId === story.id) rerenderStory(); + if (storyId === story.id) rerenderStoryOnTick(); }; this.channel.on(Events.UPDATE_STORY_ARGS, rerenderStoryIfMatches); this.channel.on(Events.RESET_STORY_ARGS, rerenderStoryIfMatches); From abbd38f69cd6d9ceb12ab44faba0cd8f6a652034 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 15:10:00 +1000 Subject: [PATCH 233/285] Fix globals --- lib/client-api/src/ClientApi.ts | 10 ++++++++-- lib/store/src/prepareStory.ts | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/client-api/src/ClientApi.ts b/lib/client-api/src/ClientApi.ts index 8c13b7cde47..2ea5dd02247 100644 --- a/lib/client-api/src/ClientApi.ts +++ b/lib/client-api/src/ClientApi.ts @@ -196,10 +196,16 @@ export class ClientApi { parameters ); if (globals) { - this.facade.projectAnnotations.globals = globals; + this.facade.projectAnnotations.globals = { + ...this.facade.projectAnnotations.globals, + ...globals, + }; } if (globalTypes) { - this.facade.projectAnnotations.globalTypes = normalizeInputTypes(globalTypes); + this.facade.projectAnnotations.globalTypes = { + ...this.facade.projectAnnotations.globalTypes, + ...normalizeInputTypes(globalTypes), + }; } }; diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 39399a69b97..8e4c666c8f7 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -150,6 +150,7 @@ export function prepareStory( contextForEnhancers.parameters = { ...contextForEnhancers.parameters, __id: id, + globals: projectAnnotations.globals, globalTypes: projectAnnotations.globalTypes, args: contextForEnhancers.initialArgs, argTypes: contextForEnhancers.argTypes, From 2ab56b22d14b22c33a744d017acdaf180f52e8b1 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 15:26:01 +1000 Subject: [PATCH 234/285] Abort controller fallback for IE --- lib/preview-web/src/PreviewWeb.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index a79020df9ae..0a4f468ed02 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -370,7 +370,15 @@ export class PreviewWeb { }) { const { id, applyLoaders, unboundStoryFn, runPlayFunction } = story; - const controller = new AbortController(); + // IE11 doesn't support AbortController, so we either need to polyfill or just not support it + const controller = AbortController + ? new AbortController() + : { + signal: { aborted: false }, + abort() { + this.signal.aborted = true; + }, + }; let initialRenderPhase: InitialRenderPhase = 'init'; let renderContext: RenderContext; const initialRender = async () => { From 956e131556f04ff2f3bbe8d980d760f1ed241f30 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 17:01:21 +1000 Subject: [PATCH 235/285] Update CSF to allow `symbol` --- addons/a11y/package.json | 2 +- addons/actions/package.json | 2 +- addons/backgrounds/package.json | 2 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/links/package.json | 2 +- addons/measure/package.json | 2 +- addons/outline/package.json | 2 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 2 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 2 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 2 +- .../story-with-autotitle.stories.storyshot | 61 ----------------- lib/addons/package.json | 2 +- lib/api/package.json | 2 +- lib/client-api/package.json | 2 +- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/csf-tools/package.json | 2 +- lib/preview-web/package.json | 2 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- lib/store/src/inferArgTypes.test.ts | 2 +- lib/store/src/inferArgTypes.ts | 3 +- lib/store/src/inferControls.ts | 3 +- yarn.lock | 66 +++++++++---------- 34 files changed, 66 insertions(+), 129 deletions(-) delete mode 100644 examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot diff --git a/addons/a11y/package.json b/addons/a11y/package.json index 28d071f17a3..d5309c8a116 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/theming": "6.4.0-alpha.34", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/actions/package.json b/addons/actions/package.json index 6027fbd3052..07f2f7b3bea 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index a27fc0ba1c1..51fbbfb91b7 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,7 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/controls/package.json b/addons/controls/package.json index 9510dd6763e..e92de05f83d 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", diff --git a/addons/docs/package.json b/addons/docs/package.json index be205863aaa..dfb57e93baa 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/postinstall": "6.4.0-alpha.34", diff --git a/addons/links/package.json b/addons/links/package.json index b3a19608a7f..282bb474fc7 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/router": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/measure/package.json b/addons/measure/package.json index d246c59f62d..a9a092cc98d 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,7 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/outline/package.json b/addons/outline/package.json index 473b931351d..d0a747e06e8 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,7 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index 818534caeb6..c0cacaff14b 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-client": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index 98fd9050811..5e0ac929227 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/node-logger": "6.4.0-alpha.34", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index 7f2b561d244..a14cab494c3 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index c3b75ec2cb0..98c9736dc06 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/preact/package.json b/app/preact/package.json index 5ae44e63489..89a8984795b 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/react/package.json b/app/react/package.json index a8fa318c370..d8d57cb6425 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index 9e2e3160a95..39e73404767 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,7 +50,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", diff --git a/app/svelte/package.json b/app/svelte/package.json index 56c75f96ec1..d83ec608b1f 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/store": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index dd50091d8b2..6f94d390577 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index c24c5f69074..7ccee29e8f9 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index 73e58dc0d85..538355e3f80 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot b/examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot deleted file mode 100644 index b0944eece40..00000000000 --- a/examples/angular-cli/src/stories/preview/csf3/__snapshots__/story-with-autotitle.stories.storyshot +++ /dev/null @@ -1,61 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Preview/CSF3/Autotitle Default 1`] = ` - - -
- This should be hidden, if not - scss is not loaded as needed. - -
-
-

- Welcome to app! -

- -
-

- Here are some links to help you start: -

- -
-
-`; diff --git a/lib/addons/package.json b/lib/addons/package.json index e412d0ca884..811c8e5ea1d 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/api/package.json b/lib/api/package.json index aac7d09f092..4f91d1aa725 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.34", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index 7a1e447da59..c46784d1ab4 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -45,7 +45,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/store": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index e6d84c48679..14d8cb0e0d2 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index ac97bd4201d..6995b89dc4e 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/theming": "6.4.0-alpha.34", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index 1dbee39c58d..76aafeffd4f 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/ui": "6.4.0-alpha.34", diff --git a/lib/csf-tools/package.json b/lib/csf-tools/package.json index 5a099423706..b737bbdf928 100644 --- a/lib/csf-tools/package.json +++ b/lib/csf-tools/package.json @@ -48,7 +48,7 @@ "@babel/traverse": "^7.12.11", "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "core-js": "^3.8.2", "fs-extra": "^9.0.1", "global": "^4.4.0", diff --git a/lib/preview-web/package.json b/lib/preview-web/package.json index 32494bc7a17..ecd331a889f 100644 --- a/lib/preview-web/package.json +++ b/lib/preview-web/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "@storybook/store": "6.4.0-alpha.34", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index fc0b98ed491..0d87c72ef14 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index 4efb1f27b9b..40a9c31702e 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -43,7 +43,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.5459c65.0", + "@storybook/csf": "0.0.2--canary.b1d5348.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/lib/store/src/inferArgTypes.test.ts b/lib/store/src/inferArgTypes.test.ts index 0703f49d613..b5b9762b338 100644 --- a/lib/store/src/inferArgTypes.test.ts +++ b/lib/store/src/inferArgTypes.test.ts @@ -21,7 +21,7 @@ describe('inferArgTypes', () => { b: { name: 'b', type: { name: 'string' } }, c: { name: 'c', type: { name: 'number' } }, d: { name: 'd', type: { name: 'function' } }, - e: { name: 'e', type: { name: 'other', value: 'symbol' } }, + e: { name: 'e', type: { name: 'symbol' } }, }); }); diff --git a/lib/store/src/inferArgTypes.ts b/lib/store/src/inferArgTypes.ts index 5c0dd90605b..7a6bc2d0cc5 100644 --- a/lib/store/src/inferArgTypes.ts +++ b/lib/store/src/inferArgTypes.ts @@ -11,9 +11,8 @@ const inferType = (value: any, name: string, visited: Set): SBType => { case 'string': case 'number': case 'function': - return { name: type }; case 'symbol': - return { name: 'other', value: 'symbol' }; + return { name: type }; default: break; } diff --git a/lib/store/src/inferControls.ts b/lib/store/src/inferControls.ts index 701d868df79..00c4ec45cf6 100644 --- a/lib/store/src/inferControls.ts +++ b/lib/store/src/inferControls.ts @@ -47,8 +47,7 @@ const inferControl = (argType: StrictInputType, name: string, matchers: Controls return { control: { type: value?.length <= 5 ? 'radio' : 'select' }, options: value }; } case 'function': - // case 'symbol': - // case 'void': + case 'symbol': return null; default: return { control: { type: options ? 'select' : 'object' } }; diff --git a/yarn.lock b/yarn.lock index 7fcf8cc66eb..3cef6f5a875 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6834,7 +6834,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/theming": 6.4.0-alpha.34 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -6865,7 +6865,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/theming": 6.4.0-alpha.34 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -6900,7 +6900,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/theming": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -6928,7 +6928,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 @@ -6971,7 +6971,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/html": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 @@ -7173,7 +7173,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/router": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7203,7 +7203,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7227,7 +7227,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7262,7 +7262,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/node-logger": 6.4.0-alpha.34 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -7292,7 +7292,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-client": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/react": 6.4.0-alpha.34 "@storybook/vue": 6.4.0-alpha.34 "@storybook/vue3": 6.4.0-alpha.34 @@ -7455,7 +7455,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7488,7 +7488,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/autoprefixer": ^9.7.2 @@ -7557,7 +7557,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.34 @@ -7841,7 +7841,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/store": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7877,7 +7877,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7899,7 +7899,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/theming": 6.4.0-alpha.34 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -7938,7 +7938,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/ui": 6.4.0-alpha.34 @@ -8125,7 +8125,7 @@ __metadata: "@babel/traverse": ^7.12.11 "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@types/fs-extra": ^9.0.6 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -8139,12 +8139,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.5459c65.0": - version: 0.0.2--canary.5459c65.0 - resolution: "@storybook/csf@npm:0.0.2--canary.5459c65.0" +"@storybook/csf@npm:0.0.2--canary.b1d5348.0": + version: 0.0.2--canary.b1d5348.0 + resolution: "@storybook/csf@npm:0.0.2--canary.b1d5348.0" dependencies: lodash: ^4.17.15 - checksum: 67e8adfddbc4eb96f6cfdca0fe03cfcac460302489bde3b99d31f88eab14759d7d856592871434cd2d8caffebb465f8b81c87576ecb9da755baace09f83b5c57 + checksum: 9e00c31b2ea32c432c7fb5ba5ea7cdaf7d7b949c561ffa32673bbc03486959b937f136f49cea3757ef3ea6961c2bea2c96638d16cf283e0c5abf25e59eb42ccc languageName: node linkType: hard @@ -8272,7 +8272,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 @@ -8487,7 +8487,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -8547,7 +8547,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/store": 6.4.0-alpha.34 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -8593,7 +8593,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -8892,7 +8892,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 @@ -8921,7 +8921,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -8942,7 +8942,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -8961,7 +8961,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -9060,7 +9060,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9097,7 +9097,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9140,7 +9140,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.5459c65.0 + "@storybook/csf": 0.0.2--canary.b1d5348.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 From b68f6d39fc30d59226f2691dbaffcd108575a7b9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 21:57:28 +1000 Subject: [PATCH 236/285] Ensure we teardown when going to missing properly --- lib/preview-web/src/PreviewWeb.tsx | 25 ++++++++++++++----------- lib/preview-web/src/WebView.ts | 11 +++++++---- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 0a4f468ed02..08a337517bd 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -272,16 +272,8 @@ export class PreviewWeb { this.channel.emit(Events.STORY_UNCHANGED, selection.storyId); return; } - const previousViewMode = this.previousStory?.parameters?.docsOnly - ? 'docs' - : this.previousSelection?.viewMode; - if (viewModeChanged && previousViewMode === 'docs') { - ReactDOM.unmountComponentAtNode(this.view.docsRoot()); - } - if (previousViewMode === 'story') { - this.removePreviousStory(); - } + this.cleanupPreviousRender({ unmountDocs: viewModeChanged }); // If we are rendering something new (as opposed to re-rendering the same or first story), emit if (this.previousSelection && (storyChanged || viewModeChanged)) { @@ -532,8 +524,18 @@ export class PreviewWeb { }; } - removePreviousStory() { - this.previousCleanup(); + cleanupPreviousRender({ unmountDocs = true }: { unmountDocs?: boolean } = {}) { + const previousViewMode = this.previousStory?.parameters?.docsOnly + ? 'docs' + : this.previousSelection?.viewMode; + + if (unmountDocs && previousViewMode === 'docs') { + ReactDOM.unmountComponentAtNode(this.view.docsRoot()); + } + + if (previousViewMode === 'story') { + this.previousCleanup(); + } } renderPreviewEntryError(err: Error) { @@ -542,6 +544,7 @@ export class PreviewWeb { } renderMissingStory(storySpecifier?: StorySpecifier) { + this.cleanupPreviousRender(); this.view.showNoPreview(); this.channel.emit(Events.STORY_MISSING, storySpecifier); } diff --git a/lib/preview-web/src/WebView.ts b/lib/preview-web/src/WebView.ts index 5938b581afd..2a163c2120c 100644 --- a/lib/preview-web/src/WebView.ts +++ b/lib/preview-web/src/WebView.ts @@ -93,6 +93,9 @@ export class WebView { document.body.classList.remove(classes.ERROR); document.body.classList.add(classes.NOPREVIEW); + + this.storyRoot().setAttribute('hidden', 'true'); + this.docsRoot().setAttribute('hidden', 'true'); } showMain() { @@ -103,12 +106,12 @@ export class WebView { } showDocs() { - document.getElementById('root').setAttribute('hidden', 'true'); - document.getElementById('docs-root').removeAttribute('hidden'); + this.storyRoot().setAttribute('hidden', 'true'); + this.docsRoot().removeAttribute('hidden'); } showStory() { - document.getElementById('docs-root').setAttribute('hidden', 'true'); - document.getElementById('root').removeAttribute('hidden'); + this.docsRoot().setAttribute('hidden', 'true'); + this.storyRoot().removeAttribute('hidden'); } } From b0dda030f3ec7c7841f44e354ab3bb5f2abbb349 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Sep 2021 23:40:45 +1000 Subject: [PATCH 237/285] Add a note --- lib/store/src/prepareStory.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/store/src/prepareStory.ts b/lib/store/src/prepareStory.ts index 8e4c666c8f7..8ca98d72e49 100644 --- a/lib/store/src/prepareStory.ts +++ b/lib/store/src/prepareStory.ts @@ -73,7 +73,8 @@ export function prepareStory( ...(storyAnnotations.loaders || []), ]; - // TODO make a note about what's happening here + // The render function on annotations *has* to be an `ArgsStoryFn`, so when we normalize + // CSFv1/2, we use a new field called `userStoryFn` so we know that it can be a LegacyStoryFn const render = storyAnnotations.userStoryFn || storyAnnotations.render || From d586ce7072450e2a43bbba04655e75a8dbafc5d2 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 01:24:27 +1000 Subject: [PATCH 238/285] Don't emit `STORY_PREPARED` in v6 mode. It was causing problems when there was nothing in the store on the manager side. --- lib/preview-web/src/PreviewWeb.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 08a337517bd..a3129b22915 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -377,13 +377,15 @@ export class PreviewWeb { const storyContext = this.storyStore.getStoryContext(story); const { parameters, initialArgs, argTypes, args } = storyContext; - this.channel.emit(Events.STORY_PREPARED, { - id, - parameters, - initialArgs, - argTypes, - args, - }); + if (FEATURES?.storyStoreV7) { + this.channel.emit(Events.STORY_PREPARED, { + id, + parameters, + initialArgs, + argTypes, + args, + }); + } const viewMode = element === this.view.storyRoot() ? 'story' : 'docs'; const loadedContext = await applyLoaders({ From a6d05f446381d7f45175d2a8a4cb69fc2780c2d7 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 01:29:35 +1000 Subject: [PATCH 239/285] Don't allow setting args to `undefined` --- lib/store/src/ArgsStore.test.ts | 9 +++++++++ lib/store/src/ArgsStore.ts | 11 ++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/store/src/ArgsStore.test.ts b/lib/store/src/ArgsStore.test.ts index 031a344015f..19738277fc8 100644 --- a/lib/store/src/ArgsStore.test.ts +++ b/lib/store/src/ArgsStore.test.ts @@ -50,6 +50,15 @@ describe('ArgsStore', () => { store.update('id', { obj: { baz: 'bing' } }); expect(store.get('id')).toEqual({ obj: { baz: 'bing' } }); }); + + it('does not set keys to undefined, it simply unsets them', () => { + const store = new ArgsStore(); + + store.setInitial('id', { foo: 'bar' }); + + store.update('id', { foo: undefined }); + expect('foo' in store.get('id')).toBe(false); + }); }); describe('updateFromPersisted', () => { diff --git a/lib/store/src/ArgsStore.ts b/lib/store/src/ArgsStore.ts index 621a4e6f3f3..95833bf4b84 100644 --- a/lib/store/src/ArgsStore.ts +++ b/lib/store/src/ArgsStore.ts @@ -3,6 +3,12 @@ import { StoryId, Args } from '@storybook/csf'; import { Story } from './types'; import { combineArgs, mapArgsToTypes, validateOptions, deepDiff, DEEPLY_EQUAL } from './args'; +function deleteUndefined(obj: Record) { + // eslint-disable-next-line no-param-reassign + Object.keys(obj).forEach((key) => obj[key] === undefined && delete obj[key]); + return obj; +} + export class ArgsStore { argsByStoryId: Record = {}; @@ -52,6 +58,9 @@ export class ArgsStore { throw new Error(`No args known for ${storyId} -- has it been rendered yet?`); } - this.argsByStoryId[storyId] = { ...this.argsByStoryId[storyId], ...argsUpdate }; + this.argsByStoryId[storyId] = deleteUndefined({ + ...this.argsByStoryId[storyId], + ...argsUpdate, + }); } } From c4a2d6a4b4b1891c7488dcc88a974d2fa7dade29 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 01:43:16 +1000 Subject: [PATCH 240/285] Ignore v<3 storyIndexes --- lib/api/src/lib/stories.ts | 12 ++++++------ lib/api/src/modules/stories.ts | 17 +++++++++++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/api/src/lib/stories.ts b/lib/api/src/lib/stories.ts index eb01725e86e..b27abb07373 100644 --- a/lib/api/src/lib/stories.ts +++ b/lib/api/src/lib/stories.ts @@ -109,14 +109,14 @@ export interface StoriesRaw { } type Path = string; -export interface StoriesListStory { +export interface StoryIndexStory { name: StoryName; title: ComponentTitle; importPath: Path; } -export interface StoriesListJson { +export interface StoryIndex { v: number; - stories: Record; + stories: Record; } export type SetStoriesPayload = @@ -169,11 +169,11 @@ export const denormalizeStoryParameters = ({ const STORY_KIND_PATH_SEPARATOR = /\s*\/\s*/; -export const transformStoriesListToStoriesHash = ( - list: StoriesListJson, +export const transformStoryIndexToStoriesHash = ( + index: StoryIndex, { provider }: { provider: Provider } ): StoriesHash => { - const input = Object.entries(list.stories).reduce((acc, [id, { title, name, importPath }]) => { + const input = Object.entries(index.stories).reduce((acc, [id, { title, name, importPath }]) => { acc[id] = { id, kind: title, diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index 27cda1c3a2a..7b45c47ffc1 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -18,7 +18,7 @@ import { transformStoriesRawToStoriesHash, isStory, isRoot, - transformStoriesListToStoriesHash, + transformStoryIndexToStoriesHash, } from '../lib/stories'; import type { StoriesHash, @@ -28,7 +28,7 @@ import type { Root, StoriesRaw, SetStoriesPayload, - StoriesListJson, + StoryIndex, } from '../lib/stories'; import { Args, ModuleFn } from '../index'; @@ -351,12 +351,17 @@ export const init: ModuleFn = ({ fetchStoryList: async () => { // This needs some fleshing out as part of the stories list server project const result = await global.fetch('/stories.json'); - const storyList = (await result.json()) as StoriesListJson; + const storyIndex = (await result.json()) as StoryIndex; - await fullAPI.setStoryList(storyList); + // We can only do this if the stories.json is a proper storyIndex + if (storyIndex.v !== 3) { + return; + } + + await fullAPI.setStoryList(storyIndex); }, - setStoryList: async (storyList: StoriesListJson) => { - const hash = transformStoriesListToStoriesHash(storyList, { + setStoryList: async (storyIndex: StoryIndex) => { + const hash = transformStoryIndexToStoriesHash(storyIndex, { provider, }); From 01294ffb688ab97b5810debd7b7d059de38f857a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 01:43:47 +1000 Subject: [PATCH 241/285] Ensure we send `args` with `SET_STORIES` --- lib/core-client/src/preview/start.test.ts | 24 +++++++++++++++++++ lib/store/src/StoryStore.test.ts | 18 ++++++++++++++ lib/store/src/StoryStore.ts | 29 +++++++++++++---------- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/lib/core-client/src/preview/start.test.ts b/lib/core-client/src/preview/start.test.ts index 785eeb00bf5..4cf2c1b6251 100644 --- a/lib/core-client/src/preview/start.test.ts +++ b/lib/core-client/src/preview/start.test.ts @@ -67,6 +67,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--story-one", @@ -84,6 +85,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--story-two", @@ -101,6 +103,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-b", "id": "component-b--story-three", @@ -158,6 +161,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--story-one", @@ -347,6 +351,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--default", @@ -364,6 +369,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--new", @@ -419,6 +425,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--default", @@ -436,6 +443,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-b", "id": "component-b--default", @@ -471,6 +479,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--default", @@ -521,6 +530,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-one", @@ -538,6 +548,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-two", @@ -651,6 +662,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-one", @@ -668,6 +680,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-two", @@ -685,6 +698,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-three", @@ -741,6 +755,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-one", @@ -758,6 +773,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-two", @@ -775,6 +791,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-d", "id": "component-d--story-four", @@ -812,6 +829,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-one", @@ -829,6 +847,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-two", @@ -884,6 +903,7 @@ describe('start', () => { "stories": Array [ Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--story-one", @@ -901,6 +921,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-a", "id": "component-a--story-two", @@ -918,6 +939,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-b", "id": "component-b--story-three", @@ -935,6 +957,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-one", @@ -952,6 +975,7 @@ describe('start', () => { }, Object { "argTypes": Object {}, + "args": Object {}, "component": undefined, "componentId": "component-c", "id": "component-c--story-two", diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index 7570099cba3..5bdcfe2bb4c 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -241,6 +241,9 @@ describe('StoryStore', () => { }, }, }, + "args": Object { + "foo": "a", + }, "component": undefined, "componentId": "component-one", "id": "component-one--a", @@ -271,6 +274,9 @@ describe('StoryStore', () => { }, }, }, + "args": Object { + "foo": "b", + }, "component": undefined, "componentId": "component-one", "id": "component-one--b", @@ -301,6 +307,9 @@ describe('StoryStore', () => { }, }, }, + "args": Object { + "foo": "c", + }, "component": undefined, "componentId": "component-two", "id": "component-two--c", @@ -380,6 +389,9 @@ describe('StoryStore', () => { }, }, }, + "args": Object { + "foo": "a", + }, "component": undefined, "componentId": "component-one", "id": "component-one--a", @@ -410,6 +422,9 @@ describe('StoryStore', () => { }, }, }, + "args": Object { + "foo": "b", + }, "component": undefined, "componentId": "component-one", "id": "component-one--b", @@ -440,6 +455,9 @@ describe('StoryStore', () => { }, }, }, + "args": Object { + "foo": "c", + }, "component": undefined, "componentId": "component-two", "id": "component-two--c", diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 2df7deacd3e..9b2de12f7ea 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -241,7 +241,7 @@ export class StoryStore { this.hooks[story.id].clean(); } - extract(options: ExtractOptions = { includeDocsOnly: false }) { + extract(options: ExtractOptions = { includeDocsOnly: false }): Record { if (!this.cachedCSFFiles) { throw new Error('Cannot call extract() unless you call cacheAllCSFFiles() first.'); } @@ -255,18 +255,21 @@ export class StoryStore { return false; } - return Object.entries(story).reduce((acc, [key, value]) => { - if (typeof value === 'function') { - return acc; - } - if (['hooks'].includes(key)) { - return acc; - } - if (Array.isArray(value)) { - return Object.assign(acc, { [key]: value.slice().sort() }); - } - return Object.assign(acc, { [key]: value }); - }, {}); + return Object.entries(story).reduce( + (acc, [key, value]) => { + if (typeof value === 'function') { + return acc; + } + if (['hooks'].includes(key)) { + return acc; + } + if (Array.isArray(value)) { + return Object.assign(acc, { [key]: value.slice().sort() }); + } + return Object.assign(acc, { [key]: value }); + }, + { args: story.initialArgs } + ); }) .filter(Boolean); } From fc1b933ba5c3207af2c626df6f8347f6154ef4c0 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 01:45:38 +1000 Subject: [PATCH 242/285] Fix storyshots --- lib/preview-web/src/WebView.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/preview-web/src/WebView.ts b/lib/preview-web/src/WebView.ts index 2a163c2120c..f36d8cfcf3c 100644 --- a/lib/preview-web/src/WebView.ts +++ b/lib/preview-web/src/WebView.ts @@ -94,8 +94,9 @@ export class WebView { document.body.classList.add(classes.NOPREVIEW); - this.storyRoot().setAttribute('hidden', 'true'); - this.docsRoot().setAttribute('hidden', 'true'); + // In storyshots this can get called and these two can be null + this.storyRoot()?.setAttribute('hidden', 'true'); + this.docsRoot()?.setAttribute('hidden', 'true'); } showMain() { From ec3f41ec9cdfd8128fe09b3ab3911364935461ef Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 01:47:25 +1000 Subject: [PATCH 243/285] Revert "Wait a tick before apply arg changes and other re-renders." This reverts commit 23254408d16d3357b72a05903a85e76b1639e663. --- lib/preview-web/src/PreviewWeb.mockdata.ts | 1 - lib/preview-web/src/PreviewWeb.test.ts | 51 +--------------------- lib/preview-web/src/PreviewWeb.tsx | 9 ++-- 3 files changed, 4 insertions(+), 57 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.mockdata.ts b/lib/preview-web/src/PreviewWeb.mockdata.ts index 4c8b9c267d3..a4d1d5259ab 100644 --- a/lib/preview-web/src/PreviewWeb.mockdata.ts +++ b/lib/preview-web/src/PreviewWeb.mockdata.ts @@ -95,4 +95,3 @@ export const waitForRender = () => ]); export const waitForQuiescence = async () => new Promise((r) => setTimeout(r, 100)); -export const waitForTick = async () => new Promise((r) => setTimeout(r, 0)); diff --git a/lib/preview-web/src/PreviewWeb.test.ts b/lib/preview-web/src/PreviewWeb.test.ts index 391ad6393ca..87f4cc501c6 100644 --- a/lib/preview-web/src/PreviewWeb.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -18,7 +18,6 @@ import { waitForEvents, waitForRender, waitForQuiescence, - waitForTick, } from './PreviewWeb.mockdata'; jest.mock('./WebView'); @@ -49,7 +48,7 @@ const createGate = (): [Promise, (_?: any) => void] => { return [gate, openGate]; }; -beforeEach(async () => { +beforeEach(() => { document.location.search = ''; mockChannel.emit.mockClear(); emitter.removeAllListeners(); @@ -65,9 +64,6 @@ beforeEach(async () => { logger.warn.mockClear(); addons.setChannel(mockChannel as any); - - // Some events happen in the next tick - await waitForTick(); }); describe('PreviewWeb', () => { @@ -633,7 +629,6 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); - await waitForTick(); // Now let the loader resolve openGate({ l: 8 }); @@ -664,7 +659,6 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); - await waitForTick(); expect(logger.warn).toHaveBeenCalled(); // Now let the renderToDOM call resolve @@ -685,44 +679,6 @@ describe('PreviewWeb', () => { ); }); - it('works if it is called directly from inside non async renderToDOM', async () => { - document.location.search = '?id=component-one--a'; - projectAnnotations.renderToDOM.mockImplementationOnce(() => { - emitter.emit(Events.UPDATE_STORY_ARGS, { - storyId: 'component-one--a', - updatedArgs: { new: 'arg' }, - }); - }); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); - - await waitForRender(); - mockChannel.emit.mockClear(); - await waitForRender(); - expect(logger.warn).not.toHaveBeenCalled(); - - expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(2); - expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( - expect.objectContaining({ - forceRemount: true, - storyContext: expect.objectContaining({ - loaded: { l: 7 }, - args: { foo: 'a' }, - }), - }), - undefined // this is coming from view.prepareForStory, not super important - ); - expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( - expect.objectContaining({ - forceRemount: false, - storyContext: expect.objectContaining({ - loaded: { l: 7 }, - args: { foo: 'a', new: 'arg' }, - }), - }), - undefined // this is coming from view.prepareForStory, not super important - ); - }); - it('warns and calls renderToDOM again if play function is running', async () => { const [gate, openGate] = createGate(); componentOneExports.a.play.mockImplementationOnce(async () => gate); @@ -753,7 +709,6 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); - await waitForTick(); expect(logger.warn).toHaveBeenCalled(); // The second call should emit STORY_RENDERED @@ -814,10 +769,8 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, }); - await waitForRender(); mockChannel.emit.mockClear(); - projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.RESET_STORY_ARGS, { storyId: 'component-one--a', argNames: ['foo'], @@ -849,10 +802,8 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, }); - await waitForRender(); mockChannel.emit.mockClear(); - projectAnnotations.renderToDOM.mockClear(); emitter.emit(Events.RESET_STORY_ARGS, { storyId: 'component-one--a', }); diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index a3129b22915..95087c225bd 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -490,9 +490,6 @@ export class PreviewWeb { } this.channel.emit(Events.STORY_RENDERED, id); }; - // We wait a moment to re-render the story in case users are doing things like force - // rerender or updating args from inside story functions. - const rerenderStoryOnTick = () => setTimeout(rerenderStory, 0); // Start the first render // NOTE: we don't await here because we need to return the "cleanup" function below @@ -501,10 +498,10 @@ export class PreviewWeb { initialRender().catch((err) => renderContextWithoutStoryContext.showException(err)); // Listen to events and re-render story - this.channel.on(Events.UPDATE_GLOBALS, rerenderStoryOnTick); - this.channel.on(Events.FORCE_RE_RENDER, rerenderStoryOnTick); + this.channel.on(Events.UPDATE_GLOBALS, rerenderStory); + this.channel.on(Events.FORCE_RE_RENDER, rerenderStory); const rerenderStoryIfMatches = async ({ storyId }: { storyId: StoryId }) => { - if (storyId === story.id) rerenderStoryOnTick(); + if (storyId === story.id) rerenderStory(); }; this.channel.on(Events.UPDATE_STORY_ARGS, rerenderStoryIfMatches); this.channel.on(Events.RESET_STORY_ARGS, rerenderStoryIfMatches); From d4d0863a7ca7be31d0efdfc9024cb42eb63e5310 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 01:52:13 +1000 Subject: [PATCH 244/285] Get rid of setTimeout(0) and instead just call `renderToDOM` immediately The framework can do the queuing --- lib/preview-web/src/PreviewWeb.test.ts | 52 +++++++++++++++++++++++--- lib/preview-web/src/PreviewWeb.tsx | 12 ------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.test.ts b/lib/preview-web/src/PreviewWeb.test.ts index 87f4cc501c6..260831ffd0b 100644 --- a/lib/preview-web/src/PreviewWeb.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -648,7 +648,7 @@ describe('PreviewWeb', () => { ); }); - it('does nothing and warns renderToDOM is running', async () => { + it('renders a second time if renderToDOM is running', async () => { const [gate, openGate] = createGate(); document.location.search = '?id=component-one--a'; @@ -659,14 +659,12 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); - expect(logger.warn).toHaveBeenCalled(); // Now let the renderToDOM call resolve openGate(); await waitForRender(); - expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(1); - // renderToDOM call happens with original args, does not get retried. + expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(2); expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( expect.objectContaining({ forceRemount: true, @@ -677,6 +675,51 @@ describe('PreviewWeb', () => { }), undefined // this is coming from view.prepareForStory, not super important ); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( + expect.objectContaining({ + forceRemount: false, + storyContext: expect.objectContaining({ + loaded: { l: 7 }, + args: { foo: 'a', new: 'arg' }, + }), + }), + undefined // this is coming from view.prepareForStory, not super important + ); + }); + + it('works if it is called directly from inside non async renderToDOM', async () => { + document.location.search = '?id=component-one--a'; + projectAnnotations.renderToDOM.mockImplementationOnce(() => { + emitter.emit(Events.UPDATE_STORY_ARGS, { + storyId: 'component-one--a', + updatedArgs: { new: 'arg' }, + }); + }); + await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + + await waitForRender(); + + expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(2); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( + expect.objectContaining({ + forceRemount: true, + storyContext: expect.objectContaining({ + loaded: { l: 7 }, + args: { foo: 'a' }, + }), + }), + undefined // this is coming from view.prepareForStory, not super important + ); + expect(projectAnnotations.renderToDOM).toHaveBeenCalledWith( + expect.objectContaining({ + forceRemount: false, + storyContext: expect.objectContaining({ + loaded: { l: 7 }, + args: { foo: 'a', new: 'arg' }, + }), + }), + undefined // this is coming from view.prepareForStory, not super important + ); }); it('warns and calls renderToDOM again if play function is running', async () => { @@ -709,7 +752,6 @@ describe('PreviewWeb', () => { storyId: 'component-one--a', updatedArgs: { new: 'arg' }, }); - expect(logger.warn).toHaveBeenCalled(); // The second call should emit STORY_RENDERED await waitForRender(); diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 95087c225bd..89b128e0b6e 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -452,18 +452,6 @@ export class PreviewWeb { if (initialRenderPhase === 'init') { return; } - // The loaders are done but we are part way through rendering the story to the DOM - // This is a bit of an edge case and not something we can deal with sensibly, let's just warn - if (initialRenderPhase === 'loaded') { - logger.warn('Changed story args during rendering. Arg changes have been ignored.'); - return; - } - - if (initialRenderPhase === 'rendered') { - logger.warn( - 'Changed story args during play function. Continuing but there may be problems.' - ); - } // This story context will have the updated values of args and globals From db5cfabc2aac6f159a56634db96d4412d9217806 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 02:15:49 +1000 Subject: [PATCH 245/285] Added a bunch of comments and some READMEs --- lib/preview-web/README.md | 20 ++++- lib/preview-web/src/PreviewWeb.tsx | 8 +- lib/store/README.md | 121 ++++++++++++++++++++++++++++- lib/store/src/StoryStore.ts | 14 ++++ 4 files changed, 157 insertions(+), 6 deletions(-) diff --git a/lib/preview-web/README.md b/lib/preview-web/README.md index cf8fd0e2327..331d5e22f1f 100644 --- a/lib/preview-web/README.md +++ b/lib/preview-web/README.md @@ -1,3 +1,19 @@ -# Web Preview +# Preview (Web) -TODO +This is the main API for the (web) version of the Storybook Preview. + +The preview's job is: + +1. Read and update the URL (via the URL Store) + +2. Listen to instructions on the channel and emit events as things occur. + +3. Render the current selection to the web view in either story or docs mode. + +## V7 Store vs Legacy (V6) + +The story store is designed to load stories 'on demand', and will operate in this fashion if the `storyStoreV7` feature is enabled. + +However, for back-compat reasons, in v6 mode, we need to load all stories, synchronously on bootup, emitting the `SET_STORIES` event. + +In V7 mode we do not emit that event, instead preferring the `STORY_PREPARED` event. diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 89b128e0b6e..f8adc3a2096 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -95,6 +95,8 @@ export class PreviewWeb { await this.setupListenersAndRenderSelection(); } + // We have a second "sync" code path through `initialize` for back-compat reasons. + // Specifically Storyshots requires the story store to be syncronously loaded completely on bootup initializeSync({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { this.storyStore.initializeSync({ cacheAllCSFFiles }); // NOTE: we don't await this, but return the promise so the caller can await it if they want @@ -129,7 +131,7 @@ export class PreviewWeb { this.channel.on(Events.RESET_STORY_ARGS, this.onResetArgs.bind(this)); } - // Use the selection specifier to choose a story + // Use the selection specifier to choose a story, then render it async selectSpecifiedStory() { if (!this.urlStore.selectionSpecifier) { this.renderMissingStory(); @@ -346,8 +348,8 @@ export class PreviewWeb { return this.renderStoryToElement({ story, renderContext, element }); } - // We want this function to be called directly by `renderSelection` above, - // but also by the `` docs component + // Render a story into a given element and watch for the events that would trigger us + // to re-render it (plus deal sensibly with things like changing story mid-way through). renderStoryToElement({ story, renderContext: renderContextWithoutStoryContext, diff --git a/lib/store/README.md b/lib/store/README.md index 84da37ae000..3a97f2a63f1 100644 --- a/lib/store/README.md +++ b/lib/store/README.md @@ -1,3 +1,122 @@ # Storybook Store -TODO +The store is reponsible for loading a story from a CSF file and preparing into a `Story` type, which is our internal format. + +## Story vs StoryContext + +Story functions and decorators recieve a `StoryContext` object (parameterized by their framework). + +The `Story` type that we pass around in our code includes all of those fields apart from the `args`, `globals`, `hooks` and `viewMode`, which are mutable and stored separately in the store. + +## Identification + +The first set of fields on a `Story` are the identifying fields for a story: + +- `componentId` - the URL "id" of the component +- `title` - the title of the component, which generates the sidebar entry +- `id` - the story "id" (in the URL) +- `name` - the name of the story + +## Annotations + +The main fields on a `Story` are the various annotations. Annotations can be set: + +- At the project level in `preview.js` (or via addons) +- At the component level via `export default = { ... }` in a CSF file +- At the story level via `export Story = {...}` in a CSF file. + +Not all annotations can be set at every level but most can. + +## Parameters + +The story parameters is a static, serializable object of data that provides details about the story. Those details can be used by addons or Storybook itself to render UI or provide defaults about the story rendering. + +Parameters _cannot change_ and are synchronized to the manager once when the story is loaded (note over the lifetime of a development Storybook a story can be loaded several times due to hot module reload, so the parameters technically can change for that reason). + +Usually addons will read from a single key of `parameters` namespaced by the name of that addon. For instance the configuration of the `backgrounds` addon is driven by the `parameters.backgrounds` namespace. + +Parameters are inheritable -- you can set project parameters via `export parameters = {}`, at the component level by the `parameters` key of the component (default) export in CSF, and on a single story via the `parameters` key on the story data. + +Some notable parameters: + +- `parameters.fileName` - the file that the story was defined in, when available + +## Args + +Args are "inputs" to stories. + +You can think of them equivalently to React props, Angular inputs and outputs, etc. + +Changing the args cause the story to be re-rendered with the new set of args. + +### Using args in a story + +By default (starting in 6.0) the args will be passed to the story as first argument and the context as second: + +```js +const YourStory = ({ x, y } /*, context*/) => /* render your story using `x` and `y` */ +``` + +If you set the `parameters.options.passArgsFirst` option on a story to false, args are passed to a story in the context, preserving the pre-6.0 story API; like parameters, they are available as `context.args`. + +```js +const YourStory = ({ args: { x, y }}) => /* render your story using `x` and `y` */ +``` + +### Arg types and values + +Arg types are used by the docs addon to populate the props table and are documented there. They are controlled by `argTypes` and can (sometimes) be automatically inferred from type information about the story or the component rendered by the story. + +A story can set initial values of its args with the `args` annotation. If you set an initial value for an arg that doesn't have a type a simple type will be inferred from the value. + +If an arg doesn't have an initial value, it will start unset, although it can still be set later via user interaction. + +Args can be set at the project, component and story level. + +### Using args in an addon + +Args values are automatically synchronized (via the `changeStoryArgs` and `storyArgsChanged` events) between the preview and manager; APIs exist in `lib/api` to read and set args in the manager. + +Args need to be serializable -- so currently cannot include callbacks (this may change in a future version). + +Note that arg values are passed directly to a story -- you should only store the actual value that the story needs to render in the arg. If you need more complex information supporting that, use parameters or addon state. + +Both `@storybook/client-api` (preview) and `@storybook/api` (manager) export a `useArgs()` hook that you can use to access args in decorators or addon panels. The API is as follows: + +```js +import { useArgs } from '@storybook/client-api'; // or '@storybook/api' + +// `args` is the args of the currently rendered story +// `updateArgs` will update its args. You can pass a subset of the args; other args will not be changed. +const [args, updateArgs] = useArgs(); +``` + +## ArgTypes + +Arg types add type information and metadata about args that are used to control the docs and controls addons. + +### ArgTypes enhancement + +To add a argTypes enhancer, `export addArgTypesEnhancers = []` from `preview.js` or and addon + +There is a default enhancer that ensures that each `arg` in a story has a baseline `argType`. This value can be improved by subsequent enhancers, e.g. those provided by `@storybook/addon-docs`. + +## Globals + +Globals are rendering information that is global across stories. They are used for things like themes and internationalization (i18n) in stories, where you want Storybook to "remember" your setting as you browse between stories. + +They can be access in stories and decorators in the `context.globals` key. + +### Initial values of globals + +To set initial values of globals, `export globals = {...}` from `preview.js` + +### Using globals in an addon + +Similar to args, globals are synchronized to the manager and can be accessed via the `useGlobals` hook. + +```js +import { useGlobals } from '@storybook/addons'; // or '@storybook/api' + +const [globals, updateGlobals] = useGlobals(); +``` diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 9b2de12f7ea..15233cdaa12 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -94,6 +94,9 @@ export class StoryStore { this.args = new ArgsStore(); this.hooks = {}; + // We use a cache for these two functions for two reasons: + // 1. For performance + // 2. To ensure that when the same story is prepared with the same inputs you get the same output this.processCSFFileWithCache = memoize(CSF_CACHE_SIZE)(processCSFFile) as typeof processCSFFile; this.prepareStoryWithCache = memoize(STORY_CACHE_SIZE)(prepareStory) as typeof prepareStory; } @@ -106,6 +109,7 @@ export class StoryStore { } } + // See note in PreviewWeb about the 'sync' init path. initializeSync({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { this.storyIndex.initializeSync(); @@ -120,6 +124,7 @@ export class StoryStore { this.globals.resetOnProjectAnnotationsChange({ globals, globalTypes }); } + // This means that one of the CSF functions has changed. async onImportFnChanged({ importFn }: { importFn: ModuleImportFn }) { this.importFn = importFn; @@ -131,9 +136,11 @@ export class StoryStore { } } + // To load a single CSF file to service a story we need to look up the importPath in the index async loadCSFFileByStoryId(storyId: StoryId): Promise> { const { importPath, title } = this.storyIndex.storyIdToEntry(storyId); const moduleExports = await this.importFn(importPath); + // We pass the title in here as it may have been generated by autoTitle on the server. return this.processCSFFileWithCache(moduleExports, title); } @@ -148,6 +155,7 @@ export class StoryStore { return this.processCSFFileWithCache(moduleExports as ModuleExports, title); } + // Load all CSF files into the cache so we can call synchronous functions like `extract()`. async loadAllCSFFiles(): Promise>> { const importPaths: Record = {}; Object.entries(this.storyIndex.stories).forEach(([storyId, { importPath }]) => { @@ -194,11 +202,14 @@ export class StoryStore { this.cachedCSFFiles = this.loadAllCSFFilesSync(); } + // Load the CSF file for a story and prepare the story from it and the project annotations. async loadStory({ storyId }: { storyId: StoryId }): Promise> { const csfFile = await this.loadCSFFileByStoryId(storyId); return this.storyFromCSFFile({ storyId, csfFile }); } + // This function is synchronous for convenience -- often times if you have a CSF file already + // it is easier not to have to await `loadStory`. storyFromCSFFile({ storyId, csfFile, @@ -222,12 +233,15 @@ export class StoryStore { return story; } + // If we have a CSF file we can get all the stories from it synchronously componentStoriesFromCSFFile({ csfFile }: { csfFile: CSFFile }): Story[] { return Object.keys(csfFile.stories).map((storyId: StoryId) => this.storyFromCSFFile({ storyId, csfFile }) ); } + // A prepared story does not include args, globals or hooks. These are stored in the story store + // and updated separtely to the (immutable) story. getStoryContext(story: Story): Omit, 'viewMode'> { return { ...story, From 81838bd8a531aac5fb1ae14449dbb3e1b63f0e97 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 02:19:10 +1000 Subject: [PATCH 246/285] Arg fix `lib/api` --- lib/api/src/modules/stories.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index 7b45c47ffc1..33ad5c1675c 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -74,7 +74,7 @@ export interface SubAPI { resetStoryArgs: (story: Story, argNames?: string[]) => void; findLeafStoryId(StoriesHash: StoriesHash, storyId: StoryId): StoryId; fetchStoryList: () => Promise; - setStoryList: (storyList: StoriesListJson) => Promise; + setStoryList: (storyList: StoryIndex) => Promise; updateStory: (storyId: StoryId, update: StoryUpdate, ref?: ComposedRef) => Promise; } From 53e00b34bad188ad83f9d3628d9a6d8979eb7d19 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 02:33:32 +1000 Subject: [PATCH 247/285] Fix exported type from `.raw()` --- lib/store/src/StoryStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 15233cdaa12..b54377a3551 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -323,7 +323,7 @@ export class StoryStore { }; }; - raw() { + raw(): BoundStory[] { return this.extract().map(({ id }: { id: StoryId }) => this.fromId(id)); } From d9679bbd5933e293e0ba925e74e15ddffeaac72b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Sep 2021 14:15:57 +1000 Subject: [PATCH 248/285] Refactor to pass sync as an arg rather than using a separate method Using TS overloads to deal with the type differences. It's a little awkward but probably avoids code duplication a little. --- lib/core-client/src/preview/start.ts | 2 +- lib/preview-web/src/PreviewWeb.tsx | 27 +++-- lib/store/src/StoryIndexStore.ts | 45 +++++---- lib/store/src/StoryStore.test.ts | 40 ++++---- lib/store/src/StoryStore.ts | 146 ++++++++++++++++----------- 5 files changed, 151 insertions(+), 109 deletions(-) diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index 4a87b15cbcd..ec47f0e5b7a 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -82,7 +82,7 @@ export function start( clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); clientApi.storyStore = preview.storyStore; - preview.initializeSync({ cacheAllCSFFiles: true }); + preview.initialize({ cacheAllCSFFiles: true, sync: true }); } else { getProjectAnnotations(); preview.onImportFnChanged({ importFn: (path: Path) => clientApi.importFn(path) }); diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index f8adc3a2096..d0d2da0725c 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -37,6 +37,7 @@ function focusInInput(event: Event) { } type InitialRenderPhase = 'init' | 'loaded' | 'rendered' | 'done'; +type MaybePromise = Promise | T; export class PreviewWeb { channel: Channel; @@ -90,17 +91,21 @@ export class PreviewWeb { } } - async initialize({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { - await this.storyStore.initialize({ cacheAllCSFFiles }); - await this.setupListenersAndRenderSelection(); - } - // We have a second "sync" code path through `initialize` for back-compat reasons. // Specifically Storyshots requires the story store to be syncronously loaded completely on bootup - initializeSync({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { - this.storyStore.initializeSync({ cacheAllCSFFiles }); - // NOTE: we don't await this, but return the promise so the caller can await it if they want - return this.setupListenersAndRenderSelection(); + initialize({ + cacheAllCSFFiles = false, + sync = false, + }: { cacheAllCSFFiles?: boolean; sync?: boolean } = {}): MaybePromise { + if (sync) { + this.storyStore.initialize({ cacheAllCSFFiles, sync: true }); + // NOTE: we don't await this, but return the promise so the caller can await it if they want + return this.setupListenersAndRenderSelection(); + } + + return this.storyStore + .initialize({ cacheAllCSFFiles, sync: false }) + .then(() => this.setupListenersAndRenderSelection()); } async setupListenersAndRenderSelection() { @@ -296,7 +301,9 @@ export class PreviewWeb { async renderDocs({ story }: { story: Story }) { const { id, title, name } = story; const element = this.view.prepareForDocs(); - const csfFile: CSFFile = await this.storyStore.loadCSFFileByStoryId(id); + const csfFile: CSFFile = await this.storyStore.loadCSFFileByStoryId(id, { + sync: false, + }); const docsContext = { id, title, diff --git a/lib/store/src/StoryIndexStore.ts b/lib/store/src/StoryIndexStore.ts index f5487f51e18..8cb65e48bb6 100644 --- a/lib/store/src/StoryIndexStore.ts +++ b/lib/store/src/StoryIndexStore.ts @@ -16,34 +16,41 @@ export class StoryIndexStore { this.fetchStoryIndex = fetchStoryIndex; } - async initialize() { - return this.cache(); - } + initialize(options: { sync: false }): Promise; + + initialize(options: { sync: true }): void; - initializeSync() { - return this.cacheSync(); + initialize({ sync = false } = {}) { + return sync ? this.cache(true) : this.cache(false); } - async onStoriesChanged() { - const { stories } = await this.fetchStoryIndex(); - this.stories = stories; + cache(sync: false): Promise; + + cache(sync: true): void; + + cache(sync = false): Promise | void { + const fetchResult = this.fetchStoryIndex(); + + if (sync) { + if (!(fetchResult as StoryIndex).v) { + throw new Error( + `fetchStoryIndex() didn't return an index, did you pass an async version then call initialize({ sync: true })?` + ); + } + this.stories = (fetchResult as StoryIndex).stories; + return null; + } + + return Promise.resolve(fetchResult).then(({ stories }) => { + this.stories = stories; + }); } - async cache() { + async onStoriesChanged() { const { stories } = await this.fetchStoryIndex(); this.stories = stories; } - async cacheSync() { - const data = this.fetchStoryIndex() as StoryIndex; - if (!data.v) { - throw new Error( - `fetchStoryIndex() didn't return a stories list, did you pass an async version then call initializeSync()?` - ); - } - this.stories = data.stories; - } - storyIdFromSpecifier(specifier: StorySpecifier) { const storyIds = Object.keys(this.stories); if (specifier === '*') { diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index 5bdcfe2bb4c..0d47cef38c3 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -68,7 +68,7 @@ describe('StoryStore', () => { describe('projectAnnotations', () => { it('normalizes on initialization', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); expect(store.projectAnnotations.globalTypes).toEqual({ a: { name: 'a', type: { name: 'string' } }, @@ -78,9 +78,9 @@ describe('StoryStore', () => { }); }); - it('normalizes on updateProjectAnnotations', async () => { + it('normalizes on updateGlobalAnnotations', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); store.updateProjectAnnotations(projectAnnotations); expect(store.projectAnnotations.globalTypes).toEqual({ @@ -95,7 +95,7 @@ describe('StoryStore', () => { describe('loadStory', () => { it('pulls the story via the importFn', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); importFn.mockClear(); expect(await store.loadStory({ storyId: 'component-one--a' })).toMatchObject({ @@ -109,7 +109,7 @@ describe('StoryStore', () => { it('uses a cache', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); expect(processCSFFile).toHaveBeenCalledTimes(1); @@ -133,9 +133,9 @@ describe('StoryStore', () => { describe('componentStoriesFromCSFFile', () => { it('returns all the stories in the file', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); - const csfFile = await store.loadCSFFileByStoryId('component-one--a'); + const csfFile = await store.loadCSFFileByStoryId('component-one--a', { sync: false }); const stories = store.componentStoriesFromCSFFile({ csfFile }); expect(stories).toHaveLength(2); @@ -146,7 +146,7 @@ describe('StoryStore', () => { describe('getStoryContext', () => { it('returns the args and globals correctly', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -158,7 +158,7 @@ describe('StoryStore', () => { it('returns the args and globals correctly when they change', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -173,7 +173,7 @@ describe('StoryStore', () => { it('returns the same hooks each time', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -185,7 +185,7 @@ describe('StoryStore', () => { describe('cleanupStory', () => { it('cleans the hooks from the context', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -199,10 +199,10 @@ describe('StoryStore', () => { describe('loadAllCSFFiles', () => { it('imports *all* csf files', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); importFn.mockClear(); - const csfFiles = await store.loadAllCSFFiles(); + const csfFiles = await store.loadAllCSFFiles(false); expect(Object.keys(csfFiles)).toEqual([ './src/ComponentOne.stories.js', @@ -214,15 +214,15 @@ describe('StoryStore', () => { describe('extract', () => { it('throws if you have not called cacheAllCSFFiles', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); + await store.initialize({ sync: false }); expect(() => store.extract()).toThrow(/Cannot call extract/); }); it('produces objects with functions and hooks stripped', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); - await store.cacheAllCSFFiles(); + await store.initialize({ sync: false }); + await store.cacheAllCSFFiles(false); expect(store.extract()).toMatchInlineSnapshot(` Array [ @@ -343,8 +343,8 @@ describe('StoryStore', () => { projectAnnotations, fetchStoryIndex, }); - await store.initialize(); - await store.cacheAllCSFFiles(); + await store.initialize({ sync: false }); + await store.cacheAllCSFFiles(false); expect((store.extract() as { id: StoryId }[]).map((s) => s.id)).toEqual([ 'component-one--b', @@ -360,8 +360,8 @@ describe('StoryStore', () => { describe('getSetStoriesPayload', () => { it('maps stories list to payload correctly', async () => { const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize(); - await store.cacheAllCSFFiles(); + await store.initialize({ sync: false }); + await store.cacheAllCSFFiles(false); expect(store.getSetStoriesPayload()).toMatchInlineSnapshot(` Object { diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index b54377a3551..1f447020e6a 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -31,6 +31,8 @@ import { normalizeInputTypes } from './normalizeInputTypes'; import { inferArgTypes } from './inferArgTypes'; import { inferControls } from './inferControls'; +type MaybePromise = Promise | T; + // TODO -- what are reasonable values for these? const CSF_CACHE_SIZE = 100; const STORY_CACHE_SIZE = 1000; @@ -101,21 +103,29 @@ export class StoryStore { this.prepareStoryWithCache = memoize(STORY_CACHE_SIZE)(prepareStory) as typeof prepareStory; } - async initialize({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { - await this.storyIndex.initialize(); - - if (cacheAllCSFFiles) { - await this.cacheAllCSFFiles(); - } - } - // See note in PreviewWeb about the 'sync' init path. - initializeSync({ cacheAllCSFFiles = false }: { cacheAllCSFFiles?: boolean } = {}) { - this.storyIndex.initializeSync(); + initialize(options: { sync: false; cacheAllCSFFiles?: boolean }): Promise; - if (cacheAllCSFFiles) { - this.cacheAllCSFFilesSync(); + initialize(options: { sync: true; cacheAllCSFFiles?: boolean }): void; + + initialize({ + sync = false, + cacheAllCSFFiles = false, + }: { + sync?: boolean; + cacheAllCSFFiles?: boolean; + } = {}): MaybePromise { + if (sync) { + this.storyIndex.initialize({ sync: true }); + if (cacheAllCSFFiles) { + this.cacheAllCSFFiles(true); + } + return null; } + + return this.storyIndex + .initialize({ sync: false }) + .then(() => (cacheAllCSFFiles ? this.cacheAllCSFFiles(false) : null)); } updateProjectAnnotations(projectAnnotations: ProjectAnnotations) { @@ -129,82 +139,100 @@ export class StoryStore { this.importFn = importFn; // We need to refetch the stories list as it may have changed too - await this.storyIndex.cache(); + await this.storyIndex.cache(false); if (this.cachedCSFFiles) { - await this.cacheAllCSFFiles(); + await this.cacheAllCSFFiles(false); } } // To load a single CSF file to service a story we need to look up the importPath in the index - async loadCSFFileByStoryId(storyId: StoryId): Promise> { - const { importPath, title } = this.storyIndex.storyIdToEntry(storyId); - const moduleExports = await this.importFn(importPath); - // We pass the title in here as it may have been generated by autoTitle on the server. - return this.processCSFFileWithCache(moduleExports, title); - } + loadCSFFileByStoryId(storyId: StoryId, options: { sync: false }): Promise>; + + loadCSFFileByStoryId(storyId: StoryId, options: { sync: true }): CSFFile; - loadCSFFileByStoryIdSync(storyId: StoryId): CSFFile { + loadCSFFileByStoryId( + storyId: StoryId, + { sync = false }: { sync?: boolean } = {} + ): MaybePromise> { const { importPath, title } = this.storyIndex.storyIdToEntry(storyId); - const moduleExports = this.importFn(importPath); - if (Promise.resolve(moduleExports) === moduleExports) { + const moduleExportsOrPromise = this.importFn(importPath); + + const isPromise = Promise.resolve(moduleExportsOrPromise) === moduleExportsOrPromise; + if (!isPromise) { + // We pass the title in here as it may have been generated by autoTitle on the server. + return this.processCSFFileWithCache(moduleExportsOrPromise as ModuleExports, title); + } + + if (sync) { throw new Error( `importFn() returned a promise, did you pass an async version then call initializeSync()?` ); } - return this.processCSFFileWithCache(moduleExports as ModuleExports, title); - } - - // Load all CSF files into the cache so we can call synchronous functions like `extract()`. - async loadAllCSFFiles(): Promise>> { - const importPaths: Record = {}; - Object.entries(this.storyIndex.stories).forEach(([storyId, { importPath }]) => { - importPaths[importPath] = storyId; - }); - const csfFileList = await Promise.all( - Object.entries(importPaths).map( - async ([importPath, storyId]): Promise<[Path, CSFFile]> => [ - importPath, - await this.loadCSFFileByStoryId(storyId), - ] - ) + return (moduleExportsOrPromise as Promise).then((moduleExports) => + // We pass the title in here as it may have been generated by autoTitle on the server. + this.processCSFFileWithCache(moduleExports, title) ); - - return csfFileList.reduce((acc, [importPath, csfFile]) => { - acc[importPath] = csfFile; - return acc; - }, {} as Record>); } - loadAllCSFFilesSync(): Record> { + loadAllCSFFiles(sync: false): Promise['cachedCSFFiles']>; + + loadAllCSFFiles(sync: true): StoryStore['cachedCSFFiles']; + + loadAllCSFFiles(sync: boolean): MaybePromise['cachedCSFFiles']> { const importPaths: Record = {}; Object.entries(this.storyIndex.stories).forEach(([storyId, { importPath }]) => { importPaths[importPath] = storyId; }); - const csfFileList = Object.entries(importPaths).map(([importPath, storyId]): [ - Path, - CSFFile - ] => [importPath, this.loadCSFFileByStoryIdSync(storyId)]); + const csfFileList = Object.entries(importPaths).map(([importPath, storyId]) => ({ + importPath, + csfFileOrPromise: sync + ? this.loadCSFFileByStoryId(storyId, { sync: true }) + : this.loadCSFFileByStoryId(storyId, { sync: false }), + })); - return csfFileList.reduce((acc, [importPath, csfFile]) => { - acc[importPath] = csfFile; - return acc; - }, {} as Record>); - } + function toObject(list: { importPath: Path; csfFile: CSFFile }[]) { + return list.reduce((acc, { importPath, csfFile }) => { + acc[importPath] = csfFile; + return acc; + }, {} as Record>); + } - async cacheAllCSFFiles(): Promise { - this.cachedCSFFiles = await this.loadAllCSFFiles(); + if (sync) { + return toObject( + csfFileList.map(({ importPath, csfFileOrPromise }) => ({ + importPath, + csfFile: csfFileOrPromise, + })) as { importPath: Path; csfFile: CSFFile }[] + ); + } + return Promise.all( + csfFileList.map(async ({ importPath, csfFileOrPromise }) => ({ + importPath, + csfFile: await csfFileOrPromise, + })) + ).then(toObject); } - cacheAllCSFFilesSync() { - this.cachedCSFFiles = this.loadAllCSFFilesSync(); + cacheAllCSFFiles(sync: false): Promise; + + cacheAllCSFFiles(sync: true): void; + + cacheAllCSFFiles(sync: boolean): MaybePromise { + if (sync) { + this.cachedCSFFiles = this.loadAllCSFFiles(true); + return null; + } + return this.loadAllCSFFiles(false).then((csfFiles) => { + this.cachedCSFFiles = csfFiles; + }); } // Load the CSF file for a story and prepare the story from it and the project annotations. async loadStory({ storyId }: { storyId: StoryId }): Promise> { - const csfFile = await this.loadCSFFileByStoryId(storyId); + const csfFile = await this.loadCSFFileByStoryId(storyId, { sync: false }); return this.storyFromCSFFile({ storyId, csfFile }); } From 18066d0ce805623ee4b1e746f47760d654e70bf9 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 9 Sep 2021 19:32:13 +1000 Subject: [PATCH 249/285] Add migration notes about new features --- MIGRATION.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 76c01e2cf7e..717a5e50034 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,7 +1,9 @@

Migration

- [From version 6.3.x to 6.4.0](#from-version-63x-to-640) + - [Story Store v7](#story-store-v7) - [Babel mode v7](#babel-mode-v7) + - [Loader behavior with args changes](#loader-behaviour-with-args-changes) - [From version 6.2.x to 6.3.0](#from-version-62x-to-630) - [Webpack 5 manager build](#webpack-5-manager-build) - [Angular 12 upgrade](#angular-12-upgrade) @@ -166,6 +168,42 @@ ## From version 6.3.x to 6.4.0 +### Story Store v7 + +SB6.4 introduces an opt-in feature flag, `features.storyStoreV7`, which loads stories in an "on demand" way (that is when rendered), rather than up front when the Storybook is booted. This way of operating will become the default in 7.0 and will likely be switched to opt-out in that version. + +The key benefit of the on demand store is that stories are code-split automatically (in `builder-webpack4` and `builder-webpack5`), which allows for much smaller bundle sizes, faster rendering, and improved general performance via various opt-in Webpack features. + +The on-demand store relies on the "story index" data structure which is generated in the server (node) via static code analysis. As such, it has the following limitations: + +- Does not work with `storiesOf()` +- Does not work if you used dynamic story names or component titles. + +However, the `autoTitle` feature is supported. + +#### Behavioral differences + +The key behavioral differences of the v7 store are: + +- `SET_STORIES` is not emitted on boot up. Instead the manager loads the story index independenly. +- A new event `STORY_PREPARED` is emitted when a story is rendered for the first time, which contains metadata about the story, such as `parameters`. +- All "entire" store APIs such as `extract()` need to be proceeded by an async call to `loadAllCSFFiles()` which fetches all CSF files and processes them. + +#### Using the v7 store + +To activate the v7 mode set the feature flag in your `.storybook/main.js` config: + +```js +module.exports = { + // ... your existing config + features: { + storyStoreV7: true, + }, +}; +``` + +NOTE: `features.storyStoreV7` implies `features.buildStoriesJson` and has the same limitations. + ### Babel mode v7 SB6.4 introduces an opt-in feature flag, `features.babelModeV7`, that reworks the way Babel is configured in Storybook to make it more consistent with the Babel is configured in your app. This breaking change will become the default in SB 7.0, but we encourage you to migrate today. @@ -197,6 +235,10 @@ npx sb@next babelrc This will create a `.babelrc.json` file. This file includes a bunch of babel plugins, so you may need to add new package devDependencies accordingly. +### Loader behavior with args changes + +In 6.4 the behavior of loaders when arg changes occurred was tweaked so loaders do not re-run. Instead the previous value of the loader in passed to the story, irrespective of the new args. + ## From version 6.2.x to 6.3.0 ### Webpack 5 manager build From b76e744af478819fda1e71b215970ebfb1e301fe Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Fri, 10 Sep 2021 13:26:22 +0800 Subject: [PATCH 250/285] Temporarily restore glob-base to fix importFn --- lib/core-common/package.json | 2 ++ lib/core-common/src/utils/to-importFn.ts | 10 +++--- yarn.lock | 44 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/lib/core-common/package.json b/lib/core-common/package.json index e3c40e7011a..cf7cb7f2afb 100644 --- a/lib/core-common/package.json +++ b/lib/core-common/package.json @@ -63,6 +63,7 @@ "@babel/register": "^7.12.1", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", + "@types/glob-base": "^0.3.0", "@types/micromatch": "^4.0.1", "@types/node": "^14.0.10", "@types/pretty-hrtime": "^1.0.0", @@ -77,6 +78,7 @@ "fork-ts-checker-webpack-plugin": "^6.0.4", "fs-extra": "^9.0.1", "glob": "^7.1.6", + "glob-base": "^0.3.0", "handlebars": "^4.7.7", "interpret": "^2.2.0", "json5": "^2.1.3", diff --git a/lib/core-common/src/utils/to-importFn.ts b/lib/core-common/src/utils/to-importFn.ts index 35a4f5c764c..7310bc904e8 100644 --- a/lib/core-common/src/utils/to-importFn.ts +++ b/lib/core-common/src/utils/to-importFn.ts @@ -1,19 +1,21 @@ +import globBase from 'glob-base'; +import { makeRe } from 'micromatch'; import dedent from 'ts-dedent'; import type { NormalizedStoriesEntry } from '../types'; -import { toRequireContext } from './to-require-context'; export function toImportFnPart(entry: NormalizedStoriesEntry) { - const { path: base, match } = toRequireContext(entry.glob); + const { base } = globBase(entry.glob); + const regex = makeRe(entry.glob, { fastpaths: false, noglobstar: false, bash: false }); - const webpackIncludeRegex = new RegExp(match.substring(1)); + const webpackIncludeRegex = new RegExp(regex.source.substring(1)); // NOTE: `base` looks like './src' but `path`, (and what micromatch expects) // is something that starts with `src/`. So to strip off base from path, we // need to drop `base.length - 1` chars. return dedent` async (path) => { - if (!/${match}/.exec(path)) { + if (!${regex}.exec(path)) { return; } const remainder = path.substring(${base.length - 1}); diff --git a/yarn.lock b/yarn.lock index 3cef6f5a875..28e0cae5d93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7991,6 +7991,7 @@ __metadata: "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 + "@types/glob-base": ^0.3.0 "@types/interpret": ^1.1.1 "@types/micromatch": ^4.0.1 "@types/mock-fs": ^4.13.0 @@ -8007,6 +8008,7 @@ __metadata: fork-ts-checker-webpack-plugin: ^6.0.4 fs-extra: ^9.0.1 glob: ^7.1.6 + glob-base: ^0.3.0 handlebars: ^4.7.7 interpret: ^2.2.0 json5: ^2.1.3 @@ -9922,6 +9924,13 @@ __metadata: languageName: node linkType: hard +"@types/glob-base@npm:^0.3.0": + version: 0.3.0 + resolution: "@types/glob-base@npm:0.3.0" + checksum: 2c0cb3b7bb7c8661b9421194c0fd90a36e1c786a4124375749df9dc1dd8ade536c8eb2ac93b217db24ed3a427755def9a54bc86c2b6bf64a81fb82e7e6f44cc7 + languageName: node + linkType: hard + "@types/glob@npm:*, @types/glob@npm:^7.1.1, @types/glob@npm:^7.1.3": version: 7.1.3 resolution: "@types/glob@npm:7.1.3" @@ -24220,6 +24229,25 @@ fsevents@^1.2.7: languageName: node linkType: hard +"glob-base@npm:^0.3.0": + version: 0.3.0 + resolution: "glob-base@npm:0.3.0" + dependencies: + glob-parent: ^2.0.0 + is-glob: ^2.0.0 + checksum: 4ce785c1dac2ff1e4660c010fa43ed2f1b38993dfd004023a3e7080b20bc61f29fbfe5d265b7e64cc84096ecf44e8ca876c7c1aad8f1f995d4c0f33034f3ae8c + languageName: node + linkType: hard + +"glob-parent@npm:^2.0.0": + version: 2.0.0 + resolution: "glob-parent@npm:2.0.0" + dependencies: + is-glob: ^2.0.0 + checksum: b9d59dc532d47aaaa4841046ff631b325a707f738445300b83b7a1ee603dd060c041a378e8a195c887d479bb703685cee4725c8f54b8dacef65355375f57d32a + languageName: node + linkType: hard + "glob-parent@npm:^3.1.0": version: 3.1.0 resolution: "glob-parent@npm:3.1.0" @@ -26693,6 +26721,13 @@ fsevents@^1.2.7: languageName: node linkType: hard +"is-extglob@npm:^1.0.0": + version: 1.0.0 + resolution: "is-extglob@npm:1.0.0" + checksum: 1ce5366d19958f36069a45ca996c1e51ab607f42a01eb0505f0ccffe8f9c91f5bcba6e971605efd8b4d4dfd0111afa3c8df3e1746db5b85b9a8f933f5e7286b7 + languageName: node + linkType: hard + "is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -26751,6 +26786,15 @@ fsevents@^1.2.7: languageName: node linkType: hard +"is-glob@npm:^2.0.0": + version: 2.0.1 + resolution: "is-glob@npm:2.0.1" + dependencies: + is-extglob: ^1.0.0 + checksum: ef156806af0924983325c9218a8b8a838fa50e1a104ed2a11fe94829a5b27c1b05a4c8cf98d96cb3a7fea539c21f14ae2081e1a248f3d5a9eea62f2d4e9f8b0c + languageName: node + linkType: hard + "is-glob@npm:^3.0.0, is-glob@npm:^3.1.0": version: 3.1.0 resolution: "is-glob@npm:3.1.0" From 5b5524babf9c3896a6a03754d1815ff3eaeee6b6 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Fri, 10 Sep 2021 13:27:01 +0800 Subject: [PATCH 251/285] Recompute stories.json on each request in dev-mode --- lib/core-server/src/utils/stories-json.ts | 51 +++++++++++------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/lib/core-server/src/utils/stories-json.ts b/lib/core-server/src/utils/stories-json.ts index 11059fdefe4..29fdaeca154 100644 --- a/lib/core-server/src/utils/stories-json.ts +++ b/lib/core-server/src/utils/stories-json.ts @@ -2,7 +2,7 @@ import path from 'path'; import fs from 'fs-extra'; import glob from 'globby'; import { logger } from '@storybook/node-logger'; -import { resolvePathInStorybookCache, Options, normalizeStories } from '@storybook/core-common'; +import { Options, normalizeStories } from '@storybook/core-common'; import { readCsfOrMdx } from '@storybook/csf-tools'; interface ExtractedStory { @@ -13,11 +13,7 @@ interface ExtractedStory { type ExtractedStories = Record; -export async function extractStoriesJson( - outputFile: string, - storiesGlobs: string[], - configDir: string -) { +async function extractStories(storiesGlobs: string[], configDir: string) { if (!storiesGlobs) { throw new Error('No stories glob'); } @@ -54,34 +50,37 @@ export async function extractStoriesJson( } }) ); - await fs.writeJson(outputFile, { v: 3, stories }); + return stories; } -const timeout = 30000; // 30s -const step = 100; // .1s +export async function extractStoriesJson( + outputFile: string, + storiesGlobs: string[], + configDir: string +) { + const stories = await extractStories(storiesGlobs, configDir); + await fs.writeJson(outputFile, { v: 3, stories }); +} export async function useStoriesJson(router: any, options: Options) { - const storiesJson = resolvePathInStorybookCache('stories.json'); - await fs.remove(storiesJson); - const stories = normalizeStories(await options.presets.apply('stories'), { + const normalized = normalizeStories(await options.presets.apply('stories'), { configDir: options.configDir, workingDir: process.cwd(), }); - const globs = stories.map((s) => s.glob); - extractStoriesJson(storiesJson, globs, options.configDir); - console.log('extracted'); + const globs = normalized.map((s) => s.glob); router.use('/stories.json', async (_req: any, res: any) => { - console.log('getting stories.json'); - for (let i = 0; i < timeout / step; i += 1) { - if (fs.existsSync(storiesJson)) { - // eslint-disable-next-line no-await-in-loop - const json = await fs.readFile(storiesJson, 'utf-8'); + extractStories(globs, options.configDir) + .then((stories: ExtractedStories) => { res.header('Content-Type', 'application/json'); - return res.send(json); - } - // eslint-disable-next-line no-await-in-loop - await new Promise((r: any) => setTimeout(r, step)); - } - return res.status(408).send('stories.json timeout'); + return res.send( + JSON.stringify({ + v: 3, + stories, + }) + ); + }) + .catch((err: Error) => { + res.status(500).send(err.message); + }); }); } From 5c833834b2646b7a615de766a830f23524e4f1a6 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 10 Sep 2021 18:31:28 +1000 Subject: [PATCH 252/285] Add warning if find old `stories.json` https://github.com/storybookjs/storybook/pull/16004/files/b05020ce5c1ca9f12cc5c0f7bd4e2aa8d20d7102#r705834795 --- lib/api/src/modules/stories.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/api/src/modules/stories.ts b/lib/api/src/modules/stories.ts index 33ad5c1675c..78224e84013 100644 --- a/lib/api/src/modules/stories.ts +++ b/lib/api/src/modules/stories.ts @@ -11,6 +11,7 @@ import { STORY_SPECIFIED, } from '@storybook/core-events'; import deprecate from 'util-deprecate'; +import { logger } from '@storybook/client-logger'; import { getEventMetadata } from '../lib/events'; import { @@ -355,6 +356,7 @@ export const init: ModuleFn = ({ // We can only do this if the stories.json is a proper storyIndex if (storyIndex.v !== 3) { + logger.warn(`Skipping story index with version v${storyIndex.v}, awaiting SET_STORIES.`); return; } From 9473f4db90ded429d0d34c1296efb69cad9f42a4 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 10 Sep 2021 18:36:52 +1000 Subject: [PATCH 253/285] Apply suggestions from code review --- lib/preview-web/src/PreviewWeb.mockdata.ts | 4 ++-- lib/preview-web/src/UrlStore.test.ts | 2 +- lib/store/README.md | 10 +++++----- lib/store/src/StoryStore.ts | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.mockdata.ts b/lib/preview-web/src/PreviewWeb.mockdata.ts index a4d1d5259ab..6c3238974ed 100644 --- a/lib/preview-web/src/PreviewWeb.mockdata.ts +++ b/lib/preview-web/src/PreviewWeb.mockdata.ts @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; import Events from '@storybook/core-events'; -import { StoriesList } from '@storybook/store'; +import { StoryIndex } from '@storybook/store'; export const componentOneExports = { default: { @@ -33,7 +33,7 @@ export const projectAnnotations = { }; export const getProjectAnnotations = () => projectAnnotations; -export const storyIndex: StoriesList = { +export const storyIndex: StoryIndex = { v: 3, stories: { 'component-one--a': { diff --git a/lib/preview-web/src/UrlStore.test.ts b/lib/preview-web/src/UrlStore.test.ts index 28fda9cc8fd..463008c8b58 100644 --- a/lib/preview-web/src/UrlStore.test.ts +++ b/lib/preview-web/src/UrlStore.test.ts @@ -75,7 +75,7 @@ describe('UrlStore', () => { viewMode: 'story', }); }); - it('should redirect legacy queries', () => { + it('should parse legacy queries', () => { document.location.search = '?selectedKind=kind&selectedStory=story'; expect(getSelectionSpecifierFromPath()).toEqual({ storySpecifier: { title: 'kind', name: 'story' }, diff --git a/lib/store/README.md b/lib/store/README.md index 3a97f2a63f1..ee8d5968ea9 100644 --- a/lib/store/README.md +++ b/lib/store/README.md @@ -22,8 +22,8 @@ The first set of fields on a `Story` are the identifying fields for a story: The main fields on a `Story` are the various annotations. Annotations can be set: - At the project level in `preview.js` (or via addons) -- At the component level via `export default = { ... }` in a CSF file -- At the story level via `export Story = {...}` in a CSF file. +- At the component level via `export default { ... }` in a CSF file +- At the story level via `export const Story = {...}` in a CSF file. Not all annotations can be set at every level but most can. @@ -97,7 +97,7 @@ Arg types add type information and metadata about args that are used to control ### ArgTypes enhancement -To add a argTypes enhancer, `export addArgTypesEnhancers = []` from `preview.js` or and addon +To add a argTypes enhancer, `export const argTypesEnhancers = []` from `preview.js` or and addon There is a default enhancer that ensures that each `arg` in a story has a baseline `argType`. This value can be improved by subsequent enhancers, e.g. those provided by `@storybook/addon-docs`. @@ -105,11 +105,11 @@ There is a default enhancer that ensures that each `arg` in a story has a baseli Globals are rendering information that is global across stories. They are used for things like themes and internationalization (i18n) in stories, where you want Storybook to "remember" your setting as you browse between stories. -They can be access in stories and decorators in the `context.globals` key. +They can be accessed in stories and decorators in the `context.globals` key. ### Initial values of globals -To set initial values of globals, `export globals = {...}` from `preview.js` +To set initial values of globals, `export const globals = {...}` from `preview.js` ### Using globals in an addon diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 1f447020e6a..c2040498d27 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -34,8 +34,8 @@ import { inferControls } from './inferControls'; type MaybePromise = Promise | T; // TODO -- what are reasonable values for these? -const CSF_CACHE_SIZE = 100; -const STORY_CACHE_SIZE = 1000; +const CSF_CACHE_SIZE = 1000; +const STORY_CACHE_SIZE = 10000; function normalizeProjectAnnotations({ argTypes, @@ -166,7 +166,7 @@ export class StoryStore { if (sync) { throw new Error( - `importFn() returned a promise, did you pass an async version then call initializeSync()?` + `importFn() returned a promise, did you pass an async version then call initialize({sync: true})?` ); } From 06c58d9d6e40ac44ebc1c6d7c9bf5b03c0c98bc7 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 11 Sep 2021 16:04:56 +1000 Subject: [PATCH 254/285] Add presets for all frameworks --- app/ember/src/client/preview/index.ts | 4 ++-- app/ember/src/client/preview/render.ts | 2 +- app/html/preset.js | 7 +++++++ app/html/src/client/preview/config.ts | 3 +++ app/html/src/client/preview/index.ts | 4 ++-- app/html/src/client/preview/render.ts | 2 +- app/preact/preset.js | 7 +++++++ app/preact/src/client/preview/config.ts | 3 +++ app/preact/src/client/preview/index.ts | 4 ++-- app/preact/src/client/preview/render.tsx | 2 +- app/react/src/client/preview/config.ts | 3 +++ app/react/src/client/preview/config.tsx | 5 ----- app/server/preset.js | 7 +++++++ app/server/src/client/preview/config.ts | 3 +++ app/server/src/client/preview/index.ts | 6 ++---- app/server/src/client/preview/render.ts | 6 ++++-- app/svelte/preset.js | 7 +++++++ app/svelte/src/client/preview/config.ts | 3 +++ app/svelte/src/client/preview/index.ts | 6 ++++-- app/svelte/src/client/preview/render.ts | 2 +- app/vue/preset.js | 7 +++++++ app/vue/src/client/preview/config.ts | 3 +++ app/vue/src/client/preview/index.ts | 4 ++-- app/vue/src/client/preview/render.ts | 2 +- app/vue3/preset.js | 7 +++++++ app/vue3/src/client/preview/config.ts | 3 +++ app/vue3/src/client/preview/index.ts | 4 ++-- app/vue3/src/client/preview/render.ts | 2 +- app/web-components/preset.js | 7 +++++++ app/web-components/src/client/preview/config.ts | 3 +++ app/web-components/src/client/preview/index.ts | 4 ++-- app/web-components/src/client/preview/render.ts | 2 +- 32 files changed, 102 insertions(+), 32 deletions(-) create mode 100644 app/html/preset.js create mode 100644 app/html/src/client/preview/config.ts create mode 100644 app/preact/preset.js create mode 100644 app/preact/src/client/preview/config.ts create mode 100644 app/react/src/client/preview/config.ts delete mode 100644 app/react/src/client/preview/config.tsx create mode 100644 app/server/preset.js create mode 100644 app/server/src/client/preview/config.ts create mode 100644 app/svelte/preset.js create mode 100644 app/svelte/src/client/preview/config.ts create mode 100644 app/vue/preset.js create mode 100644 app/vue/src/client/preview/config.ts create mode 100644 app/vue3/preset.js create mode 100644 app/vue3/src/client/preview/config.ts create mode 100644 app/web-components/preset.js create mode 100644 app/web-components/src/client/preview/config.ts diff --git a/app/ember/src/client/preview/index.ts b/app/ember/src/client/preview/index.ts index 6eb84bc6140..78bc0f24d3b 100644 --- a/app/ember/src/client/preview/index.ts +++ b/app/ember/src/client/preview/index.ts @@ -1,9 +1,9 @@ import { start } from '@storybook/core/client'; import './globals'; -import render from './render'; +import { renderToDOM } from './render'; -const { configure: coreConfigure, clientApi, forceReRender } = start(render); +const { configure: coreConfigure, clientApi, forceReRender } = start(renderToDOM); export const { setAddon, diff --git a/app/ember/src/client/preview/render.ts b/app/ember/src/client/preview/render.ts index afb49e565f0..29f9375680a 100644 --- a/app/ember/src/client/preview/render.ts +++ b/app/ember/src/client/preview/render.ts @@ -60,7 +60,7 @@ function render(options: OptionsArgs, el: HTMLElement) { }); } -export default function renderMain( +export function renderToDOM( { storyFn, kind, name, showMain, showError }: RenderContext, domElement: HTMLElement ) { diff --git a/app/html/preset.js b/app/html/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/html/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/html/src/client/preview/config.ts b/app/html/src/client/preview/config.ts new file mode 100644 index 00000000000..981ec886773 --- /dev/null +++ b/app/html/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { renderToDOM } from './render'; + +export const parameters = { framework: 'html' }; diff --git a/app/html/src/client/preview/index.ts b/app/html/src/client/preview/index.ts index 50450304f66..96f8be1e915 100644 --- a/app/html/src/client/preview/index.ts +++ b/app/html/src/client/preview/index.ts @@ -4,7 +4,7 @@ import { ClientStoryApi, Loadable } from '@storybook/addons'; import { HtmlFramework } from './types-6-0'; import './globals'; -import render from './render'; +import { renderToDOM } from './render'; import { IStorybookSection } from './types'; const framework = 'html'; @@ -18,7 +18,7 @@ interface ClientApi extends ClientStoryApi { raw: () => any; // todo add type } -const api = start(render); +const api = start(renderToDOM); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ diff --git a/app/html/src/client/preview/render.ts b/app/html/src/client/preview/render.ts index 411a745a0dd..f9a29aab5eb 100644 --- a/app/html/src/client/preview/render.ts +++ b/app/html/src/client/preview/render.ts @@ -7,7 +7,7 @@ import { HtmlFramework } from './types-6-0'; const { Node } = global; -export default function renderMain( +export function renderToDOM( { storyFn, kind, name, showMain, showError, forceRemount }: RenderContext, domElement: HTMLElement ) { diff --git a/app/preact/preset.js b/app/preact/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/preact/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/preact/src/client/preview/config.ts b/app/preact/src/client/preview/config.ts new file mode 100644 index 00000000000..4038e5dbab2 --- /dev/null +++ b/app/preact/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { renderToDOM } from './render'; + +export const parameters = { framework: 'preact' }; diff --git a/app/preact/src/client/preview/index.ts b/app/preact/src/client/preview/index.ts index 6f35fcf2060..82bbf67a73d 100644 --- a/app/preact/src/client/preview/index.ts +++ b/app/preact/src/client/preview/index.ts @@ -3,7 +3,7 @@ import { start } from '@storybook/core/client'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import './globals'; -import render from './render'; +import { renderToDOM } from './render'; import { IStorybookSection } from './types'; import { PreactFramework } from './types-6-0'; @@ -18,7 +18,7 @@ export interface ClientApi extends ClientStoryApi { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ diff --git a/app/preact/src/client/preview/render.tsx b/app/preact/src/client/preview/render.tsx index 981197f28f7..095e2ebea50 100644 --- a/app/preact/src/client/preview/render.tsx +++ b/app/preact/src/client/preview/render.tsx @@ -36,7 +36,7 @@ const StoryHarness: preact.FunctionalComponent<{ return content; }; -export default function renderMain( +export function renderToDOM( { storyFn, title, name, showMain, showError, forceRemount }: RenderContext, domElement: HTMLElement ) { diff --git a/app/react/src/client/preview/config.ts b/app/react/src/client/preview/config.ts new file mode 100644 index 00000000000..decd470c6d0 --- /dev/null +++ b/app/react/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { render, renderToDOM } from './render'; + +export const parameters = { framework: 'react' }; diff --git a/app/react/src/client/preview/config.tsx b/app/react/src/client/preview/config.tsx deleted file mode 100644 index 575cb8584d2..00000000000 --- a/app/react/src/client/preview/config.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Parameters } from './types-6-3'; - -export { render, renderToDOM } from './render'; - -export const parameters: Parameters = { framework: 'react' }; diff --git a/app/server/preset.js b/app/server/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/server/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/server/src/client/preview/config.ts b/app/server/src/client/preview/config.ts new file mode 100644 index 00000000000..221ce28653f --- /dev/null +++ b/app/server/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { render, renderToDOM } from './render'; + +export const parameters = { framework: 'server' }; diff --git a/app/server/src/client/preview/index.ts b/app/server/src/client/preview/index.ts index e77650e889a..6b6d6f99db5 100644 --- a/app/server/src/client/preview/index.ts +++ b/app/server/src/client/preview/index.ts @@ -1,8 +1,8 @@ import { start } from '@storybook/core/client'; -import { ClientStoryApi, Loadable, StoryFn, Args } from '@storybook/addons'; +import { ClientStoryApi, Loadable } from '@storybook/addons'; import './globals'; -import { renderMain as renderToDOM } from './render'; +import { renderToDOM, render } from './render'; import { IStorybookSection, ServerFramework } from './types'; const framework = 'server'; @@ -16,8 +16,6 @@ interface ClientApi extends ClientStoryApi { raw: () => any; // todo add type } -const render: StoryFn = (args: Args) => {}; - const api = start(renderToDOM, { render }); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { diff --git a/app/server/src/client/preview/render.ts b/app/server/src/client/preview/render.ts index 0d2f00bded5..450bab66d85 100644 --- a/app/server/src/client/preview/render.ts +++ b/app/server/src/client/preview/render.ts @@ -1,9 +1,9 @@ /* eslint-disable no-param-reassign */ import global from 'global'; import dedent from 'ts-dedent'; -import { Args, ArgTypes } from '@storybook/api'; import { RenderContext } from '@storybook/store'; import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/preview-web'; +import { StoryFn, Args, ArgTypes } from '@storybook/csf'; import { FetchStoryHtmlType, ServerFramework } from './types'; const { fetch, Node } = global; @@ -40,7 +40,9 @@ const buildStoryArgs = (args: Args, argTypes: ArgTypes) => { return storyArgs; }; -export async function renderMain( +export const render: StoryFn = (args: Args) => {}; + +export async function renderToDOM( { id, title, diff --git a/app/svelte/preset.js b/app/svelte/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/svelte/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/svelte/src/client/preview/config.ts b/app/svelte/src/client/preview/config.ts new file mode 100644 index 00000000000..1a3054f5126 --- /dev/null +++ b/app/svelte/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { renderToDOM } from './render'; + +export const parameters = { framework: 'svelte' }; diff --git a/app/svelte/src/client/preview/index.ts b/app/svelte/src/client/preview/index.ts index cbfed51c166..271ccc0602b 100644 --- a/app/svelte/src/client/preview/index.ts +++ b/app/svelte/src/client/preview/index.ts @@ -2,9 +2,11 @@ import { start } from '@storybook/core/client'; import { decorateStory } from './decorators'; import './globals'; -import render from './render'; +import { renderToDOM } from './render'; -const { configure: coreConfigure, clientApi, forceReRender } = start(render, { decorateStory }); +const { configure: coreConfigure, clientApi, forceReRender } = start(renderToDOM, { + decorateStory, +}); export const { setAddon, diff --git a/app/svelte/src/client/preview/render.ts b/app/svelte/src/client/preview/render.ts index aa1934a21c7..4b2e4a9a81f 100644 --- a/app/svelte/src/client/preview/render.ts +++ b/app/svelte/src/client/preview/render.ts @@ -15,7 +15,7 @@ function cleanUpPreviousStory() { previousComponent = null; } -export default function render( +export function renderToDOM( { storyFn, kind, name, showMain, showError }: RenderContext, domElement: HTMLElement ) { diff --git a/app/vue/preset.js b/app/vue/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/vue/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/vue/src/client/preview/config.ts b/app/vue/src/client/preview/config.ts new file mode 100644 index 00000000000..1ffa6048478 --- /dev/null +++ b/app/vue/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { renderToDOM } from './render'; + +export const parameters = { framework: 'vue' }; diff --git a/app/vue/src/client/preview/index.ts b/app/vue/src/client/preview/index.ts index f733d2b44a7..1470e77e91b 100644 --- a/app/vue/src/client/preview/index.ts +++ b/app/vue/src/client/preview/index.ts @@ -9,7 +9,7 @@ import './globals'; import { IStorybookSection, StoryFnVueReturnType } from './types'; import { VueFramework } from './types-6-0'; -import render, { VALUES } from './render'; +import { renderToDOM, VALUES } from './render'; import { extractProps } from './util'; export const WRAPS = 'STORYBOOK_WRAPS'; @@ -100,7 +100,7 @@ interface ClientApi extends ClientStoryApi { load: (...args: any[]) => void; } -const api = start(render, { decorateStory }); +const api = start(renderToDOM, { decorateStory }); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ diff --git a/app/vue/src/client/preview/render.ts b/app/vue/src/client/preview/render.ts index c1328c2719a..2f82dd7fa70 100644 --- a/app/vue/src/client/preview/render.ts +++ b/app/vue/src/client/preview/render.ts @@ -19,7 +19,7 @@ const root = new Vue({ }, }); -export default function render( +export function renderToDOM( { title, name, diff --git a/app/vue3/preset.js b/app/vue3/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/vue3/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/vue3/src/client/preview/config.ts b/app/vue3/src/client/preview/config.ts new file mode 100644 index 00000000000..256d07e9a05 --- /dev/null +++ b/app/vue3/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { renderToDOM } from './render'; + +export const parameters = { framework: 'vue3' }; diff --git a/app/vue3/src/client/preview/index.ts b/app/vue3/src/client/preview/index.ts index e8302827ab0..83ea77664b3 100644 --- a/app/vue3/src/client/preview/index.ts +++ b/app/vue3/src/client/preview/index.ts @@ -9,7 +9,7 @@ import './globals'; import { IStorybookSection } from './types'; import { VueFramework } from './types-6-0'; -import render, { storybookApp } from './render'; +import { renderToDOM, storybookApp } from './render'; /* This normalizes a functional component into a render method in ComponentOptions. @@ -87,7 +87,7 @@ interface ClientApi extends ClientStoryApi { app: App; } -const api = start(render, { decorateStory }); +const api = start(renderToDOM, { decorateStory }); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ diff --git a/app/vue3/src/client/preview/render.ts b/app/vue3/src/client/preview/render.ts index 22fa07929eb..db46ddfaa96 100644 --- a/app/vue3/src/client/preview/render.ts +++ b/app/vue3/src/client/preview/render.ts @@ -23,7 +23,7 @@ export const storybookApp = createApp({ }, }); -export default function render( +export function renderToDOM( { title, name, storyFn, showMain, showError, showException }: RenderContext, domElement: HTMLElement ) { diff --git a/app/web-components/preset.js b/app/web-components/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/web-components/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/web-components/src/client/preview/config.ts b/app/web-components/src/client/preview/config.ts new file mode 100644 index 00000000000..a8f16dae770 --- /dev/null +++ b/app/web-components/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { renderToDOM } from './render'; + +export const parameters = { framework: 'web-components' }; diff --git a/app/web-components/src/client/preview/index.ts b/app/web-components/src/client/preview/index.ts index f6f71e6669d..44ba037d0f0 100644 --- a/app/web-components/src/client/preview/index.ts +++ b/app/web-components/src/client/preview/index.ts @@ -3,7 +3,7 @@ import { start } from '@storybook/core/client'; import { ClientStoryApi, Loadable } from '@storybook/addons'; import './globals'; -import render from './render'; +import { renderToDOM } from './render'; import { IStorybookSection } from './types'; import { WebComponentsFramework } from './types-6-0'; @@ -18,7 +18,7 @@ interface ClientApi extends ClientStoryApi any; // todo add type } -const api = start(render); +const api = start(renderToDOM); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { return (api.clientApi.storiesOf(kind, m) as ReturnType).addParameters({ diff --git a/app/web-components/src/client/preview/render.ts b/app/web-components/src/client/preview/render.ts index 3b4662c1ec8..86a44c81b9d 100644 --- a/app/web-components/src/client/preview/render.ts +++ b/app/web-components/src/client/preview/render.ts @@ -11,7 +11,7 @@ import { WebComponentsFramework } from './types-6-0'; const { Node } = global; -export default function renderMain( +export function renderToDOM( { storyFn, kind, name, showMain, showError, forceRemount }: RenderContext, domElement: HTMLElement ) { From 66e226e9eb4f7fa2e98e1d2b691c1d8906f69978 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 11 Sep 2021 16:28:21 +1000 Subject: [PATCH 255/285] Somehow missed this --- app/angular/preset.js | 7 +++++++ app/angular/src/client/preview/config.ts | 3 +++ app/angular/src/client/preview/index.ts | 5 ++--- app/angular/src/client/preview/render.ts | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 app/angular/preset.js create mode 100644 app/angular/src/client/preview/config.ts diff --git a/app/angular/preset.js b/app/angular/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/angular/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/angular/src/client/preview/config.ts b/app/angular/src/client/preview/config.ts new file mode 100644 index 00000000000..2ea6e7700bc --- /dev/null +++ b/app/angular/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { render, renderToDOM } from './render'; + +export const parameters = { framework: 'angular' }; diff --git a/app/angular/src/client/preview/index.ts b/app/angular/src/client/preview/index.ts index 408d96f0f83..91ff1e5e2ea 100644 --- a/app/angular/src/client/preview/index.ts +++ b/app/angular/src/client/preview/index.ts @@ -2,10 +2,10 @@ import { ClientStoryApi, Loadable } from '@storybook/addons'; import { start } from '@storybook/core/client'; import './globals'; -import renderToDOM from './render'; +import { renderToDOM, render } from './render'; import decorateStory from './decorateStory'; import { IStorybookSection } from './types'; -import { AngularFramework, Story } from './types-6-0'; +import { AngularFramework } from './types-6-0'; const framework = 'angular'; @@ -19,7 +19,6 @@ interface ClientApi extends ClientStoryApi { load: (...args: any[]) => void; } -const render: Story = (props) => ({ props }); const api = start(renderToDOM, { decorateStory, render }); export const storiesOf: ClientApi['storiesOf'] = (kind, m) => { diff --git a/app/angular/src/client/preview/render.ts b/app/angular/src/client/preview/render.ts index 4b6749a5e10..a942d7e05ad 100644 --- a/app/angular/src/client/preview/render.ts +++ b/app/angular/src/client/preview/render.ts @@ -1,4 +1,5 @@ import { RenderContext } from '@storybook/store'; +import { ArgsStoryFn } from '@storybook/csf'; import { renderNgApp } from './angular/helpers'; import { AngularFramework } from './types-6-0'; @@ -7,7 +8,9 @@ import { RendererFactory } from './angular-beta/RendererFactory'; export const rendererFactory = new RendererFactory(); -export default async function renderMain( +export const render: ArgsStoryFn = (props) => ({ props }); + +export async function renderToDOM( { storyFn, showMain, From 75bad87ea050453bd9d1c4282e8d7177b2790bd4 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 11 Sep 2021 16:31:50 +1000 Subject: [PATCH 256/285] Somehow missed this too --- app/ember/preset.js | 7 +++++++ app/ember/src/client/preview/config.ts | 3 +++ 2 files changed, 10 insertions(+) create mode 100644 app/ember/preset.js create mode 100644 app/ember/src/client/preview/config.ts diff --git a/app/ember/preset.js b/app/ember/preset.js new file mode 100644 index 00000000000..20b417ae97b --- /dev/null +++ b/app/ember/preset.js @@ -0,0 +1,7 @@ +function config(entry = []) { + return [...entry, require.resolve('./dist/esm/client/preview/config')]; +} + +module.exports = { + config, +}; diff --git a/app/ember/src/client/preview/config.ts b/app/ember/src/client/preview/config.ts new file mode 100644 index 00000000000..062428c585d --- /dev/null +++ b/app/ember/src/client/preview/config.ts @@ -0,0 +1,3 @@ +export { renderToDOM } from './render'; + +export const parameters = { framework: 'ember' }; From 0c7a166636afd80a276835a7ba637a04b90829e5 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 11 Sep 2021 19:50:48 +1000 Subject: [PATCH 257/285] Update most to nothing which defaults to --- addons/docs/package.json | 3 +++ addons/docs/src/blocks/ArgsTable.tsx | 10 +++++----- addons/docs/src/blocks/DocsContainer.tsx | 7 ++----- addons/docs/src/blocks/Meta.tsx | 6 +++--- addons/docs/src/blocks/Source.tsx | 4 ++-- addons/docs/src/blocks/Story.tsx | 12 ++++++------ addons/docs/src/blocks/Title.tsx | 2 +- addons/docs/src/blocks/mdx.tsx | 2 +- lib/preview-web/src/types.ts | 2 +- lib/store/src/types.ts | 20 ++++++++++++-------- 10 files changed, 36 insertions(+), 32 deletions(-) diff --git a/addons/docs/package.json b/addons/docs/package.json index dfb57e93baa..2ec46af49c7 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -160,6 +160,9 @@ "@storybook/angular": { "optional": true }, + "@storybook/html": { + "optional": true + }, "@storybook/react": { "optional": true }, diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index 7db03289d8e..7dac7f5a972 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -10,7 +10,7 @@ import { import { addons } from '@storybook/addons'; import { filterArgTypes, PropDescriptor } from '@storybook/store'; import Events from '@storybook/core-events'; -import { StrictArgTypes, Args } from '@storybook/csf'; +import { StrictArgTypes, Args, AnyFramework } from '@storybook/csf'; import { DocsContext, DocsContextProps } from './DocsContext'; import { Component, CURRENT_SELECTION, PRIMARY_STORY } from './types'; @@ -44,7 +44,7 @@ type ArgsTableProps = BaseProps | OfProps | ComponentsProps | StoryProps; const useArgs = ( storyId: string, - context: DocsContextProps + context: DocsContextProps ): [Args, (args: Args) => void, (argNames?: string[]) => void] => { const channel = addons.getChannel(); @@ -78,7 +78,7 @@ const useArgs = ( export const extractComponentArgTypes = ( component: Component, - { id, storyById }: DocsContextProps, + { id, storyById }: DocsContextProps, include?: PropDescriptor, exclude?: PropDescriptor ): StrictArgTypes => { @@ -99,7 +99,7 @@ const isShortcut = (value?: string) => { export const getComponent = ( props: ArgsTableProps = {}, - { id, storyById }: DocsContextProps + { id, storyById }: DocsContextProps ): Component => { const { of } = props as OfProps; const { story } = props as StoryProps; @@ -116,7 +116,7 @@ export const getComponent = ( const addComponentTabs = ( tabs: Record, components: Record, - context: DocsContextProps, + context: DocsContextProps, include?: PropDescriptor, exclude?: PropDescriptor, sort?: SortType diff --git a/addons/docs/src/blocks/DocsContainer.tsx b/addons/docs/src/blocks/DocsContainer.tsx index a3cf42db9ac..66d904b1f5d 100644 --- a/addons/docs/src/blocks/DocsContainer.tsx +++ b/addons/docs/src/blocks/DocsContainer.tsx @@ -15,7 +15,7 @@ import { scrollToElement } from './utils'; const { document, window: globalWindow } = global; -export interface DocsContainerProps { +export interface DocsContainerProps { context: DocsContextProps; } @@ -35,10 +35,7 @@ const warnOptionsTheme = deprecate( ` ); -export const DocsContainer: FunctionComponent> = ({ - context, - children, -}) => { +export const DocsContainer: FunctionComponent = ({ context, children }) => { const { id: storyId, storyById } = context; const { parameters: { options = {}, docs = {} }, diff --git a/addons/docs/src/blocks/Meta.tsx b/addons/docs/src/blocks/Meta.tsx index d2aca741e5c..206496266e8 100644 --- a/addons/docs/src/blocks/Meta.tsx +++ b/addons/docs/src/blocks/Meta.tsx @@ -1,14 +1,14 @@ import React, { FC, useContext } from 'react'; import global from 'global'; -import { BaseAnnotations } from '@storybook/csf'; +import { AnyFramework, BaseAnnotations } from '@storybook/csf'; import { Anchor } from './Anchor'; import { DocsContext, DocsContextProps } from './DocsContext'; const { document } = global; -type MetaProps = BaseAnnotations; +type MetaProps = BaseAnnotations; -function getFirstStoryId(docsContext: DocsContextProps): string { +function getFirstStoryId(docsContext: DocsContextProps): string { const stories = docsContext.componentStories(); return stories.length > 0 ? stories[0].id : null; diff --git a/addons/docs/src/blocks/Source.tsx b/addons/docs/src/blocks/Source.tsx index 0b23310cd8f..1c521af3426 100644 --- a/addons/docs/src/blocks/Source.tsx +++ b/addons/docs/src/blocks/Source.tsx @@ -42,11 +42,11 @@ type NoneProps = CommonProps; type SourceProps = SingleSourceProps | MultiSourceProps | CodeProps | NoneProps; -const getStory = (storyId: StoryId, docsContext: DocsContextProps): Story | null => { +const getStory = (storyId: StoryId, docsContext: DocsContextProps): Story | null => { return docsContext.storyById(storyId); }; -const getSourceState = (storyIds: string[], docsContext: DocsContextProps) => { +const getSourceState = (storyIds: string[], docsContext: DocsContextProps) => { const states = storyIds .map((storyId) => { const story = getStory(storyId, docsContext); diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index c99cefb80c2..46e98913497 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -22,7 +22,7 @@ export const storyBlockIdFromId = (storyId: string) => `story--${storyId}`; type PureStoryProps = ComponentProps; type Annotations = Pick< - StoryAnnotations, + StoryAnnotations, 'decorators' | 'parameters' | 'args' | 'argTypes' | 'loaders' >; type CommonProps = Annotations & { @@ -48,24 +48,24 @@ export type StoryProps = (StoryDefProps | StoryRefProps | StoryImportProps) & Co export const lookupStoryId = ( storyName: string, - { mdxStoryNameToKey, mdxComponentAnnotations }: DocsContextProps + { mdxStoryNameToKey, mdxComponentAnnotations }: DocsContextProps ) => toId( mdxComponentAnnotations.id || mdxComponentAnnotations.title, storyNameFromExport(mdxStoryNameToKey[storyName]) ); -export const getStoryId = (props: StoryProps, context: DocsContextProps): StoryId => { +export const getStoryId = (props: StoryProps, context: DocsContextProps): StoryId => { const { id } = props as StoryRefProps; const { name } = props as StoryDefProps; const inputId = id === CURRENT_SELECTION ? context.id : id; return inputId || lookupStoryId(name, context); }; -export const getStoryProps = ( +export const getStoryProps = ( { height, inline }: StoryProps, - story: StoryType, - context: DocsContextProps + story: StoryType, + context: DocsContextProps ): PureStoryProps => { const { name: storyName, parameters } = story; const { docs = {} } = parameters; diff --git a/addons/docs/src/blocks/Title.tsx b/addons/docs/src/blocks/Title.tsx index a815a189486..100b8b2926d 100644 --- a/addons/docs/src/blocks/Title.tsx +++ b/addons/docs/src/blocks/Title.tsx @@ -8,7 +8,7 @@ interface TitleProps { const STORY_KIND_PATH_SEPARATOR = /\s*\/\s*/; -export const extractTitle = ({ title }: DocsContextProps) => { +export const extractTitle = ({ title }: DocsContextProps) => { const groups = title.trim().split(STORY_KIND_PATH_SEPARATOR); return (groups && groups[groups.length - 1]) || title; }; diff --git a/addons/docs/src/blocks/mdx.tsx b/addons/docs/src/blocks/mdx.tsx index 59566c72930..3dbc6746ee9 100644 --- a/addons/docs/src/blocks/mdx.tsx +++ b/addons/docs/src/blocks/mdx.tsx @@ -17,7 +17,7 @@ export const assertIsFn = (val: any) => { }; // Hacky utility for adding mdxStoryToId to the default context -export const AddContext: FC> = (props) => { +export const AddContext: FC = (props) => { const { children, ...rest } = props; const parentContext = React.useContext(DocsContext); return ( diff --git a/lib/preview-web/src/types.ts b/lib/preview-web/src/types.ts index db389e2518a..95992f3eaf2 100644 --- a/lib/preview-web/src/types.ts +++ b/lib/preview-web/src/types.ts @@ -8,7 +8,7 @@ export type WebProjectAnnotations< renderToDOM?: (context: RenderContext, element: Element) => Promise | void; }; -export interface DocsContextProps { +export interface DocsContextProps { id: string; title: string; name: string; diff --git a/lib/store/src/types.ts b/lib/store/src/types.ts index fb8d4d4f953..7484a518a9d 100644 --- a/lib/store/src/types.ts +++ b/lib/store/src/types.ts @@ -26,21 +26,21 @@ export type ModuleExports = Record; export type ModuleImportFn = (path: Path) => Promise | ModuleExports; export type NormalizedProjectAnnotations< - TFramework extends AnyFramework + TFramework extends AnyFramework = AnyFramework > = ProjectAnnotations & { argTypes?: StrictArgTypes; globalTypes?: StrictGlobalTypes; }; export type NormalizedComponentAnnotations< - TFramework extends AnyFramework + TFramework extends AnyFramework = AnyFramework > = ComponentAnnotations & { // Useful to guarantee that id exists id: ComponentId; argTypes?: StrictArgTypes; }; -export type NormalizedStoryAnnotations = Omit< +export type NormalizedStoryAnnotations = Omit< StoryAnnotations, 'storyName' | 'story' > & { @@ -50,12 +50,14 @@ export type NormalizedStoryAnnotations = Omit< userStoryFn?: StoryFn; }; -export type CSFFile = { +export type CSFFile = { meta: NormalizedComponentAnnotations; stories: Record>; }; -export type Story = StoryContextForEnhancers & { +export type Story< + TFramework extends AnyFramework = AnyFramework +> = StoryContextForEnhancers & { originalStoryFn: StoryFn; undecoratedStoryFn: LegacyStoryFn; unboundStoryFn: LegacyStoryFn; @@ -63,11 +65,13 @@ export type Story = StoryContextForEnhancers Promise; }; -export type BoundStory = Story & { +export type BoundStory = Story & { storyFn: PartialStoryFn; }; -export declare type RenderContext = StoryIdentifier & { +export declare type RenderContext< + TFramework extends AnyFramework = AnyFramework +> = StoryIdentifier & { showMain: () => void; showError: (error: { title: string; description: string }) => void; showException: (err: Error) => void; @@ -102,7 +106,7 @@ export interface Selection { viewMode: ViewMode; } -export type DecoratorApplicator = ( +export type DecoratorApplicator = ( storyFn: LegacyStoryFn, decorators: DecoratorFunction[] ) => LegacyStoryFn; From ff29a54115aaf95bb6f853049051fe9da9e23d81 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 11 Sep 2021 19:54:15 +1000 Subject: [PATCH 258/285] Update CSF for `AnyFramework` --- addons/a11y/package.json | 2 +- addons/actions/package.json | 2 +- addons/backgrounds/package.json | 2 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/links/package.json | 2 +- addons/measure/package.json | 2 +- addons/outline/package.json | 2 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 2 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 2 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 2 +- lib/addons/package.json | 2 +- lib/api/package.json | 2 +- lib/client-api/package.json | 2 +- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/csf-tools/package.json | 2 +- lib/preview-web/package.json | 2 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- yarn.lock | 68 ++++++++++--------- 30 files changed, 65 insertions(+), 63 deletions(-) diff --git a/addons/a11y/package.json b/addons/a11y/package.json index d5309c8a116..5420031fd56 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/theming": "6.4.0-alpha.34", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/actions/package.json b/addons/actions/package.json index 07f2f7b3bea..551d6de0448 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index 51fbbfb91b7..7eb222e70e1 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,7 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/controls/package.json b/addons/controls/package.json index e92de05f83d..b7521193696 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", diff --git a/addons/docs/package.json b/addons/docs/package.json index 2ec46af49c7..c37cff2d03d 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/postinstall": "6.4.0-alpha.34", diff --git a/addons/links/package.json b/addons/links/package.json index 282bb474fc7..94be34d79e5 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/router": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/measure/package.json b/addons/measure/package.json index a9a092cc98d..cd6912bee98 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,7 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/outline/package.json b/addons/outline/package.json index d0a747e06e8..45c71c2474d 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,7 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index c0cacaff14b..0f02d85e89d 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-client": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index 5e0ac929227..363acbd8a9b 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/node-logger": "6.4.0-alpha.34", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index a14cab494c3..90c5de1964f 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index 98c9736dc06..1dc271b994e 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/preact/package.json b/app/preact/package.json index 89a8984795b..4788e881d11 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/react/package.json b/app/react/package.json index d8d57cb6425..8caaddc8f5b 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index 39e73404767..adb0fef3ee0 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,7 +50,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", diff --git a/app/svelte/package.json b/app/svelte/package.json index d83ec608b1f..29a58ccc5d2 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/store": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index 6f94d390577..2ca4f109426 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index 7ccee29e8f9..73084ffb980 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index 538355e3f80..74da6051b6c 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/lib/addons/package.json b/lib/addons/package.json index 811c8e5ea1d..0a50417f38c 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/api/package.json b/lib/api/package.json index 4f91d1aa725..49075c92c65 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.34", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index c46784d1ab4..cfd58eb971b 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -45,7 +45,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/store": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index 14d8cb0e0d2..46fbcb5f69e 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index 6995b89dc4e..ebe563d619f 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/theming": "6.4.0-alpha.34", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index 76aafeffd4f..caed3178a5e 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/ui": "6.4.0-alpha.34", diff --git a/lib/csf-tools/package.json b/lib/csf-tools/package.json index b737bbdf928..29b91a303b1 100644 --- a/lib/csf-tools/package.json +++ b/lib/csf-tools/package.json @@ -48,7 +48,7 @@ "@babel/traverse": "^7.12.11", "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "core-js": "^3.8.2", "fs-extra": "^9.0.1", "global": "^4.4.0", diff --git a/lib/preview-web/package.json b/lib/preview-web/package.json index ecd331a889f..e344a41ce92 100644 --- a/lib/preview-web/package.json +++ b/lib/preview-web/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "@storybook/store": "6.4.0-alpha.34", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index 0d87c72ef14..465a68baa27 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index 40a9c31702e..43910e6d127 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -43,7 +43,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.b1d5348.0", + "@storybook/csf": "0.0.2--canary.062665d.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/yarn.lock b/yarn.lock index 3cef6f5a875..bdcd4bb8d75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6834,7 +6834,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/theming": 6.4.0-alpha.34 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -6865,7 +6865,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/theming": 6.4.0-alpha.34 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -6900,7 +6900,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/theming": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -6928,7 +6928,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 @@ -6971,7 +6971,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/html": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 @@ -7050,6 +7050,8 @@ __metadata: peerDependenciesMeta: "@storybook/angular": optional: true + "@storybook/html": + optional: true "@storybook/react": optional: true "@storybook/vue": @@ -7173,7 +7175,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/router": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7203,7 +7205,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7227,7 +7229,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7262,7 +7264,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/node-logger": 6.4.0-alpha.34 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -7292,7 +7294,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-client": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/react": 6.4.0-alpha.34 "@storybook/vue": 6.4.0-alpha.34 "@storybook/vue3": 6.4.0-alpha.34 @@ -7455,7 +7457,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7488,7 +7490,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/autoprefixer": ^9.7.2 @@ -7557,7 +7559,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.34 @@ -7841,7 +7843,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/store": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7877,7 +7879,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7899,7 +7901,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/theming": 6.4.0-alpha.34 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -7938,7 +7940,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/ui": 6.4.0-alpha.34 @@ -8125,7 +8127,7 @@ __metadata: "@babel/traverse": ^7.12.11 "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@types/fs-extra": ^9.0.6 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -8139,12 +8141,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.b1d5348.0": - version: 0.0.2--canary.b1d5348.0 - resolution: "@storybook/csf@npm:0.0.2--canary.b1d5348.0" +"@storybook/csf@npm:0.0.2--canary.062665d.0": + version: 0.0.2--canary.062665d.0 + resolution: "@storybook/csf@npm:0.0.2--canary.062665d.0" dependencies: lodash: ^4.17.15 - checksum: 9e00c31b2ea32c432c7fb5ba5ea7cdaf7d7b949c561ffa32673bbc03486959b937f136f49cea3757ef3ea6961c2bea2c96638d16cf283e0c5abf25e59eb42ccc + checksum: 5a7e8d06d640c60d0a162061b8d4f1b3d1a55d80499914eb026c92f42725a04b5ddcfe8d2d33067cb37f16e4b4e390a4f8fb8e199be63aac9c3cc03c223cec2a languageName: node linkType: hard @@ -8272,7 +8274,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 @@ -8487,7 +8489,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -8547,7 +8549,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/store": 6.4.0-alpha.34 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -8593,7 +8595,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -8892,7 +8894,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 @@ -8921,7 +8923,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -8942,7 +8944,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -8961,7 +8963,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -9060,7 +9062,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9097,7 +9099,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9140,7 +9142,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.b1d5348.0 + "@storybook/csf": 0.0.2--canary.062665d.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 From a0acaccfadf4a4a73b16d3277ee42d3f2d5323b2 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 09:08:55 +1000 Subject: [PATCH 259/285] Use `to-require-context` for glob generation after all --- lib/core-common/package.json | 2 - lib/core-common/src/utils/to-importFn.ts | 6 +-- .../src/utils/to-require-context.ts | 2 +- yarn.lock | 44 ------------------- 4 files changed, 3 insertions(+), 51 deletions(-) diff --git a/lib/core-common/package.json b/lib/core-common/package.json index cf7cb7f2afb..e3c40e7011a 100644 --- a/lib/core-common/package.json +++ b/lib/core-common/package.json @@ -63,7 +63,6 @@ "@babel/register": "^7.12.1", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", - "@types/glob-base": "^0.3.0", "@types/micromatch": "^4.0.1", "@types/node": "^14.0.10", "@types/pretty-hrtime": "^1.0.0", @@ -78,7 +77,6 @@ "fork-ts-checker-webpack-plugin": "^6.0.4", "fs-extra": "^9.0.1", "glob": "^7.1.6", - "glob-base": "^0.3.0", "handlebars": "^4.7.7", "interpret": "^2.2.0", "json5": "^2.1.3", diff --git a/lib/core-common/src/utils/to-importFn.ts b/lib/core-common/src/utils/to-importFn.ts index 7310bc904e8..b72af8357e3 100644 --- a/lib/core-common/src/utils/to-importFn.ts +++ b/lib/core-common/src/utils/to-importFn.ts @@ -1,12 +1,10 @@ -import globBase from 'glob-base'; -import { makeRe } from 'micromatch'; import dedent from 'ts-dedent'; +import { toRequireContext } from '..'; import type { NormalizedStoriesEntry } from '../types'; export function toImportFnPart(entry: NormalizedStoriesEntry) { - const { base } = globBase(entry.glob); - const regex = makeRe(entry.glob, { fastpaths: false, noglobstar: false, bash: false }); + const { path: base, regex } = toRequireContext(entry.glob); const webpackIncludeRegex = new RegExp(regex.source.substring(1)); diff --git a/lib/core-common/src/utils/to-require-context.ts b/lib/core-common/src/utils/to-require-context.ts index 69fd7a57cb6..cd89f422efd 100644 --- a/lib/core-common/src/utils/to-require-context.ts +++ b/lib/core-common/src/utils/to-require-context.ts @@ -50,7 +50,7 @@ export const toRequireContext = (input: any) => { const match = ['^\\.', glob.startsWith('**') ? '' : '\\/', source.substring(1)].join(''); const recursive = glob.includes('**') || glob.split('/').length > 1; - return { path: base, recursive, match }; + return { path: base, recursive, match, regex }; } throw new Error(`Invalid glob: >> ${input} >> ${regex}`); diff --git a/yarn.lock b/yarn.lock index 28e0cae5d93..3cef6f5a875 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7991,7 +7991,6 @@ __metadata: "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 - "@types/glob-base": ^0.3.0 "@types/interpret": ^1.1.1 "@types/micromatch": ^4.0.1 "@types/mock-fs": ^4.13.0 @@ -8008,7 +8007,6 @@ __metadata: fork-ts-checker-webpack-plugin: ^6.0.4 fs-extra: ^9.0.1 glob: ^7.1.6 - glob-base: ^0.3.0 handlebars: ^4.7.7 interpret: ^2.2.0 json5: ^2.1.3 @@ -9924,13 +9922,6 @@ __metadata: languageName: node linkType: hard -"@types/glob-base@npm:^0.3.0": - version: 0.3.0 - resolution: "@types/glob-base@npm:0.3.0" - checksum: 2c0cb3b7bb7c8661b9421194c0fd90a36e1c786a4124375749df9dc1dd8ade536c8eb2ac93b217db24ed3a427755def9a54bc86c2b6bf64a81fb82e7e6f44cc7 - languageName: node - linkType: hard - "@types/glob@npm:*, @types/glob@npm:^7.1.1, @types/glob@npm:^7.1.3": version: 7.1.3 resolution: "@types/glob@npm:7.1.3" @@ -24229,25 +24220,6 @@ fsevents@^1.2.7: languageName: node linkType: hard -"glob-base@npm:^0.3.0": - version: 0.3.0 - resolution: "glob-base@npm:0.3.0" - dependencies: - glob-parent: ^2.0.0 - is-glob: ^2.0.0 - checksum: 4ce785c1dac2ff1e4660c010fa43ed2f1b38993dfd004023a3e7080b20bc61f29fbfe5d265b7e64cc84096ecf44e8ca876c7c1aad8f1f995d4c0f33034f3ae8c - languageName: node - linkType: hard - -"glob-parent@npm:^2.0.0": - version: 2.0.0 - resolution: "glob-parent@npm:2.0.0" - dependencies: - is-glob: ^2.0.0 - checksum: b9d59dc532d47aaaa4841046ff631b325a707f738445300b83b7a1ee603dd060c041a378e8a195c887d479bb703685cee4725c8f54b8dacef65355375f57d32a - languageName: node - linkType: hard - "glob-parent@npm:^3.1.0": version: 3.1.0 resolution: "glob-parent@npm:3.1.0" @@ -26721,13 +26693,6 @@ fsevents@^1.2.7: languageName: node linkType: hard -"is-extglob@npm:^1.0.0": - version: 1.0.0 - resolution: "is-extglob@npm:1.0.0" - checksum: 1ce5366d19958f36069a45ca996c1e51ab607f42a01eb0505f0ccffe8f9c91f5bcba6e971605efd8b4d4dfd0111afa3c8df3e1746db5b85b9a8f933f5e7286b7 - languageName: node - linkType: hard - "is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -26786,15 +26751,6 @@ fsevents@^1.2.7: languageName: node linkType: hard -"is-glob@npm:^2.0.0": - version: 2.0.1 - resolution: "is-glob@npm:2.0.1" - dependencies: - is-extglob: ^1.0.0 - checksum: ef156806af0924983325c9218a8b8a838fa50e1a104ed2a11fe94829a5b27c1b05a4c8cf98d96cb3a7fea539c21f14ae2081e1a248f3d5a9eea62f2d4e9f8b0c - languageName: node - linkType: hard - "is-glob@npm:^3.0.0, is-glob@npm:^3.1.0": version: 3.1.0 resolution: "is-glob@npm:3.1.0" From 58817dec0018832de057297d435d8013173b68b1 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 16:30:09 +1000 Subject: [PATCH 260/285] Fix problem with `prepareForInline` --- addons/docs/src/blocks/Story.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 46e98913497..e6f30d5200b 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -89,12 +89,14 @@ export const getStoryProps = ( loaded: {}, }); return { - parameters, inline: storyIsInline, id: story.id, - storyFn: prepareForInline ? () => prepareForInline(boundStoryFn, story) : boundStoryFn, height: height || (storyIsInline ? undefined : iframeHeight), title: storyName, + ...(storyIsInline && { + parameters, + storyFn: () => prepareForInline(boundStoryFn, story), + }), }; }; From 58db776769bdc0ebfee8c7e1bdf02a25abef9de7 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 16:30:51 +1000 Subject: [PATCH 261/285] Update CSF to get rid of play context --- addons/a11y/package.json | 2 +- addons/actions/package.json | 2 +- addons/backgrounds/package.json | 2 +- addons/controls/package.json | 2 +- addons/docs/package.json | 2 +- addons/links/package.json | 2 +- addons/measure/package.json | 2 +- addons/outline/package.json | 2 +- .../storyshots/storyshots-core/package.json | 2 +- .../storyshots-puppeteer/package.json | 4 +- app/angular/package.json | 2 +- app/html/package.json | 2 +- app/preact/package.json | 2 +- app/react/package.json | 2 +- app/server/package.json | 2 +- app/svelte/package.json | 2 +- app/vue/package.json | 2 +- app/vue3/package.json | 2 +- app/web-components/package.json | 2 +- lib/addons/package.json | 2 +- lib/api/package.json | 2 +- lib/client-api/package.json | 2 +- lib/codemod/package.json | 2 +- lib/components/package.json | 2 +- lib/core-client/package.json | 2 +- lib/csf-tools/package.json | 2 +- lib/preview-web/package.json | 2 +- lib/source-loader/package.json | 2 +- lib/store/package.json | 2 +- yarn.lock | 66 +++++++++---------- 30 files changed, 63 insertions(+), 63 deletions(-) diff --git a/addons/a11y/package.json b/addons/a11y/package.json index 5420031fd56..6c3a93806f5 100644 --- a/addons/a11y/package.json +++ b/addons/a11y/package.json @@ -51,7 +51,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/theming": "6.4.0-alpha.34", "axe-core": "^4.2.0", "core-js": "^3.8.2", diff --git a/addons/actions/package.json b/addons/actions/package.json index 551d6de0448..8809f83d020 100644 --- a/addons/actions/package.json +++ b/addons/actions/package.json @@ -45,7 +45,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", diff --git a/addons/backgrounds/package.json b/addons/backgrounds/package.json index 7eb222e70e1..211891495e0 100644 --- a/addons/backgrounds/package.json +++ b/addons/backgrounds/package.json @@ -50,7 +50,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/addons/controls/package.json b/addons/controls/package.json index b7521193696..f8bc4929a25 100644 --- a/addons/controls/package.json +++ b/addons/controls/package.json @@ -49,7 +49,7 @@ "@storybook/api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", diff --git a/addons/docs/package.json b/addons/docs/package.json index c37cff2d03d..dd459de0b73 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -71,7 +71,7 @@ "@storybook/components": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/postinstall": "6.4.0-alpha.34", diff --git a/addons/links/package.json b/addons/links/package.json index 94be34d79e5..430baa1b1ed 100644 --- a/addons/links/package.json +++ b/addons/links/package.json @@ -44,7 +44,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/router": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "core-js": "^3.8.2", diff --git a/addons/measure/package.json b/addons/measure/package.json index cd6912bee98..9ebbbd699b9 100644 --- a/addons/measure/package.json +++ b/addons/measure/package.json @@ -49,7 +49,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "core-js": "^3.8.2", "global": "^4.4.0" }, diff --git a/addons/outline/package.json b/addons/outline/package.json index 45c71c2474d..eb591752d0c 100644 --- a/addons/outline/package.json +++ b/addons/outline/package.json @@ -52,7 +52,7 @@ "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/components": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7", diff --git a/addons/storyshots/storyshots-core/package.json b/addons/storyshots/storyshots-core/package.json index 0f02d85e89d..bec0956e981 100644 --- a/addons/storyshots/storyshots-core/package.json +++ b/addons/storyshots/storyshots-core/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-client": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@types/glob": "^7.1.3", "@types/jest": "^26.0.16", "@types/jest-specific-snapshot": "^0.5.3", diff --git a/addons/storyshots/storyshots-puppeteer/package.json b/addons/storyshots/storyshots-puppeteer/package.json index 363acbd8a9b..d6b25fad168 100644 --- a/addons/storyshots/storyshots-puppeteer/package.json +++ b/addons/storyshots/storyshots-puppeteer/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/node-logger": "6.4.0-alpha.34", "@types/jest-image-snapshot": "^4.1.3", "core-js": "^3.8.2", @@ -49,7 +49,7 @@ "regenerator-runtime": "^0.13.7" }, "devDependencies": { - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@types/puppeteer": "^5.4.0" }, "peerDependencies": { diff --git a/app/angular/package.json b/app/angular/package.json index 90c5de1964f..1f1c829037f 100644 --- a/app/angular/package.json +++ b/app/angular/package.json @@ -50,7 +50,7 @@ "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/html/package.json b/app/html/package.json index 1dc271b994e..2d5d8e335fd 100644 --- a/app/html/package.json +++ b/app/html/package.json @@ -49,7 +49,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/app/preact/package.json b/app/preact/package.json index 4788e881d11..361f32676e5 100644 --- a/app/preact/package.json +++ b/app/preact/package.json @@ -49,7 +49,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/react/package.json b/app/react/package.json index 8caaddc8f5b..2a108a8e77f 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -52,7 +52,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", diff --git a/app/server/package.json b/app/server/package.json index adb0fef3ee0..022b4110873 100644 --- a/app/server/package.json +++ b/app/server/package.json @@ -50,7 +50,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/node-logger": "6.4.0-alpha.34", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", diff --git a/app/svelte/package.json b/app/svelte/package.json index 29a58ccc5d2..c004de2802e 100644 --- a/app/svelte/package.json +++ b/app/svelte/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/store": "6.4.0-alpha.34", "core-js": "^3.8.2", "global": "^4.4.0", diff --git a/app/vue/package.json b/app/vue/package.json index 2ca4f109426..72cfae7dc9a 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/vue3/package.json b/app/vue3/package.json index 73084ffb980..5ad2584dbd7 100644 --- a/app/vue3/package.json +++ b/app/vue3/package.json @@ -48,7 +48,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", "core-js": "^3.8.2", diff --git a/app/web-components/package.json b/app/web-components/package.json index 74da6051b6c..516810bbe3c 100644 --- a/app/web-components/package.json +++ b/app/web-components/package.json @@ -54,7 +54,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/core": "6.4.0-alpha.34", "@storybook/core-common": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@types/webpack-env": "^1.16.0", diff --git a/lib/addons/package.json b/lib/addons/package.json index 0a50417f38c..be2bc0d2c45 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -44,7 +44,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/theming": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/api/package.json b/lib/api/package.json index 49075c92c65..83631f05a9a 100644 --- a/lib/api/package.json +++ b/lib/api/package.json @@ -42,7 +42,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/router": "6.4.0-alpha.34", "@storybook/semver": "^7.3.2", "@storybook/theming": "6.4.0-alpha.34", diff --git a/lib/client-api/package.json b/lib/client-api/package.json index cfd58eb971b..d71a44f0590 100644 --- a/lib/client-api/package.json +++ b/lib/client-api/package.json @@ -45,7 +45,7 @@ "@storybook/channels": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/store": "6.4.0-alpha.34", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", diff --git a/lib/codemod/package.json b/lib/codemod/package.json index 46fbcb5f69e..6b86066e0a9 100644 --- a/lib/codemod/package.json +++ b/lib/codemod/package.json @@ -43,7 +43,7 @@ "dependencies": { "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/csf-tools": "6.4.0-alpha.34", "@storybook/node-logger": "6.4.0-alpha.34", "core-js": "^3.8.2", diff --git a/lib/components/package.json b/lib/components/package.json index ebe563d619f..1f0a78d8041 100644 --- a/lib/components/package.json +++ b/lib/components/package.json @@ -42,7 +42,7 @@ "dependencies": { "@popperjs/core": "^2.6.0", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/theming": "6.4.0-alpha.34", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", diff --git a/lib/core-client/package.json b/lib/core-client/package.json index caed3178a5e..3f419419db6 100644 --- a/lib/core-client/package.json +++ b/lib/core-client/package.json @@ -45,7 +45,7 @@ "@storybook/client-api": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/preview-web": "6.4.0-alpha.34", "@storybook/store": "6.4.0-alpha.34", "@storybook/ui": "6.4.0-alpha.34", diff --git a/lib/csf-tools/package.json b/lib/csf-tools/package.json index 29b91a303b1..610b976ba7d 100644 --- a/lib/csf-tools/package.json +++ b/lib/csf-tools/package.json @@ -48,7 +48,7 @@ "@babel/traverse": "^7.12.11", "@babel/types": "^7.12.11", "@mdx-js/mdx": "^1.6.22", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "core-js": "^3.8.2", "fs-extra": "^9.0.1", "global": "^4.4.0", diff --git a/lib/preview-web/package.json b/lib/preview-web/package.json index e344a41ce92..d2f1039bcc7 100644 --- a/lib/preview-web/package.json +++ b/lib/preview-web/package.json @@ -44,7 +44,7 @@ "@storybook/channel-postmessage": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "@storybook/store": "6.4.0-alpha.34", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", diff --git a/lib/source-loader/package.json b/lib/source-loader/package.json index 465a68baa27..a10773ce553 100644 --- a/lib/source-loader/package.json +++ b/lib/source-loader/package.json @@ -43,7 +43,7 @@ "dependencies": { "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "core-js": "^3.8.2", "estraverse": "^5.2.0", "global": "^4.4.0", diff --git a/lib/store/package.json b/lib/store/package.json index 43910e6d127..344e1b4c5d0 100644 --- a/lib/store/package.json +++ b/lib/store/package.json @@ -43,7 +43,7 @@ "@storybook/addons": "6.4.0-alpha.34", "@storybook/client-logger": "6.4.0-alpha.34", "@storybook/core-events": "6.4.0-alpha.34", - "@storybook/csf": "0.0.2--canary.062665d.0", + "@storybook/csf": "0.0.2--canary.68887a1.0", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", diff --git a/yarn.lock b/yarn.lock index bdcd4bb8d75..c07a0a559f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6834,7 +6834,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/theming": 6.4.0-alpha.34 "@testing-library/react": ^11.2.2 "@types/webpack-env": ^1.16.0 @@ -6865,7 +6865,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/theming": 6.4.0-alpha.34 "@types/lodash": ^4.14.167 "@types/webpack-env": ^1.16.0 @@ -6900,7 +6900,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/theming": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -6928,7 +6928,7 @@ __metadata: "@storybook/api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 @@ -6971,7 +6971,7 @@ __metadata: "@storybook/components": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/html": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 @@ -7175,7 +7175,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/router": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7205,7 +7205,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7229,7 +7229,7 @@ __metadata: "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/components": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 global: ^4.4.0 @@ -7264,7 +7264,7 @@ __metadata: resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots/storyshots-puppeteer" dependencies: "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/node-logger": 6.4.0-alpha.34 "@types/jest-image-snapshot": ^4.1.3 "@types/puppeteer": ^5.4.0 @@ -7294,7 +7294,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-client": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/react": 6.4.0-alpha.34 "@storybook/vue": 6.4.0-alpha.34 "@storybook/vue3": 6.4.0-alpha.34 @@ -7457,7 +7457,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/theming": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7490,7 +7490,7 @@ __metadata: "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/autoprefixer": ^9.7.2 @@ -7559,7 +7559,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/router": 6.4.0-alpha.34 "@storybook/semver": ^7.3.2 "@storybook/theming": 6.4.0-alpha.34 @@ -7843,7 +7843,7 @@ __metadata: "@storybook/channels": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/store": 6.4.0-alpha.34 "@types/qs": ^6.9.5 "@types/webpack-env": ^1.16.0 @@ -7879,7 +7879,7 @@ __metadata: dependencies: "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/csf-tools": 6.4.0-alpha.34 "@storybook/node-logger": 6.4.0-alpha.34 core-js: ^3.8.2 @@ -7901,7 +7901,7 @@ __metadata: dependencies: "@popperjs/core": ^2.6.0 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/theming": 6.4.0-alpha.34 "@types/color-convert": ^2.0.0 "@types/overlayscrollbars": ^1.12.0 @@ -7940,7 +7940,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@storybook/ui": 6.4.0-alpha.34 @@ -8127,7 +8127,7 @@ __metadata: "@babel/traverse": ^7.12.11 "@babel/types": ^7.12.11 "@mdx-js/mdx": ^1.6.22 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@types/fs-extra": ^9.0.6 core-js: ^3.8.2 fs-extra: ^9.0.1 @@ -8141,12 +8141,12 @@ __metadata: languageName: unknown linkType: soft -"@storybook/csf@npm:0.0.2--canary.062665d.0": - version: 0.0.2--canary.062665d.0 - resolution: "@storybook/csf@npm:0.0.2--canary.062665d.0" +"@storybook/csf@npm:0.0.2--canary.68887a1.0": + version: 0.0.2--canary.68887a1.0 + resolution: "@storybook/csf@npm:0.0.2--canary.68887a1.0" dependencies: lodash: ^4.17.15 - checksum: 5a7e8d06d640c60d0a162061b8d4f1b3d1a55d80499914eb026c92f42725a04b5ddcfe8d2d33067cb37f16e4b4e390a4f8fb8e199be63aac9c3cc03c223cec2a + checksum: 3235b52cd246a319b099e0e1022f0acd3ba3b402d4e0baf27b4c842980677fd49eb13cace3228392ca43156d4c704caee6bb554718bcadc0a45131bae9469b66 languageName: node linkType: hard @@ -8274,7 +8274,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 @@ -8489,7 +8489,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -8549,7 +8549,7 @@ __metadata: "@storybook/channel-postmessage": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/store": 6.4.0-alpha.34 ansi-to-html: ^0.6.11 core-js: ^3.8.2 @@ -8595,7 +8595,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.253f8c1.0 "@storybook/semver": ^7.3.2 @@ -8894,7 +8894,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/node-logger": 6.4.0-alpha.34 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 @@ -8923,7 +8923,7 @@ __metadata: dependencies: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 core-js: ^3.8.2 estraverse: ^5.2.0 global: ^4.4.0 @@ -8944,7 +8944,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/client-logger": 6.4.0-alpha.34 "@storybook/core-events": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 core-js: ^3.8.2 fast-deep-equal: ^3.1.3 global: ^4.4.0 @@ -8963,7 +8963,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 core-js: ^3.8.2 @@ -9062,7 +9062,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9099,7 +9099,7 @@ __metadata: "@storybook/addons": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/store": 6.4.0-alpha.34 "@types/node": ^14.14.20 "@types/webpack-env": ^1.16.0 @@ -9142,7 +9142,7 @@ __metadata: "@storybook/client-api": 6.4.0-alpha.34 "@storybook/core": 6.4.0-alpha.34 "@storybook/core-common": 6.4.0-alpha.34 - "@storybook/csf": 0.0.2--canary.062665d.0 + "@storybook/csf": 0.0.2--canary.68887a1.0 "@storybook/preview-web": 6.4.0-alpha.34 "@storybook/store": 6.4.0-alpha.34 "@types/webpack-env": ^1.16.0 From a1e1ec62451cad357e9bdc751c30acc998864367 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Mon, 13 Sep 2021 14:53:10 +0800 Subject: [PATCH 262/285] Fix docs rendering --- addons/docs/src/blocks/Story.tsx | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index e6f30d5200b..caf0de45683 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -105,26 +105,22 @@ const Story: FunctionComponent = (props) => { const ref = useRef(); const story = useStory(getStoryId(props, context), context); - if (!story) { - return
Loading...
; - } - - const { componentId, id, title, name } = story; - const renderContext = { - componentId, - title, - kind: title, - id, - name, - story: name, - // TODO what to do when these fail? - showMain: () => {}, - showError: () => {}, - showException: () => {}, - }; useEffect(() => { let cleanup: () => void; if (story && ref.current) { + const { componentId, id, title, name } = story; + const renderContext = { + componentId, + title, + kind: title, + id, + name, + story: name, + // TODO what to do when these fail? + showMain: () => {}, + showError: () => {}, + showException: () => {}, + }; cleanup = context.renderStoryToElement({ story, renderContext, @@ -134,6 +130,10 @@ const Story: FunctionComponent = (props) => { return () => cleanup && cleanup(); }, [story]); + if (!story) { + return
Loading...
; + } + if (global?.FEATURES.modernInlineRender) { // We do this so React doesn't complain when we replace the span in a secondary render const htmlContents = `loading story...`; From dcdf150b88c4b00531a366a895b960ec130d8105 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 17:03:21 +1000 Subject: [PATCH 263/285] Update store/preview to take project annotations on init. This way they can be set on `window` at boot time. --- .../virtualModuleModernEntry.js.handlebars | 4 +- .../virtualModuleModernEntry.js.handlebars | 5 +- lib/core-client/src/preview/start.ts | 30 +- .../src/PreviewWeb.integration.test.ts | 10 +- lib/preview-web/src/PreviewWeb.test.ts | 313 +++++++++--------- lib/preview-web/src/PreviewWeb.tsx | 45 +-- lib/store/src/GlobalsStore.test.ts | 24 +- lib/store/src/GlobalsStore.ts | 2 +- lib/store/src/StoryStore.test.ts | 55 ++- lib/store/src/StoryStore.ts | 26 +- 10 files changed, 264 insertions(+), 250 deletions(-) diff --git a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars index d10128be22b..0e7ff5e0500 100644 --- a/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars @@ -22,14 +22,14 @@ const fetchStoryIndex = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoryIndex }); +const preview = new PreviewWeb({ importFn, fetchStoryIndex }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; window.__STORYBOOK_ADDONS_CHANNEL__ = channel; window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore }); -preview.initialize(); +preview.initialize({ getProjectAnnotations }); if (module.hot) { module.hot.accept('./{{storiesFilename}}', () => { diff --git a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars index 7c4d3ab6d5a..0e7ff5e0500 100644 --- a/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars +++ b/lib/builder-webpack5/src/preview/virtualModuleModernEntry.js.handlebars @@ -7,7 +7,6 @@ import createChannel from '@storybook/channel-postmessage'; import { importFn } from './{{storiesFilename}}'; - const getProjectAnnotations = () => composeConfigs([ {{#each configs}} @@ -23,14 +22,14 @@ const fetchStoryIndex = async () => { const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); -const preview = new PreviewWeb({ importFn, getProjectAnnotations, fetchStoryIndex }); +const preview = new PreviewWeb({ importFn, fetchStoryIndex }); window.__STORYBOOK_PREVIEW__ = preview; window.__STORYBOOK_STORY_STORE__ = preview.storyStore; window.__STORYBOOK_ADDONS_CHANNEL__ = channel; window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore }); -preview.initialize(); +preview.initialize({ getProjectAnnotations }); if (module.hot) { module.hot.accept('./{{storiesFilename}}', () => { diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index ec47f0e5b7a..bb1ded1962d 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -25,12 +25,22 @@ export function start( const channel = createChannel({ page: 'preview' }); addons.setChannel(channel); - let preview: PreviewWeb; const clientApi = new ClientApi(); + const preview = new PreviewWeb({ + importFn: (path: Path) => clientApi.importFn(path), + fetchStoryIndex: () => clientApi.fetchStoryIndex(), + }); + // These two bits are a bit ugly, but due to dependencies, `ClientApi` cannot have + // direct reference to `PreviewWeb`, so we need to patch in bits + clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); + clientApi.storyStore = preview.storyStore; if (globalWindow) { globalWindow.__STORYBOOK_CLIENT_API__ = clientApi; globalWindow.__STORYBOOK_ADDONS_CHANNEL__ = channel; + // eslint-disable-next-line no-underscore-dangle + globalWindow.__STORYBOOK_PREVIEW__ = preview; + globalWindow.__STORYBOOK_STORY_STORE__ = preview.storyStore; } return { @@ -66,23 +76,7 @@ export function start( }; if (!preview) { - preview = new PreviewWeb({ - importFn: (path: Path) => clientApi.importFn(path), - getProjectAnnotations, - fetchStoryIndex: () => clientApi.fetchStoryIndex(), - }); - if (globalWindow) { - // eslint-disable-next-line no-underscore-dangle - globalWindow.__STORYBOOK_PREVIEW__ = preview; - globalWindow.__STORYBOOK_STORY_STORE__ = preview.storyStore; - } - - // These two bits are a bit ugly, but due to dependencies, `ClientApi` cannot have - // direct reference to `PreviewWeb`, so we need to patch in bits - clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); - clientApi.storyStore = preview.storyStore; - - preview.initialize({ cacheAllCSFFiles: true, sync: true }); + preview.initialize({ getProjectAnnotations, cacheAllCSFFiles: true, sync: true }); } else { getProjectAnnotations(); preview.onImportFnChanged({ importFn: (path: Path) => clientApi.importFn(path) }); diff --git a/lib/preview-web/src/PreviewWeb.integration.test.ts b/lib/preview-web/src/PreviewWeb.integration.test.ts index 6fd4070e48e..95b89096609 100644 --- a/lib/preview-web/src/PreviewWeb.integration.test.ts +++ b/lib/preview-web/src/PreviewWeb.integration.test.ts @@ -61,7 +61,7 @@ describe('PreviewWeb', () => { storyFn() ); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -71,7 +71,7 @@ describe('PreviewWeb', () => { it('renders docs mode through docs page', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); const docsRoot = window.document.createElement('div'); // @ts-ignore @@ -80,7 +80,7 @@ describe('PreviewWeb', () => { React.createElement('div', {}, 'INSIDE') ); - await preview.initialize(); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); expect(docsRoot.outerHTML).toMatchInlineSnapshot(` @@ -106,8 +106,8 @@ describe('PreviewWeb', () => { it('renders story mode through the updated stack', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); projectAnnotations.renderToDOM.mockImplementationOnce(({ storyFn }: RenderContext) => diff --git a/lib/preview-web/src/PreviewWeb.test.ts b/lib/preview-web/src/PreviewWeb.test.ts index 260831ffd0b..fd3f1cfcadb 100644 --- a/lib/preview-web/src/PreviewWeb.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -71,11 +71,13 @@ describe('PreviewWeb', () => { it('shows an error if getProjectAnnotations throws', async () => { const err = new Error('meta error'); const preview = new PreviewWeb({ + importFn, + fetchStoryIndex, + }); + preview.initialize({ getProjectAnnotations: () => { throw err; }, - importFn, - fetchStoryIndex, }); expect(preview.view.showErrorDisplay).toHaveBeenCalled(); @@ -87,14 +89,14 @@ describe('PreviewWeb', () => { it('sets globals from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.storyStore.globals.get()).toEqual({ a: 'c' }); }); it('emits the SET_GLOBALS event', async () => { - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'b' }, @@ -104,10 +106,9 @@ describe('PreviewWeb', () => { it('SET_GLOBALS sets globals and types even when undefined', async () => { await new PreviewWeb({ - getProjectAnnotations: () => ({}), importFn, fetchStoryIndex, - }).initialize(); + }).initialize({ getProjectAnnotations: () => ({}) }); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: {}, @@ -118,7 +119,7 @@ describe('PreviewWeb', () => { it('emits the SET_GLOBALS event from the URL', async () => { document.location.search = '?id=*&globals=a:c'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); expect(mockChannel.emit).toHaveBeenCalledWith(Events.SET_GLOBALS, { globals: { a: 'c' }, @@ -129,8 +130,8 @@ describe('PreviewWeb', () => { it('sets args from the URL', async () => { document.location.search = '?id=component-one--a&args=foo:url'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.storyStore.args.get('component-one--a')).toEqual({ foo: 'url', @@ -142,8 +143,8 @@ describe('PreviewWeb', () => { it('selects the story specified in the URL', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.urlStore.selection).toEqual({ storyId: 'component-one--a', @@ -159,7 +160,7 @@ describe('PreviewWeb', () => { it('emits the STORY_SPECIFIED event', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_SPECIFIED, { storyId: 'component-one--a', @@ -170,7 +171,7 @@ describe('PreviewWeb', () => { it('emits the CURRENT_STORY_WAS_SET event', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); expect(mockChannel.emit).toHaveBeenCalledWith(Events.CURRENT_STORY_WAS_SET, { storyId: 'component-one--a', @@ -182,8 +183,8 @@ describe('PreviewWeb', () => { it('renders missing', async () => { document.location.search = '?id=random'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.view.showNoPreview).toHaveBeenCalled(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_MISSING, 'random'); @@ -193,8 +194,8 @@ describe('PreviewWeb', () => { it.skip('tries again with a specifier if CSF file changes', async () => { document.location.search = '?id=component-one--d'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.view.showNoPreview).toHaveBeenCalled(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_MISSING, 'component-one--d'); @@ -220,8 +221,8 @@ describe('PreviewWeb', () => { it.skip('DOES NOT try again if CSF file changes if selection changed', async () => { document.location.search = '?id=component-one--d'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.view.showNoPreview).toHaveBeenCalled(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_MISSING, 'component-one--d'); @@ -250,8 +251,8 @@ describe('PreviewWeb', () => { it.skip('tries again with a specifier if stories list changes', async () => { document.location.search = '?id=component-three--d'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.view.showNoPreview).toHaveBeenCalled(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_MISSING, 'component-three--d'); @@ -265,8 +266,8 @@ describe('PreviewWeb', () => { }); it('renders missing if no selection', async () => { - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.view.showNoPreview).toHaveBeenCalled(); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_MISSING, undefined); @@ -276,8 +277,8 @@ describe('PreviewWeb', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.view.prepareForStory).toHaveBeenCalledWith( expect.objectContaining({ @@ -288,7 +289,7 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_PREPARED, { id: 'component-one--a', @@ -301,7 +302,7 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -318,7 +319,7 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -346,8 +347,8 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); @@ -362,8 +363,8 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); @@ -378,8 +379,8 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); @@ -394,8 +395,8 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); @@ -413,8 +414,8 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); @@ -424,7 +425,7 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -433,7 +434,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -445,8 +446,8 @@ describe('PreviewWeb', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); expect(preview.view.prepareForDocs).toHaveBeenCalled(); }); @@ -454,7 +455,7 @@ describe('PreviewWeb', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -477,7 +478,7 @@ describe('PreviewWeb', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -489,7 +490,7 @@ describe('PreviewWeb', () => { describe('onUpdateGlobals', () => { it('emits GLOBALS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -501,8 +502,8 @@ describe('PreviewWeb', () => { it('sets new globals on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); @@ -511,8 +512,8 @@ describe('PreviewWeb', () => { it('passes new globals in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -533,7 +534,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -547,7 +548,7 @@ describe('PreviewWeb', () => { describe('onUpdateArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -562,8 +563,8 @@ describe('PreviewWeb', () => { it('sets new args on the store', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -578,8 +579,8 @@ describe('PreviewWeb', () => { it('passes new args in context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -604,7 +605,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -623,7 +624,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -653,7 +654,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -695,7 +696,7 @@ describe('PreviewWeb', () => { updatedArgs: { new: 'arg' }, }); }); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); @@ -733,7 +734,7 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await renderToDOMCalled; // Story gets rendered with original args @@ -777,7 +778,7 @@ describe('PreviewWeb', () => { describe('onResetArgs', () => { it('emits STORY_ARGS_UPDATED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -805,7 +806,7 @@ describe('PreviewWeb', () => { it('resets a single arg', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -839,7 +840,7 @@ describe('PreviewWeb', () => { it('resets all args', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', updatedArgs: { foo: 'new', new: 'value' }, @@ -872,8 +873,8 @@ describe('PreviewWeb', () => { describe('on FORCE_RE_RENDER', () => { it('rerenders the story with the same args', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -891,7 +892,7 @@ describe('PreviewWeb', () => { describe('onSetCurrentStory', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -907,7 +908,7 @@ describe('PreviewWeb', () => { it('emits CURRENT_STORY_WAS_SET', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -922,8 +923,8 @@ describe('PreviewWeb', () => { it('renders missing if the story specified does not exist', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'random', @@ -938,8 +939,8 @@ describe('PreviewWeb', () => { describe('if the selection is unchanged', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -952,8 +953,8 @@ describe('PreviewWeb', () => { it('does NOT call renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); projectAnnotations.renderToDOM.mockClear(); @@ -971,7 +972,7 @@ describe('PreviewWeb', () => { describe('when changing story in story viewMode', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -987,7 +988,7 @@ describe('PreviewWeb', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1002,7 +1003,7 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1023,7 +1024,7 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1046,7 +1047,7 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1075,8 +1076,8 @@ describe('PreviewWeb', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); const error = new Error('error'); @@ -1097,8 +1098,8 @@ describe('PreviewWeb', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); const error = { title: 'title', description: 'description' }; @@ -1122,8 +1123,8 @@ describe('PreviewWeb', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); const error = new Error('error'); @@ -1144,7 +1145,7 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1159,7 +1160,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1174,8 +1175,8 @@ describe('PreviewWeb', () => { it('retains any arg changes', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1215,7 +1216,7 @@ describe('PreviewWeb', () => { componentOneExports.default.loaders[0].mockImplementationOnce(async () => gate); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1246,7 +1247,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; projectAnnotations.renderToDOM.mockImplementationOnce(async () => gate); - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--b', @@ -1279,7 +1280,7 @@ describe('PreviewWeb', () => { }); document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await renderToDOMCalled; // Story gets rendered with original args @@ -1328,7 +1329,7 @@ describe('PreviewWeb', () => { describe('when changing from story viewMode to docs', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1344,7 +1345,7 @@ describe('PreviewWeb', () => { it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1359,8 +1360,8 @@ describe('PreviewWeb', () => { it('calls view.prepareForDocs', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1375,7 +1376,7 @@ describe('PreviewWeb', () => { it('render the docs container with the correct context', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1403,7 +1404,7 @@ describe('PreviewWeb', () => { it('emits DOCS_RENDERED', async () => { document.location.search = '?id=component-one--a'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1420,7 +1421,7 @@ describe('PreviewWeb', () => { describe('when changing from docs viewMode to story', () => { it('updates URL', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); emitter.emit(Events.SET_CURRENT_STORY, { storyId: 'component-one--a', @@ -1436,7 +1437,7 @@ describe('PreviewWeb', () => { it('unmounts docs', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1452,7 +1453,7 @@ describe('PreviewWeb', () => { // NOTE: I am not sure this entirely makes sense but this is the behaviour from 6.3 it('emits STORY_CHANGED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1467,8 +1468,8 @@ describe('PreviewWeb', () => { it('calls view.prepareForStory', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1487,7 +1488,7 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1508,7 +1509,7 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1531,7 +1532,7 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1560,8 +1561,8 @@ describe('PreviewWeb', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); const error = new Error('error'); @@ -1587,8 +1588,8 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1612,8 +1613,8 @@ describe('PreviewWeb', () => { ); document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1629,7 +1630,7 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1644,7 +1645,7 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - await new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }).initialize(); + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1672,8 +1673,8 @@ describe('PreviewWeb', () => { it('does not emit STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1688,8 +1689,8 @@ describe('PreviewWeb', () => { it('does not emit STORY_CHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1701,8 +1702,8 @@ describe('PreviewWeb', () => { it('emits STORY_PREPARED with new annotations', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1720,8 +1721,8 @@ describe('PreviewWeb', () => { it('applies loaders with story context', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1742,8 +1743,8 @@ describe('PreviewWeb', () => { it('passes loaded context to renderToDOM', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1770,8 +1771,8 @@ describe('PreviewWeb', () => { it('retains the same delta to the args', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); emitter.emit(Events.UPDATE_STORY_ARGS, { @@ -1799,8 +1800,8 @@ describe('PreviewWeb', () => { it('renders exception if renderToDOM throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); const error = new Error('error'); @@ -1818,8 +1819,8 @@ describe('PreviewWeb', () => { it('renders error if the story calls showError', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); const error = { title: 'title', description: 'description' }; @@ -1840,8 +1841,8 @@ describe('PreviewWeb', () => { it('renders exception if the story calls showException', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); const error = new Error('error'); @@ -1859,8 +1860,8 @@ describe('PreviewWeb', () => { it('executes runPlayFunction', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1873,8 +1874,8 @@ describe('PreviewWeb', () => { it('emits STORY_RENDERED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1895,8 +1896,8 @@ describe('PreviewWeb', () => { it('emits STORY_UNCHANGED', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1909,8 +1910,8 @@ describe('PreviewWeb', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1936,8 +1937,8 @@ describe('PreviewWeb', () => { it('renders story missing', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1950,8 +1951,8 @@ describe('PreviewWeb', () => { it('does not re-render the story', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1971,8 +1972,8 @@ describe('PreviewWeb', () => { describe('onGetProjectAnnotationsChanged', () => { it('shows an error the new value throws', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -1999,8 +2000,8 @@ describe('PreviewWeb', () => { it('updates globals to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -2012,8 +2013,8 @@ describe('PreviewWeb', () => { it('updates args to their new values', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); mockChannel.emit.mockClear(); @@ -2029,8 +2030,8 @@ describe('PreviewWeb', () => { it('rerenders the current story with new global meta-generated context', async () => { document.location.search = '?id=component-one--a'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); await waitForRender(); projectAnnotations.renderToDOM.mockClear(); @@ -2053,8 +2054,8 @@ describe('PreviewWeb', () => { describe('onKeydown', () => { it('emits PREVIEW_KEYDOWN for regular elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); preview.onKeydown({ target: { tagName: 'div', getAttribute: jest.fn().mockReturnValue(null) }, @@ -2068,8 +2069,8 @@ describe('PreviewWeb', () => { it('does not emit PREVIEW_KEYDOWN for input elements', async () => { document.location.search = '?id=component-one--a&viewMode=docs'; - const preview = new PreviewWeb({ getProjectAnnotations, importFn, fetchStoryIndex }); - await preview.initialize(); + const preview = new PreviewWeb({ importFn, fetchStoryIndex }); + await preview.initialize({ getProjectAnnotations }); preview.onKeydown({ target: { tagName: 'input', getAttribute: jest.fn().mockReturnValue(null) }, diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index d0d2da0725c..3ee46de52fe 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -57,21 +57,41 @@ export class PreviewWeb { previousCleanup: () => void; constructor({ - getProjectAnnotations, importFn, fetchStoryIndex, }: { - getProjectAnnotations: () => WebProjectAnnotations; importFn: ModuleImportFn; fetchStoryIndex: ConstructorParameters[0]['fetchStoryIndex']; }) { this.channel = addons.getChannel(); this.view = new WebView(); + this.urlStore = new UrlStore(); + this.storyStore = new StoryStore({ importFn, fetchStoryIndex }); + } + + // We have a second "sync" code path through `initialize` for back-compat reasons. + // Specifically Storyshots requires the story store to be syncronously loaded completely on bootup + initialize({ + getProjectAnnotations, + cacheAllCSFFiles = false, + sync = false, + }: { + getProjectAnnotations: () => WebProjectAnnotations; + cacheAllCSFFiles?: boolean; + sync?: boolean; + }): MaybePromise { const projectAnnotations = this.getProjectAnnotationsOrRenderError(getProjectAnnotations) || {}; - this.urlStore = new UrlStore(); - this.storyStore = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); + if (sync) { + this.storyStore.initialize({ projectAnnotations, cacheAllCSFFiles, sync: true }); + // NOTE: we don't await this, but return the promise so the caller can await it if they want + return this.setupListenersAndRenderSelection(); + } + + return this.storyStore + .initialize({ projectAnnotations, cacheAllCSFFiles, sync: false }) + .then(() => this.setupListenersAndRenderSelection()); } getProjectAnnotationsOrRenderError( @@ -91,23 +111,6 @@ export class PreviewWeb { } } - // We have a second "sync" code path through `initialize` for back-compat reasons. - // Specifically Storyshots requires the story store to be syncronously loaded completely on bootup - initialize({ - cacheAllCSFFiles = false, - sync = false, - }: { cacheAllCSFFiles?: boolean; sync?: boolean } = {}): MaybePromise { - if (sync) { - this.storyStore.initialize({ cacheAllCSFFiles, sync: true }); - // NOTE: we don't await this, but return the promise so the caller can await it if they want - return this.setupListenersAndRenderSelection(); - } - - return this.storyStore - .initialize({ cacheAllCSFFiles, sync: false }) - .then(() => this.setupListenersAndRenderSelection()); - } - async setupListenersAndRenderSelection() { this.setupListeners(); diff --git a/lib/store/src/GlobalsStore.test.ts b/lib/store/src/GlobalsStore.test.ts index 422d830c4b5..df778581d1d 100644 --- a/lib/store/src/GlobalsStore.test.ts +++ b/lib/store/src/GlobalsStore.test.ts @@ -2,7 +2,8 @@ import { GlobalsStore } from './GlobalsStore'; describe('GlobalsStore', () => { it('is initialized to the value in globals', () => { - const store = new GlobalsStore({ + const store = new GlobalsStore(); + store.initialize({ globals: { arg1: 'arg1', arg2: 2, @@ -19,7 +20,8 @@ describe('GlobalsStore', () => { }); it('is initialized to the default values from globalTypes if global is unset', () => { - const store = new GlobalsStore({ + const store = new GlobalsStore(); + store.initialize({ globals: { arg1: 'arg1', arg2: 2, @@ -40,7 +42,8 @@ describe('GlobalsStore', () => { describe('update', () => { it('changes the global args', () => { - const store = new GlobalsStore({ globals: { foo: 'old' }, globalTypes: { baz: {} } }); + const store = new GlobalsStore(); + store.initialize({ globals: { foo: 'old' }, globalTypes: { baz: {} } }); store.update({ foo: 'bar' }); expect(store.get()).toEqual({ foo: 'bar' }); @@ -54,7 +57,8 @@ describe('GlobalsStore', () => { }); it('does not merge objects', () => { - const store = new GlobalsStore({ globals: {}, globalTypes: {} }); + const store = new GlobalsStore(); + store.initialize({ globals: {}, globalTypes: {} }); store.update({ obj: { foo: 'bar' } }); expect(store.get()).toEqual({ obj: { foo: 'bar' } }); @@ -66,7 +70,8 @@ describe('GlobalsStore', () => { describe('updateFromPersisted', () => { it('only sets values for which globals or globalArgs exist', () => { - const store = new GlobalsStore({ + const store = new GlobalsStore(); + store.initialize({ globals: { arg1: 'arg1', }, @@ -87,7 +92,8 @@ describe('GlobalsStore', () => { describe('resetOnProjectAnnotationsChange', () => { it('is initialized to the (new) default values from globalTypes if the (new) global is unset', () => { - const store = new GlobalsStore({ globals: {}, globalTypes: {} }); + const store = new GlobalsStore(); + store.initialize({ globals: {}, globalTypes: {} }); expect(store.get()).toEqual({}); @@ -112,7 +118,8 @@ describe('GlobalsStore', () => { describe('when underlying globals have not changed', () => { it('retains updated values, but not if they are undeclared', () => { - const store = new GlobalsStore({ + const store = new GlobalsStore(); + store.initialize({ globals: { arg1: 'arg1', }, @@ -145,7 +152,8 @@ describe('GlobalsStore', () => { describe('when underlying globals have changed', () => { it('retains a the same delta', () => { - const store = new GlobalsStore({ + const store = new GlobalsStore(); + store.initialize({ globals: { arg1: 'arg1', arg4: 'arg4', diff --git a/lib/store/src/GlobalsStore.ts b/lib/store/src/GlobalsStore.ts index 181780edce6..18db1c0f17e 100644 --- a/lib/store/src/GlobalsStore.ts +++ b/lib/store/src/GlobalsStore.ts @@ -21,7 +21,7 @@ export class GlobalsStore { // NOTE: globals are initialized every time the preview entries are loaded // This happens both initially when the SB first loads, and also on HMR - constructor({ globals, globalTypes }: { globals: Globals; globalTypes: GlobalTypes }) { + initialize({ globals, globalTypes }: { globals: Globals; globalTypes: GlobalTypes }) { this.setInitialGlobals({ globals, globalTypes }); this.globals = this.initialGlobals; } diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index 0d47cef38c3..a13398242ee 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -67,8 +67,8 @@ const fetchStoryIndex = async () => storyIndex; describe('StoryStore', () => { describe('projectAnnotations', () => { it('normalizes on initialization', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); expect(store.projectAnnotations.globalTypes).toEqual({ a: { name: 'a', type: { name: 'string' } }, @@ -79,8 +79,8 @@ describe('StoryStore', () => { }); it('normalizes on updateGlobalAnnotations', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); store.updateProjectAnnotations(projectAnnotations); expect(store.projectAnnotations.globalTypes).toEqual({ @@ -94,8 +94,8 @@ describe('StoryStore', () => { describe('loadStory', () => { it('pulls the story via the importFn', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); importFn.mockClear(); expect(await store.loadStory({ storyId: 'component-one--a' })).toMatchObject({ @@ -108,8 +108,8 @@ describe('StoryStore', () => { }); it('uses a cache', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); expect(processCSFFile).toHaveBeenCalledTimes(1); @@ -132,8 +132,8 @@ describe('StoryStore', () => { describe('componentStoriesFromCSFFile', () => { it('returns all the stories in the file', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); const csfFile = await store.loadCSFFileByStoryId('component-one--a', { sync: false }); const stories = store.componentStoriesFromCSFFile({ csfFile }); @@ -145,8 +145,8 @@ describe('StoryStore', () => { describe('getStoryContext', () => { it('returns the args and globals correctly', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -157,8 +157,8 @@ describe('StoryStore', () => { }); it('returns the args and globals correctly when they change', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -172,8 +172,8 @@ describe('StoryStore', () => { }); it('returns the same hooks each time', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -184,8 +184,8 @@ describe('StoryStore', () => { describe('cleanupStory', () => { it('cleans the hooks from the context', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); const story = await store.loadStory({ storyId: 'component-one--a' }); @@ -198,8 +198,8 @@ describe('StoryStore', () => { describe('loadAllCSFFiles', () => { it('imports *all* csf files', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); importFn.mockClear(); const csfFiles = await store.loadAllCSFFiles(false); @@ -213,15 +213,15 @@ describe('StoryStore', () => { describe('extract', () => { it('throws if you have not called cacheAllCSFFiles', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); expect(() => store.extract()).toThrow(/Cannot call extract/); }); it('produces objects with functions and hooks stripped', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); await store.cacheAllCSFFiles(false); expect(store.extract()).toMatchInlineSnapshot(` @@ -340,10 +340,9 @@ describe('StoryStore', () => { }); const store = new StoryStore({ importFn: docsOnlyImportFn, - projectAnnotations, fetchStoryIndex, }); - await store.initialize({ sync: false }); + await store.initialize({ projectAnnotations, sync: false }); await store.cacheAllCSFFiles(false); expect((store.extract() as { id: StoryId }[]).map((s) => s.id)).toEqual([ @@ -359,8 +358,8 @@ describe('StoryStore', () => { describe('getSetStoriesPayload', () => { it('maps stories list to payload correctly', async () => { - const store = new StoryStore({ importFn, projectAnnotations, fetchStoryIndex }); - await store.initialize({ sync: false }); + const store = new StoryStore({ importFn, fetchStoryIndex }); + await store.initialize({ projectAnnotations, sync: false }); await store.cacheAllCSFFiles(false); expect(store.getSetStoriesPayload()).toMatchInlineSnapshot(` diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index c2040498d27..fb92670e336 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -80,19 +80,15 @@ export class StoryStore { constructor({ importFn, - projectAnnotations, fetchStoryIndex, }: { importFn: ModuleImportFn; - projectAnnotations: ProjectAnnotations; fetchStoryIndex: ConstructorParameters[0]['fetchStoryIndex']; }) { this.storyIndex = new StoryIndexStore({ fetchStoryIndex }); this.importFn = importFn; - this.projectAnnotations = normalizeProjectAnnotations(projectAnnotations); - const { globals, globalTypes } = projectAnnotations; - this.globals = new GlobalsStore({ globals, globalTypes }); + this.globals = new GlobalsStore(); this.args = new ArgsStore(); this.hooks = {}; @@ -104,17 +100,31 @@ export class StoryStore { } // See note in PreviewWeb about the 'sync' init path. - initialize(options: { sync: false; cacheAllCSFFiles?: boolean }): Promise; + initialize(options: { + projectAnnotations: ProjectAnnotations; + sync: false; + cacheAllCSFFiles?: boolean; + }): Promise; - initialize(options: { sync: true; cacheAllCSFFiles?: boolean }): void; + initialize(options: { + projectAnnotations: ProjectAnnotations; + sync: true; + cacheAllCSFFiles?: boolean; + }): void; initialize({ + projectAnnotations, sync = false, cacheAllCSFFiles = false, }: { + projectAnnotations: ProjectAnnotations; sync?: boolean; cacheAllCSFFiles?: boolean; - } = {}): MaybePromise { + }): MaybePromise { + this.projectAnnotations = normalizeProjectAnnotations(projectAnnotations); + const { globals, globalTypes } = this.projectAnnotations; + this.globals.initialize({ globals, globalTypes }); + if (sync) { this.storyIndex.initialize({ sync: true }); if (cacheAllCSFFiles) { From ca4108c53b1a82271d98c1bc3d448c4797943703 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 17:15:45 +1000 Subject: [PATCH 264/285] We need to track initialization now. --- lib/core-client/src/preview/start.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/core-client/src/preview/start.ts b/lib/core-client/src/preview/start.ts index bb1ded1962d..7f4854e1751 100644 --- a/lib/core-client/src/preview/start.ts +++ b/lib/core-client/src/preview/start.ts @@ -30,6 +30,7 @@ export function start( importFn: (path: Path) => clientApi.importFn(path), fetchStoryIndex: () => clientApi.fetchStoryIndex(), }); + let initialized = false; // These two bits are a bit ugly, but due to dependencies, `ClientApi` cannot have // direct reference to `PreviewWeb`, so we need to patch in bits clientApi.onImportFnChanged = preview.onImportFnChanged.bind(preview); @@ -75,8 +76,9 @@ export function start( }; }; - if (!preview) { + if (!initialized) { preview.initialize({ getProjectAnnotations, cacheAllCSFFiles: true, sync: true }); + initialized = true; } else { getProjectAnnotations(); preview.onImportFnChanged({ importFn: (path: Path) => clientApi.importFn(path) }); From 2c624344434553b48319112930631c6cb2b1cbbb Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Mon, 13 Sep 2021 15:20:31 +0800 Subject: [PATCH 265/285] Fix unbalanced hooks error in ArgsTable --- addons/docs/src/blocks/ArgsTable.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index 7dac7f5a972..98061ffc265 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -10,7 +10,7 @@ import { import { addons } from '@storybook/addons'; import { filterArgTypes, PropDescriptor } from '@storybook/store'; import Events from '@storybook/core-events'; -import { StrictArgTypes, Args, AnyFramework } from '@storybook/csf'; +import { StrictArgTypes, Args } from '@storybook/csf'; import { DocsContext, DocsContextProps } from './DocsContext'; import { Component, CURRENT_SELECTION, PRIMARY_STORY } from './types'; @@ -158,7 +158,11 @@ export const StoryTable: FC< storyId = lookupStoryId(storyName, context); } } + const story = useStory(storyId, context); + // eslint-disable-next-line prefer-const + let [args, updateArgs, resetArgs] = useArgs(storyId, context); + if (!story) { return
Loading...
; } @@ -167,8 +171,6 @@ export const StoryTable: FC< const mainLabel = getComponentName(component) || 'Story'; - // eslint-disable-next-line prefer-const - let [args, updateArgs, resetArgs] = useArgs(storyId, context); let tabs = { [mainLabel]: { rows: argTypes, args, updateArgs, resetArgs } } as Record< string, PureArgsTableProps From c76a8422718e2da325ac090bd4b5e7aff4a4af50 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 17:24:54 +1000 Subject: [PATCH 266/285] Update Store APIs to be backwards-compatible (Specifically to ensure the links addon works) --- lib/preview-web/src/PreviewWeb.tsx | 17 +++++++++++++++-- lib/store/src/StoryStore.ts | 8 +++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 3ee46de52fe..386d68f8629 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -1,5 +1,7 @@ import React, { ComponentType } from 'react'; import ReactDOM from 'react-dom'; +import deprecate from 'util-deprecate'; +import dedent from 'ts-dedent'; import Events from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; import global from 'global'; @@ -68,13 +70,24 @@ export class PreviewWeb { this.urlStore = new UrlStore(); this.storyStore = new StoryStore({ importFn, fetchStoryIndex }); + + // Add deprecated APIs for back-compat + // @ts-ignore + this.storyStore.getSelection = deprecate( + () => this.urlStore.selection, + dedent` + \`__STORYBOOK_STORY_STORE__.getSelection()\` is deprecated and will be removed in 7.0. + + To get the current selection, use the \`useStoryContext()\` hook from \`@storybook/addons\`. + ` + ); } - // We have a second "sync" code path through `initialize` for back-compat reasons. - // Specifically Storyshots requires the story store to be syncronously loaded completely on bootup initialize({ getProjectAnnotations, cacheAllCSFFiles = false, + // We have a second "sync" code path through `initialize` for back-compat reasons. + // Specifically Storyshots requires the story store to be syncronously loaded completely on bootup sync = false, }: { getProjectAnnotations: () => WebProjectAnnotations; diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index fb92670e336..4be14415fce 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -370,9 +370,11 @@ export class StoryStore { throw new Error('Cannot call fromId/raw() unless you call cacheAllCSFFiles() first.'); } - const { importPath } = this.storyIndex.storyIdToEntry(storyId); - if (!importPath) { - throw new Error(`Unknown storyId ${storyId}`); + let importPath; + try { + ({ importPath } = this.storyIndex.storyIdToEntry(storyId)); + } catch (err) { + return null; } const csfFile = this.cachedCSFFiles[importPath]; const story = this.storyFromCSFFile({ storyId, csfFile }); From ac1b4f5251158a0e416c16c59cb9dd48aebe3050 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Mon, 13 Sep 2021 15:34:52 +0800 Subject: [PATCH 267/285] MDX: Rename mdxComponentMeta to mdxComponentAnnotations --- lib/csf-tools/src/mdx/sb-mdx-plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/csf-tools/src/mdx/sb-mdx-plugin.ts b/lib/csf-tools/src/mdx/sb-mdx-plugin.ts index 7e4c4c34704..99c9f1c244c 100644 --- a/lib/csf-tools/src/mdx/sb-mdx-plugin.ts +++ b/lib/csf-tools/src/mdx/sb-mdx-plugin.ts @@ -339,7 +339,7 @@ const wrapperJs = ` componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), - page: () => , + page: () => , }; `.trim(); From 0ae41ca27d31d528ac8124f1fba3018220b906ce Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Mon, 13 Sep 2021 16:41:20 +0800 Subject: [PATCH 268/285] Clean up source snippet retrieval for arbitrary stories --- addons/docs/src/blocks/Source.tsx | 24 ++++++++++++------------ addons/docs/src/blocks/useStory.ts | 18 +++++++++++++++--- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/addons/docs/src/blocks/Source.tsx b/addons/docs/src/blocks/Source.tsx index 1c521af3426..e3c6da541c5 100644 --- a/addons/docs/src/blocks/Source.tsx +++ b/addons/docs/src/blocks/Source.tsx @@ -13,6 +13,7 @@ import { CURRENT_SELECTION } from './types'; import { SourceType } from '../shared'; import { enhanceSource } from './enhanceSource'; +import { useStories } from './useStory'; export enum SourceState { OPEN = 'open', @@ -46,14 +47,8 @@ const getStory = (storyId: StoryId, docsContext: DocsContextProps): Story | null return docsContext.storyById(storyId); }; -const getSourceState = (storyIds: string[], docsContext: DocsContextProps) => { - const states = storyIds - .map((storyId) => { - const story = getStory(storyId, docsContext); - return story?.parameters.docs?.source?.state; - }) - .filter(Boolean); - +const getSourceState = (stories: Story[]) => { + const states = stories.map((story) => story.parameters.docs?.source?.state).filter(Boolean); if (states.length === 0) return SourceState.CLOSED; // FIXME: handling multiple stories is a pain return states[0]; @@ -117,17 +112,22 @@ export const getSourceProps = ( singleProps.id === CURRENT_SELECTION || !singleProps.id ? currentId : singleProps.id; const targetIds = multiProps.ids || [targetId]; + const stories = useStories(targetIds, docsContext); + if (!stories) { + return { error: SourceError.SOURCE_UNAVAILABLE, state: SourceState.NONE }; + } + if (!source) { source = targetIds - .map((storyId) => { + .map((storyId, idx) => { const storySource = getStorySource(storyId, sourceContext); - const story = getStory(storyId, docsContext); - return getSnippet(storySource, story); + const storyObj = stories[idx]; + return getSnippet(storySource, storyObj); }) .join('\n\n'); } - const state = getSourceState(targetIds, docsContext); + const state = getSourceState(stories); const { docs: docsParameters = {} } = parameters; const { source: sourceParameters = {} } = docsParameters; diff --git a/addons/docs/src/blocks/useStory.ts b/addons/docs/src/blocks/useStory.ts index 6c785247fe9..6d11636eeb6 100644 --- a/addons/docs/src/blocks/useStory.ts +++ b/addons/docs/src/blocks/useStory.ts @@ -8,11 +8,23 @@ export function useStory( storyId: StoryId, context: DocsContextProps ): Story | void { - const [story, setStory] = useState(null); + const stories = useStories([storyId], context); + return stories && stories[0]; +} + +export function useStories( + storyIds: StoryId[], + context: DocsContextProps +): Story[] | void { + const [stories, setStories] = useState(null); useEffect(() => { - context.loadStory(storyId).then((s) => setStory(s)); + Promise.all(storyIds.map((storyId) => context.loadStory(storyId))).then((loadedStories) => { + if (!stories) { + setStories(loadedStories); + } + }); }); - return story; + return stories; } From 825f4350776b2df5cda0a9f58802fc37ce03fdd1 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Mon, 13 Sep 2021 16:52:06 +0800 Subject: [PATCH 269/285] Fix modern inline rendering with absolutely positioned elements --- addons/docs/src/blocks/Story.tsx | 26 ++++++++++++++----- .../addon-docs/addon-docs-mdx.stories.mdx | 8 +----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index caf0de45683..ce994e9b7ed 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -133,21 +133,35 @@ const Story: FunctionComponent = (props) => { if (!story) { return
Loading...
; } + const storyProps = getStoryProps(props, story, context); + if (!storyProps) { + return null; + } if (global?.FEATURES.modernInlineRender) { // We do this so React doesn't complain when we replace the span in a secondary render const htmlContents = `loading story...`; + + // FIXME: height/style/etc. lifted from PureStory + const { height } = storyProps; return ( -
+
+ + {height ? ( + + ) : null} +
+ +
); } - const storyProps = getStoryProps(props, story, context); - if (!storyProps) { - return null; - } return ( -
+
diff --git a/examples/official-storybook/stories/addon-docs/addon-docs-mdx.stories.mdx b/examples/official-storybook/stories/addon-docs/addon-docs-mdx.stories.mdx index f5ae3066d47..41d4261afb3 100644 --- a/examples/official-storybook/stories/addon-docs/addon-docs-mdx.stories.mdx +++ b/examples/official-storybook/stories/addon-docs/addon-docs-mdx.stories.mdx @@ -21,9 +21,7 @@ import MdxNotes from '../notes/notes.mdx'; title="Addons/Docs/mdx" component={TsButton} id="addons-docs-mdx-id" - decorators={[ - (storyFn) =>
{storyFn()}
, - ]} + decorators={[(storyFn) =>
{storyFn()}
]} parameters={{ notes: 'component notes' }} /> @@ -35,10 +33,6 @@ import MdxNotes from '../notes/notes.mdx'; - - - - ## Transclusion ### Markdown From 5bc3db4ea370973f484abf055d11643c52dd671f Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Mon, 13 Sep 2021 17:18:35 +0800 Subject: [PATCH 270/285] Fix stories.json auto-extraction for named exports --- lib/csf-tools/src/CsfFile.test.ts | 25 +++++++++++++++++++++++-- lib/csf-tools/src/CsfFile.ts | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/csf-tools/src/CsfFile.test.ts b/lib/csf-tools/src/CsfFile.test.ts index 68019daaebd..50951320b04 100644 --- a/lib/csf-tools/src/CsfFile.test.ts +++ b/lib/csf-tools/src/CsfFile.test.ts @@ -52,6 +52,27 @@ describe('CsfFile', () => { `); }); + it('underscores', async () => { + expect( + await parse( + dedent` + export default { title: 'foo/bar' }; + export const __Basic__ = () => {}; + `, + true + ) + ).toMatchInlineSnapshot(` + meta: + title: foo/bar + stories: + - id: foo-bar--basic + name: Basic + parameters: + __isArgsStory: false + __id: foo-bar--basic + `); + }); + it('exclude stories', async () => { expect( await parse( @@ -89,7 +110,7 @@ describe('CsfFile', () => { includeStories: ! /^Include.*/ stories: - id: foo-bar--include-a - name: IncludeA + name: Include A `); }); @@ -207,7 +228,7 @@ describe('CsfFile', () => { title: foo/bar stories: - id: foo-bar--page - name: __page + name: Page parameters: __isArgsStory: false __id: foo-bar--page diff --git a/lib/csf-tools/src/CsfFile.ts b/lib/csf-tools/src/CsfFile.ts index 4b8a9698b7e..ba6835a1d63 100644 --- a/lib/csf-tools/src/CsfFile.ts +++ b/lib/csf-tools/src/CsfFile.ts @@ -180,7 +180,7 @@ export class CsfFile { if (t.isVariableDeclarator(decl) && t.isIdentifier(decl.id)) { const { name: exportName } = decl.id; self._storyExports[exportName] = decl; - let name = exportName; + let name = storyNameFromExport(exportName); if (self._storyAnnotations[exportName]) { logger.warn( `Unexpected annotations for "${exportName}" before story declaration` From faf1b429c7cea31f5745f787bfaba44dfe1fe5fb Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 19:21:21 +1000 Subject: [PATCH 271/285] Retain hooks between loads of the story store. --- lib/store/src/StoryStore.test.ts | 4 ++++ lib/store/src/StoryStore.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/store/src/StoryStore.test.ts b/lib/store/src/StoryStore.test.ts index a13398242ee..429f2e4a759 100644 --- a/lib/store/src/StoryStore.test.ts +++ b/lib/store/src/StoryStore.test.ts @@ -179,6 +179,10 @@ describe('StoryStore', () => { const { hooks } = store.getStoryContext(story); expect(store.getStoryContext(story).hooks).toBe(hooks); + + // Now double check it doesn't get changed when you call `loadStory` again + const story2 = await store.loadStory({ storyId: 'component-one--a' }); + expect(store.getStoryContext(story2).hooks).toBe(hooks); }); }); diff --git a/lib/store/src/StoryStore.ts b/lib/store/src/StoryStore.ts index 4be14415fce..46b823014ce 100644 --- a/lib/store/src/StoryStore.ts +++ b/lib/store/src/StoryStore.ts @@ -267,7 +267,7 @@ export class StoryStore { this.projectAnnotations ); this.args.setInitial(story.id, story.initialArgs); - this.hooks[story.id] = new HooksContext(); + this.hooks[story.id] = this.hooks[story.id] || new HooksContext(); return story; } From ebd1f934b8fc207da16c996698fc72bc0f5bde60 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 13 Sep 2021 21:48:27 +1000 Subject: [PATCH 272/285] Ensure we don't call configure for stories if we don't have any --- lib/builder-webpack4/src/preview/iframe-webpack.config.ts | 2 +- lib/builder-webpack5/src/preview/iframe-webpack.config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts index b9f3e53846b..f47186d6091 100644 --- a/lib/builder-webpack4/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/iframe-webpack.config.ts @@ -133,7 +133,7 @@ export default async (options: Options & Record): Promise 0) { const storyTemplate = await readTemplate( path.join(__dirname, 'virtualModuleStory.template.js') ); diff --git a/lib/builder-webpack5/src/preview/iframe-webpack.config.ts b/lib/builder-webpack5/src/preview/iframe-webpack.config.ts index c3358f53f7e..40ead67f4f6 100644 --- a/lib/builder-webpack5/src/preview/iframe-webpack.config.ts +++ b/lib/builder-webpack5/src/preview/iframe-webpack.config.ts @@ -128,7 +128,7 @@ export default async (options: Options & Record): Promise 0) { const storyTemplate = await readTemplate( path.join(__dirname, 'virtualModuleStory.template.js') ); From b38539253e7f79f68c7a604bf274596b0ddbd745 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 14 Sep 2021 14:21:12 +1000 Subject: [PATCH 273/285] Hooks order fix --- addons/docs/src/blocks/ArgsTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/docs/src/blocks/ArgsTable.tsx b/addons/docs/src/blocks/ArgsTable.tsx index 7dac7f5a972..4b90d7c567b 100644 --- a/addons/docs/src/blocks/ArgsTable.tsx +++ b/addons/docs/src/blocks/ArgsTable.tsx @@ -159,6 +159,8 @@ export const StoryTable: FC< } } const story = useStory(storyId, context); + // eslint-disable-next-line prefer-const + let [args, updateArgs, resetArgs] = useArgs(storyId, context); if (!story) { return
Loading...
; } @@ -167,8 +169,6 @@ export const StoryTable: FC< const mainLabel = getComponentName(component) || 'Story'; - // eslint-disable-next-line prefer-const - let [args, updateArgs, resetArgs] = useArgs(storyId, context); let tabs = { [mainLabel]: { rows: argTypes, args, updateArgs, resetArgs } } as Record< string, PureArgsTableProps From 168e5466a5a73d22682d89a2641a1faa5e407cc1 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 12:21:57 +0800 Subject: [PATCH 274/285] Add simple docs tab e2e test --- cypress/generated/addon-docs.spec.ts | 11 +++++++++++ cypress/support/commands.js | 4 ++++ cypress/support/index.d.ts | 6 ++++++ 3 files changed, 21 insertions(+) create mode 100644 cypress/generated/addon-docs.spec.ts diff --git a/cypress/generated/addon-docs.spec.ts b/cypress/generated/addon-docs.spec.ts new file mode 100644 index 00000000000..16492600b21 --- /dev/null +++ b/cypress/generated/addon-docs.spec.ts @@ -0,0 +1,11 @@ +describe('addon-action', () => { + before(() => { + cy.visitStorybook(); + }); + + it('should have docs tab', () => { + cy.navigateToStory('example-button', 'primary'); + cy.viewAddonTab('Docs'); + cy.getDocsElement().get('.sbdocs-title').contains('Button'); + }); +}); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 78468c5de67..aab52aa129d 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -117,3 +117,7 @@ Cypress.Commands.add('navigateToStory', (kind, name) => { Cypress.Commands.add('viewAddonPanel', (name) => { cy.get(`[role=tablist] button[role=tab]`).contains(name).click(); }); + +Cypress.Commands.add('viewAddonTab', (name) => { + cy.get(`[role=main] button[type=button]`).contains(name).click(); +}); diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts index 0b1b2b22c6e..1a921997251 100644 --- a/cypress/support/index.d.ts +++ b/cypress/support/index.d.ts @@ -45,6 +45,12 @@ declare namespace Cypress { */ viewAddonPanel(name: string): Chainable; + /** + * Display main tab + * @param name of the addon + */ + viewAddonTab(name: string): Chainable; + /** * Returns the element while logging it. */ From 90706309a4dd0f1f909b4232ef322b9e17622623 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 14 Sep 2021 14:23:03 +1000 Subject: [PATCH 275/285] Wait until all sub-stories have rendered in docs We need to wait to emit DOCS_RENDERED until all the stories are rendered. --- addons/docs/src/blocks/Story.tsx | 10 ++++++++++ lib/preview-web/src/PreviewWeb.test.ts | 22 ++++++++++++++++++++++ lib/preview-web/src/PreviewWeb.tsx | 17 ++++++++++++++++- lib/preview-web/src/types.ts | 1 + 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index caf0de45683..354668dc8c3 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -6,6 +6,7 @@ import React, { useContext, useRef, useEffect, + useMemo, } from 'react'; import { MDXProvider } from '@mdx-js/react'; import { resetComponents, Story as PureStory } from '@storybook/components'; @@ -105,6 +106,15 @@ const Story: FunctionComponent = (props) => { const ref = useRef(); const story = useStory(getStoryId(props, context), context); + // Ensure we wait until this story is properly rendered in the docs context. + // The purpose of this is to ensure that that the `DOCS_RENDERED` event isn't emitted + // until all stories on the page have rendered. + const { id: storyId, registerRenderingStory } = context; + const storyRendered = useMemo(registerRenderingStory, [storyId]); + useEffect(() => { + if (story) storyRendered(); + }, [story]); + useEffect(() => { let cleanup: () => void; if (story && ref.current) { diff --git a/lib/preview-web/src/PreviewWeb.test.ts b/lib/preview-web/src/PreviewWeb.test.ts index fd3f1cfcadb..5008b67feab 100644 --- a/lib/preview-web/src/PreviewWeb.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -484,6 +484,28 @@ describe('PreviewWeb', () => { expect(mockChannel.emit).toHaveBeenCalledWith(Events.DOCS_RENDERED, 'component-one--a'); }); + + it('emits DOCS_RENDERED after all stories are rendered', async () => { + document.location.search = '?id=component-one--a&viewMode=docs'; + const [reactDomGate, openReactDomGate] = createGate(); + + let rendered; + ReactDOM.render.mockImplementationOnce((docsElement, element, cb) => { + rendered = docsElement.props.context.registerRenderingStory(); + openReactDomGate(); + cb(); + }); + + await new PreviewWeb({ importFn, fetchStoryIndex }).initialize({ getProjectAnnotations }); + + // Wait for `ReactDOM.render()` to be called. We should still be waiting for the story + await reactDomGate; + expect(mockChannel.emit).not.toHaveBeenCalledWith(Events.DOCS_RENDERED, 'component-one--a'); + + rendered(); + await waitForRender(); + expect(mockChannel.emit).toHaveBeenCalledWith(Events.DOCS_RENDERED, 'component-one--a'); + }); }); }); diff --git a/lib/preview-web/src/PreviewWeb.tsx b/lib/preview-web/src/PreviewWeb.tsx index 386d68f8629..4037f2f1abf 100644 --- a/lib/preview-web/src/PreviewWeb.tsx +++ b/lib/preview-web/src/PreviewWeb.tsx @@ -320,6 +320,7 @@ export class PreviewWeb { const csfFile: CSFFile = await this.storyStore.loadCSFFileByStoryId(id, { sync: false, }); + const renderingStoryPromises: Promise[] = []; const docsContext = { id, title, @@ -329,6 +330,17 @@ export class PreviewWeb { componentStories: () => this.storyStore.componentStoriesFromCSFFile({ csfFile }), loadStory: (storyId: StoryId) => this.storyStore.loadStory({ storyId }), renderStoryToElement: this.renderStoryToElement.bind(this), + // Keep track of the stories that are rendered by the component and don't emit + // the DOCS_RENDERED event(below) until they have all marked themselves as rendered. + registerRenderingStory: () => { + let rendered: (v: void) => void; + renderingStoryPromises.push( + new Promise((resolve) => { + rendered = resolve; + }) + ); + return rendered; + }, getStoryContext: (renderedStory: Story) => ({ ...this.storyStore.getStoryContext(renderedStory), @@ -350,7 +362,10 @@ export class PreviewWeb { ); - ReactDOM.render(docsElement, element, () => this.channel.emit(Events.DOCS_RENDERED, id)); + ReactDOM.render(docsElement, element, async () => { + await Promise.all(renderingStoryPromises); + this.channel.emit(Events.DOCS_RENDERED, id); + }); } renderStory({ story }: { story: Story }) { diff --git a/lib/preview-web/src/types.ts b/lib/preview-web/src/types.ts index 95992f3eaf2..b26cab25dfa 100644 --- a/lib/preview-web/src/types.ts +++ b/lib/preview-web/src/types.ts @@ -17,6 +17,7 @@ export interface DocsContextProps Promise>; renderStoryToElement: PreviewWeb['renderStoryToElement']; getStoryContext: (story: Story) => StoryContextForLoaders; + registerRenderingStory: () => (v: void) => void; /** * mdxStoryNameToKey is an MDX-compiler-generated mapping of an MDX story's From 6af054700a14e912b0cc17c633ef149aa4f6ffb4 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 12:23:45 +0800 Subject: [PATCH 276/285] Update snapshots --- .../__testfixtures__/mdx/component-args.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/component-id.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/csf-imports.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/decorators.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/docs-only.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/loaders.output.snapshot | 2 +- .../__testfixtures__/mdx/meta-quotes-in-title.output.snapshot | 2 +- .../__testfixtures__/mdx/non-story-exports.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/parameters.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/previews.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/story-args.output.snapshot | 2 +- .../__testfixtures__/mdx/story-current.output.snapshot | 2 +- .../__testfixtures__/mdx/story-def-text-only.output.snapshot | 2 +- .../__testfixtures__/mdx/story-definitions.output.snapshot | 2 +- .../__testfixtures__/mdx/story-function-var.output.snapshot | 2 +- .../__testfixtures__/mdx/story-function.output.snapshot | 2 +- .../mdx/story-multiple-children.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/story-object.output.snapshot | 2 +- .../__testfixtures__/mdx/story-references.output.snapshot | 2 +- .../__testfixtures__/mdx/title-template-string.output.snapshot | 2 +- lib/csf-tools/__testfixtures__/mdx/vanilla.output.snapshot | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/csf-tools/__testfixtures__/mdx/component-args.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/component-args.output.snapshot index ca2bd2aa2a7..a6a16c6dba9 100644 --- a/lib/csf-tools/__testfixtures__/mdx/component-args.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/component-args.output.snapshot @@ -66,7 +66,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/component-id.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/component-id.output.snapshot index 71c57f7711a..a96ae928535 100644 --- a/lib/csf-tools/__testfixtures__/mdx/component-id.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/component-id.output.snapshot @@ -40,7 +40,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/csf-imports.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/csf-imports.output.snapshot index 64b963aa97d..2c988d11db0 100644 --- a/lib/csf-tools/__testfixtures__/mdx/csf-imports.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/csf-imports.output.snapshot @@ -43,7 +43,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/decorators.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/decorators.output.snapshot index 5ce25afd01b..aa4d66124ed 100644 --- a/lib/csf-tools/__testfixtures__/mdx/decorators.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/decorators.output.snapshot @@ -69,7 +69,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/docs-only.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/docs-only.output.snapshot index 408ebb03cad..d46366c31e4 100644 --- a/lib/csf-tools/__testfixtures__/mdx/docs-only.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/docs-only.output.snapshot @@ -35,7 +35,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/loaders.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/loaders.output.snapshot index 661a708f86a..14c1d64b633 100644 --- a/lib/csf-tools/__testfixtures__/mdx/loaders.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/loaders.output.snapshot @@ -65,7 +65,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/meta-quotes-in-title.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/meta-quotes-in-title.output.snapshot index e14e5b9b609..2ac4dfc1ba5 100644 --- a/lib/csf-tools/__testfixtures__/mdx/meta-quotes-in-title.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/meta-quotes-in-title.output.snapshot @@ -33,7 +33,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/non-story-exports.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/non-story-exports.output.snapshot index 5fa1a03805a..1cbdd52ebaa 100644 --- a/lib/csf-tools/__testfixtures__/mdx/non-story-exports.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/non-story-exports.output.snapshot @@ -47,7 +47,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/parameters.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/parameters.output.snapshot index ec2ad5dc275..2b11e9746c4 100644 --- a/lib/csf-tools/__testfixtures__/mdx/parameters.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/parameters.output.snapshot @@ -67,7 +67,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/previews.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/previews.output.snapshot index a1a0da0484d..9066ed2add4 100644 --- a/lib/csf-tools/__testfixtures__/mdx/previews.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/previews.output.snapshot @@ -66,7 +66,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-args.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-args.output.snapshot index 055ebd1b182..79f67238ced 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-args.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-args.output.snapshot @@ -67,7 +67,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-current.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-current.output.snapshot index 8de5c7f1f0a..82ef5bb6bea 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-current.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-current.output.snapshot @@ -28,7 +28,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-def-text-only.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-def-text-only.output.snapshot index e2d7867475c..477d05f8cca 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-def-text-only.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-def-text-only.output.snapshot @@ -35,7 +35,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-definitions.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-definitions.output.snapshot index 60ebe9193b4..6ca818c3b3e 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-definitions.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-definitions.output.snapshot @@ -65,7 +65,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-function-var.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-function-var.output.snapshot index ea1f8e5aa23..ebef9ce56c6 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-function-var.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-function-var.output.snapshot @@ -49,7 +49,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-function.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-function.output.snapshot index 5b000192718..59310ca9c70 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-function.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-function.output.snapshot @@ -56,7 +56,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-multiple-children.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-multiple-children.output.snapshot index 5e6b18d94fc..3beb5013620 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-multiple-children.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-multiple-children.output.snapshot @@ -43,7 +43,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-object.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-object.output.snapshot index ed064a50926..c042fa2a3cd 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-object.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-object.output.snapshot @@ -59,7 +59,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/story-references.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/story-references.output.snapshot index da083a29795..346168650ae 100644 --- a/lib/csf-tools/__testfixtures__/mdx/story-references.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/story-references.output.snapshot @@ -28,7 +28,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/title-template-string.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/title-template-string.output.snapshot index 9b8ddfcc5f8..896abc4cbbe 100644 --- a/lib/csf-tools/__testfixtures__/mdx/title-template-string.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/title-template-string.output.snapshot @@ -34,7 +34,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), diff --git a/lib/csf-tools/__testfixtures__/mdx/vanilla.output.snapshot b/lib/csf-tools/__testfixtures__/mdx/vanilla.output.snapshot index 87c1682f789..33eeecfb4c0 100644 --- a/lib/csf-tools/__testfixtures__/mdx/vanilla.output.snapshot +++ b/lib/csf-tools/__testfixtures__/mdx/vanilla.output.snapshot @@ -29,7 +29,7 @@ componentMeta.parameters = componentMeta.parameters || {}; componentMeta.parameters.docs = { ...(componentMeta.parameters.docs || {}), page: () => ( - + ), From acf0e9c14127d36f1f8f141e7b0b3303b52a8908 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 12:29:37 +0800 Subject: [PATCH 277/285] Fix deepscan error --- addons/docs/src/blocks/Source.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/docs/src/blocks/Source.tsx b/addons/docs/src/blocks/Source.tsx index e3c6da541c5..44787d71eda 100644 --- a/addons/docs/src/blocks/Source.tsx +++ b/addons/docs/src/blocks/Source.tsx @@ -43,10 +43,6 @@ type NoneProps = CommonProps; type SourceProps = SingleSourceProps | MultiSourceProps | CodeProps | NoneProps; -const getStory = (storyId: StoryId, docsContext: DocsContextProps): Story | null => { - return docsContext.storyById(storyId); -}; - const getSourceState = (stories: Story[]) => { const states = stories.map((story) => story.parameters.docs?.source?.state).filter(Boolean); if (states.length === 0) return SourceState.CLOSED; From 9bb98c90b3e825f373a59baca5f709628e774ede Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 14 Sep 2021 14:31:28 +1000 Subject: [PATCH 278/285] Ensure we emit all `SNIPPET_RENDERED` in `useEffect()` This also enables us to simplify `SourceContainer`. --- addons/docs/src/blocks/SourceContainer.tsx | 28 ++++++++----------- .../src/frameworks/angular/sourceDecorator.ts | 17 +++++------ .../src/frameworks/html/sourceDecorator.ts | 10 ++++--- .../src/frameworks/react/jsxDecorator.tsx | 13 +++++---- .../src/frameworks/svelte/sourceDecorator.ts | 18 +++++++----- .../web-components/sourceDecorator.ts | 9 ++++-- 6 files changed, 51 insertions(+), 44 deletions(-) diff --git a/addons/docs/src/blocks/SourceContainer.tsx b/addons/docs/src/blocks/SourceContainer.tsx index aa4971286ed..b11e20135a4 100644 --- a/addons/docs/src/blocks/SourceContainer.tsx +++ b/addons/docs/src/blocks/SourceContainer.tsx @@ -18,24 +18,18 @@ export const SourceContainer: FC<{}> = ({ children }) => { const [sources, setSources] = useState({}); const channel = addons.getChannel(); - const sourcesRef = React.useRef(); - const handleSnippetRendered = (id: StoryId, newItem: SourceItem) => { - if (newItem !== sources[id]) { - const newSources = { ...sourcesRef.current, [id]: newItem }; - sourcesRef.current = newSources; - } - }; - - // Bind this early (instead of inside `useEffect`), because the `SNIPPET_RENDERED` event - // is triggered *during* the rendering process, not after. We have to use the ref - // to ensure we don't end up calling setState outside the effect though. - channel.on(SNIPPET_RENDERED, handleSnippetRendered); - useEffect(() => { - const current = sourcesRef.current || {}; - if (!deepEqual(sources, current)) { - setSources(current); - } + const handleSnippetRendered = (id: StoryId, newItem: SourceItem) => { + if (newItem !== sources[id]) { + const newSources = { ...sources, [id]: newItem }; + + if (!deepEqual(sources, newSources)) { + setSources(newSources); + } + } + }; + + channel.on(SNIPPET_RENDERED, handleSnippetRendered); return () => channel.off(SNIPPET_RENDERED, handleSnippetRendered); }); diff --git a/addons/docs/src/frameworks/angular/sourceDecorator.ts b/addons/docs/src/frameworks/angular/sourceDecorator.ts index 496a316f55c..7a14b4ce64b 100644 --- a/addons/docs/src/frameworks/angular/sourceDecorator.ts +++ b/addons/docs/src/frameworks/angular/sourceDecorator.ts @@ -1,4 +1,4 @@ -import { addons } from '@storybook/addons'; +import { addons, useEffect } from '@storybook/addons'; import { PartialStoryFn } from '@storybook/csf'; import { StoryContext, AngularFramework } from '@storybook/angular'; import { computesTemplateSourceFromComponent } from '@storybook/angular/renderer'; @@ -44,20 +44,21 @@ export const sourceDecorator = ( const { component, argTypes } = context; + let toEmit: string; + useEffect(() => { + if (toEmit) channel.emit(SNIPPET_RENDERED, context.id, prettyUp(template)); + }); + if (component && !userDefinedTemplate) { const source = computesTemplateSourceFromComponent(component, props, argTypes); // We might have a story with a Directive or Service defined as the component // In these cases there might exist a template, even if we aren't able to create source from component if (source || template) { - channel.emit(SNIPPET_RENDERED, context.id, prettyUp(source || template)); + toEmit = prettyUp(source || template); } - return story; - } - - if (template) { - channel.emit(SNIPPET_RENDERED, context.id, prettyUp(template)); - return story; + } else if (template) { + toEmit = prettyUp(template); } return story; diff --git a/addons/docs/src/frameworks/html/sourceDecorator.ts b/addons/docs/src/frameworks/html/sourceDecorator.ts index c37143f4ee2..16252f813c3 100644 --- a/addons/docs/src/frameworks/html/sourceDecorator.ts +++ b/addons/docs/src/frameworks/html/sourceDecorator.ts @@ -1,5 +1,5 @@ /* global window */ -import { addons } from '@storybook/addons'; +import { addons, useEffect } from '@storybook/addons'; import { ArgsStoryFn, PartialStoryFn, StoryContext } from '@storybook/csf'; import dedent from 'ts-dedent'; import { HtmlFramework } from '@storybook/html'; @@ -40,11 +40,13 @@ export function sourceDecorator( ? (context.originalStoryFn as ArgsStoryFn)(context.args, context) : storyFn(); + let source: string; if (typeof story === 'string' && !skipSourceRender(context)) { - const source = applyTransformSource(story, context); - - addons.getChannel().emit(SNIPPET_RENDERED, context.id, source); + source = applyTransformSource(story, context); } + useEffect(() => { + if (source) addons.getChannel().emit(SNIPPET_RENDERED, context.id, source); + }); return story; } diff --git a/addons/docs/src/frameworks/react/jsxDecorator.tsx b/addons/docs/src/frameworks/react/jsxDecorator.tsx index e3a3cc88846..860b0efe4be 100644 --- a/addons/docs/src/frameworks/react/jsxDecorator.tsx +++ b/addons/docs/src/frameworks/react/jsxDecorator.tsx @@ -3,7 +3,7 @@ import reactElementToJSXString, { Options } from 'react-element-to-jsx-string'; import dedent from 'ts-dedent'; import deprecate from 'util-deprecate'; -import { addons } from '@storybook/addons'; +import { addons, useEffect } from '@storybook/addons'; import { StoryContext, ArgsStoryFn, PartialStoryFn } from '@storybook/csf'; import { logger } from '@storybook/client-logger'; import { ReactFramework } from '@storybook/react'; @@ -175,11 +175,17 @@ export const jsxDecorator = ( storyFn: PartialStoryFn, context: StoryContext ) => { + const skip = skipJsxRender(context); const story = storyFn(); + let jsx = ''; + useEffect(() => { + if (!skip) channel.emit(SNIPPET_RENDERED, (context || {}).id, jsx); + }); + // We only need to render JSX if the source block is actually going to // consume it. Otherwise it's just slowing us down. - if (skipJsxRender(context)) { + if (skip) { return story; } @@ -197,13 +203,10 @@ export const jsxDecorator = ( const sourceJsx = mdxToJsx(storyJsx); - let jsx = ''; const rendered = renderJsx(sourceJsx, options); if (rendered) { jsx = applyTransformSource(rendered, options, context); } - channel.emit(SNIPPET_RENDERED, (context || {}).id, jsx); - return story; }; diff --git a/addons/docs/src/frameworks/svelte/sourceDecorator.ts b/addons/docs/src/frameworks/svelte/sourceDecorator.ts index 6eb2d41c2c0..dc047e619ca 100644 --- a/addons/docs/src/frameworks/svelte/sourceDecorator.ts +++ b/addons/docs/src/frameworks/svelte/sourceDecorator.ts @@ -1,4 +1,4 @@ -import { addons } from '@storybook/addons'; +import { addons, useEffect } from '@storybook/addons'; import { ArgTypes, Args, StoryContext, AnyFramework } from '@storybook/csf'; import { SourceType, SNIPPET_RENDERED } from '../../shared'; @@ -145,9 +145,17 @@ function getWrapperProperties(component: any) { * @param context StoryContext */ export const sourceDecorator = (storyFn: any, context: StoryContext) => { + const skip = skipSourceRender(context); const story = storyFn(); - if (skipSourceRender(context)) { + let source: string; + useEffect(() => { + if (!skip && source) { + channel.emit(SNIPPET_RENDERED, (context || {}).id, source); + } + }); + + if (skip) { return story; } @@ -161,11 +169,7 @@ export const sourceDecorator = (storyFn: any, context: StoryContext)(context.args, context) : storyFn(); + let source: string; + useEffect(() => { + if (source) addons.getChannel().emit(SNIPPET_RENDERED, context.id, source); + }); if (!skipSourceRender(context)) { const container = window.document.createElement('div'); render(story, container); - const source = applyTransformSource(container.innerHTML.replace(//g, ''), context); - if (source) addons.getChannel().emit(SNIPPET_RENDERED, context.id, source); + source = applyTransformSource(container.innerHTML.replace(//g, ''), context); } return story; From f2edc58755696dda00516ded9af793b6e3515722 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 13:05:59 +0800 Subject: [PATCH 279/285] Fix docs test --- cypress/generated/addon-docs.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/generated/addon-docs.spec.ts b/cypress/generated/addon-docs.spec.ts index 16492600b21..b3506c0bc86 100644 --- a/cypress/generated/addon-docs.spec.ts +++ b/cypress/generated/addon-docs.spec.ts @@ -6,6 +6,6 @@ describe('addon-action', () => { it('should have docs tab', () => { cy.navigateToStory('example-button', 'primary'); cy.viewAddonTab('Docs'); - cy.getDocsElement().get('.sbdocs-title').contains('Button'); + cy.getDocsElement().find('h1').should('contain.text', 'Button'); }); }); From 2a16b7a1c9646a34155521b7b1c5738997a3d86a Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 13:31:56 +0800 Subject: [PATCH 280/285] Update story to new DocsContext --- .../stories/addon-docs/mdx.stories.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/official-storybook/stories/addon-docs/mdx.stories.js b/examples/official-storybook/stories/addon-docs/mdx.stories.js index 7142e9c2e35..c5c14efcd20 100644 --- a/examples/official-storybook/stories/addon-docs/mdx.stories.js +++ b/examples/official-storybook/stories/addon-docs/mdx.stories.js @@ -7,7 +7,11 @@ export default { title: 'Addons/Docs/mdx-in-story', decorators: [ (storyFn) => ( - ({ parameters: {} }) }}>{storyFn()} + [], storyById: () => ({ parameters: {} }) }} + > + {storyFn()} + ), ], parameters: { @@ -29,7 +33,10 @@ export const DarkModeDocs = () => { DarkModeDocs.decorators = [ (storyFn) => ( ({ parameters: { docs: { theme: themes.dark } } }) }} + context={{ + componentStories: () => [], + storyById: () => ({ parameters: { docs: { theme: themes.dark } } }), + }} > {storyFn()} From 65be2181883b5c41e30532179e2532aa06ae44c0 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 14 Sep 2021 15:54:15 +1000 Subject: [PATCH 281/285] Fix tests and ensure channel is defined --- .../frameworks/react/jsxDecorator.test.tsx | 26 ++++++++++++++----- .../src/frameworks/react/jsxDecorator.tsx | 4 +-- .../src/frameworks/svelte/sourceDecorator.ts | 3 +-- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/addons/docs/src/frameworks/react/jsxDecorator.test.tsx b/addons/docs/src/frameworks/react/jsxDecorator.test.tsx index cb44d60da6d..b18e9984c51 100644 --- a/addons/docs/src/frameworks/react/jsxDecorator.test.tsx +++ b/addons/docs/src/frameworks/react/jsxDecorator.test.tsx @@ -1,12 +1,13 @@ /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ import React from 'react'; import PropTypes from 'prop-types'; -import { addons, StoryContext } from '@storybook/addons'; +import { addons, StoryContext, useEffect } from '@storybook/addons'; import { renderJsx, jsxDecorator } from './jsxDecorator'; import { SNIPPET_RENDERED } from '../../shared'; jest.mock('@storybook/addons'); const mockedAddons = addons as jest.Mocked; +const mockedUseEffect = useEffect as jest.Mocked; expect.addSnapshotSerializer({ print: (val: any) => val, @@ -168,15 +169,17 @@ describe('jsxDecorator', () => { let mockChannel: { on: jest.Mock; emit?: jest.Mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); + mockedUseEffect.mockImplementation((cb) => setTimeout(cb, 0)); mockChannel = { on: jest.fn(), emit: jest.fn() }; mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); - it('should render dynamically for args stories', () => { + it('should render dynamically for args stories', async () => { const storyFn = (args: any) =>
args story
; const context = makeContext('args', { __isArgsStory: true }, {}); jsxDecorator(storyFn, context); + await new Promise((r) => setTimeout(r, 0)); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'jsx-test--args', @@ -184,7 +187,7 @@ describe('jsxDecorator', () => { ); }); - it('should not render decorators when provided excludeDecorators parameter', () => { + it('should not render decorators when provided excludeDecorators parameter', async () => { const storyFn = (args: any) =>
args story
; const decoratedStoryFn = (args: any) => (
{storyFn(args)}
@@ -203,6 +206,8 @@ describe('jsxDecorator', () => { { originalStoryFn: storyFn } ); jsxDecorator(decoratedStoryFn, context); + await new Promise((r) => setTimeout(r, 0)); + expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'jsx-test--args', @@ -210,20 +215,24 @@ describe('jsxDecorator', () => { ); }); - it('should skip dynamic rendering for no-args stories', () => { + it('should skip dynamic rendering for no-args stories', async () => { const storyFn = () =>
classic story
; const context = makeContext('classic', {}, {}); jsxDecorator(storyFn, context); + await new Promise((r) => setTimeout(r, 0)); + expect(mockChannel.emit).not.toHaveBeenCalled(); }); // This is deprecated, but still test it - it('allows the snippet output to be modified by onBeforeRender', () => { + it('allows the snippet output to be modified by onBeforeRender', async () => { const storyFn = (args: any) =>
args story
; const onBeforeRender = (dom: string) => `

${dom}

`; const jsx = { onBeforeRender }; const context = makeContext('args', { __isArgsStory: true, jsx }, {}); jsxDecorator(storyFn, context); + await new Promise((r) => setTimeout(r, 0)); + expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'jsx-test--args', @@ -231,12 +240,14 @@ describe('jsxDecorator', () => { ); }); - it('allows the snippet output to be modified by transformSource', () => { + it('allows the snippet output to be modified by transformSource', async () => { const storyFn = (args: any) =>
args story
; const transformSource = (dom: string) => `

${dom}

`; const jsx = { transformSource }; const context = makeContext('args', { __isArgsStory: true, jsx }, {}); jsxDecorator(storyFn, context); + await new Promise((r) => setTimeout(r, 0)); + expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'jsx-test--args', @@ -253,7 +264,7 @@ describe('jsxDecorator', () => { expect(transformSource).toHaveBeenCalledWith('
\n args story\n
', context); }); - it('renders MDX properly', () => { + it('renders MDX properly', async () => { // FIXME: generate this from actual MDX const mdxElement = { type: { displayName: 'MDXCreateElement' }, @@ -265,6 +276,7 @@ describe('jsxDecorator', () => { }; jsxDecorator(() => mdxElement, makeContext('mdx-args', { __isArgsStory: true }, {})); + await new Promise((r) => setTimeout(r, 0)); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, diff --git a/addons/docs/src/frameworks/react/jsxDecorator.tsx b/addons/docs/src/frameworks/react/jsxDecorator.tsx index 860b0efe4be..9170adaa3cc 100644 --- a/addons/docs/src/frameworks/react/jsxDecorator.tsx +++ b/addons/docs/src/frameworks/react/jsxDecorator.tsx @@ -175,10 +175,12 @@ export const jsxDecorator = ( storyFn: PartialStoryFn, context: StoryContext ) => { + const channel = addons.getChannel(); const skip = skipJsxRender(context); const story = storyFn(); let jsx = ''; + useEffect(() => { if (!skip) channel.emit(SNIPPET_RENDERED, (context || {}).id, jsx); }); @@ -189,8 +191,6 @@ export const jsxDecorator = ( return story; } - const channel = addons.getChannel(); - const options = { ...defaultOpts, ...(context?.parameters.jsx || {}), diff --git a/addons/docs/src/frameworks/svelte/sourceDecorator.ts b/addons/docs/src/frameworks/svelte/sourceDecorator.ts index dc047e619ca..f740a4c857b 100644 --- a/addons/docs/src/frameworks/svelte/sourceDecorator.ts +++ b/addons/docs/src/frameworks/svelte/sourceDecorator.ts @@ -145,6 +145,7 @@ function getWrapperProperties(component: any) { * @param context StoryContext */ export const sourceDecorator = (storyFn: any, context: StoryContext) => { + const channel = addons.getChannel(); const skip = skipSourceRender(context); const story = storyFn(); @@ -159,8 +160,6 @@ export const sourceDecorator = (storyFn: any, context: StoryContext Date: Tue, 14 Sep 2021 14:35:38 +0800 Subject: [PATCH 282/285] Fix failing sourceDecorator tests --- .../frameworks/html/sourceDecorator.test.ts | 21 +++++++++++++------ .../web-components/sourceDecorator.test.ts | 18 +++++++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/addons/docs/src/frameworks/html/sourceDecorator.test.ts b/addons/docs/src/frameworks/html/sourceDecorator.test.ts index 6efefd6cfac..9e66c1ebd1c 100644 --- a/addons/docs/src/frameworks/html/sourceDecorator.test.ts +++ b/addons/docs/src/frameworks/html/sourceDecorator.test.ts @@ -1,15 +1,18 @@ -import { addons, StoryContext } from '@storybook/addons'; +import { addons, StoryContext, useEffect } from '@storybook/addons'; import { sourceDecorator } from './sourceDecorator'; import { SNIPPET_RENDERED } from '../../shared'; jest.mock('@storybook/addons'); const mockedAddons = addons as jest.Mocked; +const mockedUseEffect = useEffect as jest.Mocked; expect.addSnapshotSerializer({ print: (val: any) => val, test: (val) => typeof val === 'string', }); +const tick = () => new Promise((r) => setTimeout(r, 0)); + const makeContext = (name: string, parameters: any, args: any, extra?: object): StoryContext => ({ id: `html-test--${name}`, kind: 'js-text', @@ -25,15 +28,17 @@ describe('sourceDecorator', () => { let mockChannel: { on: jest.Mock; emit?: jest.Mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); + mockedUseEffect.mockImplementation((cb) => setTimeout(cb, 0)); mockChannel = { on: jest.fn(), emit: jest.fn() }; mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); - it('should render dynamically for args stories', () => { + it('should render dynamically for args stories', async () => { const storyFn = (args: any) => `
args story
`; const context = makeContext('args', { __isArgsStory: true }, {}); sourceDecorator(storyFn, context); + await tick(); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'html-test--args', @@ -41,7 +46,7 @@ describe('sourceDecorator', () => { ); }); - it('should dedent source by default', () => { + it('should dedent source by default', async () => { const storyFn = (args: any) => `
args story @@ -49,6 +54,7 @@ describe('sourceDecorator', () => { `; const context = makeContext('args', { __isArgsStory: true }, {}); sourceDecorator(storyFn, context); + await tick(); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'html-test--args', @@ -56,14 +62,15 @@ describe('sourceDecorator', () => { ); }); - it('should skip dynamic rendering for no-args stories', () => { + it('should skip dynamic rendering for no-args stories', async () => { const storyFn = () => `
classic story
`; const context = makeContext('classic', {}, {}); sourceDecorator(storyFn, context); + await tick(); expect(mockChannel.emit).not.toHaveBeenCalled(); }); - it('should use the originalStoryFn if excludeDecorators is set', () => { + it('should use the originalStoryFn if excludeDecorators is set', async () => { const storyFn = (args: any) => `
args story
`; const decoratedStoryFn = (args: any) => `
${storyFn(args)}
@@ -82,6 +89,7 @@ describe('sourceDecorator', () => { { originalStoryFn: storyFn } ); sourceDecorator(decoratedStoryFn, context); + await tick(); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'html-test--args', @@ -89,12 +97,13 @@ describe('sourceDecorator', () => { ); }); - it('allows the snippet output to be modified by transformSource', () => { + it('allows the snippet output to be modified by transformSource', async () => { const storyFn = (args: any) => `
args story
`; const transformSource = (dom: string) => `

${dom}

`; const docs = { transformSource }; const context = makeContext('args', { __isArgsStory: true, docs }, {}); sourceDecorator(storyFn, context); + await tick(); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'html-test--args', diff --git a/addons/docs/src/frameworks/web-components/sourceDecorator.test.ts b/addons/docs/src/frameworks/web-components/sourceDecorator.test.ts index 4c2c4985104..28cff3d42c7 100644 --- a/addons/docs/src/frameworks/web-components/sourceDecorator.test.ts +++ b/addons/docs/src/frameworks/web-components/sourceDecorator.test.ts @@ -1,17 +1,20 @@ import { html } from 'lit-html'; import { styleMap } from 'lit-html/directives/style-map'; -import { addons, StoryContext } from '@storybook/addons'; +import { addons, StoryContext, useEffect } from '@storybook/addons'; import { sourceDecorator } from './sourceDecorator'; import { SNIPPET_RENDERED } from '../../shared'; jest.mock('@storybook/addons'); const mockedAddons = addons as jest.Mocked; +const mockedUseEffect = useEffect as jest.Mocked; expect.addSnapshotSerializer({ print: (val: any) => val, test: (val) => typeof val === 'string', }); +const tick = () => new Promise((r) => setTimeout(r, 0)); + const makeContext = (name: string, parameters: any, args: any, extra?: object): StoryContext => ({ id: `lit-test--${name}`, kind: 'js-text', @@ -27,15 +30,17 @@ describe('sourceDecorator', () => { let mockChannel: { on: jest.Mock; emit?: jest.Mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); + mockedUseEffect.mockImplementation((cb) => setTimeout(cb, 0)); mockChannel = { on: jest.fn(), emit: jest.fn() }; mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); - it('should render dynamically for args stories', () => { + it('should render dynamically for args stories', async () => { const storyFn = (args: any) => html`
args story
`; const context = makeContext('args', { __isArgsStory: true }, {}); sourceDecorator(storyFn, context); + await tick(); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'lit-test--args', @@ -43,14 +48,15 @@ describe('sourceDecorator', () => { ); }); - it('should skip dynamic rendering for no-args stories', () => { + it('should skip dynamic rendering for no-args stories', async () => { const storyFn = () => html`
classic story
`; const context = makeContext('classic', {}, {}); sourceDecorator(storyFn, context); + await tick(); expect(mockChannel.emit).not.toHaveBeenCalled(); }); - it('should use the originalStoryFn if excludeDecorators is set', () => { + it('should use the originalStoryFn if excludeDecorators is set', async () => { const storyFn = (args: any) => html`
args story
`; const decoratedStoryFn = (args: any) => html`
${storyFn(args)}
@@ -69,6 +75,7 @@ describe('sourceDecorator', () => { { originalStoryFn: storyFn } ); sourceDecorator(decoratedStoryFn, context); + await tick(); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'lit-test--args', @@ -76,12 +83,13 @@ describe('sourceDecorator', () => { ); }); - it('allows the snippet output to be modified by transformSource', () => { + it('allows the snippet output to be modified by transformSource', async () => { const storyFn = (args: any) => html`
args story
`; const transformSource = (dom: string) => `

${dom}

`; const docs = { transformSource }; const context = makeContext('args', { __isArgsStory: true, docs }, {}); sourceDecorator(storyFn, context); + await tick(); expect(mockChannel.emit).toHaveBeenCalledWith( SNIPPET_RENDERED, 'lit-test--args', From adcc98ff9f1d3dc491ca383f62d3dae842f7f2d1 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 16:16:59 +0800 Subject: [PATCH 283/285] E2E force remove package-lock.json --- lib/cli/src/repro-generators/scripts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cli/src/repro-generators/scripts.ts b/lib/cli/src/repro-generators/scripts.ts index 43507008111..8d678d8ed06 100644 --- a/lib/cli/src/repro-generators/scripts.ts +++ b/lib/cli/src/repro-generators/scripts.ts @@ -136,7 +136,7 @@ const initStorybook = async ({ cwd, autoDetect = true, name, e2e }: Options) => const addRequiredDeps = async ({ cwd, additionalDeps }: Options) => { // Remove any lockfile generated without Yarn 2 - shell.rm(path.join(cwd, 'package-lock.json'), path.join(cwd, 'yarn.lock')); + shell.rm('-f', path.join(cwd, 'package-lock.json'), path.join(cwd, 'yarn.lock')); const command = additionalDeps && additionalDeps.length > 0 From 18f4c717dbd830b3cfa1149bfe6e0eced21e100b Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 16:18:32 +0800 Subject: [PATCH 284/285] Addon-docs/web-components: Handle no-manifest version check --- addons/docs/src/frameworks/web-components/custom-elements.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/docs/src/frameworks/web-components/custom-elements.ts b/addons/docs/src/frameworks/web-components/custom-elements.ts index 701bfb866ba..38d83a8f56a 100644 --- a/addons/docs/src/frameworks/web-components/custom-elements.ts +++ b/addons/docs/src/frameworks/web-components/custom-elements.ts @@ -123,7 +123,7 @@ export const extractArgTypesFromElements = (tagName: string, customElements: Cus }; const getMetaData = (tagName: string, manifest: any) => { - if (manifest.version === 'experimental') { + if (manifest?.version === 'experimental') { return getMetaDataExperimental(tagName, manifest); } return getMetaDataV1(tagName, manifest); From 5a981b4bd50cce62586971a82602b0a18af7fff2 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Tue, 14 Sep 2021 16:45:42 +0800 Subject: [PATCH 285/285] Fix deepscan --- addons/docs/src/blocks/Meta.tsx | 2 +- .../stories/addon-docs/dynamic-title.stories.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/docs/src/blocks/Meta.tsx b/addons/docs/src/blocks/Meta.tsx index 206496266e8..facf978b568 100644 --- a/addons/docs/src/blocks/Meta.tsx +++ b/addons/docs/src/blocks/Meta.tsx @@ -1,6 +1,6 @@ import React, { FC, useContext } from 'react'; import global from 'global'; -import { AnyFramework, BaseAnnotations } from '@storybook/csf'; +import { BaseAnnotations } from '@storybook/csf'; import { Anchor } from './Anchor'; import { DocsContext, DocsContextProps } from './DocsContext'; diff --git a/examples/official-storybook/stories/addon-docs/dynamic-title.stories.js b/examples/official-storybook/stories/addon-docs/dynamic-title.stories.js index 015e67afd44..9250bb4fbea 100644 --- a/examples/official-storybook/stories/addon-docs/dynamic-title.stories.js +++ b/examples/official-storybook/stories/addon-docs/dynamic-title.stories.js @@ -1,4 +1,4 @@ -const getTitle = () => `Addons/Docs/${['dynamic title'][0]}`; +// const getTitle = () => `Addons/Docs/${['dynamic title'][0]}`; export default { // FIXME dynamic title