diff --git a/core/store/src/serialization/load-store.ts b/core/store/src/serialization/load-store.ts index 7458d13b2..813e40e7b 100644 --- a/core/store/src/serialization/load-store.ts +++ b/core/store/src/serialization/load-store.ts @@ -86,7 +86,6 @@ export const loadStoryStore = (): StoriesStore | undefined => { story.controls || {}, ); } - if (kind.title && story.name) { const id = toId(kind.title, storyNameFromExport(story.name)); if (!kind.stories) { diff --git a/integrations/storybook/src/panel/ControlsPanel.tsx b/integrations/storybook/src/panel/ControlsPanel.tsx index ba6d7e24e..e03c65c42 100644 --- a/integrations/storybook/src/panel/ControlsPanel.tsx +++ b/integrations/storybook/src/panel/ControlsPanel.tsx @@ -12,7 +12,7 @@ export const ControlsPanel: React.FC = ({ active, api, }) => { - const [storyId, setStoryId] = React.useState(''); + const [storyId, setStoryId] = React.useState(); const channel = React.useMemo(() => api.getChannel(), []); React.useEffect(() => { const onChangeStory = (props: any) => { @@ -22,7 +22,7 @@ export const ControlsPanel: React.FC = ({ return () => channel.off(SET_CURRENT_STORY, onChangeStory); }); - return active ? ( + return active && storyId ? ( diff --git a/ui/blocks/src/BlockContainer/story/StoryBlockContainer.tsx b/ui/blocks/src/BlockContainer/story/StoryBlockContainer.tsx index e31178a23..1d2b559fc 100644 --- a/ui/blocks/src/BlockContainer/story/StoryBlockContainer.tsx +++ b/ui/blocks/src/BlockContainer/story/StoryBlockContainer.tsx @@ -40,7 +40,6 @@ export const StoryBlockContainer: FC = ({ title: userTitle, }); const block = children(context, rest); - return ( = props => ( {(context, rest) => { - const { story: selected, kind, getStory } = context; + const { story: selected, kind } = context; const stories = kind?.stories - ?.map((id: string) => getStory(id)) - .filter( - (story?: Story) => !selected || (story && selected.id !== story.id), - ); + ? kind.stories.filter((id: string) => !selected || selected.id !== id) + : []; if (!stories || !stories.length) { return null; } return ( <> - {(stories as Story[]).map((story: Story) => { - const storyTitle = story.name; + {stories.map((id: string) => { return ( = props => ( disabled: true, }, }} - title={storyTitle} + title="." collapsible={false} - key={`playground-${story.id}`} + key={`playground-${id}`} {...rest} > - + ); })} diff --git a/ui/blocks/src/context/block/BlockContext.tsx b/ui/blocks/src/context/block/BlockContext.tsx index 8b7fc67b1..499bfb63c 100644 --- a/ui/blocks/src/context/block/BlockContext.tsx +++ b/ui/blocks/src/context/block/BlockContext.tsx @@ -1,6 +1,5 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { store as storyStore, StoryStore } from '@component-controls/store'; -import { Story } from '@component-controls/specification'; import { BlockDataContextProvider } from './BlockDataContext'; import { BlockControlsContextProvider } from './BlockControlsContext'; @@ -19,7 +18,11 @@ export interface BlockContextProps { /** * current story */ - story?: Story; + storyId: string; + /** + * store interface + */ + storeProvider: StoryStore; } //@ts-ignore export const BlockContext = React.createContext({}); @@ -30,43 +33,14 @@ export const BlockContextProvider: React.FC = ({ mockStore, }) => { const storeProvider = mockStore || storyStore; - const store = storeProvider.getStore(); - const [story, setStory] = useState<{ story?: Story; id: string }>({ - story: store ? store.stories[storyId] : undefined, - id: storyId, - }); - - const refreshData = () => { - setStory({ - story: store ? { ...store.stories[storyId] } : undefined, - id: storyId, - }); - }; - useEffect(() => { - const onChange = (id?: string) => { - if (id === undefined || storyId === id) { - refreshData(); - } - }; - storyStore.addObserver(onChange); - return () => { - storyStore.removeObserver(onChange); - }; - }, []); - - useEffect(() => { - if (story.id !== storyId) { - refreshData(); - } - }, [storyId, store]); - return ( - + {children} diff --git a/ui/blocks/src/context/block/BlockDataContext.tsx b/ui/blocks/src/context/block/BlockDataContext.tsx index 9d8635c71..2e688401a 100644 --- a/ui/blocks/src/context/block/BlockDataContext.tsx +++ b/ui/blocks/src/context/block/BlockDataContext.tsx @@ -1,21 +1,16 @@ import React from 'react'; import { toId, storyNameFromExport } from '@storybook/csf'; +import { StoryStore } from '@component-controls/store'; import { Story, + StoriesStore, StoryComponent, StoryComponents, StoriesKind, getComponentName, - StoriesStore, } from '@component-controls/specification'; export interface BlockDataContextProps { - /** - /** - * returns a story, given a story id - */ - getStory: (storyId?: string) => Story | undefined; - /** * returns a story and its associated objects (kind, component), given a story id */ @@ -41,16 +36,15 @@ export interface BlockDataContextProps { export const BlockDataContext = React.createContext({}); export interface BlockDataContextInoutProps { - store?: StoriesStore; + store: StoryStore; } export const BlockDataContextProvider: React.FC = ({ children, - store, + store: storeProvider, }) => { - /** - * returns a story and its file, given a story id - */ + const store: StoriesStore | undefined = storeProvider.getStore(); + const getStoryData = (id?: string) => { const story: Story | undefined = store && store.stories && id ? store.stories[id] : undefined; @@ -67,8 +61,6 @@ export const BlockDataContextProvider: React.FC = ({ : undefined; return { story, kind, component }; }; - const getStory = (id?: string) => - store && store.stories && id && store.stories[id]; const getComponents = ( components: { [key: string]: any }, @@ -104,7 +96,6 @@ export const BlockDataContextProvider: React.FC = ({ return ( Story | undefined; } /** @@ -46,26 +41,49 @@ export interface StoryContextProps { * Context to be used by components that will display 'story' information */ export const useStoryContext = ({ - id, + id = CURRENT_STORY, name, }: StoryInputProps): StoryContextProps => { - const { story: currentStory } = React.useContext(BlockContext); - const { getStoryData, getStory, storyIdFromName } = React.useContext( - BlockDataContext, - ); - const currentId = currentStory ? currentStory.id : undefined; - const inputId = id === CURRENT_STORY ? currentId : id; - const storyId = inputId || (name && storyIdFromName(name)) || currentId; - if (!storyId) { - return { getStory }; - } - const { story, kind, component } = getStoryData(storyId); + const { storyId: currentId, storeProvider } = React.useContext(BlockContext); + const { getStoryData, storyIdFromName } = React.useContext(BlockDataContext); + const storyId = name + ? storyIdFromName(name) + : id === CURRENT_STORY + ? currentId + : id; + const [data, setData] = useState<{ + story?: Story; + kind?: StoriesKind; + component?: StoryComponent; + }>(getStoryData(storyId)); + + const updateData = () => { + const { story, kind, component } = getStoryData(storyId); + setData({ story, kind, component }); + }; + useEffect(() => { + const onChange = (id?: string) => { + if (storyId === id) { + updateData(); + } + }; + storeProvider.addObserver(onChange); + + return () => { + storeProvider.removeObserver(onChange); + }; + }, []); + + useEffect(() => { + const { story } = data; + if (!story || story.id !== storyId) { + updateData(); + } + }, [storyId]); + return { id: storyId, - kind, - story, - component, - getStory, + ...data, }; };