@sproutsocial/seeds-react-toast 1.0.20 → 1.0.24

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.
@@ -3,19 +3,19 @@ $ tsup --dts
3
3
  CLI Building entry: src/index.ts
4
4
  CLI Using tsconfig: tsconfig.json
5
5
  CLI tsup v8.5.0
6
- CLI Using tsup config: /home/runner/work/seeds/seeds/seeds-react/seeds-react-toast/tsup.config.ts
6
+ CLI Using tsup config: /home/runner/_work/seeds/seeds/seeds-react/seeds-react-toast/tsup.config.ts
7
7
  CLI Target: es2022
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- CJS dist/index.js 9.52 KB
12
- CJS dist/index.js.map 13.09 KB
13
- CJS ⚡️ Build success in 185ms
14
- ESM dist/esm/index.js 6.76 KB
15
- ESM dist/esm/index.js.map 12.64 KB
16
- ESM ⚡️ Build success in 184ms
11
+ CJS dist/index.js 9.75 KB
12
+ CJS dist/index.js.map 13.32 KB
13
+ CJS ⚡️ Build success in 15ms
14
+ ESM dist/esm/index.js 6.93 KB
15
+ ESM dist/esm/index.js.map 12.88 KB
16
+ ESM ⚡️ Build success in 16ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 38804ms
18
+ DTS ⚡️ Build success in 5626ms
19
19
  DTS dist/index.d.ts 3.18 KB
20
20
  DTS dist/index.d.mts 3.18 KB
21
- Done in 47.15s.
21
+ Done in 7.71s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @sproutsocial/seeds-react-toast
2
2
 
3
+ ## 1.0.24
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [17d4f12]
8
+ - @sproutsocial/seeds-react-theme@3.6.0
9
+ - @sproutsocial/seeds-react-box@1.1.14
10
+ - @sproutsocial/seeds-react-icon@2.2.5
11
+
12
+ ## 1.0.23
13
+
14
+ ### Patch Changes
15
+
16
+ - 2689788: Fix Toast and Modal V1 being unclickable when Modal V2 is open
17
+
18
+ When a Radix Dialog (Modal V2) is open, it sets `pointer-events: none` on `document.body`
19
+ and listens for `pointerdown` on the document to detect outside clicks. This breaks non-Radix
20
+ overlays that portal to body (Toast, Modal V1) — making them unclickable and causing Modal V2
21
+ to dismiss when interacting with them.
22
+
23
+ **Toast**: Wrap `ToastRoot` in Radix `DismissableLayerBranch` with `pointer-events: auto`.
24
+ This registers the toast container as a branch of the dismissable layer system, preventing
25
+ Modal V2 from closing on toast interaction.
26
+
27
+ **Modal V1**: Use react-modal's `contentRef` to set `pointer-events: auto` on the portal node
28
+ and stop `pointerdown` propagation. `DismissableLayerBranch` can't be used here because
29
+ react-modal portals to `document.body`, and Modal V2's `transform` creates a containing block
30
+ that would break V1's `position: fixed` overlay if portaled inside V2.
31
+
32
+ ## 1.0.22
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies [118e300]
37
+ - @sproutsocial/seeds-react-theme@3.5.1
38
+ - @sproutsocial/seeds-react-box@1.1.13
39
+ - @sproutsocial/seeds-react-icon@2.2.4
40
+
41
+ ## 1.0.21
42
+
43
+ ### Patch Changes
44
+
45
+ - @sproutsocial/seeds-react-icon@2.2.3
46
+
3
47
  ## 1.0.20
4
48
 
5
49
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  toast as toastifyToast,
4
4
  cssTransition
5
5
  } from "react-toastify";
6
+ import { DismissableLayerBranch } from "@radix-ui/react-dismissable-layer";
6
7
  import Box2 from "@sproutsocial/seeds-react-box";
7
8
  import Icon from "@sproutsocial/seeds-react-icon";
8
9
  import Text from "@sproutsocial/seeds-react-text";
@@ -134,7 +135,7 @@ var SproutZoomTransition = cssTransition({
134
135
  enter: "SproutToast__zoom-in",
135
136
  exit: "SproutToast__zoom-out"
136
137
  });
