{"version":3,"sources":["../src/manager/components/IFrame.tsx","../src/manager/components/Figma.tsx","../src/manager/components/Figspec.tsx","../src/manager/register.tsx","../src/constants.ts","../src/manager/components/ErrorBoundary.tsx","../src/manager/containers/Wrapper.tsx","../src/manager/components/Wrapper.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/LinkPanel.tsx","../src/manager/components/Sketch.tsx","../src/manager/components/Tabs.tsx","../src/register-panel.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","addons","types","useParameter","AddonPanel","AddonName","PanelName","Events","ParameterName","Component","Link","ErrorBoundary","error","info","useStorybookState","lazy","Suspense","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","LinkPanel","v1UrlParser","malformedUrlErrorMessage","pathSegments","s","sid","aid","Sketch","result","parsed","SbTabs","Tabs","tabs","selected","setSelected","tab","Wrapper","meta","active","onceRevealed","setOnceRevealed","DEFAULT_TAB_NAME","register","renderTarget","api","title","param"],"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","/** @jsx jsx */\nimport { addons, types, useParameter } from \"@storybook/manager-api\";\nimport { AddonPanel } from \"@storybook/components\";\nimport { jsx } from \"@storybook/theming\";\n\nimport { AddonName, PanelName, ParameterName } from \"../constants\";\nimport { ErrorBoundary } from \"./components/ErrorBoundary\";\nimport type { Config } from \"../config\";\n\nimport { Wrapper } from \"./containers/Wrapper\";\n\nconst DEFAULT_TAB_NAME = \"Design\";\n\nexport function register(renderTarget: \"panel\" | \"tab\") {\n  addons.register(AddonName, (api) => {\n    const title = function () {\n      const param = useParameter<Config | Config[] | undefined>(ParameterName);\n\n      if (!param) {\n        return DEFAULT_TAB_NAME;\n      }\n\n      // As the addon shows an additional tab panel, it's better not to\n      // use any of items' name.\n      if (Array.isArray(param)) {\n        return param.length > 0\n          ? `${DEFAULT_TAB_NAME} (${param.length})`\n          : DEFAULT_TAB_NAME;\n      }\n\n      return (param.name || DEFAULT_TAB_NAME) + \" (1)\";\n    };\n\n    if (renderTarget === \"tab\") {\n      addons.add(PanelName, {\n        title: DEFAULT_TAB_NAME,\n        render({ active }) {\n          if (!active) {\n            // NOTE: Return type of render is `ReactElement`, hence returning `null` causes\n            //       type error. I'm using `<noscript>` in place of `null`.\n            return <noscript />;\n          }\n\n          return (\n            <ErrorBoundary>\n              <Wrapper active />\n            </ErrorBoundary>\n          );\n        },\n        type: types.TAB,\n        paramKey: ParameterName,\n      });\n    } else {\n      addons.add(PanelName, {\n        type: types.PANEL,\n        title,\n        paramKey: ParameterName,\n        render({ active }) {\n          return (\n            <AddonPanel active={!!active}>\n              <ErrorBoundary>\n                <Wrapper active={!!active} />\n              </ErrorBoundary>\n            </AddonPanel>\n          );\n        },\n      });\n    }\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","/** @jsx jsx */\nimport { Component, ErrorInfo, Fragment } from \"react\";\nimport { Link, Placeholder } from \"@storybook/components\";\nimport { jsx } from \"@storybook/theming\";\n\ntype State =\n  | {\n      hasError: false;\n    }\n  | {\n      hasError: true;\n      error: unknown;\n    };\n\nexport class ErrorBoundary extends Component<{ children: React.ReactNode }> {\n  public state: State = { hasError: false };\n\n  static getDerivedStateFromError(error: unknown): State {\n    return {\n      hasError: true,\n      error,\n    };\n  }\n\n  override componentDidCatch(error: unknown, info: ErrorInfo): void {\n    console.group(\n      \"An error occurred during rendering Addon panel of storybook-addon-designs\",\n    );\n    console.log(\"--- Error ---\");\n    console.error(error);\n    console.log(\"--- React Component Stack ---\");\n    console.error(info.componentStack);\n    console.groupEnd();\n  }\n\n  override render() {\n    if (this.state.hasError) {\n      return (\n        <Placeholder>\n          <Fragment>Failed to render addon UI</Fragment>\n          <Fragment>\n            <p>\n              Sorry, this addon has crashed due to the below error has thrown\n              during rendering the addon UI.\n            </p>\n            <pre>{String(this.state.error)}</pre>\n            <p>\n              See console log for more details. To clear the error state, please\n              reload the page.{\" \"}\n              <Link\n                href=\"https://github.com/storybookjs/addon-designs/issues/new?assignees=&labels=category%3A+bug&template=bug_report.yml\"\n                target=\"_blank\"\n                rel=\"noopener\"\n                withArrow\n                cancel={false}\n              >\n                Bug report\n              </Link>\n            </p>\n          </Fragment>\n        </Placeholder>\n      );\n    }\n\n    return this.props.children;\n  }\n}\n","/** @jsx jsx */\nimport { FC, useEffect, useState } from \"react\";\nimport { jsx } from \"@storybook/theming\";\nimport { useParameter, useStorybookState } from \"@storybook/manager-api\";\n\nimport { Config } from \"../../config\";\nimport { ParameterName } from \"../../constants\";\n\nimport { Wrapper as Pure } from \"../components/Wrapper\";\n\ninterface Props {\n  active: boolean;\n}\n\nexport const Wrapper: FC<Props> = ({ active }) => {\n  const state = useStorybookState();\n  const config = useParameter(ParameterName) as Config;\n\n  // Whether the addon panel has been visible to a user with the config.\n  const [onceRevealed, setOnceRevealed] = useState(active);\n\n  // When a user navigates to another story or updates a story parameter,\n  // sync `onceRevealed` to `active`.\n  useEffect(() => {\n    setOnceRevealed(active);\n  }, [config]);\n\n  // When a user enters the \"Design\" tab, mark the addon panel \"once revealed\".\n  useEffect(() => {\n    if (active) {\n      setOnceRevealed(true);\n    }\n  }, [active]);\n\n  // If a user has not entered the \"Design\" tab for the current story yet,\n  // do not render panel contents. This makes loading embeds explicit and\n  // prevents embedded sites from obtaining viewport (iframe) size behind,\n  // which often leads to incorrect measurements.\n  if (!onceRevealed) {\n    return null;\n  }\n\n  return <Pure key={state.storyId} config={config} />;\n};\n\nexport default Wrapper;\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 { 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 { 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","import { register } from \"./manager/register\";\n\nregister(\"panel\");\n"]}