UNPKG

@storybook/addon-designs

Version:

Storybook addon for embedding your design preview in addon panel

1 lines 49.3 kB
{"version":3,"sources":["../src/manager/components/IFrame.tsx","../src/manager/components/Figma.tsx","../src/manager/components/Figspec.tsx","../src/blocks.tsx","../src/manager/components/Image.tsx","../src/manager/components/Pan.tsx","../src/manager/components/hooks/usePan.ts","../src/manager/components/ZoomButtons.tsx","../src/manager/components/hooks/useZoom.ts","../src/manager/components/Wrapper.tsx","../src/manager/components/LinkPanel.tsx","../src/manager/components/Sketch.tsx","../src/manager/components/Tabs.tsx","../src/constants.ts"],"names":["useEffect","useState","css","jsx","Placeholder","IFrame","$container","$loading","$iframe","init_IFrame","__esmMin","config","defer","url","setUrl","loaded","setLoaded","handle","useMemo","figmaURLPattern","isFigmaURL","Figma","init_Figma","iframeConfig","Figspec_exports","__export","Figspec","Figspec_default","Fragment","FigspecFileViewer","FigspecFrameViewer","unwrapJson","res","getAccessToken","cfg","listAllFrames","node","a","b","fullscreen","init_Figspec","state","setState","fetchDetails","signal","match","fileKey","nodeId","accessToken","headers","nodeUrl","imageUrl","documentNode","resp","frames","frame","images","nodes","err","fulfilled","fulfil","ac","React","ActionBar","styled","useOf","FlexBar","Separator","useCallback","usePan","cb","deps","lastPosition","savePosition","isPanning","setPanState","onMouseDown","ev","onTouchStart","touch","move","p","prev","onMouseMove","screenX","screenY","onTouchMove","clear","Pan","children","className","style","defaultValue","value","onChange","offset","panHandlers","delta","transform","vec","$transformLayer","IconButton","Icons","ZoomButtons","onZoomIn","onZoomOut","onReset","useZoom","initialValue","scale","setScale","zoomIn","prevScale","zoomOut","resetZoom","ImagePreview","zoom","imageStyles","$preview","$image","lazy","Suspense","Link","LinkPanel","v1UrlParser","malformedUrlErrorMessage","pathSegments","s","sid","aid","Sketch","result","parsed","SbTabs","Tabs","tabs","selected","setSelected","tab","Wrapper","meta","AddonName","PanelName","Events","ParameterName","ResetWrapper","theme","height","collapsed","CollapsedText","DocBlockBase","collapsable","defaultCollapsed","placeholder","showLink","onCollapsedChange","rest","setCollapsed","showOpenInNewTab","newValue","props","Image","AbsoluteLocater","Design","of","story"],"mappings":"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","sourcesContent":["/** @jsx jsx */\nimport { FC, ReactNode, useEffect, useState } from \"react\";\nimport { css, jsx } from \"@storybook/theming\";\n\nimport { Placeholder } from \"@storybook/components\";\n\nimport { IFrameConfigBase } from \"../../config\";\n\ninterface Props {\n config: IFrameConfigBase;\n\n /**\n * Whether to defer loading iframe contents\n * @default false\n */\n defer?: boolean;\n}\n\nexport const IFrame: FC<Props> = ({ config, defer = false }) => {\n const [url, setUrl] = useState(defer ? undefined : config.url);\n const [loaded, setLoaded] = useState(false);\n\n // Defer loading iframe URL.\n // Some sites (e.g. Figma) detects Fullscreen API capability on\n // initial load. This is quite common implementation. But in our usage,\n // it seems that React hold the created <iframe> element when update,\n // and it causes \"outdated Fullscreen capability\" problem.\n // This might be a browser bug that \"`fullscreenEnabled` property does not\n // updated\" but I'm not sure what the correct behavior (I couldn't see the\n // statement in the Fulscreen API spec).\n // This side-effect delays the loading of an iframe contents by one frame to\n // make sure the contents gets updated attributes.\n // https://github.com/storybookjs/addon-designs/issues/77\n useEffect(() => {\n if (!defer) {\n return;\n }\n\n const handle = requestAnimationFrame(() => {\n setUrl(config.url);\n });\n\n return () => cancelAnimationFrame(handle);\n }, [defer, config.url]);\n\n useEffect(() => {\n setLoaded(false);\n }, [url]);\n\n return (\n <div css={$container}>\n {!loaded && (\n // @ts-expect-error: @types resolution is completely broken probably due to migration to npm workspace\n <Placeholder css={$loading}>Loading...</Placeholder>\n )}\n <iframe\n css={$iframe}\n src={url}\n allowFullScreen={config.allowFullscreen}\n onLoad={() => setLoaded(true)}\n />\n </div>\n );\n};\n\nexport default IFrame;\n\nconst $container = css`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n\n overflow: hidden;\n`;\n\nconst $loading = css`\n position: absolute;\n top: 50%;\n left: 50%;\n\n transform: translate(-50%, -50%);\n`;\n\nconst $iframe = css`\n position: relative;\n width: 100%;\n height: 100%;\n border: none;\n\n z-index: 1;\n`;\n","/** @jsx jsx */\nimport { FC, useMemo } from \"react\";\nimport { jsx } from \"@storybook/theming\";\n\nimport { IFrame } from \"./IFrame\";\n\nimport { FigmaConfig, IFrameConfigBase } from \"../../config\";\n\nexport const figmaURLPattern =\n /https:\\/\\/[\\w.-]+\\.?figma.com\\/([\\w-]+)\\/([0-9a-zA-Z]{22,128})(?:\\/.*)?$/;\n\nexport const isFigmaURL = (url: string) => figmaURLPattern.test(url);\n\ninterface Props {\n config: FigmaConfig;\n}\n\nexport const Figma: FC<Props> = ({ config }) => {\n const iframeConfig = useMemo<IFrameConfigBase>(() => {\n const isValid = isFigmaURL(config.url);\n\n if (!isValid) {\n console.warn(\n \"[storybook-addon-designs] \" +\n \"The URL you specified is not valid Figma URL.\\n\" +\n \"The addon fallbacks to normal iframe mode.\" +\n \"For more detail, please check <https://www.figma.com/developers/embed>.\",\n );\n return config;\n }\n\n const embedHost = config.embedHost || location.hostname;\n const url = `https://www.figma.com/embed?embed_host=${embedHost}&url=${config.url}`;\n\n return {\n url,\n allowFullscreen: config.allowFullscreen,\n };\n }, [config.url, config.allowFullscreen, config.embedHost]);\n\n return <IFrame defer config={iframeConfig} />;\n};\n","/** @jsx jsx */\nimport type {\n FileResponse,\n FileNodesResponse,\n FileImageResponse,\n Node,\n} from \"figma-js\";\nimport { FC, Fragment, useEffect, useMemo, useState } from \"react\";\nimport {\n FigspecFileViewer,\n FigspecFileViewerProps,\n FigspecFrameViewer,\n FigspecFrameViewerProps,\n} from \"@figspec/react\";\nimport { Placeholder } from \"@storybook/components\";\nimport { css, jsx } from \"@storybook/theming\";\n\nimport { FigspecConfig } from \"../../config\";\n\nimport { figmaURLPattern } from \"./Figma\";\n\nconst fullscreen = css`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n`;\n\ntype RenderItem =\n | {\n type: \"file\";\n props: Pick<\n FigspecFileViewerProps,\n \"documentNode\" | \"renderedImages\" | \"link\"\n >;\n }\n | {\n type: \"frame\";\n props: Pick<FigspecFrameViewerProps, \"nodes\" | \"renderedImage\" | \"link\">;\n };\n\ntype Remote<T, E = Error> =\n | {\n state: \"fetched\";\n value: T;\n }\n | {\n state: \"failed\";\n error: E;\n }\n | {\n state: \"loading\";\n };\n\nfunction unwrapJson<T>(res: Response): Promise<T> {\n return res.status !== 200\n ? Promise.reject(res.statusText)\n : (res.json() as Promise<T>);\n}\n\n/**\n * Safely get Figma API access token.\n */\nfunction getAccessToken(cfg: FigspecConfig): string | null {\n if (cfg.accessToken) {\n return cfg.accessToken;\n }\n\n try {\n return process.env.STORYBOOK_FIGMA_ACCESS_TOKEN ?? null;\n } catch (err) {\n // The only case here is no DefinePlugin entry for `process.env` nor\n // `process.env.STORYBOOK_FIGMA_ACCESS_TOKEN`. We can safely ignore this.\n return null;\n }\n}\n\ninterface Props {\n config: FigspecConfig;\n}\n\nexport const Figspec: FC<Props> = ({ config }) => {\n const [state, setState] = useState<Remote<RenderItem, string>>({\n state: \"loading\",\n });\n\n const fetchDetails = async (signal: AbortSignal) => {\n setState({ state: \"loading\" });\n\n try {\n const match = config.url.match(figmaURLPattern);\n\n if (!match) {\n throw new Error(config.url + \" is not a valid Figma URL.\");\n }\n\n const [, , fileKey] = match;\n\n const url = new URL(config.url);\n\n const nodeId = url.searchParams.get(\"node-id\");\n\n const accessToken = getAccessToken(config);\n\n if (!accessToken) {\n throw new Error(\"Personal Access Token is required.\");\n }\n\n const headers = {\n \"X-FIGMA-TOKEN\": accessToken,\n };\n\n const nodeUrl = new URL(`https://api.figma.com/v1/files/${fileKey}`);\n const imageUrl = new URL(`https://api.figma.com/v1/images/${fileKey}`);\n\n imageUrl.searchParams.set(\"format\", \"svg\");\n\n if (!nodeId) {\n const documentNode = await fetch(nodeUrl.href, {\n headers,\n signal,\n }).then((resp) => unwrapJson<FileResponse>(resp));\n\n const frames = listAllFrames(documentNode.document);\n\n imageUrl.searchParams.set(\n \"ids\",\n frames.map((frame) => frame.id).join(\",\"),\n );\n\n const images = await fetch(imageUrl.href, {\n headers,\n signal,\n }).then((resp) => unwrapJson<FileImageResponse>(resp));\n\n setState({\n state: \"fetched\",\n value: {\n type: \"file\",\n props: {\n documentNode,\n renderedImages: images.images,\n link: config.url,\n },\n },\n });\n return;\n }\n\n nodeUrl.pathname += \"/nodes\";\n\n nodeUrl.searchParams.set(\"ids\", nodeId);\n imageUrl.searchParams.set(\"ids\", nodeId);\n\n const [nodes, images] = await Promise.all([\n fetch(nodeUrl.href, {\n headers,\n signal,\n }).then((resp) => unwrapJson<FileNodesResponse>(resp)),\n fetch(imageUrl.href, { headers, signal }).then((resp) =>\n unwrapJson<FileImageResponse>(resp),\n ),\n ]);\n\n setState({\n state: \"fetched\",\n value: {\n type: \"frame\",\n props: {\n nodes,\n renderedImage: Object.values<string>(images.images)[0],\n link: config.url,\n },\n },\n });\n } catch (err) {\n if (err instanceof DOMException && err.code === DOMException.ABORT_ERR) {\n return;\n }\n\n console.error(err);\n\n setState({\n state: \"failed\",\n error: err instanceof Error ? err.message : String(err),\n });\n }\n };\n\n useEffect(() => {\n let fulfilled = false;\n const fulfil = () => {\n fulfilled = true;\n };\n\n const ac = new AbortController();\n\n fetchDetails(ac.signal).then(fulfil, fulfil);\n\n return () => {\n if (!fulfilled) {\n ac.abort();\n }\n };\n }, [config.url]);\n\n switch (state.state) {\n case \"loading\":\n return (\n <Placeholder>\n <Fragment>Loading Figma file...</Fragment>\n </Placeholder>\n );\n case \"failed\":\n return (\n <Placeholder>\n <Fragment>Failed to load Figma file</Fragment>\n <Fragment>{state.error}</Fragment>\n </Placeholder>\n );\n case \"fetched\":\n return state.value.type === \"file\" ? (\n <FigspecFileViewer css={fullscreen} {...state.value.props} />\n ) : (\n <FigspecFrameViewer css={fullscreen} {...state.value.props} />\n );\n }\n};\n\nexport default Figspec;\n\nfunction listAllFrames(node: Node): Node[] {\n if (\"absoluteBoundingBox\" in node) {\n return [node];\n }\n\n if (!node.children || node.children.length === 0) {\n return [];\n }\n\n return node.children.map(listAllFrames).reduce((a, b) => a.concat(b), []);\n}\n","import React, { useState } from \"react\";\nimport type { CSSProperties, FC } from \"react\";\nimport { ActionBar, Placeholder } from \"@storybook/components\";\nimport { styled } from \"@storybook/theming\";\nimport { useOf, Of } from \"@storybook/blocks\";\n\nimport { Figma as FigmaInternal } from \"./manager/components/Figma\";\nimport { Figspec as FigspecInternal } from \"./manager/components/Figspec\";\nimport { IFrame as IFrameInternal } from \"./manager/components/IFrame\";\nimport { ImagePreview } from \"./manager/components/Image\";\nimport { Wrapper as WrapperInternal } from \"./manager/components/Wrapper\";\n\nimport * as config from \"./config\";\nimport { ParameterName } from \"./constants\";\n\n// Since the exports of `@storybook/components` is unstable, I couldn't manage\n// to import the `components.resetWrapper` while maintaining version requirements.\n// This component does similar to the official one at minimum.\n// https://github.com/storybookjs/storybook/blob/4bd2fc9b0677190c59e60fd63841294ab88e80c5/lib/components/src/typography/DocumentFormatting.tsx#L364-L372\n// https://github.com/storybookjs/storybook/blob/4bd2fc9b0677190c59e60fd63841294ab88e80c5/lib/components/src/typography/shared.tsx#L42-L51\nconst ResetWrapper = styled.div(\n ({ theme }) => `\n font-family: ${theme.typography.fonts.base};\n font-size: ${theme.typography.size.s3}px;\n margin: 0;\n`,\n);\n\nconst Wrapper = styled.div<BlocksCommonProps & { collapsed: boolean }>(\n ({ theme, height = \"60%\", collapsed }) => `\n position: relative;\n width: 100%;\n height: 0;\n padding: 0;\n padding-top: ${\n collapsed ? \"3em\" : typeof height == \"string\" ? height : height + \"px\"\n };\n margin: 25px 0 40px;\n border: 1px solid ${theme.appBorderColor};\n\n border-radius: ${theme.appBorderRadius}px;\n box-shadow:\n ${\n theme.base === \"light\"\n ? \"rgba(0, 0, 0, 0.10) 0 1px 3px 0\"\n : \"rgba(0, 0, 0, 0.20) 0 2px 5px 0\"\n };\n`,\n);\n\nconst CollapsedText = styled(Placeholder)`\n position: absolute;\n top: 50%;\n left: 50%;\n\n transform: translate(-50%, -50%);\n`;\n\nexport interface BlocksCommonProps {\n /**\n * **Doc Block Props**\n *\n * A `class` prop passed down to embed wrapper.\n */\n className?: string;\n /**\n * **Doc Block Props**\n *\n * A `style` passed down to embed wrapper.\n */\n style?: CSSProperties;\n\n /**\n * **Doc Block Props**\n *\n * Height of the block. Numbers will be converted into pixels.\n * Relative value (%) is based on width of the block.\n */\n height?: string | number;\n\n /**\n * **Doc Block Props**\n *\n * Whether to allow the block to toggle collapse/expand.\n * @default true\n */\n collapsable?: boolean;\n\n children?: React.ReactNode;\n\n /**\n * **Doc Block Props**\n *\n * Render the block with collapsed initially?\n * Available when `collapsable` is set to `true`.\n * @default false\n */\n defaultCollapsed?: boolean;\n\n /**\n * **Doc Block Props**\n *\n * Placeholder text shown when the block is collapsed.\n * Default value differs by a type of the block (e.g. \"Design (Figma)\").\n */\n placeholder?: string;\n\n /**\n * **Doc Block Props**\n *\n * Whether to show an \"Open in new tab\" button.\n * @default true\n */\n showLink?: boolean;\n\n /**\n * **Doc Block Props**\n *\n * Will be called when a user changed collapse/expand state of the block.\n */\n onCollapsedChange?(newValue: boolean, oldValue: boolean): void;\n}\n\nexport const DocBlockBase: FC<BlocksCommonProps> = ({\n children,\n collapsable = true,\n defaultCollapsed = false,\n placeholder,\n showLink = true,\n onCollapsedChange,\n ...rest\n}) => {\n const [collapsed, setCollapsed] = useState(!!defaultCollapsed);\n\n const showOpenInNewTab = showLink && \"url\" in rest;\n\n return (\n <ResetWrapper>\n <Wrapper collapsed={collapsable && collapsed} {...rest}>\n {collapsable && collapsed ? (\n <CollapsedText>{placeholder}</CollapsedText>\n ) : (\n children\n )}\n <ActionBar\n actionItems={[\n collapsable && {\n title: collapsed ? \"Show\" : \"Hide\",\n onClick: () => {\n const newValue = !collapsed;\n if (onCollapsedChange) onCollapsedChange(newValue, collapsed);\n setCollapsed(newValue);\n },\n },\n showOpenInNewTab && {\n title: \"Open in new tab\",\n onClick: () => window.open((rest as any).url, \"_blank\"),\n },\n ].filter((s): s is Exclude<typeof s, false> => !!s)}\n />\n </Wrapper>\n </ResetWrapper>\n );\n};\n\nexport const Figma: FC<\n Omit<config.FigmaConfig, \"type\"> & BlocksCommonProps\n> = ({ placeholder, ...props }) => (\n <DocBlockBase placeholder={placeholder ?? \"Design (Figma)\"} {...props}>\n <FigmaInternal config={{ type: \"figma\", ...props }} />\n </DocBlockBase>\n);\n\nexport const Figspec: FC<\n Omit<config.FigspecConfig, \"type\"> & BlocksCommonProps\n> = ({ placeholder, ...props }) => {\n return (\n <DocBlockBase placeholder={placeholder ?? \"Design (Figma-Spec)\"} {...props}>\n <FigspecInternal config={{ type: \"figspec\", ...props }} />\n </DocBlockBase>\n );\n};\n\nexport const IFrame: FC<\n Omit<config.IFrameConfig, \"type\"> & BlocksCommonProps\n> = ({ placeholder, ...props }) => (\n <DocBlockBase placeholder={placeholder ?? \"Design (iframe)\"} {...props}>\n <IFrameInternal config={props} />\n </DocBlockBase>\n);\n\n// Image would do shadowing the native variable (Image constructor, which creates\n// HTMLImageElement), but I think it doesn't matter since there is less chance to\n// use Image constructor in MDX.\nexport const Image: FC<\n Omit<config.ImageConfig, \"type\"> & BlocksCommonProps\n> = ({ placeholder, ...props }) => (\n <DocBlockBase placeholder={placeholder ?? \"Design (Image)\"} {...props}>\n <ImagePreview config={{ type: \"image\", ...props }} />\n </DocBlockBase>\n);\n\nconst AbsoluteLocater = styled.div`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n\n overflow: auto;\n`;\n\nexport interface DesignProps {\n /**\n * A reference to a story that has `design` parameter to use for rendering.\n */\n of: Of;\n}\n\nexport const Design: FC<DesignProps & Omit<BlocksCommonProps, \"showLink\">> = (\n props,\n) => {\n const { of, placeholder, ...rest } = props;\n\n if (\"of\" in props && of === undefined) {\n // MDX isn't always type-safe, it's often that users mistype their imports\n throw new Error(\n \"Unexpected `of={undefined}`, did you mistype a CSF file reference?\",\n );\n }\n\n const { story } = useOf(of || \"story\", [\"story\"]);\n\n return (\n <DocBlockBase placeholder={placeholder ?? \"Design\"} {...rest}>\n <AbsoluteLocater>\n <WrapperInternal config={story.parameters[ParameterName]} />\n </AbsoluteLocater>\n </DocBlockBase>\n );\n};\n","/** @jsx jsx */\nimport { Fragment, useMemo, CSSProperties, FC } from \"react\";\nimport { css, jsx } from \"@storybook/theming\";\n\nimport { FlexBar, Separator } from \"@storybook/components\";\n\nimport { Pan } from \"./Pan\";\nimport { ZoomButtons } from \"./ZoomButtons\";\n\nimport { ImageConfig } from \"../../config\";\n\nimport { useZoom } from \"./hooks/useZoom\";\n\ninterface Props {\n config: ImageConfig;\n}\n\nexport const ImagePreview: FC<Props> = ({ config }) => {\n const zoom = useZoom(config.scale || 1, [config.scale]);\n\n const imageStyles = useMemo<CSSProperties>(\n () => ({\n transform: `scale(${zoom.scale})`,\n }),\n [zoom.scale],\n );\n\n return (\n <div css={$container}>\n <FlexBar border>\n <Fragment key=\"left\">\n <p>\n <b>Image</b>\n </p>\n <Separator />\n <ZoomButtons\n onReset={zoom.resetZoom}\n onZoomIn={zoom.zoomIn}\n onZoomOut={zoom.zoomOut}\n />\n </Fragment>\n </FlexBar>\n <Pan css={$preview} defaultValue={config.offset}>\n <img css={$image} src={config.url} style={imageStyles} />\n </Pan>\n </div>\n );\n};\n\nexport default ImagePreview;\n\nconst $container = css`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n`;\n\nconst $preview = css`\n flex-grow: 1;\n`;\n\nconst $image = css`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n margin: auto;\n\n pointer-events: none;\n border-radius: 1px;\n box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.15);\n`;\n","/** @jsx jsx */\nimport {\n useEffect,\n useMemo,\n useState,\n CSSProperties,\n FC,\n ReactNode,\n} from \"react\";\nimport { css, jsx } from \"@storybook/theming\";\n\nimport { usePan, Point2D } from \"./hooks/usePan\";\n\ninterface Props {\n children: ReactNode;\n\n className?: string;\n style?: CSSProperties;\n\n defaultValue?: Point2D;\n\n value?: Point2D;\n\n onChange?(delta: Point2D): any;\n}\n\nexport const Pan: FC<Props> = ({\n children,\n className,\n style,\n defaultValue,\n value,\n onChange,\n}) => {\n const [offset, move] = useState<Point2D>([0, 0]);\n\n useEffect(() => {\n if (defaultValue) {\n move(defaultValue);\n } else {\n move(value || [0, 0]);\n }\n }, [defaultValue]);\n\n const panHandlers = usePan(\n (delta) => {\n if (onChange) {\n onChange(delta);\n }\n\n move((prev) => [prev[0] + delta[0], prev[1] + delta[1]]);\n },\n [move, onChange],\n );\n\n const transform = useMemo<CSSProperties>(() => {\n const vec = value || offset;\n\n return {\n transform: `translate(${vec[0]}px, ${vec[1]}px)`,\n };\n }, [value, offset]);\n\n return (\n <div css={$container} className={className} style={style} {...panHandlers}>\n <div css={$transformLayer} style={transform}>\n {children}\n </div>\n </div>\n );\n};\n\nexport default Pan;\n\nconst $container = css`\n position: relative;\n overflow: hidden;\n\n &:active {\n cursor: move;\n }\n`;\n\nconst $transformLayer = css`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n`;\n","import {\n useCallback,\n useState,\n DependencyList,\n MouseEventHandler,\n TouchEventHandler,\n} from \"react\";\n\nexport type Point2D = [number, number];\n\ninterface PanController {\n onMouseDown: MouseEventHandler;\n onMouseMove: MouseEventHandler;\n onMouseUp: MouseEventHandler;\n onMouseLeave: MouseEventHandler;\n onTouchStart: TouchEventHandler;\n onTouchMove: TouchEventHandler;\n onTouchCancel: TouchEventHandler;\n onTouchEnd: TouchEventHandler;\n}\n\n/**\n * Emulate MouseEvent.movementX and MouseEvent.movementY(Candidate Recommendation)\n * Needed due to lack of support in Safari\n */\ntype UsePan = (\n cb: (movement: Point2D) => any,\n deps: DependencyList,\n) => PanController;\n\nexport const usePan: UsePan = (cb, deps) => {\n const [lastPosition, savePosition] = useState<Point2D>([0, 0]);\n const [isPanning, setPanState] = useState<boolean>(false);\n\n const onMouseDown = useCallback<PanController[\"onMouseDown\"]>(\n (ev) => {\n // Ensure to turn on pan mode only for main button down\n if (ev.button !== 0) {\n return;\n }\n\n savePosition([ev.screenX, ev.screenY]);\n setPanState(true);\n },\n [setPanState, savePosition],\n );\n\n const onTouchStart = useCallback<PanController[\"onTouchStart\"]>(\n (ev) => {\n const touch = ev.touches[0];\n\n savePosition([touch.screenX, touch.screenY]);\n setPanState(true);\n },\n [setPanState, savePosition],\n );\n\n const move = useCallback(\n (p: Point2D) => {\n if (!isPanning) {\n return;\n }\n\n savePosition((prev) => {\n cb([p[0] - prev[0], p[1] - prev[1]]);\n\n return p;\n });\n },\n [savePosition, isPanning, ...deps],\n );\n\n const onMouseMove = useCallback<PanController[\"onMouseMove\"]>(\n (ev) => {\n const { screenX, screenY } = ev;\n\n move([screenX, screenY]);\n },\n [move],\n );\n\n const onTouchMove = useCallback<PanController[\"onTouchMove\"]>(\n (ev) => {\n const { screenX, screenY } = ev.touches[0];\n\n move([screenX, screenY]);\n },\n [savePosition, isPanning, ...deps],\n );\n\n const clear = useCallback(() => {\n savePosition([0, 0]);\n setPanState(false);\n }, [setPanState, savePosition]);\n\n return {\n onMouseDown,\n onMouseMove,\n onMouseUp: clear,\n onMouseLeave: clear,\n onTouchStart,\n onTouchMove,\n onTouchCancel: clear,\n onTouchEnd: clear,\n };\n};\n","/** @jsx jsx */\nimport { Fragment, FC } from \"react\";\nimport { jsx } from \"@storybook/theming\";\n\nimport { IconButton, Icons } from \"@storybook/components\";\n\ninterface Props {\n onZoomIn?(): any;\n onZoomOut?(): any;\n onReset?(): any;\n}\n\nexport const ZoomButtons: FC<Props> = ({ onZoomIn, onZoomOut, onReset }) => (\n <Fragment>\n <IconButton onClick={onZoomIn}>\n <Icons icon=\"zoom\" />\n </IconButton>\n <IconButton onClick={onZoomOut}>\n <Icons icon=\"zoomout\" />\n </IconButton>\n <IconButton onClick={onReset}>\n <Icons icon=\"zoomreset\" />\n </IconButton>\n </Fragment>\n);\n\nexport default ZoomButtons;\n","import { useCallback, useEffect, useState, DependencyList } from \"react\";\n\ntype UseZoom = (\n initialValue: number,\n deps: DependencyList,\n) => {\n /**\n * Current scale factor.\n * 0.0 < n < Infinity\n */\n scale: number;\n\n /**\n * Zoom in\n */\n zoomIn(): void;\n\n /**\n * Zoom out\n */\n zoomOut(): void;\n\n /**\n * Reset scale factor to 1.\n */\n resetZoom(): void;\n};\n\nexport const useZoom: UseZoom = (initialValue, deps) => {\n const [scale, setScale] = useState<number>(1);\n\n useEffect(() => {\n setScale(initialValue);\n }, deps);\n\n const zoomIn = useCallback(() => {\n setScale((prevScale) => prevScale + 0.1);\n }, [setScale]);\n\n const zoomOut = useCallback(() => {\n setScale((prevScale) => Math.max(prevScale - 0.1, 0.1));\n }, [setScale]);\n\n const resetZoom = useCallback(() => {\n setScale(1);\n }, [setScale]);\n\n return { scale, zoomIn, zoomOut, resetZoom };\n};\n","/** @jsx jsx */\nimport { Fragment, lazy, Suspense, FC } from \"react\";\nimport { jsx } from \"@storybook/theming\";\n\nimport { Link, Placeholder } from \"@storybook/components\";\n\nimport { Config } from \"../../config\";\n\nimport { Figma } from \"./Figma\";\nimport { IFrame } from \"./IFrame\";\nimport { ImagePreview } from \"./Image\";\nimport { LinkPanel } from \"./LinkPanel\";\nimport { Sketch } from \"./Sketch\";\nimport { Tab, Tabs } from \"./Tabs\";\n\nconst Figspec = lazy(() => import(\"./Figspec\"));\n\ninterface Props {\n config?: Config | Config[];\n}\n\nexport const Wrapper: FC<Props> = ({ config }) => {\n if (!config || (\"length\" in config && config.length === 0)) {\n return (\n <Placeholder>\n <Fragment>No designs found</Fragment>\n <Fragment>\n Learn how to{\" \"}\n <Link\n href=\"https://github.com/storybookjs/addon-designs#3-add-it-to-story\"\n target=\"_blank\"\n rel=\"noopener\"\n withArrow\n cancel={false}\n >\n display design preview for the story\n </Link>\n </Fragment>\n </Placeholder>\n );\n }\n\n const tabs = [...(config instanceof Array ? config : [config])].map<Tab>(\n (cfg) => {\n const meta: Omit<Tab, \"content\"> = {\n id: JSON.stringify(cfg),\n name:\n cfg.name ||\n (cfg.type as Config[\"type\"] | undefined)?.toUpperCase() ||\n \"ERROR\",\n offscreen: cfg.offscreen ?? true,\n };\n\n switch (cfg.type) {\n case \"iframe\":\n return {\n ...meta,\n content: <IFrame config={cfg} />,\n };\n case \"figma\":\n return {\n ...meta,\n content: <Figma config={cfg} />,\n offscreen: false,\n };\n case \"sketch\":\n return {\n ...meta,\n content: <Sketch config={cfg} />,\n };\n case \"figspec\":\n case \"experimental-figspec\":\n if (cfg.type === \"experimental-figspec\") {\n console.warn(\n \"[storybook-addon-designs] `experimental-figspec` is deprecated. We will remove it in v7.0. Please replace it to `figspec` type.\",\n );\n }\n\n return {\n ...meta,\n content: (\n <Suspense fallback=\"Preparing Figspec viewer...\">\n <Figspec config={cfg} />\n </Suspense>\n ),\n offscreen: false,\n };\n case \"image\":\n return {\n ...meta,\n content: <ImagePreview config={cfg} />,\n };\n case \"link\":\n return {\n ...meta,\n content: <LinkPanel config={cfg} />,\n };\n }\n\n // FIXME: Link is temporarily set to source code due to \"Available config types\" section\n // had been removed from README. We need to add a list to README or docs site.\n // This is very much user-unfriendly, especially for whom not familier with TypeScript.\n return {\n ...meta,\n content: (\n <Placeholder>\n <Fragment>Invalid config type</Fragment>\n <Fragment>\n Config type you set is not supported. Please choose one from{\" \"}\n <Link\n href=\"https://github.com/storybookjs/addon-designs/blob/master/packages/storybook-addon-designs/src/config.ts\"\n target=\"_blank\"\n rel=\"noopener\"\n withArrow\n cancel={false}\n >\n available config types\n </Link>\n </Fragment>\n </Placeholder>\n ),\n };\n },\n );\n\n if (tabs.length === 1) {\n return <div>{tabs[0].content}</div>;\n }\n\n return <Tabs tabs={tabs} deps={[config]} />;\n};\n\nexport default Wrapper;\n","/** @jsx jsx */\nimport { FC } from \"react\";\nimport { css, jsx } from \"@storybook/theming\";\n\nimport { Link } from \"@storybook/components\";\n\nimport { LinkConfig } from \"../../config\";\n\ninterface Props {\n config: LinkConfig;\n}\n\nexport const LinkPanel: FC<Props> = ({ config }) => (\n <div css={$container}>\n <Link\n cancel={false}\n href={config.url}\n target={config.target ?? \"_blank\"}\n rel={config.rel ?? \"noopener\"}\n withArrow={config.showArrow ?? true}\n >\n {config.label || config.url}\n </Link>\n </div>\n);\n\nexport default LinkPanel;\n\nconst $container = css`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n`;\n","/** @jsx jsx */\nimport { Link, Placeholder } from \"@storybook/components\";\nimport { jsx } from \"@storybook/theming\";\nimport { FC, Fragment, ReactNode, useMemo } from \"react\";\n\nimport { SketchConfig, IFrameConfigBase } from \"../../config\";\n\nimport { IFrame } from \"./IFrame\";\n\ninterface ParseSucceeded<T> {\n valid: true;\n\n data: T;\n}\n\ninterface ParseFailed {\n valid: false;\n\n error: ReactNode;\n}\n\ntype Parser<T> = (url: URL) => ParseSucceeded<T> | ParseFailed;\n\nexport const v1UrlParser: Parser<IFrameConfigBase> = (url) => {\n if (url.protocol !== \"https:\") {\n return {\n valid: false,\n error: (\n <Fragment>\n Expected HTTPS link, received <code>{url.protocol}</code>.\n </Fragment>\n ),\n };\n }\n\n if (url.hostname !== \"www.sketch.com\") {\n return {\n valid: false,\n error: (\n <Fragment>\n Expected a hostname <code>www.sketch.com</code>, received{\" \"}\n <code>{url.hostname}</code>\n </Fragment>\n ),\n };\n }\n\n const malformedUrlErrorMessage = (\n <Fragment>\n Expected pathname <code>{\"/s/<string>/a/<string>\"}</code>, received{\" \"}\n <code>{url.pathname}</code>.\n </Fragment>\n );\n\n const pathSegments = url.pathname.split(\"/\").slice(1);\n if (pathSegments.length < 4) {\n return {\n valid: false,\n error: malformedUrlErrorMessage,\n };\n }\n\n if (pathSegments[0] === \"embed\") {\n return {\n valid: true,\n data: {\n url: url.href,\n offscreen: false,\n },\n };\n }\n\n const [s, sid, a, aid] = pathSegments;\n if (s !== \"s\" || !sid || a !== \"a\" || !aid) {\n return {\n valid: false,\n error: malformedUrlErrorMessage,\n };\n }\n\n return {\n valid: true,\n data: {\n url: `https://www.sketch.com/embed/s/${sid}/a/${aid}`,\n offscreen: false,\n },\n };\n};\n\ninterface Props {\n config: SketchConfig;\n}\n\nexport const Sketch: FC<Props> = ({ config }) => {\n const result = useMemo(() => {\n const parsed = v1UrlParser(new URL(config.url));\n if (!parsed.valid) {\n return parsed;\n }\n\n return {\n ...parsed,\n data: {\n ...config,\n ...parsed.data,\n },\n };\n }, [config]);\n\n if (!result.valid) {\n return (\n <Placeholder>\n <Fragment>Invalid Sketch URL</Fragment>\n <Fragment>{result.error}</Fragment>\n </Placeholder>\n );\n }\n\n return <IFrame defer config={result.data} />;\n};\n","/** @jsx jsx */\nimport { DependencyList, FC, ReactNode, useEffect, useState } from \"react\";\nimport { jsx } from \"@storybook/theming\";\n\nimport { Tabs as SbTabs } from \"@storybook/components\";\n\nexport interface Tab {\n id: string;\n name: string;\n content: ReactNode;\n offscreen: boolean;\n}\n\nexport interface TabsProps {\n tabs: readonly Tab[];\n\n /**\n * Effect trigger for tab initialization. Everytime this dependency list is\n * updated, the selection goes to the first tab.\n */\n deps?: DependencyList;\n}\n\nexport const Tabs: FC<TabsProps> = ({ tabs, deps = [] }) => {\n const [selected, setSelected] = useState(tabs[0].id);\n\n useEffect(() => {\n setSelected(tabs[0].id);\n }, deps);\n\n return (\n <SbTabs absolute selected={selected} actions={{ onSelect: setSelected }}>\n {tabs.map((tab) => (\n <div key={tab.id} id={tab.id} title={tab.name}>\n {tab.offscreen || selected === tab.id ? tab.content : null}\n </div>\n ))}\n </SbTabs>\n );\n};\n","/**\n * The identifier of the addon.\n */\nexport const AddonName = \"STORYBOOK_ADDON_DESIGNS\";\n\n/**\n * The name of the panel.\n */\nexport const PanelName = AddonName + \"/panel\";\n\n/**\n * Addon events.\n */\nexport const Events = {\n UpdateConfig: AddonName + \"/update_config\",\n};\n\n/**\n * A key of story parameters.\n */\nexport const ParameterName = \"design\";\n"]}