137
- var ToastContainer2 = (props) => /* @__PURE__ */ jsx(ToastRoot, { ...props });
138
+ var ToastContainer2 = (props) => /* @__PURE__ */ jsx(DismissableLayerBranch, { style: { pointerEvents: "auto" }, children: /* @__PURE__ */ jsx(ToastRoot, { ...props }) });
138
139
  var themeIcon = {
139
140
  success: "circle-check-outline",
140
141
  info: "circle-i-outline",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Toast.tsx","../../src/styles.ts","../../src/ToastTypes.ts"],"sourcesContent":["import type { PropsWithChildren, ReactNode, ComponentProps } from \"react\";\nimport {\n toast as toastifyToast,\n cssTransition,\n type ToastContent,\n} from \"react-toastify\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon, { type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Container, ToastRoot } from \"./styles\";\nimport type { TypeToastOptions, TypeToastTheme } from \"./ToastTypes\";\nimport styled from \"styled-components\";\n\nexport const toastDismiss: typeof toastifyToast.dismiss = (...input) =>\n // @ts-ignore Not sure what this type is supposed to be\n toastifyToast.dismiss(...input);\nexport const toastIsActive: typeof toastifyToast.isActive = (...input) =>\n toastifyToast.isActive(...input);\nexport const toastUpdate: typeof toastifyToast.update = (...input) =>\n toastifyToast.update(...input);\n\nconst NoTransition = cssTransition({\n enter: \"SproutToast__none-in\",\n exit: \"SproutToast__none-out\",\n});\nconst SproutZoomTransition = cssTransition({\n enter: \"SproutToast__zoom-in\",\n exit: \"SproutToast__zoom-out\",\n});\n\nexport const ToastContainer = (\n props: Partial<ComponentProps<typeof ToastRoot>>\n) => <ToastRoot {...props} />;\n\nconst themeIcon: Record<TypeToastTheme, TypeIconName> = {\n success: \"circle-check-outline\",\n info: \"circle-i-outline\",\n warning: \"triangle-exclamation-outline\",\n error: \"triangle-exclamation-outline\",\n} as const;\n\nexport function toast<TData = unknown>(\n options: TypeToastOptions<TData>\n): ReturnType<typeof toastifyToast> {\n const {\n closeOnClick = true,\n content,\n onClose,\n persist,\n toastId: inputToastId,\n useTransition = true,\n position = \"bottom-right\",\n autoClose = persist ? false : 6000,\n transition = useTransition ? SproutZoomTransition : NoTransition,\n ...rest\n } = options;\n\n let toastId = inputToastId;\n if (!toastId && typeof content === \"string\") {\n toastId = content;\n }\n\n const renderToast: ToastContent<TData> = (toastInput) => {\n const renderedContent =\n typeof content === \"function\" ? content(toastInput) : content;\n\n if (options.theme === \"custom\") {\n return renderedContent;\n }\n\n const theme = options.theme || \"info\";\n const iconName = options.icon || themeIcon[theme];\n const containerColor =\n options.color ||\n (\n {\n success: \"container.border.success\",\n error: \"container.border.error\",\n info: \"container.border.info\",\n warning: \"container.border.warning\",\n } as const\n )[theme];\n const iconColor =\n options.color ||\n (\n {\n success: \"icon.success\",\n error: \"icon.error\",\n info: \"icon.info\",\n warning: \"icon.warning\",\n } as const\n )[theme];\n\n return (\n // TODO: if this closes when clicked, there should be a label saying \"Click to close\" that can be overridden\n <ToastContentContainer\n icon={<Icon name={iconName} color={iconColor} />}\n close={<Icon name=\"x-outline\" color=\"icon.base\" aria-hidden />}\n highlightColor={containerColor}\n >\n {renderedContent}\n </ToastContentContainer>\n );\n };\n\n const toastOptions = {\n autoClose,\n closeOnClick,\n onClose,\n toastId: toastId || undefined,\n transition,\n position,\n ...rest,\n icon: undefined,\n color: undefined,\n } as const;\n\n if (toastId && toastIsActive(toastId)) {\n toastifyToast.update<TData>(toastId, {\n ...toastOptions,\n render: renderToast,\n });\n } else {\n toastId = toastifyToast<TData>(renderToast, toastOptions);\n }\n\n return toastId;\n}\n\nexport default ToastContainer;\n\nexport const ToastContentContainer = ({\n children,\n icon,\n close,\n highlightColor,\n}: PropsWithChildren<{\n /**\n * A ReactNode in the icon slot\n */\n icon: ReactNode;\n /**\n * A ReactNode in the close button slot\n */\n close: ReactNode;\n highlightColor?: ComponentProps<typeof Box>[\"bg\"];\n}>) => {\n return (\n <Container data-qa-toast=\"\">\n {highlightColor ? (\n <ToastHighlight bg={highlightColor} aria-hidden />\n ) : null}\n\n <Box css=\"line-height: 1;\">{icon}</Box>\n\n <Box flex={1}>\n <Text as=\"div\" color=\"text.body\" data-qa-toast-content=\"\">\n {children}\n </Text>\n </Box>\n\n <Box css=\"line-height: 1;\">{close}</Box>\n </Container>\n );\n};\n\nexport const ToastHighlight = styled(Box)<ComponentProps<typeof Box>>`\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 2px;\n`;\n","import styled from \"styled-components\";\nimport type { ComponentProps } from \"react\";\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport \"react-toastify/dist/ReactToastify.css\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { ToastContainer } from \"react-toastify\";\n\nexport const TOAST_Z_INDEX = 9999;\n\nexport const Container = styled(Box)<ComponentProps<typeof Box>>`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[350]};\n font-family: ${({ theme }) => theme.fontFamily};\n ${({ theme }) => theme.typography[200]}\n position: relative;\n padding: ${({ theme }) => theme.space[350]};\n`;\n\nexport const ToastRoot = styled(ToastContainer).attrs({\n toastClassName: \"Toastify-toast-overrides\",\n hideProgressBar: true,\n closeButton: false,\n icon: false,\n position: \"bottom-right\",\n})`\n --toastify-z-index: ${TOAST_Z_INDEX};\n --toastify-toast-offset: ${({ theme }) => theme.space[400]};\n --toastify-toast-width: 360px;\n --toastify-toast-min-height: 48px;\n --toastify-toast-max-height: 70vh;\n --toastify-toast-bd-radius: ${({ theme }) => theme.radii[400]};\n --toastify-toast-background: ${({ theme }) =>\n theme.colors.container.background.base};\n /* there's margin-bottom on the last toast so we can remove this */\n --toastify-toast-bottom: 0;\n\n padding: 0;\n\n .Toastify-toast-overrides {\n background: ${({ theme }) => theme.colors.container.background.base};\n color: ${({ theme }) => theme.colors.text.body};\n box-shadow: ${({ theme }) => theme.shadows.low};\n padding: 0;\n margin-bottom: var(--toastify-toast-offset);\n }\n\n .Toastify__toast-body {\n padding: 0;\n margin: 0;\n }\n\n /* Override React Toastify's mobile width styles */\n @media only screen and (max-width: 480px) {\n .Toastify-container-overrides {\n min-width: initial !important;\n }\n }\n\n /* Zoom animation */\n @keyframes SproutToast__zoom-in {\n from {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3);\n }\n 50% {\n opacity: 1;\n }\n }\n @keyframes SproutToast__zoom-out {\n from {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3) translate3d(0, var(--y), 0);\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__zoom-in {\n animation: SproutToast__zoom-in ${({ theme }) => theme.duration.medium}\n ${({ theme }) => theme.easing.ease_out} both;\n }\n .SproutToast__zoom-out {\n animation: SproutToast__zoom-out ${({ theme }) => theme.duration.slow}\n ${({ theme }) => theme.easing.ease_in} both;\n }\n\n /* No animation (it's still necessary to define classes for no animation to work properly) */\n @keyframes SproutToast__none-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n @keyframes SproutToast__none-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__none-in {\n animation: SproutToast__none-in 0s both;\n }\n .SproutToast__none-out {\n animation: SproutToast__none-out 0s both;\n }\n`;\n","import type { ComponentProps } from \"react\";\nimport { type Icon, type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport type { ToastContent, ToastOptions } from \"react-toastify\";\n\nexport type TypeToastTheme = \"info\" | \"success\" | \"warning\" | \"error\";\n\ninterface BaseToastOptions<TData>\n extends Omit<ToastOptions<TData>, \"closeButton\" | \"icon\" | \"type\"> {\n theme?: TypeToastTheme | \"custom\";\n content: ToastContent<TData>;\n persist?: boolean;\n useTransition?: boolean;\n}\n\ninterface ThemedToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * One of `info`, `success`, `warning`, or `error`.\n */\n theme?: TypeToastTheme;\n /**\n * @deprecated Use `custom` theme instead.\n */\n color?: ComponentProps<typeof Icon>[\"color\"];\n /**\n * @deprecated Use `custom` theme instead.\n */\n icon?: TypeIconName;\n}\ninterface CustomToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * If you need to break out of the supported styles you can use the `custom` theme. You can use `ToastContentContainer` with `Icon` and `ToastHighlight` to build your custom toast.\n */\n theme: \"custom\";\n}\n\nexport type TypeToastOptions<TData> =\n | ThemedToastOptions<TData>\n | CustomToastOptions<TData>;\n"],"mappings":"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","names":["Box","styled","ToastContainer","Box","styled"]}
