@fairmint/ui 0.3.16 → 0.3.18

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 (33) hide show
  1. package/dist/components/generic/Banner/Banner.cjs +11 -10
  2. package/dist/components/generic/Banner/Banner.cjs.map +1 -1
  3. package/dist/components/generic/Banner/Banner.d.ts +1 -1
  4. package/dist/components/generic/Banner/Banner.d.ts.map +1 -1
  5. package/dist/components/generic/Banner/Banner.js +11 -10
  6. package/dist/components/generic/Banner/Banner.js.map +1 -1
  7. package/dist/components/primitives/Alert/Alert.cjs +198 -57
  8. package/dist/components/primitives/Alert/Alert.cjs.map +1 -1
  9. package/dist/components/primitives/Alert/Alert.d.ts +19 -3
  10. package/dist/components/primitives/Alert/Alert.d.ts.map +1 -1
  11. package/dist/components/primitives/Alert/Alert.js +199 -58
  12. package/dist/components/primitives/Alert/Alert.js.map +1 -1
  13. package/dist/components/primitives/index.d.ts +1 -1
  14. package/dist/components/primitives/index.d.ts.map +1 -1
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/notify.cjs +84 -4
  18. package/dist/notify.cjs.map +1 -1
  19. package/dist/notify.d.ts +44 -7
  20. package/dist/notify.d.ts.map +1 -1
  21. package/dist/notify.js +84 -4
  22. package/dist/notify.js.map +1 -1
  23. package/dist/snackbarCompat.cjs +78 -21
  24. package/dist/snackbarCompat.cjs.map +1 -1
  25. package/dist/snackbarCompat.d.ts.map +1 -1
  26. package/dist/snackbarCompat.js +78 -21
  27. package/dist/snackbarCompat.js.map +1 -1
  28. package/dist/theme/index.cjs +76 -0
  29. package/dist/theme/index.cjs.map +1 -1
  30. package/dist/theme/index.d.ts.map +1 -1
  31. package/dist/theme/index.js +76 -0
  32. package/dist/theme/index.js.map +1 -1
  33. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../src/notify.ts"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM;6CAC+B,aAAa;2CAGf,aAAa;6CAGX,aAAa;0CAGhB,aAAa;CAE3D,CAAC"}
