@metamask-previews/design-system-react 0.24.0-preview.f5c2542 → 0.25.0-preview.1f40f69f

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 (172) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/dist/components/AvatarBase/AvatarBase.cjs +1 -1
  3. package/dist/components/AvatarBase/AvatarBase.cjs.map +1 -1
  4. package/dist/components/AvatarBase/AvatarBase.mjs +1 -1
  5. package/dist/components/AvatarBase/AvatarBase.mjs.map +1 -1
  6. package/dist/components/AvatarFavicon/AvatarFavicon.cjs +1 -1
  7. package/dist/components/AvatarFavicon/AvatarFavicon.cjs.map +1 -1
  8. package/dist/components/AvatarFavicon/AvatarFavicon.mjs +1 -1
  9. package/dist/components/AvatarFavicon/AvatarFavicon.mjs.map +1 -1
  10. package/dist/components/AvatarNetwork/AvatarNetwork.cjs +1 -1
  11. package/dist/components/AvatarNetwork/AvatarNetwork.cjs.map +1 -1
  12. package/dist/components/AvatarNetwork/AvatarNetwork.mjs +1 -1
  13. package/dist/components/AvatarNetwork/AvatarNetwork.mjs.map +1 -1
  14. package/dist/components/AvatarToken/AvatarToken.cjs +2 -2
  15. package/dist/components/AvatarToken/AvatarToken.cjs.map +1 -1
  16. package/dist/components/AvatarToken/AvatarToken.mjs +2 -2
  17. package/dist/components/AvatarToken/AvatarToken.mjs.map +1 -1
  18. package/dist/components/FormTextField/FormTextField.cjs +38 -0
  19. package/dist/components/FormTextField/FormTextField.cjs.map +1 -0
  20. package/dist/components/FormTextField/FormTextField.d.cts +4 -0
  21. package/dist/components/FormTextField/FormTextField.d.cts.map +1 -0
  22. package/dist/components/FormTextField/FormTextField.d.mts +4 -0
  23. package/dist/components/FormTextField/FormTextField.d.mts.map +1 -0
  24. package/dist/components/FormTextField/FormTextField.mjs +19 -0
  25. package/dist/components/FormTextField/FormTextField.mjs.map +1 -0
  26. package/dist/components/FormTextField/FormTextField.types.cjs +3 -0
  27. package/dist/components/FormTextField/FormTextField.types.cjs.map +1 -0
  28. package/dist/components/FormTextField/FormTextField.types.d.cts +50 -0
  29. package/dist/components/FormTextField/FormTextField.types.d.cts.map +1 -0
  30. package/dist/components/FormTextField/FormTextField.types.d.mts +50 -0
  31. package/dist/components/FormTextField/FormTextField.types.d.mts.map +1 -0
  32. package/dist/components/FormTextField/FormTextField.types.mjs +2 -0
  33. package/dist/components/FormTextField/FormTextField.types.mjs.map +1 -0
  34. package/dist/components/FormTextField/index.cjs +6 -0
  35. package/dist/components/FormTextField/index.cjs.map +1 -0
  36. package/dist/components/FormTextField/index.d.cts +3 -0
  37. package/dist/components/FormTextField/index.d.cts.map +1 -0
  38. package/dist/components/FormTextField/index.d.mts +3 -0
  39. package/dist/components/FormTextField/index.d.mts.map +1 -0
  40. package/dist/components/FormTextField/index.mjs +2 -0
  41. package/dist/components/FormTextField/index.mjs.map +1 -0
  42. package/dist/components/Popover/Popover.cjs +129 -0
  43. package/dist/components/Popover/Popover.cjs.map +1 -0
  44. package/dist/components/Popover/Popover.constants.cjs +28 -0
  45. package/dist/components/Popover/Popover.constants.cjs.map +1 -0
  46. package/dist/components/Popover/Popover.constants.d.cts +12 -0
  47. package/dist/components/Popover/Popover.constants.d.cts.map +1 -0
  48. package/dist/components/Popover/Popover.constants.d.mts +12 -0
  49. package/dist/components/Popover/Popover.constants.d.mts.map +1 -0
  50. package/dist/components/Popover/Popover.constants.mjs +25 -0
  51. package/dist/components/Popover/Popover.constants.mjs.map +1 -0
  52. package/dist/components/Popover/Popover.d.cts +4 -0
  53. package/dist/components/Popover/Popover.d.cts.map +1 -0
  54. package/dist/components/Popover/Popover.d.mts +4 -0
  55. package/dist/components/Popover/Popover.d.mts.map +1 -0
  56. package/dist/components/Popover/Popover.mjs +110 -0
  57. package/dist/components/Popover/Popover.mjs.map +1 -0
  58. package/dist/components/Popover/Popover.types.cjs +33 -0
  59. package/dist/components/Popover/Popover.types.cjs.map +1 -0
  60. package/dist/components/Popover/Popover.types.d.cts +128 -0
  61. package/dist/components/Popover/Popover.types.d.cts.map +1 -0
  62. package/dist/components/Popover/Popover.types.d.mts +128 -0
  63. package/dist/components/Popover/Popover.types.d.mts.map +1 -0
  64. package/dist/components/Popover/Popover.types.mjs +30 -0
  65. package/dist/components/Popover/Popover.types.mjs.map +1 -0
  66. package/dist/components/Popover/index.cjs +9 -0
  67. package/dist/components/Popover/index.cjs.map +1 -0
  68. package/dist/components/Popover/index.d.cts +4 -0
  69. package/dist/components/Popover/index.d.cts.map +1 -0
  70. package/dist/components/Popover/index.d.mts +4 -0
  71. package/dist/components/Popover/index.d.mts.map +1 -0
  72. package/dist/components/Popover/index.mjs +3 -0
  73. package/dist/components/Popover/index.mjs.map +1 -0
  74. package/dist/components/TextArea/TextArea.cjs +37 -0
  75. package/dist/components/TextArea/TextArea.cjs.map +1 -0
  76. package/dist/components/TextArea/TextArea.constants.cjs +35 -0
  77. package/dist/components/TextArea/TextArea.constants.cjs.map +1 -0
  78. package/dist/components/TextArea/TextArea.constants.d.cts +28 -0
  79. package/dist/components/TextArea/TextArea.constants.d.cts.map +1 -0
  80. package/dist/components/TextArea/TextArea.constants.d.mts +28 -0
  81. package/dist/components/TextArea/TextArea.constants.d.mts.map +1 -0
  82. package/dist/components/TextArea/TextArea.constants.mjs +32 -0
  83. package/dist/components/TextArea/TextArea.constants.mjs.map +1 -0
  84. package/dist/components/TextArea/TextArea.d.cts +9 -0
  85. package/dist/components/TextArea/TextArea.d.cts.map +1 -0
  86. package/dist/components/TextArea/TextArea.d.mts +9 -0
  87. package/dist/components/TextArea/TextArea.d.mts.map +1 -0
  88. package/dist/components/TextArea/TextArea.mjs +18 -0
  89. package/dist/components/TextArea/TextArea.mjs.map +1 -0
  90. package/dist/components/TextArea/TextArea.types.cjs +3 -0
  91. package/dist/components/TextArea/TextArea.types.cjs.map +1 -0
  92. package/dist/components/TextArea/TextArea.types.d.cts +33 -0
  93. package/dist/components/TextArea/TextArea.types.d.cts.map +1 -0
  94. package/dist/components/TextArea/TextArea.types.d.mts +33 -0
  95. package/dist/components/TextArea/TextArea.types.d.mts.map +1 -0
  96. package/dist/components/TextArea/TextArea.types.mjs +2 -0
  97. package/dist/components/TextArea/TextArea.types.mjs.map +1 -0
  98. package/dist/components/TextArea/index.cjs +8 -0
  99. package/dist/components/TextArea/index.cjs.map +1 -0
  100. package/dist/components/TextArea/index.d.cts +4 -0
  101. package/dist/components/TextArea/index.d.cts.map +1 -0
  102. package/dist/components/TextArea/index.d.mts +4 -0
  103. package/dist/components/TextArea/index.d.mts.map +1 -0
  104. package/dist/components/TextArea/index.mjs +3 -0
  105. package/dist/components/TextArea/index.mjs.map +1 -0
  106. package/dist/components/TextFieldSearch/TextFieldSearch.cjs +40 -0
  107. package/dist/components/TextFieldSearch/TextFieldSearch.cjs.map +1 -0
  108. package/dist/components/TextFieldSearch/TextFieldSearch.d.cts +6 -0
  109. package/dist/components/TextFieldSearch/TextFieldSearch.d.cts.map +1 -0
  110. package/dist/components/TextFieldSearch/TextFieldSearch.d.mts +6 -0
  111. package/dist/components/TextFieldSearch/TextFieldSearch.d.mts.map +1 -0
  112. package/dist/components/TextFieldSearch/TextFieldSearch.mjs +21 -0
  113. package/dist/components/TextFieldSearch/TextFieldSearch.mjs.map +1 -0
  114. package/dist/components/TextFieldSearch/TextFieldSearch.types.cjs +3 -0
  115. package/dist/components/TextFieldSearch/TextFieldSearch.types.cjs.map +1 -0
  116. package/dist/components/TextFieldSearch/TextFieldSearch.types.d.cts +17 -0
  117. package/dist/components/TextFieldSearch/TextFieldSearch.types.d.cts.map +1 -0
  118. package/dist/components/TextFieldSearch/TextFieldSearch.types.d.mts +17 -0
  119. package/dist/components/TextFieldSearch/TextFieldSearch.types.d.mts.map +1 -0
  120. package/dist/components/TextFieldSearch/TextFieldSearch.types.mjs +2 -0
  121. package/dist/components/TextFieldSearch/TextFieldSearch.types.mjs.map +1 -0
  122. package/dist/components/TextFieldSearch/index.cjs +6 -0
  123. package/dist/components/TextFieldSearch/index.cjs.map +1 -0
  124. package/dist/components/TextFieldSearch/index.d.cts +3 -0
  125. package/dist/components/TextFieldSearch/index.d.cts.map +1 -0
  126. package/dist/components/TextFieldSearch/index.d.mts +3 -0
  127. package/dist/components/TextFieldSearch/index.d.mts.map +1 -0
  128. package/dist/components/TextFieldSearch/index.mjs +2 -0
  129. package/dist/components/TextFieldSearch/index.mjs.map +1 -0
  130. package/dist/components/Toast/Toast.cjs +7 -1
  131. package/dist/components/Toast/Toast.cjs.map +1 -1
  132. package/dist/components/Toast/Toast.constants.cjs +6 -4
  133. package/dist/components/Toast/Toast.constants.cjs.map +1 -1
  134. package/dist/components/Toast/Toast.constants.d.cts +1 -3
  135. package/dist/components/Toast/Toast.constants.d.cts.map +1 -1
  136. package/dist/components/Toast/Toast.constants.d.mts +1 -3
  137. package/dist/components/Toast/Toast.constants.d.mts.map +1 -1
  138. package/dist/components/Toast/Toast.constants.mjs +3 -3
  139. package/dist/components/Toast/Toast.constants.mjs.map +1 -1
  140. package/dist/components/Toast/Toast.d.cts.map +1 -1
  141. package/dist/components/Toast/Toast.d.mts.map +1 -1
  142. package/dist/components/Toast/Toast.mjs +7 -1
  143. package/dist/components/Toast/Toast.mjs.map +1 -1
  144. package/dist/components/Toast/Toast.types.cjs.map +1 -1
  145. package/dist/components/Toast/Toast.types.d.cts +4 -0
  146. package/dist/components/Toast/Toast.types.d.cts.map +1 -1
  147. package/dist/components/Toast/Toast.types.d.mts +4 -0
  148. package/dist/components/Toast/Toast.types.d.mts.map +1 -1
  149. package/dist/components/Toast/Toast.types.mjs.map +1 -1
  150. package/dist/components/Toast/Toaster.cjs +124 -54
  151. package/dist/components/Toast/Toaster.cjs.map +1 -1
  152. package/dist/components/Toast/Toaster.d.cts.map +1 -1
  153. package/dist/components/Toast/Toaster.d.mts.map +1 -1
  154. package/dist/components/Toast/Toaster.mjs +125 -55
  155. package/dist/components/Toast/Toaster.mjs.map +1 -1
  156. package/dist/components/Toast/index.cjs +1 -4
  157. package/dist/components/Toast/index.cjs.map +1 -1
  158. package/dist/components/Toast/index.d.cts +1 -2
  159. package/dist/components/Toast/index.d.cts.map +1 -1
  160. package/dist/components/Toast/index.d.mts +1 -2
  161. package/dist/components/Toast/index.d.mts.map +1 -1
  162. package/dist/components/Toast/index.mjs +0 -1
  163. package/dist/components/Toast/index.mjs.map +1 -1
  164. package/dist/components/index.cjs +13 -4
  165. package/dist/components/index.cjs.map +1 -1
  166. package/dist/components/index.d.cts +9 -2
  167. package/dist/components/index.d.cts.map +1 -1
  168. package/dist/components/index.d.mts +9 -2
  169. package/dist/components/index.d.mts.map +1 -1
  170. package/dist/components/index.mjs +4 -1
  171. package/dist/components/index.mjs.map +1 -1
  172. package/package.json +6 -5