1
+ {"version":3,"sources":["../../src/Toast.tsx","../../src/styles.ts","../../src/ToastTypes.ts"],"sourcesContent":["import type { PropsWithChildren, ReactNode, ComponentProps } from \"react\";\nimport {\n toast as toastifyToast,\n cssTransition,\n type ToastContent,\n} from \"react-toastify\";\nimport { DismissableLayerBranch } from \"@radix-ui/react-dismissable-layer\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon, { type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Container, ToastRoot } from \"./styles\";\nimport type { TypeToastOptions, TypeToastTheme } from \"./ToastTypes\";\nimport styled from \"styled-components\";\n\nexport const toastDismiss: typeof toastifyToast.dismiss = (...input) =>\n // @ts-ignore Not sure what this type is supposed to be\n toastifyToast.dismiss(...input);\nexport const toastIsActive: typeof toastifyToast.isActive = (...input) =>\n toastifyToast.isActive(...input);\nexport const toastUpdate: typeof toastifyToast.update = (...input) =>\n toastifyToast.update(...input);\n\nconst NoTransition = cssTransition({\n enter: \"SproutToast__none-in\",\n exit: \"SproutToast__none-out\",\n});\nconst SproutZoomTransition = cssTransition({\n enter: \"SproutToast__zoom-in\",\n exit: \"SproutToast__zoom-out\",\n});\n\nexport const ToastContainer = (\n props: Partial<ComponentProps<typeof ToastRoot>>\n) => (\n <DismissableLayerBranch style={{ pointerEvents: \"auto\" }}>\n <ToastRoot {...props} />\n </DismissableLayerBranch>\n);\n\nconst themeIcon: Record<TypeToastTheme, TypeIconName> = {\n success: \"circle-check-outline\",\n info: \"circle-i-outline\",\n warning: \"triangle-exclamation-outline\",\n error: \"triangle-exclamation-outline\",\n} as const;\n\nexport function toast<TData = unknown>(\n options: TypeToastOptions<TData>\n): ReturnType<typeof toastifyToast> {\n const {\n closeOnClick = true,\n content,\n onClose,\n persist,\n toastId: inputToastId,\n useTransition = true,\n position = \"bottom-right\",\n autoClose = persist ? false : 6000,\n transition = useTransition ? SproutZoomTransition : NoTransition,\n ...rest\n } = options;\n\n let toastId = inputToastId;\n if (!toastId && typeof content === \"string\") {\n toastId = content;\n }\n\n const renderToast: ToastContent<TData> = (toastInput) => {\n const renderedContent =\n typeof content === \"function\" ? content(toastInput) : content;\n\n if (options.theme === \"custom\") {\n return renderedContent;\n }\n\n const theme = options.theme || \"info\";\n const iconName = options.icon || themeIcon[theme];\n const containerColor =\n options.color ||\n (\n {\n success: \"container.border.success\",\n error: \"container.border.error\",\n info: \"container.border.info\",\n warning: \"container.border.warning\",\n } as const\n )[theme];\n const iconColor =\n options.color ||\n (\n {\n success: \"icon.success\",\n error: \"icon.error\",\n info: \"icon.info\",\n warning: \"icon.warning\",\n } as const\n )[theme];\n\n return (\n // TODO: if this closes when clicked, there should be a label saying \"Click to close\" that can be overridden\n <ToastContentContainer\n icon={<Icon name={iconName} color={iconColor} />}\n close={<Icon name=\"x-outline\" color=\"icon.base\" aria-hidden />}\n highlightColor={containerColor}\n >\n {renderedContent}\n </ToastContentContainer>\n );\n };\n\n const toastOptions = {\n autoClose,\n closeOnClick,\n onClose,\n toastId: toastId || undefined,\n transition,\n position,\n ...rest,\n icon: undefined,\n color: undefined,\n } as const;\n\n if (toastId && toastIsActive(toastId)) {\n toastifyToast.update<TData>(toastId, {\n ...toastOptions,\n render: renderToast,\n });\n } else {\n toastId = toastifyToast<TData>(renderToast, toastOptions);\n }\n\n return toastId;\n}\n\nexport default ToastContainer;\n\nexport const ToastContentContainer = ({\n children,\n icon,\n close,\n highlightColor,\n}: PropsWithChildren<{\n /**\n * A ReactNode in the icon slot\n */\n icon: ReactNode;\n /**\n * A ReactNode in the close button slot\n */\n close: ReactNode;\n highlightColor?: ComponentProps<typeof Box>[\"bg\"];\n}>) => {\n return (\n <Container data-qa-toast=\"\">\n {highlightColor ? (\n <ToastHighlight bg={highlightColor} aria-hidden />\n ) : null}\n\n <Box css=\"line-height: 1;\">{icon}</Box>\n\n <Box flex={1}>\n <Text as=\"div\" color=\"text.body\" data-qa-toast-content=\"\">\n {children}\n </Text>\n </Box>\n\n <Box css=\"line-height: 1;\">{close}</Box>\n </Container>\n );\n};\n\nexport const ToastHighlight = styled(Box)<ComponentProps<typeof Box>>`\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 2px;\n`;\n","import styled from \"styled-components\";\nimport type { ComponentProps } from \"react\";\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport \"react-toastify/dist/ReactToastify.css\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { ToastContainer } from \"react-toastify\";\n\nexport const TOAST_Z_INDEX = 9999;\n\nexport const Container = styled(Box)<ComponentProps<typeof Box>>`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[350]};\n font-family: ${({ theme }) => theme.fontFamily};\n ${({ theme }) => theme.typography[200]}\n position: relative;\n padding: ${({ theme }) => theme.space[350]};\n`;\n\nexport const ToastRoot = styled(ToastContainer).attrs({\n toastClassName: \"Toastify-toast-overrides\",\n hideProgressBar: true,\n closeButton: false,\n icon: false,\n position: \"bottom-right\",\n})`\n --toastify-z-index: ${TOAST_Z_INDEX};\n --toastify-toast-offset: ${({ theme }) => theme.space[400]};\n --toastify-toast-width: 360px;\n --toastify-toast-min-height: 48px;\n --toastify-toast-max-height: 70vh;\n --toastify-toast-bd-radius: ${({ theme }) => theme.radii[400]};\n --toastify-toast-background: ${({ theme }) =>\n theme.colors.container.background.base};\n /* there's margin-bottom on the last toast so we can remove this */\n --toastify-toast-bottom: 0;\n\n padding: 0;\n\n .Toastify-toast-overrides {\n background: ${({ theme }) => theme.colors.container.background.base};\n color: ${({ theme }) => theme.colors.text.body};\n box-shadow: ${({ theme }) => theme.shadows.low};\n padding: 0;\n margin-bottom: var(--toastify-toast-offset);\n }\n\n .Toastify__toast-body {\n padding: 0;\n margin: 0;\n }\n\n /* Override React Toastify's mobile width styles */\n @media only screen and (max-width: 480px) {\n .Toastify-container-overrides {\n min-width: initial !important;\n }\n }\n\n /* Zoom animation */\n @keyframes SproutToast__zoom-in {\n from {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3);\n }\n 50% {\n opacity: 1;\n }\n }\n @keyframes SproutToast__zoom-out {\n from {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3) translate3d(0, var(--y), 0);\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__zoom-in {\n animation: SproutToast__zoom-in ${({ theme }) => theme.duration.medium}\n ${({ theme }) => theme.easing.ease_out} both;\n }\n .SproutToast__zoom-out {\n animation: SproutToast__zoom-out ${({ theme }) => theme.duration.slow}\n ${({ theme }) => theme.easing.ease_in} both;\n }\n\n /* No animation (it's still necessary to define classes for no animation to work properly) */\n @keyframes SproutToast__none-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n @keyframes SproutToast__none-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__none-in {\n animation: SproutToast__none-in 0s both;\n }\n .SproutToast__none-out {\n animation: SproutToast__none-out 0s both;\n }\n`;\n","import type { ComponentProps } from \"react\";\nimport { type Icon, type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport type { ToastContent, ToastOptions } from \"react-toastify\";\n\nexport type TypeToastTheme = \"info\" | \"success\" | \"warning\" | \"error\";\n\ninterface BaseToastOptions<TData>\n extends Omit<ToastOptions<TData>, \"closeButton\" | \"icon\" | \"type\"> {\n theme?: TypeToastTheme | \"custom\";\n content: ToastContent<TData>;\n persist?: boolean;\n useTransition?: boolean;\n}\n\ninterface ThemedToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * One of `info`, `success`, `warning`, or `error`.\n */\n theme?: TypeToastTheme;\n /**\n * @deprecated Use `custom` theme instead.\n */\n color?: ComponentProps<typeof Icon>[\"color\"];\n /**\n * @deprecated Use `custom` theme instead.\n */\n icon?: TypeIconName;\n}\ninterface CustomToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * If you need to break out of the supported styles you can use the `custom` theme. You can use `ToastContentContainer` with `Icon` and `ToastHighlight` to build your custom toast.\n */\n theme: \"custom\";\n}\n\nexport type TypeToastOptions<TData> =\n | ThemedToastOptions<TData>\n | CustomToastOptions<TData>;\n"],"mappings":"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","names":["Box","styled","ToastContainer","Box","styled"]}
package/dist/index.js CHANGED
@@ -43,6 +43,7 @@ module.exports = __toCommonJS(index_exports);
43
43
 
