Skip to content

Commit

Permalink
feat: replace broadcast channel with storybook channel
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Apr 21, 2020
1 parent f0706a4 commit f825f53
Show file tree
Hide file tree
Showing 16 changed files with 102 additions and 159 deletions.
2 changes: 1 addition & 1 deletion docs/iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@
}</script><style>#root[hidden],
#docs-root[hidden] {
display: none !important;
}</style></head><body><div class="sb-nopreview sb-wrapper"><div class="sb-nopreview_main"><h1 class="sb-nopreview_heading sb-heading">No Preview</h1><p>Sorry, but you either have no stories or none are selected somehow.</p><ul><li>Please check the Storybook config.</li><li>Try reloading the page.</li></ul><p>If the problem persists, check the browser console, or the terminal you've run Storybook from.</p></div></div><div class="sb-errordisplay sb-wrapper"><pre id="error-message" class="sb-heading"></pre><pre class="sb-errordisplay_code"><code id="error-stack"></code></pre></div><div id="root"></div><div id="docs-root"></div><script src="runtime~main.b95c37e9979d1bf8afb3.bundle.js"></script><script src="vendors~main.b95c37e9979d1bf8afb3.bundle.js"></script><script src="main.b95c37e9979d1bf8afb3.bundle.js"></script></body></html>
}</style></head><body><div class="sb-nopreview sb-wrapper"><div class="sb-nopreview_main"><h1 class="sb-nopreview_heading sb-heading">No Preview</h1><p>Sorry, but you either have no stories or none are selected somehow.</p><ul><li>Please check the Storybook config.</li><li>Try reloading the page.</li></ul><p>If the problem persists, check the browser console, or the terminal you've run Storybook from.</p></div></div><div class="sb-errordisplay sb-wrapper"><pre id="error-message" class="sb-heading"></pre><pre class="sb-errordisplay_code"><code id="error-stack"></code></pre></div><div id="root"></div><div id="docs-root"></div><script src="runtime~main.1b4f95d3b01d405f81af.bundle.js"></script><script src="vendors~main.1b4f95d3b01d405f81af.bundle.js"></script><script src="main.1b4f95d3b01d405f81af.bundle.js"></script></body></html>
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
}</script><style>#root[hidden],
#docs-root[hidden] {
display: none !important;
}</style></head><body><div id="root"></div><div id="docs-root"></div><script>window['DOCS_MODE'] = false;</script><script src="runtime~main.ab7db0239d02e2e25577.bundle.js"></script><script src="vendors~main.86f030f1bd84ba827971.bundle.js"></script><script src="main.3b8d3344b6e125cd94a6.bundle.js"></script></body></html>
}</style></head><body><div id="root"></div><div id="docs-root"></div><script>window['DOCS_MODE'] = false;</script><script src="runtime~main.ab7db0239d02e2e25577.bundle.js"></script><script src="vendors~main.0245ae1700604a4f0f91.bundle.js"></script><script src="main.31377b7a1289382fb28c.bundle.js"></script></body></html>
55 changes: 0 additions & 55 deletions examples/storybook-custom-docs-pages/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,68 +23,13 @@ module.exports = {
configureJSX: true,
},
},
{
name: '@component-controls/storybook',
options: {
addonPanel: false,
docsPage: false,
},
},
{
name: '@component-controls/storybook-custom-docs',
options: {
pages: [
require.resolve('./page-simple.tsx'),
require.resolve('./page-docs-blocks.tsx'),
require.resolve('./page-component-blocks.tsx'),
require.resolve('./page-mixed-blocks.tsx')
]
},
}
],
webpackFinal: async (config, { configType }) => {
return {
...config,
module: {
...config.module,
rules: [
...config.module.rules,
{
test: /\.(story|stories).(js|jsx|ts|tsx|mdx)$/,
loader: "@component-controls/loader/loader",
exclude: [/node_modules/],
enforce: 'pre',
options: {
propsLoaders: [
{ name: '@component-controls/react-docgen-info', test: /\.(js|jsx)$/},
{ name: '@component-controls/react-docgen-typescript-info', test: /\.(ts|tsx)$/}
],
prettier: {
tabWidth: 2,
},
components: {
storeSourceFile: true, //false
resolveFile: (componentName, filePath) => {
if (filePath.includes('/theme-ui/dist')) {
return `${
filePath.split('/theme-ui/dist')[0]
}/@theme-ui/components/src/${componentName}.js`;
} else if (filePath.includes('@component-controls/storybook/dist')) {
return path.resolve(path.dirname(filePath), `../src/blocks/${componentName}.tsx`)
}
return filePath;
},
},
stories: {
storeSourceFile: true, //false
},
},
},
],
},
resolve: {
...config.resolve,
extensions: [...(config.resolve.extensions || []), '.ts', '.tsx'],
},
}},
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { Story, Title, ControlsTable, Playground } from '@component-controls/bl
import { CustomPageDef } from '@component-controls/storybook-custom-docs';


