{"version":3,"file":"Nudge.mjs","sources":["../../src/nudge/Nudge.tsx"],"sourcesContent":["import { Illustration, Assets, type IllustrationNames } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { ReactNode, useEffect, useState, MouseEvent } from 'react';\n\nimport Body from '../body';\nimport { Typography } from '../common';\nimport Link from '../link';\nimport type { AlertAction } from '../alert';\nimport IconButton from '../iconButton';\nimport { Cross } from '@transferwise/icons';\nimport { useIntl } from 'react-intl';\nimport closeBtnMessages from '../common/closeButton/CloseButton.messages';\n\n// WARNING: Changing this will cause nudges to reappear wherever persist nudge is used and privacy team will need to be updated too\nexport const STORAGE_NAME = 'dismissedNudges';\n\nconst getLocalStorage = (): string[] => {\n  try {\n    const storageItem = localStorage.getItem(STORAGE_NAME);\n\n    if (storageItem) {\n      const storage: unknown = JSON.parse(storageItem);\n\n      if (Array.isArray(storage)) {\n        return storage.map((item) => String(item));\n      }\n    }\n  } catch (error) {}\n\n  return [];\n};\n\ntype MediaNameType =\n  | `${Assets.GLOBE}`\n  | `${Assets.LOCK}`\n  | `${Assets.WALLET}`\n  | `${Assets.GEAR}`\n  | `${Assets.INVITE_LETTER}`\n  | `${Assets.PERSONAL_CARD}`\n  | `${Assets.BUSINESS_CARD}`\n  | `${Assets.HEART}`\n  | `${Assets.MULTI_CURRENCY}`\n  | `${Assets.SHOPPING_BAG}`\n  | `${Assets.FLOWER}`\n  | `${Assets.GIFT_BOX}`\n  | `${Assets.BACKPACK}`;\n\ntype BaseProps = {\n  /** @deprecated Use `mediaName` property instead. */\n  media?: ReactNode;\n  /** Media name  */\n  mediaName?: MediaNameType;\n  title: ReactNode;\n  link?: ReactNode;\n  href?: string;\n  onClick?: (event?: MouseEvent<HTMLSpanElement>) => void;\n  /** Fired when the user clicks on close button */\n  onDismiss?: () => void;\n  /** An optional call to action to sit under the main body of the nudge. If your label is short, use aria-label to provide more context */\n  action?: AlertAction;\n  className?: string;\n};\n\nexport interface OptionalId extends BaseProps {\n  id?: string;\n  persistDismissal?: false;\n  isPreviouslyDismissed?: undefined;\n}\n\nexport interface RequiredPersistProps extends BaseProps {\n  /** This ID should be completely unique to the page and feature as it uses a shared array which could conflict with other nudges in Wise */\n  id: string;\n  /** Use persist dismissal to keep the nudge dismissed using the browser's localStorage */\n  persistDismissal: true;\n  /**\n   * Fired on mount for determining if nudge has been dismissed before\n   *\n   * @param {boolean}  value - set to true if dismissed previously\n   */\n  isPreviouslyDismissed?: (value: boolean) => void;\n}\n\nexport type Props = OptionalId | RequiredPersistProps;\n\nconst Nudge = ({\n  mediaName,\n  title,\n  link,\n  href,\n  onClick,\n  onDismiss,\n  persistDismissal,\n  isPreviouslyDismissed,\n  id,\n  className,\n  action,\n}: Props) => {\n  const intl = useIntl();\n  const [isDismissed, setIsDismissed] = useState(false);\n  const [isMounted, setIsMounted] = useState(false);\n\n  const handleOnDismiss = () => {\n    const dismissedNudgesStorage = getLocalStorage();\n\n    if (persistDismissal && id) {\n      try {\n        localStorage.setItem(STORAGE_NAME, JSON.stringify([...dismissedNudgesStorage, id]));\n      } catch (error) {}\n\n      setIsDismissed(true);\n    }\n\n    if (onDismiss) {\n      onDismiss();\n    }\n  };\n\n  useEffect(() => {\n    if (persistDismissal && id) {\n      const dismissedNudgesStorage = getLocalStorage();\n      let isDismissed = false;\n\n      if (dismissedNudgesStorage?.find((item) => item === id)) {\n        setIsDismissed(true);\n        isDismissed = true;\n      }\n\n      if (isPreviouslyDismissed) {\n        isPreviouslyDismissed(isDismissed);\n      }\n    }\n\n    setIsMounted(true);\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [id, persistDismissal]);\n\n  if (persistDismissal && (isDismissed || !isMounted)) {\n    return null;\n  }\n\n  return (\n    <div className={clsx('wds-nudge', className)} id={id}>\n      {!!mediaName && (\n        <div className=\"wds-nudge-media\">\n          <Illustration\n            name={mediaName as IllustrationNames}\n            className={clsx(`wds-nudge-media-${mediaName}`)}\n            size=\"small\"\n            disablePadding\n            alt=\"\"\n          />\n        </div>\n      )}\n      <div className=\"wds-nudge-container\">\n        <div className=\"wds-nudge-content\">\n          <Body type={Typography.BODY_LARGE} className={clsx('wds-nudge-body')}>\n            {title}\n          </Body>\n          {/* Merge these two Link instances into one */}\n          {link && (\n            <Link\n              href={href}\n              type={Typography.LINK_LARGE}\n              className=\"wds-nudge-link\"\n              onClick={onClick}\n            >\n              {link}\n            </Link>\n          )}\n          {action && (\n            <Link\n              href={action.href}\n              target={action.target}\n              className=\"m-t-1\"\n              aria-label={action['aria-label']}\n              type={Typography.LINK_LARGE}\n              onClick={action.onClick}\n            >\n              {action.text}\n            </Link>\n          )}\n        </div>\n        {onDismiss || persistDismissal ? (\n          <IconButton\n            size={24}\n            priority=\"tertiary\"\n            aria-label={intl.formatMessage(closeBtnMessages.ariaLabel)}\n            onClick={handleOnDismiss}\n          >\n            <Cross />\n          </IconButton>\n        ) : null}\n      </div>\n    </div>\n  );\n};\n\nexport default Nudge;\n"],"names":["STORAGE_NAME","getLocalStorage","storageItem","localStorage","getItem","storage","JSON","parse","Array","isArray","map","item","String","error","Nudge","mediaName","title","link","href","onClick","onDismiss","persistDismissal","isPreviouslyDismissed","id","className","action","intl","useIntl","isDismissed","setIsDismissed","useState","isMounted","setIsMounted","handleOnDismiss","dismissedNudgesStorage","setItem","stringify","useEffect","find","_jsxs","clsx","children","_jsx","Illustration","name","size","disablePadding","alt","Body","type","Typography","BODY_LARGE","Link","LINK_LARGE","target","text","IconButton","priority","formatMessage","closeBtnMessages","ariaLabel","Cross"],"mappings":"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"}