@tamagui/dismissable 2.7.7 → 3.0.0-beta.643.1
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/Dismissable.cjs +282 -330
- package/dist/cjs/Dismissable.native.cjs +61 -0
- package/dist/cjs/Dismissable.native.js +33 -37
- package/dist/cjs/Dismissable.native.js.map +1 -1
- package/dist/cjs/DismissableProps.cjs +10 -11
- package/dist/cjs/DismissableProps.native.cjs +19 -0
- package/dist/cjs/DismissableProps.native.js +10 -10
- package/dist/cjs/DismissableProps.native.js.map +1 -1
- package/dist/cjs/index.cjs +10 -11
- package/dist/cjs/index.native.cjs +21 -0
- package/dist/cjs/index.native.js +10 -10
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/Dismissable.mjs +261 -301
- package/dist/esm/Dismissable.mjs.map +1 -1
- package/dist/esm/Dismissable.native.js +12 -9
- package/dist/esm/Dismissable.native.js.map +1 -1
- package/dist/esm/DismissableProps.mjs +0 -2
- package/dist/esm/DismissableProps.native.js +0 -2
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.mjs +1 -2
- package/dist/esm/index.native.js +1 -2
- package/dist/jsx/Dismissable.mjs +261 -301
- package/dist/jsx/Dismissable.mjs.map +1 -1
- package/dist/jsx/Dismissable.native.cjs +61 -0
- package/dist/jsx/Dismissable.native.js +33 -37
- package/dist/jsx/Dismissable.native.js.map +1 -1
- package/dist/jsx/DismissableProps.mjs +0 -2
- package/dist/jsx/DismissableProps.native.cjs +19 -0
- package/dist/jsx/DismissableProps.native.js +10 -10
- package/dist/jsx/DismissableProps.native.js.map +1 -1
- package/dist/jsx/index.js +1 -2
- package/dist/jsx/index.mjs +1 -2
- package/dist/jsx/index.native.cjs +21 -0
- package/dist/jsx/index.native.js +10 -10
- package/dist/jsx/index.native.js.map +1 -1
- package/package.json +7 -7
- package/src/Dismissable.native.tsx +3 -2
- package/src/Dismissable.tsx +90 -92
- package/src/DismissableProps.tsx +31 -10
- package/types/Dismissable.d.ts +3 -9
- package/types/Dismissable.d.ts.map +1 -1
- package/types/Dismissable.native.d.ts +2 -2
- package/types/Dismissable.native.d.ts.map +1 -1
- package/types/DismissableProps.d.ts +22 -10
- package/types/DismissableProps.d.ts.map +1 -1
- package/dist/esm/DismissableProps.mjs.map +0 -1
- package/dist/esm/DismissableProps.native.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/index.native.js.map +0 -1
- package/dist/jsx/DismissableProps.mjs.map +0 -1
- package/dist/jsx/index.js.map +0 -1
- package/dist/jsx/index.mjs.map +0 -1
package/dist/esm/Dismissable.mjs
CHANGED
|
@@ -1,340 +1,300 @@
|
|
|
1
1
|
import { useComposedRefs } from "@tamagui/compose-refs";
|
|
2
|
-
import { Slot, View, composeEventHandlers } from "@tamagui/core";
|
|
2
|
+
import { Slot, View, composeEventHandlers, createChangeEventDetails, createRefComponent } from "@tamagui/core";
|
|
3
3
|
import { useEscapeKeydown } from "@tamagui/use-escape-keydown";
|
|
4
4
|
import { useEvent } from "@tamagui/use-event";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import * as ReactDOM from "react-dom";
|
|
7
7
|
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
|
|
8
9
|
function dispatchDiscreteCustomEvent(target, event) {
|
|
9
|
-
|
|
10
|
+
if (target) ReactDOM.flushSync(() => target.dispatchEvent(event));
|
|
10
11
|
}
|
|
11
12
|
const DISMISSABLE_LAYER_NAME = "Dismissable";
|
|
12
13
|
const CONTEXT_UPDATE = "dismissable.update";
|
|
13
|
-
const POINTER_DOWN_OUTSIDE = "dismissable.pointerDownOutside";
|
|
14
|
-
const FOCUS_OUTSIDE = "dismissable.focusOutside";
|
|
15
14
|
let originalBodyPointerEvents;
|
|
16
|
-
const globalLayers = /* @__PURE__ */new Set();
|
|
17
|
-
const layerChangeListeners = /* @__PURE__ */new Set();
|
|
15
|
+
const globalLayers = /* @__PURE__ */ new Set();
|
|
16
|
+
const layerChangeListeners = /* @__PURE__ */ new Set();
|
|
18
17
|
let layersWithPointerEventsDisabledCount = 0;
|
|
19
18
|
function notifyLayerChange() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
for (const listener of layerChangeListeners) {
|
|
20
|
+
listener();
|
|
21
|
+
}
|
|
23
22
|
}
|
|
24
23
|
function getDismissableLayerCount() {
|
|
25
|
-
|
|
24
|
+
return globalLayers.size;
|
|
26
25
|
}
|
|
27
26
|
function debugDismissableLayers() {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const layers = Array.from(globalLayers);
|
|
28
|
+
console.log("[Dismissable] Active layers:", layers.length, layers);
|
|
29
|
+
return layers;
|
|
31
30
|
}
|
|
32
31
|
function useHasDismissableLayers() {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
const [count, setCount] = React.useState(() => globalLayers.size);
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
setCount(globalLayers.size);
|
|
35
|
+
const update = () => setCount(globalLayers.size);
|
|
36
|
+
layerChangeListeners.add(update);
|
|
37
|
+
return () => {
|
|
38
|
+
layerChangeListeners.delete(update);
|
|
39
|
+
};
|
|
40
|
+
}, []);
|
|
41
|
+
return count > 0;
|
|
43
42
|
}
|
|
44
43
|
const DismissableContext = React.createContext({
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
layers: /* @__PURE__ */ new Set(),
|
|
45
|
+
layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
|
|
46
|
+
branches: /* @__PURE__ */ new Set()
|
|
48
47
|
});
|
|
49
48
|
function useIsInsideDismissable(ref) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
49
|
+
const context = React.useContext(DismissableContext);
|
|
50
|
+
const [isInside, setIsInside] = React.useState(false);
|
|
51
|
+
React.useEffect(() => {
|
|
52
|
+
const check = () => {
|
|
53
|
+
const el = ref.current;
|
|
54
|
+
if (!el) {
|
|
55
|
+
setIsInside(false);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
for (const layer of context.layers) {
|
|
59
|
+
if (layer.contains(el)) {
|
|
60
|
+
setIsInside(true);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
setIsInside(false);
|
|
65
|
+
};
|
|
66
|
+
check();
|
|
67
|
+
document.addEventListener(CONTEXT_UPDATE, check);
|
|
68
|
+
return () => document.removeEventListener(CONTEXT_UPDATE, check);
|
|
69
|
+
}, [context.layers, ref]);
|
|
70
|
+
return isInside;
|
|
72
71
|
}
|
|
73
72
|
function useDismissableLayersAbove(ref) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
73
|
+
const context = React.useContext(DismissableContext);
|
|
74
|
+
const [count, setCount] = React.useState(0);
|
|
75
|
+
React.useEffect(() => {
|
|
76
|
+
const check = () => {
|
|
77
|
+
const el = ref.current;
|
|
78
|
+
if (!el) {
|
|
79
|
+
setCount(0);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
let above = 0;
|
|
83
|
+
for (const layer of context.layers) {
|
|
84
|
+
if (layer.contains(el)) {
|
|
85
|
+
above++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
setCount(above);
|
|
89
|
+
};
|
|
90
|
+
check();
|
|
91
|
+
document.addEventListener(CONTEXT_UPDATE, check);
|
|
92
|
+
return () => document.removeEventListener(CONTEXT_UPDATE, check);
|
|
93
|
+
}, [context.layers, ref]);
|
|
94
|
+
return count;
|
|
96
95
|
}
|
|
97
|
-
const Dismissable =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
|
|
214
|
-
onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
|
|
215
|
-
onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
|
|
216
|
-
onPointerDownCapture: composeEventHandlers(props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture),
|
|
217
|
-
children
|
|
218
|
-
});
|
|
96
|
+
const Dismissable = createRefComponent((props, forwardedRef) => {
|
|
97
|
+
const { disableOutsidePointerEvents = false, forceUnmount, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, asChild, children, branches: branchesProp, ...layerProps } = props;
|
|
98
|
+
const Comp = asChild ? Slot : View;
|
|
99
|
+
const context = React.useContext(DismissableContext);
|
|
100
|
+
const [node, setNode] = React.useState(null);
|
|
101
|
+
const [, force] = React.useState({});
|
|
102
|
+
const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
|
|
103
|
+
const layers = Array.from(context.layers);
|
|
104
|
+
const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
|
|
105
|
+
const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
|
|
106
|
+
const index = node ? layers.indexOf(node) : -1;
|
|
107
|
+
const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
|
|
108
|
+
const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;
|
|
109
|
+
const pointerDownOutside = usePointerDownOutside((event) => {
|
|
110
|
+
const target = event.target;
|
|
111
|
+
const branches = branchesProp || context.branches;
|
|
112
|
+
const isPointerDownOnBranch = [...branches].some((branch) => branch.contains(target));
|
|
113
|
+
if (!isPointerEventsEnabled || isPointerDownOnBranch) return;
|
|
114
|
+
const details = createChangeEventDetails("outside-press", event, event.target, { interaction: "pointer" });
|
|
115
|
+
onPointerDownOutside?.(details);
|
|
116
|
+
onInteractOutside?.(details);
|
|
117
|
+
if (!details.isCanceled) onDismiss?.(details);
|
|
118
|
+
});
|
|
119
|
+
const focusOutside = useFocusOutside((event) => {
|
|
120
|
+
const target = event.target;
|
|
121
|
+
const branches = branchesProp || context.branches;
|
|
122
|
+
const isFocusInBranch = [...branches].some((branch) => branch.contains(target));
|
|
123
|
+
if (isFocusInBranch) return;
|
|
124
|
+
if (node && target.contains(node)) return;
|
|
125
|
+
const details = createChangeEventDetails("focus-out", event, event.target, { interaction: "focus" });
|
|
126
|
+
onFocusOutside?.(details);
|
|
127
|
+
onInteractOutside?.(details);
|
|
128
|
+
if (!details.isCanceled) onDismiss?.(details);
|
|
129
|
+
});
|
|
130
|
+
const forceUnmountRef = React.useRef(forceUnmount);
|
|
131
|
+
React.useEffect(() => {
|
|
132
|
+
forceUnmountRef.current = forceUnmount;
|
|
133
|
+
}, [forceUnmount]);
|
|
134
|
+
useEscapeKeydown((event) => {
|
|
135
|
+
if (event.defaultPrevented) return;
|
|
136
|
+
if (forceUnmountRef.current) return;
|
|
137
|
+
const currentLayers = Array.from(context.layers);
|
|
138
|
+
const currentIndex = node ? currentLayers.indexOf(node) : -1;
|
|
139
|
+
const isHighestLayer = currentIndex === currentLayers.length - 1;
|
|
140
|
+
if (!isHighestLayer) return;
|
|
141
|
+
const details = createChangeEventDetails("escape-key", event, event.target);
|
|
142
|
+
onEscapeKeyDown?.(details);
|
|
143
|
+
if (!details.isCanceled && onDismiss) {
|
|
144
|
+
event.preventDefault();
|
|
145
|
+
onDismiss(details);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
React.useEffect(() => {
|
|
149
|
+
if (!node) return;
|
|
150
|
+
if (forceUnmount) return;
|
|
151
|
+
context.layers.add(node);
|
|
152
|
+
globalLayers.add(node);
|
|
153
|
+
dispatchUpdate();
|
|
154
|
+
notifyLayerChange();
|
|
155
|
+
return () => {
|
|
156
|
+
context.layers.delete(node);
|
|
157
|
+
globalLayers.delete(node);
|
|
158
|
+
dispatchUpdate();
|
|
159
|
+
notifyLayerChange();
|
|
160
|
+
};
|
|
161
|
+
}, [
|
|
162
|
+
node,
|
|
163
|
+
forceUnmount,
|
|
164
|
+
context
|
|
165
|
+
]);
|
|
166
|
+
React.useEffect(() => {
|
|
167
|
+
if (!node) return;
|
|
168
|
+
if (forceUnmount) return;
|
|
169
|
+
if (!disableOutsidePointerEvents) return;
|
|
170
|
+
if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
|
|
171
|
+
originalBodyPointerEvents = document.body.style.pointerEvents;
|
|
172
|
+
document.body.style.pointerEvents = "none";
|
|
173
|
+
}
|
|
174
|
+
context.layersWithOutsidePointerEventsDisabled.add(node);
|
|
175
|
+
layersWithPointerEventsDisabledCount++;
|
|
176
|
+
dispatchUpdate();
|
|
177
|
+
notifyLayerChange();
|
|
178
|
+
return () => {
|
|
179
|
+
context.layersWithOutsidePointerEventsDisabled.delete(node);
|
|
180
|
+
if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
|
|
181
|
+
document.body.style.pointerEvents = originalBodyPointerEvents;
|
|
182
|
+
}
|
|
183
|
+
dispatchUpdate();
|
|
184
|
+
notifyLayerChange();
|
|
185
|
+
layersWithPointerEventsDisabledCount--;
|
|
186
|
+
};
|
|
187
|
+
}, [
|
|
188
|
+
node,
|
|
189
|
+
disableOutsidePointerEvents,
|
|
190
|
+
forceUnmount,
|
|
191
|
+
context
|
|
192
|
+
]);
|
|
193
|
+
React.useEffect(() => {
|
|
194
|
+
const handleUpdate = () => {
|
|
195
|
+
if (layersWithPointerEventsDisabledCount > 0) {
|
|
196
|
+
force({});
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
document.addEventListener(CONTEXT_UPDATE, handleUpdate);
|
|
200
|
+
return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
|
|
201
|
+
}, []);
|
|
202
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
203
|
+
...layerProps,
|
|
204
|
+
ref: composedRefs,
|
|
205
|
+
...!asChild && { display: "contents" },
|
|
206
|
+
pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
|
|
207
|
+
onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
|
|
208
|
+
onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
|
|
209
|
+
onPointerDownCapture: composeEventHandlers(props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture),
|
|
210
|
+
children
|
|
211
|
+
});
|
|
219
212
|
});
|
|
220
213
|
Dismissable.displayName = DISMISSABLE_LAYER_NAME;
|
|
221
214
|
const BRANCH_NAME = "DismissableBranch";
|
|
222
|
-
const DismissableBranch =
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
...rest,
|
|
244
|
-
ref: composedRefs
|
|
245
|
-
});
|
|
215
|
+
const DismissableBranch = createRefComponent((props, forwardedRef) => {
|
|
216
|
+
const { branches: branchesProp, ...rest } = props;
|
|
217
|
+
const context = React.useContext(DismissableContext);
|
|
218
|
+
const ref = React.useRef(null);
|
|
219
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
220
|
+
React.useEffect(() => {
|
|
221
|
+
const node = ref.current;
|
|
222
|
+
if (!(node instanceof HTMLElement)) return;
|
|
223
|
+
const branches = branchesProp || context.branches;
|
|
224
|
+
if (node && branches) {
|
|
225
|
+
branches.add(node);
|
|
226
|
+
return () => {
|
|
227
|
+
branches.delete(node);
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}, [branchesProp, context.branches]);
|
|
231
|
+
return /* @__PURE__ */ jsx(View, {
|
|
232
|
+
asChild: "except-style",
|
|
233
|
+
...rest,
|
|
234
|
+
ref: composedRefs
|
|
235
|
+
});
|
|
246
236
|
});
|
|
247
237
|
DismissableBranch.displayName = BRANCH_NAME;
|
|
248
238
|
function usePointerDownOutside(onPointerDownOutside) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
};
|
|
283
|
-
}, [handlePointerDownOutside]);
|
|
284
|
-
return {
|
|
285
|
-
// ensures we check React component tree (not just DOM tree)
|
|
286
|
-
onPointerDownCapture: () => {
|
|
287
|
-
isPointerInsideReactTreeRef.current = true;
|
|
288
|
-
}
|
|
289
|
-
};
|
|
239
|
+
const handlePointerDownOutside = useEvent(onPointerDownOutside);
|
|
240
|
+
const isPointerInsideReactTreeRef = React.useRef(false);
|
|
241
|
+
const handleClickRef = React.useRef(() => {});
|
|
242
|
+
React.useEffect(() => {
|
|
243
|
+
const handlePointerDown = (event) => {
|
|
244
|
+
if (event.target && !isPointerInsideReactTreeRef.current) {
|
|
245
|
+
let handlePointerDownOutsideEvent = function() {
|
|
246
|
+
if (handlePointerDownOutside) {
|
|
247
|
+
ReactDOM.flushSync(() => handlePointerDownOutside(event));
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
if (event.pointerType === "touch") {
|
|
251
|
+
document.removeEventListener("click", handleClickRef.current);
|
|
252
|
+
handleClickRef.current = handlePointerDownOutsideEvent;
|
|
253
|
+
document.addEventListener("click", handleClickRef.current, { once: true });
|
|
254
|
+
} else {
|
|
255
|
+
handlePointerDownOutsideEvent();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
isPointerInsideReactTreeRef.current = false;
|
|
259
|
+
};
|
|
260
|
+
const timerId = setTimeout(() => {
|
|
261
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
262
|
+
}, 0);
|
|
263
|
+
return () => {
|
|
264
|
+
window.clearTimeout(timerId);
|
|
265
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
266
|
+
document.removeEventListener("click", handleClickRef.current);
|
|
267
|
+
};
|
|
268
|
+
}, [handlePointerDownOutside]);
|
|
269
|
+
return { onPointerDownCapture: () => {
|
|
270
|
+
isPointerInsideReactTreeRef.current = true;
|
|
271
|
+
} };
|
|
290
272
|
}
|
|
291
273
|
function useFocusOutside(onFocusOutside) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
},
|
|
312
|
-
onBlurCapture: () => {
|
|
313
|
-
isFocusInsideReactTreeRef.current = false;
|
|
314
|
-
}
|
|
315
|
-
};
|
|
274
|
+
const handleFocusOutside = useEvent(onFocusOutside);
|
|
275
|
+
const isFocusInsideReactTreeRef = React.useRef(false);
|
|
276
|
+
React.useEffect(() => {
|
|
277
|
+
const handleFocus = (event) => {
|
|
278
|
+
if (event.target && !isFocusInsideReactTreeRef.current) {
|
|
279
|
+
handleFocusOutside?.(event);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
document.addEventListener("focusin", handleFocus);
|
|
283
|
+
return () => document.removeEventListener("focusin", handleFocus);
|
|
284
|
+
}, [handleFocusOutside]);
|
|
285
|
+
return {
|
|
286
|
+
onFocusCapture: () => {
|
|
287
|
+
isFocusInsideReactTreeRef.current = true;
|
|
288
|
+
},
|
|
289
|
+
onBlurCapture: () => {
|
|
290
|
+
isFocusInsideReactTreeRef.current = false;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
316
293
|
}
|
|
317
294
|
function dispatchUpdate() {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
function handleAndDispatchCustomEvent(name, handler, detail, {
|
|
322
|
-
discrete
|
|
323
|
-
}) {
|
|
324
|
-
const target = detail.originalEvent.target;
|
|
325
|
-
const event = new CustomEvent(name, {
|
|
326
|
-
bubbles: false,
|
|
327
|
-
cancelable: true,
|
|
328
|
-
detail
|
|
329
|
-
});
|
|
330
|
-
if (handler) target.addEventListener(name, handler, {
|
|
331
|
-
once: true
|
|
332
|
-
});
|
|
333
|
-
if (discrete) {
|
|
334
|
-
dispatchDiscreteCustomEvent(target, event);
|
|
335
|
-
} else {
|
|
336
|
-
target.dispatchEvent(event);
|
|
337
|
-
}
|
|
295
|
+
const event = new CustomEvent(CONTEXT_UPDATE);
|
|
296
|
+
document.dispatchEvent(event);
|
|
338
297
|
}
|
|
298
|
+
|
|
339
299
|
export { Dismissable, DismissableBranch, debugDismissableLayers, dispatchDiscreteCustomEvent, getDismissableLayerCount, useDismissableLayersAbove, useHasDismissableLayers, useIsInsideDismissable };
|
|
340
300
|
//# sourceMappingURL=Dismissable.mjs.map
|