44
44
  // src/Toast.tsx
45
45
  var import_react_toastify2 = require("react-toastify");
46
+ var import_react_dismissable_layer = require("@radix-ui/react-dismissable-layer");
46
47
  var import_seeds_react_box2 = __toESM(require("@sproutsocial/seeds-react-box"));
47
48
  var import_seeds_react_icon = __toESM(require("@sproutsocial/seeds-react-icon"));
48
49
  var import_seeds_react_text = __toESM(require("@sproutsocial/seeds-react-text"));
@@ -174,7 +175,7 @@ var SproutZoomTransition = (0, import_react_toastify2.cssTransition)({
174
175
  enter: "SproutToast__zoom-in",
175
176
  exit: "SproutToast__zoom-out"
176
177
  });
177
- var ToastContainer2 = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastRoot, { ...props });
178
+ var ToastContainer2 = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_dismissable_layer.DismissableLayerBranch, { style: { pointerEvents: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastRoot, { ...props }) });
178
179
  var themeIcon = {
179
180
  success: "circle-check-outline",
180
181
  info: "circle-i-outline",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Toast.tsx","../src/styles.ts","../src/ToastTypes.ts"],"sourcesContent":["export * from \"./Toast\";\nexport * from \"./ToastTypes\";\nexport { TOAST_Z_INDEX } from \"./styles\";\n","import type { PropsWithChildren, ReactNode, ComponentProps } from \"react\";\nimport {\n toast as toastifyToast,\n cssTransition,\n type ToastContent,\n} from \"react-toastify\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon, { type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Container, ToastRoot } from \"./styles\";\nimport type { TypeToastOptions, TypeToastTheme } from \"./ToastTypes\";\nimport styled from \"styled-components\";\n\nexport const toastDismiss: typeof toastifyToast.dismiss = (...input) =>\n // @ts-ignore Not sure what this type is supposed to be\n toastifyToast.dismiss(...input);\nexport const toastIsActive: typeof toastifyToast.isActive = (...input) =>\n toastifyToast.isActive(...input);\nexport const toastUpdate: typeof toastifyToast.update = (...input) =>\n toastifyToast.update(...input);\n\nconst NoTransition = cssTransition({\n enter: \"SproutToast__none-in\",\n exit: \"SproutToast__none-out\",\n});\nconst SproutZoomTransition = cssTransition({\n enter: \"SproutToast__zoom-in\",\n exit: \"SproutToast__zoom-out\",\n});\n\nexport const ToastContainer = (\n props: Partial<ComponentProps<typeof ToastRoot>>\n) => <ToastRoot {...props} />;\n\nconst themeIcon: Record<TypeToastTheme, TypeIconName> = {\n success: \"circle-check-outline\",\n info: \"circle-i-outline\",\n warning: \"triangle-exclamation-outline\",\n error: \"triangle-exclamation-outline\",\n} as const;\n\nexport function toast<TData = unknown>(\n options: TypeToastOptions<TData>\n): ReturnType<typeof toastifyToast> {\n const {\n closeOnClick = true,\n content,\n onClose,\n persist,\n toastId: inputToastId,\n useTransition = true,\n position = \"bottom-right\",\n autoClose = persist ? false : 6000,\n transition = useTransition ? SproutZoomTransition : NoTransition,\n ...rest\n } = options;\n\n let toastId = inputToastId;\n if (!toastId && typeof content === \"string\") {\n toastId = content;\n }\n\n const renderToast: ToastContent<TData> = (toastInput) => {\n const renderedContent =\n typeof content === \"function\" ? content(toastInput) : content;\n\n if (options.theme === \"custom\") {\n return renderedContent;\n }\n\n const theme = options.theme || \"info\";\n const iconName = options.icon || themeIcon[theme];\n const containerColor =\n options.color ||\n (\n {\n success: \"container.border.success\",\n error: \"container.border.error\",\n info: \"container.border.info\",\n warning: \"container.border.warning\",\n } as const\n )[theme];\n const iconColor =\n options.color ||\n (\n {\n success: \"icon.success\",\n error: \"icon.error\",\n info: \"icon.info\",\n warning: \"icon.warning\",\n } as const\n )[theme];\n\n return (\n // TODO: if this closes when clicked, there should be a label saying \"Click to close\" that can be overridden\n <ToastContentContainer\n icon={<Icon name={iconName} color={iconColor} />}\n close={<Icon name=\"x-outline\" color=\"icon.base\" aria-hidden />}\n highlightColor={containerColor}\n >\n {renderedContent}\n </ToastContentContainer>\n );\n };\n\n const toastOptions = {\n autoClose,\n closeOnClick,\n onClose,\n toastId: toastId || undefined,\n transition,\n position,\n ...rest,\n icon: undefined,\n color: undefined,\n } as const;\n\n if (toastId && toastIsActive(toastId)) {\n toastifyToast.update<TData>(toastId, {\n ...toastOptions,\n render: renderToast,\n });\n } else {\n toastId = toastifyToast<TData>(renderToast, toastOptions);\n }\n\n return toastId;\n}\n\nexport default ToastContainer;\n\nexport const ToastContentContainer = ({\n children,\n icon,\n close,\n highlightColor,\n}: PropsWithChildren<{\n /**\n * A ReactNode in the icon slot\n */\n icon: ReactNode;\n /**\n * A ReactNode in the close button slot\n */\n close: ReactNode;\n highlightColor?: ComponentProps<typeof Box>[\"bg\"];\n}>) => {\n return (\n <Container data-qa-toast=\"\">\n {highlightColor ? (\n <ToastHighlight bg={highlightColor} aria-hidden />\n ) : null}\n\n <Box css=\"line-height: 1;\">{icon}</Box>\n\n <Box flex={1}>\n <Text as=\"div\" color=\"text.body\" data-qa-toast-content=\"\">\n {children}\n </Text>\n </Box>\n\n <Box css=\"line-height: 1;\">{close}</Box>\n </Container>\n );\n};\n\nexport const ToastHighlight = styled(Box)<ComponentProps<typeof Box>>`\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 2px;\n`;\n","import styled from \"styled-components\";\nimport type { ComponentProps } from \"react\";\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport \"react-toastify/dist/ReactToastify.css\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { ToastContainer } from \"react-toastify\";\n\nexport const TOAST_Z_INDEX = 9999;\n\nexport const Container = styled(Box)<ComponentProps<typeof Box>>`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[350]};\n font-family: ${({ theme }) => theme.fontFamily};\n ${({ theme }) => theme.typography[200]}\n position: relative;\n padding: ${({ theme }) => theme.space[350]};\n`;\n\nexport const ToastRoot = styled(ToastContainer).attrs({\n toastClassName: \"Toastify-toast-overrides\",\n hideProgressBar: true,\n closeButton: false,\n icon: false,\n position: \"bottom-right\",\n})`\n --toastify-z-index: ${TOAST_Z_INDEX};\n --toastify-toast-offset: ${({ theme }) => theme.space[400]};\n --toastify-toast-width: 360px;\n --toastify-toast-min-height: 48px;\n --toastify-toast-max-height: 70vh;\n --toastify-toast-bd-radius: ${({ theme }) => theme.radii[400]};\n --toastify-toast-background: ${({ theme }) =>\n theme.colors.container.background.base};\n /* there's margin-bottom on the last toast so we can remove this */\n --toastify-toast-bottom: 0;\n\n padding: 0;\n\n .Toastify-toast-overrides {\n background: ${({ theme }) => theme.colors.container.background.base};\n color: ${({ theme }) => theme.colors.text.body};\n box-shadow: ${({ theme }) => theme.shadows.low};\n padding: 0;\n margin-bottom: var(--toastify-toast-offset);\n }\n\n .Toastify__toast-body {\n padding: 0;\n margin: 0;\n }\n\n /* Override React Toastify's mobile width styles */\n @media only screen and (max-width: 480px) {\n .Toastify-container-overrides {\n min-width: initial !important;\n }\n }\n\n /* Zoom animation */\n @keyframes SproutToast__zoom-in {\n from {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3);\n }\n 50% {\n opacity: 1;\n }\n }\n @keyframes SproutToast__zoom-out {\n from {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3) translate3d(0, var(--y), 0);\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__zoom-in {\n animation: SproutToast__zoom-in ${({ theme }) => theme.duration.medium}\n ${({ theme }) => theme.easing.ease_out} both;\n }\n .SproutToast__zoom-out {\n animation: SproutToast__zoom-out ${({ theme }) => theme.duration.slow}\n ${({ theme }) => theme.easing.ease_in} both;\n }\n\n /* No animation (it's still necessary to define classes for no animation to work properly) */\n @keyframes SproutToast__none-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n @keyframes SproutToast__none-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__none-in {\n animation: SproutToast__none-in 0s both;\n }\n .SproutToast__none-out {\n animation: SproutToast__none-out 0s both;\n }\n`;\n","import type { ComponentProps } from \"react\";\nimport { type Icon, type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport type { ToastContent, ToastOptions } from \"react-toastify\";\n\nexport type TypeToastTheme = \"info\" | \"success\" | \"warning\" | \"error\";\n\ninterface BaseToastOptions<TData>\n extends Omit<ToastOptions<TData>, \"closeButton\" | \"icon\" | \"type\"> {\n theme?: TypeToastTheme | \"custom\";\n content: ToastContent<TData>;\n persist?: boolean;\n useTransition?: boolean;\n}\n\ninterface ThemedToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * One of `info`, `success`, `warning`, or `error`.\n */\n theme?: TypeToastTheme;\n /**\n * @deprecated Use `custom` theme instead.\n */\n color?: ComponentProps<typeof Icon>[\"color\"];\n /**\n * @deprecated Use `custom` theme instead.\n */\n icon?: TypeIconName;\n}\ninterface CustomToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * If you need to break out of the supported styles you can use the `custom` theme. You can use `ToastContentContainer` with `Icon` and `ToastHighlight` to build your custom toast.\n */\n theme: \"custom\";\n}\n\nexport type TypeToastOptions<TData> =\n | ThemedToastOptions<TData>\n | CustomToastOptions<TData>;\n"],"mappings":"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","names":["ToastContainer","import_react_toastify","import_seeds_react_box","styled","Box","import_styled_components","toastifyToast","ToastContainer","Icon","Box","Text","styled","import_seeds_react_icon"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Toast.tsx","../src/styles.ts","../src/ToastTypes.ts"],"sourcesContent":["export * from \"./Toast\";\nexport * from \"./ToastTypes\";\nexport { TOAST_Z_INDEX } from \"./styles\";\n","import type { PropsWithChildren, ReactNode, ComponentProps } from \"react\";\nimport {\n toast as toastifyToast,\n cssTransition,\n type ToastContent,\n} from \"react-toastify\";\nimport { DismissableLayerBranch } from \"@radix-ui/react-dismissable-layer\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon, { type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Container, ToastRoot } from \"./styles\";\nimport type { TypeToastOptions, TypeToastTheme } from \"./ToastTypes\";\nimport styled from \"styled-components\";\n\nexport const toastDismiss: typeof toastifyToast.dismiss = (...input) =>\n // @ts-ignore Not sure what this type is supposed to be\n toastifyToast.dismiss(...input);\nexport const toastIsActive: typeof toastifyToast.isActive = (...input) =>\n toastifyToast.isActive(...input);\nexport const toastUpdate: typeof toastifyToast.update = (...input) =>\n toastifyToast.update(...input);\n\nconst NoTransition = cssTransition({\n enter: \"SproutToast__none-in\",\n exit: \"SproutToast__none-out\",\n});\nconst SproutZoomTransition = cssTransition({\n enter: \"SproutToast__zoom-in\",\n exit: \"SproutToast__zoom-out\",\n});\n\nexport const ToastContainer = (\n props: Partial<ComponentProps<typeof ToastRoot>>\n) => (\n <DismissableLayerBranch style={{ pointerEvents: \"auto\" }}>\n <ToastRoot {...props} />\n </DismissableLayerBranch>\n);\n\nconst themeIcon: Record<TypeToastTheme, TypeIconName> = {\n success: \"circle-check-outline\",\n info: \"circle-i-outline\",\n warning: \"triangle-exclamation-outline\",\n error: \"triangle-exclamation-outline\",\n} as const;\n\nexport function toast<TData = unknown>(\n options: TypeToastOptions<TData>\n): ReturnType<typeof toastifyToast> {\n const {\n closeOnClick = true,\n content,\n onClose,\n persist,\n toastId: inputToastId,\n useTransition = true,\n position = \"bottom-right\",\n autoClose = persist ? false : 6000,\n transition = useTransition ? SproutZoomTransition : NoTransition,\n ...rest\n } = options;\n\n let toastId = inputToastId;\n if (!toastId && typeof content === \"string\") {\n toastId = content;\n }\n\n const renderToast: ToastContent<TData> = (toastInput) => {\n const renderedContent =\n typeof content === \"function\" ? content(toastInput) : content;\n\n if (options.theme === \"custom\") {\n return renderedContent;\n }\n\n const theme = options.theme || \"info\";\n const iconName = options.icon || themeIcon[theme];\n const containerColor =\n options.color ||\n (\n {\n success: \"container.border.success\",\n error: \"container.border.error\",\n info: \"container.border.info\",\n warning: \"container.border.warning\",\n } as const\n )[theme];\n const iconColor =\n options.color ||\n (\n {\n success: \"icon.success\",\n error: \"icon.error\",\n info: \"icon.info\",\n warning: \"icon.warning\",\n } as const\n )[theme];\n\n return (\n // TODO: if this closes when clicked, there should be a label saying \"Click to close\" that can be overridden\n <ToastContentContainer\n icon={<Icon name={iconName} color={iconColor} />}\n close={<Icon name=\"x-outline\" color=\"icon.base\" aria-hidden />}\n highlightColor={containerColor}\n >\n {renderedContent}\n </ToastContentContainer>\n );\n };\n\n const toastOptions = {\n autoClose,\n closeOnClick,\n onClose,\n toastId: toastId || undefined,\n transition,\n position,\n ...rest,\n icon: undefined,\n color: undefined,\n } as const;\n\n if (toastId && toastIsActive(toastId)) {\n toastifyToast.update<TData>(toastId, {\n ...toastOptions,\n render: renderToast,\n });\n } else {\n toastId = toastifyToast<TData>(renderToast, toastOptions);\n }\n\n return toastId;\n}\n\nexport default ToastContainer;\n\nexport const ToastContentContainer = ({\n children,\n icon,\n close,\n highlightColor,\n}: PropsWithChildren<{\n /**\n * A ReactNode in the icon slot\n */\n icon: ReactNode;\n /**\n * A ReactNode in the close button slot\n */\n close: ReactNode;\n highlightColor?: ComponentProps<typeof Box>[\"bg\"];\n}>) => {\n return (\n <Container data-qa-toast=\"\">\n {highlightColor ? (\n <ToastHighlight bg={highlightColor} aria-hidden />\n ) : null}\n\n <Box css=\"line-height: 1;\">{icon}</Box>\n\n <Box flex={1}>\n <Text as=\"div\" color=\"text.body\" data-qa-toast-content=\"\">\n {children}\n </Text>\n </Box>\n\n <Box css=\"line-height: 1;\">{close}</Box>\n </Container>\n );\n};\n\nexport const ToastHighlight = styled(Box)<ComponentProps<typeof Box>>`\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 2px;\n`;\n","import styled from \"styled-components\";\nimport type { ComponentProps } from \"react\";\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport \"react-toastify/dist/ReactToastify.css\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { ToastContainer } from \"react-toastify\";\n\nexport const TOAST_Z_INDEX = 9999;\n\nexport const Container = styled(Box)<ComponentProps<typeof Box>>`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[350]};\n font-family: ${({ theme }) => theme.fontFamily};\n ${({ theme }) => theme.typography[200]}\n position: relative;\n padding: ${({ theme }) => theme.space[350]};\n`;\n\nexport const ToastRoot = styled(ToastContainer).attrs({\n toastClassName: \"Toastify-toast-overrides\",\n hideProgressBar: true,\n closeButton: false,\n icon: false,\n position: \"bottom-right\",\n})`\n --toastify-z-index: ${TOAST_Z_INDEX};\n --toastify-toast-offset: ${({ theme }) => theme.space[400]};\n --toastify-toast-width: 360px;\n --toastify-toast-min-height: 48px;\n --toastify-toast-max-height: 70vh;\n --toastify-toast-bd-radius: ${({ theme }) => theme.radii[400]};\n --toastify-toast-background: ${({ theme }) =>\n theme.colors.container.background.base};\n /* there's margin-bottom on the last toast so we can remove this */\n --toastify-toast-bottom: 0;\n\n padding: 0;\n\n .Toastify-toast-overrides {\n background: ${({ theme }) => theme.colors.container.background.base};\n color: ${({ theme }) => theme.colors.text.body};\n box-shadow: ${({ theme }) => theme.shadows.low};\n padding: 0;\n margin-bottom: var(--toastify-toast-offset);\n }\n\n .Toastify__toast-body {\n padding: 0;\n margin: 0;\n }\n\n /* Override React Toastify's mobile width styles */\n @media only screen and (max-width: 480px) {\n .Toastify-container-overrides {\n min-width: initial !important;\n }\n }\n\n /* Zoom animation */\n @keyframes SproutToast__zoom-in {\n from {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3);\n }\n 50% {\n opacity: 1;\n }\n }\n @keyframes SproutToast__zoom-out {\n from {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n transform: scale3d(0.3, 0.3, 0.3) translate3d(0, var(--y), 0);\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__zoom-in {\n animation: SproutToast__zoom-in ${({ theme }) => theme.duration.medium}\n ${({ theme }) => theme.easing.ease_out} both;\n }\n .SproutToast__zoom-out {\n animation: SproutToast__zoom-out ${({ theme }) => theme.duration.slow}\n ${({ theme }) => theme.easing.ease_in} both;\n }\n\n /* No animation (it's still necessary to define classes for no animation to work properly) */\n @keyframes SproutToast__none-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n @keyframes SproutToast__none-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n .SproutToast__none-in {\n animation: SproutToast__none-in 0s both;\n }\n .SproutToast__none-out {\n animation: SproutToast__none-out 0s both;\n }\n`;\n","import type { ComponentProps } from \"react\";\nimport { type Icon, type TypeIconName } from \"@sproutsocial/seeds-react-icon\";\nimport type { ToastContent, ToastOptions } from \"react-toastify\";\n\nexport type TypeToastTheme = \"info\" | \"success\" | \"warning\" | \"error\";\n\ninterface BaseToastOptions<TData>\n extends Omit<ToastOptions<TData>, \"closeButton\" | \"icon\" | \"type\"> {\n theme?: TypeToastTheme | \"custom\";\n content: ToastContent<TData>;\n persist?: boolean;\n useTransition?: boolean;\n}\n\ninterface ThemedToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * One of `info`, `success`, `warning`, or `error`.\n */\n theme?: TypeToastTheme;\n /**\n * @deprecated Use `custom` theme instead.\n */\n color?: ComponentProps<typeof Icon>[\"color\"];\n /**\n * @deprecated Use `custom` theme instead.\n */\n icon?: TypeIconName;\n}\ninterface CustomToastOptions<TData> extends BaseToastOptions<TData> {\n /**\n * If you need to break out of the supported styles you can use the `custom` theme. You can use `ToastContentContainer` with `Icon` and `ToastHighlight` to build your custom toast.\n */\n theme: \"custom\";\n}\n\nexport type TypeToastOptions<TData> =\n | ThemedToastOptions<TData>\n | CustomToastOptions<TData>;\n"],"mappings":"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","names":["ToastContainer","import_react_toastify","import_seeds_react_box","styled","Box","import_styled_components","toastifyToast","ToastContainer","Icon","Box","Text","styled","import_seeds_react_icon"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-toast",
3
- "version": "1.0.20",
3
+ "version": "1.0.24",
4
4
  "description": "Seeds React Toast",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -16,10 +16,11 @@
16
16
  "typecheck": "tsc --noEmit"
17
17
  },
