From 3f1bdb1d3f373436bffb27a76a1ba92775a2800f Mon Sep 17 00:00:00 2001 From: Alan Orozco Date: Sun, 13 Feb 2022 00:36:29 -0800 Subject: [PATCH] decorators for other wrappers --- src/addon.ts | 14 ++- src/index.ts | 18 +++- .../{Wrapper.tsx => ConfigPanel.tsx} | 67 ++++++------- src/register/components/PreactDecorator.tsx | 68 ------------- src/register/components/bento.tsx | 82 ---------------- src/register/index.tsx | 4 +- src/register/wrappers.tsx | 96 ++++++++++++++++++ src/util/{amphtml.tsx => amp.tsx} | 97 ++++++++----------- src/util/bento.tsx | 63 ++++++++++++ src/util/cdn-url.ts | 12 +++ src/util/html.ts | 6 -- src/util/html.tsx | 46 +++++++++ 12 files changed, 317 insertions(+), 256 deletions(-) rename src/register/components/{Wrapper.tsx => ConfigPanel.tsx} (79%) delete mode 100644 src/register/components/PreactDecorator.tsx delete mode 100644 src/register/components/bento.tsx create mode 100644 src/register/wrappers.tsx rename src/util/{amphtml.tsx => amp.tsx} (54%) create mode 100644 src/util/bento.tsx create mode 100644 src/util/cdn-url.ts delete mode 100644 src/util/html.ts create mode 100644 src/util/html.tsx diff --git a/src/addon.ts b/src/addon.ts index c8b9cfc..d1b09aa 100755 --- a/src/addon.ts +++ b/src/addon.ts @@ -1,7 +1,15 @@ +export interface AmpParameters { + extensions?: {name: string; version: string}[]; + experiments?: string[]; +} + export const AddonName = 'storybook/amp'; -export const PanelName = AddonName + '/panel'; +export const PanelName = `${AddonName}/panel`; + export const Events = { - UpdateConfig: AddonName + '/update_config', - AskConfig: AddonName + '/ask_config', + UpdateDocumentType: `${AddonName}/update_document_type`, + UpdateConfig: `${AddonName}/update_config`, + AskConfig: `${AddonName}/ask_config`, }; + export const ParameterName = 'amp'; diff --git a/src/index.ts b/src/index.ts index 6fed622..2877976 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,27 @@ import {makeDecorator} from '@storybook/addons'; import {ParameterName} from './addon'; -import PreactDecorator from './register/components/PreactDecorator'; +import {AmphtmlWrapper, BentoWrapper, PlainWrapper} from './register/wrappers'; export const withAmp = makeDecorator({ name: 'withAmp', parameterName: ParameterName, skipIfNoParametersOrOptions: false, - wrapper: PreactDecorator, // TODO: Implement React and Vue.js deocrators + wrapper: AmphtmlWrapper, +}); + +export const withBento = makeDecorator({ + name: 'withBento', + parameterName: ParameterName, + skipIfNoParametersOrOptions: false, + wrapper: BentoWrapper, +}); + +export const withIframe = makeDecorator({ + name: 'withIframe', + parameterName: ParameterName, + skipIfNoParametersOrOptions: false, + wrapper: PlainWrapper, }); if (module && module.hot && module.hot.decline) { diff --git a/src/register/components/Wrapper.tsx b/src/register/components/ConfigPanel.tsx similarity index 79% rename from src/register/components/Wrapper.tsx rename to src/register/components/ConfigPanel.tsx index 84c9d7e..76e1382 100755 --- a/src/register/components/Wrapper.tsx +++ b/src/register/components/ConfigPanel.tsx @@ -15,7 +15,7 @@ import {SourceSelect} from './SourceSelect'; import {ScrollArea, Form} from '@storybook/components'; import {useParameter} from '@storybook/api'; -import {Events, ParameterName} from '../../addon'; +import {Events} from '../../addon'; import { Config, SOURCE_BASE_URL, @@ -53,8 +53,13 @@ const HorizontalFormFields = styled.div({ }, }); -export const Wrapper: FunctionComponent = ({active, api, channel}) => { +export const ConfigPanel: FunctionComponent = ({ + active, + api, + channel, +}) => { const [config, setConfig] = useState(getPersistedConfig); + const [documentType, setDocumentType] = useState(); const configRef = useRef(config); configRef.current = config; const ampBaseUrlOptions = useParameter('ampBaseUrlOptions', []); @@ -75,10 +80,12 @@ export const Wrapper: FunctionComponent = ({active, api, channel}) => { channel.on(STORY_CHANGED, onStoryChanged); channel.on(Events.AskConfig, onStoryChanged); + channel.on(Events.UpdateDocumentType, setDocumentType); return () => { channel.removeListener(STORY_CHANGED, onStoryChanged); channel.removeListener(Events.AskConfig, onStoryChanged); + channel.removeListener(Events.UpdateDocumentType, setDocumentType); }; }, []); @@ -126,44 +133,30 @@ export const Wrapper: FunctionComponent = ({active, api, channel}) => { /> - - { - updateConfig({...config, binary: e.target.value}); - }} - size="flex" - > - - - - - - { - updateConfig({...config, mode: e.target.value}); - }} - size="flex" - > - - - - + {/* BentoWrapper uses nomodule/module at the same time */} + {documentType !== 'bento' && ( + + { + updateConfig({...config, binary: e.target.value}); + }} + size="flex" + > + + + + + )} ); }; -export default Wrapper; +export default ConfigPanel; diff --git a/src/register/components/PreactDecorator.tsx b/src/register/components/PreactDecorator.tsx deleted file mode 100644 index e5a137d..0000000 --- a/src/register/components/PreactDecorator.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/** @jsx h */ -import {h} from 'preact'; -import {renderToString as preactRenderToString} from 'preact-render-to-string'; -import {useEffect, useRef, useState} from '@storybook/client-api'; -import addons, {StoryWrapper} from '@storybook/addons'; -import {Events} from '../../addon'; -import {Config, defaultConfig, sameConfig} from '../../util/config'; -import {useBentoMode} from './bento'; -import {wrapAmpHtml} from '../../util/amphtml'; - -export const Decorator: StoryWrapper = (getStory, context, {parameters}) => { - const [config, setConfig] = useState(defaultConfig); - const configRef = useRef(config); - configRef.current = config; - - useEffect(() => { - const channel = addons.getChannel(); - channel.emit(Events.AskConfig); - - const onUpdatedConfig = (config) => { - if (!sameConfig(config, configRef.current)) { - setConfig(config); - } - }; - channel.on(Events.UpdateConfig, onUpdatedConfig); - return () => { - channel.removeListener(Events.UpdateConfig, onUpdatedConfig); - }; - }, []); - - const tree = getStory(context) as preact.VNode; - const html = wrapAmpHtml(tree, config, context); - const ref = useRef(null); - - // TODO(alanorozco): Figure out this `useBentoMode` business. This is not - // used on amphtml's config of the addon. - useBentoMode(ref, config, html, getStory, context); - if (config.mode === 'bento') { - // Preact mode, unfortunately, completely rerenders the content - // (e.g. iframe), which forces the reload making it impossible to test - // Bento mode. Thus, this code only renders the placeholder element and - // the iframe is created and reused in the `useBentoMode`. - // See https://github.com/storybookjs/storybook/issues/12177 - return
; - } - - // ampdoc mode: reload the iframe. - const contents = preactRenderToString(tree); - const fullContent = html.replace('', contents); - const blob = new Blob([fullContent], {type: 'text/html'}); - return ( -