@stytch/react 20.0.0-next.3 → 20.0.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/b2b/index.cjs +15 -8
  3. package/dist/cjs/b2b/index.cjs.map +1 -1
  4. package/dist/cjs/index.cjs +45 -56
  5. package/dist/cjs/index.cjs.map +1 -1
  6. package/dist/cjs/{shadcn-Z4AvHriT.js → shadcn-aVU6Lm9q.js} +9 -3
  7. package/dist/cjs/shadcn-aVU6Lm9q.js.map +1 -0
  8. package/dist/cjs-dev/b2b/index.cjs +15 -8
  9. package/dist/cjs-dev/b2b/index.cjs.map +1 -1
  10. package/dist/cjs-dev/index.cjs +45 -56
  11. package/dist/cjs-dev/index.cjs.map +1 -1
  12. package/dist/cjs-dev/{shadcn-DnNfms7-.js → shadcn-DMk6ZSoD.js} +9 -3
  13. package/dist/cjs-dev/shadcn-DMk6ZSoD.js.map +1 -0
  14. package/dist/esm/_virtual/index3.mjs +5 -3
  15. package/dist/esm/_virtual/index3.mjs.map +1 -1
  16. package/dist/esm/_virtual/index4.mjs +3 -5
  17. package/dist/esm/_virtual/index4.mjs.map +1 -1
  18. package/dist/esm/packages/web/src/adminPortal/utils/theme.mjs +1 -1
  19. package/dist/esm/packages/web/src/ui/b2b/components/OAuthB2BButton.mjs +6 -3
  20. package/dist/esm/packages/web/src/ui/b2b/components/OAuthB2BButton.mjs.map +1 -1
  21. package/dist/esm/packages/web/src/ui/b2b/components/SSOButton.mjs +5 -3
  22. package/dist/esm/packages/web/src/ui/b2b/components/SSOButton.mjs.map +1 -1
  23. package/dist/esm/packages/web/src/ui/b2b/screens/SsoAndOAuthButtons.mjs +6 -3
  24. package/dist/esm/packages/web/src/ui/b2b/screens/SsoAndOAuthButtons.mjs.map +1 -1
  25. package/dist/esm/packages/web/src/ui/b2b/types/authMethodKeys.mjs +2 -2
  26. package/dist/esm/packages/web/src/ui/b2b/types/authMethodKeys.mjs.map +1 -1
  27. package/dist/esm/packages/web/src/ui/b2c/components/OAuthButton.mjs +6 -3
  28. package/dist/esm/packages/web/src/ui/b2c/components/OAuthButton.mjs.map +1 -1
  29. package/dist/esm/packages/web/src/ui/b2c/screens/Crypto/SetupNewWallet.mjs +20 -40
  30. package/dist/esm/packages/web/src/ui/b2c/screens/Crypto/SetupNewWallet.mjs.map +1 -1
  31. package/dist/esm/packages/web/src/ui/b2c/screens/Crypto/WalletButtons.mjs +7 -5
  32. package/dist/esm/packages/web/src/ui/b2c/screens/Crypto/WalletButtons.mjs.map +1 -1
  33. package/dist/esm/packages/web/src/ui/components/PresentationConfig.mjs +6 -1
  34. package/dist/esm/packages/web/src/ui/components/PresentationConfig.mjs.map +1 -1
  35. package/dist/esm/packages/web/src/ui/components/atoms/Button.mjs.map +1 -1
  36. package/dist/esm/packages/web/src/ui/components/molecules/EmailInput.mjs +1 -1
  37. package/dist/esm/packages/web/src/ui/components/molecules/EmailInput.mjs.map +1 -1
  38. package/dist/esm/packages/web/src/ui/components/molecules/Input.mjs +1 -1
  39. package/dist/esm/packages/web/src/ui/components/molecules/Input.mjs.map +1 -1
  40. package/dist/esm/packages/web/src/utils/crypto.mjs +12 -8
  41. package/dist/esm/packages/web/src/utils/crypto.mjs.map +1 -1
  42. package/dist/esm-dev/_virtual/index3.mjs +3 -5
  43. package/dist/esm-dev/_virtual/index3.mjs.map +1 -1
  44. package/dist/esm-dev/_virtual/index4.mjs +5 -3
  45. package/dist/esm-dev/_virtual/index4.mjs.map +1 -1
  46. package/dist/esm-dev/packages/web/src/adminPortal/utils/theme.mjs +1 -1
  47. package/dist/esm-dev/packages/web/src/ui/b2b/components/OAuthB2BButton.mjs +6 -3
  48. package/dist/esm-dev/packages/web/src/ui/b2b/components/OAuthB2BButton.mjs.map +1 -1
  49. package/dist/esm-dev/packages/web/src/ui/b2b/components/SSOButton.mjs +5 -3
  50. package/dist/esm-dev/packages/web/src/ui/b2b/components/SSOButton.mjs.map +1 -1
  51. package/dist/esm-dev/packages/web/src/ui/b2b/screens/SsoAndOAuthButtons.mjs +6 -3
  52. package/dist/esm-dev/packages/web/src/ui/b2b/screens/SsoAndOAuthButtons.mjs.map +1 -1
  53. package/dist/esm-dev/packages/web/src/ui/b2b/types/authMethodKeys.mjs +2 -2
  54. package/dist/esm-dev/packages/web/src/ui/b2b/types/authMethodKeys.mjs.map +1 -1
  55. package/dist/esm-dev/packages/web/src/ui/b2c/components/OAuthButton.mjs +6 -3
  56. package/dist/esm-dev/packages/web/src/ui/b2c/components/OAuthButton.mjs.map +1 -1
  57. package/dist/esm-dev/packages/web/src/ui/b2c/screens/Crypto/SetupNewWallet.mjs +20 -40
  58. package/dist/esm-dev/packages/web/src/ui/b2c/screens/Crypto/SetupNewWallet.mjs.map +1 -1
  59. package/dist/esm-dev/packages/web/src/ui/b2c/screens/Crypto/WalletButtons.mjs +7 -5
  60. package/dist/esm-dev/packages/web/src/ui/b2c/screens/Crypto/WalletButtons.mjs.map +1 -1
  61. package/dist/esm-dev/packages/web/src/ui/components/PresentationConfig.mjs +6 -1
  62. package/dist/esm-dev/packages/web/src/ui/components/PresentationConfig.mjs.map +1 -1
  63. package/dist/esm-dev/packages/web/src/ui/components/atoms/Button.mjs.map +1 -1
  64. package/dist/esm-dev/packages/web/src/ui/components/molecules/EmailInput.mjs +1 -1
  65. package/dist/esm-dev/packages/web/src/ui/components/molecules/EmailInput.mjs.map +1 -1
  66. package/dist/esm-dev/packages/web/src/ui/components/molecules/Input.mjs +1 -1
  67. package/dist/esm-dev/packages/web/src/ui/components/molecules/Input.mjs.map +1 -1
  68. package/dist/esm-dev/packages/web/src/utils/crypto.mjs +12 -8
  69. package/dist/esm-dev/packages/web/src/utils/crypto.mjs.map +1 -1
  70. package/dist/types/{PresentationConfig-CcNEXkjS.d.ts → PresentationConfig-B2jX85oV.d.ts} +8 -1
  71. package/dist/types/b2b/index.d.ts +3 -3
  72. package/dist/types/compat.d.ts +1 -1
  73. package/dist/types/index.d.ts +3 -3
  74. package/dist/types/{shadcn-B04UXoBD.d.ts → shadcn-CGdmyIUF.d.ts} +1 -1
  75. package/package.json +1 -1
  76. package/dist/cjs/shadcn-Z4AvHriT.js.map +0 -1
  77. package/dist/cjs-dev/shadcn-DnNfms7-.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PresentationConfig.mjs","sources":["../../../../../../../../web/src/ui/components/PresentationConfig.ts"],"sourcesContent":["import { defaultTheme } from './themes/themes';\nimport { createContext, useContext, useMemo } from 'react';\nimport { PresentationConfig } from '../../types';\nimport { Theme } from './themes/ThemeConfig';\nimport { useMediaQuery } from '../hooks/useMediaQuery';\nimport { IconRegistry } from './IconRegistry';\nimport { IconNames } from '../b2c/components/Icons';\nimport { logger, RUN_IN_DEV } from '@stytch/core';\n\nexport type PresentationOptions = {\n /**\n * When this value is false, the title and description text will not show in the SDK.\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 * 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 products: { id: string; icons?: Partial<IconRegistry<IconNames>> }[],\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 ...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"],"names":["defaultOptions","hideHeaderText","usePresentationWithDefault","maybeConfig","displayWatermark","products","productsName","theme","options","isDynamic","isDynamicTheme","darkMode","useMediaQuery","undefined","effectiveTheme","iconRegistry","useMemo","registry","product","Object","assign","icons","defaultTheme","Array","isArray","PresentationContext","createContext","usePresentation","useContext"],"mappings":";;;;AAqEA,MAAMA,cAAAA,GAAsC;IAC1CC,cAAAA,EAAgB;AAClB,CAAA;AAeO,SAASC,2BACdC,WAA2C,EAC3CC,gBAAyB,EACzBC,QAAoE,EACpEC,YAAqB,EAAA;AAErB,IAAA,MAAM,EAAEC,KAAK,EAAEC,OAAO,EAAE,GAAGL,eAAe,EAAC;;AAiB3C,IAAA,MAAMM,YAAYC,cAAAA,CAAeH,KAAAA,CAAAA;IACjC,MAAMI,QAAAA,GAAWC,aAAAA,CAAcH,SAAAA,GAAY,8BAAA,GAAiCI,SAAAA,CAAAA;IAE5E,IAAIC,cAAAA;AACJ,IAAA,IAAIL,SAAAA,EAAW;AACbK,QAAAA,cAAAA,GAAiBH,WAAWJ,KAAK,CAAC,EAAE,GAAGA,KAAK,CAAC,CAAA,CAAE;KACjD,MAAO;QACLO,cAAAA,GAAiBP,KAAAA;AACnB,IAAA;;AAGA,IAAA,MAAMQ,eAAeC,OAAAA,CAAQ,IAAA;AAC3B,QAAA,MAAMC,WAAiC,EAAC;QACxC,KAAK,MAAMC,WAAWb,QAAAA,CAAU;AAC9Bc,YAAAA,MAAAA,CAAOC,MAAM,CAACH,QAAAA,EAAUC,OAAAA,CAAQG,KAAK,CAAA;AACvC,QAAA;QACAF,MAAAA,CAAOC,MAAM,CAACH,QAAAA,EAAUT,OAAAA,EAASa,KAAAA,CAAAA;QACjC,OAAOJ,QAAAA;KACT,EAAG;AAACZ,QAAAA,QAAAA;AAAUG,QAAAA;AAAQ,KAAA,CAAA;IAEtB,OAAO;QACLD,KAAAA,EAAO;AACL,YAAA,GAAGe,YAAY;AACf,YAAA,GAAGR;AACL,SAAA;QACAN,OAAAA,EAAS;AACP,YAAA,GAAGR,cAAc;AACjB,YAAA,GAAGQ;AACL,SAAA;AACAJ,QAAAA,gBAAAA;AACAW,QAAAA;AACF,KAAA;AACF;AAEO,SAASL,eACdH,KAAkC,EAAA;IAElC,OAAOgB,KAAAA,CAAMC,OAAO,CAACjB,KAAAA,CAAAA;AACvB;MAEakB,mBAAAA,GAAsBC,aAAAA,CAA4Bb,SAAAA;MAClDc,eAAAA,GAAkB,IAAMC,UAAAA,CAAWH,mBAAAA;;;;"}
1
+ {"version":3,"file":"PresentationConfig.mjs","sources":["../../../../../../../../web/src/ui/components/PresentationConfig.ts"],"sourcesContent":["import { defaultTheme } from './themes/themes';\nimport { createContext, useContext, useMemo } from 'react';\nimport { PresentationConfig } from '../../types';\nimport { Theme } from './themes/ThemeConfig';\nimport { useMediaQuery } from '../hooks/useMediaQuery';\nimport { IconRegistry } from './IconRegistry';\nimport { IconNames } from '../b2c/components/Icons';\nimport { logger, RUN_IN_DEV } from '@stytch/core';\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 * 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 products: { id: string; icons?: Partial<IconRegistry<IconNames>> }[],\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 ...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","productsName","theme","options","isDynamic","isDynamicTheme","darkMode","useMediaQuery","undefined","effectiveTheme","iconRegistry","useMemo","registry","product","Object","assign","icons","defaultTheme","Array","isArray","PresentationContext","createContext","usePresentation","useContext","getButtonId","base","buttonId"],"mappings":";;;;AA6EA,MAAMA,cAAAA,GAAsC;IAC1CC,cAAAA,EAAgB;AAClB,CAAA;AAeO,SAASC,2BACdC,WAA2C,EAC3CC,gBAAyB,EACzBC,QAAoE,EACpEC,YAAqB,EAAA;AAErB,IAAA,MAAM,EAAEC,KAAK,EAAEC,OAAO,EAAE,GAAGL,eAAe,EAAC;;AAiB3C,IAAA,MAAMM,YAAYC,cAAAA,CAAeH,KAAAA,CAAAA;IACjC,MAAMI,QAAAA,GAAWC,aAAAA,CAAcH,SAAAA,GAAY,8BAAA,GAAiCI,SAAAA,CAAAA;IAE5E,IAAIC,cAAAA;AACJ,IAAA,IAAIL,SAAAA,EAAW;AACbK,QAAAA,cAAAA,GAAiBH,WAAWJ,KAAK,CAAC,EAAE,GAAGA,KAAK,CAAC,CAAA,CAAE;KACjD,MAAO;QACLO,cAAAA,GAAiBP,KAAAA;AACnB,IAAA;;AAGA,IAAA,MAAMQ,eAAeC,OAAAA,CAAQ,IAAA;AAC3B,QAAA,MAAMC,WAAiC,EAAC;QACxC,KAAK,MAAMC,WAAWb,QAAAA,CAAU;AAC9Bc,YAAAA,MAAAA,CAAOC,MAAM,CAACH,QAAAA,EAAUC,OAAAA,CAAQG,KAAK,CAAA;AACvC,QAAA;QACAF,MAAAA,CAAOC,MAAM,CAACH,QAAAA,EAAUT,OAAAA,EAASa,KAAAA,CAAAA;QACjC,OAAOJ,QAAAA;KACT,EAAG;AAACZ,QAAAA,QAAAA;AAAUG,QAAAA;AAAQ,KAAA,CAAA;IAEtB,OAAO;QACLD,KAAAA,EAAO;AACL,YAAA,GAAGe,YAAY;AACf,YAAA,GAAGR;AACL,SAAA;QACAN,OAAAA,EAAS;AACP,YAAA,GAAGR,cAAc;AACjB,YAAA,GAAGQ;AACL,SAAA;AACAJ,QAAAA,gBAAAA;AACAW,QAAAA;AACF,KAAA;AACF;AAEO,SAASL,eACdH,KAAkC,EAAA;IAElC,OAAOgB,KAAAA,CAAMC,OAAO,CAACjB,KAAAA,CAAAA;AACvB;MAEakB,mBAAAA,GAAsBC,aAAAA,CAA4Bb,SAAAA;MAClDc,eAAAA,GAAkB,IAAMC,UAAAA,CAAWH,mBAAAA;AAEzC,SAASI,WAAAA,CAAYC,IAAY,EAAEtB,OAA4B,EAAA;IACpE,IAAIA,OAAAA,CAAQuB,QAAQ,IAAI,IAAA,IAAQvB,QAAQuB,QAAQ,KAAK,OAAO,OAAOlB,SAAAA;IACnE,IAAI,OAAOL,QAAQuB,QAAQ,KAAK,UAAU,OAAOD,IAAAA,GAAOtB,QAAQuB,QAAQ;IACxE,OAAOD,IAAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Button.mjs","sources":["../../../../../../../../../web/src/ui/components/atoms/Button.tsx"],"sourcesContent":["import React, { ReactNode, KeyboardEventHandler } from 'react';\nimport classNames from 'classnames';\nimport { CircularProgress } from './CircularProgress';\nimport styles from './Button.module.css';\n\nexport type ButtonProps = {\n variant: 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';\n children: ReactNode;\n\n /**\n * Button is full width and content is centered\n * @default true\n */\n block?: boolean;\n\n icon?: ReactNode;\n\n /** If true, display a spinner and disables the button */\n loading?: boolean;\n disabled?: boolean;\n\n /**\n * Unlike HTML <button> we deliberately set the default to button to\n * avoid bugs where buttons inadvertently submit forms\n * @default 'button'\n **/\n type?: 'button' | 'submit' | 'reset';\n onClick?: () => void;\n onKeyDown?: KeyboardEventHandler<HTMLElement>;\n};\n\nexport function buttonClassNames({ variant, block = true }: Pick<ButtonProps, 'variant' | 'block'>) {\n return classNames(styles.button, styles[variant], {\n [styles.block]: block,\n });\n}\n\n// Base renderer for both <a> and <button> based <Button>s\nconst baseButton = (props: ButtonProps & { as?: string }) => {\n const { as, children, icon, onClick, loading, disabled = loading, block, variant, ...otherProps } = props;\n const Element = as as 'button';\n\n let buttonContent = (\n <>\n {icon}\n <span>{children}</span>\n </>\n );\n\n if (loading) {\n buttonContent = <CircularProgress size={20} />;\n }\n\n return (\n <Element className={buttonClassNames(props)} onClick={onClick} disabled={disabled} {...otherProps}>\n {buttonContent}\n </Element>\n );\n};\n\nconst Button = (props: ButtonProps) =>\n baseButton({\n type: 'button',\n as: 'button',\n ...props,\n });\n\nexport default Button;\n\n// Deriving this from ButtonProps is not very neat, but ButtonAnchor is not frequently used\nexport type ButtonAnchorProps = Omit<ButtonProps, 'type' | 'as'> & {\n href: string;\n download?: string;\n target?: string;\n rel?: string;\n};\n\nexport const ButtonAnchor = (props: ButtonAnchorProps) =>\n baseButton({\n ...props,\n // Links don't fire click event on space while buttons do, so we implement that ourselves for these\n // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/button_role#accessibility_concerns\n onKeyDown: (evt) => {\n props.onKeyDown?.(evt);\n if (evt.defaultPrevented) return;\n if (evt.key === ' ') evt.currentTarget.click();\n },\n as: 'a',\n });\n"],"names":["buttonClassNames","variant","block","classNames","styles","button","baseButton","props","as","children","icon","onClick","loading","disabled","otherProps","Element","buttonContent","React","span","CircularProgress","size","className","Button","type","ButtonAnchor","onKeyDown","evt","defaultPrevented","key","currentTarget","click"],"mappings":";;;;;AA+BO,SAASA,gBAAAA,CAAiB,EAAEC,OAAO,EAAEC,KAAAA,GAAQ,IAAI,EAA0C,EAAA;AAChG,IAAA,OAAOC,WAAWC,gBAAAA,CAAOC,MAAM,EAAED,gBAAM,CAACH,QAAQ,EAAE;QAChD,CAACG,gBAAAA,CAAOF,KAAK,GAAGA;AAClB,KAAA,CAAA;AACF;AAEA;AACA,MAAMI,aAAa,CAACC,KAAAA,GAAAA;IAClB,MAAM,EAAEC,EAAE,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,OAAO,EAAEC,OAAO,EAAEC,QAAAA,GAAWD,OAAO,EAAEV,KAAK,EAAED,OAAO,EAAE,GAAGa,YAAY,GAAGP,KAAAA;AACpG,IAAA,MAAMQ,OAAAA,GAAUP,EAAAA;AAEhB,IAAA,IAAIQ,aAAAA,iBACFC,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA,EACGP,IAAAA,gBACDO,cAAA,CAAA,aAAA,CAACC,MAAAA,EAAAA,IAAAA,EAAMT,QAAAA,CAAAA,CAAAA;AAIX,IAAA,IAAIG,OAAAA,EAAS;AACXI,QAAAA,aAAAA,iBAAgBC,cAAA,CAAA,aAAA,CAACE,gBAAAA,EAAAA;YAAiBC,IAAAA,EAAM;;AAC1C,IAAA;AAEA,IAAA,qBACEH,cAAA,CAAA,aAAA,CAACF,OAAAA,EAAAA;AAAQM,QAAAA,SAAAA,EAAWrB,gBAAAA,CAAiBO,KAAAA,CAAAA;QAAQI,OAAAA,EAASA,OAAAA;QAASE,QAAAA,EAAUA,QAAAA;AAAW,QAAA,GAAGC;AACpFE,KAAAA,EAAAA,aAAAA,CAAAA;AAGP,CAAA;AAEA,MAAMM,MAAAA,GAAS,CAACf,KAAAA,GACdD,UAAAA,CAAW;QACTiB,IAAAA,EAAM,QAAA;QACNf,EAAAA,EAAI,QAAA;AACJ,QAAA,GAAGD;AACL,KAAA;AAYK,MAAMiB,YAAAA,GAAe,CAACjB,KAAAA,GAC3BD,UAAAA,CAAW;AACT,QAAA,GAAGC,KAAK;;;AAGRkB,QAAAA,SAAAA,EAAW,CAACC,GAAAA,GAAAA;AACVnB,YAAAA,KAAAA,CAAMkB,SAAS,GAAGC,GAAAA,CAAAA;YAClB,IAAIA,GAAAA,CAAIC,gBAAgB,EAAE;AAC1B,YAAA,IAAID,IAAIE,GAAG,KAAK,KAAKF,GAAAA,CAAIG,aAAa,CAACC,KAAK,EAAA;AAC9C,QAAA,CAAA;QACAtB,EAAAA,EAAI;KACN;;;;"}
1
+ {"version":3,"file":"Button.mjs","sources":["../../../../../../../../../web/src/ui/components/atoms/Button.tsx"],"sourcesContent":["import React, { ReactNode, KeyboardEventHandler } from 'react';\nimport classNames from 'classnames';\nimport { CircularProgress } from './CircularProgress';\nimport styles from './Button.module.css';\n\nexport type ButtonProps = {\n variant: 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';\n children: ReactNode;\n\n /**\n * Button is full width and content is centered\n * @default true\n */\n block?: boolean;\n\n icon?: ReactNode;\n\n /** If true, display a spinner and disables the button */\n loading?: boolean;\n disabled?: boolean;\n\n /**\n * Unlike HTML <button> we deliberately set the default to button to\n * avoid bugs where buttons inadvertently submit forms\n * @default 'button'\n **/\n type?: 'button' | 'submit' | 'reset';\n onClick?: () => void;\n onKeyDown?: KeyboardEventHandler<HTMLElement>;\n id?: string;\n};\n\nexport function buttonClassNames({ variant, block = true }: Pick<ButtonProps, 'variant' | 'block'>) {\n return classNames(styles.button, styles[variant], {\n [styles.block]: block,\n });\n}\n\n// Base renderer for both <a> and <button> based <Button>s\nconst baseButton = (props: ButtonProps & { as?: string }) => {\n const { as, children, icon, onClick, loading, disabled = loading, block, variant, ...otherProps } = props;\n const Element = as as 'button';\n\n let buttonContent = (\n <>\n {icon}\n <span>{children}</span>\n </>\n );\n\n if (loading) {\n buttonContent = <CircularProgress size={20} />;\n }\n\n return (\n <Element className={buttonClassNames(props)} onClick={onClick} disabled={disabled} {...otherProps}>\n {buttonContent}\n </Element>\n );\n};\n\nconst Button = (props: ButtonProps) =>\n baseButton({\n type: 'button',\n as: 'button',\n ...props,\n });\n\nexport default Button;\n\n// Deriving this from ButtonProps is not very neat, but ButtonAnchor is not frequently used\nexport type ButtonAnchorProps = Omit<ButtonProps, 'type' | 'as'> & {\n href: string;\n download?: string;\n target?: string;\n rel?: string;\n};\n\nexport const ButtonAnchor = (props: ButtonAnchorProps) =>\n baseButton({\n ...props,\n // Links don't fire click event on space while buttons do, so we implement that ourselves for these\n // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/button_role#accessibility_concerns\n onKeyDown: (evt) => {\n props.onKeyDown?.(evt);\n if (evt.defaultPrevented) return;\n if (evt.key === ' ') evt.currentTarget.click();\n },\n as: 'a',\n });\n"],"names":["buttonClassNames","variant","block","classNames","styles","button","baseButton","props","as","children","icon","onClick","loading","disabled","otherProps","Element","buttonContent","React","span","CircularProgress","size","className","Button","type","ButtonAnchor","onKeyDown","evt","defaultPrevented","key","currentTarget","click"],"mappings":";;;;;AAgCO,SAASA,gBAAAA,CAAiB,EAAEC,OAAO,EAAEC,KAAAA,GAAQ,IAAI,EAA0C,EAAA;AAChG,IAAA,OAAOC,WAAWC,gBAAAA,CAAOC,MAAM,EAAED,gBAAM,CAACH,QAAQ,EAAE;QAChD,CAACG,gBAAAA,CAAOF,KAAK,GAAGA;AAClB,KAAA,CAAA;AACF;AAEA;AACA,MAAMI,aAAa,CAACC,KAAAA,GAAAA;IAClB,MAAM,EAAEC,EAAE,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,OAAO,EAAEC,OAAO,EAAEC,QAAAA,GAAWD,OAAO,EAAEV,KAAK,EAAED,OAAO,EAAE,GAAGa,YAAY,GAAGP,KAAAA;AACpG,IAAA,MAAMQ,OAAAA,GAAUP,EAAAA;AAEhB,IAAA,IAAIQ,aAAAA,iBACFC,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA,EACGP,IAAAA,gBACDO,cAAA,CAAA,aAAA,CAACC,MAAAA,EAAAA,IAAAA,EAAMT,QAAAA,CAAAA,CAAAA;AAIX,IAAA,IAAIG,OAAAA,EAAS;AACXI,QAAAA,aAAAA,iBAAgBC,cAAA,CAAA,aAAA,CAACE,gBAAAA,EAAAA;YAAiBC,IAAAA,EAAM;;AAC1C,IAAA;AAEA,IAAA,qBACEH,cAAA,CAAA,aAAA,CAACF,OAAAA,EAAAA;AAAQM,QAAAA,SAAAA,EAAWrB,gBAAAA,CAAiBO,KAAAA,CAAAA;QAAQI,OAAAA,EAASA,OAAAA;QAASE,QAAAA,EAAUA,QAAAA;AAAW,QAAA,GAAGC;AACpFE,KAAAA,EAAAA,aAAAA,CAAAA;AAGP,CAAA;AAEA,MAAMM,MAAAA,GAAS,CAACf,KAAAA,GACdD,UAAAA,CAAW;QACTiB,IAAAA,EAAM,QAAA;QACNf,EAAAA,EAAI,QAAA;AACJ,QAAA,GAAGD;AACL,KAAA;AAYK,MAAMiB,YAAAA,GAAe,CAACjB,KAAAA,GAC3BD,UAAAA,CAAW;AACT,QAAA,GAAGC,KAAK;;;AAGRkB,QAAAA,SAAAA,EAAW,CAACC,GAAAA,GAAAA;AACVnB,YAAAA,KAAAA,CAAMkB,SAAS,GAAGC,GAAAA,CAAAA;YAClB,IAAIA,GAAAA,CAAIC,gBAAgB,EAAE;AAC1B,YAAA,IAAID,IAAIE,GAAG,KAAK,KAAKF,GAAAA,CAAIG,aAAa,CAACC,KAAK,EAAA;AAC9C,QAAA,CAAA;QACAtB,EAAAA,EAAI;KACN;;;;"}
@@ -6,7 +6,7 @@ import Input from './Input.mjs';
6
6
  const EmailInput = ({ email, setEmail, hasPasskeys = false, ...additionalProps })=>{
7
7
  const { i18n: $__i18n, _: $__ } = useLingui();
8
8
  return /*#__PURE__*/ React__default.createElement(Input, {
9
- id: "email",
9
+ id: "email-input",
10
10
  label: $__i18n._({
11
11
  id: "formField.email.label",
12
12
  message: "Email"
@@ -1 +1 @@
1
- {"version":3,"file":"EmailInput.mjs","sources":["../../../../../../../../../web/src/ui/components/molecules/EmailInput.tsx"],"sourcesContent":["import React from 'react';\nimport { useLingui } from '@lingui/react/macro';\nimport { passwordManagerDisableAutofillProps } from '../../../utils/passwordManagerDisableAutofillProps';\nimport Input from './Input';\n\nconst EmailInput = ({\n email,\n setEmail,\n hasPasskeys = false,\n ...additionalProps\n}: {\n email: string;\n setEmail: (email: string) => void;\n hasPasskeys?: boolean;\n\n // Passed through\n hideLabel?: boolean;\n disabled?: boolean;\n error?: string;\n}) => {\n const { t } = useLingui();\n return (\n <Input\n id=\"email\"\n label={t({ id: 'formField.email.label', message: 'Email' })}\n placeholder={t({ id: 'formField.email.placeholder', message: 'example@email.com' })}\n type=\"email\"\n autoComplete={hasPasskeys ? 'username webauthn' : 'email'}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n // We want to block 1PW's autofill when passkeys is enabled for now\n // (it is breaking to our integration)\n {...(hasPasskeys ? passwordManagerDisableAutofillProps : {})}\n {...additionalProps}\n />\n );\n};\n\nexport default EmailInput;\n"],"names":["EmailInput","email","setEmail","hasPasskeys","additionalProps","useLingui","React","Input","id","label","placeholder","type","autoComplete","value","onChange","e","target","required","passwordManagerDisableAutofillProps"],"mappings":";;;;;AAKA,MAAMA,UAAAA,GAAa,CAAC,EAClBC,KAAK,EACLC,QAAQ,EACRC,WAAAA,GAAc,KAAK,EACnB,GAAGC,eAAAA,EAUJ,GAAA;AACC,IAAA,MAAM,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,GAAA,EAAA,GAAQC,SAAAA,EAAAA;AACd,IAAA,qBACEC,cAAA,CAAA,aAAA,CAACC,KAAAA,EAAAA;QACCC,EAAAA,EAAG,OAAA;QACHC,KAAK,EAAA,OAAA,CAAA,CAAA,CAAA;;;;QACLC,WAAW,EAAA,OAAA,CAAA,CAAA,CAAA;;;;QACXC,IAAAA,EAAK,OAAA;AACLC,QAAAA,YAAAA,EAAcT,cAAc,mBAAA,GAAsB,OAAA;QAClDU,KAAAA,EAAOZ,KAAAA;AACPa,QAAAA,QAAAA,EAAU,CAACC,CAAAA,GAAMb,QAAAA,CAASa,CAAAA,CAAEC,MAAM,CAACH,KAAK,CAAA;QACxCI,QAAAA,EAAAA,IAAAA;QAGC,GAAId,WAAAA,GAAce,mCAAAA,GAAsC,EAAE;AAC1D,QAAA,GAAGd;;AAGV;;;;"}
1
+ {"version":3,"file":"EmailInput.mjs","sources":["../../../../../../../../../web/src/ui/components/molecules/EmailInput.tsx"],"sourcesContent":["import React from 'react';\nimport { useLingui } from '@lingui/react/macro';\nimport { passwordManagerDisableAutofillProps } from '../../../utils/passwordManagerDisableAutofillProps';\nimport Input from './Input';\n\nconst EmailInput = ({\n email,\n setEmail,\n hasPasskeys = false,\n ...additionalProps\n}: {\n email: string;\n setEmail: (email: string) => void;\n hasPasskeys?: boolean;\n\n // Passed through\n hideLabel?: boolean;\n disabled?: boolean;\n error?: string;\n}) => {\n const { t } = useLingui();\n return (\n <Input\n id=\"email-input\"\n label={t({ id: 'formField.email.label', message: 'Email' })}\n placeholder={t({ id: 'formField.email.placeholder', message: 'example@email.com' })}\n type=\"email\"\n autoComplete={hasPasskeys ? 'username webauthn' : 'email'}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n // We want to block 1PW's autofill when passkeys is enabled for now\n // (it is breaking to our integration)\n {...(hasPasskeys ? passwordManagerDisableAutofillProps : {})}\n {...additionalProps}\n />\n );\n};\n\nexport default EmailInput;\n"],"names":["EmailInput","email","setEmail","hasPasskeys","additionalProps","useLingui","React","Input","id","label","placeholder","type","autoComplete","value","onChange","e","target","required","passwordManagerDisableAutofillProps"],"mappings":";;;;;AAKA,MAAMA,UAAAA,GAAa,CAAC,EAClBC,KAAK,EACLC,QAAQ,EACRC,WAAAA,GAAc,KAAK,EACnB,GAAGC,eAAAA,EAUJ,GAAA;AACC,IAAA,MAAM,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,GAAA,EAAA,GAAQC,SAAAA,EAAAA;AACd,IAAA,qBACEC,cAAA,CAAA,aAAA,CAACC,KAAAA,EAAAA;QACCC,EAAAA,EAAG,aAAA;QACHC,KAAK,EAAA,OAAA,CAAA,CAAA,CAAA;;;;QACLC,WAAW,EAAA,OAAA,CAAA,CAAA,CAAA;;;;QACXC,IAAAA,EAAK,OAAA;AACLC,QAAAA,YAAAA,EAAcT,cAAc,mBAAA,GAAsB,OAAA;QAClDU,KAAAA,EAAOZ,KAAAA;AACPa,QAAAA,QAAAA,EAAU,CAACC,CAAAA,GAAMb,QAAAA,CAASa,CAAAA,CAAEC,MAAM,CAACH,KAAK,CAAA;QACxCI,QAAAA,EAAAA,IAAAA;QAGC,GAAId,WAAAA,GAAce,mCAAAA,GAAsC,EAAE;AAC1D,QAAA,GAAGd;;AAGV;;;;"}
@@ -12,7 +12,7 @@ import { usePresentation } from '../PresentationConfig.mjs';
12
12
  * You may want to use a more specific component in /molecules instead like {@link EmailInput}, {@link PasswordInput}
13
13
  */ const Input = /*#__PURE__*/ forwardRef(({ className, label: labelText, hideLabel, action, id: idProp, containerClassName, error, ...props }, ref)=>{
14
14
  const presentation = usePresentation();
15
- const id = idProp + (presentation.options?.inputIdSuffix || '');
15
+ const id = idProp + (presentation.options?.inputIdSuffix ?? '');
16
16
  const errorId = useUniqueId();
17
17
  // Calculate the width of the action element and add it to the input padding so the input content
18
18
  // cannot go behind the action
@@ -1 +1 @@
1
- {"version":3,"file":"Input.mjs","sources":["../../../../../../../../../web/src/ui/components/molecules/Input.tsx"],"sourcesContent":["import React, { forwardRef, InputHTMLAttributes, ReactNode, useLayoutEffect, useRef, useState } from 'react';\nimport classNames from 'classnames';\nimport { useUniqueId } from '../../../utils/uniqueId';\nimport ErrorText from './ErrorText';\nimport VisuallyHidden from '../atoms/VisuallyHidden';\nimport styles from './Input.module.css';\nimport { usePresentation } from '../PresentationConfig';\n\nexport type InputProps = InputHTMLAttributes<HTMLInputElement> & {\n label: string;\n id: string;\n containerClassName?: string;\n hideLabel?: boolean;\n action?: ReactNode;\n error?: string;\n};\n\n/**\n * Generic low level text Input element\n * A label must be provided for accessibility, but can be hidden using the `hideLabel` prop\n * You may want to use a more specific component in /molecules instead like {@link EmailInput}, {@link PasswordInput}\n */\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n ({ className, label: labelText, hideLabel, action, id: idProp, containerClassName, error, ...props }, ref) => {\n const presentation = usePresentation();\n const id = idProp + (presentation.options?.inputIdSuffix || '');\n\n const errorId = useUniqueId();\n\n // Calculate the width of the action element and add it to the input padding so the input content\n // cannot go behind the action\n const actionRef = useRef<HTMLDivElement>(null);\n const [actionWidth, setActionWidth] = useState<number>();\n useLayoutEffect(() => {\n if (actionRef.current) {\n // getBoundingClientRect accounts for transformations while clientWidth does not\n setActionWidth(actionRef.current.getBoundingClientRect().width);\n }\n }, [action]);\n\n const label = (\n <label className={styles.label} htmlFor={id}>\n {labelText}\n </label>\n );\n\n if (error) {\n props['aria-invalid'] = true;\n props['aria-errormessage'] = errorId;\n }\n\n return (\n <div className={classNames(containerClassName, styles.container)}>\n {hideLabel ? <VisuallyHidden>{label}</VisuallyHidden> : label}\n\n <div className={styles.inputWrapper}>\n <input\n ref={ref}\n id={id}\n className={classNames(className, styles.input)}\n style={\n actionWidth\n ? {\n // spacing-4 because action has a 2 unit horizontal margin\n paddingInlineEnd: `calc(${actionWidth}px + var(--st-spacing-4))`,\n }\n : undefined\n }\n {...props}\n />\n {action && (\n <div ref={actionRef} className={styles.action}>\n {action}\n </div>\n )}\n </div>\n\n {error && (\n <ErrorText id={errorId} className={styles.error} aria-live=\"polite\">\n {error}\n </ErrorText>\n )}\n </div>\n );\n },\n);\n\nexport default Input;\n"],"names":["Input","forwardRef","className","label","labelText","hideLabel","action","id","idProp","containerClassName","error","props","ref","presentation","usePresentation","options","inputIdSuffix","errorId","useUniqueId","actionRef","useRef","actionWidth","setActionWidth","useState","useLayoutEffect","current","getBoundingClientRect","width","React","styles","htmlFor","div","classNames","container","VisuallyHidden","inputWrapper","input","style","paddingInlineEnd","undefined","ErrorText","aria-live"],"mappings":";;;;;;;;AAiBA;;;;IAKA,MAAMA,sBAAQC,UAAAA,CACZ,CAAC,EAAEC,SAAS,EAAEC,KAAAA,EAAOC,SAAS,EAAEC,SAAS,EAAEC,MAAM,EAAEC,EAAAA,EAAIC,MAAM,EAAEC,kBAAkB,EAAEC,KAAK,EAAE,GAAGC,KAAAA,EAAO,EAAEC,GAAAA,GAAAA;AACpG,IAAA,MAAMC,YAAAA,GAAeC,eAAAA,EAAAA;AACrB,IAAA,MAAMP,KAAKC,MAAAA,IAAUK,aAAaE,OAAO,EAAEC,iBAAiB,EAAC,CAAA;AAE7D,IAAA,MAAMC,OAAAA,GAAUC,WAAAA,EAAAA;;;AAIhB,IAAA,MAAMC,YAAYC,MAAAA,CAAuB,IAAA,CAAA;IACzC,MAAM,CAACC,WAAAA,EAAaC,cAAAA,CAAe,GAAGC,QAAAA,EAAAA;IACtCC,eAAAA,CAAgB,IAAA;QACd,IAAIL,SAAAA,CAAUM,OAAO,EAAE;;AAErBH,YAAAA,cAAAA,CAAeH,SAAAA,CAAUM,OAAO,CAACC,qBAAqB,GAAGC,KAAK,CAAA;AAChE,QAAA;IACF,CAAA,EAAG;AAACrB,QAAAA;AAAO,KAAA,CAAA;AAEX,IAAA,MAAMH,sBACJyB,cAAA,CAAA,aAAA,CAACzB,OAAAA,EAAAA;AAAMD,QAAAA,SAAAA,EAAW2B,iBAAO1B,KAAK;QAAE2B,OAAAA,EAASvB;AACtCH,KAAAA,EAAAA,SAAAA,CAAAA;AAIL,IAAA,IAAIM,KAAAA,EAAO;QACTC,KAAK,CAAC,eAAe,GAAG,IAAA;QACxBA,KAAK,CAAC,oBAAoB,GAAGM,OAAAA;AAC/B,IAAA;AAEA,IAAA,qBACEW,cAAA,CAAA,aAAA,CAACG,KAAAA,EAAAA;QAAI7B,SAAAA,EAAW8B,UAAAA,CAAWvB,kBAAAA,EAAoBoB,gBAAAA,CAAOI,SAAS;AAC5D5B,KAAAA,EAAAA,SAAAA,iBAAYuB,cAAA,CAAA,aAAA,CAACM,cAAAA,EAAAA,IAAAA,EAAgB/B,KAAAA,CAAAA,GAA0BA,KAAAA,gBAExDyB,cAAA,CAAA,aAAA,CAACG,KAAAA,EAAAA;AAAI7B,QAAAA,SAAAA,EAAW2B,iBAAOM;qBACrBP,cAAA,CAAA,aAAA,CAACQ,OAAAA,EAAAA;QACCxB,GAAAA,EAAKA,GAAAA;QACLL,EAAAA,EAAIA,EAAAA;QACJL,SAAAA,EAAW8B,UAAAA,CAAW9B,SAAAA,EAAW2B,gBAAAA,CAAOO,KAAK,CAAA;AAC7CC,QAAAA,KAAAA,EACEhB,WAAAA,GACI;;AAEEiB,YAAAA,gBAAAA,EAAkB,CAAC,KAAK,EAAEjB,WAAAA,CAAY,yBAAyB;SACjE,GACAkB,SAAAA;AAEL,QAAA,GAAG5B;AAELL,KAAAA,CAAAA,EAAAA,MAAAA,kBACCsB,cAAA,CAAA,aAAA,CAACG,KAAAA,EAAAA;QAAInB,GAAAA,EAAKO,SAAAA;AAAWjB,QAAAA,SAAAA,EAAW2B,iBAAOvB;AACpCA,KAAAA,EAAAA,MAAAA,CAAAA,CAAAA,EAKNI,uBACCkB,cAAA,CAAA,aAAA,CAACY,SAAAA,EAAAA;QAAUjC,EAAAA,EAAIU,OAAAA;AAASf,QAAAA,SAAAA,EAAW2B,iBAAOnB,KAAK;QAAE+B,WAAAA,EAAU;AACxD/B,KAAAA,EAAAA,KAAAA,CAAAA,CAAAA;AAKX,CAAA;;;;"}
1
+ {"version":3,"file":"Input.mjs","sources":["../../../../../../../../../web/src/ui/components/molecules/Input.tsx"],"sourcesContent":["import React, { forwardRef, InputHTMLAttributes, ReactNode, useLayoutEffect, useRef, useState } from 'react';\nimport classNames from 'classnames';\nimport { useUniqueId } from '../../../utils/uniqueId';\nimport ErrorText from './ErrorText';\nimport VisuallyHidden from '../atoms/VisuallyHidden';\nimport styles from './Input.module.css';\nimport { usePresentation } from '../PresentationConfig';\n\nexport type InputProps = InputHTMLAttributes<HTMLInputElement> & {\n label: string;\n id: string;\n containerClassName?: string;\n hideLabel?: boolean;\n action?: ReactNode;\n error?: string;\n};\n\n/**\n * Generic low level text Input element\n * A label must be provided for accessibility, but can be hidden using the `hideLabel` prop\n * You may want to use a more specific component in /molecules instead like {@link EmailInput}, {@link PasswordInput}\n */\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n ({ className, label: labelText, hideLabel, action, id: idProp, containerClassName, error, ...props }, ref) => {\n const presentation = usePresentation();\n const id = idProp + (presentation.options?.inputIdSuffix ?? '');\n\n const errorId = useUniqueId();\n\n // Calculate the width of the action element and add it to the input padding so the input content\n // cannot go behind the action\n const actionRef = useRef<HTMLDivElement>(null);\n const [actionWidth, setActionWidth] = useState<number>();\n useLayoutEffect(() => {\n if (actionRef.current) {\n // getBoundingClientRect accounts for transformations while clientWidth does not\n setActionWidth(actionRef.current.getBoundingClientRect().width);\n }\n }, [action]);\n\n const label = (\n <label className={styles.label} htmlFor={id}>\n {labelText}\n </label>\n );\n\n if (error) {\n props['aria-invalid'] = true;\n props['aria-errormessage'] = errorId;\n }\n\n return (\n <div className={classNames(containerClassName, styles.container)}>\n {hideLabel ? <VisuallyHidden>{label}</VisuallyHidden> : label}\n\n <div className={styles.inputWrapper}>\n <input\n ref={ref}\n id={id}\n className={classNames(className, styles.input)}\n style={\n actionWidth\n ? {\n // spacing-4 because action has a 2 unit horizontal margin\n paddingInlineEnd: `calc(${actionWidth}px + var(--st-spacing-4))`,\n }\n : undefined\n }\n {...props}\n />\n {action && (\n <div ref={actionRef} className={styles.action}>\n {action}\n </div>\n )}\n </div>\n\n {error && (\n <ErrorText id={errorId} className={styles.error} aria-live=\"polite\">\n {error}\n </ErrorText>\n )}\n </div>\n );\n },\n);\n\nexport default Input;\n"],"names":["Input","forwardRef","className","label","labelText","hideLabel","action","id","idProp","containerClassName","error","props","ref","presentation","usePresentation","options","inputIdSuffix","errorId","useUniqueId","actionRef","useRef","actionWidth","setActionWidth","useState","useLayoutEffect","current","getBoundingClientRect","width","React","styles","htmlFor","div","classNames","container","VisuallyHidden","inputWrapper","input","style","paddingInlineEnd","undefined","ErrorText","aria-live"],"mappings":";;;;;;;;AAiBA;;;;IAKA,MAAMA,sBAAQC,UAAAA,CACZ,CAAC,EAAEC,SAAS,EAAEC,KAAAA,EAAOC,SAAS,EAAEC,SAAS,EAAEC,MAAM,EAAEC,EAAAA,EAAIC,MAAM,EAAEC,kBAAkB,EAAEC,KAAK,EAAE,GAAGC,KAAAA,EAAO,EAAEC,GAAAA,GAAAA;AACpG,IAAA,MAAMC,YAAAA,GAAeC,eAAAA,EAAAA;AACrB,IAAA,MAAMP,KAAKC,MAAAA,IAAUK,aAAaE,OAAO,EAAEC,iBAAiB,EAAC,CAAA;AAE7D,IAAA,MAAMC,OAAAA,GAAUC,WAAAA,EAAAA;;;AAIhB,IAAA,MAAMC,YAAYC,MAAAA,CAAuB,IAAA,CAAA;IACzC,MAAM,CAACC,WAAAA,EAAaC,cAAAA,CAAe,GAAGC,QAAAA,EAAAA;IACtCC,eAAAA,CAAgB,IAAA;QACd,IAAIL,SAAAA,CAAUM,OAAO,EAAE;;AAErBH,YAAAA,cAAAA,CAAeH,SAAAA,CAAUM,OAAO,CAACC,qBAAqB,GAAGC,KAAK,CAAA;AAChE,QAAA;IACF,CAAA,EAAG;AAACrB,QAAAA;AAAO,KAAA,CAAA;AAEX,IAAA,MAAMH,sBACJyB,cAAA,CAAA,aAAA,CAACzB,OAAAA,EAAAA;AAAMD,QAAAA,SAAAA,EAAW2B,iBAAO1B,KAAK;QAAE2B,OAAAA,EAASvB;AACtCH,KAAAA,EAAAA,SAAAA,CAAAA;AAIL,IAAA,IAAIM,KAAAA,EAAO;QACTC,KAAK,CAAC,eAAe,GAAG,IAAA;QACxBA,KAAK,CAAC,oBAAoB,GAAGM,OAAAA;AAC/B,IAAA;AAEA,IAAA,qBACEW,cAAA,CAAA,aAAA,CAACG,KAAAA,EAAAA;QAAI7B,SAAAA,EAAW8B,UAAAA,CAAWvB,kBAAAA,EAAoBoB,gBAAAA,CAAOI,SAAS;AAC5D5B,KAAAA,EAAAA,SAAAA,iBAAYuB,cAAA,CAAA,aAAA,CAACM,cAAAA,EAAAA,IAAAA,EAAgB/B,KAAAA,CAAAA,GAA0BA,KAAAA,gBAExDyB,cAAA,CAAA,aAAA,CAACG,KAAAA,EAAAA;AAAI7B,QAAAA,SAAAA,EAAW2B,iBAAOM;qBACrBP,cAAA,CAAA,aAAA,CAACQ,OAAAA,EAAAA;QACCxB,GAAAA,EAAKA,GAAAA;QACLL,EAAAA,EAAIA,EAAAA;QACJL,SAAAA,EAAW8B,UAAAA,CAAW9B,SAAAA,EAAW2B,gBAAAA,CAAOO,KAAK,CAAA;AAC7CC,QAAAA,KAAAA,EACEhB,WAAAA,GACI;;AAEEiB,YAAAA,gBAAAA,EAAkB,CAAC,KAAK,EAAEjB,WAAAA,CAAY,yBAAyB;SACjE,GACAkB,SAAAA;AAEL,QAAA,GAAG5B;AAELL,KAAAA,CAAAA,EAAAA,MAAAA,kBACCsB,cAAA,CAAA,aAAA,CAACG,KAAAA,EAAAA;QAAInB,GAAAA,EAAKO,SAAAA;AAAWjB,QAAAA,SAAAA,EAAW2B,iBAAOvB;AACpCA,KAAAA,EAAAA,MAAAA,CAAAA,CAAAA,EAKNI,uBACCkB,cAAA,CAAA,aAAA,CAACY,SAAAA,EAAAA;QAAUjC,EAAAA,EAAIU,OAAAA;AAASf,QAAAA,SAAAA,EAAW2B,iBAAOnB,KAAK;QAAE+B,WAAAA,EAAU;AACxD/B,KAAAA,EAAAA,KAAAA,CAAAA,CAAAA;AAKX,CAAA;;;;"}
@@ -1,7 +1,7 @@
1
- import { b as bs58Exports } from '../../../../_virtual/index3.mjs';
1
+ import { b as bs58Exports } from '../../../../_virtual/index4.mjs';
2
2
  import 'react';
3
3
  import { GenericWalletIcon } from '../assets/genericWallet.mjs';
4
- import { usePresentation } from '../ui/components/PresentationConfig.mjs';
4
+ import { usePresentation, getButtonId } from '../ui/components/PresentationConfig.mjs';
5
5
  import { Wallets } from '../../../core/src/public/ui.mjs';
6
6
 
7
7
  const hasMultipleEthereumWallets = ()=>!!window.ethereum?.providers;
@@ -17,11 +17,15 @@ const walletIcons = {
17
17
  [Wallets.Coinbase]: 'coinbase',
18
18
  [Wallets.Metamask]: 'metamask'
19
19
  };
20
- const useCryptoIcon = ()=>{
21
- const iconRegistry = usePresentation().iconRegistry;
22
- return (wallet)=>{
23
- const iconName = walletIcons[wallet];
24
- return iconName ? iconRegistry[iconName] : GenericWalletIcon;
20
+ const useCryptoButtonProps = ()=>{
21
+ const presentation = usePresentation();
22
+ const iconRegistry = presentation.iconRegistry;
23
+ return {
24
+ getIcon: (wallet)=>{
25
+ const iconName = walletIcons[wallet];
26
+ return iconName ? iconRegistry[iconName] : GenericWalletIcon;
27
+ },
28
+ getId: (wallet)=>getButtonId(`wallet-${wallet}`, presentation.options)
25
29
  };
26
30
  };
27
31
  const WalletToText = {
@@ -168,5 +172,5 @@ const isSolanaWallet = (wallet)=>{
168
172
  return solanaWallets.includes(wallet);
169
173
  };
170
174
 
171
- export { WalletToText, connectWithWallet, isSolanaWallet, isWalletVisible, signMessageWithWallet, useCryptoIcon, walletIcons };
175
+ export { WalletToText, connectWithWallet, isSolanaWallet, isWalletVisible, signMessageWithWallet, useCryptoButtonProps, walletIcons };
172
176
  //# sourceMappingURL=crypto.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.mjs","sources":["../../../../../../../web/src/utils/crypto.tsx"],"sourcesContent":["import { MessageDescriptor } from '@lingui/core';\nimport { msg } from '@lingui/core/macro';\nimport { Wallets } from '@stytch/core/public';\nimport { encode } from 'bs58';\n\nimport { GenericWalletIcon } from '../assets';\nimport { cryptoIcons } from '../ui/b2c/components/Icons';\nimport { IconRegistry } from '../ui/components/IconRegistry';\nimport { usePresentation } from '../ui/components/PresentationConfig';\n\ntype ProviderRequest = ({\n method,\n params,\n}: {\n method: 'eth_requestAccounts' | 'personal_sign';\n params?: string[];\n}) => string[] | string;\n\ntype ETHProvider = {\n isMetaMask?: boolean;\n isCoinbaseWallet?: boolean;\n request: ProviderRequest;\n};\n\ndeclare global {\n interface Window {\n solana: {\n isPhantom?: boolean;\n connect: () => { publicKey: { toString: () => string } };\n request: ({\n method,\n params,\n }: {\n method: 'signMessage';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params: Record<string, any>;\n }) => { signature: Uint8Array };\n };\n\n ethereum: {\n isMetaMask?: boolean;\n isCoinbaseWallet?: boolean;\n request?: ({ method, params }: { method: string; params?: string[] }) => string[] | string;\n providers?: ETHProvider[];\n };\n\n BinanceChain: { request: ProviderRequest };\n }\n}\n\nconst hasMultipleEthereumWallets = () => !!window.ethereum?.providers;\n\nconst hasMetaMask = () =>\n !!(hasMultipleEthereumWallets()\n ? window.ethereum.providers?.find((wallet) => wallet.isMetaMask)\n : window.ethereum.isMetaMask);\n\nconst hasCoinbaseWallet = () =>\n !!(hasMultipleEthereumWallets()\n ? window.ethereum.providers?.find((wallet) => wallet.isCoinbaseWallet)\n : window.ethereum?.isCoinbaseWallet);\n\nconst hasOtherEthereumWallet = () => !hasMetaMask() && !hasCoinbaseWallet() && !!window.ethereum;\n\nconst getMetaMaskProvider = () =>\n hasMultipleEthereumWallets() ? window.ethereum.providers?.find((wallet) => wallet.isMetaMask) : window.ethereum;\n\nconst getCoinbaseProvider = () =>\n hasMultipleEthereumWallets() ? window.ethereum.providers?.find((wallet) => wallet.isCoinbaseWallet) : window.ethereum;\n\nconst getOtherInjectedProvider = () =>\n window.ethereum.providers?.find((wallet) => !wallet.isCoinbaseWallet && !wallet.isMetaMask);\n\ntype CryptoIcon = keyof typeof cryptoIcons;\nexport const walletIcons: Partial<Record<Wallets, CryptoIcon>> = {\n [Wallets.Phantom]: 'phantom',\n [Wallets.Binance]: 'binance',\n [Wallets.Coinbase]: 'coinbase',\n [Wallets.Metamask]: 'metamask',\n};\n\nexport const useCryptoIcon = () => {\n const iconRegistry: IconRegistry<CryptoIcon> = usePresentation().iconRegistry;\n return (wallet: Wallets) => {\n const iconName = walletIcons[wallet];\n return iconName ? iconRegistry[iconName] : GenericWalletIcon;\n };\n};\n\nexport const WalletToText: Record<Wallets, MessageDescriptor> = {\n [Wallets.Phantom]: msg({ id: 'crypto.wallet.phantom', message: 'Phantom' }),\n [Wallets.Binance]: msg({ id: 'crypto.wallet.binance', message: 'Binance' }),\n [Wallets.Coinbase]: msg({ id: 'crypto.wallet.coinbase', message: 'Coinbase' }),\n [Wallets.Metamask]: msg({ id: 'crypto.wallet.metamask', message: 'Metamask' }),\n [Wallets.GenericEthereumWallet]: msg({ id: 'crypto.wallet.otherEthereum', message: 'Other Ethereum Wallet' }),\n [Wallets.GenericSolanaWallet]: msg({ id: 'crypto.wallet.otherSolana', message: 'Other Solana Wallet' }),\n};\n\nexport const isWalletVisible = (wallet: Wallets): boolean => {\n switch (wallet) {\n case Wallets.Metamask:\n return !!window.ethereum && hasMetaMask();\n case Wallets.Phantom:\n return (!!window.solana && window.solana?.isPhantom) ?? false;\n case Wallets.Binance:\n return !!window.BinanceChain;\n case Wallets.Coinbase:\n return !!window.ethereum && hasCoinbaseWallet();\n case Wallets.GenericEthereumWallet:\n return !!window.ethereum && hasOtherEthereumWallet();\n case Wallets.GenericSolanaWallet:\n return !!window.solana && !window.solana.isPhantom;\n default:\n return false;\n }\n};\n\nconst connectWithEthereumProvider = async (request: ProviderRequest): Promise<string> => {\n const [address] = await request({\n method: 'eth_requestAccounts',\n });\n return address;\n};\n\nexport const connectWithWallet = async ({ wallet }: { wallet: Wallets }): Promise<string> => {\n switch (wallet) {\n case Wallets.Metamask: {\n const provider = getMetaMaskProvider();\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.Phantom: {\n const connectResp = await window.solana.connect();\n return connectResp.publicKey.toString();\n }\n case Wallets.Binance: {\n const provider = window.BinanceChain;\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.Coinbase: {\n const provider = getCoinbaseProvider();\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.GenericEthereumWallet: {\n const provider = getOtherInjectedProvider();\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.GenericSolanaWallet: {\n const connectResp = await window.solana.connect();\n return connectResp.publicKey.toString();\n }\n default:\n return '';\n }\n};\n\nconst signMessageWithSolanaProvider = async (message: string): Promise<string> => {\n const encodedMessage = new TextEncoder().encode(message);\n const signResp = await window.solana.request({\n method: 'signMessage',\n params: {\n message: encodedMessage,\n display: 'utf8',\n },\n });\n return encode(signResp.signature);\n};\n\nconst signMessageWithEthereumProvider = async (\n request: ProviderRequest,\n message: string,\n address: string,\n): Promise<string> => {\n const signature = await request({\n method: 'personal_sign',\n params: [message, address],\n });\n return signature as string;\n};\n\nexport const signMessageWithWallet = async ({\n wallet,\n message,\n address,\n}: {\n wallet: Wallets;\n message: string;\n address: string;\n}): Promise<string> => {\n switch (wallet) {\n case Wallets.Phantom:\n case Wallets.GenericSolanaWallet:\n return signMessageWithSolanaProvider(message);\n case Wallets.Metamask: {\n const provider = getMetaMaskProvider();\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n case Wallets.Binance: {\n const provider = window.BinanceChain;\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n case Wallets.Coinbase: {\n const provider = getCoinbaseProvider();\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n case Wallets.GenericEthereumWallet: {\n const provider = getOtherInjectedProvider();\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n default:\n return '';\n }\n};\n\nexport const isSolanaWallet = (wallet: Wallets) => {\n const solanaWallets: Wallets[] = [Wallets.Phantom, Wallets.GenericSolanaWallet];\n return solanaWallets.includes(wallet);\n};\n\nexport const isEthereumWallet = (wallet: Wallets) => {\n const ethWallets: Wallets[] = [Wallets.Binance, Wallets.GenericEthereumWallet, Wallets.Coinbase, Wallets.Metamask];\n return ethWallets.includes(wallet);\n};\n"],"names":["hasMultipleEthereumWallets","window","ethereum","providers","hasMetaMask","find","wallet","isMetaMask","hasCoinbaseWallet","isCoinbaseWallet","hasOtherEthereumWallet","getMetaMaskProvider","getCoinbaseProvider","getOtherInjectedProvider","walletIcons","Wallets","Phantom","Binance","Coinbase","Metamask","useCryptoIcon","iconRegistry","usePresentation","iconName","GenericWalletIcon","WalletToText","GenericEthereumWallet","GenericSolanaWallet","isWalletVisible","solana","isPhantom","BinanceChain","connectWithEthereumProvider","request","address","method","connectWithWallet","provider","connectResp","connect","publicKey","toString","signMessageWithSolanaProvider","message","encodedMessage","TextEncoder","encode","signResp","params","display","signature","signMessageWithEthereumProvider","signMessageWithWallet","isSolanaWallet","solanaWallets","includes"],"mappings":"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"}
1
+ {"version":3,"file":"crypto.mjs","sources":["../../../../../../../web/src/utils/crypto.tsx"],"sourcesContent":["import { MessageDescriptor } from '@lingui/core';\nimport { msg } from '@lingui/core/macro';\nimport { Wallets } from '@stytch/core/public';\nimport { encode } from 'bs58';\n\nimport { GenericWalletIcon } from '../assets';\nimport { cryptoIcons } from '../ui/b2c/components/Icons';\nimport { IconRegistry } from '../ui/components/IconRegistry';\nimport { getButtonId, usePresentation } from '../ui/components/PresentationConfig';\n\ntype ProviderRequest = ({\n method,\n params,\n}: {\n method: 'eth_requestAccounts' | 'personal_sign';\n params?: string[];\n}) => string[] | string;\n\ntype ETHProvider = {\n isMetaMask?: boolean;\n isCoinbaseWallet?: boolean;\n request: ProviderRequest;\n};\n\ndeclare global {\n interface Window {\n solana: {\n isPhantom?: boolean;\n connect: () => { publicKey: { toString: () => string } };\n request: ({\n method,\n params,\n }: {\n method: 'signMessage';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params: Record<string, any>;\n }) => { signature: Uint8Array };\n };\n\n ethereum: {\n isMetaMask?: boolean;\n isCoinbaseWallet?: boolean;\n request?: ({ method, params }: { method: string; params?: string[] }) => string[] | string;\n providers?: ETHProvider[];\n };\n\n BinanceChain: { request: ProviderRequest };\n }\n}\n\nconst hasMultipleEthereumWallets = () => !!window.ethereum?.providers;\n\nconst hasMetaMask = () =>\n !!(hasMultipleEthereumWallets()\n ? window.ethereum.providers?.find((wallet) => wallet.isMetaMask)\n : window.ethereum.isMetaMask);\n\nconst hasCoinbaseWallet = () =>\n !!(hasMultipleEthereumWallets()\n ? window.ethereum.providers?.find((wallet) => wallet.isCoinbaseWallet)\n : window.ethereum?.isCoinbaseWallet);\n\nconst hasOtherEthereumWallet = () => !hasMetaMask() && !hasCoinbaseWallet() && !!window.ethereum;\n\nconst getMetaMaskProvider = () =>\n hasMultipleEthereumWallets() ? window.ethereum.providers?.find((wallet) => wallet.isMetaMask) : window.ethereum;\n\nconst getCoinbaseProvider = () =>\n hasMultipleEthereumWallets() ? window.ethereum.providers?.find((wallet) => wallet.isCoinbaseWallet) : window.ethereum;\n\nconst getOtherInjectedProvider = () =>\n window.ethereum.providers?.find((wallet) => !wallet.isCoinbaseWallet && !wallet.isMetaMask);\n\ntype CryptoIcon = keyof typeof cryptoIcons;\nexport const walletIcons: Partial<Record<Wallets, CryptoIcon>> = {\n [Wallets.Phantom]: 'phantom',\n [Wallets.Binance]: 'binance',\n [Wallets.Coinbase]: 'coinbase',\n [Wallets.Metamask]: 'metamask',\n};\n\nexport const useCryptoButtonProps = () => {\n const presentation = usePresentation();\n const iconRegistry: IconRegistry<CryptoIcon> = presentation.iconRegistry;\n\n return {\n getIcon: (wallet: Wallets) => {\n const iconName = walletIcons[wallet];\n return iconName ? iconRegistry[iconName] : GenericWalletIcon;\n },\n getId: (wallet: Wallets) => getButtonId(`wallet-${wallet}`, presentation.options),\n };\n};\n\nexport const WalletToText: Record<Wallets, MessageDescriptor> = {\n [Wallets.Phantom]: msg({ id: 'crypto.wallet.phantom', message: 'Phantom' }),\n [Wallets.Binance]: msg({ id: 'crypto.wallet.binance', message: 'Binance' }),\n [Wallets.Coinbase]: msg({ id: 'crypto.wallet.coinbase', message: 'Coinbase' }),\n [Wallets.Metamask]: msg({ id: 'crypto.wallet.metamask', message: 'Metamask' }),\n [Wallets.GenericEthereumWallet]: msg({ id: 'crypto.wallet.otherEthereum', message: 'Other Ethereum Wallet' }),\n [Wallets.GenericSolanaWallet]: msg({ id: 'crypto.wallet.otherSolana', message: 'Other Solana Wallet' }),\n};\n\nexport const isWalletVisible = (wallet: Wallets): boolean => {\n switch (wallet) {\n case Wallets.Metamask:\n return !!window.ethereum && hasMetaMask();\n case Wallets.Phantom:\n return (!!window.solana && window.solana?.isPhantom) ?? false;\n case Wallets.Binance:\n return !!window.BinanceChain;\n case Wallets.Coinbase:\n return !!window.ethereum && hasCoinbaseWallet();\n case Wallets.GenericEthereumWallet:\n return !!window.ethereum && hasOtherEthereumWallet();\n case Wallets.GenericSolanaWallet:\n return !!window.solana && !window.solana.isPhantom;\n default:\n return false;\n }\n};\n\nconst connectWithEthereumProvider = async (request: ProviderRequest): Promise<string> => {\n const [address] = await request({\n method: 'eth_requestAccounts',\n });\n return address;\n};\n\nexport const connectWithWallet = async ({ wallet }: { wallet: Wallets }): Promise<string> => {\n switch (wallet) {\n case Wallets.Metamask: {\n const provider = getMetaMaskProvider();\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.Phantom: {\n const connectResp = await window.solana.connect();\n return connectResp.publicKey.toString();\n }\n case Wallets.Binance: {\n const provider = window.BinanceChain;\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.Coinbase: {\n const provider = getCoinbaseProvider();\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.GenericEthereumWallet: {\n const provider = getOtherInjectedProvider();\n return provider?.request ? connectWithEthereumProvider(provider?.request) : '';\n }\n case Wallets.GenericSolanaWallet: {\n const connectResp = await window.solana.connect();\n return connectResp.publicKey.toString();\n }\n default:\n return '';\n }\n};\n\nconst signMessageWithSolanaProvider = async (message: string): Promise<string> => {\n const encodedMessage = new TextEncoder().encode(message);\n const signResp = await window.solana.request({\n method: 'signMessage',\n params: {\n message: encodedMessage,\n display: 'utf8',\n },\n });\n return encode(signResp.signature);\n};\n\nconst signMessageWithEthereumProvider = async (\n request: ProviderRequest,\n message: string,\n address: string,\n): Promise<string> => {\n const signature = await request({\n method: 'personal_sign',\n params: [message, address],\n });\n return signature as string;\n};\n\nexport const signMessageWithWallet = async ({\n wallet,\n message,\n address,\n}: {\n wallet: Wallets;\n message: string;\n address: string;\n}): Promise<string> => {\n switch (wallet) {\n case Wallets.Phantom:\n case Wallets.GenericSolanaWallet:\n return signMessageWithSolanaProvider(message);\n case Wallets.Metamask: {\n const provider = getMetaMaskProvider();\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n case Wallets.Binance: {\n const provider = window.BinanceChain;\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n case Wallets.Coinbase: {\n const provider = getCoinbaseProvider();\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n case Wallets.GenericEthereumWallet: {\n const provider = getOtherInjectedProvider();\n return provider?.request ? signMessageWithEthereumProvider(provider?.request, message, address) : '';\n }\n default:\n return '';\n }\n};\n\nexport const isSolanaWallet = (wallet: Wallets) => {\n const solanaWallets: Wallets[] = [Wallets.Phantom, Wallets.GenericSolanaWallet];\n return solanaWallets.includes(wallet);\n};\n\nexport const isEthereumWallet = (wallet: Wallets) => {\n const ethWallets: Wallets[] = [Wallets.Binance, Wallets.GenericEthereumWallet, Wallets.Coinbase, Wallets.Metamask];\n return ethWallets.includes(wallet);\n};\n"],"names":["hasMultipleEthereumWallets","window","ethereum","providers","hasMetaMask","find","wallet","isMetaMask","hasCoinbaseWallet","isCoinbaseWallet","hasOtherEthereumWallet","getMetaMaskProvider","getCoinbaseProvider","getOtherInjectedProvider","walletIcons","Wallets","Phantom","Binance","Coinbase","Metamask","useCryptoButtonProps","presentation","usePresentation","iconRegistry","getIcon","iconName","GenericWalletIcon","getId","getButtonId","options","WalletToText","GenericEthereumWallet","GenericSolanaWallet","isWalletVisible","solana","isPhantom","BinanceChain","connectWithEthereumProvider","request","address","method","connectWithWallet","provider","connectResp","connect","publicKey","toString","signMessageWithSolanaProvider","message","encodedMessage","TextEncoder","encode","signResp","params","display","signature","signMessageWithEthereumProvider","signMessageWithWallet","isSolanaWallet","solanaWallets","includes"],"mappings":"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"}
@@ -1,8 +1,6 @@
1
- import { getDefaultExportFromCjs } from './_commonjsHelpers.mjs';
2
- import { __require as requireLodash_merge } from '../node_modules/lodash.merge/index.mjs';
1
+ import { __require as requireBs58 } from '../node_modules/bs58/index.mjs';
3
2
 
4
- var lodash_mergeExports = requireLodash_merge();
5
- var merge = /*@__PURE__*/getDefaultExportFromCjs(lodash_mergeExports);
3
+ var bs58Exports = requireBs58();
6
4
 
7
- export { merge as default };
5
+ export { bs58Exports as b };
8
6
  //# sourceMappingURL=index3.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index3.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
1
+ {"version":3,"file":"index3.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -1,6 +1,8 @@
1
- import { __require as requireBs58 } from '../node_modules/bs58/index.mjs';
1
+ import { getDefaultExportFromCjs } from './_commonjsHelpers.mjs';
2
+ import { __require as requireLodash_merge } from '../node_modules/lodash.merge/index.mjs';
2
3
 
3
- var bs58Exports = requireBs58();
4
+ var lodash_mergeExports = requireLodash_merge();
5
+ var merge = /*@__PURE__*/getDefaultExportFromCjs(lodash_mergeExports);
4
6
 
5
- export { bs58Exports as b };
7
+ export { merge as default };
6
8
  //# sourceMappingURL=index4.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index4.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
1
+ {"version":3,"file":"index4.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import merge from '../../../../../_virtual/index3.mjs';
1
+ import merge from '../../../../../_virtual/index4.mjs';
2
2
  import 'react';
3
3
  import createTheme from '../../../../../node_modules/@mui/material/styles/createTheme.mjs';
4
4
  import selectClasses from '../../../../../node_modules/@mui/material/Select/selectClasses.mjs';
@@ -2,7 +2,7 @@ import React__default from 'react';
2
2
  import { useLingui } from '../../../../../../node_modules/@lingui/react/dist/index.mjs';
3
3
  import { useStytch, useGlobalReducer } from '../GlobalContextProvider.mjs';
4
4
  import Button from '../../components/atoms/Button.mjs';
5
- import { usePresentation } from '../../components/PresentationConfig.mjs';
5
+ import { usePresentation, getButtonId } from '../../components/PresentationConfig.mjs';
6
6
  import { B2BOAuthProviders } from '../../../../../core/src/public/b2b/ui.mjs';
7
7
 
8
8
  const providerInfo = {
@@ -41,7 +41,9 @@ const OAuthB2BButton = ({ providerType, loginRedirectUrl, signupRedirectUrl, dis
41
41
  const { i18n: $__i18n, _: $__ } = useLingui();
42
42
  const stytchClient = useStytch();
43
43
  const [state] = useGlobalReducer();
44
- const iconRegistry = usePresentation().iconRegistry;
44
+ const presentation = usePresentation();
45
+ const iconRegistry = presentation.iconRegistry;
46
+ const id = getButtonId(`oauth-${providerType}`, presentation.options);
45
47
  const provider = providerInfo[providerType];
46
48
  let label = providerType;
47
49
  let icon = null;
@@ -73,7 +75,8 @@ const OAuthB2BButton = ({ providerType, loginRedirectUrl, signupRedirectUrl, dis
73
75
  return /*#__PURE__*/ React__default.createElement(Button, {
74
76
  onClick: onButtonClick,
75
77
  variant: "outline",
76
- icon: icon
78
+ icon: icon,
79
+ id: id
77
80
  }, label);
78
81
  };
79
82
 
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthB2BButton.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/OAuthB2BButton.tsx"],"sourcesContent":["import React from 'react';\nimport { B2BOAuthProviders } from '@stytch/core/public';\nimport { msg } from '@lingui/core/macro';\nimport { useLingui } from '@lingui/react/macro';\nimport { MessageDescriptor } from '@lingui/core';\nimport { useGlobalReducer, useStytch } from '../GlobalContextProvider';\nimport Button from '../../components/atoms/Button';\nimport { usePresentation } from '../../components/PresentationConfig';\nimport { IconRegistry } from '../../components/IconRegistry';\nimport type { oauthIcons } from './Icons';\n\ntype OauthIconName = keyof typeof oauthIcons;\n\ninterface OAuthProviderInfo {\n messageDescriptor: MessageDescriptor;\n}\n\nconst providerInfo: Record<B2BOAuthProviders, OAuthProviderInfo> = {\n [B2BOAuthProviders.Google]: {\n messageDescriptor: msg({ id: 'oauth.continueWithGoogle', message: 'Continue with Google' }),\n },\n [B2BOAuthProviders.Microsoft]: {\n messageDescriptor: msg({ id: 'oauth.continueWithMicrosoft', message: 'Continue with Microsoft' }),\n },\n [B2BOAuthProviders.HubSpot]: {\n messageDescriptor: msg({ id: 'oauth.continueWithHubSpot', message: 'Continue with HubSpot' }),\n },\n [B2BOAuthProviders.Slack]: {\n messageDescriptor: msg({ id: 'oauth.continueWithSlack', message: 'Continue with Slack' }),\n },\n [B2BOAuthProviders.GitHub]: {\n messageDescriptor: msg({ id: 'oauth.continueWithGitHub', message: 'Continue with GitHub' }),\n },\n};\n\nexport type OauthB2BButtonProps = {\n providerType: B2BOAuthProviders;\n loginRedirectUrl?: string;\n signupRedirectUrl?: string;\n discoveryRedirectUrl?: string;\n customScopes?: string[];\n providerParams?: Record<string, string>;\n onSuccess?: () => void;\n};\n\nexport const OAuthB2BButton = ({\n providerType,\n loginRedirectUrl,\n signupRedirectUrl,\n discoveryRedirectUrl,\n customScopes,\n providerParams,\n onSuccess,\n}: OauthB2BButtonProps) => {\n const { t } = useLingui();\n const stytchClient = useStytch();\n const [state] = useGlobalReducer();\n const iconRegistry: IconRegistry<OauthIconName> = usePresentation().iconRegistry;\n\n const provider = providerInfo[providerType];\n let label: string = providerType;\n let icon = null;\n if (provider) {\n const { messageDescriptor } = provider;\n const Icon = iconRegistry[providerType];\n label = t(messageDescriptor);\n icon = <Icon />;\n }\n\n const onButtonClick = async () => {\n const providerClient = stytchClient.oauth[providerType];\n\n if (state.flowState.organization) {\n await providerClient.start({\n login_redirect_url: loginRedirectUrl,\n signup_redirect_url: signupRedirectUrl,\n custom_scopes: customScopes,\n organization_id: state.flowState.organization.organization_id,\n provider_params: providerParams,\n });\n } else {\n await providerClient.discovery.start({\n discovery_redirect_url: discoveryRedirectUrl,\n custom_scopes: customScopes,\n provider_params: providerParams,\n });\n }\n\n onSuccess?.();\n };\n\n return (\n <Button onClick={onButtonClick} variant=\"outline\" icon={icon}>\n {label}\n </Button>\n );\n};\n"],"names":["providerInfo","B2BOAuthProviders","Google","messageDescriptor","Microsoft","HubSpot","Slack","GitHub","OAuthB2BButton","providerType","loginRedirectUrl","signupRedirectUrl","discoveryRedirectUrl","customScopes","providerParams","onSuccess","useLingui","stytchClient","useStytch","state","useGlobalReducer","iconRegistry","usePresentation","provider","label","icon","Icon","React","onButtonClick","providerClient","oauth","flowState","organization","start","login_redirect_url","signup_redirect_url","custom_scopes","organization_id","provider_params","discovery","discovery_redirect_url","Button","onClick","variant"],"mappings":";;;;;;;AAiBA,MAAMA,YAAAA,GAA6D;IACjE,CAACC,iBAAAA,CAAkBC,MAAM,GAAG;QAC1BC,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBG,SAAS,GAAG;QAC7BD,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBI,OAAO,GAAG;QAC3BF,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBK,KAAK,GAAG;QACzBH,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBM,MAAM,GAAG;QAC1BJ,iBAAiB,EAAA;;;;AACnB;AACF,CAAA;MAYaK,cAAAA,GAAiB,CAAC,EAC7BC,YAAY,EACZC,gBAAgB,EAChBC,iBAAiB,EACjBC,oBAAoB,EACpBC,YAAY,EACZC,cAAc,EACdC,SAAS,EACW,GAAA;AACpB,IAAA,MAAM,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,GAAA,EAAA,GAAQC,SAAAA,EAAAA;AACd,IAAA,MAAMC,YAAAA,GAAeC,SAAAA,EAAAA;IACrB,MAAM,CAACC,MAAM,GAAGC,gBAAAA,EAAAA;IAChB,MAAMC,YAAAA,GAA4CC,kBAAkBD,YAAY;IAEhF,MAAME,QAAAA,GAAWvB,YAAY,CAACS,YAAAA,CAAa;AAC3C,IAAA,IAAIe,KAAAA,GAAgBf,YAAAA;AACpB,IAAA,IAAIgB,IAAAA,GAAO,IAAA;AACX,IAAA,IAAIF,QAAAA,EAAU;QACZ,MAAM,EAAEpB,iBAAiB,EAAE,GAAGoB,QAAAA;QAC9B,MAAMG,IAAAA,GAAOL,YAAY,CAACZ,YAAAA,CAAa;QACvCe,KAAAA,GAAAA,OAAAA,CAAAA,CAAAA,CAAUrB,iBAAAA,CAAAA;AACVsB,QAAAA,IAAAA,iBAAOE,cAAA,CAAA,aAAA,CAACD,IAAAA,EAAAA,IAAAA,CAAAA;AACV,IAAA;AAEA,IAAA,MAAME,aAAAA,GAAgB,UAAA;AACpB,QAAA,MAAMC,cAAAA,GAAiBZ,YAAAA,CAAaa,KAAK,CAACrB,YAAAA,CAAa;AAEvD,QAAA,IAAIU,KAAAA,CAAMY,SAAS,CAACC,YAAY,EAAE;YAChC,MAAMH,cAAAA,CAAeI,KAAK,CAAC;gBACzBC,kBAAAA,EAAoBxB,gBAAAA;gBACpByB,mBAAAA,EAAqBxB,iBAAAA;gBACrByB,aAAAA,EAAevB,YAAAA;AACfwB,gBAAAA,eAAAA,EAAiBlB,KAAAA,CAAMY,SAAS,CAACC,YAAY,CAACK,eAAe;gBAC7DC,eAAAA,EAAiBxB;AACnB,aAAA,CAAA;QACF,CAAA,MAAO;AACL,YAAA,MAAMe,cAAAA,CAAeU,SAAS,CAACN,KAAK,CAAC;gBACnCO,sBAAAA,EAAwB5B,oBAAAA;gBACxBwB,aAAAA,EAAevB,YAAAA;gBACfyB,eAAAA,EAAiBxB;AACnB,aAAA,CAAA;AACF,QAAA;AAEAC,QAAAA,SAAAA,IAAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACEY,cAAA,CAAA,aAAA,CAACc,MAAAA,EAAAA;QAAOC,OAAAA,EAASd,aAAAA;QAAee,OAAAA,EAAQ,SAAA;QAAUlB,IAAAA,EAAMA;AACrDD,KAAAA,EAAAA,KAAAA,CAAAA;AAGP;;;;"}
1
+ {"version":3,"file":"OAuthB2BButton.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/OAuthB2BButton.tsx"],"sourcesContent":["import React from 'react';\nimport { B2BOAuthProviders } from '@stytch/core/public';\nimport { msg } from '@lingui/core/macro';\nimport { useLingui } from '@lingui/react/macro';\nimport { MessageDescriptor } from '@lingui/core';\nimport { useGlobalReducer, useStytch } from '../GlobalContextProvider';\nimport Button from '../../components/atoms/Button';\nimport { getButtonId, usePresentation } from '../../components/PresentationConfig';\nimport { IconRegistry } from '../../components/IconRegistry';\nimport type { oauthIcons } from './Icons';\n\ntype OauthIconName = keyof typeof oauthIcons;\n\ninterface OAuthProviderInfo {\n messageDescriptor: MessageDescriptor;\n}\n\nconst providerInfo: Record<B2BOAuthProviders, OAuthProviderInfo> = {\n [B2BOAuthProviders.Google]: {\n messageDescriptor: msg({ id: 'oauth.continueWithGoogle', message: 'Continue with Google' }),\n },\n [B2BOAuthProviders.Microsoft]: {\n messageDescriptor: msg({ id: 'oauth.continueWithMicrosoft', message: 'Continue with Microsoft' }),\n },\n [B2BOAuthProviders.HubSpot]: {\n messageDescriptor: msg({ id: 'oauth.continueWithHubSpot', message: 'Continue with HubSpot' }),\n },\n [B2BOAuthProviders.Slack]: {\n messageDescriptor: msg({ id: 'oauth.continueWithSlack', message: 'Continue with Slack' }),\n },\n [B2BOAuthProviders.GitHub]: {\n messageDescriptor: msg({ id: 'oauth.continueWithGitHub', message: 'Continue with GitHub' }),\n },\n};\n\nexport type OauthB2BButtonProps = {\n providerType: B2BOAuthProviders;\n loginRedirectUrl?: string;\n signupRedirectUrl?: string;\n discoveryRedirectUrl?: string;\n customScopes?: string[];\n providerParams?: Record<string, string>;\n onSuccess?: () => void;\n};\n\nexport const OAuthB2BButton = ({\n providerType,\n loginRedirectUrl,\n signupRedirectUrl,\n discoveryRedirectUrl,\n customScopes,\n providerParams,\n onSuccess,\n}: OauthB2BButtonProps) => {\n const { t } = useLingui();\n const stytchClient = useStytch();\n const [state] = useGlobalReducer();\n\n const presentation = usePresentation();\n const iconRegistry: IconRegistry<OauthIconName> = presentation.iconRegistry;\n const id = getButtonId(`oauth-${providerType}`, presentation.options);\n\n const provider = providerInfo[providerType];\n let label: string = providerType;\n let icon = null;\n if (provider) {\n const { messageDescriptor } = provider;\n const Icon = iconRegistry[providerType];\n label = t(messageDescriptor);\n icon = <Icon />;\n }\n\n const onButtonClick = async () => {\n const providerClient = stytchClient.oauth[providerType];\n\n if (state.flowState.organization) {\n await providerClient.start({\n login_redirect_url: loginRedirectUrl,\n signup_redirect_url: signupRedirectUrl,\n custom_scopes: customScopes,\n organization_id: state.flowState.organization.organization_id,\n provider_params: providerParams,\n });\n } else {\n await providerClient.discovery.start({\n discovery_redirect_url: discoveryRedirectUrl,\n custom_scopes: customScopes,\n provider_params: providerParams,\n });\n }\n\n onSuccess?.();\n };\n\n return (\n <Button onClick={onButtonClick} variant=\"outline\" icon={icon} id={id}>\n {label}\n </Button>\n );\n};\n"],"names":["providerInfo","B2BOAuthProviders","Google","messageDescriptor","Microsoft","HubSpot","Slack","GitHub","OAuthB2BButton","providerType","loginRedirectUrl","signupRedirectUrl","discoveryRedirectUrl","customScopes","providerParams","onSuccess","useLingui","stytchClient","useStytch","state","useGlobalReducer","presentation","usePresentation","iconRegistry","id","getButtonId","options","provider","label","icon","Icon","React","onButtonClick","providerClient","oauth","flowState","organization","start","login_redirect_url","signup_redirect_url","custom_scopes","organization_id","provider_params","discovery","discovery_redirect_url","Button","onClick","variant"],"mappings":";;;;;;;AAiBA,MAAMA,YAAAA,GAA6D;IACjE,CAACC,iBAAAA,CAAkBC,MAAM,GAAG;QAC1BC,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBG,SAAS,GAAG;QAC7BD,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBI,OAAO,GAAG;QAC3BF,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBK,KAAK,GAAG;QACzBH,iBAAiB,EAAA;;;;AACnB,KAAA;IACA,CAACF,iBAAAA,CAAkBM,MAAM,GAAG;QAC1BJ,iBAAiB,EAAA;;;;AACnB;AACF,CAAA;MAYaK,cAAAA,GAAiB,CAAC,EAC7BC,YAAY,EACZC,gBAAgB,EAChBC,iBAAiB,EACjBC,oBAAoB,EACpBC,YAAY,EACZC,cAAc,EACdC,SAAS,EACW,GAAA;AACpB,IAAA,MAAM,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,GAAA,EAAA,GAAQC,SAAAA,EAAAA;AACd,IAAA,MAAMC,YAAAA,GAAeC,SAAAA,EAAAA;IACrB,MAAM,CAACC,MAAM,GAAGC,gBAAAA,EAAAA;AAEhB,IAAA,MAAMC,YAAAA,GAAeC,eAAAA,EAAAA;IACrB,MAAMC,YAAAA,GAA4CF,aAAaE,YAAY;IAC3E,MAAMC,EAAAA,GAAKC,YAAY,CAAC,MAAM,EAAEhB,YAAAA,CAAAA,CAAc,EAAEY,aAAaK,OAAO,CAAA;IAEpE,MAAMC,QAAAA,GAAW3B,YAAY,CAACS,YAAAA,CAAa;AAC3C,IAAA,IAAImB,KAAAA,GAAgBnB,YAAAA;AACpB,IAAA,IAAIoB,IAAAA,GAAO,IAAA;AACX,IAAA,IAAIF,QAAAA,EAAU;QACZ,MAAM,EAAExB,iBAAiB,EAAE,GAAGwB,QAAAA;QAC9B,MAAMG,IAAAA,GAAOP,YAAY,CAACd,YAAAA,CAAa;QACvCmB,KAAAA,GAAAA,OAAAA,CAAAA,CAAAA,CAAUzB,iBAAAA,CAAAA;AACV0B,QAAAA,IAAAA,iBAAOE,cAAA,CAAA,aAAA,CAACD,IAAAA,EAAAA,IAAAA,CAAAA;AACV,IAAA;AAEA,IAAA,MAAME,aAAAA,GAAgB,UAAA;AACpB,QAAA,MAAMC,cAAAA,GAAiBhB,YAAAA,CAAaiB,KAAK,CAACzB,YAAAA,CAAa;AAEvD,QAAA,IAAIU,KAAAA,CAAMgB,SAAS,CAACC,YAAY,EAAE;YAChC,MAAMH,cAAAA,CAAeI,KAAK,CAAC;gBACzBC,kBAAAA,EAAoB5B,gBAAAA;gBACpB6B,mBAAAA,EAAqB5B,iBAAAA;gBACrB6B,aAAAA,EAAe3B,YAAAA;AACf4B,gBAAAA,eAAAA,EAAiBtB,KAAAA,CAAMgB,SAAS,CAACC,YAAY,CAACK,eAAe;gBAC7DC,eAAAA,EAAiB5B;AACnB,aAAA,CAAA;QACF,CAAA,MAAO;AACL,YAAA,MAAMmB,cAAAA,CAAeU,SAAS,CAACN,KAAK,CAAC;gBACnCO,sBAAAA,EAAwBhC,oBAAAA;gBACxB4B,aAAAA,EAAe3B,YAAAA;gBACf6B,eAAAA,EAAiB5B;AACnB,aAAA,CAAA;AACF,QAAA;AAEAC,QAAAA,SAAAA,IAAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACEgB,cAAA,CAAA,aAAA,CAACc,MAAAA,EAAAA;QAAOC,OAAAA,EAASd,aAAAA;QAAee,OAAAA,EAAQ,SAAA;QAAUlB,IAAAA,EAAMA,IAAAA;QAAML,EAAAA,EAAIA;AAC/DI,KAAAA,EAAAA,KAAAA,CAAAA;AAGP;;;;"}
@@ -3,7 +3,7 @@ import { useLingui } from '../../../../../../node_modules/@lingui/react/dist/ind
3
3
  import { useStytch, useConfig } from '../GlobalContextProvider.mjs';
4
4
  import { SSOIcon } from '../../../assets/sso.mjs';
5
5
  import Button from '../../components/atoms/Button.mjs';
6
- import { usePresentation } from '../../components/PresentationConfig.mjs';
6
+ import { usePresentation, getButtonId } from '../../components/PresentationConfig.mjs';
7
7
 
8
8
  const iconMap = {
9
9
  'google-workspace': 'google',
@@ -14,8 +14,9 @@ const SSOButton = ({ connection, onStart })=>{
14
14
  const { i18n: $__i18n, _: $__ } = useLingui();
15
15
  const stytchClient = useStytch();
16
16
  const { ssoOptions } = useConfig();
17
- const { iconRegistry } = usePresentation();
17
+ const { iconRegistry, options } = usePresentation();
18
18
  const { connection_id, display_name, identity_provider } = connection;
19
+ const id = getButtonId(`sso-${display_name}`, options);
19
20
  const onButtonClick = ()=>stytchClient.sso.start({
20
21
  connection_id,
21
22
  signup_redirect_url: ssoOptions?.signupRedirectURL,
@@ -28,7 +29,8 @@ const SSOButton = ({ connection, onStart })=>{
28
29
  return /*#__PURE__*/ React__default.createElement(Button, {
29
30
  variant: "outline",
30
31
  onClick: onButtonClick,
31
- icon: /*#__PURE__*/ React__default.createElement(Icon, null)
32
+ icon: /*#__PURE__*/ React__default.createElement(Icon, null),
33
+ id: id
32
34
  }, $__i18n._({
33
35
  id: "provider.continueWith",
34
36
  message: "Continue with {display_name}",
@@ -1 +1 @@
1
- {"version":3,"file":"SSOButton.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/SSOButton.tsx"],"sourcesContent":["import React from 'react';\nimport { SSOActiveConnection } from '@stytch/core/public';\nimport { useLingui } from '@lingui/react/macro';\nimport { useConfig, useStytch } from '../GlobalContextProvider';\nimport { SsoKnownIdp } from '../../../utils/KnownIdp';\n\nimport { SSOIcon } from '../../../assets';\nimport Button from '../../components/atoms/Button';\nimport { usePresentation } from '../../components/PresentationConfig';\nimport type { ssoIcons } from './Icons';\n\ntype SsoIconNames = keyof typeof ssoIcons;\n\nconst iconMap: Record<string, SsoIconNames> = {\n 'google-workspace': 'google',\n 'microsoft-entra': 'microsoft',\n okta: 'okta',\n} satisfies Record<Exclude<SsoKnownIdp, 'generic'>, SsoIconNames>;\n\nexport interface SSOButtonProps {\n connection: SSOActiveConnection;\n onStart?: (connection: SSOActiveConnection) => void;\n}\n\nexport const SSOButton = ({ connection, onStart }: SSOButtonProps) => {\n const { t } = useLingui();\n const stytchClient = useStytch();\n const { ssoOptions } = useConfig();\n const { iconRegistry } = usePresentation();\n\n const { connection_id, display_name, identity_provider } = connection;\n\n const onButtonClick = () =>\n stytchClient.sso\n .start({\n connection_id,\n signup_redirect_url: ssoOptions?.signupRedirectURL,\n login_redirect_url: ssoOptions?.loginRedirectURL,\n })\n .then(() => {\n onStart?.(connection);\n });\n\n const iconName = iconMap[identity_provider];\n const Icon = iconRegistry[iconName] ?? SSOIcon;\n\n return (\n <Button variant=\"outline\" onClick={onButtonClick} icon={<Icon />}>\n {t({ id: 'provider.continueWith', message: `Continue with ${display_name}` })}\n </Button>\n );\n};\n"],"names":["iconMap","okta","SSOButton","connection","onStart","useLingui","stytchClient","useStytch","ssoOptions","useConfig","iconRegistry","usePresentation","connection_id","display_name","identity_provider","onButtonClick","sso","start","signup_redirect_url","signupRedirectURL","login_redirect_url","loginRedirectURL","then","iconName","Icon","SSOIcon","React","Button","variant","onClick","icon"],"mappings":";;;;;;;AAaA,MAAMA,OAAAA,GAAwC;IAC5C,kBAAA,EAAoB,QAAA;IACpB,iBAAA,EAAmB,WAAA;IACnBC,IAAAA,EAAM;AACR,CAAA;MAOaC,SAAAA,GAAY,CAAC,EAAEC,UAAU,EAAEC,OAAO,EAAkB,GAAA;AAC/D,IAAA,MAAM,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,GAAA,EAAA,GAAQC,SAAAA,EAAAA;AACd,IAAA,MAAMC,YAAAA,GAAeC,SAAAA,EAAAA;IACrB,MAAM,EAAEC,UAAU,EAAE,GAAGC,SAAAA,EAAAA;IACvB,MAAM,EAAEC,YAAY,EAAE,GAAGC,eAAAA,EAAAA;AAEzB,IAAA,MAAM,EAAEC,aAAa,EAAEC,YAAY,EAAEC,iBAAiB,EAAE,GAAGX,UAAAA;AAE3D,IAAA,MAAMY,gBAAgB,IACpBT,YAAAA,CAAaU,GAAG,CACbC,KAAK,CAAC;AACLL,YAAAA,aAAAA;AACAM,YAAAA,mBAAAA,EAAqBV,UAAAA,EAAYW,iBAAAA;AACjCC,YAAAA,kBAAAA,EAAoBZ,UAAAA,EAAYa;AAClC,SAAA,CAAA,CACCC,IAAI,CAAC,IAAA;YACJlB,OAAAA,GAAUD,UAAAA,CAAAA;AACZ,QAAA,CAAA,CAAA;IAEJ,MAAMoB,QAAAA,GAAWvB,OAAO,CAACc,iBAAAA,CAAkB;AAC3C,IAAA,MAAMU,IAAAA,GAAOd,YAAY,CAACa,QAAAA,CAAS,IAAIE,OAAAA;AAEvC,IAAA,qBACEC,cAAA,CAAA,aAAA,CAACC,MAAAA,EAAAA;QAAOC,OAAAA,EAAQ,SAAA;QAAUC,OAAAA,EAASd,aAAAA;AAAee,QAAAA,IAAAA,gBAAMJ,cAAA,CAAA,aAAA,CAACF,IAAAA,EAAAA,IAAAA;;;;;AACKX,YAAAA,YAAAA,EAAAA;;;AAGlE;;;;"}
1
+ {"version":3,"file":"SSOButton.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/SSOButton.tsx"],"sourcesContent":["import React from 'react';\nimport { SSOActiveConnection } from '@stytch/core/public';\nimport { useLingui } from '@lingui/react/macro';\nimport { useConfig, useStytch } from '../GlobalContextProvider';\nimport { SsoKnownIdp } from '../../../utils/KnownIdp';\n\nimport { SSOIcon } from '../../../assets';\nimport Button from '../../components/atoms/Button';\nimport { getButtonId, usePresentation } from '../../components/PresentationConfig';\nimport type { ssoIcons } from './Icons';\n\ntype SsoIconNames = keyof typeof ssoIcons;\n\nconst iconMap: Record<string, SsoIconNames> = {\n 'google-workspace': 'google',\n 'microsoft-entra': 'microsoft',\n okta: 'okta',\n} satisfies Record<Exclude<SsoKnownIdp, 'generic'>, SsoIconNames>;\n\nexport interface SSOButtonProps {\n connection: SSOActiveConnection;\n onStart?: (connection: SSOActiveConnection) => void;\n}\n\nexport const SSOButton = ({ connection, onStart }: SSOButtonProps) => {\n const { t } = useLingui();\n const stytchClient = useStytch();\n const { ssoOptions } = useConfig();\n const { iconRegistry, options } = usePresentation();\n\n const { connection_id, display_name, identity_provider } = connection;\n\n const id = getButtonId(`sso-${display_name}`, options);\n\n const onButtonClick = () =>\n stytchClient.sso\n .start({\n connection_id,\n signup_redirect_url: ssoOptions?.signupRedirectURL,\n login_redirect_url: ssoOptions?.loginRedirectURL,\n })\n .then(() => {\n onStart?.(connection);\n });\n\n const iconName = iconMap[identity_provider];\n const Icon = iconRegistry[iconName] ?? SSOIcon;\n\n return (\n <Button variant=\"outline\" onClick={onButtonClick} icon={<Icon />} id={id}>\n {t({ id: 'provider.continueWith', message: `Continue with ${display_name}` })}\n </Button>\n );\n};\n"],"names":["iconMap","okta","SSOButton","connection","onStart","useLingui","stytchClient","useStytch","ssoOptions","useConfig","iconRegistry","options","usePresentation","connection_id","display_name","identity_provider","id","getButtonId","onButtonClick","sso","start","signup_redirect_url","signupRedirectURL","login_redirect_url","loginRedirectURL","then","iconName","Icon","SSOIcon","React","Button","variant","onClick","icon"],"mappings":";;;;;;;AAaA,MAAMA,OAAAA,GAAwC;IAC5C,kBAAA,EAAoB,QAAA;IACpB,iBAAA,EAAmB,WAAA;IACnBC,IAAAA,EAAM;AACR,CAAA;MAOaC,SAAAA,GAAY,CAAC,EAAEC,UAAU,EAAEC,OAAO,EAAkB,GAAA;AAC/D,IAAA,MAAM,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,GAAA,EAAA,GAAQC,SAAAA,EAAAA;AACd,IAAA,MAAMC,YAAAA,GAAeC,SAAAA,EAAAA;IACrB,MAAM,EAAEC,UAAU,EAAE,GAAGC,SAAAA,EAAAA;AACvB,IAAA,MAAM,EAAEC,YAAY,EAAEC,OAAO,EAAE,GAAGC,eAAAA,EAAAA;AAElC,IAAA,MAAM,EAAEC,aAAa,EAAEC,YAAY,EAAEC,iBAAiB,EAAE,GAAGZ,UAAAA;AAE3D,IAAA,MAAMa,KAAKC,WAAAA,CAAY,CAAC,IAAI,EAAEH,cAAc,EAAEH,OAAAA,CAAAA;AAE9C,IAAA,MAAMO,gBAAgB,IACpBZ,YAAAA,CAAaa,GAAG,CACbC,KAAK,CAAC;AACLP,YAAAA,aAAAA;AACAQ,YAAAA,mBAAAA,EAAqBb,UAAAA,EAAYc,iBAAAA;AACjCC,YAAAA,kBAAAA,EAAoBf,UAAAA,EAAYgB;AAClC,SAAA,CAAA,CACCC,IAAI,CAAC,IAAA;YACJrB,OAAAA,GAAUD,UAAAA,CAAAA;AACZ,QAAA,CAAA,CAAA;IAEJ,MAAMuB,QAAAA,GAAW1B,OAAO,CAACe,iBAAAA,CAAkB;AAC3C,IAAA,MAAMY,IAAAA,GAAOjB,YAAY,CAACgB,QAAAA,CAAS,IAAIE,OAAAA;AAEvC,IAAA,qBACEC,cAAA,CAAA,aAAA,CAACC,MAAAA,EAAAA;QAAOC,OAAAA,EAAQ,SAAA;QAAUC,OAAAA,EAASd,aAAAA;AAAee,QAAAA,IAAAA,gBAAMJ,cAAA,CAAA,aAAA,CAACF,IAAAA,EAAAA,IAAAA,CAAAA;QAASX,EAAAA,EAAIA;;;;;AACRF,YAAAA,YAAAA,EAAAA;;;AAGlE;;;;"}
@@ -5,11 +5,12 @@ import { MainScreenComponent, AppScreens } from '../types/AppScreens.mjs';
5
5
  import { useEffectiveAuthConfig } from '../hooks/useEffectiveAuthConfig.mjs';
6
6
  import { useProductComponents } from '../utils.mjs';
7
7
  import { assertUnreachable } from '../../../utils/assertUnreachable.mjs';
8
- import { getButtonId, getSsoMethodKey } from '../types/authMethodKeys.mjs';
8
+ import { getButtonKey, getSsoMethodKey } from '../types/authMethodKeys.mjs';
9
9
  import { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod.mjs';
10
10
  import Button from '../../components/atoms/Button.mjs';
11
11
  import LastUsed from '../../components/molecules/LastUsed.mjs';
12
12
  import ButtonColumn from '../../components/molecules/ButtonColumn.mjs';
13
+ import { usePresentation, getButtonId } from '../../components/PresentationConfig.mjs';
13
14
  import { AuthFlowType, B2BOAuthProviders } from '../../../../../core/src/public/b2b/ui.mjs';
14
15
  import { arrayUtils } from '../../../../../core/src/utils/arrayUtils.mjs';
15
16
 
@@ -38,6 +39,7 @@ const SsoAndOAuthButtons = ({ buttons })=>{
38
39
  const { i18n: $__i18n, _: $__ } = useLingui();
39
40
  const [state, dispatch] = useGlobalReducer();
40
41
  const { oauthProviderSettings = [] } = useEffectiveAuthConfig();
42
+ const presentation = usePresentation();
41
43
  const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();
42
44
  const config = useConfig();
43
45
  const { loginRedirectURL, signupRedirectURL, discoveryRedirectURL, customScopes, providerParams } = config.oauthOptions ?? {};
@@ -65,7 +67,7 @@ const SsoAndOAuthButtons = ({ buttons })=>{
65
67
  return null;
66
68
  }
67
69
  // Reorder providers based on last used
68
- const [reorderedButtons, foundLastUsedOAuth] = arrayUtils.moveToFront(authButtons, (button)=>getButtonId(button) === lastUsedMethod);
70
+ const [reorderedButtons, foundLastUsedOAuth] = arrayUtils.moveToFront(authButtons, (button)=>getButtonKey(button) === lastUsedMethod);
69
71
  // Helper function to create OAuth button component
70
72
  const createOAuthButton = (oauthProvider)=>{
71
73
  const providerProps = {
@@ -104,6 +106,7 @@ const SsoAndOAuthButtons = ({ buttons })=>{
104
106
  return /*#__PURE__*/ React__default.createElement(Button, {
105
107
  key: "sso-discovery",
106
108
  variant: "outline",
109
+ id: getButtonId('sso-discovery', presentation.options),
107
110
  onClick: ()=>{
108
111
  dispatch({
109
112
  type: 'transition',
@@ -120,7 +123,7 @@ const SsoAndOAuthButtons = ({ buttons })=>{
120
123
  }
121
124
  })();
122
125
  return foundLastUsedOAuth && index === 0 ? /*#__PURE__*/ React__default.createElement(LastUsed, {
123
- key: getButtonId(button)
126
+ key: getButtonKey(button)
124
127
  }, buttonComponent) : buttonComponent;
125
128
  }));
126
129
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SsoAndOAuthButtons.mjs","sources":["../../../../../../../../../web/src/ui/b2b/screens/SsoAndOAuthButtons.tsx"],"sourcesContent":["import React from 'react';\nimport { B2BOAuthProviders, AuthFlowType } from '@stytch/core/public';\nimport { arrayUtils } from '@stytch/core';\nimport { useLingui } from '@lingui/react/macro';\n\nimport { useConfig, useGlobalReducer } from '../GlobalContextProvider';\nimport { AppScreens, ButtonComponent, MainScreenComponent } from '../types/AppScreens';\nimport { OauthProviderParams, useEffectiveAuthConfig } from '../hooks/useEffectiveAuthConfig';\nimport { useProductComponents } from '../utils';\nimport { assertUnreachable } from '../../../utils/assertUnreachable';\nimport { AuthButton as AuthButtonType, getButtonId, getSsoMethodKey } from '../types/authMethodKeys';\nimport { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod';\nimport Button from '../../components/atoms/Button';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport ButtonColumn from '../../components/molecules/ButtonColumn';\n\n// OAuth helper functions\nexport const getCustomScopesForProvider = (\n oauthProvider: {\n type: B2BOAuthProviders;\n one_tap: boolean;\n customScopes: string[];\n providerParams: Record<string, string>;\n cancel_on_tap_outside?: boolean;\n },\n oauthOptionsCustomScopes: string[] | undefined,\n) => {\n let currentCustomScopes = oauthProvider.customScopes;\n if (Object.keys(currentCustomScopes).length == 0) {\n currentCustomScopes = oauthOptionsCustomScopes as string[];\n }\n return currentCustomScopes;\n};\n\nexport const getProviderParamsForProvider = (\n oauthProvider: {\n type: B2BOAuthProviders;\n one_tap: boolean;\n customScopes: string[];\n providerParams: Record<string, string>;\n cancel_on_tap_outside?: boolean;\n },\n oauthOptionsProviderParams: Record<string, string> | undefined,\n email: string | undefined,\n) => {\n let currentProviderParams = oauthProvider.providerParams;\n if (Object.keys(currentProviderParams).length == 0) {\n currentProviderParams = oauthOptionsProviderParams ?? {};\n }\n\n if (\n email &&\n (oauthProvider.type === B2BOAuthProviders.Google || oauthProvider.type === B2BOAuthProviders.Microsoft) &&\n !('login_hint' in currentProviderParams)\n ) {\n currentProviderParams = {\n ...currentProviderParams,\n login_hint: email,\n };\n }\n\n return currentProviderParams;\n};\n\nexport const SsoAndOAuthButtons = ({ buttons }: { buttons: ButtonComponent[] }) => {\n const { t } = useLingui();\n const [state, dispatch] = useGlobalReducer();\n const { oauthProviderSettings = [] } = useEffectiveAuthConfig();\n\n const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();\n\n const config = useConfig();\n const { loginRedirectURL, signupRedirectURL, discoveryRedirectURL, customScopes, providerParams } =\n config.oauthOptions ?? {};\n\n const { B2BGoogleOneTap, OAuthB2BButton, SSOButton } = useProductComponents(config, 'ssoAndOAuthButtons')!;\n\n // Determine which buttons need to be displayed\n const isDiscoveryFlow = state.flowState.type === AuthFlowType.Discovery;\n const authButtons = buttons.flatMap<AuthButtonType>((button) => {\n if (button === MainScreenComponent.OAuthButtons) {\n return oauthProviderSettings.map((provider) => ({ type: 'oauth', provider }));\n } else if (button === MainScreenComponent.SSOButtons) {\n return isDiscoveryFlow\n ? { type: 'sso-discovery' }\n : (state.flowState.organization?.sso_active_connections?.map((connection) => ({ type: 'sso', connection })) ??\n []);\n } else {\n assertUnreachable(button);\n }\n });\n\n if (authButtons.length === 0) {\n return null;\n }\n\n // Reorder providers based on last used\n const [reorderedButtons, foundLastUsedOAuth] = arrayUtils.moveToFront(\n authButtons,\n (button) => getButtonId(button) === lastUsedMethod,\n );\n\n // Helper function to create OAuth button component\n const createOAuthButton = (oauthProvider: OauthProviderParams) => {\n const providerProps = {\n customScopes: getCustomScopesForProvider(oauthProvider, customScopes),\n providerParams: getProviderParamsForProvider(oauthProvider, providerParams, state.primary.email),\n };\n\n if (oauthProvider.one_tap) {\n return (\n <B2BGoogleOneTap\n key={oauthProvider.type}\n {...providerProps}\n cancelOnTapOutside={oauthProvider.cancel_on_tap_outside}\n />\n );\n }\n\n return (\n <OAuthB2BButton\n key={oauthProvider.type}\n providerType={oauthProvider.type}\n loginRedirectUrl={loginRedirectURL}\n signupRedirectUrl={signupRedirectURL}\n discoveryRedirectUrl={discoveryRedirectURL}\n onSuccess={() => setLastUsedMethod(oauthProvider.type)}\n {...providerProps}\n />\n );\n };\n\n return (\n <ButtonColumn>\n {reorderedButtons.map((button, index) => {\n const buttonComponent = (() => {\n switch (button.type) {\n case 'oauth':\n return createOAuthButton(button.provider);\n\n case 'sso':\n return (\n <SSOButton\n key={button.connection.display_name}\n connection={button.connection}\n onStart={() => setLastUsedMethod(getSsoMethodKey(button.connection))}\n />\n );\n\n case 'sso-discovery':\n return (\n <Button\n key=\"sso-discovery\"\n variant=\"outline\"\n onClick={() => {\n dispatch({ type: 'transition', screen: AppScreens.SSODiscoveryEmail, history: 'push' });\n }}\n >\n {t({ id: 'provider.continueWithSSO', message: 'Use single sign-on' })}\n </Button>\n );\n\n default:\n assertUnreachable(button);\n }\n })();\n\n return foundLastUsedOAuth && index === 0 ? (\n <LastUsed key={getButtonId(button)}>{buttonComponent}</LastUsed>\n ) : (\n buttonComponent\n );\n })}\n </ButtonColumn>\n );\n};\n"],"names":["getCustomScopesForProvider","oauthProvider","oauthOptionsCustomScopes","currentCustomScopes","customScopes","Object","keys","length","getProviderParamsForProvider","oauthOptionsProviderParams","email","currentProviderParams","providerParams","type","B2BOAuthProviders","Google","Microsoft","login_hint","SsoAndOAuthButtons","buttons","useLingui","state","dispatch","useGlobalReducer","oauthProviderSettings","useEffectiveAuthConfig","lastUsedMethod","setLastUsedMethod","useLastUsedAuthMethod","config","useConfig","loginRedirectURL","signupRedirectURL","discoveryRedirectURL","oauthOptions","B2BGoogleOneTap","OAuthB2BButton","SSOButton","useProductComponents","isDiscoveryFlow","flowState","AuthFlowType","Discovery","authButtons","flatMap","button","MainScreenComponent","OAuthButtons","map","provider","SSOButtons","organization","sso_active_connections","connection","assertUnreachable","reorderedButtons","foundLastUsedOAuth","arrayUtils","moveToFront","getButtonId","createOAuthButton","providerProps","primary","one_tap","React","key","cancelOnTapOutside","cancel_on_tap_outside","providerType","loginRedirectUrl","signupRedirectUrl","discoveryRedirectUrl","onSuccess","ButtonColumn","index","buttonComponent","display_name","onStart","getSsoMethodKey","Button","variant","onClick","screen","AppScreens","SSODiscoveryEmail","history","LastUsed"],"mappings":";;;;;;;;;;;;;;;AAgBA;AACO,MAAMA,0BAAAA,GAA6B,CACxCC,aAAAA,EAOAC,wBAAAA,GAAAA;IAEA,IAAIC,mBAAAA,GAAsBF,cAAcG,YAAY;AACpD,IAAA,IAAIC,OAAOC,IAAI,CAACH,mBAAAA,CAAAA,CAAqBI,MAAM,IAAI,CAAA,EAAG;QAChDJ,mBAAAA,GAAsBD,wBAAAA;AACxB,IAAA;IACA,OAAOC,mBAAAA;AACT;AAEO,MAAMK,4BAAAA,GAA+B,CAC1CP,aAAAA,EAOAQ,0BAAAA,EACAC,KAAAA,GAAAA;IAEA,IAAIC,qBAAAA,GAAwBV,cAAcW,cAAc;AACxD,IAAA,IAAIP,OAAOC,IAAI,CAACK,qBAAAA,CAAAA,CAAuBJ,MAAM,IAAI,CAAA,EAAG;AAClDI,QAAAA,qBAAAA,GAAwBF,8BAA8B,EAAC;AACzD,IAAA;AAEA,IAAA,IACEC,UACCT,aAAAA,CAAcY,IAAI,KAAKC,iBAAAA,CAAkBC,MAAM,IAAId,aAAAA,CAAcY,IAAI,KAAKC,iBAAAA,CAAkBE,SAAS,CAAD,IACrG,EAAE,YAAA,IAAgBL,qBAAoB,CAAA,EACtC;QACAA,qBAAAA,GAAwB;AACtB,YAAA,GAAGA,qBAAqB;YACxBM,UAAAA,EAAYP;AACd,SAAA;AACF,IAAA;IAEA,OAAOC,qBAAAA;AACT;AAEO,MAAMO,kBAAAA,GAAqB,CAAC,EAAEC,OAAO,EAAkC,GAAA;AAC5E,IAAA,MAAM,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,GAAA,EAAA,GAAQC,SAAAA,EAAAA;IACd,MAAM,CAACC,KAAAA,EAAOC,QAAAA,CAAS,GAAGC,gBAAAA,EAAAA;AAC1B,IAAA,MAAM,EAAEC,qBAAAA,GAAwB,EAAE,EAAE,GAAGC,sBAAAA,EAAAA;IAEvC,MAAM,CAACC,cAAAA,EAAgBC,iBAAAA,CAAkB,GAAGC,qBAAAA,EAAAA;AAE5C,IAAA,MAAMC,MAAAA,GAASC,SAAAA,EAAAA;AACf,IAAA,MAAM,EAAEC,gBAAgB,EAAEC,iBAAiB,EAAEC,oBAAoB,EAAE7B,YAAY,EAAEQ,cAAc,EAAE,GAC/FiB,MAAAA,CAAOK,YAAY,IAAI,EAAC;IAE1B,MAAM,EAAEC,eAAe,EAAEC,cAAc,EAAEC,SAAS,EAAE,GAAGC,oBAAAA,CAAqBT,MAAAA,EAAQ,oBAAA,CAAA;;AAGpF,IAAA,MAAMU,kBAAkBlB,KAAAA,CAAMmB,SAAS,CAAC3B,IAAI,KAAK4B,aAAaC,SAAS;AACvE,IAAA,MAAMC,WAAAA,GAAcxB,OAAAA,CAAQyB,OAAO,CAAiB,CAACC,MAAAA,GAAAA;QACnD,IAAIA,MAAAA,KAAWC,mBAAAA,CAAoBC,YAAY,EAAE;AAC/C,YAAA,OAAOvB,qBAAAA,CAAsBwB,GAAG,CAAC,CAACC,YAAc;oBAAEpC,IAAAA,EAAM,OAAA;AAASoC,oBAAAA;iBAAS,CAAA,CAAA;AAC5E,QAAA,CAAA,MAAO,IAAIJ,MAAAA,KAAWC,mBAAAA,CAAoBI,UAAU,EAAE;AACpD,YAAA,OAAOX,eAAAA,GACH;gBAAE1B,IAAAA,EAAM;aAAgB,GACvBQ,KAAAA,CAAMmB,SAAS,CAACW,YAAY,EAAEC,sBAAAA,EAAwBJ,GAAAA,CAAI,CAACK,UAAAA,IAAgB;oBAAExC,IAAAA,EAAM,KAAA;AAAOwC,oBAAAA;AAAW,iBAAA,MACpG,EAAE;QACV,CAAA,MAAO;YACLC,iBAAAA,CAAkBT,CAAAA;AACpB,QAAA;AACF,IAAA,CAAA,CAAA;IAEA,IAAIF,WAAAA,CAAYpC,MAAM,KAAK,CAAA,EAAG;QAC5B,OAAO,IAAA;AACT,IAAA;;IAGA,MAAM,CAACgD,gBAAAA,EAAkBC,kBAAAA,CAAmB,GAAGC,UAAAA,CAAWC,WAAW,CACnEf,WAAAA,EACA,CAACE,MAAAA,GAAWc,WAAAA,CAAYd,MAAAA,CAAAA,KAAYnB,cAAAA,CAAAA;;AAItC,IAAA,MAAMkC,oBAAoB,CAAC3D,aAAAA,GAAAA;AACzB,QAAA,MAAM4D,aAAAA,GAAgB;AACpBzD,YAAAA,YAAAA,EAAcJ,2BAA2BC,aAAAA,EAAeG,YAAAA,CAAAA;AACxDQ,YAAAA,cAAAA,EAAgBJ,6BAA6BP,aAAAA,EAAeW,cAAAA,EAAgBS,KAAAA,CAAMyC,OAAO,CAACpD,KAAK;AACjG,SAAA;QAEA,IAAIT,aAAAA,CAAc8D,OAAO,EAAE;AACzB,YAAA,qBACEC,cAAA,CAAA,aAAA,CAAC7B,eAAAA,EAAAA;AACC8B,gBAAAA,GAAAA,EAAKhE,cAAcY,IAAI;AACtB,gBAAA,GAAGgD,aAAa;AACjBK,gBAAAA,kBAAAA,EAAoBjE,cAAckE;;AAGxC,QAAA;AAEA,QAAA,qBACEH,cAAA,CAAA,aAAA,CAAC5B,cAAAA,EAAAA;AACC6B,YAAAA,GAAAA,EAAKhE,cAAcY,IAAI;AACvBuD,YAAAA,YAAAA,EAAcnE,cAAcY,IAAI;YAChCwD,gBAAAA,EAAkBtC,gBAAAA;YAClBuC,iBAAAA,EAAmBtC,iBAAAA;YACnBuC,oBAAAA,EAAsBtC,oBAAAA;YACtBuC,SAAAA,EAAW,IAAM7C,iBAAAA,CAAkB1B,aAAAA,CAAcY,IAAI,CAAA;AACpD,YAAA,GAAGgD;;AAGV,IAAA,CAAA;AAEA,IAAA,qBACEG,6BAACS,YAAAA,EAAAA,IAAAA,EACElB,gBAAAA,CAAiBP,GAAG,CAAC,CAACH,MAAAA,EAAQ6B,KAAAA,GAAAA;QAC7B,MAAMC,eAAAA,GAAkB,CAAC,IAAA;AACvB,YAAA,OAAQ9B,OAAOhC,IAAI;gBACjB,KAAK,OAAA;oBACH,OAAO+C,iBAAAA,CAAkBf,OAAOI,QAAQ,CAAA;gBAE1C,KAAK,KAAA;AACH,oBAAA,qBACEe,cAAA,CAAA,aAAA,CAAC3B,SAAAA,EAAAA;wBACC4B,GAAAA,EAAKpB,MAAAA,CAAOQ,UAAU,CAACuB,YAAY;AACnCvB,wBAAAA,UAAAA,EAAYR,OAAOQ,UAAU;AAC7BwB,wBAAAA,OAAAA,EAAS,IAAMlD,iBAAAA,CAAkBmD,eAAAA,CAAgBjC,MAAAA,CAAOQ,UAAU,CAAA;;gBAIxE,KAAK,eAAA;AACH,oBAAA,qBACEW,cAAA,CAAA,aAAA,CAACe,MAAAA,EAAAA;wBACCd,GAAAA,EAAI,eAAA;wBACJe,OAAAA,EAAQ,SAAA;wBACRC,OAAAA,EAAS,IAAA;4BACP3D,QAAAA,CAAS;gCAAET,IAAAA,EAAM,YAAA;AAAcqE,gCAAAA,MAAAA,EAAQC,WAAWC,iBAAiB;gCAAEC,OAAAA,EAAS;AAAO,6BAAA,CAAA;AACvF,wBAAA;;;;;AAMN,gBAAA;oBACE/B,iBAAAA,CAAkBT,CAAAA;AACtB;QACF,CAAA,GAAA;QAEA,OAAOW,kBAAAA,IAAsBkB,KAAAA,KAAU,CAAA,iBACrCV,cAAA,CAAA,aAAA,CAACsB,QAAAA,EAAAA;AAASrB,YAAAA,GAAAA,EAAKN,WAAAA,CAAYd,MAAAA;WAAU8B,eAAAA,CAAAA,GAErCA,eAAAA;AAEJ,IAAA,CAAA,CAAA,CAAA;AAGN;;;;"}
1
+ {"version":3,"file":"SsoAndOAuthButtons.mjs","sources":["../../../../../../../../../web/src/ui/b2b/screens/SsoAndOAuthButtons.tsx"],"sourcesContent":["import React from 'react';\nimport { B2BOAuthProviders, AuthFlowType } from '@stytch/core/public';\nimport { arrayUtils } from '@stytch/core';\nimport { useLingui } from '@lingui/react/macro';\n\nimport { useConfig, useGlobalReducer } from '../GlobalContextProvider';\nimport { AppScreens, ButtonComponent, MainScreenComponent } from '../types/AppScreens';\nimport { OauthProviderParams, useEffectiveAuthConfig } from '../hooks/useEffectiveAuthConfig';\nimport { useProductComponents } from '../utils';\nimport { assertUnreachable } from '../../../utils/assertUnreachable';\nimport { AuthButton as AuthButtonType, getButtonKey, getSsoMethodKey } from '../types/authMethodKeys';\nimport { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod';\nimport Button from '../../components/atoms/Button';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport ButtonColumn from '../../components/molecules/ButtonColumn';\nimport { getButtonId, usePresentation } from '../../components/PresentationConfig';\n\n// OAuth helper functions\nexport const getCustomScopesForProvider = (\n oauthProvider: {\n type: B2BOAuthProviders;\n one_tap: boolean;\n customScopes: string[];\n providerParams: Record<string, string>;\n cancel_on_tap_outside?: boolean;\n },\n oauthOptionsCustomScopes: string[] | undefined,\n) => {\n let currentCustomScopes = oauthProvider.customScopes;\n if (Object.keys(currentCustomScopes).length == 0) {\n currentCustomScopes = oauthOptionsCustomScopes as string[];\n }\n return currentCustomScopes;\n};\n\nexport const getProviderParamsForProvider = (\n oauthProvider: {\n type: B2BOAuthProviders;\n one_tap: boolean;\n customScopes: string[];\n providerParams: Record<string, string>;\n cancel_on_tap_outside?: boolean;\n },\n oauthOptionsProviderParams: Record<string, string> | undefined,\n email: string | undefined,\n) => {\n let currentProviderParams = oauthProvider.providerParams;\n if (Object.keys(currentProviderParams).length == 0) {\n currentProviderParams = oauthOptionsProviderParams ?? {};\n }\n\n if (\n email &&\n (oauthProvider.type === B2BOAuthProviders.Google || oauthProvider.type === B2BOAuthProviders.Microsoft) &&\n !('login_hint' in currentProviderParams)\n ) {\n currentProviderParams = {\n ...currentProviderParams,\n login_hint: email,\n };\n }\n\n return currentProviderParams;\n};\n\nexport const SsoAndOAuthButtons = ({ buttons }: { buttons: ButtonComponent[] }) => {\n const { t } = useLingui();\n const [state, dispatch] = useGlobalReducer();\n const { oauthProviderSettings = [] } = useEffectiveAuthConfig();\n const presentation = usePresentation();\n\n const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();\n\n const config = useConfig();\n const { loginRedirectURL, signupRedirectURL, discoveryRedirectURL, customScopes, providerParams } =\n config.oauthOptions ?? {};\n\n const { B2BGoogleOneTap, OAuthB2BButton, SSOButton } = useProductComponents(config, 'ssoAndOAuthButtons')!;\n\n // Determine which buttons need to be displayed\n const isDiscoveryFlow = state.flowState.type === AuthFlowType.Discovery;\n const authButtons = buttons.flatMap<AuthButtonType>((button) => {\n if (button === MainScreenComponent.OAuthButtons) {\n return oauthProviderSettings.map((provider) => ({ type: 'oauth', provider }));\n } else if (button === MainScreenComponent.SSOButtons) {\n return isDiscoveryFlow\n ? { type: 'sso-discovery' }\n : (state.flowState.organization?.sso_active_connections?.map((connection) => ({ type: 'sso', connection })) ??\n []);\n } else {\n assertUnreachable(button);\n }\n });\n\n if (authButtons.length === 0) {\n return null;\n }\n\n // Reorder providers based on last used\n const [reorderedButtons, foundLastUsedOAuth] = arrayUtils.moveToFront(\n authButtons,\n (button) => getButtonKey(button) === lastUsedMethod,\n );\n\n // Helper function to create OAuth button component\n const createOAuthButton = (oauthProvider: OauthProviderParams) => {\n const providerProps = {\n customScopes: getCustomScopesForProvider(oauthProvider, customScopes),\n providerParams: getProviderParamsForProvider(oauthProvider, providerParams, state.primary.email),\n };\n\n if (oauthProvider.one_tap) {\n return (\n <B2BGoogleOneTap\n key={oauthProvider.type}\n {...providerProps}\n cancelOnTapOutside={oauthProvider.cancel_on_tap_outside}\n />\n );\n }\n\n return (\n <OAuthB2BButton\n key={oauthProvider.type}\n providerType={oauthProvider.type}\n loginRedirectUrl={loginRedirectURL}\n signupRedirectUrl={signupRedirectURL}\n discoveryRedirectUrl={discoveryRedirectURL}\n onSuccess={() => setLastUsedMethod(oauthProvider.type)}\n {...providerProps}\n />\n );\n };\n\n return (\n <ButtonColumn>\n {reorderedButtons.map((button, index) => {\n const buttonComponent = (() => {\n switch (button.type) {\n case 'oauth':\n return createOAuthButton(button.provider);\n\n case 'sso':\n return (\n <SSOButton\n key={button.connection.display_name}\n connection={button.connection}\n onStart={() => setLastUsedMethod(getSsoMethodKey(button.connection))}\n />\n );\n\n case 'sso-discovery':\n return (\n <Button\n key=\"sso-discovery\"\n variant=\"outline\"\n id={getButtonId('sso-discovery', presentation.options)}\n onClick={() => {\n dispatch({ type: 'transition', screen: AppScreens.SSODiscoveryEmail, history: 'push' });\n }}\n >\n {t({ id: 'provider.continueWithSSO', message: 'Use single sign-on' })}\n </Button>\n );\n\n default:\n assertUnreachable(button);\n }\n })();\n\n return foundLastUsedOAuth && index === 0 ? (\n <LastUsed key={getButtonKey(button)}>{buttonComponent}</LastUsed>\n ) : (\n buttonComponent\n );\n })}\n </ButtonColumn>\n );\n};\n"],"names":["getCustomScopesForProvider","oauthProvider","oauthOptionsCustomScopes","currentCustomScopes","customScopes","Object","keys","length","getProviderParamsForProvider","oauthOptionsProviderParams","email","currentProviderParams","providerParams","type","B2BOAuthProviders","Google","Microsoft","login_hint","SsoAndOAuthButtons","buttons","useLingui","state","dispatch","useGlobalReducer","oauthProviderSettings","useEffectiveAuthConfig","presentation","usePresentation","lastUsedMethod","setLastUsedMethod","useLastUsedAuthMethod","config","useConfig","loginRedirectURL","signupRedirectURL","discoveryRedirectURL","oauthOptions","B2BGoogleOneTap","OAuthB2BButton","SSOButton","useProductComponents","isDiscoveryFlow","flowState","AuthFlowType","Discovery","authButtons","flatMap","button","MainScreenComponent","OAuthButtons","map","provider","SSOButtons","organization","sso_active_connections","connection","assertUnreachable","reorderedButtons","foundLastUsedOAuth","arrayUtils","moveToFront","getButtonKey","createOAuthButton","providerProps","primary","one_tap","React","key","cancelOnTapOutside","cancel_on_tap_outside","providerType","loginRedirectUrl","signupRedirectUrl","discoveryRedirectUrl","onSuccess","ButtonColumn","index","buttonComponent","display_name","onStart","getSsoMethodKey","Button","variant","id","getButtonId","options","onClick","screen","AppScreens","SSODiscoveryEmail","history","LastUsed"],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  function extractConnectionId(method) {
5
5
  return method?.startsWith('sso:') ? method.slice(4) : undefined;
6
6
  }
7
- function getButtonId(button) {
7
+ function getButtonKey(button) {
8
8
  if (button.type === 'oauth') {
9
9
  return button.provider.type;
10
10
  } else if (button.type === 'sso') {
@@ -14,5 +14,5 @@ function getButtonId(button) {
14
14
  }
15
15
  }
16
16
 
17
- export { extractConnectionId, getButtonId, getSsoMethodKey };
17
+ export { extractConnectionId, getButtonKey, getSsoMethodKey };
18
18
  //# sourceMappingURL=authMethodKeys.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"authMethodKeys.mjs","sources":["../../../../../../../../../web/src/ui/b2b/types/authMethodKeys.ts"],"sourcesContent":["import { B2BOAuthProviders, SSOActiveConnection } from '@stytch/core/public';\nimport { OauthProviderParams } from '../hooks/useEffectiveAuthConfig';\n\n// This file contains a combined type to identify OAuth providers and SSO connections,\n// used to help with rendering these buttons and storing the last used method.\n// Extracting the logic for generating the key helps make it more consistent\n\nexport type LastUsedMethod = B2BOAuthProviders | `sso:${string}`;\n\n/* eslint-disable lingui/no-unlocalized-strings */\n\nexport function getSsoMethodKey(method: SSOActiveConnection): LastUsedMethod {\n return `sso:${method.connection_id}`;\n}\n\nexport function extractConnectionId(method: string | null): string | undefined {\n return method?.startsWith('sso:') ? method.slice(4) : undefined;\n}\n\nexport type AuthButton =\n | { type: 'oauth'; provider: OauthProviderParams }\n | { type: 'sso'; connection: SSOActiveConnection }\n | { type: 'sso-discovery' };\n\nexport function getButtonId(button: AuthButton) {\n if (button.type === 'oauth') {\n return button.provider.type;\n } else if (button.type === 'sso') {\n return getSsoMethodKey(button.connection);\n } else {\n return 'sso-discovery';\n }\n}\n"],"names":["getSsoMethodKey","method","connection_id","extractConnectionId","startsWith","slice","undefined","getButtonId","button","type","provider","connection"],"mappings":"AASA,mDAEO,SAASA,eAAAA,CAAgBC,MAA2B,EAAA;AACzD,IAAA,OAAO,CAAC,IAAI,EAAEA,MAAAA,CAAOC,aAAa,CAAA,CAAE;AACtC;AAEO,SAASC,oBAAoBF,MAAqB,EAAA;AACvD,IAAA,OAAOA,QAAQG,UAAAA,CAAW,MAAA,CAAA,GAAUH,MAAAA,CAAOI,KAAK,CAAC,CAAA,CAAA,GAAKC,SAAAA;AACxD;AAOO,SAASC,YAAYC,MAAkB,EAAA;IAC5C,IAAIA,MAAAA,CAAOC,IAAI,KAAK,OAAA,EAAS;QAC3B,OAAOD,MAAAA,CAAOE,QAAQ,CAACD,IAAI;AAC7B,IAAA,CAAA,MAAO,IAAID,MAAAA,CAAOC,IAAI,KAAK,KAAA,EAAO;QAChC,OAAOT,eAAAA,CAAgBQ,OAAOG,UAAU,CAAA;IAC1C,CAAA,MAAO;QACL,OAAO,eAAA;AACT,IAAA;AACF;;;;"}
1
+ {"version":3,"file":"authMethodKeys.mjs","sources":["../../../../../../../../../web/src/ui/b2b/types/authMethodKeys.ts"],"sourcesContent":["import { B2BOAuthProviders, SSOActiveConnection } from '@stytch/core/public';\nimport { OauthProviderParams } from '../hooks/useEffectiveAuthConfig';\n\n// This file contains a combined type to identify OAuth providers and SSO connections,\n// used to help with rendering these buttons and storing the last used method.\n// Extracting the logic for generating the key helps make it more consistent\n\nexport type LastUsedMethod = B2BOAuthProviders | `sso:${string}`;\n\n/* eslint-disable lingui/no-unlocalized-strings */\n\nexport function getSsoMethodKey(method: SSOActiveConnection): LastUsedMethod {\n return `sso:${method.connection_id}`;\n}\n\nexport function extractConnectionId(method: string | null): string | undefined {\n return method?.startsWith('sso:') ? method.slice(4) : undefined;\n}\n\nexport type AuthButton =\n | { type: 'oauth'; provider: OauthProviderParams }\n | { type: 'sso'; connection: SSOActiveConnection }\n | { type: 'sso-discovery' };\n\nexport function getButtonKey(button: AuthButton) {\n if (button.type === 'oauth') {\n return button.provider.type;\n } else if (button.type === 'sso') {\n return getSsoMethodKey(button.connection);\n } else {\n return 'sso-discovery';\n }\n}\n"],"names":["getSsoMethodKey","method","connection_id","extractConnectionId","startsWith","slice","undefined","getButtonKey","button","type","provider","connection"],"mappings":"AASA,mDAEO,SAASA,eAAAA,CAAgBC,MAA2B,EAAA;AACzD,IAAA,OAAO,CAAC,IAAI,EAAEA,MAAAA,CAAOC,aAAa,CAAA,CAAE;AACtC;AAEO,SAASC,oBAAoBF,MAAqB,EAAA;AACvD,IAAA,OAAOA,QAAQG,UAAAA,CAAW,MAAA,CAAA,GAAUH,MAAAA,CAAOI,KAAK,CAAC,CAAA,CAAA,GAAKC,SAAAA;AACxD;AAOO,SAASC,aAAaC,MAAkB,EAAA;IAC7C,IAAIA,MAAAA,CAAOC,IAAI,KAAK,OAAA,EAAS;QAC3B,OAAOD,MAAAA,CAAOE,QAAQ,CAACD,IAAI;AAC7B,IAAA,CAAA,MAAO,IAAID,MAAAA,CAAOC,IAAI,KAAK,KAAA,EAAO;QAChC,OAAOT,eAAAA,CAAgBQ,OAAOG,UAAU,CAAA;IAC1C,CAAA,MAAO;QACL,OAAO,eAAA;AACT,IAAA;AACF;;;;"}
@@ -2,7 +2,7 @@ import React__default from 'react';
2
2
  import { useLingui } from '../../../../../../node_modules/@lingui/react/dist/index.mjs';
3
3
  import { useStytch } from '../GlobalContextProvider.mjs';
4
4
  import Button from '../../components/atoms/Button.mjs';
5
- import { usePresentation } from '../../components/PresentationConfig.mjs';
5
+ import { usePresentation, getButtonId } from '../../components/PresentationConfig.mjs';
6
6
  import { OAuthProviders } from '../../../../../core/src/public/ui.mjs';
7
7
 
8
8
  const providerInfo = {
@@ -124,7 +124,9 @@ const providerInfo = {
124
124
  const OAuthButton = ({ providerType, loginRedirectUrl, signupRedirectUrl, customScopes, providerParams, onSuccess })=>{
125
125
  const { i18n: $__i18n, _: $__ } = useLingui();
126
126
  const stytchClient = useStytch();
127
- const iconRegistry = usePresentation().iconRegistry;
127
+ const presentation = usePresentation();
128
+ const iconRegistry = presentation.iconRegistry;
129
+ const id = getButtonId(`oauth-${providerType}`, presentation.options);
128
130
  const provider = providerInfo[providerType];
129
131
  let label = providerType;
130
132
  let icon = null;
@@ -147,7 +149,8 @@ const OAuthButton = ({ providerType, loginRedirectUrl, signupRedirectUrl, custom
147
149
  return /*#__PURE__*/ React__default.createElement(Button, {
148
150
  onClick: onButtonClick,
149
151
  variant: "outline",
150
- icon: icon
152
+ icon: icon,
153
+ id: id
151
154
  }, label);
152
155
  };
153
156