@udecode/react-utils 51.1.2 → 52.0.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/index.d.ts +86 -56
- package/dist/index.js +275 -344
- package/package.json +9 -12
- package/dist/index.d.mts +0 -155
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -325
- package/dist/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,381 +1,312 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/index.ts
|
|
31
|
-
var index_exports = {};
|
|
32
|
-
__export(index_exports, {
|
|
33
|
-
Box: () => Box,
|
|
34
|
-
CAN_USE_DOM: () => CAN_USE_DOM,
|
|
35
|
-
DEFAULT_IGNORE_CLASS: () => DEFAULT_IGNORE_CLASS,
|
|
36
|
-
MemoizedChildren: () => MemoizedChildren,
|
|
37
|
-
PortalBody: () => PortalBody,
|
|
38
|
-
Text: () => Text,
|
|
39
|
-
composeEventHandlers: () => composeEventHandlers,
|
|
40
|
-
composeRefs: () => composeRefs,
|
|
41
|
-
createPrimitiveComponent: () => createPrimitiveComponent,
|
|
42
|
-
createPrimitiveElement: () => createPrimitiveElement,
|
|
43
|
-
createSlotComponent: () => createSlotComponent,
|
|
44
|
-
useComposedRef: () => useComposedRef,
|
|
45
|
-
useEffectOnce: () => useEffectOnce,
|
|
46
|
-
useIsomorphicLayoutEffect: () => useIsomorphicLayoutEffect,
|
|
47
|
-
useMemoizedSelector: () => useMemoizedSelector,
|
|
48
|
-
useOnClickOutside: () => useOnClickOutside,
|
|
49
|
-
useStableFn: () => useStableFn,
|
|
50
|
-
useStableMemo: () => useStableMemo,
|
|
51
|
-
withProviders: () => withProviders,
|
|
52
|
-
withRef: () => withRef
|
|
53
|
-
});
|
|
54
|
-
module.exports = __toCommonJS(index_exports);
|
|
1
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import ReactDOM from "react-dom";
|
|
4
|
+
import { isDefined } from "@udecode/utils";
|
|
5
|
+
import { clsx } from "clsx";
|
|
55
6
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
7
|
+
//#region src/createSlotComponent.tsx
|
|
8
|
+
const createSlotComponent = (element) => React.forwardRef(({ as, asChild = false, ...props }, ref) => {
|
|
9
|
+
const Comp = asChild ? Slot : as || element;
|
|
10
|
+
return /* @__PURE__ */ React.createElement(Comp, {
|
|
11
|
+
ref,
|
|
12
|
+
...props
|
|
13
|
+
});
|
|
62
14
|
});
|
|
63
15
|
|
|
64
|
-
|
|
65
|
-
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/Box.tsx
|
|
18
|
+
const Box = createSlotComponent("div");
|
|
66
19
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
({ children }) => /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, children)
|
|
71
|
-
);
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/MemoizedChildren.tsx
|
|
22
|
+
const MemoizedChildren = React.memo(({ children }) => /* @__PURE__ */ React.createElement(React.Fragment, null, children));
|
|
72
23
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}) => {
|
|
79
|
-
const container = element || typeof window !== "undefined" ? document.body : void 0;
|
|
80
|
-
if (!container) return children;
|
|
81
|
-
return import_react_dom.default.createPortal(children, element || document.body);
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/PortalBody.tsx
|
|
26
|
+
const PortalBody = ({ children, element }) => {
|
|
27
|
+
if (!(element || typeof window !== "undefined" ? document.body : void 0)) return children;
|
|
28
|
+
return ReactDOM.createPortal(children, element || document.body);
|
|
82
29
|
};
|
|
83
30
|
|
|
84
|
-
|
|
85
|
-
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/Text.tsx
|
|
33
|
+
const Text = createSlotComponent("span");
|
|
86
34
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/composeEventHandlers.ts
|
|
37
|
+
/** @see https://github.com/radix-ui/primitives/blob/b324ec2d7ddf13a2a115cb5b11478e24d2f45b87/packages/core/primitive/src/primitive.tsx#L1 */
|
|
38
|
+
const composeEventHandlers = (originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) => (event) => {
|
|
39
|
+
originalEventHandler?.(event);
|
|
40
|
+
if (checkForDefaultPrevented === false || !event.defaultPrevented) return ourEventHandler?.(event);
|
|
93
41
|
};
|
|
94
42
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return ref(value);
|
|
105
|
-
}
|
|
106
|
-
if (ref !== null && ref !== void 0) {
|
|
107
|
-
ref.current = value;
|
|
108
|
-
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/useComposedRef.ts
|
|
45
|
+
/**
|
|
46
|
+
* Set a given ref to a given value This utility takes care of different types
|
|
47
|
+
* of refs: callback refs and React.RefObject(s)
|
|
48
|
+
*/
|
|
49
|
+
const setRef = (ref, value) => {
|
|
50
|
+
if (typeof ref === "function") return ref(value);
|
|
51
|
+
if (ref !== null && ref !== void 0) ref.current = value;
|
|
109
52
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
};
|
|
124
|
-
}
|
|
53
|
+
/**
|
|
54
|
+
* A utility to compose multiple refs together Accepts callback refs and
|
|
55
|
+
* React.RefObject(s)
|
|
56
|
+
*/
|
|
57
|
+
const composeRefs = (...refs) => (node) => {
|
|
58
|
+
const cleanups = [];
|
|
59
|
+
refs.forEach((ref) => {
|
|
60
|
+
const cleanup = setRef(ref, node);
|
|
61
|
+
if (typeof cleanup === "function") cleanups.push(cleanup);
|
|
62
|
+
});
|
|
63
|
+
if (cleanups.length > 0) return () => {
|
|
64
|
+
for (const cleanup of cleanups) cleanup?.();
|
|
65
|
+
};
|
|
125
66
|
};
|
|
126
|
-
|
|
127
|
-
|
|
67
|
+
/**
|
|
68
|
+
* A custom hook that composes multiple refs Accepts callback refs and
|
|
69
|
+
* React.RefObject(s)
|
|
70
|
+
*/
|
|
71
|
+
const useComposedRef = (...refs) => {
|
|
72
|
+
return React.useCallback(composeRefs(...refs), refs);
|
|
128
73
|
};
|
|
129
74
|
|
|
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
|
-
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/createPrimitiveComponent.tsx
|
|
77
|
+
/**
|
|
78
|
+
* Primitive component factory. It uses hooks for managing state and props, and
|
|
79
|
+
* forwards references to child components. Component props:
|
|
80
|
+
*
|
|
81
|
+
* - `asChild`: If true, the component will be rendered as a `Slot`
|
|
82
|
+
* {@link https://www.radix-ui.com/docs/primitives/utilities/slot}.
|
|
83
|
+
* - `options`: Options passed to the state hook.
|
|
84
|
+
* - `state`: Provide your state instead of using the state hook.
|
|
85
|
+
* - `className`: Class name to be merged to the component.
|
|
86
|
+
* - `style`: Style object to be merged to the component.
|
|
87
|
+
* - `setProps`: Function to set props from the props hook.
|
|
88
|
+
* - `...props`: Props to be passed to the component. Props hook return value:
|
|
89
|
+
* - `ref`: Reference to be forwarded to the component.
|
|
90
|
+
* - `props`: Props to be passed to the component.
|
|
91
|
+
* - `hidden`: If true, the component will not be rendered.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* const MyButton = createPrimitiveComponent(Button)({
|
|
95
|
+
* stateHook: useButtonState,
|
|
96
|
+
* propsHook: useButton,
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* @param {React.ElementType} element The base component or native HTML element.
|
|
100
|
+
* @returns {function} A primitive component.
|
|
101
|
+
*/
|
|
102
|
+
const createPrimitiveComponent = (element) => {
|
|
103
|
+
const Comp = createSlotComponent(element);
|
|
104
|
+
return ({ propsHook, stateHook } = {}) => React.forwardRef(({ asChild, className: classNameProp, getClassName, options, state: stateProp, ...props }, ref) => {
|
|
105
|
+
const state = isDefined(stateProp) ? stateProp : stateHook ? stateHook(options) : void 0;
|
|
106
|
+
const { hidden, props: hookProps, ref: hookRef } = propsHook ? propsHook(state) : {
|
|
107
|
+
hidden: false,
|
|
108
|
+
props: {},
|
|
109
|
+
ref: null
|
|
110
|
+
};
|
|
111
|
+
const _ref = useComposedRef(ref, hookRef);
|
|
112
|
+
const className = isDefined(hookProps?.className) || isDefined(classNameProp) ? clsx(hookProps?.className, classNameProp) : void 0;
|
|
113
|
+
const style = hookProps?.style || props.style ? {
|
|
114
|
+
...hookProps?.style,
|
|
115
|
+
...props.style
|
|
116
|
+
} : void 0;
|
|
117
|
+
if (!asChild && hidden) return null;
|
|
118
|
+
return /* @__PURE__ */ React.createElement(Comp, {
|
|
119
|
+
asChild,
|
|
120
|
+
ref: _ref,
|
|
121
|
+
...hookProps,
|
|
122
|
+
className,
|
|
123
|
+
style,
|
|
124
|
+
...props,
|
|
125
|
+
...props.setProps?.(hookProps ?? {}) ?? {}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
169
128
|
};
|
|
170
129
|
|
|
171
|
-
|
|
172
|
-
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/createPrimitiveElement.tsx
|
|
173
132
|
function createPrimitiveElement(tag) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
133
|
+
return React.forwardRef(function CreateComponent(props, ref) {
|
|
134
|
+
return React.createElement(tag, {
|
|
135
|
+
...props,
|
|
136
|
+
ref
|
|
137
|
+
});
|
|
138
|
+
});
|
|
179
139
|
}
|
|
180
140
|
|
|
181
|
-
|
|
182
|
-
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/useEffectOnce.ts
|
|
183
143
|
function useEffectOnce(effect, deps) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
144
|
+
const initialized = React.useRef(false);
|
|
145
|
+
const prevDepsRef = React.useRef(deps);
|
|
146
|
+
React.useEffect(() => {
|
|
147
|
+
const depsChanged = deps.some((dep, i) => dep !== prevDepsRef.current[i]);
|
|
148
|
+
if (!initialized.current || depsChanged) {
|
|
149
|
+
initialized.current = true;
|
|
150
|
+
prevDepsRef.current = deps;
|
|
151
|
+
effect();
|
|
152
|
+
}
|
|
153
|
+
}, deps);
|
|
194
154
|
}
|
|
195
155
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/useIsomorphicLayoutEffect.ts
|
|
158
|
+
const CAN_USE_DOM = typeof window !== "undefined" && window.document?.createElement !== void 0;
|
|
159
|
+
/**
|
|
160
|
+
* Prevent warning on SSR by falling back to React.useEffect when DOM isn't
|
|
161
|
+
* available
|
|
162
|
+
*/
|
|
163
|
+
const useIsomorphicLayoutEffect = CAN_USE_DOM ? React.useLayoutEffect : React.useEffect;
|
|
200
164
|
|
|
201
|
-
|
|
202
|
-
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/useMemoizedSelector.ts
|
|
167
|
+
/**
|
|
168
|
+
* Re-render only when the selector result changes.
|
|
169
|
+
*
|
|
170
|
+
* @param selector A function that derives a value from deps
|
|
171
|
+
* @param deps Dependencies on which to run the selector
|
|
172
|
+
* @param equalityFn Optional comparison function to detect changes in the
|
|
173
|
+
* derived value
|
|
174
|
+
*/
|
|
203
175
|
function useMemoizedSelector(selector, deps, equalityFn = (a, b) => a === b) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
176
|
+
const [memoizedValue, setMemoizedValue] = React.useState(() => selector());
|
|
177
|
+
const previousValueRef = React.useRef(memoizedValue);
|
|
178
|
+
React.useEffect(() => {
|
|
179
|
+
const newValue = selector();
|
|
180
|
+
if (!equalityFn(previousValueRef.current, newValue)) {
|
|
181
|
+
setMemoizedValue(newValue);
|
|
182
|
+
previousValueRef.current = newValue;
|
|
183
|
+
}
|
|
184
|
+
}, deps);
|
|
185
|
+
return memoizedValue;
|
|
214
186
|
}
|
|
215
187
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
window.addEventListener("test", noop, options);
|
|
229
|
-
window.removeEventListener("test", noop, options);
|
|
230
|
-
return passive;
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region src/useOnClickOutside.ts
|
|
190
|
+
const canUsePassiveEvents = () => {
|
|
191
|
+
if (typeof window === "undefined" || typeof window.addEventListener !== "function") return false;
|
|
192
|
+
let passive = false;
|
|
193
|
+
const options = Object.defineProperty({}, "passive", { get() {
|
|
194
|
+
passive = true;
|
|
195
|
+
} });
|
|
196
|
+
const noop = () => null;
|
|
197
|
+
window.addEventListener("test", noop, options);
|
|
198
|
+
window.removeEventListener("test", noop, options);
|
|
199
|
+
return passive;
|
|
231
200
|
};
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
return false;
|
|
201
|
+
const DEFAULT_IGNORE_CLASS = "ignore-onclickoutside";
|
|
202
|
+
const checkClass = (el, cl) => el.classList?.contains(cl);
|
|
203
|
+
const hasIgnoreClass = (e, ignoreClass) => {
|
|
204
|
+
let el = e.target || e;
|
|
205
|
+
while (el) {
|
|
206
|
+
if (Array.isArray(ignoreClass)) {
|
|
207
|
+
if (ignoreClass.some((c) => checkClass(el, c))) return true;
|
|
208
|
+
} else if (checkClass(el, ignoreClass)) return true;
|
|
209
|
+
el = el.parentElement;
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
245
212
|
};
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const removeEventListener = () => {
|
|
288
|
-
for (const type of eventTypes) {
|
|
289
|
-
document.removeEventListener(
|
|
290
|
-
type,
|
|
291
|
-
handler,
|
|
292
|
-
getEventOptions(type)
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
if (detectIFrame) window.removeEventListener("blur", blurHandler);
|
|
296
|
-
};
|
|
297
|
-
if (disabled) {
|
|
298
|
-
removeEventListener();
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
for (const type of eventTypes) {
|
|
302
|
-
document.addEventListener(type, handler, getEventOptions(type));
|
|
303
|
-
}
|
|
304
|
-
if (detectIFrame) window.addEventListener("blur", blurHandler);
|
|
305
|
-
return () => removeEventListener();
|
|
306
|
-
},
|
|
307
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
308
|
-
[
|
|
309
|
-
refsState,
|
|
310
|
-
ignoreClass,
|
|
311
|
-
excludeScrollbar,
|
|
312
|
-
disabled,
|
|
313
|
-
detectIFrame,
|
|
314
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
315
|
-
JSON.stringify(eventTypes)
|
|
316
|
-
]
|
|
317
|
-
);
|
|
318
|
-
return ref;
|
|
213
|
+
const clickedOnScrollbar = (e) => document.documentElement.clientWidth <= e.clientX || document.documentElement.clientHeight <= e.clientY;
|
|
214
|
+
const getEventOptions = (type) => type.includes("touch") && canUsePassiveEvents() ? { passive: true } : false;
|
|
215
|
+
const useOnClickOutside = (callback, { detectIFrame = true, disabled, eventTypes = ["mousedown", "touchstart"], excludeScrollbar, ignoreClass = DEFAULT_IGNORE_CLASS, refs: refsOpt } = {}) => {
|
|
216
|
+
const [refsState, setRefsState] = React.useState([]);
|
|
217
|
+
const callbackRef = React.useRef(callback);
|
|
218
|
+
callbackRef.current = callback;
|
|
219
|
+
const ref = React.useCallback((el) => setRefsState((prevState) => [...prevState, { current: el }]), []);
|
|
220
|
+
React.useEffect(() => {
|
|
221
|
+
if (!refsOpt?.length && refsState.length === 0) return;
|
|
222
|
+
const getEls = () => {
|
|
223
|
+
const els = [];
|
|
224
|
+
for (const { current } of refsOpt || refsState) if (current) els.push(current);
|
|
225
|
+
return els;
|
|
226
|
+
};
|
|
227
|
+
const handler = (e) => {
|
|
228
|
+
if (!hasIgnoreClass(e, ignoreClass) && !(excludeScrollbar && clickedOnScrollbar(e)) && getEls().every((el) => !el.contains(e.target))) callbackRef.current(e);
|
|
229
|
+
};
|
|
230
|
+
const blurHandler = (e) => setTimeout(() => {
|
|
231
|
+
const { activeElement } = document;
|
|
232
|
+
if (activeElement?.tagName === "IFRAME" && !hasIgnoreClass(activeElement, ignoreClass) && !getEls().includes(activeElement)) callbackRef.current(e);
|
|
233
|
+
}, 0);
|
|
234
|
+
const removeEventListener = () => {
|
|
235
|
+
for (const type of eventTypes) document.removeEventListener(type, handler, getEventOptions(type));
|
|
236
|
+
if (detectIFrame) window.removeEventListener("blur", blurHandler);
|
|
237
|
+
};
|
|
238
|
+
if (disabled) {
|
|
239
|
+
removeEventListener();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
for (const type of eventTypes) document.addEventListener(type, handler, getEventOptions(type));
|
|
243
|
+
if (detectIFrame) window.addEventListener("blur", blurHandler);
|
|
244
|
+
return () => removeEventListener();
|
|
245
|
+
}, [
|
|
246
|
+
refsState,
|
|
247
|
+
ignoreClass,
|
|
248
|
+
excludeScrollbar,
|
|
249
|
+
disabled,
|
|
250
|
+
detectIFrame,
|
|
251
|
+
JSON.stringify(eventTypes)
|
|
252
|
+
]);
|
|
253
|
+
return ref;
|
|
319
254
|
};
|
|
320
255
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region src/useStableFn.ts
|
|
258
|
+
/**
|
|
259
|
+
* Create a stable version of a function that can be used in dependency arrays
|
|
260
|
+
* without causing hooks like useEffect to re-run if the function changes.
|
|
261
|
+
* Calling the returned function always calls the most recent version of the
|
|
262
|
+
* function that was passed to useStableFn.
|
|
263
|
+
*
|
|
264
|
+
* If you do want the function to be replaced when certain dependency values
|
|
265
|
+
* change, include those values in the dependency array of useStableFn.
|
|
266
|
+
*/
|
|
267
|
+
const useStableFn = (fn, deps = []) => {
|
|
268
|
+
const fnRef = React.useRef(fn);
|
|
269
|
+
fnRef.current = fn;
|
|
270
|
+
return React.useCallback((...args) => fnRef.current(...args), deps);
|
|
327
271
|
};
|
|
328
272
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/useStableMemo.ts
|
|
275
|
+
const useStableMemo = (producer, deps) => {
|
|
276
|
+
const [value, setValue] = React.useState(producer);
|
|
277
|
+
React.useLayoutEffect(() => {
|
|
278
|
+
setValue(producer);
|
|
279
|
+
}, deps);
|
|
280
|
+
return value;
|
|
337
281
|
};
|
|
338
282
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
283
|
+
//#endregion
|
|
284
|
+
//#region src/withProviders.tsx
|
|
285
|
+
/** biome-ignore-all lint/correctness/useJsxKeyInIterable: biome */
|
|
286
|
+
/**
|
|
287
|
+
* Wrap a component into multiple providers. If there are any props that you
|
|
288
|
+
* want a provider to receive, you can simply pass an array.
|
|
289
|
+
*/
|
|
290
|
+
const withProviders = (...providers) => (WrappedComponent) => (props) => providers.reduceRight((acc, prov) => {
|
|
291
|
+
let Provider = prov;
|
|
292
|
+
if (Array.isArray(prov)) {
|
|
293
|
+
[Provider] = prov;
|
|
294
|
+
return /* @__PURE__ */ React.createElement(Provider, prov[1], acc);
|
|
295
|
+
}
|
|
296
|
+
return /* @__PURE__ */ React.createElement(Provider, null, acc);
|
|
297
|
+
}, /* @__PURE__ */ React.createElement(WrappedComponent, props));
|
|
352
298
|
|
|
353
|
-
|
|
354
|
-
|
|
299
|
+
//#endregion
|
|
300
|
+
//#region src/withRef.tsx
|
|
301
|
+
/**
|
|
302
|
+
* Shorter alternative to `React.forwardRef`.
|
|
303
|
+
*
|
|
304
|
+
* @generic1 Component type or element type
|
|
305
|
+
* @generic2 Extended prop types
|
|
306
|
+
*/
|
|
355
307
|
function withRef(renderFunction) {
|
|
356
|
-
|
|
308
|
+
return React.forwardRef(renderFunction);
|
|
357
309
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
CAN_USE_DOM,
|
|
362
|
-
DEFAULT_IGNORE_CLASS,
|
|
363
|
-
MemoizedChildren,
|
|
364
|
-
PortalBody,
|
|
365
|
-
Text,
|
|
366
|
-
composeEventHandlers,
|
|
367
|
-
composeRefs,
|
|
368
|
-
createPrimitiveComponent,
|
|
369
|
-
createPrimitiveElement,
|
|
370
|
-
createSlotComponent,
|
|
371
|
-
useComposedRef,
|
|
372
|
-
useEffectOnce,
|
|
373
|
-
useIsomorphicLayoutEffect,
|
|
374
|
-
useMemoizedSelector,
|
|
375
|
-
useOnClickOutside,
|
|
376
|
-
useStableFn,
|
|
377
|
-
useStableMemo,
|
|
378
|
-
withProviders,
|
|
379
|
-
withRef
|
|
380
|
-
});
|
|
381
|
-
//# sourceMappingURL=index.js.map
|
|
310
|
+
|
|
311
|
+
//#endregion
|
|
312
|
+
export { Box, CAN_USE_DOM, DEFAULT_IGNORE_CLASS, MemoizedChildren, PortalBody, Text, composeEventHandlers, composeRefs, createPrimitiveComponent, createPrimitiveElement, createSlotComponent, useComposedRef, useEffectOnce, useIsomorphicLayoutEffect, useMemoizedSelector, useOnClickOutside, useStableFn, useStableMemo, withProviders, withRef };
|