@huin-core/react-dismissable-layer 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+ import * as React from 'react';
2
+ import { Primitive } from '@huin-core/react-primitive';
3
+
4
+ type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
5
+ interface DismissableLayerProps extends PrimitiveDivProps {
6
+ /**
7
+ * When `true`, hover/focus/click interactions will be disabled on elements outside
8
+ * the `DismissableLayer`. Users will need to click twice on outside elements to
9
+ * interact with them: once to close the `DismissableLayer`, and again to trigger the element.
10
+ */
11
+ disableOutsidePointerEvents?: boolean;
12
+ /**
13
+ * Event handler called when the escape key is down.
14
+ * Can be prevented.
15
+ */
16
+ onEscapeKeyDown?: (event: KeyboardEvent) => void;
17
+ /**
18
+ * Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`.
19
+ * Can be prevented.
20
+ */
21
+ onPointerDownOutside?: (event: PointerDownOutsideEvent) => void;
22
+ /**
23
+ * Event handler called when the focus moves outside of the `DismissableLayer`.
24
+ * Can be prevented.
25
+ */
26
+ onFocusOutside?: (event: FocusOutsideEvent) => void;
27
+ /**
28
+ * Event handler called when an interaction happens outside the `DismissableLayer`.
29
+ * Specifically, when a `pointerdown` event happens outside or focus moves outside of it.
30
+ * Can be prevented.
31
+ */
32
+ onInteractOutside?: (event: PointerDownOutsideEvent | FocusOutsideEvent) => void;
33
+ /**
34
+ * Handler called when the `DismissableLayer` should be dismissed
35
+ */
36
+ onDismiss?: () => void;
37
+ }
38
+ declare const DismissableLayer: React.ForwardRefExoticComponent<DismissableLayerProps & React.RefAttributes<HTMLDivElement>>;
39
+ interface DismissableLayerBranchProps extends PrimitiveDivProps {
40
+ }
41
+ declare const DismissableLayerBranch: React.ForwardRefExoticComponent<DismissableLayerBranchProps & React.RefAttributes<HTMLDivElement>>;
42
+ type PointerDownOutsideEvent = CustomEvent<{
43
+ originalEvent: PointerEvent;
44
+ }>;
45
+ type FocusOutsideEvent = CustomEvent<{
46
+ originalEvent: FocusEvent;
47
+ }>;
48
+ declare const Root: React.ForwardRefExoticComponent<DismissableLayerProps & React.RefAttributes<HTMLDivElement>>;
49
+ declare const Branch: React.ForwardRefExoticComponent<DismissableLayerBranchProps & React.RefAttributes<HTMLDivElement>>;
50
+
51
+ export { Branch, DismissableLayer, DismissableLayerBranch, type DismissableLayerProps, Root };
@@ -0,0 +1,51 @@
1
+ import * as React from 'react';
2
+ import { Primitive } from '@huin-core/react-primitive';
3
+
4
+ type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
5
+ interface DismissableLayerProps extends PrimitiveDivProps {
6
+ /**
7
+ * When `true`, hover/focus/click interactions will be disabled on elements outside
8
+ * the `DismissableLayer`. Users will need to click twice on outside elements to
9
+ * interact with them: once to close the `DismissableLayer`, and again to trigger the element.
10
+ */
11
+ disableOutsidePointerEvents?: boolean;
12
+ /**
13
+ * Event handler called when the escape key is down.
14
+ * Can be prevented.
15
+ */
16
+ onEscapeKeyDown?: (event: KeyboardEvent) => void;
17
+ /**
18
+ * Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`.
19
+ * Can be prevented.
20
+ */
21
+ onPointerDownOutside?: (event: PointerDownOutsideEvent) => void;
22
+ /**
23
+ * Event handler called when the focus moves outside of the `DismissableLayer`.
24
+ * Can be prevented.
25
+ */
26
+ onFocusOutside?: (event: FocusOutsideEvent) => void;
27
+ /**
28
+ * Event handler called when an interaction happens outside the `DismissableLayer`.
29
+ * Specifically, when a `pointerdown` event happens outside or focus moves outside of it.
30
+ * Can be prevented.
31
+ */
32
+ onInteractOutside?: (event: PointerDownOutsideEvent | FocusOutsideEvent) => void;
33
+ /**
34
+ * Handler called when the `DismissableLayer` should be dismissed
35
+ */
36
+ onDismiss?: () => void;
37
+ }
38
+ declare const DismissableLayer: React.ForwardRefExoticComponent<DismissableLayerProps & React.RefAttributes<HTMLDivElement>>;
39
+ interface DismissableLayerBranchProps extends PrimitiveDivProps {
40
+ }
41
+ declare const DismissableLayerBranch: React.ForwardRefExoticComponent<DismissableLayerBranchProps & React.RefAttributes<HTMLDivElement>>;
42
+ type PointerDownOutsideEvent = CustomEvent<{
43
+ originalEvent: PointerEvent;
44
+ }>;
45
+ type FocusOutsideEvent = CustomEvent<{
46
+ originalEvent: FocusEvent;
47
+ }>;
48
+ declare const Root: React.ForwardRefExoticComponent<DismissableLayerProps & React.RefAttributes<HTMLDivElement>>;
49
+ declare const Branch: React.ForwardRefExoticComponent<DismissableLayerBranchProps & React.RefAttributes<HTMLDivElement>>;
50
+
51
+ export { Branch, DismissableLayer, DismissableLayerBranch, type DismissableLayerProps, Root };
package/dist/index.js ADDED
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // packages/react/dismissable-layer/src/index.ts
32
+ var src_exports = {};
33
+ __export(src_exports, {
34
+ Branch: () => Branch,
35
+ DismissableLayer: () => DismissableLayer,
36
+ DismissableLayerBranch: () => DismissableLayerBranch,
37
+ Root: () => Root
38
+ });
39
+ module.exports = __toCommonJS(src_exports);
40
+
41
+ // packages/react/dismissable-layer/src/DismissableLayer.tsx
42
+ var React = __toESM(require("react"));
43
+ var import_primitive = require("@huin-core/primitive");
44
+ var import_react_primitive = require("@huin-core/react-primitive");
45
+ var import_react_compose_refs = require("@huin-core/react-compose-refs");
46
+ var import_react_use_callback_ref = require("@huin-core/react-use-callback-ref");
47
+ var import_react_use_escape_keydown = require("@huin-core/react-use-escape-keydown");
48
+ var import_jsx_runtime = require("react/jsx-runtime");
49
+ var DISMISSABLE_LAYER_NAME = "DismissableLayer";
50
+ var CONTEXT_UPDATE = "dismissableLayer.update";
51
+ var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
52
+ var FOCUS_OUTSIDE = "dismissableLayer.focusOutside";
53
+ var originalBodyPointerEvents;
54
+ var DismissableLayerContext = React.createContext({
55
+ layers: /* @__PURE__ */ new Set(),
56
+ layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
57
+ branches: /* @__PURE__ */ new Set()
58
+ });
59
+ var DismissableLayer = React.forwardRef(
60
+ (props, forwardedRef) => {
61
+ const {
62
+ disableOutsidePointerEvents = false,
63
+ onEscapeKeyDown,
64
+ onPointerDownOutside,
65
+ onFocusOutside,
66
+ onInteractOutside,
67
+ onDismiss,
68
+ ...layerProps
69
+ } = props;
70
+ const context = React.useContext(DismissableLayerContext);
71
+ const [node, setNode] = React.useState(null);
72
+ const ownerDocument = node?.ownerDocument ?? globalThis?.document;
73
+ const [, force] = React.useState({});
74
+ const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node2) => setNode(node2));
75
+ const layers = Array.from(context.layers);
76
+ const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
77
+ const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
78
+ const index = node ? layers.indexOf(node) : -1;
79
+ const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
80
+ const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;
81
+ const pointerDownOutside = usePointerDownOutside((event) => {
82
+ const target = event.target;
83
+ const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));
84
+ if (!isPointerEventsEnabled || isPointerDownOnBranch) return;
85
+ onPointerDownOutside?.(event);
86
+ onInteractOutside?.(event);
87
+ if (!event.defaultPrevented) onDismiss?.();
88
+ }, ownerDocument);
89
+ const focusOutside = useFocusOutside((event) => {
90
+ const target = event.target;
91
+ const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));
92
+ if (isFocusInBranch) return;
93
+ onFocusOutside?.(event);
94
+ onInteractOutside?.(event);
95
+ if (!event.defaultPrevented) onDismiss?.();
96
+ }, ownerDocument);
97
+ (0, import_react_use_escape_keydown.useEscapeKeydown)((event) => {
98
+ const isHighestLayer = index === context.layers.size - 1;
99
+ if (!isHighestLayer) return;
100
+ onEscapeKeyDown?.(event);
101
+ if (!event.defaultPrevented && onDismiss) {
102
+ event.preventDefault();
103
+ onDismiss();
104
+ }
105
+ }, ownerDocument);
106
+ React.useEffect(() => {
107
+ if (!node) return;
108
+ if (disableOutsidePointerEvents) {
109
+ if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
110
+ originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
111
+ ownerDocument.body.style.pointerEvents = "none";
112
+ }
113
+ context.layersWithOutsidePointerEventsDisabled.add(node);
114
+ }
115
+ context.layers.add(node);
116
+ dispatchUpdate();
117
+ return () => {
118
+ if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) {
119
+ ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;
120
+ }
121
+ };
122
+ }, [node, ownerDocument, disableOutsidePointerEvents, context]);
123
+ React.useEffect(() => {
124
+ return () => {
125
+ if (!node) return;
126
+ context.layers.delete(node);
127
+ context.layersWithOutsidePointerEventsDisabled.delete(node);
128
+ dispatchUpdate();
129
+ };
130
+ }, [node, context]);
131
+ React.useEffect(() => {
132
+ const handleUpdate = () => force({});
133
+ document.addEventListener(CONTEXT_UPDATE, handleUpdate);
134
+ return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
135
+ }, []);
136
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
137
+ import_react_primitive.Primitive.div,
138
+ {
139
+ ...layerProps,
140
+ ref: composedRefs,
141
+ style: {
142
+ pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
143
+ ...props.style
144
+ },
145
+ onFocusCapture: (0, import_primitive.composeEventHandlers)(props.onFocusCapture, focusOutside.onFocusCapture),
146
+ onBlurCapture: (0, import_primitive.composeEventHandlers)(props.onBlurCapture, focusOutside.onBlurCapture),
147
+ onPointerDownCapture: (0, import_primitive.composeEventHandlers)(
148
+ props.onPointerDownCapture,
149
+ pointerDownOutside.onPointerDownCapture
150
+ )
151
+ }
152
+ );
153
+ }
154
+ );
155
+ DismissableLayer.displayName = DISMISSABLE_LAYER_NAME;
156
+ var BRANCH_NAME = "DismissableLayerBranch";
157
+ var DismissableLayerBranch = React.forwardRef((props, forwardedRef) => {
158
+ const context = React.useContext(DismissableLayerContext);
159
+ const ref = React.useRef(null);
160
+ const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref);
161
+ React.useEffect(() => {
162
+ const node = ref.current;
163
+ if (node) {
164
+ context.branches.add(node);
165
+ return () => {
166
+ context.branches.delete(node);
167
+ };
168
+ }
169
+ }, [context.branches]);
170
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...props, ref: composedRefs });
171
+ });
172
+ DismissableLayerBranch.displayName = BRANCH_NAME;
173
+ function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis?.document) {
174
+ const handlePointerDownOutside = (0, import_react_use_callback_ref.useCallbackRef)(onPointerDownOutside);
175
+ const isPointerInsideReactTreeRef = React.useRef(false);
176
+ const handleClickRef = React.useRef(() => {
177
+ });
178
+ React.useEffect(() => {
179
+ const handlePointerDown = (event) => {
180
+ if (event.target && !isPointerInsideReactTreeRef.current) {
181
+ let handleAndDispatchPointerDownOutsideEvent2 = function() {
182
+ handleAndDispatchCustomEvent(
183
+ POINTER_DOWN_OUTSIDE,
184
+ handlePointerDownOutside,
185
+ eventDetail,
186
+ { discrete: true }
187
+ );
188
+ };
189
+ var handleAndDispatchPointerDownOutsideEvent = handleAndDispatchPointerDownOutsideEvent2;
190
+ const eventDetail = { originalEvent: event };
191
+ if (event.pointerType === "touch") {
192
+ ownerDocument.removeEventListener("click", handleClickRef.current);
193
+ handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2;
194
+ ownerDocument.addEventListener("click", handleClickRef.current, { once: true });
195
+ } else {
196
+ handleAndDispatchPointerDownOutsideEvent2();
197
+ }
198
+ } else {
199
+ ownerDocument.removeEventListener("click", handleClickRef.current);
200
+ }
201
+ isPointerInsideReactTreeRef.current = false;
202
+ };
203
+ const timerId = window.setTimeout(() => {
204
+ ownerDocument.addEventListener("pointerdown", handlePointerDown);
205
+ }, 0);
206
+ return () => {
207
+ window.clearTimeout(timerId);
208
+ ownerDocument.removeEventListener("pointerdown", handlePointerDown);
209
+ ownerDocument.removeEventListener("click", handleClickRef.current);
210
+ };
211
+ }, [ownerDocument, handlePointerDownOutside]);
212
+ return {
213
+ // ensures we check React component tree (not just DOM tree)
214
+ onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true
215
+ };
216
+ }
217
+ function useFocusOutside(onFocusOutside, ownerDocument = globalThis?.document) {
218
+ const handleFocusOutside = (0, import_react_use_callback_ref.useCallbackRef)(onFocusOutside);
219
+ const isFocusInsideReactTreeRef = React.useRef(false);
220
+ React.useEffect(() => {
221
+ const handleFocus = (event) => {
222
+ if (event.target && !isFocusInsideReactTreeRef.current) {
223
+ const eventDetail = { originalEvent: event };
224
+ handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {
225
+ discrete: false
226
+ });
227
+ }
228
+ };
229
+ ownerDocument.addEventListener("focusin", handleFocus);
230
+ return () => ownerDocument.removeEventListener("focusin", handleFocus);
231
+ }, [ownerDocument, handleFocusOutside]);
232
+ return {
233
+ onFocusCapture: () => isFocusInsideReactTreeRef.current = true,
234
+ onBlurCapture: () => isFocusInsideReactTreeRef.current = false
235
+ };
236
+ }
237
+ function dispatchUpdate() {
238
+ const event = new CustomEvent(CONTEXT_UPDATE);
239
+ document.dispatchEvent(event);
240
+ }
241
+ function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
242
+ const target = detail.originalEvent.target;
243
+ const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });
244
+ if (handler) target.addEventListener(name, handler, { once: true });
245
+ if (discrete) {
246
+ (0, import_react_primitive.dispatchDiscreteCustomEvent)(target, event);
247
+ } else {
248
+ target.dispatchEvent(event);
249
+ }
250
+ }
251
+ var Root = DismissableLayer;
252
+ var Branch = DismissableLayerBranch;
253
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/DismissableLayer.tsx"],
4
+ "sourcesContent": ["'use client';\nexport {\n DismissableLayer,\n DismissableLayerBranch,\n //\n Root,\n Branch,\n} from './DismissableLayer';\nexport type { DismissableLayerProps } from './DismissableLayer';\n", "import * as React from 'react';\nimport { composeEventHandlers } from '@huin-core/primitive';\nimport { Primitive, dispatchDiscreteCustomEvent } from '@huin-core/react-primitive';\nimport { useComposedRefs } from '@huin-core/react-compose-refs';\nimport { useCallbackRef } from '@huin-core/react-use-callback-ref';\nimport { useEscapeKeydown } from '@huin-core/react-use-escape-keydown';\n\n/* -------------------------------------------------------------------------------------------------\n * DismissableLayer\n * -----------------------------------------------------------------------------------------------*/\n\nconst DISMISSABLE_LAYER_NAME = 'DismissableLayer';\nconst CONTEXT_UPDATE = 'dismissableLayer.update';\nconst POINTER_DOWN_OUTSIDE = 'dismissableLayer.pointerDownOutside';\nconst FOCUS_OUTSIDE = 'dismissableLayer.focusOutside';\n\nlet originalBodyPointerEvents: string;\n\nconst DismissableLayerContext = React.createContext({\n layers: new Set<DismissableLayerElement>(),\n layersWithOutsidePointerEventsDisabled: new Set<DismissableLayerElement>(),\n branches: new Set<DismissableLayerBranchElement>(),\n});\n\ntype DismissableLayerElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface DismissableLayerProps extends PrimitiveDivProps {\n /**\n * When `true`, hover/focus/click interactions will be disabled on elements outside\n * the `DismissableLayer`. Users will need to click twice on outside elements to\n * interact with them: once to close the `DismissableLayer`, and again to trigger the element.\n */\n disableOutsidePointerEvents?: boolean;\n /**\n * Event handler called when the escape key is down.\n * Can be prevented.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /**\n * Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`.\n * Can be prevented.\n */\n onPointerDownOutside?: (event: PointerDownOutsideEvent) => void;\n /**\n * Event handler called when the focus moves outside of the `DismissableLayer`.\n * Can be prevented.\n */\n onFocusOutside?: (event: FocusOutsideEvent) => void;\n /**\n * Event handler called when an interaction happens outside the `DismissableLayer`.\n * Specifically, when a `pointerdown` event happens outside or focus moves outside of it.\n * Can be prevented.\n */\n onInteractOutside?: (event: PointerDownOutsideEvent | FocusOutsideEvent) => void;\n /**\n * Handler called when the `DismissableLayer` should be dismissed\n */\n onDismiss?: () => void;\n}\n\nconst DismissableLayer = React.forwardRef<DismissableLayerElement, DismissableLayerProps>(\n (props, forwardedRef) => {\n const {\n disableOutsidePointerEvents = false,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside,\n onInteractOutside,\n onDismiss,\n ...layerProps\n } = props;\n const context = React.useContext(DismissableLayerContext);\n const [node, setNode] = React.useState<DismissableLayerElement | null>(null);\n const ownerDocument = node?.ownerDocument ?? globalThis?.document;\n const [, force] = React.useState({});\n const composedRefs = useComposedRefs(forwardedRef, (node) => setNode(node));\n const layers = Array.from(context.layers);\n const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1); // prettier-ignore\n const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled); // prettier-ignore\n const index = node ? layers.indexOf(node) : -1;\n const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;\n const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;\n\n const pointerDownOutside = usePointerDownOutside((event) => {\n const target = event.target as HTMLElement;\n const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));\n if (!isPointerEventsEnabled || isPointerDownOnBranch) return;\n onPointerDownOutside?.(event);\n onInteractOutside?.(event);\n if (!event.defaultPrevented) onDismiss?.();\n }, ownerDocument);\n\n const focusOutside = useFocusOutside((event) => {\n const target = event.target as HTMLElement;\n const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));\n if (isFocusInBranch) return;\n onFocusOutside?.(event);\n onInteractOutside?.(event);\n if (!event.defaultPrevented) onDismiss?.();\n }, ownerDocument);\n\n useEscapeKeydown((event) => {\n const isHighestLayer = index === context.layers.size - 1;\n if (!isHighestLayer) return;\n onEscapeKeyDown?.(event);\n if (!event.defaultPrevented && onDismiss) {\n event.preventDefault();\n onDismiss();\n }\n }, ownerDocument);\n\n React.useEffect(() => {\n if (!node) return;\n if (disableOutsidePointerEvents) {\n if (context.layersWithOutsidePointerEventsDisabled.size === 0) {\n originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;\n ownerDocument.body.style.pointerEvents = 'none';\n }\n context.layersWithOutsidePointerEventsDisabled.add(node);\n }\n context.layers.add(node);\n dispatchUpdate();\n return () => {\n if (\n disableOutsidePointerEvents &&\n context.layersWithOutsidePointerEventsDisabled.size === 1\n ) {\n ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;\n }\n };\n }, [node, ownerDocument, disableOutsidePointerEvents, context]);\n\n /**\n * We purposefully prevent combining this effect with the `disableOutsidePointerEvents` effect\n * because a change to `disableOutsidePointerEvents` would remove this layer from the stack\n * and add it to the end again so the layering order wouldn't be _creation order_.\n * We only want them to be removed from context stacks when unmounted.\n */\n React.useEffect(() => {\n return () => {\n if (!node) return;\n context.layers.delete(node);\n context.layersWithOutsidePointerEventsDisabled.delete(node);\n dispatchUpdate();\n };\n }, [node, context]);\n\n React.useEffect(() => {\n const handleUpdate = () => force({});\n document.addEventListener(CONTEXT_UPDATE, handleUpdate);\n return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);\n }, []);\n\n return (\n <Primitive.div\n {...layerProps}\n ref={composedRefs}\n style={{\n pointerEvents: isBodyPointerEventsDisabled\n ? isPointerEventsEnabled\n ? 'auto'\n : 'none'\n : undefined,\n ...props.style,\n }}\n onFocusCapture={composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture)}\n onBlurCapture={composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture)}\n onPointerDownCapture={composeEventHandlers(\n props.onPointerDownCapture,\n pointerDownOutside.onPointerDownCapture\n )}\n />\n );\n }\n);\n\nDismissableLayer.displayName = DISMISSABLE_LAYER_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * DismissableLayerBranch\n * -----------------------------------------------------------------------------------------------*/\n\nconst BRANCH_NAME = 'DismissableLayerBranch';\n\ntype DismissableLayerBranchElement = React.ElementRef<typeof Primitive.div>;\ninterface DismissableLayerBranchProps extends PrimitiveDivProps {}\n\nconst DismissableLayerBranch = React.forwardRef<\n DismissableLayerBranchElement,\n DismissableLayerBranchProps\n>((props, forwardedRef) => {\n const context = React.useContext(DismissableLayerContext);\n const ref = React.useRef<DismissableLayerBranchElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n context.branches.add(node);\n return () => {\n context.branches.delete(node);\n };\n }\n }, [context.branches]);\n\n return <Primitive.div {...props} ref={composedRefs} />;\n});\n\nDismissableLayerBranch.displayName = BRANCH_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype PointerDownOutsideEvent = CustomEvent<{ originalEvent: PointerEvent }>;\ntype FocusOutsideEvent = CustomEvent<{ originalEvent: FocusEvent }>;\n\n/**\n * Listens for `pointerdown` outside a react subtree. We use `pointerdown` rather than `pointerup`\n * to mimic layer dismissing behaviour present in OS.\n * Returns props to pass to the node we want to check for outside events.\n */\nfunction usePointerDownOutside(\n onPointerDownOutside?: (event: PointerDownOutsideEvent) => void,\n ownerDocument: Document = globalThis?.document\n) {\n const handlePointerDownOutside = useCallbackRef(onPointerDownOutside) as EventListener;\n const isPointerInsideReactTreeRef = React.useRef(false);\n const handleClickRef = React.useRef(() => {});\n\n React.useEffect(() => {\n const handlePointerDown = (event: PointerEvent) => {\n if (event.target && !isPointerInsideReactTreeRef.current) {\n const eventDetail = { originalEvent: event };\n\n function handleAndDispatchPointerDownOutsideEvent() {\n handleAndDispatchCustomEvent(\n POINTER_DOWN_OUTSIDE,\n handlePointerDownOutside,\n eventDetail,\n { discrete: true }\n );\n }\n\n /**\n * On touch devices, we need to wait for a click event because browsers implement\n * a ~350ms delay between the time the user stops touching the display and when the\n * browser executres events. We need to ensure we don't reactivate pointer-events within\n * this timeframe otherwise the browser may execute events that should have been prevented.\n *\n * Additionally, this also lets us deal automatically with cancellations when a click event\n * isn't raised because the page was considered scrolled/drag-scrolled, long-pressed, etc.\n *\n * This is why we also continuously remove the previous listener, because we cannot be\n * certain that it was raised, and therefore cleaned-up.\n */\n if (event.pointerType === 'touch') {\n ownerDocument.removeEventListener('click', handleClickRef.current);\n handleClickRef.current = handleAndDispatchPointerDownOutsideEvent;\n ownerDocument.addEventListener('click', handleClickRef.current, { once: true });\n } else {\n handleAndDispatchPointerDownOutsideEvent();\n }\n } else {\n // We need to remove the event listener in case the outside click has been canceled.\n // See: https://github.com/firatorhan/huin-core/issues/2171\n ownerDocument.removeEventListener('click', handleClickRef.current);\n }\n isPointerInsideReactTreeRef.current = false;\n };\n /**\n * if this hook executes in a component that mounts via a `pointerdown` event, the event\n * would bubble up to the document and trigger a `pointerDownOutside` event. We avoid\n * this by delaying the event listener registration on the document.\n * This is not React specific, but rather how the DOM works, ie:\n * ```\n * button.addEventListener('pointerdown', () => {\n * console.log('I will log');\n * document.addEventListener('pointerdown', () => {\n * console.log('I will also log');\n * })\n * });\n */\n const timerId = window.setTimeout(() => {\n ownerDocument.addEventListener('pointerdown', handlePointerDown);\n }, 0);\n return () => {\n window.clearTimeout(timerId);\n ownerDocument.removeEventListener('pointerdown', handlePointerDown);\n ownerDocument.removeEventListener('click', handleClickRef.current);\n };\n }, [ownerDocument, handlePointerDownOutside]);\n\n return {\n // ensures we check React component tree (not just DOM tree)\n onPointerDownCapture: () => (isPointerInsideReactTreeRef.current = true),\n };\n}\n\n/**\n * Listens for when focus happens outside a react subtree.\n * Returns props to pass to the root (node) of the subtree we want to check.\n */\nfunction useFocusOutside(\n onFocusOutside?: (event: FocusOutsideEvent) => void,\n ownerDocument: Document = globalThis?.document\n) {\n const handleFocusOutside = useCallbackRef(onFocusOutside) as EventListener;\n const isFocusInsideReactTreeRef = React.useRef(false);\n\n React.useEffect(() => {\n const handleFocus = (event: FocusEvent) => {\n if (event.target && !isFocusInsideReactTreeRef.current) {\n const eventDetail = { originalEvent: event };\n handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {\n discrete: false,\n });\n }\n };\n ownerDocument.addEventListener('focusin', handleFocus);\n return () => ownerDocument.removeEventListener('focusin', handleFocus);\n }, [ownerDocument, handleFocusOutside]);\n\n return {\n onFocusCapture: () => (isFocusInsideReactTreeRef.current = true),\n onBlurCapture: () => (isFocusInsideReactTreeRef.current = false),\n };\n}\n\nfunction dispatchUpdate() {\n const event = new CustomEvent(CONTEXT_UPDATE);\n document.dispatchEvent(event);\n}\n\nfunction handleAndDispatchCustomEvent<E extends CustomEvent, OriginalEvent extends Event>(\n name: string,\n handler: ((event: E) => void) | undefined,\n detail: { originalEvent: OriginalEvent } & (E extends CustomEvent<infer D> ? D : never),\n { discrete }: { discrete: boolean }\n) {\n const target = detail.originalEvent.target;\n const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });\n if (handler) target.addEventListener(name, handler as EventListener, { once: true });\n\n if (discrete) {\n dispatchDiscreteCustomEvent(target, event);\n } else {\n target.dispatchEvent(event);\n }\n}\n\nconst Root = DismissableLayer;\nconst Branch = DismissableLayerBranch;\n\nexport {\n DismissableLayer,\n DismissableLayerBranch,\n //\n Root,\n Branch,\n};\nexport type { DismissableLayerProps };\n"],
5
+ "mappings": "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",
6
+ "names": ["node", "handleAndDispatchPointerDownOutsideEvent"]
7
+ }
package/dist/index.mjs ADDED
@@ -0,0 +1,221 @@
1
+ "use client";
2
+
3
+ // packages/react/dismissable-layer/src/DismissableLayer.tsx
4
+ import * as React from "react";
5
+ import { composeEventHandlers } from "@huin-core/primitive";
6
+ import { Primitive, dispatchDiscreteCustomEvent } from "@huin-core/react-primitive";
7
+ import { useComposedRefs } from "@huin-core/react-compose-refs";
8
+ import { useCallbackRef } from "@huin-core/react-use-callback-ref";
9
+ import { useEscapeKeydown } from "@huin-core/react-use-escape-keydown";
10
+ import { jsx } from "react/jsx-runtime";
11
+ var DISMISSABLE_LAYER_NAME = "DismissableLayer";
12
+ var CONTEXT_UPDATE = "dismissableLayer.update";
13
+ var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
14
+ var FOCUS_OUTSIDE = "dismissableLayer.focusOutside";
15
+ var originalBodyPointerEvents;
16
+ var DismissableLayerContext = React.createContext({
17
+ layers: /* @__PURE__ */ new Set(),
18
+ layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
19
+ branches: /* @__PURE__ */ new Set()
20
+ });
21
+ var DismissableLayer = React.forwardRef(
22
+ (props, forwardedRef) => {
23
+ const {
24
+ disableOutsidePointerEvents = false,
25
+ onEscapeKeyDown,
26
+ onPointerDownOutside,
27
+ onFocusOutside,
28
+ onInteractOutside,
29
+ onDismiss,
30
+ ...layerProps
31
+ } = props;
32
+ const context = React.useContext(DismissableLayerContext);
33
+ const [node, setNode] = React.useState(null);
34
+ const ownerDocument = node?.ownerDocument ?? globalThis?.document;
35
+ const [, force] = React.useState({});
36
+ const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
37
+ const layers = Array.from(context.layers);
38
+ const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
39
+ const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
40
+ const index = node ? layers.indexOf(node) : -1;
41
+ const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
42
+ const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;
43
+ const pointerDownOutside = usePointerDownOutside((event) => {
44
+ const target = event.target;
45
+ const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));
46
+ if (!isPointerEventsEnabled || isPointerDownOnBranch) return;
47
+ onPointerDownOutside?.(event);
48
+ onInteractOutside?.(event);
49
+ if (!event.defaultPrevented) onDismiss?.();
50
+ }, ownerDocument);
51
+ const focusOutside = useFocusOutside((event) => {
52
+ const target = event.target;
53
+ const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));
54
+ if (isFocusInBranch) return;
55
+ onFocusOutside?.(event);
56
+ onInteractOutside?.(event);
57
+ if (!event.defaultPrevented) onDismiss?.();
58
+ }, ownerDocument);
59
+ useEscapeKeydown((event) => {
60
+ const isHighestLayer = index === context.layers.size - 1;
61
+ if (!isHighestLayer) return;
62
+ onEscapeKeyDown?.(event);
63
+ if (!event.defaultPrevented && onDismiss) {
64
+ event.preventDefault();
65
+ onDismiss();
66
+ }
67
+ }, ownerDocument);
68
+ React.useEffect(() => {
69
+ if (!node) return;
70
+ if (disableOutsidePointerEvents) {
71
+ if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
72
+ originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
73
+ ownerDocument.body.style.pointerEvents = "none";
74
+ }
75
+ context.layersWithOutsidePointerEventsDisabled.add(node);
76
+ }
77
+ context.layers.add(node);
78
+ dispatchUpdate();
79
+ return () => {
80
+ if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) {
81
+ ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;
82
+ }
83
+ };
84
+ }, [node, ownerDocument, disableOutsidePointerEvents, context]);
85
+ React.useEffect(() => {
86
+ return () => {
87
+ if (!node) return;
88
+ context.layers.delete(node);
89
+ context.layersWithOutsidePointerEventsDisabled.delete(node);
90
+ dispatchUpdate();
91
+ };
92
+ }, [node, context]);
93
+ React.useEffect(() => {
94
+ const handleUpdate = () => force({});
95
+ document.addEventListener(CONTEXT_UPDATE, handleUpdate);
96
+ return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
97
+ }, []);
98
+ return /* @__PURE__ */ jsx(
99
+ Primitive.div,
100
+ {
101
+ ...layerProps,
102
+ ref: composedRefs,
103
+ style: {
104
+ pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
105
+ ...props.style
106
+ },
107
+ onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
108
+ onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
109
+ onPointerDownCapture: composeEventHandlers(
110
+ props.onPointerDownCapture,
111
+ pointerDownOutside.onPointerDownCapture
112
+ )
113
+ }
114
+ );
115
+ }
116
+ );
117
+ DismissableLayer.displayName = DISMISSABLE_LAYER_NAME;
118
+ var BRANCH_NAME = "DismissableLayerBranch";
119
+ var DismissableLayerBranch = React.forwardRef((props, forwardedRef) => {
120
+ const context = React.useContext(DismissableLayerContext);
121
+ const ref = React.useRef(null);
122
+ const composedRefs = useComposedRefs(forwardedRef, ref);
123
+ React.useEffect(() => {
124
+ const node = ref.current;
125
+ if (node) {
126
+ context.branches.add(node);
127
+ return () => {
128
+ context.branches.delete(node);
129
+ };
130
+ }
131
+ }, [context.branches]);
132
+ return /* @__PURE__ */ jsx(Primitive.div, { ...props, ref: composedRefs });
133
+ });
134
+ DismissableLayerBranch.displayName = BRANCH_NAME;
135
+ function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis?.document) {
136
+ const handlePointerDownOutside = useCallbackRef(onPointerDownOutside);
137
+ const isPointerInsideReactTreeRef = React.useRef(false);
138
+ const handleClickRef = React.useRef(() => {
139
+ });
140
+ React.useEffect(() => {
141
+ const handlePointerDown = (event) => {
142
+ if (event.target && !isPointerInsideReactTreeRef.current) {
143
+ let handleAndDispatchPointerDownOutsideEvent2 = function() {
144
+ handleAndDispatchCustomEvent(
145
+ POINTER_DOWN_OUTSIDE,
146
+ handlePointerDownOutside,
147
+ eventDetail,
148
+ { discrete: true }
149
+ );
150
+ };
151
+ var handleAndDispatchPointerDownOutsideEvent = handleAndDispatchPointerDownOutsideEvent2;
152
+ const eventDetail = { originalEvent: event };
153
+ if (event.pointerType === "touch") {
154
+ ownerDocument.removeEventListener("click", handleClickRef.current);
155
+ handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2;
156
+ ownerDocument.addEventListener("click", handleClickRef.current, { once: true });
157
+ } else {
158
+ handleAndDispatchPointerDownOutsideEvent2();
159
+ }
160
+ } else {
161
+ ownerDocument.removeEventListener("click", handleClickRef.current);
162
+ }
163
+ isPointerInsideReactTreeRef.current = false;
164
+ };
165
+ const timerId = window.setTimeout(() => {
166
+ ownerDocument.addEventListener("pointerdown", handlePointerDown);
167
+ }, 0);
168
+ return () => {
169
+ window.clearTimeout(timerId);
170
+ ownerDocument.removeEventListener("pointerdown", handlePointerDown);
171
+ ownerDocument.removeEventListener("click", handleClickRef.current);
172
+ };
173
+ }, [ownerDocument, handlePointerDownOutside]);
174
+ return {
175
+ // ensures we check React component tree (not just DOM tree)
176
+ onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true
177
+ };
178
+ }
179
+ function useFocusOutside(onFocusOutside, ownerDocument = globalThis?.document) {
180
+ const handleFocusOutside = useCallbackRef(onFocusOutside);
181
+ const isFocusInsideReactTreeRef = React.useRef(false);
182
+ React.useEffect(() => {
183
+ const handleFocus = (event) => {
184
+ if (event.target && !isFocusInsideReactTreeRef.current) {
185
+ const eventDetail = { originalEvent: event };
186
+ handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {
187
+ discrete: false
188
+ });
189
+ }
190
+ };
191
+ ownerDocument.addEventListener("focusin", handleFocus);
192
+ return () => ownerDocument.removeEventListener("focusin", handleFocus);
193
+ }, [ownerDocument, handleFocusOutside]);
194
+ return {
195
+ onFocusCapture: () => isFocusInsideReactTreeRef.current = true,
196
+ onBlurCapture: () => isFocusInsideReactTreeRef.current = false
197
+ };
198
+ }
199
+ function dispatchUpdate() {
200
+ const event = new CustomEvent(CONTEXT_UPDATE);
201
+ document.dispatchEvent(event);
202
+ }
203
+ function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
204
+ const target = detail.originalEvent.target;
205
+ const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });
206
+ if (handler) target.addEventListener(name, handler, { once: true });
207
+ if (discrete) {
208
+ dispatchDiscreteCustomEvent(target, event);
209
+ } else {
210
+ target.dispatchEvent(event);
211
+ }
212
+ }
213
+ var Root = DismissableLayer;
214
+ var Branch = DismissableLayerBranch;
215
+ export {
216
+ Branch,
217
+ DismissableLayer,
218
+ DismissableLayerBranch,
219
+ Root
220
+ };
221
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/DismissableLayer.tsx"],
4
+ "sourcesContent": ["import * as React from 'react';\nimport { composeEventHandlers } from '@huin-core/primitive';\nimport { Primitive, dispatchDiscreteCustomEvent } from '@huin-core/react-primitive';\nimport { useComposedRefs } from '@huin-core/react-compose-refs';\nimport { useCallbackRef } from '@huin-core/react-use-callback-ref';\nimport { useEscapeKeydown } from '@huin-core/react-use-escape-keydown';\n\n/* -------------------------------------------------------------------------------------------------\n * DismissableLayer\n * -----------------------------------------------------------------------------------------------*/\n\nconst DISMISSABLE_LAYER_NAME = 'DismissableLayer';\nconst CONTEXT_UPDATE = 'dismissableLayer.update';\nconst POINTER_DOWN_OUTSIDE = 'dismissableLayer.pointerDownOutside';\nconst FOCUS_OUTSIDE = 'dismissableLayer.focusOutside';\n\nlet originalBodyPointerEvents: string;\n\nconst DismissableLayerContext = React.createContext({\n layers: new Set<DismissableLayerElement>(),\n layersWithOutsidePointerEventsDisabled: new Set<DismissableLayerElement>(),\n branches: new Set<DismissableLayerBranchElement>(),\n});\n\ntype DismissableLayerElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface DismissableLayerProps extends PrimitiveDivProps {\n /**\n * When `true`, hover/focus/click interactions will be disabled on elements outside\n * the `DismissableLayer`. Users will need to click twice on outside elements to\n * interact with them: once to close the `DismissableLayer`, and again to trigger the element.\n */\n disableOutsidePointerEvents?: boolean;\n /**\n * Event handler called when the escape key is down.\n * Can be prevented.\n */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /**\n * Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`.\n * Can be prevented.\n */\n onPointerDownOutside?: (event: PointerDownOutsideEvent) => void;\n /**\n * Event handler called when the focus moves outside of the `DismissableLayer`.\n * Can be prevented.\n */\n onFocusOutside?: (event: FocusOutsideEvent) => void;\n /**\n * Event handler called when an interaction happens outside the `DismissableLayer`.\n * Specifically, when a `pointerdown` event happens outside or focus moves outside of it.\n * Can be prevented.\n */\n onInteractOutside?: (event: PointerDownOutsideEvent | FocusOutsideEvent) => void;\n /**\n * Handler called when the `DismissableLayer` should be dismissed\n */\n onDismiss?: () => void;\n}\n\nconst DismissableLayer = React.forwardRef<DismissableLayerElement, DismissableLayerProps>(\n (props, forwardedRef) => {\n const {\n disableOutsidePointerEvents = false,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside,\n onInteractOutside,\n onDismiss,\n ...layerProps\n } = props;\n const context = React.useContext(DismissableLayerContext);\n const [node, setNode] = React.useState<DismissableLayerElement | null>(null);\n const ownerDocument = node?.ownerDocument ?? globalThis?.document;\n const [, force] = React.useState({});\n const composedRefs = useComposedRefs(forwardedRef, (node) => setNode(node));\n const layers = Array.from(context.layers);\n const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1); // prettier-ignore\n const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled); // prettier-ignore\n const index = node ? layers.indexOf(node) : -1;\n const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;\n const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;\n\n const pointerDownOutside = usePointerDownOutside((event) => {\n const target = event.target as HTMLElement;\n const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));\n if (!isPointerEventsEnabled || isPointerDownOnBranch) return;\n onPointerDownOutside?.(event);\n onInteractOutside?.(event);\n if (!event.defaultPrevented) onDismiss?.();\n }, ownerDocument);\n\n const focusOutside = useFocusOutside((event) => {\n const target = event.target as HTMLElement;\n const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));\n if (isFocusInBranch) return;\n onFocusOutside?.(event);\n onInteractOutside?.(event);\n if (!event.defaultPrevented) onDismiss?.();\n }, ownerDocument);\n\n useEscapeKeydown((event) => {\n const isHighestLayer = index === context.layers.size - 1;\n if (!isHighestLayer) return;\n onEscapeKeyDown?.(event);\n if (!event.defaultPrevented && onDismiss) {\n event.preventDefault();\n onDismiss();\n }\n }, ownerDocument);\n\n React.useEffect(() => {\n if (!node) return;\n if (disableOutsidePointerEvents) {\n if (context.layersWithOutsidePointerEventsDisabled.size === 0) {\n originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;\n ownerDocument.body.style.pointerEvents = 'none';\n }\n context.layersWithOutsidePointerEventsDisabled.add(node);\n }\n context.layers.add(node);\n dispatchUpdate();\n return () => {\n if (\n disableOutsidePointerEvents &&\n context.layersWithOutsidePointerEventsDisabled.size === 1\n ) {\n ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;\n }\n };\n }, [node, ownerDocument, disableOutsidePointerEvents, context]);\n\n /**\n * We purposefully prevent combining this effect with the `disableOutsidePointerEvents` effect\n * because a change to `disableOutsidePointerEvents` would remove this layer from the stack\n * and add it to the end again so the layering order wouldn't be _creation order_.\n * We only want them to be removed from context stacks when unmounted.\n */\n React.useEffect(() => {\n return () => {\n if (!node) return;\n context.layers.delete(node);\n context.layersWithOutsidePointerEventsDisabled.delete(node);\n dispatchUpdate();\n };\n }, [node, context]);\n\n React.useEffect(() => {\n const handleUpdate = () => force({});\n document.addEventListener(CONTEXT_UPDATE, handleUpdate);\n return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);\n }, []);\n\n return (\n <Primitive.div\n {...layerProps}\n ref={composedRefs}\n style={{\n pointerEvents: isBodyPointerEventsDisabled\n ? isPointerEventsEnabled\n ? 'auto'\n : 'none'\n : undefined,\n ...props.style,\n }}\n onFocusCapture={composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture)}\n onBlurCapture={composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture)}\n onPointerDownCapture={composeEventHandlers(\n props.onPointerDownCapture,\n pointerDownOutside.onPointerDownCapture\n )}\n />\n );\n }\n);\n\nDismissableLayer.displayName = DISMISSABLE_LAYER_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * DismissableLayerBranch\n * -----------------------------------------------------------------------------------------------*/\n\nconst BRANCH_NAME = 'DismissableLayerBranch';\n\ntype DismissableLayerBranchElement = React.ElementRef<typeof Primitive.div>;\ninterface DismissableLayerBranchProps extends PrimitiveDivProps {}\n\nconst DismissableLayerBranch = React.forwardRef<\n DismissableLayerBranchElement,\n DismissableLayerBranchProps\n>((props, forwardedRef) => {\n const context = React.useContext(DismissableLayerContext);\n const ref = React.useRef<DismissableLayerBranchElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n context.branches.add(node);\n return () => {\n context.branches.delete(node);\n };\n }\n }, [context.branches]);\n\n return <Primitive.div {...props} ref={composedRefs} />;\n});\n\nDismissableLayerBranch.displayName = BRANCH_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype PointerDownOutsideEvent = CustomEvent<{ originalEvent: PointerEvent }>;\ntype FocusOutsideEvent = CustomEvent<{ originalEvent: FocusEvent }>;\n\n/**\n * Listens for `pointerdown` outside a react subtree. We use `pointerdown` rather than `pointerup`\n * to mimic layer dismissing behaviour present in OS.\n * Returns props to pass to the node we want to check for outside events.\n */\nfunction usePointerDownOutside(\n onPointerDownOutside?: (event: PointerDownOutsideEvent) => void,\n ownerDocument: Document = globalThis?.document\n) {\n const handlePointerDownOutside = useCallbackRef(onPointerDownOutside) as EventListener;\n const isPointerInsideReactTreeRef = React.useRef(false);\n const handleClickRef = React.useRef(() => {});\n\n React.useEffect(() => {\n const handlePointerDown = (event: PointerEvent) => {\n if (event.target && !isPointerInsideReactTreeRef.current) {\n const eventDetail = { originalEvent: event };\n\n function handleAndDispatchPointerDownOutsideEvent() {\n handleAndDispatchCustomEvent(\n POINTER_DOWN_OUTSIDE,\n handlePointerDownOutside,\n eventDetail,\n { discrete: true }\n );\n }\n\n /**\n * On touch devices, we need to wait for a click event because browsers implement\n * a ~350ms delay between the time the user stops touching the display and when the\n * browser executres events. We need to ensure we don't reactivate pointer-events within\n * this timeframe otherwise the browser may execute events that should have been prevented.\n *\n * Additionally, this also lets us deal automatically with cancellations when a click event\n * isn't raised because the page was considered scrolled/drag-scrolled, long-pressed, etc.\n *\n * This is why we also continuously remove the previous listener, because we cannot be\n * certain that it was raised, and therefore cleaned-up.\n */\n if (event.pointerType === 'touch') {\n ownerDocument.removeEventListener('click', handleClickRef.current);\n handleClickRef.current = handleAndDispatchPointerDownOutsideEvent;\n ownerDocument.addEventListener('click', handleClickRef.current, { once: true });\n } else {\n handleAndDispatchPointerDownOutsideEvent();\n }\n } else {\n // We need to remove the event listener in case the outside click has been canceled.\n // See: https://github.com/firatorhan/huin-core/issues/2171\n ownerDocument.removeEventListener('click', handleClickRef.current);\n }\n isPointerInsideReactTreeRef.current = false;\n };\n /**\n * if this hook executes in a component that mounts via a `pointerdown` event, the event\n * would bubble up to the document and trigger a `pointerDownOutside` event. We avoid\n * this by delaying the event listener registration on the document.\n * This is not React specific, but rather how the DOM works, ie:\n * ```\n * button.addEventListener('pointerdown', () => {\n * console.log('I will log');\n * document.addEventListener('pointerdown', () => {\n * console.log('I will also log');\n * })\n * });\n */\n const timerId = window.setTimeout(() => {\n ownerDocument.addEventListener('pointerdown', handlePointerDown);\n }, 0);\n return () => {\n window.clearTimeout(timerId);\n ownerDocument.removeEventListener('pointerdown', handlePointerDown);\n ownerDocument.removeEventListener('click', handleClickRef.current);\n };\n }, [ownerDocument, handlePointerDownOutside]);\n\n return {\n // ensures we check React component tree (not just DOM tree)\n onPointerDownCapture: () => (isPointerInsideReactTreeRef.current = true),\n };\n}\n\n/**\n * Listens for when focus happens outside a react subtree.\n * Returns props to pass to the root (node) of the subtree we want to check.\n */\nfunction useFocusOutside(\n onFocusOutside?: (event: FocusOutsideEvent) => void,\n ownerDocument: Document = globalThis?.document\n) {\n const handleFocusOutside = useCallbackRef(onFocusOutside) as EventListener;\n const isFocusInsideReactTreeRef = React.useRef(false);\n\n React.useEffect(() => {\n const handleFocus = (event: FocusEvent) => {\n if (event.target && !isFocusInsideReactTreeRef.current) {\n const eventDetail = { originalEvent: event };\n handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {\n discrete: false,\n });\n }\n };\n ownerDocument.addEventListener('focusin', handleFocus);\n return () => ownerDocument.removeEventListener('focusin', handleFocus);\n }, [ownerDocument, handleFocusOutside]);\n\n return {\n onFocusCapture: () => (isFocusInsideReactTreeRef.current = true),\n onBlurCapture: () => (isFocusInsideReactTreeRef.current = false),\n };\n}\n\nfunction dispatchUpdate() {\n const event = new CustomEvent(CONTEXT_UPDATE);\n document.dispatchEvent(event);\n}\n\nfunction handleAndDispatchCustomEvent<E extends CustomEvent, OriginalEvent extends Event>(\n name: string,\n handler: ((event: E) => void) | undefined,\n detail: { originalEvent: OriginalEvent } & (E extends CustomEvent<infer D> ? D : never),\n { discrete }: { discrete: boolean }\n) {\n const target = detail.originalEvent.target;\n const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });\n if (handler) target.addEventListener(name, handler as EventListener, { once: true });\n\n if (discrete) {\n dispatchDiscreteCustomEvent(target, event);\n } else {\n target.dispatchEvent(event);\n }\n}\n\nconst Root = DismissableLayer;\nconst Branch = DismissableLayerBranch;\n\nexport {\n DismissableLayer,\n DismissableLayerBranch,\n //\n Root,\n Branch,\n};\nexport type { DismissableLayerProps };\n"],
5
+ "mappings": ";;;AAAA,YAAY,WAAW;AACvB,SAAS,4BAA4B;AACrC,SAAS,WAAW,mCAAmC;AACvD,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAqJ3B;AA/IN,IAAM,yBAAyB;AAC/B,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAC7B,IAAM,gBAAgB;AAEtB,IAAI;AAEJ,IAAM,0BAAgC,oBAAc;AAAA,EAClD,QAAQ,oBAAI,IAA6B;AAAA,EACzC,wCAAwC,oBAAI,IAA6B;AAAA,EACzE,UAAU,oBAAI,IAAmC;AACnD,CAAC;AAsCD,IAAM,mBAAyB;AAAA,EAC7B,CAAC,OAAO,iBAAiB;AACvB,UAAM;AAAA,MACJ,8BAA8B;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AACJ,UAAM,UAAgB,iBAAW,uBAAuB;AACxD,UAAM,CAAC,MAAM,OAAO,IAAU,eAAyC,IAAI;AAC3E,UAAM,gBAAgB,MAAM,iBAAiB,YAAY;AACzD,UAAM,CAAC,EAAE,KAAK,IAAU,eAAS,CAAC,CAAC;AACnC,UAAM,eAAe,gBAAgB,cAAc,CAACA,UAAS,QAAQA,KAAI,CAAC;AAC1E,UAAM,SAAS,MAAM,KAAK,QAAQ,MAAM;AACxC,UAAM,CAAC,4CAA4C,IAAI,CAAC,GAAG,QAAQ,sCAAsC,EAAE,MAAM,EAAE;AACnH,UAAM,oDAAoD,OAAO,QAAQ,4CAA4C;AACrH,UAAM,QAAQ,OAAO,OAAO,QAAQ,IAAI,IAAI;AAC5C,UAAM,8BAA8B,QAAQ,uCAAuC,OAAO;AAC1F,UAAM,yBAAyB,SAAS;AAExC,UAAM,qBAAqB,sBAAsB,CAAC,UAAU;AAC1D,YAAM,SAAS,MAAM;AACrB,YAAM,wBAAwB,CAAC,GAAG,QAAQ,QAAQ,EAAE,KAAK,CAAC,WAAW,OAAO,SAAS,MAAM,CAAC;AAC5F,UAAI,CAAC,0BAA0B,sBAAuB;AACtD,6BAAuB,KAAK;AAC5B,0BAAoB,KAAK;AACzB,UAAI,CAAC,MAAM,iBAAkB,aAAY;AAAA,IAC3C,GAAG,aAAa;AAEhB,UAAM,eAAe,gBAAgB,CAAC,UAAU;AAC9C,YAAM,SAAS,MAAM;AACrB,YAAM,kBAAkB,CAAC,GAAG,QAAQ,QAAQ,EAAE,KAAK,CAAC,WAAW,OAAO,SAAS,MAAM,CAAC;AACtF,UAAI,gBAAiB;AACrB,uBAAiB,KAAK;AACtB,0BAAoB,KAAK;AACzB,UAAI,CAAC,MAAM,iBAAkB,aAAY;AAAA,IAC3C,GAAG,aAAa;AAEhB,qBAAiB,CAAC,UAAU;AAC1B,YAAM,iBAAiB,UAAU,QAAQ,OAAO,OAAO;AACvD,UAAI,CAAC,eAAgB;AACrB,wBAAkB,KAAK;AACvB,UAAI,CAAC,MAAM,oBAAoB,WAAW;AACxC,cAAM,eAAe;AACrB,kBAAU;AAAA,MACZ;AAAA,IACF,GAAG,aAAa;AAEhB,IAAM,gBAAU,MAAM;AACpB,UAAI,CAAC,KAAM;AACX,UAAI,6BAA6B;AAC/B,YAAI,QAAQ,uCAAuC,SAAS,GAAG;AAC7D,sCAA4B,cAAc,KAAK,MAAM;AACrD,wBAAc,KAAK,MAAM,gBAAgB;AAAA,QAC3C;AACA,gBAAQ,uCAAuC,IAAI,IAAI;AAAA,MACzD;AACA,cAAQ,OAAO,IAAI,IAAI;AACvB,qBAAe;AACf,aAAO,MAAM;AACX,YACE,+BACA,QAAQ,uCAAuC,SAAS,GACxD;AACA,wBAAc,KAAK,MAAM,gBAAgB;AAAA,QAC3C;AAAA,MACF;AAAA,IACF,GAAG,CAAC,MAAM,eAAe,6BAA6B,OAAO,CAAC;AAQ9D,IAAM,gBAAU,MAAM;AACpB,aAAO,MAAM;AACX,YAAI,CAAC,KAAM;AACX,gBAAQ,OAAO,OAAO,IAAI;AAC1B,gBAAQ,uCAAuC,OAAO,IAAI;AAC1D,uBAAe;AAAA,MACjB;AAAA,IACF,GAAG,CAAC,MAAM,OAAO,CAAC;AAElB,IAAM,gBAAU,MAAM;AACpB,YAAM,eAAe,MAAM,MAAM,CAAC,CAAC;AACnC,eAAS,iBAAiB,gBAAgB,YAAY;AACtD,aAAO,MAAM,SAAS,oBAAoB,gBAAgB,YAAY;AAAA,IACxE,GAAG,CAAC,CAAC;AAEL,WACE;AAAA,MAAC,UAAU;AAAA,MAAV;AAAA,QACE,GAAG;AAAA,QACJ,KAAK;AAAA,QACL,OAAO;AAAA,UACL,eAAe,8BACX,yBACE,SACA,SACF;AAAA,UACJ,GAAG,MAAM;AAAA,QACX;AAAA,QACA,gBAAgB,qBAAqB,MAAM,gBAAgB,aAAa,cAAc;AAAA,QACtF,eAAe,qBAAqB,MAAM,eAAe,aAAa,aAAa;AAAA,QACnF,sBAAsB;AAAA,UACpB,MAAM;AAAA,UACN,mBAAmB;AAAA,QACrB;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,iBAAiB,cAAc;AAM/B,IAAM,cAAc;AAKpB,IAAM,yBAA+B,iBAGnC,CAAC,OAAO,iBAAiB;AACzB,QAAM,UAAgB,iBAAW,uBAAuB;AACxD,QAAM,MAAY,aAAsC,IAAI;AAC5D,QAAM,eAAe,gBAAgB,cAAc,GAAG;AAEtD,EAAM,gBAAU,MAAM;AACpB,UAAM,OAAO,IAAI;AACjB,QAAI,MAAM;AACR,cAAQ,SAAS,IAAI,IAAI;AACzB,aAAO,MAAM;AACX,gBAAQ,SAAS,OAAO,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,SAAO,oBAAC,UAAU,KAAV,EAAe,GAAG,OAAO,KAAK,cAAc;AACtD,CAAC;AAED,uBAAuB,cAAc;AAYrC,SAAS,sBACP,sBACA,gBAA0B,YAAY,UACtC;AACA,QAAM,2BAA2B,eAAe,oBAAoB;AACpE,QAAM,8BAAoC,aAAO,KAAK;AACtD,QAAM,iBAAuB,aAAO,MAAM;AAAA,EAAC,CAAC;AAE5C,EAAM,gBAAU,MAAM;AACpB,UAAM,oBAAoB,CAAC,UAAwB;AACjD,UAAI,MAAM,UAAU,CAAC,4BAA4B,SAAS;AAGxD,YAASC,4CAAT,WAAoD;AAClD;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA,EAAE,UAAU,KAAK;AAAA,UACnB;AAAA,QACF;AAPS,uDAAAA;AAFT,cAAM,cAAc,EAAE,eAAe,MAAM;AAuB3C,YAAI,MAAM,gBAAgB,SAAS;AACjC,wBAAc,oBAAoB,SAAS,eAAe,OAAO;AACjE,yBAAe,UAAUA;AACzB,wBAAc,iBAAiB,SAAS,eAAe,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,QAChF,OAAO;AACL,UAAAA,0CAAyC;AAAA,QAC3C;AAAA,MACF,OAAO;AAGL,sBAAc,oBAAoB,SAAS,eAAe,OAAO;AAAA,MACnE;AACA,kCAA4B,UAAU;AAAA,IACxC;AAcA,UAAM,UAAU,OAAO,WAAW,MAAM;AACtC,oBAAc,iBAAiB,eAAe,iBAAiB;AAAA,IACjE,GAAG,CAAC;AACJ,WAAO,MAAM;AACX,aAAO,aAAa,OAAO;AAC3B,oBAAc,oBAAoB,eAAe,iBAAiB;AAClE,oBAAc,oBAAoB,SAAS,eAAe,OAAO;AAAA,IACnE;AAAA,EACF,GAAG,CAAC,eAAe,wBAAwB,CAAC;AAE5C,SAAO;AAAA;AAAA,IAEL,sBAAsB,MAAO,4BAA4B,UAAU;AAAA,EACrE;AACF;AAMA,SAAS,gBACP,gBACA,gBAA0B,YAAY,UACtC;AACA,QAAM,qBAAqB,eAAe,cAAc;AACxD,QAAM,4BAAkC,aAAO,KAAK;AAEpD,EAAM,gBAAU,MAAM;AACpB,UAAM,cAAc,CAAC,UAAsB;AACzC,UAAI,MAAM,UAAU,CAAC,0BAA0B,SAAS;AACtD,cAAM,cAAc,EAAE,eAAe,MAAM;AAC3C,qCAA6B,eAAe,oBAAoB,aAAa;AAAA,UAC3E,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AACA,kBAAc,iBAAiB,WAAW,WAAW;AACrD,WAAO,MAAM,cAAc,oBAAoB,WAAW,WAAW;AAAA,EACvE,GAAG,CAAC,eAAe,kBAAkB,CAAC;AAEtC,SAAO;AAAA,IACL,gBAAgB,MAAO,0BAA0B,UAAU;AAAA,IAC3D,eAAe,MAAO,0BAA0B,UAAU;AAAA,EAC5D;AACF;AAEA,SAAS,iBAAiB;AACxB,QAAM,QAAQ,IAAI,YAAY,cAAc;AAC5C,WAAS,cAAc,KAAK;AAC9B;AAEA,SAAS,6BACP,MACA,SACA,QACA,EAAE,SAAS,GACX;AACA,QAAM,SAAS,OAAO,cAAc;AACpC,QAAM,QAAQ,IAAI,YAAY,MAAM,EAAE,SAAS,OAAO,YAAY,MAAM,OAAO,CAAC;AAChF,MAAI,QAAS,QAAO,iBAAiB,MAAM,SAA0B,EAAE,MAAM,KAAK,CAAC;AAEnF,MAAI,UAAU;AACZ,gCAA4B,QAAQ,KAAK;AAAA,EAC3C,OAAO;AACL,WAAO,cAAc,KAAK;AAAA,EAC5B;AACF;AAEA,IAAM,OAAO;AACb,IAAM,SAAS;",
6
+ "names": ["node", "handleAndDispatchPointerDownOutsideEvent"]
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@huin-core/react-dismissable-layer",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": {
@@ -20,7 +20,8 @@
20
20
  "types": "./dist/index.d.ts",
21
21
  "files": [
22
22
  "dist",
23
- "README.md"
23
+ "README.md",
24
+ "package.json"
24
25
  ],
25
26
  "sideEffects": false,
26
27
  "scripts": {