1
+ {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../src/notify.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGhE,KAAK,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3B,yEAAyE;IACzE,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,oBAAoB;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4CAA4C;IAC5C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AA+DD,0EAA0E;AAC1E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,aAAa,EACtB,EACE,KAAK,EACL,OAAO,EACP,SAAsC,EACtC,IAAI,EACJ,MAAM,EACN,eAAsB,EACtB,EAAE,EACF,OAAO,GACR,EAAE,aAAa;;;;;;;;;;EAajB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,MAAM;uBACE,aAAa;qBAGf,aAAa;uBAEX,aAAa;oBAGhB,aAAa;IAE7B;;;OAGG;sCACwC,mBAAmB;CAE/D,CAAC"}
package/dist/notify.js CHANGED
@@ -1,12 +1,92 @@
1
+ import { createElement, Fragment } from "react";
1
2
  import { colors } from "./theme/colors.js";
2
3
  import { notifications } from "./node_modules/@mantine/notifications/esm/notifications.store.js";
4
+ const autoCloseDefaults = {
5
+ success: 4e3,
6
+ error: 6e3,
7
+ warning: 5e3,
8
+ info: 4e3
9
+ };
10
+ const iconPaths = {
11
+ success: ["m9 12 2 2 4-4", "M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0Z"],
12
+ error: ["m15 9-6 6", "m9 9 6 6", "M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0Z"],
13
+ warning: [
14
+ "M12 9v4",
15
+ "M12 17h.01",
16
+ "M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z"
17
+ ],
18
+ info: ["M12 16v-4", "M12 8h.01", "M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0Z"]
19
+ };
20
+ function createNotifyIcon(variant) {
21
+ return createElement(
22
+ "svg",
23
+ {
24
+ "aria-hidden": true,
25
+ "data-fairmint-notify-icon": variant,
26
+ fill: "none",
27
+ focusable: "false",
28
+ height: 20,
29
+ stroke: "currentColor",
30
+ strokeLinecap: "round",
31
+ strokeLinejoin: "round",
32
+ strokeWidth: 1.75,
33
+ viewBox: "0 0 24 24",
34
+ width: 20,
35
+ xmlns: "http://www.w3.org/2000/svg"
36
+ },
37
+ ...iconPaths[variant].map((d) => createElement("path", { d, key: d }))
38
+ );
39
+ }
40
+ function resolveIcon(variant, icon, loading) {
41
+ if (loading) return void 0;
42
+ if (icon === null) return void 0;
43
+ if (icon !== void 0) return icon;
44
+ return createNotifyIcon(variant);
45
+ }
46
+ function resolveMessage(message, action) {
47
+ if (action === void 0) return message;
48
+ return createElement(
49
+ Fragment,
50
+ null,
51
+ message,
52
+ createElement("div", { "data-fairmint-notify-action": true, style: { marginTop: 8 } }, action)
53
+ );
54
+ }
55
+ function buildNotifyNotification(variant, {
56
+ title,
57
+ message,
58
+ autoClose = autoCloseDefaults[variant],
59
+ icon,
60
+ action,
61
+ withCloseButton = true,
62
+ id,
63
+ loading
64
+ }) {
65
+ return {
66
+ id,
67
+ title,
68
+ message: resolveMessage(message, action),
69
+ color: colors[variant],
70
+ autoClose,
71
+ withBorder: true,
72
+ withCloseButton,
73
+ loading,
74
+ icon: resolveIcon(variant, icon, loading)
75
+ };
76
+ }
3
77
  const notify = {
4
- success: ({ title, message, autoClose = 4e3 }) => notifications.show({ title, message, color: colors.success, autoClose }),
5
- error: ({ title, message, autoClose = 6e3 }) => notifications.show({ title, message, color: colors.error, autoClose }),
6
- warning: ({ title, message, autoClose = 5e3 }) => notifications.show({ title, message, color: colors.warning, autoClose }),
7
- info: ({ title, message, autoClose = 4e3 }) => notifications.show({ title, message, color: colors.info, autoClose })
78
+ success: (options) => notifications.show(buildNotifyNotification("success", options)),
79
+ error: (options) => notifications.show(buildNotifyNotification("error", options)),
80
+ warning: (options) => notifications.show(buildNotifyNotification("warning", options)),
81
+ info: (options) => notifications.show(buildNotifyNotification("info", options)),
82
+ /**
83
+ * Update an existing toast by `id` (e.g. loading → success).
84
+ * Applies the same visual defaults as `notify.*` show helpers.
85
+ */
86
+ update: ({ variant = "info", ...options }) => notifications.update(buildNotifyNotification(variant, options))
8
87
  };
9
88
  export {
89
+ buildNotifyNotification,
10
90
  notify
11
91
  };
12
92
  //# sourceMappingURL=notify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notify.js","sources":["../src/notify.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport { colors } from \"./theme/colors\";\n\ninterface NotifyOptions {\n title?: string;\n message: string;\n autoClose?: number | false;\n}\n\n/**\n * Fairmint notification helpers.\n *\n * Uses Mantine's notifications system with Fairmint semantic colors.\n * Requires FairmintProvider to be mounted in the component tree.\n *\n * @example\n * notify.success({ message: \"Investment saved.\" });\n * notify.error({ title: \"Error\", message: \"Failed to load data.\" });\n */\nexport const notify = {\n success: ({ title, message, autoClose = 4000 }: NotifyOptions) =>\n notifications.show({ title, message, color: colors.success, autoClose }),\n\n error: ({ title, message, autoClose = 6000 }: NotifyOptions) =>\n notifications.show({ title, message, color: colors.error, autoClose }),\n\n warning: ({ title, message, autoClose = 5000 }: NotifyOptions) =>\n notifications.show({ title, message, color: colors.warning, autoClose }),\n\n info: ({ title, message, autoClose = 4000 }: NotifyOptions) =>\n notifications.show({ title, message, color: colors.info, autoClose }),\n};\n"],"names":[],"mappings":";;AAmBO,MAAM,SAAS;AAAA,EACpB,SAAS,CAAC,EAAE,OAAO,SAAS,YAAY,IAAA,MACtC,cAAc,KAAK,EAAE,OAAO,SAAS,OAAO,OAAO,SAAS,WAAW;AAAA,EAEzE,OAAO,CAAC,EAAE,OAAO,SAAS,YAAY,IAAA,MACpC,cAAc,KAAK,EAAE,OAAO,SAAS,OAAO,OAAO,OAAO,WAAW;AAAA,EAEvE,SAAS,CAAC,EAAE,OAAO,SAAS,YAAY,IAAA,MACtC,cAAc,KAAK,EAAE,OAAO,SAAS,OAAO,OAAO,SAAS,WAAW;AAAA,EAEzE,MAAM,CAAC,EAAE,OAAO,SAAS,YAAY,IAAA,MACnC,cAAc,KAAK,EAAE,OAAO,SAAS,OAAO,OAAO,MAAM,WAAW;AACxE;"}
1
+ {"version":3,"file":"notify.js","sources":["../src/notify.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\nimport { colors } from \"./theme/colors\";\n\ntype NotifyVariant = \"success\" | \"error\" | \"warning\" | \"info\";\n\nexport interface NotifyOptions {\n title?: string;\n message: string;\n autoClose?: number | false;\n /** Override the default semantic icon, or pass `null` to suppress it. */\n icon?: ReactNode | null;\n /** Optional action content rendered below the message (e.g. a Button). */\n action?: ReactNode;\n /** @default true */\n withCloseButton?: boolean;\n /** Stable id for dismiss / update flows. */\n id?: string;\n /** Shows a loading indicator in place of the icon. */\n loading?: boolean;\n}\n\nexport interface NotifyUpdateOptions extends NotifyOptions {\n id: string;\n /** Semantic tone for color + default icon. @default \"info\" */\n variant?: NotifyVariant;\n}\n\nconst autoCloseDefaults: Record<NotifyVariant, number> = {\n success: 4000,\n error: 6000,\n warning: 5000,\n info: 4000,\n};\n\n/** Outlined stroke paths only — no filled shapes. Semantic color comes from currentColor. */\nconst iconPaths: Record<NotifyVariant, string[]> = {\n success: [\"m9 12 2 2 4-4\", \"M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0Z\"],\n error: [\"m15 9-6 6\", \"m9 9 6 6\", \"M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0Z\"],\n warning: [\n \"M12 9v4\",\n \"M12 17h.01\",\n \"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z\",\n ],\n info: [\"M12 16v-4\", \"M12 8h.01\", \"M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0Z\"],\n};\n\nfunction createNotifyIcon(variant: NotifyVariant): ReactNode {\n return createElement(\n \"svg\",\n {\n \"aria-hidden\": true,\n \"data-fairmint-notify-icon\": variant,\n fill: \"none\",\n focusable: \"false\",\n height: 20,\n stroke: \"currentColor\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n strokeWidth: 1.75,\n viewBox: \"0 0 24 24\",\n width: 20,\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n ...iconPaths[variant].map((d) => createElement(\"path\", { d, key: d })),\n );\n}\n\nfunction resolveIcon(\n variant: NotifyVariant,\n icon: ReactNode | null | undefined,\n loading: boolean | undefined,\n): ReactNode | undefined {\n if (loading) return undefined;\n if (icon === null) return undefined;\n if (icon !== undefined) return icon;\n return createNotifyIcon(variant);\n}\n\nfunction resolveMessage(message: string, action: ReactNode | undefined): ReactNode {\n if (action === undefined) return message;\n return createElement(\n Fragment,\n null,\n message,\n createElement(\"div\", { \"data-fairmint-notify-action\": true, style: { marginTop: 8 } }, action),\n );\n}\n\n/** Shared Notify presentation used by `notify.*` and `snackbarCompat`. */\nexport function buildNotifyNotification(\n variant: NotifyVariant,\n {\n title,\n message,\n autoClose = autoCloseDefaults[variant],\n icon,\n action,\n withCloseButton = true,\n id,\n loading,\n }: NotifyOptions,\n) {\n return {\n id,\n title,\n message: resolveMessage(message, action),\n color: colors[variant],\n autoClose,\n withBorder: true,\n withCloseButton,\n loading,\n icon: resolveIcon(variant, icon, loading),\n };\n}\n\n/**\n * Fairmint notification helpers.\n *\n * Uses Mantine's notifications system with Fairmint semantic colors, outlined\n * semantic icons (no filled circles), and a 1px border. Subtle single-layer\n * elevation (`--fairmint-elevation-subtle`), tinted semantic surfaces\n * (`*-bg` / light /50), and outlined icon chrome come from the Fairmint theme\n * `Notification` defaults. Requires FairmintProvider.\n *\n * @example\n * notify.success({ message: \"Investment saved.\" });\n * notify.error({ title: \"Error\", message: \"Failed to load data.\" });\n */\nexport const notify = {\n success: (options: NotifyOptions) =>\n notifications.show(buildNotifyNotification(\"success\", options)),\n\n error: (options: NotifyOptions) => notifications.show(buildNotifyNotification(\"error\", options)),\n\n warning: (options: NotifyOptions) =>\n notifications.show(buildNotifyNotification(\"warning\", options)),\n\n info: (options: NotifyOptions) => notifications.show(buildNotifyNotification(\"info\", options)),\n\n /**\n * Update an existing toast by `id` (e.g. loading → success).\n * Applies the same visual defaults as `notify.*` show helpers.\n */\n update: ({ variant = \"info\", ...options }: NotifyUpdateOptions) =>\n notifications.update(buildNotifyNotification(variant, options)),\n};\n"],"names":[],"mappings":";;;AA4BA,MAAM,oBAAmD;AAAA,EACvD,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AACR;AAGA,MAAM,YAA6C;AAAA,EACjD,SAAS,CAAC,iBAAiB,2CAA2C;AAAA,EACtE,OAAO,CAAC,aAAa,YAAY,2CAA2C;AAAA,EAC5E,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF,MAAM,CAAC,aAAa,aAAa,2CAA2C;AAC9E;AAEA,SAAS,iBAAiB,SAAmC;AAC3D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,eAAe;AAAA,MACf,6BAA6B;AAAA,MAC7B,MAAM;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,SAAS;AAAA,MACT,OAAO;AAAA,MACP,OAAO;AAAA,IAAA;AAAA,IAET,GAAG,UAAU,OAAO,EAAE,IAAI,CAAC,MAAM,cAAc,QAAQ,EAAE,GAAG,KAAK,EAAA,CAAG,CAAC;AAAA,EAAA;AAEzE;AAEA,SAAS,YACP,SACA,MACA,SACuB;AACvB,MAAI,QAAS,QAAO;AACpB,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,SAAS,OAAW,QAAO;AAC/B,SAAO,iBAAiB,OAAO;AACjC;AAEA,SAAS,eAAe,SAAiB,QAA0C;AACjF,MAAI,WAAW,OAAW,QAAO;AACjC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,OAAO,EAAE,+BAA+B,MAAM,OAAO,EAAE,WAAW,EAAA,EAAE,GAAK,MAAM;AAAA,EAAA;AAEjG;AAGO,SAAS,wBACd,SACA;AAAA,EACE;AAAA,EACA;AAAA,EACA,YAAY,kBAAkB,OAAO;AAAA,EACrC;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA;AACF,GACA;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS,eAAe,SAAS,MAAM;AAAA,IACvC,OAAO,OAAO,OAAO;AAAA,IACrB;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,MAAM,YAAY,SAAS,MAAM,OAAO;AAAA,EAAA;AAE5C;AAeO,MAAM,SAAS;AAAA,EACpB,SAAS,CAAC,YACR,cAAc,KAAK,wBAAwB,WAAW,OAAO,CAAC;AAAA,EAEhE,OAAO,CAAC,YAA2B,cAAc,KAAK,wBAAwB,SAAS,OAAO,CAAC;AAAA,EAE/F,SAAS,CAAC,YACR,cAAc,KAAK,wBAAwB,WAAW,OAAO,CAAC;AAAA,EAEhE,MAAM,CAAC,YAA2B,cAAc,KAAK,wBAAwB,QAAQ,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAM7F,QAAQ,CAAC,EAAE,UAAU,QAAQ,GAAG,cAC9B,cAAc,OAAO,wBAAwB,SAAS,OAAO,CAAC;AAClE;"}
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const React = require("react");
4
- const colors = require("./theme/colors.cjs");
4
+ const notify = require("./notify.cjs");
5
5
  const notifications_store = require("./node_modules/@mantine/notifications/esm/notifications.store.cjs");
6
- const variantColorMap = {
7
- default: void 0,
8
- error: colors.colors.error,
9
- info: colors.colors.info,
10
- success: colors.colors.success,
11
- warning: colors.colors.warning
6
+ const semanticNotifyMethods = {
7
+ error: notify.notify.error,
8
+ info: notify.notify.info,
9
+ success: notify.notify.success,
10
+ warning: notify.notify.warning
12
11
  };
12
+ const isSemanticVariant = (variant) => variant !== "default";
13
13
  const resolveAutoClose = (options) => {
14
14
  if (options.persist || options.autoHideDuration === null) return false;
15
15
  return options.autoHideDuration;
@@ -20,6 +20,23 @@ const resolvePosition = (options) => {
20
20
  const horizontal = options.anchorOrigin?.horizontal;
21
21
  return `${vertical ?? "bottom"}-${horizontal ?? "left"}`;
22
22
  };
23
+ const resolveWithCloseButton = (options, action) => {
24
+ if (action !== void 0 && (options.persist || options.autoHideDuration === null)) {
25
+ return false;
26
+ }
27
+ return true;
28
+ };
29
+ const canRouteThroughNotify = (message, options) => {
30
+ if (!isSemanticVariant(options.variant ?? "default")) return false;
31
+ if (typeof message !== "string") return false;
32
+ if (options.title !== void 0 && typeof options.title !== "string") return false;
33
+ if (options.content !== void 0) return false;
34
+ if (options.style !== void 0) return false;
35
+ if (options.anchorOrigin !== void 0) return false;
36
+ if (options.onClose !== void 0) return false;
37
+ if (options.preventDuplicate) return false;
38
+ return true;
39
+ };
23
40
  let generatedSnackbarKey = 0;
24
41
  let generatedNodeDuplicateKey = 0;
25
42
  const activeDuplicateKeys = /* @__PURE__ */ new Set();
@@ -54,6 +71,13 @@ const clearDuplicateId = (id) => {
54
71
  const duplicateKey = duplicateKeysById.get(id);
55
72
  if (duplicateKey) clearDuplicateKey(duplicateKey);
56
73
  };
74
+ const trackDuplicate = (id, options, duplicateKey) => {
75
+ if (options.preventDuplicate) {
76
+ activeDuplicateKeys.add(duplicateKey);
77
+ duplicateKeysById.set(id, duplicateKey);
78
+ duplicateIdsByKey.set(duplicateKey, id);
79
+ }
80
+ };
57
81
  const enqueueSnackbar = (message, options = {}) => {
58
82
  const duplicateKey = createDuplicateKey(message, options);
59
83
  const needsStableKey = Boolean(options.action || options.content);
@@ -71,28 +95,61 @@ const enqueueSnackbar = (message, options = {}) => {
71
95
  const renderKey = explicitId ?? "";
72
96
  const action = typeof options.action === "function" ? options.action(renderKey) : options.action;
73
97
  const content = typeof options.content === "function" ? options.content(renderKey, message) : options.content;
98
+ const variant = options.variant ?? "default";
99
+ const autoClose = resolveAutoClose(options);
100
+ const withCloseButton = resolveWithCloseButton(options, action);
101
+ if (typeof message === "string" && canRouteThroughNotify(message, options) && isSemanticVariant(variant)) {
102
+ const notifyOptions = {
103
+ id: explicitId,
104
+ title: typeof options.title === "string" ? options.title : void 0,
105
+ message,
106
+ action,
107
+ withCloseButton,
108
+ ...autoClose === void 0 ? {} : { autoClose }
109
+ };
110
+ const id2 = semanticNotifyMethods[variant](notifyOptions);
111
+ trackDuplicate(id2, options, duplicateKey);
112
+ return id2;
113
+ }
74
114
  const renderedMessage = content ?? (action ? React.createElement(React.Fragment, null, message, action) : message);
115
+ const onClose = (notification) => {
116
+ const notificationId = String(notification?.id ?? explicitId ?? "");
117
+ const closeReason = notificationId && instructedCloseIds.has(notificationId) ? "instructed" : "timeout";
118
+ if (notificationId) instructedCloseIds.delete(notificationId);
119
+ if (options.preventDuplicate) clearDuplicateKey(duplicateKey);
120
+ options.onClose?.(void 0, closeReason, notification?.id ?? explicitId);
121
+ };
122
+ if (isSemanticVariant(variant)) {
123
+ const presentation = notify.buildNotifyNotification(variant, {
124
+ id: explicitId,
125
+ title: typeof options.title === "string" ? options.title : void 0,
126
+ // Message/action are composed by snackbarCompat for notistack content/action parity.
127
+ message: typeof message === "string" ? message : "",
128
+ withCloseButton,
129
+ ...autoClose === void 0 ? {} : { autoClose }
130
+ });
131
+ const id2 = notifications_store.notifications.show({
132
+ ...presentation,
133
+ title: options.title,
134
+ message: renderedMessage,
135
+ onClose,
136
+ position: resolvePosition(options),
137
+ style: options.style
138
+ });
139
+ trackDuplicate(id2, options, duplicateKey);
140
+ return id2;
141
+ }
75
142
  const id = notifications_store.notifications.show({
76
143
  id: explicitId,
77
144
  title: options.title,
78
145
  message: renderedMessage,
79
- color: variantColorMap[options.variant ?? "default"],
80
- autoClose: resolveAutoClose(options),
81
- onClose: (notification) => {
82
- const notificationId = String(notification?.id ?? explicitId ?? "");
83
- const closeReason = notificationId && instructedCloseIds.has(notificationId) ? "instructed" : "timeout";
84
- if (notificationId) instructedCloseIds.delete(notificationId);
85
- if (options.preventDuplicate) clearDuplicateKey(duplicateKey);
86
- options.onClose?.(void 0, closeReason, notification?.id ?? explicitId);
87
- },
146
+ autoClose,
147
+ withCloseButton,
148
+ onClose,
88
149
  position: resolvePosition(options),
89
150
  style: options.style
90
151
  });
91
- if (options.preventDuplicate) {
92
- activeDuplicateKeys.add(duplicateKey);
93
- duplicateKeysById.set(id, duplicateKey);
94
- duplicateIdsByKey.set(duplicateKey, id);
95
- }
152
+ trackDuplicate(id, options, duplicateKey);
96
153
  return id;
97
154
  };
98
155
  const closeSnackbar = (id) => {
@@ -1 +1 @@
1
- {"version":3,"file":"snackbarCompat.cjs","sources":["../src/snackbarCompat.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport { type CSSProperties, createElement, Fragment, type ReactNode } from \"react\";\nimport { colors } from \"./theme/colors\";\n\ntype SnackbarVariant = \"default\" | \"error\" | \"info\" | \"success\" | \"warning\";\ntype SnackbarKey = string | number;\ntype SnackbarCloseReason = \"clickaway\" | \"instructed\" | \"maxsnack\" | \"timeout\";\n\ninterface SnackbarOptions {\n action?: ReactNode | ((key: SnackbarKey) => ReactNode);\n anchorOrigin?: {\n horizontal?: \"center\" | \"left\" | \"right\";\n vertical?: \"bottom\" | \"top\";\n };\n autoHideDuration?: number | null;\n content?: ReactNode | ((key: SnackbarKey, message: ReactNode) => ReactNode);\n key?: SnackbarKey;\n onClose?: (event?: unknown, reason?: SnackbarCloseReason, key?: SnackbarKey) => void;\n persist?: boolean;\n preventDuplicate?: boolean;\n style?: CSSProperties;\n title?: ReactNode;\n variant?: SnackbarVariant;\n [key: string]: unknown;\n}\n\nconst variantColorMap: Record<SnackbarVariant, string | undefined> = {\n default: undefined,\n error: colors.error,\n info: colors.info,\n success: colors.success,\n warning: colors.warning,\n};\n\nconst resolveAutoClose = (options: SnackbarOptions) => {\n if (options.persist || options.autoHideDuration === null) return false;\n return options.autoHideDuration;\n};\n\nconst resolvePosition = (options: SnackbarOptions) => {\n if (!options.anchorOrigin) return undefined;\n\n const vertical = options.anchorOrigin?.vertical;\n const horizontal = options.anchorOrigin?.horizontal;\n\n return `${vertical ?? \"bottom\"}-${horizontal ?? \"left\"}` as const;\n};\n\nlet generatedSnackbarKey = 0;\nlet generatedNodeDuplicateKey = 0;\nconst activeDuplicateKeys = new Set<string>();\nconst duplicateKeysById = new Map<string, string>();\nconst duplicateIdsByKey = new Map<string, string>();\nconst instructedCloseIds = new Set<string>();\nconst nodeDuplicateKeys = new WeakMap<object, string>();\n\nconst createDuplicatePart = (value: ReactNode, part: string) => {\n if ((typeof value === \"object\" || typeof value === \"function\") && value !== null) {\n const keyTarget = value as object;\n const existingKey = nodeDuplicateKeys.get(keyTarget);\n if (existingKey) return existingKey;\n\n generatedNodeDuplicateKey += 1;\n const nextKey = `${part}:node-${generatedNodeDuplicateKey}`;\n nodeDuplicateKeys.set(keyTarget, nextKey);\n return nextKey;\n }\n\n return `${part}:primitive:${String(value ?? \"\")}`;\n};\n\nconst createDuplicateKey = (message: ReactNode, options: SnackbarOptions) =>\n [\n options.variant ?? \"default\",\n createDuplicatePart(options.title, \"title\"),\n createDuplicatePart(message, \"message\"),\n ].join(\":\");\n\nconst clearDuplicateKey = (duplicateKey: string) => {\n const id = duplicateIdsByKey.get(duplicateKey);\n activeDuplicateKeys.delete(duplicateKey);\n duplicateIdsByKey.delete(duplicateKey);\n if (id) duplicateKeysById.delete(id);\n};\n\nconst clearDuplicateId = (id: string) => {\n const duplicateKey = duplicateKeysById.get(id);\n if (duplicateKey) clearDuplicateKey(duplicateKey);\n};\n\nexport const enqueueSnackbar = (message: ReactNode, options: SnackbarOptions = {}) => {\n const duplicateKey = createDuplicateKey(message, options);\n const needsStableKey = Boolean(options.action || options.content);\n if (options.key === undefined && needsStableKey) {\n generatedSnackbarKey += 1;\n }\n const explicitId =\n options.key === undefined\n ? needsStableKey\n ? `snackbar-${generatedSnackbarKey}`\n : undefined\n : String(options.key);\n const previousDuplicateKey = explicitId ? duplicateKeysById.get(explicitId) : undefined;\n if (explicitId && previousDuplicateKey && previousDuplicateKey !== duplicateKey) {\n clearDuplicateId(explicitId);\n }\n\n if (options.preventDuplicate && activeDuplicateKeys.has(duplicateKey)) {\n return duplicateIdsByKey.get(duplicateKey) ?? duplicateKey;\n }\n\n const renderKey = explicitId ?? \"\";\n const action = typeof options.action === \"function\" ? options.action(renderKey) : options.action;\n const content =\n typeof options.content === \"function\" ? options.content(renderKey, message) : options.content;\n const renderedMessage =\n content ?? (action ? createElement(Fragment, null, message, action) : message);\n\n const id = notifications.show({\n id: explicitId,\n title: options.title,\n message: renderedMessage,\n color: variantColorMap[options.variant ?? \"default\"],\n autoClose: resolveAutoClose(options),\n onClose: (notification) => {\n const notificationId = String(notification?.id ?? explicitId ?? \"\");\n const closeReason =\n notificationId && instructedCloseIds.has(notificationId) ? \"instructed\" : \"timeout\";\n if (notificationId) instructedCloseIds.delete(notificationId);\n if (options.preventDuplicate) clearDuplicateKey(duplicateKey);\n options.onClose?.(undefined, closeReason, notification?.id ?? explicitId);\n },\n position: resolvePosition(options),\n style: options.style,\n });\n\n if (options.preventDuplicate) {\n activeDuplicateKeys.add(duplicateKey);\n duplicateKeysById.set(id, duplicateKey);\n duplicateIdsByKey.set(duplicateKey, id);\n }\n\n return id;\n};\n\nexport const closeSnackbar = (id?: SnackbarKey) => {\n if (id === undefined) {\n for (const notificationId of duplicateKeysById.keys()) {\n instructedCloseIds.add(notificationId);\n }\n activeDuplicateKeys.clear();\n duplicateKeysById.clear();\n duplicateIdsByKey.clear();\n notifications.clean();\n return;\n }\n\n const resolvedId = String(id);\n instructedCloseIds.add(resolvedId);\n clearDuplicateId(resolvedId);\n notifications.hide(resolvedId);\n};\n\nexport const useSnackbar = () => ({\n closeSnackbar,\n enqueueSnackbar,\n});\n"],"names":["colors","createElement","Fragment","notifications"],"mappings":"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"}
1
+ {"version":3,"file":"snackbarCompat.cjs","sources":["../src/snackbarCompat.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport { type CSSProperties, createElement, Fragment, type ReactNode } from \"react\";\nimport { buildNotifyNotification, notify } from \"./notify\";\n\ntype SnackbarVariant = \"default\" | \"error\" | \"info\" | \"success\" | \"warning\";\ntype SemanticSnackbarVariant = Exclude<SnackbarVariant, \"default\">;\ntype SnackbarKey = string | number;\ntype SnackbarCloseReason = \"clickaway\" | \"instructed\" | \"maxsnack\" | \"timeout\";\n\ninterface SnackbarOptions {\n action?: ReactNode | ((key: SnackbarKey) => ReactNode);\n anchorOrigin?: {\n horizontal?: \"center\" | \"left\" | \"right\";\n vertical?: \"bottom\" | \"top\";\n };\n autoHideDuration?: number | null;\n content?: ReactNode | ((key: SnackbarKey, message: ReactNode) => ReactNode);\n key?: SnackbarKey;\n onClose?: (event?: unknown, reason?: SnackbarCloseReason, key?: SnackbarKey) => void;\n persist?: boolean;\n preventDuplicate?: boolean;\n style?: CSSProperties;\n title?: ReactNode;\n variant?: SnackbarVariant;\n [key: string]: unknown;\n}\n\nconst semanticNotifyMethods = {\n error: notify.error,\n info: notify.info,\n success: notify.success,\n warning: notify.warning,\n} as const;\n\nconst isSemanticVariant = (variant: SnackbarVariant): variant is SemanticSnackbarVariant =>\n variant !== \"default\";\n\nconst resolveAutoClose = (options: SnackbarOptions): number | false | undefined => {\n if (options.persist || options.autoHideDuration === null) return false;\n return options.autoHideDuration;\n};\n\nconst resolvePosition = (options: SnackbarOptions) => {\n if (!options.anchorOrigin) return undefined;\n\n const vertical = options.anchorOrigin?.vertical;\n const horizontal = options.anchorOrigin?.horizontal;\n\n return `${vertical ?? \"bottom\"}-${horizontal ?? \"left\"}` as const;\n};\n\nconst resolveWithCloseButton = (options: SnackbarOptions, action: ReactNode | undefined) => {\n // Persist + custom action often ships its own dismiss control — avoid a double close affordance.\n if (action !== undefined && (options.persist || options.autoHideDuration === null)) {\n return false;\n }\n return true;\n};\n\n/**\n * Simple semantic snackbars can use the public notify helpers directly.\n * Complex notistack features keep a hybrid notifications.show path that still\n * applies Notify chrome (icon, withBorder, semantic color).\n */\nconst canRouteThroughNotify = (message: ReactNode, options: SnackbarOptions) => {\n if (!isSemanticVariant(options.variant ?? \"default\")) return false;\n if (typeof message !== \"string\") return false;\n if (options.title !== undefined && typeof options.title !== \"string\") return false;\n if (options.content !== undefined) return false;\n if (options.style !== undefined) return false;\n if (options.anchorOrigin !== undefined) return false;\n if (options.onClose !== undefined) return false;\n if (options.preventDuplicate) return false;\n return true;\n};\n\nlet generatedSnackbarKey = 0;\nlet generatedNodeDuplicateKey = 0;\nconst activeDuplicateKeys = new Set<string>();\nconst duplicateKeysById = new Map<string, string>();\nconst duplicateIdsByKey = new Map<string, string>();\nconst instructedCloseIds = new Set<string>();\nconst nodeDuplicateKeys = new WeakMap<object, string>();\n\nconst createDuplicatePart = (value: ReactNode, part: string) => {\n if ((typeof value === \"object\" || typeof value === \"function\") && value !== null) {\n const keyTarget = value as object;\n const existingKey = nodeDuplicateKeys.get(keyTarget);\n if (existingKey) return existingKey;\n\n generatedNodeDuplicateKey += 1;\n const nextKey = `${part}:node-${generatedNodeDuplicateKey}`;\n nodeDuplicateKeys.set(keyTarget, nextKey);\n return nextKey;\n }\n\n return `${part}:primitive:${String(value ?? \"\")}`;\n};\n\nconst createDuplicateKey = (message: ReactNode, options: SnackbarOptions) =>\n [\n options.variant ?? \"default\",\n createDuplicatePart(options.title, \"title\"),\n createDuplicatePart(message, \"message\"),\n ].join(\":\");\n\nconst clearDuplicateKey = (duplicateKey: string) => {\n const id = duplicateIdsByKey.get(duplicateKey);\n activeDuplicateKeys.delete(duplicateKey);\n duplicateIdsByKey.delete(duplicateKey);\n if (id) duplicateKeysById.delete(id);\n};\n\nconst clearDuplicateId = (id: string) => {\n const duplicateKey = duplicateKeysById.get(id);\n if (duplicateKey) clearDuplicateKey(duplicateKey);\n};\n\nconst trackDuplicate = (id: string, options: SnackbarOptions, duplicateKey: string) => {\n if (options.preventDuplicate) {\n activeDuplicateKeys.add(duplicateKey);\n duplicateKeysById.set(id, duplicateKey);\n duplicateIdsByKey.set(duplicateKey, id);\n }\n};\n\nexport const enqueueSnackbar = (message: ReactNode, options: SnackbarOptions = {}) => {\n const duplicateKey = createDuplicateKey(message, options);\n const needsStableKey = Boolean(options.action || options.content);\n if (options.key === undefined && needsStableKey) {\n generatedSnackbarKey += 1;\n }\n const explicitId =\n options.key === undefined\n ? needsStableKey\n ? `snackbar-${generatedSnackbarKey}`\n : undefined\n : String(options.key);\n const previousDuplicateKey = explicitId ? duplicateKeysById.get(explicitId) : undefined;\n if (explicitId && previousDuplicateKey && previousDuplicateKey !== duplicateKey) {\n clearDuplicateId(explicitId);\n }\n\n if (options.preventDuplicate && activeDuplicateKeys.has(duplicateKey)) {\n return duplicateIdsByKey.get(duplicateKey) ?? duplicateKey;\n }\n\n const renderKey = explicitId ?? \"\";\n const action = typeof options.action === \"function\" ? options.action(renderKey) : options.action;\n const content =\n typeof options.content === \"function\" ? options.content(renderKey, message) : options.content;\n const variant = options.variant ?? \"default\";\n const autoClose = resolveAutoClose(options);\n const withCloseButton = resolveWithCloseButton(options, action);\n\n if (\n typeof message === \"string\" &&\n canRouteThroughNotify(message, options) &&\n isSemanticVariant(variant)\n ) {\n const notifyOptions = {\n id: explicitId,\n title: typeof options.title === \"string\" ? options.title : undefined,\n message,\n action,\n withCloseButton,\n ...(autoClose === undefined ? {} : { autoClose }),\n };\n const id = semanticNotifyMethods[variant](notifyOptions);\n trackDuplicate(id, options, duplicateKey);\n return id;\n }\n\n const renderedMessage =\n content ?? (action ? createElement(Fragment, null, message, action) : message);\n\n const onClose = (notification: { id?: string } | undefined) => {\n const notificationId = String(notification?.id ?? explicitId ?? \"\");\n const closeReason =\n notificationId && instructedCloseIds.has(notificationId) ? \"instructed\" : \"timeout\";\n if (notificationId) instructedCloseIds.delete(notificationId);\n if (options.preventDuplicate) clearDuplicateKey(duplicateKey);\n options.onClose?.(undefined, closeReason, notification?.id ?? explicitId);\n };\n\n if (isSemanticVariant(variant)) {\n const presentation = buildNotifyNotification(variant, {\n id: explicitId,\n title: typeof options.title === \"string\" ? options.title : undefined,\n // Message/action are composed by snackbarCompat for notistack content/action parity.\n message: typeof message === \"string\" ? message : \"\",\n withCloseButton,\n ...(autoClose === undefined ? {} : { autoClose }),\n });\n\n const id = notifications.show({\n ...presentation,\n title: options.title,\n message: renderedMessage,\n onClose,\n position: resolvePosition(options),\n style: options.style,\n });\n\n trackDuplicate(id, options, duplicateKey);\n return id;\n }\n\n const id = notifications.show({\n id: explicitId,\n title: options.title,\n message: renderedMessage,\n autoClose,\n withCloseButton,\n onClose,\n position: resolvePosition(options),\n style: options.style,\n });\n\n trackDuplicate(id, options, duplicateKey);\n return id;\n};\n\nexport const closeSnackbar = (id?: SnackbarKey) => {\n if (id === undefined) {\n for (const notificationId of duplicateKeysById.keys()) {\n instructedCloseIds.add(notificationId);\n }\n activeDuplicateKeys.clear();\n duplicateKeysById.clear();\n duplicateIdsByKey.clear();\n notifications.clean();\n return;\n }\n\n const resolvedId = String(id);\n instructedCloseIds.add(resolvedId);\n clearDuplicateId(resolvedId);\n notifications.hide(resolvedId);\n};\n\nexport const useSnackbar = () => ({\n closeSnackbar,\n enqueueSnackbar,\n});\n"],"names":["notify","id","createElement","Fragment","buildNotifyNotification","notifications"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"snackbarCompat.d.ts","sourceRoot":"","sources":["../src/snackbarCompat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpF,KAAK,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAC5E,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AACnC,KAAK,mBAAmB,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/E,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC;IACvD,YAAY,CAAC,EAAE;QACb,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;QACzC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;KAC7B,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC;IAC5E,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,mBAAmB,EAAE,GAAG,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAkED,eAAO,MAAM,eAAe,GAAI,SAAS,SAAS,EAAE,UAAS,eAAoB,WAqDhF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,KAAK,WAAW,SAgB7C,CAAC;AAEF,eAAO,MAAM,WAAW;yBAlBW,WAAW;+BAvDL,SAAS,YAAW,eAAe;CA4E1E,CAAC"}
1
+ {"version":3,"file":"snackbarCompat.d.ts","sourceRoot":"","sources":["../src/snackbarCompat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpF,KAAK,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5E,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AACnC,KAAK,mBAAmB,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/E,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC;IACvD,YAAY,CAAC,EAAE;QACb,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;QACzC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;KAC7B,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC;IAC5E,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,mBAAmB,EAAE,GAAG,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAqGD,eAAO,MAAM,eAAe,GAAI,SAAS,SAAS,EAAE,UAAS,eAAoB,WA+FhF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,KAAK,WAAW,SAgB7C,CAAC;AAEF,eAAO,MAAM,WAAW;yBAlBW,WAAW;+BAjGL,SAAS,YAAW,eAAe;CAsH1E,CAAC"}
@@ -1,13 +1,13 @@
1
1
  import { createElement, Fragment } from "react";
2
- import { colors } from "./theme/colors.js";
2
+ import { notify, buildNotifyNotification } from "./notify.js";
3
3
  import { notifications } from "./node_modules/@mantine/notifications/esm/notifications.store.js";
4
- const variantColorMap = {
5
- default: void 0,
6
- error: colors.error,
7
- info: colors.info,
8
- success: colors.success,
9
- warning: colors.warning
4
+ const semanticNotifyMethods = {
5
+ error: notify.error,
6
+ info: notify.info,
7
+ success: notify.success,
8
+ warning: notify.warning
10
9
  };
10
+ const isSemanticVariant = (variant) => variant !== "default";
11
11
  const resolveAutoClose = (options) => {
12
12
  if (options.persist || options.autoHideDuration === null) return false;
13
13
  return options.autoHideDuration;
@@ -18,6 +18,23 @@ const resolvePosition = (options) => {
18
18
  const horizontal = options.anchorOrigin?.horizontal;
19
19
  return `${vertical ?? "bottom"}-${horizontal ?? "left"}`;
20
20
  };
21
+ const resolveWithCloseButton = (options, action) => {
22
+ if (action !== void 0 && (options.persist || options.autoHideDuration === null)) {
23
+ return false;
24
+ }
25
+ return true;
26
+ };
27
+ const canRouteThroughNotify = (message, options) => {
28
+ if (!isSemanticVariant(options.variant ?? "default")) return false;
29
+ if (typeof message !== "string") return false;
30
+ if (options.title !== void 0 && typeof options.title !== "string") return false;
31
+ if (options.content !== void 0) return false;
32
+ if (options.style !== void 0) return false;
33
+ if (options.anchorOrigin !== void 0) return false;
34
+ if (options.onClose !== void 0) return false;
35
+ if (options.preventDuplicate) return false;
36
+ return true;
37
+ };
21
38
  let generatedSnackbarKey = 0;
22
39
  let generatedNodeDuplicateKey = 0;
23
40
  const activeDuplicateKeys = /* @__PURE__ */ new Set();
@@ -52,6 +69,13 @@ const clearDuplicateId = (id) => {
52
69
  const duplicateKey = duplicateKeysById.get(id);
53
70
  if (duplicateKey) clearDuplicateKey(duplicateKey);
54
71
  };
72
+ const trackDuplicate = (id, options, duplicateKey) => {
73
+ if (options.preventDuplicate) {
74
+ activeDuplicateKeys.add(duplicateKey);
75
+ duplicateKeysById.set(id, duplicateKey);
76
+ duplicateIdsByKey.set(duplicateKey, id);
77
+ }
78
+ };
55
79
  const enqueueSnackbar = (message, options = {}) => {
56
80
  const duplicateKey = createDuplicateKey(message, options);
57
81
  const needsStableKey = Boolean(options.action || options.content);
@@ -69,28 +93,61 @@ const enqueueSnackbar = (message, options = {}) => {
69
93
  const renderKey = explicitId ?? "";
70
94
  const action = typeof options.action === "function" ? options.action(renderKey) : options.action;
71
95
  const content = typeof options.content === "function" ? options.content(renderKey, message) : options.content;
96
+ const variant = options.variant ?? "default";
97
+ const autoClose = resolveAutoClose(options);
98
+ const withCloseButton = resolveWithCloseButton(options, action);
99
+ if (typeof message === "string" && canRouteThroughNotify(message, options) && isSemanticVariant(variant)) {
100
+ const notifyOptions = {
101
+ id: explicitId,
102
+ title: typeof options.title === "string" ? options.title : void 0,
103
+ message,
104
+ action,
105
+ withCloseButton,
106
+ ...autoClose === void 0 ? {} : { autoClose }
107
+ };
108
+ const id2 = semanticNotifyMethods[variant](notifyOptions);
109
+ trackDuplicate(id2, options, duplicateKey);
110
+ return id2;
111
+ }
72
112
  const renderedMessage = content ?? (action ? createElement(Fragment, null, message, action) : message);
113
+ const onClose = (notification) => {
114
+ const notificationId = String(notification?.id ?? explicitId ?? "");
115
+ const closeReason = notificationId && instructedCloseIds.has(notificationId) ? "instructed" : "timeout";
116
+ if (notificationId) instructedCloseIds.delete(notificationId);
117
+ if (options.preventDuplicate) clearDuplicateKey(duplicateKey);
118
+ options.onClose?.(void 0, closeReason, notification?.id ?? explicitId);
119
+ };
120
+ if (isSemanticVariant(variant)) {
121
+ const presentation = buildNotifyNotification(variant, {
122
+ id: explicitId,
123
+ title: typeof options.title === "string" ? options.title : void 0,
124
+ // Message/action are composed by snackbarCompat for notistack content/action parity.
125
+ message: typeof message === "string" ? message : "",
126
+ withCloseButton,
127
+ ...autoClose === void 0 ? {} : { autoClose }
128
+ });
129
+ const id2 = notifications.show({
130
+ ...presentation,
131
+ title: options.title,
132
+ message: renderedMessage,
133
+ onClose,
134
+ position: resolvePosition(options),
135
+ style: options.style
136
+ });
137
+ trackDuplicate(id2, options, duplicateKey);
138
+ return id2;
139
+ }
73
140
  const id = notifications.show({
74
141
  id: explicitId,
75
142
  title: options.title,
76
143
  message: renderedMessage,
77
- color: variantColorMap[options.variant ?? "default"],
78
- autoClose: resolveAutoClose(options),
79
- onClose: (notification) => {
80
- const notificationId = String(notification?.id ?? explicitId ?? "");
81
- const closeReason = notificationId && instructedCloseIds.has(notificationId) ? "instructed" : "timeout";
82
- if (notificationId) instructedCloseIds.delete(notificationId);
83
- if (options.preventDuplicate) clearDuplicateKey(duplicateKey);
84
- options.onClose?.(void 0, closeReason, notification?.id ?? explicitId);
85
- },
144
+ autoClose,
145
+ withCloseButton,
146
+ onClose,
86
147
  position: resolvePosition(options),
87
148
  style: options.style
88
149
  });
89
- if (options.preventDuplicate) {
90
- activeDuplicateKeys.add(duplicateKey);
91
- duplicateKeysById.set(id, duplicateKey);
92
- duplicateIdsByKey.set(duplicateKey, id);
93
- }
150
+ trackDuplicate(id, options, duplicateKey);
94
151
  return id;
95
152
  };
96
153
  const closeSnackbar = (id) => {
@@ -1 +1 @@
1
- {"version":3,"file":"snackbarCompat.js","sources":["../src/snackbarCompat.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport { type CSSProperties, createElement, Fragment, type ReactNode } from \"react\";\nimport { colors } from \"./theme/colors\";\n\ntype SnackbarVariant = \"default\" | \"error\" | \"info\" | \"success\" | \"warning\";\ntype SnackbarKey = string | number;\ntype SnackbarCloseReason = \"clickaway\" | \"instructed\" | \"maxsnack\" | \"timeout\";\n\ninterface SnackbarOptions {\n action?: ReactNode | ((key: SnackbarKey) => ReactNode);\n anchorOrigin?: {\n horizontal?: \"center\" | \"left\" | \"right\";\n vertical?: \"bottom\" | \"top\";\n };\n autoHideDuration?: number | null;\n content?: ReactNode | ((key: SnackbarKey, message: ReactNode) => ReactNode);\n key?: SnackbarKey;\n onClose?: (event?: unknown, reason?: SnackbarCloseReason, key?: SnackbarKey) => void;\n persist?: boolean;\n preventDuplicate?: boolean;\n style?: CSSProperties;\n title?: ReactNode;\n variant?: SnackbarVariant;\n [key: string]: unknown;\n}\n\nconst variantColorMap: Record<SnackbarVariant, string | undefined> = {\n default: undefined,\n error: colors.error,\n info: colors.info,\n success: colors.success,\n warning: colors.warning,\n};\n\nconst resolveAutoClose = (options: SnackbarOptions) => {\n if (options.persist || options.autoHideDuration === null) return false;\n return options.autoHideDuration;\n};\n\nconst resolvePosition = (options: SnackbarOptions) => {\n if (!options.anchorOrigin) return undefined;\n\n const vertical = options.anchorOrigin?.vertical;\n const horizontal = options.anchorOrigin?.horizontal;\n\n return `${vertical ?? \"bottom\"}-${horizontal ?? \"left\"}` as const;\n};\n\nlet generatedSnackbarKey = 0;\nlet generatedNodeDuplicateKey = 0;\nconst activeDuplicateKeys = new Set<string>();\nconst duplicateKeysById = new Map<string, string>();\nconst duplicateIdsByKey = new Map<string, string>();\nconst instructedCloseIds = new Set<string>();\nconst nodeDuplicateKeys = new WeakMap<object, string>();\n\nconst createDuplicatePart = (value: ReactNode, part: string) => {\n if ((typeof value === \"object\" || typeof value === \"function\") && value !== null) {\n const keyTarget = value as object;\n const existingKey = nodeDuplicateKeys.get(keyTarget);\n if (existingKey) return existingKey;\n\n generatedNodeDuplicateKey += 1;\n const nextKey = `${part}:node-${generatedNodeDuplicateKey}`;\n nodeDuplicateKeys.set(keyTarget, nextKey);\n return nextKey;\n }\n\n return `${part}:primitive:${String(value ?? \"\")}`;\n};\n\nconst createDuplicateKey = (message: ReactNode, options: SnackbarOptions) =>\n [\n options.variant ?? \"default\",\n createDuplicatePart(options.title, \"title\"),\n createDuplicatePart(message, \"message\"),\n ].join(\":\");\n\nconst clearDuplicateKey = (duplicateKey: string) => {\n const id = duplicateIdsByKey.get(duplicateKey);\n activeDuplicateKeys.delete(duplicateKey);\n duplicateIdsByKey.delete(duplicateKey);\n if (id) duplicateKeysById.delete(id);\n};\n\nconst clearDuplicateId = (id: string) => {\n const duplicateKey = duplicateKeysById.get(id);\n if (duplicateKey) clearDuplicateKey(duplicateKey);\n};\n\nexport const enqueueSnackbar = (message: ReactNode, options: SnackbarOptions = {}) => {\n const duplicateKey = createDuplicateKey(message, options);\n const needsStableKey = Boolean(options.action || options.content);\n if (options.key === undefined && needsStableKey) {\n generatedSnackbarKey += 1;\n }\n const explicitId =\n options.key === undefined\n ? needsStableKey\n ? `snackbar-${generatedSnackbarKey}`\n : undefined\n : String(options.key);\n const previousDuplicateKey = explicitId ? duplicateKeysById.get(explicitId) : undefined;\n if (explicitId && previousDuplicateKey && previousDuplicateKey !== duplicateKey) {\n clearDuplicateId(explicitId);\n }\n\n if (options.preventDuplicate && activeDuplicateKeys.has(duplicateKey)) {\n return duplicateIdsByKey.get(duplicateKey) ?? duplicateKey;\n }\n\n const renderKey = explicitId ?? \"\";\n const action = typeof options.action === \"function\" ? options.action(renderKey) : options.action;\n const content =\n typeof options.content === \"function\" ? options.content(renderKey, message) : options.content;\n const renderedMessage =\n content ?? (action ? createElement(Fragment, null, message, action) : message);\n\n const id = notifications.show({\n id: explicitId,\n title: options.title,\n message: renderedMessage,\n color: variantColorMap[options.variant ?? \"default\"],\n autoClose: resolveAutoClose(options),\n onClose: (notification) => {\n const notificationId = String(notification?.id ?? explicitId ?? \"\");\n const closeReason =\n notificationId && instructedCloseIds.has(notificationId) ? \"instructed\" : \"timeout\";\n if (notificationId) instructedCloseIds.delete(notificationId);\n if (options.preventDuplicate) clearDuplicateKey(duplicateKey);\n options.onClose?.(undefined, closeReason, notification?.id ?? explicitId);\n },\n position: resolvePosition(options),\n style: options.style,\n });\n\n if (options.preventDuplicate) {\n activeDuplicateKeys.add(duplicateKey);\n duplicateKeysById.set(id, duplicateKey);\n duplicateIdsByKey.set(duplicateKey, id);\n }\n\n return id;\n};\n\nexport const closeSnackbar = (id?: SnackbarKey) => {\n if (id === undefined) {\n for (const notificationId of duplicateKeysById.keys()) {\n instructedCloseIds.add(notificationId);\n }\n activeDuplicateKeys.clear();\n duplicateKeysById.clear();\n duplicateIdsByKey.clear();\n notifications.clean();\n return;\n }\n\n const resolvedId = String(id);\n instructedCloseIds.add(resolvedId);\n clearDuplicateId(resolvedId);\n notifications.hide(resolvedId);\n};\n\nexport const useSnackbar = () => ({\n closeSnackbar,\n enqueueSnackbar,\n});\n"],"names":[],"mappings":";;;AA0BA,MAAM,kBAA+D;AAAA,EACnE,SAAS;AAAA,EACT,OAAO,OAAO;AAAA,EACd,MAAM,OAAO;AAAA,EACb,SAAS,OAAO;AAAA,EAChB,SAAS,OAAO;AAClB;AAEA,MAAM,mBAAmB,CAAC,YAA6B;AACrD,MAAI,QAAQ,WAAW,QAAQ,qBAAqB,KAAM,QAAO;AACjE,SAAO,QAAQ;AACjB;AAEA,MAAM,kBAAkB,CAAC,YAA6B;AACpD,MAAI,CAAC,QAAQ,aAAc,QAAO;AAElC,QAAM,WAAW,QAAQ,cAAc;AACvC,QAAM,aAAa,QAAQ,cAAc;AAEzC,SAAO,GAAG,YAAY,QAAQ,IAAI,cAAc,MAAM;AACxD;AAEA,IAAI,uBAAuB;AAC3B,IAAI,4BAA4B;AAChC,MAAM,0CAA0B,IAAA;AAChC,MAAM,wCAAwB,IAAA;AAC9B,MAAM,wCAAwB,IAAA;AAC9B,MAAM,yCAAyB,IAAA;AAC/B,MAAM,wCAAwB,QAAA;AAE9B,MAAM,sBAAsB,CAAC,OAAkB,SAAiB;AAC9D,OAAK,OAAO,UAAU,YAAY,OAAO,UAAU,eAAe,UAAU,MAAM;AAChF,UAAM,YAAY;AAClB,UAAM,cAAc,kBAAkB,IAAI,SAAS;AACnD,QAAI,YAAa,QAAO;AAExB,iCAA6B;AAC7B,UAAM,UAAU,GAAG,IAAI,SAAS,yBAAyB;AACzD,sBAAkB,IAAI,WAAW,OAAO;AACxC,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,IAAI,cAAc,OAAO,SAAS,EAAE,CAAC;AACjD;AAEA,MAAM,qBAAqB,CAAC,SAAoB,YAC9C;AAAA,EACE,QAAQ,WAAW;AAAA,EACnB,oBAAoB,QAAQ,OAAO,OAAO;AAAA,EAC1C,oBAAoB,SAAS,SAAS;AACxC,EAAE,KAAK,GAAG;AAEZ,MAAM,oBAAoB,CAAC,iBAAyB;AAClD,QAAM,KAAK,kBAAkB,IAAI,YAAY;AAC7C,sBAAoB,OAAO,YAAY;AACvC,oBAAkB,OAAO,YAAY;AACrC,MAAI,GAAI,mBAAkB,OAAO,EAAE;AACrC;AAEA,MAAM,mBAAmB,CAAC,OAAe;AACvC,QAAM,eAAe,kBAAkB,IAAI,EAAE;AAC7C,MAAI,gCAAgC,YAAY;AAClD;AAEO,MAAM,kBAAkB,CAAC,SAAoB,UAA2B,OAAO;AACpF,QAAM,eAAe,mBAAmB,SAAS,OAAO;AACxD,QAAM,iBAAiB,QAAQ,QAAQ,UAAU,QAAQ,OAAO;AAChE,MAAI,QAAQ,QAAQ,UAAa,gBAAgB;AAC/C,4BAAwB;AAAA,EAC1B;AACA,QAAM,aACJ,QAAQ,QAAQ,SACZ,iBACE,YAAY,oBAAoB,KAChC,SACF,OAAO,QAAQ,GAAG;AACxB,QAAM,uBAAuB,aAAa,kBAAkB,IAAI,UAAU,IAAI;AAC9E,MAAI,cAAc,wBAAwB,yBAAyB,cAAc;AAC/E,qBAAiB,UAAU;AAAA,EAC7B;AAEA,MAAI,QAAQ,oBAAoB,oBAAoB,IAAI,YAAY,GAAG;AACrE,WAAO,kBAAkB,IAAI,YAAY,KAAK;AAAA,EAChD;AAEA,QAAM,YAAY,cAAc;AAChC,QAAM,SAAS,OAAO,QAAQ,WAAW,aAAa,QAAQ,OAAO,SAAS,IAAI,QAAQ;AAC1F,QAAM,UACJ,OAAO,QAAQ,YAAY,aAAa,QAAQ,QAAQ,WAAW,OAAO,IAAI,QAAQ;AACxF,QAAM,kBACJ,YAAY,SAAS,cAAc,UAAU,MAAM,SAAS,MAAM,IAAI;AAExE,QAAM,KAAK,cAAc,KAAK;AAAA,IAC5B,IAAI;AAAA,IACJ,OAAO,QAAQ;AAAA,IACf,SAAS;AAAA,IACT,OAAO,gBAAgB,QAAQ,WAAW,SAAS;AAAA,IACnD,WAAW,iBAAiB,OAAO;AAAA,IACnC,SAAS,CAAC,iBAAiB;AACzB,YAAM,iBAAiB,OAAO,cAAc,MAAM,cAAc,EAAE;AAClE,YAAM,cACJ,kBAAkB,mBAAmB,IAAI,cAAc,IAAI,eAAe;AAC5E,UAAI,eAAgB,oBAAmB,OAAO,cAAc;AAC5D,UAAI,QAAQ,iBAAkB,mBAAkB,YAAY;AAC5D,cAAQ,UAAU,QAAW,aAAa,cAAc,MAAM,UAAU;AAAA,IAC1E;AAAA,IACA,UAAU,gBAAgB,OAAO;AAAA,IACjC,OAAO,QAAQ;AAAA,EAAA,CAChB;AAED,MAAI,QAAQ,kBAAkB;AAC5B,wBAAoB,IAAI,YAAY;AACpC,sBAAkB,IAAI,IAAI,YAAY;AACtC,sBAAkB,IAAI,cAAc,EAAE;AAAA,EACxC;AAEA,SAAO;AACT;AAEO,MAAM,gBAAgB,CAAC,OAAqB;AACjD,MAAI,OAAO,QAAW;AACpB,eAAW,kBAAkB,kBAAkB,QAAQ;AACrD,yBAAmB,IAAI,cAAc;AAAA,IACvC;AACA,wBAAoB,MAAA;AACpB,sBAAkB,MAAA;AAClB,sBAAkB,MAAA;AAClB,kBAAc,MAAA;AACd;AAAA,EACF;AAEA,QAAM,aAAa,OAAO,EAAE;AAC5B,qBAAmB,IAAI,UAAU;AACjC,mBAAiB,UAAU;AAC3B,gBAAc,KAAK,UAAU;AAC/B;AAEO,MAAM,cAAc,OAAO;AAAA,EAChC;AAAA,EACA;AACF;"}
1
+ {"version":3,"file":"snackbarCompat.js","sources":["../src/snackbarCompat.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport { type CSSProperties, createElement, Fragment, type ReactNode } from \"react\";\nimport { buildNotifyNotification, notify } from \"./notify\";\n\ntype SnackbarVariant = \"default\" | \"error\" | \"info\" | \"success\" | \"warning\";\ntype SemanticSnackbarVariant = Exclude<SnackbarVariant, \"default\">;\ntype SnackbarKey = string | number;\ntype SnackbarCloseReason = \"clickaway\" | \"instructed\" | \"maxsnack\" | \"timeout\";\n\ninterface SnackbarOptions {\n action?: ReactNode | ((key: SnackbarKey) => ReactNode);\n anchorOrigin?: {\n horizontal?: \"center\" | \"left\" | \"right\";\n vertical?: \"bottom\" | \"top\";\n };\n autoHideDuration?: number | null;\n content?: ReactNode | ((key: SnackbarKey, message: ReactNode) => ReactNode);\n key?: SnackbarKey;\n onClose?: (event?: unknown, reason?: SnackbarCloseReason, key?: SnackbarKey) => void;\n persist?: boolean;\n preventDuplicate?: boolean;\n style?: CSSProperties;\n title?: ReactNode;\n variant?: SnackbarVariant;\n [key: string]: unknown;\n}\n\nconst semanticNotifyMethods = {\n error: notify.error,\n info: notify.info,\n success: notify.success,\n warning: notify.warning,\n} as const;\n\nconst isSemanticVariant = (variant: SnackbarVariant): variant is SemanticSnackbarVariant =>\n variant !== \"default\";\n\nconst resolveAutoClose = (options: SnackbarOptions): number | false | undefined => {\n if (options.persist || options.autoHideDuration === null) return false;\n return options.autoHideDuration;\n};\n\nconst resolvePosition = (options: SnackbarOptions) => {\n if (!options.anchorOrigin) return undefined;\n\n const vertical = options.anchorOrigin?.vertical;\n const horizontal = options.anchorOrigin?.horizontal;\n\n return `${vertical ?? \"bottom\"}-${horizontal ?? \"left\"}` as const;\n};\n\nconst resolveWithCloseButton = (options: SnackbarOptions, action: ReactNode | undefined) => {\n // Persist + custom action often ships its own dismiss control — avoid a double close affordance.\n if (action !== undefined && (options.persist || options.autoHideDuration === null)) {\n return false;\n }\n return true;\n};\n\n/**\n * Simple semantic snackbars can use the public notify helpers directly.\n * Complex notistack features keep a hybrid notifications.show path that still\n * applies Notify chrome (icon, withBorder, semantic color).\n */\nconst canRouteThroughNotify = (message: ReactNode, options: SnackbarOptions) => {\n if (!isSemanticVariant(options.variant ?? \"default\")) return false;\n if (typeof message !== \"string\") return false;\n if (options.title !== undefined && typeof options.title !== \"string\") return false;\n if (options.content !== undefined) return false;\n if (options.style !== undefined) return false;\n if (options.anchorOrigin !== undefined) return false;\n if (options.onClose !== undefined) return false;\n if (options.preventDuplicate) return false;\n return true;\n};\n\nlet generatedSnackbarKey = 0;\nlet generatedNodeDuplicateKey = 0;\nconst activeDuplicateKeys = new Set<string>();\nconst duplicateKeysById = new Map<string, string>();\nconst duplicateIdsByKey = new Map<string, string>();\nconst instructedCloseIds = new Set<string>();\nconst nodeDuplicateKeys = new WeakMap<object, string>();\n\nconst createDuplicatePart = (value: ReactNode, part: string) => {\n if ((typeof value === \"object\" || typeof value === \"function\") && value !== null) {\n const keyTarget = value as object;\n const existingKey = nodeDuplicateKeys.get(keyTarget);\n if (existingKey) return existingKey;\n\n generatedNodeDuplicateKey += 1;\n const nextKey = `${part}:node-${generatedNodeDuplicateKey}`;\n nodeDuplicateKeys.set(keyTarget, nextKey);\n return nextKey;\n }\n\n return `${part}:primitive:${String(value ?? \"\")}`;\n};\n\nconst createDuplicateKey = (message: ReactNode, options: SnackbarOptions) =>\n [\n options.variant ?? \"default\",\n createDuplicatePart(options.title, \"title\"),\n createDuplicatePart(message, \"message\"),\n ].join(\":\");\n\nconst clearDuplicateKey = (duplicateKey: string) => {\n const id = duplicateIdsByKey.get(duplicateKey);\n activeDuplicateKeys.delete(duplicateKey);\n duplicateIdsByKey.delete(duplicateKey);\n if (id) duplicateKeysById.delete(id);\n};\n\nconst clearDuplicateId = (id: string) => {\n const duplicateKey = duplicateKeysById.get(id);\n if (duplicateKey) clearDuplicateKey(duplicateKey);\n};\n\nconst trackDuplicate = (id: string, options: SnackbarOptions, duplicateKey: string) => {\n if (options.preventDuplicate) {\n activeDuplicateKeys.add(duplicateKey);\n duplicateKeysById.set(id, duplicateKey);\n duplicateIdsByKey.set(duplicateKey, id);\n }\n};\n\nexport const enqueueSnackbar = (message: ReactNode, options: SnackbarOptions = {}) => {\n const duplicateKey = createDuplicateKey(message, options);\n const needsStableKey = Boolean(options.action || options.content);\n if (options.key === undefined && needsStableKey) {\n generatedSnackbarKey += 1;\n }\n const explicitId =\n options.key === undefined\n ? needsStableKey\n ? `snackbar-${generatedSnackbarKey}`\n : undefined\n : String(options.key);\n const previousDuplicateKey = explicitId ? duplicateKeysById.get(explicitId) : undefined;\n if (explicitId && previousDuplicateKey && previousDuplicateKey !== duplicateKey) {\n clearDuplicateId(explicitId);\n }\n\n if (options.preventDuplicate && activeDuplicateKeys.has(duplicateKey)) {\n return duplicateIdsByKey.get(duplicateKey) ?? duplicateKey;\n }\n\n const renderKey = explicitId ?? \"\";\n const action = typeof options.action === \"function\" ? options.action(renderKey) : options.action;\n const content =\n typeof options.content === \"function\" ? options.content(renderKey, message) : options.content;\n const variant = options.variant ?? \"default\";\n const autoClose = resolveAutoClose(options);\n const withCloseButton = resolveWithCloseButton(options, action);\n\n if (\n typeof message === \"string\" &&\n canRouteThroughNotify(message, options) &&\n isSemanticVariant(variant)\n ) {\n const notifyOptions = {\n id: explicitId,\n title: typeof options.title === \"string\" ? options.title : undefined,\n message,\n action,\n withCloseButton,\n ...(autoClose === undefined ? {} : { autoClose }),\n };\n const id = semanticNotifyMethods[variant](notifyOptions);\n trackDuplicate(id, options, duplicateKey);\n return id;\n }\n\n const renderedMessage =\n content ?? (action ? createElement(Fragment, null, message, action) : message);\n\n const onClose = (notification: { id?: string } | undefined) => {\n const notificationId = String(notification?.id ?? explicitId ?? \"\");\n const closeReason =\n notificationId && instructedCloseIds.has(notificationId) ? \"instructed\" : \"timeout\";\n if (notificationId) instructedCloseIds.delete(notificationId);\n if (options.preventDuplicate) clearDuplicateKey(duplicateKey);\n options.onClose?.(undefined, closeReason, notification?.id ?? explicitId);\n };\n\n if (isSemanticVariant(variant)) {\n const presentation = buildNotifyNotification(variant, {\n id: explicitId,\n title: typeof options.title === \"string\" ? options.title : undefined,\n // Message/action are composed by snackbarCompat for notistack content/action parity.\n message: typeof message === \"string\" ? message : \"\",\n withCloseButton,\n ...(autoClose === undefined ? {} : { autoClose }),\n });\n\n const id = notifications.show({\n ...presentation,\n title: options.title,\n message: renderedMessage,\n onClose,\n position: resolvePosition(options),\n style: options.style,\n });\n\n trackDuplicate(id, options, duplicateKey);\n return id;\n }\n\n const id = notifications.show({\n id: explicitId,\n title: options.title,\n message: renderedMessage,\n autoClose,\n withCloseButton,\n onClose,\n position: resolvePosition(options),\n style: options.style,\n });\n\n trackDuplicate(id, options, duplicateKey);\n return id;\n};\n\nexport const closeSnackbar = (id?: SnackbarKey) => {\n if (id === undefined) {\n for (const notificationId of duplicateKeysById.keys()) {\n instructedCloseIds.add(notificationId);\n }\n activeDuplicateKeys.clear();\n duplicateKeysById.clear();\n duplicateIdsByKey.clear();\n notifications.clean();\n return;\n }\n\n const resolvedId = String(id);\n instructedCloseIds.add(resolvedId);\n clearDuplicateId(resolvedId);\n notifications.hide(resolvedId);\n};\n\nexport const useSnackbar = () => ({\n closeSnackbar,\n enqueueSnackbar,\n});\n"],"names":["id"],"mappings":"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"}
@@ -165,6 +165,28 @@ const typography = {
165
165
  fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
166
166
  headingFontFamily: '"Plus Jakarta Sans", sans-serif'
167
167
  };
168
+ const notificationToneStyles = {
169
+ success: {
170
+ bg: "var(--fairmint-color-success-bg)",
171
+ border: "var(--fairmint-color-success-border)",
172
+ text: "var(--fairmint-color-success-text)"
173
+ },
174
+ error: {
175
+ bg: "var(--fairmint-color-error-bg)",
176
+ border: "var(--fairmint-color-error-border)",
177
+ text: "var(--fairmint-color-error-text)"
178
+ },
179
+ warning: {
180
+ bg: "var(--fairmint-color-warning-bg)",
181
+ border: "var(--fairmint-color-warning-border)",
182
+ text: "var(--fairmint-color-warning-text)"
183
+ },
184
+ info: {
185
+ bg: "var(--fairmint-color-info-bg)",
186
+ border: "var(--fairmint-color-info-border)",
187
+ text: "var(--fairmint-color-info-text)"
188
+ }
189
+ };
168
190
  const theme = createTheme.createTheme({
169
191
  primaryColor: "indigo",
170
192
  // Mantine defaults to a darker shade for dark-mode filled/light variants
@@ -264,6 +286,56 @@ const theme = createTheme.createTheme({
264
286
  lineHeight: 1.3
265
287
  }
266
288
  }
289
+ },
290
+ // Toasts: Ramp-inspired restraint — single-layer subtle elevation (lighter
291
+ // than Mantine shadow-xs) + 1px semantic border (override shadow-lg / filled
292
+ // icon). Semantic variants use *-bg (light = ramp /50 / tuple[0]; dark =
293
+ // approved charcoal semantic surfaces) with matching border/text/icon tokens.
294
+ // Neutral/default (no color) stays on the standard surface.
295
+ // Horizontal padding is symmetric spacing.md (16px): Mantine defaults to
296
+ // 22px start (accent rail) vs spacing.xs end (~10px); Fairmint toasts use
297
+ // outlined icons (rail hidden), so match left/right on the spacing scale.
298
+ Notification: {
299
+ styles: (_theme, params) => {
300
+ const tone = notificationToneStyles[params.color ?? ""];
301
+ const rootPadding = {
302
+ paddingInlineStart: spacing.spacing.md,
303
+ paddingInlineEnd: spacing.spacing.md
304
+ };
305
+ if (!tone) {
306
+ return {
307
+ root: {
308
+ boxShadow: "var(--fairmint-elevation-subtle)",
309
+ ...rootPadding
310
+ },
311
+ icon: {
312
+ backgroundColor: "transparent",
313
+ color: "var(--notification-color)"
314
+ }
315
+ };
316
+ }
317
+ return {
318
+ root: {
319
+ boxShadow: "var(--fairmint-elevation-subtle)",
320
+ backgroundColor: tone.bg,
321
+ border: `1px solid ${tone.border}`,
322
+ ...rootPadding
323
+ },
324
+ title: {
325
+ color: tone.text
326
+ },
327
+ description: {
328
+ color: tone.text
329
+ },
330
+ icon: {
331
+ backgroundColor: "transparent",
332
+ color: tone.text
333
+ },
334
+ closeButton: {
335
+ color: tone.text
336
+ }
337
+ };
338
+ }
267
339
  }
268
340
  }
269
341
  });
@@ -306,6 +378,8 @@ const fairmintCssVariables = () => ({
306
378
  "--fairmint-color-surface-selected": indigo[0],
307
379
  "--fairmint-color-icon-on-surface-selected": indigo[6],
308
380
  "--fairmint-interactive-hover-shadow": `0 2px 6px ${neutral[9]}0F`,
381
+ // Single soft layer — lighter than Mantine shadow-xs (no multi-layer stack).
382
+ "--fairmint-elevation-subtle": `0 1px 3px ${neutral[9]}06`,
309
383
  "--fairmint-interactive-hover-bg": neutral[0],
310
384
  "--fairmint-color-success-bg": success[0],
311
385
  "--fairmint-color-success-text": success[7],
@@ -365,6 +439,8 @@ const fairmintCssVariables = () => ({
365
439
  // dark selected surface — use a light indigo instead.
366
440
  "--fairmint-color-icon-on-surface-selected": indigo[2],
367
441
  "--fairmint-interactive-hover-shadow": "0 2px 6px #00000066",
442
+ // Single soft layer — restrained vs hover shadow and Mantine shadow-xs.
443
+ "--fairmint-elevation-subtle": "0 1px 3px #00000014",
368
444
  "--fairmint-interactive-hover-bg": charcoalDark.surface,
369
445
  "--fairmint-color-success-bg": charcoalDark.successBg,
370
446
  "--fairmint-color-success-text": charcoalDark.successText,