{"version":3,"file":"PresentationConfig.mjs","sources":["../../../../../../../../web/src/ui/components/PresentationConfig.ts"],"sourcesContent":["import { logger, RUN_IN_DEV } from '@stytch/core';\nimport { createContext, useContext, useMemo } from 'react';\n\nimport { PresentationConfig } from '../../types';\nimport { IconNames } from '../b2c/components/Icons';\nimport { useMediaQuery } from '../hooks/useMediaQuery';\nimport { IconRegistry } from './IconRegistry';\nimport { Theme } from './themes/ThemeConfig';\nimport { defaultTheme } from './themes/themes';\n\nexport type PresentationOptions = {\n  /**\n   * When this value is false, the header title and description text will be hidden.\n   * This is useful if you prefer to display and style the title outside the Stytch component.\n   */\n  hideHeaderText: boolean;\n\n  /**\n   * Optional suffix for <input> id attribute so input IDs are unique.\n   */\n  inputIdSuffix?: string;\n\n  /**\n   * The configuration object for your custom logo.\n   */\n  logo?: {\n    /**\n     * The URL of your custom logo.\n     */\n    url: string;\n\n    /**\n     * Alt text for the logo. This would usually be the name of the website or your company,\n     * unless this is already repeated nearby in which case this should be left empty.\n     */\n    alt: string;\n  };\n\n  /**\n   * Set to true to add id like 'oauth-google' to buttons, or a string to add a suffix to button ids to make\n   * them more unique. This exists for backwards compatibility. We do not recommend using this to style or\n   * modify elements in Stytch UI.\n   */\n  buttonId?: string | boolean;\n\n  /**\n   * Wraps the Stytch UI components to be contained in a shadow DOM. Use this to enable style isolation.\n   * @default false\n   */\n  enableShadowDOM?: boolean;\n\n  /**\n   * Override our icons. Currently, this only supports logos, such as those that appear in Oauth buttons.\n   * This should be an object where the key is the icon name and the value is a React component\n   * (not React element) with a size prop and the rest spread onto the root element.\n   *\n   * Note that custom logos not imported from our packages is not yet available in @stytch/vanilla-js.\n   * We are looking at provide alternatives in the future.\n   *\n   * @example\n   *\n   * // Using a solid black or white icon\n   * import { whiteIcons } from '@stytch/react';\n   *\n   * const presentation = {\n   *   options: {\n   *     icons: {\n   *       outlook: whiteIcons.outlook,\n   *     },\n   *   },\n   * };\n   *\n   * // Using a custom icon\n   * const presentation = {\n   *  icons: {\n   *    outlook: ({ size, ...props }) => (\n   *      <svg width={size} height={size} {...props}>...</svg>\n   *    ),\n   *  },\n   * };\n   */\n  icons?: IconRegistry<string>;\n};\n\nconst defaultOptions: PresentationOptions = {\n  hideHeaderText: false,\n};\n\n/**\n * Internal type -\n * @see {PresentationConfig} is the public one\n */\nexport type Presentation = {\n  theme: Theme;\n  options: PresentationOptions;\n\n  // Internal properties\n  displayWatermark: boolean;\n  iconRegistry: IconRegistry<string>;\n};\n\nexport function usePresentationWithDefault(\n  maybeConfig: PresentationConfig | undefined,\n  displayWatermark: boolean,\n  {\n    products,\n    enableShadowDOM,\n  }: {\n    products: { id: string; icons?: Partial<IconRegistry<IconNames>> }[];\n    enableShadowDOM?: boolean;\n  },\n  productsName?: string,\n): Presentation {\n  const { theme, options } = maybeConfig ?? {};\n\n  RUN_IN_DEV(() => {\n    const stringProducts = products.filter((p) => typeof p === 'string');\n    if (stringProducts.length > 0) {\n      logger.error(\n        `Please add an import for ${productsName} and update config.products to\\n` +\n          'products: [' +\n          products.map((p) => `${productsName}.${typeof p === 'string' ? p : p.id}`).join(', ') +\n          ']',\n      );\n\n      throw new Error(\"'config.products' should not include strings anymore\");\n    }\n  });\n\n  // Switch theme automatically depending on color scheme\n  const isDynamic = isDynamicTheme(theme);\n  const darkMode = useMediaQuery(isDynamic ? '(prefers-color-scheme: dark)' : undefined);\n\n  let effectiveTheme: Partial<Theme> | undefined;\n  if (isDynamic) {\n    effectiveTheme = darkMode ? theme[1] : theme[0];\n  } else {\n    effectiveTheme = theme;\n  }\n\n  // Memoize the icon registry so it only need to be constructed once\n  const iconRegistry = useMemo(() => {\n    const registry: IconRegistry<string> = {};\n    for (const product of products) {\n      Object.assign(registry, product.icons);\n    }\n    Object.assign(registry, options?.icons);\n    return registry;\n  }, [products, options]);\n\n  return {\n    theme: {\n      ...defaultTheme,\n      ...effectiveTheme,\n    },\n    options: {\n      enableShadowDOM,\n      ...defaultOptions,\n      ...options,\n    },\n    displayWatermark,\n    iconRegistry,\n  };\n}\n\nexport function isDynamicTheme(\n  theme: PresentationConfig['theme'],\n): theme is readonly [light: Partial<Theme>, dark: Partial<Theme>] {\n  return Array.isArray(theme);\n}\n\nexport const PresentationContext = createContext<Presentation>(undefined!);\nexport const usePresentation = () => useContext(PresentationContext);\n\nexport function getButtonId(base: string, options: PresentationOptions) {\n  if (options.buttonId == null || options.buttonId === false) return undefined;\n  if (typeof options.buttonId === 'string') return base + options.buttonId;\n  return base;\n}\n"],"names":["defaultOptions","hideHeaderText","usePresentationWithDefault","maybeConfig","displayWatermark","products","enableShadowDOM","productsName","theme","options","RUN_IN_DEV","stringProducts","filter","p","length","logger","error","map","id","join","Error","isDynamic","isDynamicTheme","darkMode","useMediaQuery","undefined","effectiveTheme","iconRegistry","useMemo","registry","product","Object","assign","icons","defaultTheme","Array","isArray","PresentationContext","createContext","usePresentation","useContext","getButtonId","base","buttonId"],"mappings":";;;;;;;;AAoFA,MAAMA,cAAAA,GAAsC;IAC1CC,cAAAA,EAAgB;AAClB,CAAA;AAeO,SAASC,0BAAAA,CACdC,WAA2C,EAC3CC,gBAAyB,EACzB,EACEC,QAAQ,EACRC,eAAe,EAIhB,EACDC,YAAqB,EAAA;AAErB,IAAA,MAAM,EAAEC,KAAK,EAAEC,OAAO,EAAE,GAAGN,eAAe,EAAC;IAE3CO,UAAAA,CAAW,IAAA;AACT,QAAA,MAAMC,iBAAiBN,QAAAA,CAASO,MAAM,CAAC,CAACC,CAAAA,GAAM,OAAOA,CAAAA,KAAM,QAAA,CAAA;QAC3D,IAAIF,cAAAA,CAAeG,MAAM,GAAG,CAAA,EAAG;AAC7BC,YAAAA,MAAAA,CAAOC,KAAK,CACV,CAAC,yBAAyB,EAAET,YAAAA,CAAa,gCAAgC,CAAC,GACxE,aAAA,GACAF,QAAAA,CAASY,GAAG,CAAC,CAACJ,CAAAA,GAAM,CAAA,EAAGN,YAAAA,CAAa,CAAC,EAAE,OAAOM,CAAAA,KAAM,QAAA,GAAWA,CAAAA,GAAIA,CAAAA,CAAEK,EAAE,CAAA,CAAE,CAAA,CAAEC,IAAI,CAAC,IAAA,CAAA,GAChF,GAAA,CAAA;AAGJ,YAAA,MAAM,IAAIC,KAAAA,CAAM,sDAAA,CAAA;AAClB,QAAA;AACF,IAAA,CAAA,CAAA;;AAGA,IAAA,MAAMC,YAAYC,cAAAA,CAAed,KAAAA,CAAAA;IACjC,MAAMe,QAAAA,GAAWC,aAAAA,CAAcH,SAAAA,GAAY,8BAAA,GAAiCI,SAAAA,CAAAA;IAE5E,IAAIC,cAAAA;AACJ,IAAA,IAAIL,SAAAA,EAAW;AACbK,QAAAA,cAAAA,GAAiBH,WAAWf,KAAK,CAAC,EAAE,GAAGA,KAAK,CAAC,CAAA,CAAE;IACjD,CAAA,MAAO;QACLkB,cAAAA,GAAiBlB,KAAAA;AACnB,IAAA;;AAGA,IAAA,MAAMmB,eAAeC,GAAAA,CAAQ,IAAA;AAC3B,QAAA,MAAMC,WAAiC,EAAC;QACxC,KAAK,MAAMC,WAAWzB,QAAAA,CAAU;AAC9B0B,YAAAA,MAAAA,CAAOC,MAAM,CAACH,QAAAA,EAAUC,OAAAA,CAAQG,KAAK,CAAA;AACvC,QAAA;QACAF,MAAAA,CAAOC,MAAM,CAACH,QAAAA,EAAUpB,OAAAA,EAASwB,KAAAA,CAAAA;QACjC,OAAOJ,QAAAA;IACT,CAAA,EAAG;AAACxB,QAAAA,QAAAA;AAAUI,QAAAA;AAAQ,KAAA,CAAA;IAEtB,OAAO;QACLD,KAAAA,EAAO;AACL,YAAA,GAAG0B,YAAY;AACf,YAAA,GAAGR;AACL,SAAA;QACAjB,OAAAA,EAAS;AACPH,YAAAA,eAAAA;AACA,YAAA,GAAGN,cAAc;AACjB,YAAA,GAAGS;AACL,SAAA;AACAL,QAAAA,gBAAAA;AACAuB,QAAAA;AACF,KAAA;AACF;AAEO,SAASL,eACdd,KAAkC,EAAA;IAElC,OAAO2B,KAAAA,CAAMC,OAAO,CAAC5B,KAAAA,CAAAA;AACvB;AAEO,MAAM6B,mBAAAA,GAAsBC,CAAAA,CAA4Bb,SAAAA;AACxD,MAAMc,eAAAA,GAAkB,IAAMC,CAAAA,CAAWH,mBAAAA;AAEzC,SAASI,WAAAA,CAAYC,IAAY,EAAEjC,OAA4B,EAAA;IACpE,IAAIA,OAAAA,CAAQkC,QAAQ,IAAI,IAAA,IAAQlC,QAAQkC,QAAQ,KAAK,OAAO,OAAOlB,SAAAA;IACnE,IAAI,OAAOhB,QAAQkC,QAAQ,KAAK,UAAU,OAAOD,IAAAA,GAAOjC,QAAQkC,QAAQ;IACxE,OAAOD,IAAAA;AACT;;;;"}