const Page = ({ active, storyId }) => {
const Page = ({ active }) => {
return (
<DocsContainer active={active} storyId={storyId}>
<DocsContainer active={active} >
<Title>Component controls blocks</Title>
<Playground openTab="source" title=".">
<Story id="." />
Expand All @@ -18,8 +18,8 @@ const Page = ({ active, storyId }) => {
const page: CustomPageDef = {
key: 'component-page',
title: 'Controls blocks',
render: ({ active, storyId }) => {
return <Page storyId={storyId} active={active} />;
render: ({ active }) => {
return <Page active={active} />;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Page = () => {
const page: CustomPageDef = {
key: 'docs-page',
title: 'Docs blocks',
render: ({ active, storyId }) => {
render: ({ active }) => {
return active ? <Page /> : null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { Story, Title, Playground, PropsTable } from '@component-controls/block
import { CustomPageDef } from '@component-controls/storybook-custom-docs';


const Page = ({ storyId: id }) => {
const storyId = useStoryId(id);
const Page = () => {
const storyId = useStoryId();
return (
<>
<SBDocsContainer context={getContext()}>
Expand All @@ -30,8 +30,8 @@ const Page = ({ storyId: id }) => {
const page: CustomPageDef = {
key: 'mixed-page',
title: 'Mixed blocks',
render: ({ active, storyId }) => {
return active ? <Page storyId={storyId} /> : null;
render: ({ active }) => {
return active ? <Page /> : null;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from 'react';
import { CustomPageDef } from '@component-controls/storybook-custom-docs';
import { CustomPageDef, useStoryId } from '@component-controls/storybook-custom-docs';

const CustomPage: React.FC = () => {
const storyId = useStoryId();
return <div><h1>Simple docs page</h1><p>{storyId}</p></div>
}
const page: CustomPageDef = {
key: 'custom',
title: 'Simple Page',
render: ({ active, storyId }) => active ? <div><h1>Simple docs page</h1><p>{storyId}</p></div> : null,
render: ({ active }) => active ? <CustomPage /> : null,
}

export default page;
2 changes: 1 addition & 1 deletion integrations/storybook/src/context/BlockContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const BlockContextProvider: React.FC<BlockContextProviderProps> = ({
children,
id,
}) => {
const defaultStoyId = useStoryId(id);
const defaultStoyId = useStoryId();
const storyId = id ? id : defaultStoyId;
return (
<BlocksContextProvider storyId={storyId}>{children}</BlocksContextProvider>
Expand Down
13 changes: 3 additions & 10 deletions integrations/storybook/src/docs-page/DocsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import {
import { useStoryId } from '@component-controls/storybook-custom-docs';
import { useIsDark } from '../context/useIsDark';

export const PageContextContainer: FC<PageContainerProps> = ({
children,
storyId: defaultStoryId,
}) => {
const storyId = useStoryId(defaultStoryId);
export const PageContextContainer: FC<PageContainerProps> = ({ children }) => {
const storyId = useStoryId();
const isDark = useIsDark();
return (
<BlockPageContainer dark={isDark} storyId={storyId}>
Expand All @@ -22,8 +19,4 @@ export const PageContextContainer: FC<PageContainerProps> = ({
export const DocsContainer: FC<PageContainerProps & { active?: boolean }> = ({
children,
active = true,
storyId,
}) =>
active ? (
<PageContextContainer storyId={storyId}>{children}</PageContextContainer>
) : null;
}) => (active ? <PageContextContainer>{children}</PageContextContainer> : null);
4 changes: 2 additions & 2 deletions integrations/storybook/src/docs-page/full-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { ControlsPage } from './ControlsPage';
export default {
key: 'page',
title: 'Page',
render: ({ active, storyId }: { active: boolean; storyId: string }) => {
render: ({ active }: { active: boolean }) => {
return (
<DocsContainer active={active} storyId={storyId}>
<DocsContainer active={active}>
<ControlsPage />
</DocsContainer>
);
Expand Down
1 change: 0 additions & 1 deletion misc/storybook-custom-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
},
"license": "MIT",
"dependencies": {
"broadcast-channel": "^3.1.0",
"react": "^16.12.0",
"react-dom": "^16.12.0"
},
Expand Down
78 changes: 25 additions & 53 deletions misc/storybook-custom-docs/src/components/ManagerContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,39 @@
import React from 'react';
import { BroadcastChannel } from 'broadcast-channel';
import { API } from '@storybook/api';

interface ManagerContainerProps {
active?: boolean;
id: string;
api: API;
route: string;
title: string;
}
const activePages: string[] = [];
export const ManagerContainer: React.FC<ManagerContainerProps> = ({
active,
id,
api,
title,
}) => {
const channel = React.useMemo(
() =>
new BroadcastChannel(`attach_docs_page_${title}`, {
type: 'localstorage',
}),
[],
);

export const ManagerContainer: React.FC<ManagerContainerProps> = props => {
const { active, api, route } = props;
const ATTACH_DOCS_PAGE = `attach_docs_page_${route}`;
const REQUEST_DOCS_PAGE = `request_docs_page_${route}`;
const channel = React.useMemo(() => api.getChannel(), []);
const sendMessage = () => {
const story = api.getCurrentStoryData();
channel.emit(ATTACH_DOCS_PAGE, { active, storyId: story?.id });
};

React.useEffect(() => {
const iframe = document.getElementById(
'storybook-preview-iframe',
) as HTMLIFrameElement;
const wrapper = document.getElementById('storybook-preview-wrapper');
if (iframe && iframe.contentDocument) {
const updateDOM = () => {
const story = api.getCurrentStoryData();
channel.postMessage({ id: id, active, storyId: story?.id });
const root = iframe?.contentDocument?.getElementById('root');
if (wrapper && root) {
const pageIndex = activePages.indexOf(id);
if (active) {
if (pageIndex < 0) {
activePages.push(id);
}
root.style.setProperty('display', 'none');
wrapper.removeAttribute('hidden');
} else if (pageIndex >= 0) {
activePages.splice(pageIndex, 1);
if (activePages.length === 0) {
root.style.removeProperty('display');
}
}
}
};

if (!iframe.contentDocument.getElementById('root')) {
const saveOnLoad = iframe.onload;
iframe.onload = e => {
updateDOM();
if (saveOnLoad) {
//@ts-ignore
saveOnLoad(e);
}
};
} else {
updateDOM();
const onRequestPage = () => {
sendMessage();
};
channel.on(REQUEST_DOCS_PAGE, onRequestPage);
const updateDOM = () => {
sendMessage();
if (wrapper) {
wrapper.removeAttribute('hidden');
}
}
};
updateDOM();
return () => {
channel.off(REQUEST_DOCS_PAGE, onRequestPage);
};
}, [active]);
return null;
};
22 changes: 19 additions & 3 deletions misc/storybook-custom-docs/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,36 @@ export const getContext = () => {
parameters,
};
};

/**
* function returning the current story id
*/
export const getCurrentStoryId = (): string | undefined => {
const selection =
window &&
//@ts-ignore
window.__STORYBOOK_CLIENT_API__ &&
//@ts-ignore
window.__STORYBOOK_CLIENT_API__.store().getSelection();
return selection ? selection.storyId : undefined;
};

/**
* React hook hook that tracks the changes to the current story and returns it's id
* @param defaultId initial story value, if not provided will return the current story
* @returns a story id as a React hook, when the the current story changes, will call back
*/
export const useStoryId = (defaultId: string = '.') => {
const [storyId, setStoryId] = React.useState<string>(defaultId);
export const useStoryId = () => {
const [storyId, setStoryId] = React.useState<string>(
getCurrentStoryId() || '.',
);
const channel = React.useMemo(() => addons.getChannel(), []);
React.useEffect(() => {
const onStoryChange = (id: string) => {
setStoryId(id);
};

channel.on(STORY_CHANGED, onStoryChange);

return () => {
channel.off(STORY_CHANGED, onStoryChange);
};
Expand Down
8 changes: 4 additions & 4 deletions misc/storybook-custom-docs/src/manager-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ module.exports.default = async function() {
route: ({ storyId }) => \`/\${key}/\${storyId}\`,
match: ({ viewMode }) => viewMode === key,
render: ({ active }) => {
return React.createElement(ManagerContainer, {
const props = {
active,
title,
id:\`controls-docs-page-\${key}\`,
route: key,
api,
});
};
return React.createElement(ManagerContainer, props);
},
});
});
Expand Down
Loading

0 comments on commit f825f53

Please sign in to comment.