18
18
  "dependencies": {
19
- "@sproutsocial/seeds-react-theme": "^3.5.0",
19
+ "@radix-ui/react-dismissable-layer": "^1.1.11",
20
+ "@sproutsocial/seeds-react-theme": "^3.6.0",
20
21
  "@sproutsocial/seeds-react-system-props": "^3.0.1",
21
- "@sproutsocial/seeds-react-icon": "^2.2.2",
22
- "@sproutsocial/seeds-react-box": "^1.1.12",
22
+ "@sproutsocial/seeds-react-icon": "^2.2.5",
23
+ "@sproutsocial/seeds-react-box": "^1.1.14",
23
24
  "@sproutsocial/seeds-react-text": "^1.4.0"
24
25
  },
25
26
  "devDependencies": {
@@ -12,6 +12,13 @@ import Link from "@sproutsocial/seeds-react-link";
12
12
  import Radio from "@sproutsocial/seeds-react-radio";
13
13
  import Switch from "@sproutsocial/seeds-react-switch";
14
14
  import Text from "@sproutsocial/seeds-react-text";
15
+ import {
16
+ Modal,
17
+ ModalBody,
18
+ ModalCustomFooter,
19
+ ModalFooter,
20
+ ModalHeader,
21
+ } from "@sproutsocial/seeds-react-modal/v2";
15
22
  import {
16
23
  toast,
17
24
  toastDismiss,
@@ -298,3 +305,54 @@ export const WithLink: Story = {
298
305
  );
299
306
  },
300
307
  };
