@tamagui/toast 1.7.11 → 1.8.0
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.
- package/dist/cjs/Toast.js +95 -543
- package/dist/cjs/Toast.js.map +3 -3
- package/dist/cjs/ToastAnnounce.js +93 -0
- package/dist/cjs/ToastAnnounce.js.map +7 -0
- package/dist/cjs/ToastImpl.js +354 -0
- package/dist/cjs/ToastImpl.js.map +7 -0
- package/dist/cjs/ToastProvider.js +109 -0
- package/dist/cjs/ToastProvider.js.map +7 -0
- package/dist/cjs/ToastViewport.js +307 -0
- package/dist/cjs/ToastViewport.js.map +7 -0
- package/dist/cjs/constants.js +29 -0
- package/dist/cjs/constants.js.map +7 -0
- package/dist/cjs/createNativeToast.js +49 -0
- package/dist/cjs/createNativeToast.js.map +7 -0
- package/dist/cjs/createNativeToast.native.js +37 -0
- package/dist/cjs/createNativeToast.native.js.map +7 -0
- package/dist/cjs/createToast.js +88 -0
- package/dist/cjs/createToast.js.map +7 -0
- package/dist/cjs/types.js +17 -0
- package/dist/cjs/types.js.map +7 -0
- package/dist/esm/Toast.js +101 -531
- package/dist/esm/Toast.js.map +3 -3
- package/dist/esm/Toast.mjs +101 -531
- package/dist/esm/Toast.mjs.map +3 -3
- package/dist/esm/ToastAnnounce.js +64 -0
- package/dist/esm/ToastAnnounce.js.map +7 -0
- package/dist/esm/ToastAnnounce.mjs +64 -0
- package/dist/esm/ToastAnnounce.mjs.map +7 -0
- package/dist/esm/ToastImpl.js +330 -0
- package/dist/esm/ToastImpl.js.map +7 -0
- package/dist/esm/ToastImpl.mjs +330 -0
- package/dist/esm/ToastImpl.mjs.map +7 -0
- package/dist/esm/ToastProvider.js +70 -0
- package/dist/esm/ToastProvider.js.map +7 -0
- package/dist/esm/ToastProvider.mjs +70 -0
- package/dist/esm/ToastProvider.mjs.map +7 -0
- package/dist/esm/ToastViewport.js +274 -0
- package/dist/esm/ToastViewport.js.map +7 -0
- package/dist/esm/ToastViewport.mjs +274 -0
- package/dist/esm/ToastViewport.mjs.map +7 -0
- package/dist/esm/constants.js +5 -0
- package/dist/esm/constants.js.map +7 -0
- package/dist/esm/constants.mjs +5 -0
- package/dist/esm/constants.mjs.map +7 -0
- package/dist/esm/createNativeToast.js +25 -0
- package/dist/esm/createNativeToast.js.map +7 -0
- package/dist/esm/createNativeToast.mjs +25 -0
- package/dist/esm/createNativeToast.mjs.map +7 -0
- package/dist/esm/createNativeToast.native.js +13 -0
- package/dist/esm/createNativeToast.native.js.map +7 -0
- package/dist/esm/createNativeToast.native.mjs +13 -0
- package/dist/esm/createNativeToast.native.mjs.map +7 -0
- package/dist/esm/createToast.js +54 -0
- package/dist/esm/createToast.js.map +7 -0
- package/dist/esm/createToast.mjs +54 -0
- package/dist/esm/createToast.mjs.map +7 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +7 -0
- package/dist/esm/types.mjs +1 -0
- package/dist/esm/types.mjs.map +7 -0
- package/dist/jsx/Toast.js +97 -509
- package/dist/jsx/Toast.js.map +3 -3
- package/dist/jsx/Toast.mjs +97 -509
- package/dist/jsx/Toast.mjs.map +3 -3
- package/dist/jsx/ToastAnnounce.js +60 -0
- package/dist/jsx/ToastAnnounce.js.map +7 -0
- package/dist/jsx/ToastAnnounce.mjs +60 -0
- package/dist/jsx/ToastAnnounce.mjs.map +7 -0
- package/dist/jsx/ToastImpl.js +309 -0
- package/dist/jsx/ToastImpl.js.map +7 -0
- package/dist/jsx/ToastImpl.mjs +309 -0
- package/dist/jsx/ToastImpl.mjs.map +7 -0
- package/dist/jsx/ToastProvider.js +65 -0
- package/dist/jsx/ToastProvider.js.map +7 -0
- package/dist/jsx/ToastProvider.mjs +65 -0
- package/dist/jsx/ToastProvider.mjs.map +7 -0
- package/dist/jsx/ToastViewport.js +254 -0
- package/dist/jsx/ToastViewport.js.map +7 -0
- package/dist/jsx/ToastViewport.mjs +254 -0
- package/dist/jsx/ToastViewport.mjs.map +7 -0
- package/dist/jsx/constants.js +5 -0
- package/dist/jsx/constants.js.map +7 -0
- package/dist/jsx/constants.mjs +5 -0
- package/dist/jsx/constants.mjs.map +7 -0
- package/dist/jsx/createNativeToast.js +25 -0
- package/dist/jsx/createNativeToast.js.map +7 -0
- package/dist/jsx/createNativeToast.mjs +25 -0
- package/dist/jsx/createNativeToast.mjs.map +7 -0
- package/dist/jsx/createNativeToast.native.js +13 -0
- package/dist/jsx/createNativeToast.native.js.map +7 -0
- package/dist/jsx/createNativeToast.native.mjs +13 -0
- package/dist/jsx/createNativeToast.native.mjs.map +7 -0
- package/dist/jsx/createToast.js +49 -0
- package/dist/jsx/createToast.js.map +7 -0
- package/dist/jsx/createToast.mjs +49 -0
- package/dist/jsx/createToast.mjs.map +7 -0
- package/dist/jsx/types.js +1 -0
- package/dist/jsx/types.js.map +7 -0
- package/dist/jsx/types.mjs +1 -0
- package/dist/jsx/types.mjs.map +7 -0
- package/package.json +14 -13
- package/src/Toast.tsx +139 -908
- package/src/ToastAnnounce.tsx +97 -0
- package/src/ToastImpl.tsx +439 -0
- package/src/ToastProvider.tsx +134 -0
- package/src/ToastViewport.tsx +354 -0
- package/src/constants.ts +1 -0
- package/src/createNativeToast.native.tsx +16 -0
- package/src/createNativeToast.tsx +25 -0
- package/src/createToast.tsx +93 -0
- package/src/types.ts +21 -0
- package/types/Toast.d.ts +429 -106
- package/types/Toast.d.ts.map +1 -1
- package/types/ToastAnnounce.d.ts +35 -0
- package/types/ToastAnnounce.d.ts.map +1 -0
- package/types/ToastImpl.d.ts +267 -0
- package/types/ToastImpl.d.ts.map +1 -0
- package/types/ToastProvider.d.ts +80 -0
- package/types/ToastProvider.d.ts.map +1 -0
- package/types/ToastViewport.d.ts +115 -0
- package/types/ToastViewport.d.ts.map +1 -0
- package/types/constants.d.ts +2 -0
- package/types/constants.d.ts.map +1 -0
- package/types/createNativeToast.d.ts +3 -0
- package/types/createNativeToast.d.ts.map +1 -0
- package/types/createNativeToast.native.d.ts +3 -0
- package/types/createNativeToast.native.d.ts.map +1 -0
- package/types/createToast.d.ts +42 -0
- package/types/createToast.d.ts.map +1 -0
- package/types/types.d.ts +17 -0
- package/types/types.d.ts.map +1 -0
package/dist/esm/Toast.js
CHANGED
|
@@ -1,463 +1,80 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useComposedRefs } from "@tamagui/compose-refs";
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
2
|
import {
|
|
4
3
|
composeEventHandlers,
|
|
5
|
-
|
|
4
|
+
styled,
|
|
5
|
+
themeable,
|
|
6
6
|
useEvent,
|
|
7
|
-
|
|
7
|
+
useId,
|
|
8
|
+
withStaticProperties
|
|
8
9
|
} from "@tamagui/core";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
10
|
+
import { ThemeableStack } from "@tamagui/stacks";
|
|
11
|
+
import { SizableText } from "@tamagui/text";
|
|
11
12
|
import { useControllableState } from "@tamagui/use-controllable-state";
|
|
12
|
-
import { VisuallyHidden } from "@tamagui/visually-hidden";
|
|
13
13
|
import * as React from "react";
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
scope: __scopeToast,
|
|
36
|
-
label,
|
|
37
|
-
duration,
|
|
38
|
-
swipeDirection,
|
|
39
|
-
swipeThreshold,
|
|
40
|
-
toastCount,
|
|
41
|
-
viewport,
|
|
42
|
-
onViewportChange: setViewport,
|
|
43
|
-
onToastAdd: React.useCallback(
|
|
44
|
-
() => setToastCount((prevCount) => prevCount + 1),
|
|
45
|
-
[]
|
|
46
|
-
),
|
|
47
|
-
onToastRemove: React.useCallback(
|
|
48
|
-
() => setToastCount((prevCount) => prevCount - 1),
|
|
49
|
-
[]
|
|
50
|
-
),
|
|
51
|
-
isFocusedToastEscapeKeyDownRef,
|
|
52
|
-
isClosePausedRef,
|
|
53
|
-
children
|
|
14
|
+
import { TOAST_NAME } from "./constants";
|
|
15
|
+
import { createToast } from "./createToast";
|
|
16
|
+
import { ToastAnnounceExclude } from "./ToastAnnounce";
|
|
17
|
+
import {
|
|
18
|
+
ToastImpl,
|
|
19
|
+
ToastImplFrame,
|
|
20
|
+
useToastInteractiveContext
|
|
21
|
+
} from "./ToastImpl";
|
|
22
|
+
import {
|
|
23
|
+
ToastProvider,
|
|
24
|
+
createToastScope
|
|
25
|
+
} from "./ToastProvider";
|
|
26
|
+
import { ToastViewport } from "./ToastViewport";
|
|
27
|
+
const TITLE_NAME = "ToastTitle";
|
|
28
|
+
const ToastTitleFrame = styled(SizableText, {
|
|
29
|
+
name: TITLE_NAME,
|
|
30
|
+
color: "$color",
|
|
31
|
+
variants: {
|
|
32
|
+
unstyled: {
|
|
33
|
+
false: {
|
|
34
|
+
size: "$4"
|
|
54
35
|
}
|
|
55
|
-
)
|
|
56
|
-
);
|
|
57
|
-
};
|
|
58
|
-
ToastProvider.propTypes = {
|
|
59
|
-
label(props) {
|
|
60
|
-
if (props.label && typeof props.label === "string" && !props.label.trim()) {
|
|
61
|
-
const error = `Invalid prop \`label\` supplied to \`${PROVIDER_NAME}\`. Expected non-empty \`string\`.`;
|
|
62
|
-
return new Error(error);
|
|
63
36
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
ToastProvider.displayName = PROVIDER_NAME;
|
|
68
|
-
const VIEWPORT_NAME = "ToastViewport";
|
|
69
|
-
const VIEWPORT_DEFAULT_HOTKEY = ["F8"];
|
|
70
|
-
const VIEWPORT_PAUSE = "toast.viewportPause";
|
|
71
|
-
const VIEWPORT_RESUME = "toast.viewportResume";
|
|
72
|
-
const ToastViewport = React.forwardRef(
|
|
73
|
-
(props, forwardedRef) => {
|
|
74
|
-
const {
|
|
75
|
-
__scopeToast,
|
|
76
|
-
hotkey = VIEWPORT_DEFAULT_HOTKEY,
|
|
77
|
-
label = "Notifications ({hotkey})",
|
|
78
|
-
...viewportProps
|
|
79
|
-
} = props;
|
|
80
|
-
const context = useToastProviderContext(VIEWPORT_NAME, __scopeToast);
|
|
81
|
-
const wrapperRef = React.useRef(null);
|
|
82
|
-
const headFocusProxyRef = React.useRef(null);
|
|
83
|
-
const tailFocusProxyRef = React.useRef(null);
|
|
84
|
-
const ref = React.useRef(null);
|
|
85
|
-
const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange);
|
|
86
|
-
const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
|
|
87
|
-
const hasToasts = context.toastCount > 0;
|
|
88
|
-
React.useEffect(() => {
|
|
89
|
-
const handleKeyDown = (event) => {
|
|
90
|
-
var _a;
|
|
91
|
-
const isHotkeyPressed = hotkey.every(
|
|
92
|
-
(key) => event[key] || event.code === key
|
|
93
|
-
);
|
|
94
|
-
if (isHotkeyPressed)
|
|
95
|
-
(_a = ref.current) == null ? void 0 : _a.focus();
|
|
96
|
-
};
|
|
97
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
98
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
99
|
-
}, [hotkey]);
|
|
100
|
-
React.useEffect(() => {
|
|
101
|
-
const wrapper = wrapperRef.current;
|
|
102
|
-
const viewport = ref.current;
|
|
103
|
-
if (wrapper && viewport) {
|
|
104
|
-
const handlePause = () => {
|
|
105
|
-
const pauseEvent = new CustomEvent(VIEWPORT_PAUSE);
|
|
106
|
-
context.isClosePausedRef.current = true;
|
|
107
|
-
};
|
|
108
|
-
const handleResume = () => {
|
|
109
|
-
const resumeEvent = new CustomEvent(VIEWPORT_RESUME);
|
|
110
|
-
context.isClosePausedRef.current = false;
|
|
111
|
-
};
|
|
112
|
-
wrapper.addEventListener("focusin", handlePause);
|
|
113
|
-
wrapper.addEventListener("focusout", handleResume);
|
|
114
|
-
wrapper.addEventListener("pointerenter", handlePause);
|
|
115
|
-
wrapper.addEventListener("pointerleave", handleResume);
|
|
116
|
-
window.addEventListener("blur", handlePause);
|
|
117
|
-
window.addEventListener("focus", handleResume);
|
|
118
|
-
return () => {
|
|
119
|
-
wrapper.removeEventListener("focusin", handlePause);
|
|
120
|
-
wrapper.removeEventListener("focusout", handleResume);
|
|
121
|
-
wrapper.removeEventListener("pointerenter", handlePause);
|
|
122
|
-
wrapper.removeEventListener("pointerleave", handleResume);
|
|
123
|
-
window.removeEventListener("blur", handlePause);
|
|
124
|
-
window.removeEventListener("focus", handleResume);
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
}, [context.isClosePausedRef]);
|
|
128
|
-
React.useEffect(
|
|
129
|
-
() => {
|
|
130
|
-
const viewport = ref.current;
|
|
131
|
-
if (viewport) {
|
|
132
|
-
const handleKeyDown = (event) => {
|
|
133
|
-
var _a;
|
|
134
|
-
const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
|
|
135
|
-
const isTabKey = event.key === "Tab" && !isMetaKey;
|
|
136
|
-
if (isTabKey) {
|
|
137
|
-
const focusedElement = document.activeElement;
|
|
138
|
-
const isTabbingBackwards = event.shiftKey;
|
|
139
|
-
const targetIsViewport = event.target === viewport;
|
|
140
|
-
if (targetIsViewport && isTabbingBackwards) {
|
|
141
|
-
(_a = headFocusProxyRef.current) == null ? void 0 : _a.focus();
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
const tabbingDirection = isTabbingBackwards ? "backwards" : "forwards";
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
return () => {
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
[
|
|
152
|
-
// getItems, getSortedTabbableCandidates
|
|
153
|
-
]
|
|
154
|
-
);
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
);
|
|
158
|
-
ToastViewport.displayName = VIEWPORT_NAME;
|
|
159
|
-
const FOCUS_PROXY_NAME = "ToastFocusProxy";
|
|
160
|
-
const FocusProxy = React.forwardRef(
|
|
161
|
-
(props, forwardedRef) => {
|
|
162
|
-
const { __scopeToast, onFocusFromOutsideViewport, ...proxyProps } = props;
|
|
163
|
-
const context = useToastProviderContext(FOCUS_PROXY_NAME, __scopeToast);
|
|
164
|
-
return /* @__PURE__ */ jsx(
|
|
165
|
-
VisuallyHidden,
|
|
166
|
-
{
|
|
167
|
-
"aria-hidden": true,
|
|
168
|
-
tabIndex: 0,
|
|
169
|
-
...proxyProps,
|
|
170
|
-
ref: forwardedRef,
|
|
171
|
-
position: isWeb ? "fixed" : "absolute",
|
|
172
|
-
onFocus: (event) => {
|
|
173
|
-
var _a;
|
|
174
|
-
const prevFocusedElement = event.relatedTarget;
|
|
175
|
-
const isFocusFromOutsideViewport = !((_a = context.viewport) == null ? void 0 : _a.contains(prevFocusedElement));
|
|
176
|
-
if (isFocusFromOutsideViewport)
|
|
177
|
-
onFocusFromOutsideViewport();
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
);
|
|
37
|
+
},
|
|
38
|
+
defaultVariants: {
|
|
39
|
+
unstyled: false
|
|
181
40
|
}
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
const TOAST_NAME = "Toast";
|
|
185
|
-
const TOAST_SWIPE_START = "toast.swipeStart";
|
|
186
|
-
const TOAST_SWIPE_MOVE = "toast.swipeMove";
|
|
187
|
-
const TOAST_SWIPE_CANCEL = "toast.swipeCancel";
|
|
188
|
-
const TOAST_SWIPE_END = "toast.swipeEnd";
|
|
189
|
-
const Toast = React.forwardRef(
|
|
41
|
+
});
|
|
42
|
+
const ToastTitle = React.forwardRef(
|
|
190
43
|
(props, forwardedRef) => {
|
|
191
|
-
const {
|
|
192
|
-
|
|
193
|
-
open: openProp,
|
|
194
|
-
defaultOpen,
|
|
195
|
-
onOpenChange,
|
|
196
|
-
...toastProps
|
|
197
|
-
} = props;
|
|
198
|
-
const [open, setOpen] = useControllableState({
|
|
199
|
-
prop: openProp,
|
|
200
|
-
defaultProp: true,
|
|
201
|
-
onChange: onOpenChange,
|
|
202
|
-
transition: true
|
|
203
|
-
});
|
|
204
|
-
return (
|
|
205
|
-
// <Presence present={forceMount || open}>
|
|
206
|
-
/* @__PURE__ */ jsx(
|
|
207
|
-
ToastImpl,
|
|
208
|
-
{
|
|
209
|
-
open,
|
|
210
|
-
...toastProps,
|
|
211
|
-
ref: forwardedRef,
|
|
212
|
-
onClose: () => setOpen(false)
|
|
213
|
-
}
|
|
214
|
-
)
|
|
215
|
-
);
|
|
44
|
+
const { __scopeToast, ...titleProps } = props;
|
|
45
|
+
return /* @__PURE__ */ jsx(ToastTitleFrame, { ...titleProps, ref: forwardedRef });
|
|
216
46
|
}
|
|
217
47
|
);
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
onClose,
|
|
228
|
-
onEscapeKeyDown,
|
|
229
|
-
onSwipeStart,
|
|
230
|
-
onSwipeMove,
|
|
231
|
-
onSwipeCancel,
|
|
232
|
-
onSwipeEnd,
|
|
233
|
-
...toastProps
|
|
234
|
-
} = props;
|
|
235
|
-
const context = useToastProviderContext(TOAST_NAME, __scopeToast);
|
|
236
|
-
const ref = React.useRef(null);
|
|
237
|
-
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
238
|
-
const pointerStartRef = React.useRef(null);
|
|
239
|
-
const swipeDeltaRef = React.useRef(null);
|
|
240
|
-
const duration = durationProp || context.duration;
|
|
241
|
-
const closeTimerStartTimeRef = React.useRef(0);
|
|
242
|
-
const closeTimerRemainingTimeRef = React.useRef(duration);
|
|
243
|
-
const closeTimerRef = React.useRef(0);
|
|
244
|
-
const { onToastAdd, onToastRemove } = context;
|
|
245
|
-
const handleClose = useEvent(() => {
|
|
246
|
-
onClose();
|
|
247
|
-
});
|
|
248
|
-
const startTimer = React.useCallback(
|
|
249
|
-
(duration2) => {
|
|
250
|
-
if (!duration2 || duration2 === Infinity)
|
|
251
|
-
return;
|
|
252
|
-
window.clearTimeout(closeTimerRef.current);
|
|
253
|
-
closeTimerStartTimeRef.current = (/* @__PURE__ */ new Date()).getTime();
|
|
254
|
-
closeTimerRef.current = window.setTimeout(handleClose, duration2);
|
|
255
|
-
},
|
|
256
|
-
[handleClose]
|
|
257
|
-
);
|
|
258
|
-
React.useEffect(() => {
|
|
259
|
-
const viewport = context.viewport;
|
|
260
|
-
if (viewport) {
|
|
261
|
-
const handleResume = () => {
|
|
262
|
-
startTimer(closeTimerRemainingTimeRef.current);
|
|
263
|
-
};
|
|
264
|
-
const handlePause = () => {
|
|
265
|
-
const elapsedTime = (/* @__PURE__ */ new Date()).getTime() - closeTimerStartTimeRef.current;
|
|
266
|
-
closeTimerRemainingTimeRef.current = closeTimerRemainingTimeRef.current - elapsedTime;
|
|
267
|
-
window.clearTimeout(closeTimerRef.current);
|
|
268
|
-
};
|
|
269
|
-
viewport.addEventListener(VIEWPORT_PAUSE, handlePause);
|
|
270
|
-
viewport.addEventListener(VIEWPORT_RESUME, handleResume);
|
|
271
|
-
return () => {
|
|
272
|
-
viewport.removeEventListener(VIEWPORT_PAUSE, handlePause);
|
|
273
|
-
viewport.removeEventListener(VIEWPORT_RESUME, handleResume);
|
|
274
|
-
};
|
|
48
|
+
ToastTitle.displayName = TITLE_NAME;
|
|
49
|
+
const DESCRIPTION_NAME = "ToastDescription";
|
|
50
|
+
const ToastDescriptionFrame = styled(SizableText, {
|
|
51
|
+
name: DESCRIPTION_NAME,
|
|
52
|
+
color: "$color11",
|
|
53
|
+
variants: {
|
|
54
|
+
unstyled: {
|
|
55
|
+
false: {
|
|
56
|
+
size: "$1"
|
|
275
57
|
}
|
|
276
|
-
}, [context.viewport, duration, startTimer]);
|
|
277
|
-
React.useEffect(() => {
|
|
278
|
-
if (open && !context.isClosePausedRef.current)
|
|
279
|
-
startTimer(duration);
|
|
280
|
-
}, [open, duration, context.isClosePausedRef, startTimer]);
|
|
281
|
-
React.useEffect(() => {
|
|
282
|
-
onToastAdd();
|
|
283
|
-
return () => onToastRemove();
|
|
284
|
-
}, [onToastAdd, onToastRemove]);
|
|
285
|
-
if (!context.viewport)
|
|
286
|
-
return null;
|
|
287
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
288
|
-
/* @__PURE__ */ jsx(
|
|
289
|
-
ToastAnnounce,
|
|
290
|
-
{
|
|
291
|
-
__scopeToast,
|
|
292
|
-
role: "status",
|
|
293
|
-
"aria-live": type === "foreground" ? "assertive" : "polite",
|
|
294
|
-
"aria-atomic": true,
|
|
295
|
-
children: props.children
|
|
296
|
-
}
|
|
297
|
-
),
|
|
298
|
-
/* @__PURE__ */ jsx(
|
|
299
|
-
ToastInteractiveProvider,
|
|
300
|
-
{
|
|
301
|
-
scope: __scopeToast,
|
|
302
|
-
isInteractive: true,
|
|
303
|
-
onClose: handleClose,
|
|
304
|
-
children: ReactDOM.createPortal(
|
|
305
|
-
/* @__PURE__ */ jsx("div", {}),
|
|
306
|
-
// <Collection.ItemSlot scope={__scopeToast}>
|
|
307
|
-
// <DismissableLayer.Root
|
|
308
|
-
// asChild
|
|
309
|
-
// onEscapeKeyDown={composeEventHandlers(onEscapeKeyDown, () => {
|
|
310
|
-
// if (!context.isFocusedToastEscapeKeyDownRef.current) handleClose()
|
|
311
|
-
// context.isFocusedToastEscapeKeyDownRef.current = false
|
|
312
|
-
// })}
|
|
313
|
-
// >
|
|
314
|
-
// <Primitive.li
|
|
315
|
-
// // Ensure toasts are announced as status list or status when focused
|
|
316
|
-
// role="status"
|
|
317
|
-
// aria-live="off"
|
|
318
|
-
// aria-atomic
|
|
319
|
-
// tabIndex={0}
|
|
320
|
-
// data-state={open ? 'open' : 'closed'}
|
|
321
|
-
// data-swipe-direction={context.swipeDirection}
|
|
322
|
-
// {...toastProps}
|
|
323
|
-
// ref={composedRefs}
|
|
324
|
-
// style={{ userSelect: 'none', touchAction: 'none', ...props.style }}
|
|
325
|
-
// onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {
|
|
326
|
-
// if (event.key !== 'Escape') return
|
|
327
|
-
// onEscapeKeyDown?.(event.nativeEvent)
|
|
328
|
-
// if (!event.nativeEvent.defaultPrevented) {
|
|
329
|
-
// context.isFocusedToastEscapeKeyDownRef.current = true
|
|
330
|
-
// handleClose()
|
|
331
|
-
// }
|
|
332
|
-
// })}
|
|
333
|
-
// onPointerDown={composeEventHandlers(props.onPointerDown, (event) => {
|
|
334
|
-
// if (event.button !== 0) return
|
|
335
|
-
// pointerStartRef.current = { x: event.clientX, y: event.clientY }
|
|
336
|
-
// })}
|
|
337
|
-
// onPointerMove={composeEventHandlers(props.onPointerMove, (event) => {
|
|
338
|
-
// if (!pointerStartRef.current) return
|
|
339
|
-
// const x = event.clientX - pointerStartRef.current.x
|
|
340
|
-
// const y = event.clientY - pointerStartRef.current.y
|
|
341
|
-
// const hasSwipeMoveStarted = Boolean(swipeDeltaRef.current)
|
|
342
|
-
// const isHorizontalSwipe = ['left', 'right'].includes(context.swipeDirection)
|
|
343
|
-
// const clamp = ['left', 'up'].includes(context.swipeDirection)
|
|
344
|
-
// ? Math.min
|
|
345
|
-
// : Math.max
|
|
346
|
-
// const clampedX = isHorizontalSwipe ? clamp(0, x) : 0
|
|
347
|
-
// const clampedY = !isHorizontalSwipe ? clamp(0, y) : 0
|
|
348
|
-
// const moveStartBuffer = event.pointerType === 'touch' ? 10 : 2
|
|
349
|
-
// const delta = { x: clampedX, y: clampedY }
|
|
350
|
-
// const eventDetail = { originalEvent: event, delta }
|
|
351
|
-
// if (hasSwipeMoveStarted) {
|
|
352
|
-
// swipeDeltaRef.current = delta
|
|
353
|
-
// handleAndDispatchCustomEvent(TOAST_SWIPE_MOVE, onSwipeMove, eventDetail, {
|
|
354
|
-
// discrete: false,
|
|
355
|
-
// })
|
|
356
|
-
// } else if (isDeltaInDirection(delta, context.swipeDirection, moveStartBuffer)) {
|
|
357
|
-
// swipeDeltaRef.current = delta
|
|
358
|
-
// handleAndDispatchCustomEvent(TOAST_SWIPE_START, onSwipeStart, eventDetail, {
|
|
359
|
-
// discrete: false,
|
|
360
|
-
// })
|
|
361
|
-
// ;(event.target as HTMLElement).setPointerCapture(event.pointerId)
|
|
362
|
-
// } else if (Math.abs(x) > moveStartBuffer || Math.abs(y) > moveStartBuffer) {
|
|
363
|
-
// // User is swiping in wrong direction so we disable swipe gesture
|
|
364
|
-
// // for the current pointer down interaction
|
|
365
|
-
// pointerStartRef.current = null
|
|
366
|
-
// }
|
|
367
|
-
// })}
|
|
368
|
-
// onPointerUp={composeEventHandlers(props.onPointerUp, (event) => {
|
|
369
|
-
// const delta = swipeDeltaRef.current
|
|
370
|
-
// ;(event.target as HTMLElement).releasePointerCapture(event.pointerId)
|
|
371
|
-
// swipeDeltaRef.current = null
|
|
372
|
-
// pointerStartRef.current = null
|
|
373
|
-
// if (delta) {
|
|
374
|
-
// const toast = event.currentTarget
|
|
375
|
-
// const eventDetail = { originalEvent: event, delta }
|
|
376
|
-
// if (isDeltaInDirection(delta, context.swipeDirection, context.swipeThreshold)) {
|
|
377
|
-
// handleAndDispatchCustomEvent(TOAST_SWIPE_END, onSwipeEnd, eventDetail, {
|
|
378
|
-
// discrete: true,
|
|
379
|
-
// })
|
|
380
|
-
// } else {
|
|
381
|
-
// handleAndDispatchCustomEvent(TOAST_SWIPE_CANCEL, onSwipeCancel, eventDetail, {
|
|
382
|
-
// discrete: true,
|
|
383
|
-
// })
|
|
384
|
-
// }
|
|
385
|
-
// // Prevent click event from triggering on items within the toast when
|
|
386
|
-
// // pointer up is part of a swipe gesture
|
|
387
|
-
// toast.addEventListener('click', (event) => event.preventDefault(), {
|
|
388
|
-
// once: true,
|
|
389
|
-
// })
|
|
390
|
-
// }
|
|
391
|
-
// })}
|
|
392
|
-
// />
|
|
393
|
-
// </DismissableLayer.Root>,
|
|
394
|
-
// </Collection.ItemSlot>,
|
|
395
|
-
context.viewport
|
|
396
|
-
)
|
|
397
|
-
}
|
|
398
|
-
)
|
|
399
|
-
] });
|
|
400
|
-
}
|
|
401
|
-
);
|
|
402
|
-
ToastImpl.propTypes = {
|
|
403
|
-
type(props) {
|
|
404
|
-
if (props.type && !["foreground", "background"].includes(props.type)) {
|
|
405
|
-
const error = `Invalid prop \`type\` supplied to \`${TOAST_NAME}\`. Expected \`foreground | background\`.`;
|
|
406
|
-
return new Error(error);
|
|
407
58
|
}
|
|
408
|
-
|
|
59
|
+
},
|
|
60
|
+
defaultVariants: {
|
|
61
|
+
unstyled: false
|
|
409
62
|
}
|
|
410
|
-
};
|
|
411
|
-
const
|
|
412
|
-
const { __scopeToast, children, ...announceProps } = props;
|
|
413
|
-
const context = useToastProviderContext(TOAST_NAME, __scopeToast);
|
|
414
|
-
const [renderAnnounceText, setRenderAnnounceText] = React.useState(false);
|
|
415
|
-
const [isAnnounced, setIsAnnounced] = React.useState(false);
|
|
416
|
-
const [fragment, setFragment] = React.useState();
|
|
417
|
-
const [rootFragmentNode, setRootFragmentNode] = React.useState(null);
|
|
418
|
-
const announceTextContent = React.useMemo(() => {
|
|
419
|
-
return rootFragmentNode ? getAnnounceTextContent(rootFragmentNode) : null;
|
|
420
|
-
}, [rootFragmentNode]);
|
|
421
|
-
useIsomorphicLayoutEffect(() => {
|
|
422
|
-
setFragment(new DocumentFragment());
|
|
423
|
-
}, []);
|
|
424
|
-
useNextFrame(() => setRenderAnnounceText(true));
|
|
425
|
-
React.useEffect(() => {
|
|
426
|
-
const timer = window.setTimeout(() => setIsAnnounced(true), 1e3);
|
|
427
|
-
return () => window.clearTimeout(timer);
|
|
428
|
-
}, []);
|
|
429
|
-
return isAnnounced ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
430
|
-
fragment && // @ts-ignore
|
|
431
|
-
/* @__PURE__ */ jsxs(Portal, { container: fragment, ref: setRootFragmentNode, children: [
|
|
432
|
-
context.label,
|
|
433
|
-
" ",
|
|
434
|
-
children
|
|
435
|
-
] }),
|
|
436
|
-
/* @__PURE__ */ jsx(Portal, { asChild: true, children: /* @__PURE__ */ jsx(VisuallyHidden, { ...announceProps, children: renderAnnounceText && announceTextContent }) })
|
|
437
|
-
] });
|
|
438
|
-
};
|
|
439
|
-
const TITLE_NAME = "ToastTitle";
|
|
440
|
-
const ToastTitle = React.forwardRef(
|
|
63
|
+
});
|
|
64
|
+
const ToastDescription = React.forwardRef(
|
|
441
65
|
(props, forwardedRef) => {
|
|
442
|
-
const { __scopeToast, ...
|
|
443
|
-
return /* @__PURE__ */ jsx(
|
|
66
|
+
const { __scopeToast, ...descriptionProps } = props;
|
|
67
|
+
return /* @__PURE__ */ jsx(ToastDescriptionFrame, { ...descriptionProps, ref: forwardedRef });
|
|
444
68
|
}
|
|
445
69
|
);
|
|
446
|
-
ToastTitle.displayName = TITLE_NAME;
|
|
447
|
-
const DESCRIPTION_NAME = "ToastDescription";
|
|
448
|
-
const ToastDescription = React.forwardRef((props, forwardedRef) => {
|
|
449
|
-
const { __scopeToast, ...descriptionProps } = props;
|
|
450
|
-
return /* @__PURE__ */ jsx(YStack, { ...descriptionProps, ref: forwardedRef });
|
|
451
|
-
});
|
|
452
70
|
ToastDescription.displayName = DESCRIPTION_NAME;
|
|
453
71
|
const ACTION_NAME = "ToastAction";
|
|
454
72
|
const ToastAction = React.forwardRef(
|
|
455
73
|
(props, forwardedRef) => {
|
|
456
74
|
const { altText, ...actionProps } = props;
|
|
457
|
-
const context = useToastInteractiveContext(ACTION_NAME, props.__scopeToast);
|
|
458
75
|
if (!altText)
|
|
459
76
|
return null;
|
|
460
|
-
return
|
|
77
|
+
return /* @__PURE__ */ jsx(ToastAnnounceExclude, { altText, asChild: true, children: /* @__PURE__ */ jsx(ToastClose, { ...actionProps, ref: forwardedRef }) });
|
|
461
78
|
}
|
|
462
79
|
);
|
|
463
80
|
ToastAction.propTypes = {
|
|
@@ -470,118 +87,71 @@ ToastAction.propTypes = {
|
|
|
470
87
|
};
|
|
471
88
|
ToastAction.displayName = ACTION_NAME;
|
|
472
89
|
const CLOSE_NAME = "ToastClose";
|
|
90
|
+
const ToastCloseFrame = styled(ThemeableStack, {
|
|
91
|
+
name: CLOSE_NAME,
|
|
92
|
+
tag: "button"
|
|
93
|
+
});
|
|
473
94
|
const ToastClose = React.forwardRef(
|
|
474
95
|
(props, forwardedRef) => {
|
|
475
96
|
const { __scopeToast, ...closeProps } = props;
|
|
476
97
|
const interactiveContext = useToastInteractiveContext(CLOSE_NAME, __scopeToast);
|
|
477
|
-
return
|
|
478
|
-
|
|
98
|
+
return /* @__PURE__ */ jsx(ToastAnnounceExclude, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
99
|
+
ToastCloseFrame,
|
|
479
100
|
{
|
|
480
|
-
|
|
101
|
+
accessibilityLabel: "Dialog Close",
|
|
481
102
|
...closeProps,
|
|
482
103
|
ref: forwardedRef,
|
|
483
104
|
onPress: composeEventHandlers(props.onPress, interactiveContext.onClose)
|
|
484
105
|
}
|
|
485
|
-
)
|
|
106
|
+
) });
|
|
486
107
|
}
|
|
487
108
|
);
|
|
488
109
|
ToastClose.displayName = CLOSE_NAME;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
() => raf2 = window.requestAnimationFrame(fn)
|
|
110
|
+
const ToastComponent = React.forwardRef(
|
|
111
|
+
ToastImplFrame.extractable((props, forwardedRef) => {
|
|
112
|
+
const { forceMount, open: openProp, defaultOpen, onOpenChange, ...toastProps } = props;
|
|
113
|
+
const [open, setOpen] = useControllableState({
|
|
114
|
+
prop: openProp,
|
|
115
|
+
defaultProp: defaultOpen ?? true,
|
|
116
|
+
onChange: onOpenChange
|
|
117
|
+
});
|
|
118
|
+
const id = useId();
|
|
119
|
+
const onPause = useEvent(props.onPause);
|
|
120
|
+
const onResume = useEvent(props.onResume);
|
|
121
|
+
if (!forceMount && !open)
|
|
122
|
+
return null;
|
|
123
|
+
return /* @__PURE__ */ jsx(
|
|
124
|
+
ToastImpl,
|
|
125
|
+
{
|
|
126
|
+
id,
|
|
127
|
+
open,
|
|
128
|
+
...toastProps,
|
|
129
|
+
ref: forwardedRef,
|
|
130
|
+
onClose: () => setOpen(false),
|
|
131
|
+
onPause,
|
|
132
|
+
onResume,
|
|
133
|
+
onSwipeEnd: composeEventHandlers(props.onSwipeEnd, (event) => {
|
|
134
|
+
setOpen(false);
|
|
135
|
+
})
|
|
136
|
+
}
|
|
517
137
|
);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (isHTMLElement(node)) {
|
|
531
|
-
const isHidden = node.ariaHidden || node.hidden || node.style.display === "none";
|
|
532
|
-
if (!isHidden)
|
|
533
|
-
textContent.push(...getAnnounceTextContent(node));
|
|
534
|
-
}
|
|
535
|
-
});
|
|
536
|
-
return textContent;
|
|
537
|
-
}
|
|
538
|
-
function isHTMLElement(node) {
|
|
539
|
-
return node.nodeType === node.ELEMENT_NODE;
|
|
540
|
-
}
|
|
541
|
-
function getTabbableCandidates(container) {
|
|
542
|
-
const nodes = [];
|
|
543
|
-
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
544
|
-
acceptNode: (node) => {
|
|
545
|
-
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
|
546
|
-
if (node.disabled || node.hidden || isHiddenInput)
|
|
547
|
-
return NodeFilter.FILTER_SKIP;
|
|
548
|
-
return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
549
|
-
}
|
|
550
|
-
});
|
|
551
|
-
while (walker.nextNode())
|
|
552
|
-
nodes.push(walker.currentNode);
|
|
553
|
-
return nodes;
|
|
554
|
-
}
|
|
555
|
-
function focusFirst(candidates) {
|
|
556
|
-
const previouslyFocusedElement = document.activeElement;
|
|
557
|
-
return candidates.some((candidate) => {
|
|
558
|
-
if (candidate === previouslyFocusedElement)
|
|
559
|
-
return true;
|
|
560
|
-
candidate.focus();
|
|
561
|
-
return document.activeElement !== previouslyFocusedElement;
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
const Provider = ToastProvider;
|
|
565
|
-
const Viewport = ToastViewport;
|
|
566
|
-
const Root = Toast;
|
|
567
|
-
const Title = ToastTitle;
|
|
568
|
-
const Description = ToastDescription;
|
|
569
|
-
const Action = ToastAction;
|
|
570
|
-
const Close = ToastClose;
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
ToastComponent.displayName = TOAST_NAME;
|
|
141
|
+
const Toast = withStaticProperties(
|
|
142
|
+
themeable(ToastComponent, ToastImplFrame.staticConfig),
|
|
143
|
+
{
|
|
144
|
+
Title: ToastTitle,
|
|
145
|
+
Description: ToastDescription,
|
|
146
|
+
Action: ToastAction,
|
|
147
|
+
Close: ToastClose
|
|
148
|
+
}
|
|
149
|
+
);
|
|
571
150
|
export {
|
|
572
|
-
Action,
|
|
573
|
-
Close,
|
|
574
|
-
Description,
|
|
575
|
-
Provider,
|
|
576
|
-
Root,
|
|
577
|
-
Title,
|
|
578
151
|
Toast,
|
|
579
|
-
ToastAction,
|
|
580
|
-
ToastClose,
|
|
581
|
-
ToastDescription,
|
|
582
152
|
ToastProvider,
|
|
583
|
-
ToastTitle,
|
|
584
153
|
ToastViewport,
|
|
585
|
-
|
|
154
|
+
createToast,
|
|
155
|
+
createToastScope
|
|
586
156
|
};
|
|
587
157
|
//# sourceMappingURL=Toast.js.map
|