@@ -28,91 +28,161 @@ const react_1 = __importStar(require("react"));
28
28
  const tw_merge_1 = require("../../utils/tw-merge.cjs");
29
29
  const Toast_1 = require("./Toast.cjs");
30
30
  const Toast_constants_1 = require("./Toast.constants.cjs");
31
- let registeredRef = null;
32
- const assertRegisteredRef = (method) => {
33
- if (!registeredRef?.current) {
34
- const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;
35
- throw new Error(`${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`);
36
- }
37
- return registeredRef.current;
31
+ let storeToastOptions;
32
+ const toastStoreListeners = new Set();
33
+ const normalizeToastOptions = (options) => ({
34
+ hasNoTimeout: false,
35
+ ...options,
36
+ });
37
+ const emitToastStoreChange = () => {
38
+ toastStoreListeners.forEach((listener) => listener(storeToastOptions));
39
+ };
40
+ const setStoreToastOptions = (options) => {
41
+ storeToastOptions = normalizeToastOptions(options);
42
+ emitToastStoreChange();
43
+ };
44
+ const clearStoreToastOptions = () => {
45
+ storeToastOptions = undefined;
46
+ emitToastStoreChange();
47
+ };
48
+ const subscribeToToastStore = (listener) => {
49
+ toastStoreListeners.add(listener);
50
+ listener(storeToastOptions);
51
+ return () => {
52
+ toastStoreListeners.delete(listener);
53
+ };
38
54
  };
39
55
  const getToastProps = ({ hasNoTimeout: _hasNoTimeout, ...toastProps }) => toastProps;
40
56
  const ToasterComponent = (0, react_1.forwardRef)(({ className, ...props }, ref) => {
41
57
  const [toastOptions, setToastOptions] = (0, react_1.useState)(undefined);
58
+ const toastOptionsRef = (0, react_1.useRef)(undefined);
42
59
  const [isVisible, setIsVisible] = (0, react_1.useState)(false);
60
+ const isVisibleRef = (0, react_1.useRef)(false);
43
61
  const replacementTimerRef = (0, react_1.useRef)(null);
44
- const dismissTimerRef = (0, react_1.useRef)(null);
45
- const innerRef = (0, react_1.useRef)(null);
46
- const closeToast = () => {
62
+ const autoDismissTimerRef = (0, react_1.useRef)(null);
63
+ const exitTimerRef = (0, react_1.useRef)(null);
64
+ const enterAnimationFrameRef = (0, react_1.useRef)(null);
65
+ const pendingToastRef = (0, react_1.useRef)(undefined);
66
+ const setCurrentToastOptions = (0, react_1.useCallback)((options) => {
67
+ toastOptionsRef.current = options;
68
+ setToastOptions(options);
69
+ }, []);
70
+ const setCurrentIsVisible = (0, react_1.useCallback)((nextIsVisible) => {
71
+ isVisibleRef.current = nextIsVisible;
72
+ setIsVisible(nextIsVisible);
73
+ }, []);
74
+ const clearPendingTimers = (0, react_1.useCallback)(() => {
47
75
  if (replacementTimerRef.current !== null) {
48
76
  clearTimeout(replacementTimerRef.current);
49
77
  replacementTimerRef.current = null;
50
78
  }
51
- if (dismissTimerRef.current !== null) {
52
- clearTimeout(dismissTimerRef.current);
53
- dismissTimerRef.current = null;
79
+ if (autoDismissTimerRef.current !== null) {
80
+ clearTimeout(autoDismissTimerRef.current);
81
+ autoDismissTimerRef.current = null;
82
+ }
83
+ if (exitTimerRef.current !== null) {
84
+ clearTimeout(exitTimerRef.current);
85
+ exitTimerRef.current = null;
86
+ }
87
+ if (enterAnimationFrameRef.current !== null) {
88
+ cancelAnimationFrame(enterAnimationFrameRef.current);
89
+ enterAnimationFrameRef.current = null;
90
+ }
91
+ }, []);
92
+ const closeRenderedToast = (0, react_1.useCallback)(() => {
93
+ if (!toastOptionsRef.current && !isVisibleRef.current) {
94
+ clearPendingTimers();
95
+ pendingToastRef.current = undefined;
96
+ return;
54
97
  }
55
- setIsVisible(false);
56
- dismissTimerRef.current = setTimeout(() => {
57
- dismissTimerRef.current = null;
58
- setToastOptions(undefined);
98
+ clearPendingTimers();
99
+ pendingToastRef.current = undefined;
100
+ setCurrentIsVisible(false);
101
+ exitTimerRef.current = setTimeout(() => {
102
+ exitTimerRef.current = null;
103
+ setCurrentToastOptions(undefined);
59
104
  }, Toast_constants_1.TOAST_ANIMATION_DURATION);
60
- };
61
- const showToast = (options) => {
62
- const normalizedOptions = { hasNoTimeout: false, ...options };
63
- let timeoutDuration = 0;
64
- if (toastOptions) {
65
- setIsVisible(false);
66
- if (dismissTimerRef.current !== null) {
67
- clearTimeout(dismissTimerRef.current);
68
- dismissTimerRef.current = null;
105
+ }, [clearPendingTimers, setCurrentIsVisible, setCurrentToastOptions]);
106
+ // Replace the currently mounted toast rather than queueing multiple toasts.
107
+ // This mirrors the old app-level toast service behavior while keeping the
108
+ // imperative API centered in the shared single-toast store.
109
+ const showRenderedToast = (0, react_1.useCallback)((options) => {
110
+ const normalizedOptions = normalizeToastOptions(options);
111
+ const timeoutDuration = 0;
112
+ if (toastOptionsRef.current) {
113
+ pendingToastRef.current = normalizedOptions;
114
+ setCurrentIsVisible(false);
115
+ if (exitTimerRef.current !== null) {
116
+ clearTimeout(exitTimerRef.current);
117
+ exitTimerRef.current = null;
69
118
  }
70
- timeoutDuration = Toast_constants_1.TOAST_ANIMATION_DURATION;
71
- setToastOptions(undefined);
119
+ exitTimerRef.current = setTimeout(() => {
120
+ exitTimerRef.current = null;
121
+ setCurrentToastOptions(pendingToastRef.current);
122
+ pendingToastRef.current = undefined;
123
+ }, Toast_constants_1.TOAST_ANIMATION_DURATION);
124
+ return;
72
125
  }
73
126
  if (replacementTimerRef.current !== null) {
74
127
  clearTimeout(replacementTimerRef.current);
75
128
  }
76
129
  replacementTimerRef.current = setTimeout(() => {
77
130
  replacementTimerRef.current = null;
78
- setToastOptions(normalizedOptions);
131
+ setCurrentToastOptions(normalizedOptions);
79
132
  }, timeoutDuration);
80
- };
81
- innerRef.current = { closeToast, showToast };
82
- (0, react_1.useImperativeHandle)(ref, () => innerRef.current);
133
+ }, [setCurrentIsVisible, setCurrentToastOptions]);
134
+ (0, react_1.useImperativeHandle)(ref, () => ({
135
+ closeToast: clearStoreToastOptions,
136
+ showToast: setStoreToastOptions,
137
+ }), []);
138
+ // Subscribe before sibling passive effects run so toast() can be called
139
+ // from anywhere once the app root has rendered <Toaster />.
83
140
  (0, react_1.useLayoutEffect)(() => {
84
- registeredRef = innerRef;
85
- return () => {
86
- if (registeredRef === innerRef) {
87
- registeredRef = null;
141
+ return subscribeToToastStore((options) => {
142
+ if (options) {
143
+ showRenderedToast(options);
144
+ return;
88
145
  }
89
- };
90
- }, []);
91
- // Trigger enter animation after toast is mounted in the DOM.
146
+ closeRenderedToast();
147
+ });
148
+ }, [closeRenderedToast, showRenderedToast]);
149
+ // Delay the enter transition until after mount so the DOM can paint the
150
+ // offscreen starting position before we slide the toast into view.
92
151
  (0, react_1.useEffect)(() => {
93
152
  if (toastOptions && !isVisible) {
94
- requestAnimationFrame(() => {
95
- requestAnimationFrame(() => {
96
- setIsVisible(true);
153
+ enterAnimationFrameRef.current = requestAnimationFrame(() => {
154
+ enterAnimationFrameRef.current = requestAnimationFrame(() => {
155
+ setCurrentIsVisible(true);
156
+ enterAnimationFrameRef.current = null;
97
157
  });
98
158
  });
99
159
  }
100
- }, [toastOptions]); // intentionally omit isVisible — only react to new toast options
101
- // Auto-dismiss timer.
160
+ return () => {
161
+ clearPendingTimers();
162
+ };
163
+ }, [clearPendingTimers, setCurrentIsVisible, toastOptions]); // intentionally omit isVisible — only react to new toast options
164
+ // Auto-dismiss once the toast is visible, unless the caller requested a
165
+ // persistent toast.
102
166
  (0, react_1.useEffect)(() => {
103
167
  if (isVisible && toastOptions && !toastOptions.hasNoTimeout) {
104
- dismissTimerRef.current = setTimeout(() => {
105
- dismissTimerRef.current = null;
106
- innerRef.current?.closeToast();
168
+ autoDismissTimerRef.current = setTimeout(() => {
169
+ autoDismissTimerRef.current = null;
170
+ clearStoreToastOptions();
107
171
  }, Toast_constants_1.TOAST_VISIBILITY_DURATION);
108
172
  return () => {
109
- if (dismissTimerRef.current !== null) {
110
- clearTimeout(dismissTimerRef.current);
111
- }
173
+ clearPendingTimers();
112
174
  };
113
175
  }
114
176
  return undefined;
115
- }, [isVisible]); // intentionally omit toastOptions — timer fires once per visibility change
177
+ }, [clearPendingTimers, isVisible, toastOptions]);
178
+ (0, react_1.useEffect)(() => {
179
+ return () => {
180
+ clearPendingTimers();
181
+ pendingToastRef.current = undefined;
182
+ toastOptionsRef.current = undefined;
183
+ isVisibleRef.current = false;
184
+ };
185
+ }, [clearPendingTimers]);
116
186
  if (!toastOptions) {
117
187
  return null;
118
188
  }
@@ -125,16 +195,16 @@ const ToasterComponent = (0, react_1.forwardRef)(({ className, ...props }, ref)
125
195
  : 'translateY(calc(100% + 16px))',
126
196
  } },
127
197
  react_1.default.createElement(Toast_1.Toast, { ...toastProps, className: toastClassName, onClose: () => {
128
- closeToast();
198
+ clearStoreToastOptions();
129
199
  toastOnClose?.();
130
200
  } }))));
131
201
  });
132
202
  ToasterComponent.displayName = 'Toaster';
133
203
  exports.Toaster = ToasterComponent;
134
204
  exports.toast = ((options) => {
135
- assertRegisteredRef('toast').showToast(options);
205
+ setStoreToastOptions(options);
136
206
  });
137
207
  exports.toast.dismiss = () => {
138
- assertRegisteredRef('dismiss').closeToast();
208
+ clearStoreToastOptions();
139
209
  };
140
210
  //# sourceMappingURL=Toaster.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.cjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport type { RefObject } from 'react';\n\nimport { twMerge } from '../../utils/tw-merge';\n\nimport { Toast } from './Toast';\nimport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\nlet registeredRef: RefObject<ToasterRef | null> | null = null;\n\nconst assertRegisteredRef = (method: 'dismiss' | 'toast'): ToasterRef => {\n if (!registeredRef?.current) {\n const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;\n throw new Error(\n `${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`,\n );\n }\n return registeredRef.current;\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n ...toastProps\n}: ToastOptions): ToastProps => toastProps;\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ className, ...props }, ref) => {\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const [isVisible, setIsVisible] = useState(false);\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const dismissTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const innerRef = useRef<ToasterRef | null>(null);\n\n const closeToast = () => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n if (dismissTimerRef.current !== null) {\n clearTimeout(dismissTimerRef.current);\n dismissTimerRef.current = null;\n }\n setIsVisible(false);\n dismissTimerRef.current = setTimeout(() => {\n dismissTimerRef.current = null;\n setToastOptions(undefined);\n }, TOAST_ANIMATION_DURATION);\n };\n\n const showToast = (options: ToastOptions) => {\n const normalizedOptions = { hasNoTimeout: false, ...options };\n let timeoutDuration = 0;\n\n if (toastOptions) {\n setIsVisible(false);\n if (dismissTimerRef.current !== null) {\n clearTimeout(dismissTimerRef.current);\n dismissTimerRef.current = null;\n }\n timeoutDuration = TOAST_ANIMATION_DURATION;\n setToastOptions(undefined);\n }\n\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setToastOptions(normalizedOptions);\n }, timeoutDuration);\n };\n\n innerRef.current = { closeToast, showToast };\n\n useImperativeHandle(ref, () => innerRef.current as ToasterRef);\n\n useLayoutEffect(() => {\n registeredRef = innerRef;\n return () => {\n if (registeredRef === innerRef) {\n registeredRef = null;\n }\n };\n }, []);\n\n // Trigger enter animation after toast is mounted in the DOM.\n useEffect(() => {\n if (toastOptions && !isVisible) {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setIsVisible(true);\n });\n });\n }\n }, [toastOptions]); // intentionally omit isVisible — only react to new toast options\n\n // Auto-dismiss timer.\n useEffect(() => {\n if (isVisible && toastOptions && !toastOptions.hasNoTimeout) {\n dismissTimerRef.current = setTimeout(() => {\n dismissTimerRef.current = null;\n innerRef.current?.closeToast();\n }, TOAST_VISIBILITY_DURATION);\n return () => {\n if (dismissTimerRef.current !== null) {\n clearTimeout(dismissTimerRef.current);\n }\n };\n }\n return undefined;\n }, [isVisible]); // intentionally omit toastOptions — timer fires once per visibility change\n\n if (!toastOptions) {\n return null;\n }\n\n const {\n onClose: toastOnClose,\n className: toastClassName,\n ...toastProps\n } = getToastProps(toastOptions);\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={twMerge(\n 'pointer-events-none fixed inset-x-4 bottom-4 z-[1000] flex justify-center',\n className,\n )}\n {...props}\n >\n <div\n className=\"pointer-events-auto w-full transition-transform ease-in-out\"\n style={{\n transitionDuration: `${TOAST_ANIMATION_DURATION}ms`,\n transform: isVisible\n ? 'translateY(0)'\n : 'translateY(calc(100% + 16px))',\n }}\n >\n <Toast\n {...toastProps}\n className={toastClassName}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n />\n </div>\n </div>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n assertRegisteredRef('toast').showToast(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n assertRegisteredRef('dismiss').closeToast();\n};\n"]}
1
+ {"version":3,"file":"Toaster.cjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { twMerge } from '../../utils/tw-merge';\n\nimport { Toast } from './Toast';\nimport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\ntype ToastStoreListener = (options: ToastOptions | undefined) => void;\n\nlet storeToastOptions: ToastOptions | undefined;\nconst toastStoreListeners = new Set<ToastStoreListener>();\n\nconst normalizeToastOptions = (options: ToastOptions): ToastOptions => ({\n hasNoTimeout: false,\n ...options,\n});\n\nconst emitToastStoreChange = () => {\n toastStoreListeners.forEach((listener) => listener(storeToastOptions));\n};\n\nconst setStoreToastOptions = (options: ToastOptions) => {\n storeToastOptions = normalizeToastOptions(options);\n emitToastStoreChange();\n};\n\nconst clearStoreToastOptions = () => {\n storeToastOptions = undefined;\n emitToastStoreChange();\n};\n\nconst subscribeToToastStore = (listener: ToastStoreListener) => {\n toastStoreListeners.add(listener);\n listener(storeToastOptions);\n\n return () => {\n toastStoreListeners.delete(listener);\n };\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n ...toastProps\n}: ToastOptions): ToastProps => toastProps;\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ className, ...props }, ref) => {\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const toastOptionsRef = useRef<ToastOptions | undefined>(undefined);\n const [isVisible, setIsVisible] = useState(false);\n const isVisibleRef = useRef(false);\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const autoDismissTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const exitTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const enterAnimationFrameRef = useRef<number | null>(null);\n const pendingToastRef = useRef<ToastOptions | undefined>(undefined);\n\n const setCurrentToastOptions = useCallback(\n (options: ToastOptions | undefined) => {\n toastOptionsRef.current = options;\n setToastOptions(options);\n },\n [],\n );\n\n const setCurrentIsVisible = useCallback((nextIsVisible: boolean) => {\n isVisibleRef.current = nextIsVisible;\n setIsVisible(nextIsVisible);\n }, []);\n\n const clearPendingTimers = useCallback(() => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n if (autoDismissTimerRef.current !== null) {\n clearTimeout(autoDismissTimerRef.current);\n autoDismissTimerRef.current = null;\n }\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n if (enterAnimationFrameRef.current !== null) {\n cancelAnimationFrame(enterAnimationFrameRef.current);\n enterAnimationFrameRef.current = null;\n }\n }, []);\n\n const closeRenderedToast = useCallback(() => {\n if (!toastOptionsRef.current && !isVisibleRef.current) {\n clearPendingTimers();\n pendingToastRef.current = undefined;\n return;\n }\n\n clearPendingTimers();\n pendingToastRef.current = undefined;\n setCurrentIsVisible(false);\n exitTimerRef.current = setTimeout(() => {\n exitTimerRef.current = null;\n setCurrentToastOptions(undefined);\n }, TOAST_ANIMATION_DURATION);\n }, [clearPendingTimers, setCurrentIsVisible, setCurrentToastOptions]);\n\n // Replace the currently mounted toast rather than queueing multiple toasts.\n // This mirrors the old app-level toast service behavior while keeping the\n // imperative API centered in the shared single-toast store.\n const showRenderedToast = useCallback(\n (options: ToastOptions) => {\n const normalizedOptions = normalizeToastOptions(options);\n const timeoutDuration = 0;\n\n if (toastOptionsRef.current) {\n pendingToastRef.current = normalizedOptions;\n setCurrentIsVisible(false);\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n exitTimerRef.current = setTimeout(() => {\n exitTimerRef.current = null;\n setCurrentToastOptions(pendingToastRef.current);\n pendingToastRef.current = undefined;\n }, TOAST_ANIMATION_DURATION);\n return;\n }\n\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setCurrentToastOptions(normalizedOptions);\n }, timeoutDuration);\n },\n [setCurrentIsVisible, setCurrentToastOptions],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n closeToast: clearStoreToastOptions,\n showToast: setStoreToastOptions,\n }),\n [],\n );\n\n // Subscribe before sibling passive effects run so toast() can be called\n // from anywhere once the app root has rendered <Toaster />.\n useLayoutEffect(() => {\n return subscribeToToastStore((options) => {\n if (options) {\n showRenderedToast(options);\n return;\n }\n\n closeRenderedToast();\n });\n }, [closeRenderedToast, showRenderedToast]);\n\n // Delay the enter transition until after mount so the DOM can paint the\n // offscreen starting position before we slide the toast into view.\n useEffect(() => {\n if (toastOptions && !isVisible) {\n enterAnimationFrameRef.current = requestAnimationFrame(() => {\n enterAnimationFrameRef.current = requestAnimationFrame(() => {\n setCurrentIsVisible(true);\n enterAnimationFrameRef.current = null;\n });\n });\n }\n return () => {\n clearPendingTimers();\n };\n }, [clearPendingTimers, setCurrentIsVisible, toastOptions]); // intentionally omit isVisible — only react to new toast options\n\n // Auto-dismiss once the toast is visible, unless the caller requested a\n // persistent toast.\n useEffect(() => {\n if (isVisible && toastOptions && !toastOptions.hasNoTimeout) {\n autoDismissTimerRef.current = setTimeout(() => {\n autoDismissTimerRef.current = null;\n clearStoreToastOptions();\n }, TOAST_VISIBILITY_DURATION);\n return () => {\n clearPendingTimers();\n };\n }\n return undefined;\n }, [clearPendingTimers, isVisible, toastOptions]);\n\n useEffect(() => {\n return () => {\n clearPendingTimers();\n pendingToastRef.current = undefined;\n toastOptionsRef.current = undefined;\n isVisibleRef.current = false;\n };\n }, [clearPendingTimers]);\n\n if (!toastOptions) {\n return null;\n }\n\n const {\n onClose: toastOnClose,\n className: toastClassName,\n ...toastProps\n } = getToastProps(toastOptions);\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={twMerge(\n 'pointer-events-none fixed inset-x-4 bottom-4 z-[1000] flex justify-center',\n className,\n )}\n {...props}\n >\n <div\n className=\"pointer-events-auto w-full transition-transform ease-in-out\"\n style={{\n transitionDuration: `${TOAST_ANIMATION_DURATION}ms`,\n transform: isVisible\n ? 'translateY(0)'\n : 'translateY(calc(100% + 16px))',\n }}\n >\n <Toast\n {...toastProps}\n className={toastClassName}\n onClose={() => {\n clearStoreToastOptions();\n toastOnClose?.();\n }}\n />\n </div>\n </div>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n setStoreToastOptions(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n clearStoreToastOptions();\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.d.cts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,cAAc;AAUf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AA6JvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;0FAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
1
+ {"version":3,"file":"Toaster.d.cts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,cAAc;AASf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AAyPvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;0FAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.d.mts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,cAAc;AAUf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AA6JvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;0FAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
1
+ {"version":3,"file":"Toaster.d.mts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,cAAc;AASf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AAyPvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;0FAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
@@ -4,96 +4,166 @@ function $importDefault(module) {
4
4
  }
5
5
  return module;
6
6
  }
7
- import $React, { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
7
+ import $React, { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
8
8
  const React = $importDefault($React);
9
9
  import { twMerge } from "../../utils/tw-merge.mjs";
10
10
  import { Toast } from "./Toast.mjs";
11
11
  import { TOAST_ANIMATION_DURATION, TOAST_VISIBILITY_DURATION } from "./Toast.constants.mjs";
12
- let registeredRef = null;
13
- const assertRegisteredRef = (method) => {
14
- if (!registeredRef?.current) {
15
- const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;
16
- throw new Error(`${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`);
17
- }
18
- return registeredRef.current;
12
+ let storeToastOptions;
13
+ const toastStoreListeners = new Set();
14
+ const normalizeToastOptions = (options) => ({
15
+ hasNoTimeout: false,
16
+ ...options,
17
+ });
18
+ const emitToastStoreChange = () => {
19
+ toastStoreListeners.forEach((listener) => listener(storeToastOptions));
20
+ };
21
+ const setStoreToastOptions = (options) => {
22
+ storeToastOptions = normalizeToastOptions(options);
23
+ emitToastStoreChange();
24
+ };
25
+ const clearStoreToastOptions = () => {
26
+ storeToastOptions = undefined;
27
+ emitToastStoreChange();
28
+ };
29
+ const subscribeToToastStore = (listener) => {
30
+ toastStoreListeners.add(listener);
31
+ listener(storeToastOptions);
32
+ return () => {
33
+ toastStoreListeners.delete(listener);
34
+ };
19
35
  };
20
36
  const getToastProps = ({ hasNoTimeout: _hasNoTimeout, ...toastProps }) => toastProps;
21
37
  const ToasterComponent = forwardRef(({ className, ...props }, ref) => {
22
38
  const [toastOptions, setToastOptions] = useState(undefined);
39
+ const toastOptionsRef = useRef(undefined);
23
40
  const [isVisible, setIsVisible] = useState(false);
41
+ const isVisibleRef = useRef(false);
24
42
  const replacementTimerRef = useRef(null);
25
- const dismissTimerRef = useRef(null);
26
- const innerRef = useRef(null);
27
- const closeToast = () => {
43
+ const autoDismissTimerRef = useRef(null);
44
+ const exitTimerRef = useRef(null);
45
+ const enterAnimationFrameRef = useRef(null);
46
+ const pendingToastRef = useRef(undefined);
47
+ const setCurrentToastOptions = useCallback((options) => {
48
+ toastOptionsRef.current = options;
49
+ setToastOptions(options);
50
+ }, []);
51
+ const setCurrentIsVisible = useCallback((nextIsVisible) => {
52
+ isVisibleRef.current = nextIsVisible;
53
+ setIsVisible(nextIsVisible);
54
+ }, []);
55
+ const clearPendingTimers = useCallback(() => {
28
56
  if (replacementTimerRef.current !== null) {
29
57
  clearTimeout(replacementTimerRef.current);
30
58
  replacementTimerRef.current = null;
31
59
  }
32
- if (dismissTimerRef.current !== null) {
33
- clearTimeout(dismissTimerRef.current);
34
- dismissTimerRef.current = null;
60
+ if (autoDismissTimerRef.current !== null) {
61
+ clearTimeout(autoDismissTimerRef.current);
62
+ autoDismissTimerRef.current = null;
63
+ }
64
+ if (exitTimerRef.current !== null) {
65
+ clearTimeout(exitTimerRef.current);
66
+ exitTimerRef.current = null;
67
+ }
68
+ if (enterAnimationFrameRef.current !== null) {
69
+ cancelAnimationFrame(enterAnimationFrameRef.current);
70
+ enterAnimationFrameRef.current = null;
71
+ }
72
+ }, []);
73
+ const closeRenderedToast = useCallback(() => {
74
+ if (!toastOptionsRef.current && !isVisibleRef.current) {
75
+ clearPendingTimers();
76
+ pendingToastRef.current = undefined;
77
+ return;
35
78
  }
36
- setIsVisible(false);
37
- dismissTimerRef.current = setTimeout(() => {
38
- dismissTimerRef.current = null;
39
- setToastOptions(undefined);
79
+ clearPendingTimers();
80
+ pendingToastRef.current = undefined;
81
+ setCurrentIsVisible(false);
82
+ exitTimerRef.current = setTimeout(() => {
83
+ exitTimerRef.current = null;
84
+ setCurrentToastOptions(undefined);
40
85
  }, TOAST_ANIMATION_DURATION);
41
- };
42
- const showToast = (options) => {
43
- const normalizedOptions = { hasNoTimeout: false, ...options };
44
- let timeoutDuration = 0;
45
- if (toastOptions) {
46
- setIsVisible(false);
47
- if (dismissTimerRef.current !== null) {
48
- clearTimeout(dismissTimerRef.current);
49
- dismissTimerRef.current = null;
86
+ }, [clearPendingTimers, setCurrentIsVisible, setCurrentToastOptions]);
87
+ // Replace the currently mounted toast rather than queueing multiple toasts.
88
+ // This mirrors the old app-level toast service behavior while keeping the
89
+ // imperative API centered in the shared single-toast store.
90
+ const showRenderedToast = useCallback((options) => {
91
+ const normalizedOptions = normalizeToastOptions(options);
92
+ const timeoutDuration = 0;
93
+ if (toastOptionsRef.current) {
94
+ pendingToastRef.current = normalizedOptions;
95
+ setCurrentIsVisible(false);
96
+ if (exitTimerRef.current !== null) {
97
+ clearTimeout(exitTimerRef.current);
98
+ exitTimerRef.current = null;
50
99
  }
51
- timeoutDuration = TOAST_ANIMATION_DURATION;
52
- setToastOptions(undefined);
100
+ exitTimerRef.current = setTimeout(() => {
101
+ exitTimerRef.current = null;
102
+ setCurrentToastOptions(pendingToastRef.current);
103
+ pendingToastRef.current = undefined;
104
+ }, TOAST_ANIMATION_DURATION);
105
+ return;
53
106
  }
54
107
  if (replacementTimerRef.current !== null) {
55
108
  clearTimeout(replacementTimerRef.current);
56
109
  }
57
110
  replacementTimerRef.current = setTimeout(() => {
58
111
  replacementTimerRef.current = null;
59
- setToastOptions(normalizedOptions);
112
+ setCurrentToastOptions(normalizedOptions);
60
113
  }, timeoutDuration);
61
- };
62
- innerRef.current = { closeToast, showToast };
63
- useImperativeHandle(ref, () => innerRef.current);
114
+ }, [setCurrentIsVisible, setCurrentToastOptions]);
115
+ useImperativeHandle(ref, () => ({
116
+ closeToast: clearStoreToastOptions,
117
+ showToast: setStoreToastOptions,
118
+ }), []);
119
+ // Subscribe before sibling passive effects run so toast() can be called
120
+ // from anywhere once the app root has rendered <Toaster />.
64
121
  useLayoutEffect(() => {
65
- registeredRef = innerRef;
66
- return () => {
67
- if (registeredRef === innerRef) {
68
- registeredRef = null;
122
+ return subscribeToToastStore((options) => {
123
+ if (options) {
124
+ showRenderedToast(options);
125
+ return;
69
126
  }
70
- };
71
- }, []);
72
- // Trigger enter animation after toast is mounted in the DOM.
127
+ closeRenderedToast();
128
+ });
129
+ }, [closeRenderedToast, showRenderedToast]);
130
+ // Delay the enter transition until after mount so the DOM can paint the
131
+ // offscreen starting position before we slide the toast into view.
73
132
  useEffect(() => {
74
133
  if (toastOptions && !isVisible) {
75
- requestAnimationFrame(() => {
76
- requestAnimationFrame(() => {
77
- setIsVisible(true);
134
+ enterAnimationFrameRef.current = requestAnimationFrame(() => {
135
+ enterAnimationFrameRef.current = requestAnimationFrame(() => {
136
+ setCurrentIsVisible(true);
137
+ enterAnimationFrameRef.current = null;
78
138
  });
79
139
  });
80
140
  }
81
- }, [toastOptions]); // intentionally omit isVisible — only react to new toast options
82
- // Auto-dismiss timer.
141
+ return () => {
142
+ clearPendingTimers();
143
+ };
144
+ }, [clearPendingTimers, setCurrentIsVisible, toastOptions]); // intentionally omit isVisible — only react to new toast options
145
+ // Auto-dismiss once the toast is visible, unless the caller requested a
146
+ // persistent toast.
83
147
  useEffect(() => {
84
148
  if (isVisible && toastOptions && !toastOptions.hasNoTimeout) {
85
- dismissTimerRef.current = setTimeout(() => {
86
- dismissTimerRef.current = null;
87
- innerRef.current?.closeToast();
149
+ autoDismissTimerRef.current = setTimeout(() => {
150
+ autoDismissTimerRef.current = null;
151
+ clearStoreToastOptions();
88
152
  }, TOAST_VISIBILITY_DURATION);
89
153
  return () => {
90
- if (dismissTimerRef.current !== null) {
91
- clearTimeout(dismissTimerRef.current);
92
- }
154
+ clearPendingTimers();
93
155
  };
94
156
  }
95
157
  return undefined;
96
- }, [isVisible]); // intentionally omit toastOptions — timer fires once per visibility change
158
+ }, [clearPendingTimers, isVisible, toastOptions]);
159
+ useEffect(() => {
160
+ return () => {
161
+ clearPendingTimers();
162
+ pendingToastRef.current = undefined;
163
+ toastOptionsRef.current = undefined;
164
+ isVisibleRef.current = false;
165
+ };
166
+ }, [clearPendingTimers]);
97
167
  if (!toastOptions) {
98
168
  return null;
99
169
  }
@@ -106,16 +176,16 @@ const ToasterComponent = forwardRef(({ className, ...props }, ref) => {
106
176
  : 'translateY(calc(100% + 16px))',
107
177
  } },
108
178
  React.createElement(Toast, { ...toastProps, className: toastClassName, onClose: () => {
109
- closeToast();
179
+ clearStoreToastOptions();
110
180
  toastOnClose?.();
111
181
  } }))));
112
182
  });
113
183
  ToasterComponent.displayName = 'Toaster';
114
184
  export const Toaster = ToasterComponent;
115
185
  export const toast = ((options) => {
116
- assertRegisteredRef('toast').showToast(options);
186
+ setStoreToastOptions(options);
117
187
  });
118
188
  toast.dismiss = () => {
119
- assertRegisteredRef('dismiss').closeToast();
189
+ clearStoreToastOptions();
120
190
  };
121
191
  //# sourceMappingURL=Toaster.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.mjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport type { RefObject } from 'react';\n\nimport { twMerge } from '../../utils/tw-merge';\n\nimport { Toast } from './Toast';\nimport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\nlet registeredRef: RefObject<ToasterRef | null> | null = null;\n\nconst assertRegisteredRef = (method: 'dismiss' | 'toast'): ToasterRef => {\n if (!registeredRef?.current) {\n const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;\n throw new Error(\n `${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`,\n );\n }\n return registeredRef.current;\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n ...toastProps\n}: ToastOptions): ToastProps => toastProps;\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ className, ...props }, ref) => {\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const [isVisible, setIsVisible] = useState(false);\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const dismissTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const innerRef = useRef<ToasterRef | null>(null);\n\n const closeToast = () => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n if (dismissTimerRef.current !== null) {\n clearTimeout(dismissTimerRef.current);\n dismissTimerRef.current = null;\n }\n setIsVisible(false);\n dismissTimerRef.current = setTimeout(() => {\n dismissTimerRef.current = null;\n setToastOptions(undefined);\n }, TOAST_ANIMATION_DURATION);\n };\n\n const showToast = (options: ToastOptions) => {\n const normalizedOptions = { hasNoTimeout: false, ...options };\n let timeoutDuration = 0;\n\n if (toastOptions) {\n setIsVisible(false);\n if (dismissTimerRef.current !== null) {\n clearTimeout(dismissTimerRef.current);\n dismissTimerRef.current = null;\n }\n timeoutDuration = TOAST_ANIMATION_DURATION;\n setToastOptions(undefined);\n }\n\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setToastOptions(normalizedOptions);\n }, timeoutDuration);\n };\n\n innerRef.current = { closeToast, showToast };\n\n useImperativeHandle(ref, () => innerRef.current as ToasterRef);\n\n useLayoutEffect(() => {\n registeredRef = innerRef;\n return () => {\n if (registeredRef === innerRef) {\n registeredRef = null;\n }\n };\n }, []);\n\n // Trigger enter animation after toast is mounted in the DOM.\n useEffect(() => {\n if (toastOptions && !isVisible) {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setIsVisible(true);\n });\n });\n }\n }, [toastOptions]); // intentionally omit isVisible — only react to new toast options\n\n // Auto-dismiss timer.\n useEffect(() => {\n if (isVisible && toastOptions && !toastOptions.hasNoTimeout) {\n dismissTimerRef.current = setTimeout(() => {\n dismissTimerRef.current = null;\n innerRef.current?.closeToast();\n }, TOAST_VISIBILITY_DURATION);\n return () => {\n if (dismissTimerRef.current !== null) {\n clearTimeout(dismissTimerRef.current);\n }\n };\n }\n return undefined;\n }, [isVisible]); // intentionally omit toastOptions — timer fires once per visibility change\n\n if (!toastOptions) {\n return null;\n }\n\n const {\n onClose: toastOnClose,\n className: toastClassName,\n ...toastProps\n } = getToastProps(toastOptions);\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={twMerge(\n 'pointer-events-none fixed inset-x-4 bottom-4 z-[1000] flex justify-center',\n className,\n )}\n {...props}\n >\n <div\n className=\"pointer-events-auto w-full transition-transform ease-in-out\"\n style={{\n transitionDuration: `${TOAST_ANIMATION_DURATION}ms`,\n transform: isVisible\n ? 'translateY(0)'\n : 'translateY(calc(100% + 16px))',\n }}\n >\n <Toast\n {...toastProps}\n className={toastClassName}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n />\n </div>\n </div>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n assertRegisteredRef('toast').showToast(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n assertRegisteredRef('dismiss').closeToast();\n};\n"]}
1
+ {"version":3,"file":"Toaster.mjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { twMerge } from '../../utils/tw-merge';\n\nimport { Toast } from './Toast';\nimport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\ntype ToastStoreListener = (options: ToastOptions | undefined) => void;\n\nlet storeToastOptions: ToastOptions | undefined;\nconst toastStoreListeners = new Set<ToastStoreListener>();\n\nconst normalizeToastOptions = (options: ToastOptions): ToastOptions => ({\n hasNoTimeout: false,\n ...options,\n});\n\nconst emitToastStoreChange = () => {\n toastStoreListeners.forEach((listener) => listener(storeToastOptions));\n};\n\nconst setStoreToastOptions = (options: ToastOptions) => {\n storeToastOptions = normalizeToastOptions(options);\n emitToastStoreChange();\n};\n\nconst clearStoreToastOptions = () => {\n storeToastOptions = undefined;\n emitToastStoreChange();\n};\n\nconst subscribeToToastStore = (listener: ToastStoreListener) => {\n toastStoreListeners.add(listener);\n listener(storeToastOptions);\n\n return () => {\n toastStoreListeners.delete(listener);\n };\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n ...toastProps\n}: ToastOptions): ToastProps => toastProps;\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ className, ...props }, ref) => {\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const toastOptionsRef = useRef<ToastOptions | undefined>(undefined);\n const [isVisible, setIsVisible] = useState(false);\n const isVisibleRef = useRef(false);\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const autoDismissTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const exitTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const enterAnimationFrameRef = useRef<number | null>(null);\n const pendingToastRef = useRef<ToastOptions | undefined>(undefined);\n\n const setCurrentToastOptions = useCallback(\n (options: ToastOptions | undefined) => {\n toastOptionsRef.current = options;\n setToastOptions(options);\n },\n [],\n );\n\n const setCurrentIsVisible = useCallback((nextIsVisible: boolean) => {\n isVisibleRef.current = nextIsVisible;\n setIsVisible(nextIsVisible);\n }, []);\n\n const clearPendingTimers = useCallback(() => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n if (autoDismissTimerRef.current !== null) {\n clearTimeout(autoDismissTimerRef.current);\n autoDismissTimerRef.current = null;\n }\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n if (enterAnimationFrameRef.current !== null) {\n cancelAnimationFrame(enterAnimationFrameRef.current);\n enterAnimationFrameRef.current = null;\n }\n }, []);\n\n const closeRenderedToast = useCallback(() => {\n if (!toastOptionsRef.current && !isVisibleRef.current) {\n clearPendingTimers();\n pendingToastRef.current = undefined;\n return;\n }\n\n clearPendingTimers();\n pendingToastRef.current = undefined;\n setCurrentIsVisible(false);\n exitTimerRef.current = setTimeout(() => {\n exitTimerRef.current = null;\n setCurrentToastOptions(undefined);\n }, TOAST_ANIMATION_DURATION);\n }, [clearPendingTimers, setCurrentIsVisible, setCurrentToastOptions]);\n\n // Replace the currently mounted toast rather than queueing multiple toasts.\n // This mirrors the old app-level toast service behavior while keeping the\n // imperative API centered in the shared single-toast store.\n const showRenderedToast = useCallback(\n (options: ToastOptions) => {\n const normalizedOptions = normalizeToastOptions(options);\n const timeoutDuration = 0;\n\n if (toastOptionsRef.current) {\n pendingToastRef.current = normalizedOptions;\n setCurrentIsVisible(false);\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n exitTimerRef.current = setTimeout(() => {\n exitTimerRef.current = null;\n setCurrentToastOptions(pendingToastRef.current);\n pendingToastRef.current = undefined;\n }, TOAST_ANIMATION_DURATION);\n return;\n }\n\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setCurrentToastOptions(normalizedOptions);\n }, timeoutDuration);\n },\n [setCurrentIsVisible, setCurrentToastOptions],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n closeToast: clearStoreToastOptions,\n showToast: setStoreToastOptions,\n }),\n [],\n );\n\n // Subscribe before sibling passive effects run so toast() can be called\n // from anywhere once the app root has rendered <Toaster />.\n useLayoutEffect(() => {\n return subscribeToToastStore((options) => {\n if (options) {\n showRenderedToast(options);\n return;\n }\n\n closeRenderedToast();\n });\n }, [closeRenderedToast, showRenderedToast]);\n\n // Delay the enter transition until after mount so the DOM can paint the\n // offscreen starting position before we slide the toast into view.\n useEffect(() => {\n if (toastOptions && !isVisible) {\n enterAnimationFrameRef.current = requestAnimationFrame(() => {\n enterAnimationFrameRef.current = requestAnimationFrame(() => {\n setCurrentIsVisible(true);\n enterAnimationFrameRef.current = null;\n });\n });\n }\n return () => {\n clearPendingTimers();\n };\n }, [clearPendingTimers, setCurrentIsVisible, toastOptions]); // intentionally omit isVisible — only react to new toast options\n\n // Auto-dismiss once the toast is visible, unless the caller requested a\n // persistent toast.\n useEffect(() => {\n if (isVisible && toastOptions && !toastOptions.hasNoTimeout) {\n autoDismissTimerRef.current = setTimeout(() => {\n autoDismissTimerRef.current = null;\n clearStoreToastOptions();\n }, TOAST_VISIBILITY_DURATION);\n return () => {\n clearPendingTimers();\n };\n }\n return undefined;\n }, [clearPendingTimers, isVisible, toastOptions]);\n\n useEffect(() => {\n return () => {\n clearPendingTimers();\n pendingToastRef.current = undefined;\n toastOptionsRef.current = undefined;\n isVisibleRef.current = false;\n };\n }, [clearPendingTimers]);\n\n if (!toastOptions) {\n return null;\n }\n\n const {\n onClose: toastOnClose,\n className: toastClassName,\n ...toastProps\n } = getToastProps(toastOptions);\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={twMerge(\n 'pointer-events-none fixed inset-x-4 bottom-4 z-[1000] flex justify-center',\n className,\n )}\n {...props}\n >\n <div\n className=\"pointer-events-auto w-full transition-transform ease-in-out\"\n style={{\n transitionDuration: `${TOAST_ANIMATION_DURATION}ms`,\n transform: isVisible\n ? 'translateY(0)'\n : 'translateY(calc(100% + 16px))',\n }}\n >\n <Toast\n {...toastProps}\n className={toastClassName}\n onClose={() => {\n clearStoreToastOptions();\n toastOnClose?.();\n }}\n />\n </div>\n </div>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n setStoreToastOptions(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n clearStoreToastOptions();\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TOAST_VISIBILITY_DURATION = exports.TOAST_ANIMATION_DURATION = exports.toast = exports.Toaster = exports.Toast = exports.ToastSeverity = void 0;
3
+ exports.toast = exports.Toaster = exports.Toast = exports.ToastSeverity = void 0;
4
4
  var design_system_shared_1 = require("@metamask-previews/design-system-shared");
5
5
  Object.defineProperty(exports, "ToastSeverity", { enumerable: true, get: function () { return design_system_shared_1.ToastSeverity; } });
6
6
  var Toast_1 = require("./Toast.cjs");
@@ -8,7 +8,4 @@ Object.defineProperty(exports, "Toast", { enumerable: true, get: function () { r
8
8
  var Toaster_1 = require("./Toaster.cjs");
9
9
  Object.defineProperty(exports, "Toaster", { enumerable: true, get: function () { return Toaster_1.Toaster; } });
10
10
  Object.defineProperty(exports, "toast", { enumerable: true, get: function () { return Toaster_1.toast; } });
11
- var Toast_constants_1 = require("./Toast.constants.cjs");
12
- Object.defineProperty(exports, "TOAST_ANIMATION_DURATION", { enumerable: true, get: function () { return Toast_constants_1.TOAST_ANIMATION_DURATION; } });
13
- Object.defineProperty(exports, "TOAST_VISIBILITY_DURATION", { enumerable: true, get: function () { return Toast_constants_1.TOAST_VISIBILITY_DURATION; } });
14
11
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/components/Toast/index.ts"],"names":[],"mappings":";;;AAAA,gFAAwE;AAA/D,qHAAA,aAAa,OAAA;AACtB,qCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,yCAA2C;AAAlC,kGAAA,OAAO,OAAA;AAAE,gGAAA,KAAK,OAAA;AAOvB,yDAG2B;AAFzB,2HAAA,wBAAwB,OAAA;AACxB,4HAAA,yBAAyB,OAAA","sourcesContent":["export { ToastSeverity } from '@metamask-previews/design-system-shared';\nexport { Toast } from './Toast';\nexport { Toaster, toast } from './Toaster';\nexport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\nexport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/components/Toast/index.ts"],"names":[],"mappings":";;;AAAA,gFAAwE;AAA/D,qHAAA,aAAa,OAAA;AACtB,qCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,yCAA2C;AAAlC,kGAAA,OAAO,OAAA;AAAE,gGAAA,KAAK,OAAA","sourcesContent":["export { ToastSeverity } from '@metamask-previews/design-system-shared';\nexport { Toast } from './Toast';\nexport { Toaster, toast } from './Toaster';\nexport type { ToastOptions, ToastProps, ToasterProps } from './Toast.types';\n"]}