308
+
309
+ export const WithModalV2: Story = {
310
+ render: () => {
311
+ const triggerToast = () =>
312
+ toast({
313
+ persist: true,
314
+ content: (
315
+ <Box
316
+ display="inline-flex"
317
+ width="100%"
318
+ justifyContent="space-between"
319
+ alignItems="flex-start"
320
+ >
321
+ <Text>Message completed</Text>
322
+ <Link
323
+ onClick={() => alert("Clicked!")}
324
+ ml={300}
325
+ fontSize={200}
326
+ p={0}
327
+ >
328
+ Undo
329
+ </Link>
330
+ </Box>
331
+ ),
332
+ });
333
+
334
+ return (
335
+ <Box>
336
+ <ToastContainer />
337
+
338
+ <Modal
339
+ modalTrigger={<Button appearance="secondary">Open Modal</Button>}
340
+ closeButtonAriaLabel="Close Modal"
341
+ >
342
+ <ModalHeader title="Testing Toasts + Modal v2" />
343
+ <ModalBody>
344
+ <Text as="p" mb={400}>
345
+ Click the button below to fire a toast while the modal is open.
346
+ The toast should be clickable and dismissable.
347
+ </Text>
348
+ </ModalBody>
349
+ <ModalCustomFooter>
350
+ <Button appearance="secondary" onClick={triggerToast}>
351
+ Fire toast
352
+ </Button>
353
+ </ModalCustomFooter>
354
+ </Modal>
355
+ </Box>
356
+ );
357
+ },
358
+ };
package/src/Toast.tsx CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  cssTransition,
5
5
  type ToastContent,
