diff --git a/integrations/storybook/src/config.ts b/integrations/storybook/src/config.ts index 6ad733c03..51c834a10 100644 --- a/integrations/storybook/src/config.ts +++ b/integrations/storybook/src/config.ts @@ -1,7 +1,7 @@ import { addDecorator } from '@storybook/client-api'; import { makeDecorator } from '@storybook/addons'; import { controlsMessages } from './context/BroadcastMessage'; -// import './context/RenderDocsPages'; +import './context/RenderDocsPages'; addDecorator( makeDecorator({ diff --git a/integrations/storybook/src/context/BlockContext.tsx b/integrations/storybook/src/context/BlockContext.tsx index 74261e416..e42ade873 100644 --- a/integrations/storybook/src/context/BlockContext.tsx +++ b/integrations/storybook/src/context/BlockContext.tsx @@ -4,16 +4,26 @@ import { FORCE_RE_RENDER } from '@storybook/core-events'; import { BlockContextProvider as BlocksContextProvider } from '@component-controls/blocks'; import { DocsContext } from '@storybook/addon-docs/blocks'; -export const BlockContextProvider: React.FC = ({ children }) => { - const context = React.useContext(DocsContext); +export interface BlockContextProviderProps { + id?: string; +} +export const BlockContextProvider: React.FC = ({ + children, + id, +}) => { + let storyId: string; + if (!id) { + const context = React.useContext(DocsContext); + ({ id: storyId } = context as any); + } else { + storyId = id; + } const channel = React.useMemo(() => addons.getChannel(), []); - const { id } = context as any; const onRefresh = () => channel.emit(FORCE_RE_RENDER); - // this._channel.emit(Events.FORCE_RE_RENDER); return ( diff --git a/integrations/storybook/src/context/RenderDocsPages.tsx b/integrations/storybook/src/context/RenderDocsPages.tsx index b6e64a30c..6bd0c3d0f 100644 --- a/integrations/storybook/src/context/RenderDocsPages.tsx +++ b/integrations/storybook/src/context/RenderDocsPages.tsx @@ -7,9 +7,15 @@ const ATTACH_DOCS_PAGE = 'attach_docs_page'; const channel = new BroadcastChannel(ATTACH_DOCS_PAGE); channel.onmessage = (message: { id: string; active: boolean }) => { - console.log('will attach'); - ReactDOM.render( - , - document.getElementById(message.id), - ); + if (message.active) { + ReactDOM.render( + , + document.getElementById(message.id), + ); + } else { + const node = document.getElementById(message.id); + if (node) { + ReactDOM.unmountComponentAtNode(node); + } + } }; diff --git a/integrations/storybook/src/page/DocsPage.tsx b/integrations/storybook/src/page/DocsPage.tsx index 871a20320..9540d68e8 100644 --- a/integrations/storybook/src/page/DocsPage.tsx +++ b/integrations/storybook/src/page/DocsPage.tsx @@ -21,19 +21,29 @@ export const DocsPage: FC = ({ active }) => { return null; } return ( - - - - <Subtitle /> - <Description /> - <ComponentSource id="." title="Component" /> - <Playground openTab="source" title="."> - <Story id="." /> - </Playground> - <ControlsTable id="." /> - <PropsTable of="." /> - <Stories dark={true} /> - </BlockContextProvider> - </ThemeProvider> + <div + style={{ + display: 'flex', + justifyContent: 'center', + padding: '4rem 20px', + }} + > + <div style={{ maxWidth: '1000px', width: '100%' }}> + <ThemeProvider> + <BlockContextProvider id="components-actionbar--overview"> + <Title /> + <Subtitle /> + <Description /> + <ComponentSource id="." title="Component" /> + <Playground openTab="source" title="."> + <Story id="." /> + </Playground> + <ControlsTable id="." /> + <PropsTable of="." /> + <Stories dark={true} /> + </BlockContextProvider> + </ThemeProvider> + </div> + </div> ); }; diff --git a/integrations/storybook/src/register.tsx b/integrations/storybook/src/register.tsx index f8cf46d15..77e958baa 100644 --- a/integrations/storybook/src/register.tsx +++ b/integrations/storybook/src/register.tsx @@ -1,11 +1,12 @@ /* eslint-disable react/display-name */ import React from 'react'; +import { BroadcastChannel } from 'broadcast-channel'; import { addons, types } from '@storybook/addons'; import { ADDON_ID, PANEL_ID } from './page/constants'; interface AddonPanelProps { active?: boolean; - id?: string; + id: string; } const AddonPanel: React.FC<AddonPanelProps> = ({ active, id }) => { @@ -14,10 +15,26 @@ const AddonPanel: React.FC<AddonPanelProps> = ({ active, id }) => { [], ); React.useEffect(() => { - console.log('will post message'); - channel.postMessage({ id: id, active }); + var iframe = document.getElementById( + 'storybook-preview-iframe', + ) as HTMLIFrameElement; + if (iframe && iframe.contentWindow) { + var node = iframe.contentWindow.document.getElementById(id); + if (!node) { + node = iframe.contentWindow.document.createElement('div'); + node.setAttribute('id', id); + iframe.contentWindow.document.body.appendChild(node); + } + if (active) { + node.removeAttribute('hidden'); + } else { + node.setAttribute('hidden', 'true'); + } + node.setAttribute('id', id); + channel.postMessage({ id: id, active }); + } }, [active]); - return <div id={id} />; + return null; }; addons.register(ADDON_ID, () => { const title = 'Page'; diff --git a/ui/blocks/src/context/block/BlockContext.tsx b/ui/blocks/src/context/block/BlockContext.tsx index 6587180a5..62194074d 100644 --- a/ui/blocks/src/context/block/BlockContext.tsx +++ b/ui/blocks/src/context/block/BlockContext.tsx @@ -14,7 +14,7 @@ export interface BlockContextInputProps { /** * current story id */ - currentId: string; + storyId: string; /** * store mockup when running tests */ @@ -23,7 +23,7 @@ export interface BlockContextInputProps { * optional cllabel to invoke when the story data are changed * for example when controls values are updated */ - onRefresh: () => void; + onRefresh?: () => void; /** * when set to true, the BlockCOntext will broadcast a message for changed controls values */ @@ -34,7 +34,7 @@ export interface BlockContextProps { /** * current story id */ - currentId?: string; + storyId?: string; /** * generic function to update the values of component controls. */ @@ -54,7 +54,7 @@ export const BlockContext = React.createContext<BlockContextProps>({}); export const BlockContextProvider: React.FC<BlockContextInputProps> = ({ children, - currentId, + storyId, mockStore, onRefresh, postMessage, @@ -119,7 +119,7 @@ export const BlockContextProvider: React.FC<BlockContextInputProps> = ({ return ( <BlockContext.Provider value={{ - currentId, + storyId, setControlValue, clickControl, store, diff --git a/ui/blocks/src/context/components/ComponentsContext.tsx b/ui/blocks/src/context/components/ComponentsContext.tsx index 3d4a10f93..4e749300c 100644 --- a/ui/blocks/src/context/components/ComponentsContext.tsx +++ b/ui/blocks/src/context/components/ComponentsContext.tsx @@ -33,14 +33,14 @@ export interface ComponentContextProps { export const useComponentsContext = ({ of = CURRENT_STORY, }: ComponentInputProps): ComponentContextProps => { - const { currentId, store } = React.useContext(BlockContext); - if (!currentId) { + const { storyId, store } = React.useContext(BlockContext); + if (!storyId) { return { components: {}, }; } const story: Story | undefined = - store && store.stories && store.stories[currentId]; + store && store.stories && store.stories[storyId]; const kind = store && story && story.kind ? store.kinds[story.kind] : undefined; let cmp: any; diff --git a/ui/blocks/src/context/story/StoryContext.tsx b/ui/blocks/src/context/story/StoryContext.tsx index 0b7d07ecf..edc619664 100644 --- a/ui/blocks/src/context/story/StoryContext.tsx +++ b/ui/blocks/src/context/story/StoryContext.tsx @@ -69,7 +69,7 @@ export const useStoryContext = ({ id, name, }: StoryInputProps): StoryContextProps => { - const { currentId, store } = React.useContext(BlockContext); + const { storyId: currentId, store } = React.useContext(BlockContext); const inputId = id === CURRENT_STORY ? currentId : id; const storyId = store ? inputId || (name && storyIdFromName(store, name)) || currentId diff --git a/ui/blocks/src/test/MockContext.tsx b/ui/blocks/src/test/MockContext.tsx index ff96c820c..ef88792ee 100644 --- a/ui/blocks/src/test/MockContext.tsx +++ b/ui/blocks/src/test/MockContext.tsx @@ -13,7 +13,7 @@ export const MockContext: React.FC<MockContexProps> = ({ storyId = 'id-of-story', }) => { return ( - <BlockContextProvider currentId={storyId} mockStore={storyStore}> + <BlockContextProvider storyId={storyId} mockStore={storyStore}> {children} </BlockContextProvider> );