6
6
  } from "react-toastify";
7
+ import { DismissableLayerBranch } from "@radix-ui/react-dismissable-layer";
7
8
  import Box from "@sproutsocial/seeds-react-box";
8
9
  import Icon, { type TypeIconName } from "@sproutsocial/seeds-react-icon";
9
10
  import Text from "@sproutsocial/seeds-react-text";
@@ -30,7 +31,11 @@ const SproutZoomTransition = cssTransition({
30
31
 
31
32
  export const ToastContainer = (
32
33
  props: Partial<ComponentProps<typeof ToastRoot>>
33
- ) => <ToastRoot {...props} />;
34
+ ) => (
35
+ <DismissableLayerBranch style={{ pointerEvents: "auto" }}>
36
+ <ToastRoot {...props} />
37
+ </DismissableLayerBranch>
38
+ );
34
39
 
35
40
  const themeIcon: Record<TypeToastTheme, TypeIconName> = {
36
41
  success: "circle-check-outline",
@@ -0,0 +1,171 @@
1
+ /* eslint-disable */
2
+ import React from "react";
3
+ import {
4
+ render,
5
+ screen,
6
+ waitFor,
7
+ cleanup,
8
+ fireEvent,
9
+ } from "@sproutsocial/seeds-react-testing-library";
10
+ import userEvent from "@testing-library/user-event";
11
+ import { toast, ToastContainer, toastDismiss } from "../Toast";
12
+
13
+ // Mock matchMedia
14
+ beforeAll(() => {
15
+ Object.defineProperty(window, "matchMedia", {
16
+ writable: true,
17
+ value: jest.fn().mockImplementation((query) => ({
18
+ matches: false,
19
+ media: query,
20
+ onchange: null,
21
+ addListener: jest.fn(),
22
+ removeListener: jest.fn(),
23
+ addEventListener: jest.fn(),
24
+ removeEventListener: jest.fn(),
25
+ dispatchEvent: jest.fn(),
26
+ })),
27
+ });
28
+ });
29
+
30
+ afterEach(() => {
31
+ toastDismiss();
32
+ cleanup();
33
+ document.body.style.pointerEvents = "";
34
+ });
35
+
36
+ describe("Toast", () => {
37
+ describe("DismissableLayerBranch wrapper", () => {
38
+ it("should render inside a DismissableLayerBranch with pointer-events: auto", () => {
39
+ const { container } = render(<ToastContainer />);
40
+ const wrapper = container.firstElementChild as HTMLElement;
41
+ expect(wrapper.style.pointerEvents).toBe("auto");
42
+ });
43
+
44
+ it("should render the ToastRoot as a child of the branch wrapper", () => {
45
+ const { container } = render(<ToastContainer />);
46
+ const wrapper = container.firstElementChild as HTMLElement;
47
+ // The branch div should contain the Toastify container
48
+ const toastifyContainer = wrapper.querySelector(".Toastify");
49
+ expect(toastifyContainer).toBeInTheDocument();
50
+ });
51
+ });
52
+
53
+ describe("clickability when Modal V2 is open", () => {
54
+ it("should be clickable when document.body has pointer-events: none", async () => {
55
+ const user = userEvent.setup();
56
+ const handleClick = jest.fn();
57
+
58
+ render(
59
+ <>
60
+ <ToastContainer />
61
+ <button
62
+ onClick={() =>
63
+ toast({
64
+ persist: true,
65
+ content: (
66
+ <button data-testid="toast-action" onClick={handleClick}>
67
+ Click me
68
+ </button>
69
+ ),
70
+ })
71
+ }
72
+ >
73
+ Trigger
74
+ </button>
75
+ </>
76
+ );
77
+
78
+ await user.click(screen.getByText("Trigger"));
79
+
80
+ await waitFor(() => {
81
+ expect(screen.getByTestId("toast-action")).toBeInTheDocument();
82
+ });
83
+
84
+ // Simulate what Radix Dialog does when a modal opens
85
+ document.body.style.pointerEvents = "none";
86
+
87
+ await user.click(screen.getByTestId("toast-action"));
88
+ expect(handleClick).toHaveBeenCalledTimes(1);
89
+ });
90
+
91
+ it("should allow interacting with links inside a toast when body pointer-events are disabled", async () => {
92
+ const user = userEvent.setup();
93
+ const handleClick = jest.fn();
94
+
95
+ render(
96
+ <>
97
+ <ToastContainer />
98
+ <button
99
+ onClick={() =>
100
+ toast({
101
+ persist: true,
102
+ content: (
103
+ <a
104
+ data-testid="toast-link"
105
+ href="#"
106
+ onClick={(e) => {
107
+ e.preventDefault();
108
+ handleClick();
109
+ }}
110
+ >
111
+ Undo
112
+ </a>
113
+ ),
114
+ })
115
+ }
116
+ >
117
+ Trigger
118
+ </button>
119
+ </>
120
+ );
121
+
122
+ await user.click(screen.getByText("Trigger"));
123
+
124
+ await waitFor(() => {
125
+ expect(screen.getByTestId("toast-link")).toBeInTheDocument();
126
+ });
127
+
128
+ document.body.style.pointerEvents = "none";
129
+
130
+ await user.click(screen.getByTestId("toast-link"));
131
+ expect(handleClick).toHaveBeenCalledTimes(1);
132
+ });
133
+ });
134
+
135
+ describe("normal behavior without Modal V2", () => {
136
+ it("should be clickable when body has default pointer-events", async () => {
137
+ const user = userEvent.setup();
138
+ const handleClick = jest.fn();
139
+
140
+ render(
141
+ <>
142
+ <ToastContainer />
143
+ <button
144
+ onClick={() =>
145
+ toast({
146
+ persist: true,
147
+ content: (
148
+ <button data-testid="toast-action" onClick={handleClick}>
149
+ Click me
150
+ </button>
151
+ ),
152
+ })
153
+ }
154
+ >
155
+ Trigger
156
+ </button>
157
+ </>
158
+ );
159
+
160
+ await user.click(screen.getByText("Trigger"));
161
+
162
+ await waitFor(() => {
163
+ expect(screen.getByTestId("toast-action")).toBeInTheDocument();
164
+ });
165
+
166
+ // No pointer-events: none on body — normal usage
167
+ await user.click(screen.getByTestId("toast-action"));
168
+ expect(handleClick).toHaveBeenCalledTimes(1);
169
+ });
170
+ });
171
+ });