@rc-component/util 1.9.0 → 1.10.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/README.md +2 -2
- package/es/Dom/focus.js +37 -8
- package/es/getScrollBarSize.js +2 -2
- package/es/hooks/useEvent.d.ts +1 -1
- package/es/hooks/useEvent.js +2 -4
- package/es/index.d.ts +1 -0
- package/es/index.js +2 -1
- package/es/isMobile.d.ts +2 -2
- package/es/isMobile.js +3 -2
- package/es/mergeProps.d.ts +8 -0
- package/es/mergeProps.js +19 -0
- package/lib/Dom/focus.js +36 -7
- package/lib/getScrollBarSize.js +2 -2
- package/lib/hooks/useEvent.d.ts +1 -1
- package/lib/hooks/useEvent.js +2 -5
- package/lib/index.d.ts +1 -0
- package/lib/index.js +7 -0
- package/lib/isMobile.d.ts +2 -2
- package/lib/isMobile.js +2 -2
- package/lib/mergeProps.d.ts +8 -0
- package/lib/mergeProps.js +25 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ Common Utils For React Component.
|
|
|
13
13
|
[npm-url]: http://npmjs.org/package/rc-util
|
|
14
14
|
[travis-image]: https://img.shields.io/travis/react-component/util/master?style=flat-square
|
|
15
15
|
[travis-url]: https://travis-ci.com/react-component/util
|
|
16
|
-
[github-actions-image]: https://github.com/react-component/util/workflows/
|
|
17
|
-
[github-actions-url]: https://github.com/react-component/util/actions
|
|
16
|
+
[github-actions-image]: https://github.com/react-component/util/actions/workflows/react-component-ci.yml/badge.svg
|
|
17
|
+
[github-actions-url]: https://github.com/react-component/util/actions/workflows/react-component-ci.yml
|
|
18
18
|
[codecov-image]: https://img.shields.io/codecov/c/github/react-component/util/master.svg?style=flat-square
|
|
19
19
|
[codecov-url]: https://app.codecov.io/gh/react-component/util
|
|
20
20
|
[david-url]: https://david-dm.org/react-component/util
|
package/es/Dom/focus.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import isVisible from "./isVisible";
|
|
3
3
|
import useId from "../hooks/useId";
|
|
4
4
|
function focusable(node, includePositive = false) {
|
|
@@ -173,6 +173,30 @@ export function lockFocus(element, id) {
|
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Retry an effect until it reports ready.
|
|
178
|
+
* When `ready` is `false`, it will schedule one more effect cycle and call `func` again
|
|
179
|
+
* with the next `retryTimes`.
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
function useRetryEffect(func, deps) {
|
|
183
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
184
|
+
const retryTimesRef = useRef(0);
|
|
185
|
+
const [retryMark, setRetryMark] = useState(0);
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
retryTimesRef.current = 0;
|
|
188
|
+
}, deps);
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
const [clearFn, ready] = func(retryTimesRef.current);
|
|
191
|
+
if (!ready) {
|
|
192
|
+
retryTimesRef.current += 1;
|
|
193
|
+
setRetryMark(count => count + 1);
|
|
194
|
+
}
|
|
195
|
+
return clearFn;
|
|
196
|
+
}, [...deps, retryMark]);
|
|
197
|
+
/* eslint-enable react-hooks/exhaustive-deps */
|
|
198
|
+
}
|
|
199
|
+
|
|
176
200
|
/**
|
|
177
201
|
* Lock focus within an element.
|
|
178
202
|
* When locked, focus will be restricted to focusable elements within the specified element.
|
|
@@ -181,14 +205,19 @@ export function lockFocus(element, id) {
|
|
|
181
205
|
*/
|
|
182
206
|
export function useLockFocus(lock, getElement) {
|
|
183
207
|
const id = useId();
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
208
|
+
const getElementRef = useRef(getElement);
|
|
209
|
+
getElementRef.current = getElement;
|
|
210
|
+
const lockEffect = retryTimes => {
|
|
211
|
+
if (!lock) {
|
|
212
|
+
return [undefined, true];
|
|
213
|
+
}
|
|
214
|
+
const element = getElementRef.current();
|
|
215
|
+
if (element) {
|
|
216
|
+
return [lockFocus(element, id), true];
|
|
190
217
|
}
|
|
191
|
-
|
|
218
|
+
return [undefined, retryTimes >= 1];
|
|
219
|
+
};
|
|
220
|
+
useRetryEffect(lockEffect, [id, lock]);
|
|
192
221
|
const ignoreElement = ele => {
|
|
193
222
|
if (ele) {
|
|
194
223
|
// Set the ignored element using stable ID
|
package/es/getScrollBarSize.js
CHANGED
|
@@ -49,8 +49,8 @@ ${heightStyle}
|
|
|
49
49
|
document.body.appendChild(measureEle);
|
|
50
50
|
|
|
51
51
|
// Measure. Get fallback style if provided
|
|
52
|
-
const scrollWidth = ele && fallbackWidth && !isNaN(fallbackWidth) ? fallbackWidth : measureEle.offsetWidth - measureEle.clientWidth;
|
|
53
|
-
const scrollHeight = ele && fallbackHeight && !isNaN(fallbackHeight) ? fallbackHeight : measureEle.offsetHeight - measureEle.clientHeight;
|
|
52
|
+
const scrollWidth = ele && fallbackWidth && !Number.isNaN(fallbackWidth) ? fallbackWidth : measureEle.offsetWidth - measureEle.clientWidth;
|
|
53
|
+
const scrollHeight = ele && fallbackHeight && !Number.isNaN(fallbackHeight) ? fallbackHeight : measureEle.offsetHeight - measureEle.clientHeight;
|
|
54
54
|
|
|
55
55
|
// Clean up
|
|
56
56
|
document.body.removeChild(measureEle);
|
package/es/hooks/useEvent.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare
|
|
1
|
+
declare const useEvent: <T extends (...args: any[]) => any>(callback: T) => undefined extends T ? (...args: Parameters<NonNullable<T>>) => ReturnType<NonNullable<T>> | undefined : T;
|
|
2
2
|
export default useEvent;
|
package/es/hooks/useEvent.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
-
/* eslint-disable react-hooks/exhaustive-deps */
|
|
3
1
|
import * as React from 'react';
|
|
4
|
-
|
|
2
|
+
const useEvent = callback => {
|
|
5
3
|
const fnRef = React.useRef(callback);
|
|
6
4
|
fnRef.current = callback;
|
|
7
5
|
const memoFn = React.useCallback((...args) => fnRef.current?.(...args), []);
|
|
8
6
|
return memoFn;
|
|
9
|
-
}
|
|
7
|
+
};
|
|
10
8
|
export default useEvent;
|
package/es/index.d.ts
CHANGED
|
@@ -7,3 +7,4 @@ export { default as set, merge, mergeWith } from './utils/set';
|
|
|
7
7
|
export { default as warning, noteOnce } from './warning';
|
|
8
8
|
export { default as omit } from './omit';
|
|
9
9
|
export { default as toArray } from './Children/toArray';
|
|
10
|
+
export { default as mergeProps } from './mergeProps';
|
package/es/index.js
CHANGED
|
@@ -6,4 +6,5 @@ export { default as get } from "./utils/get";
|
|
|
6
6
|
export { default as set, merge, mergeWith } from "./utils/set";
|
|
7
7
|
export { default as warning, noteOnce } from "./warning";
|
|
8
8
|
export { default as omit } from "./omit";
|
|
9
|
-
export { default as toArray } from "./Children/toArray";
|
|
9
|
+
export { default as toArray } from "./Children/toArray";
|
|
10
|
+
export { default as mergeProps } from "./mergeProps";
|
package/es/isMobile.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const
|
|
2
|
-
export default
|
|
1
|
+
declare const getIsMobile: () => boolean;
|
|
2
|
+
export default getIsMobile;
|
package/es/isMobile.js
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges multiple props objects into one. Unlike `Object.assign()` or `{ ...a, ...b }`, it skips
|
|
3
|
+
* properties whose value is explicitly set to `undefined`.
|
|
4
|
+
*/
|
|
5
|
+
declare function mergeProps<A, B>(a: A, b: B): B & A;
|
|
6
|
+
declare function mergeProps<A, B, C>(a: A, b: B, c: C): C & B & A;
|
|
7
|
+
declare function mergeProps<A, B, C, D>(a: A, b: B, c: C, d: D): D & C & B & A;
|
|
8
|
+
export default mergeProps;
|
package/es/mergeProps.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges multiple props objects into one. Unlike `Object.assign()` or `{ ...a, ...b }`, it skips
|
|
3
|
+
* properties whose value is explicitly set to `undefined`.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
function mergeProps(...items) {
|
|
7
|
+
const ret = {};
|
|
8
|
+
for (const item of items) {
|
|
9
|
+
if (item) {
|
|
10
|
+
for (const key of Object.keys(item)) {
|
|
11
|
+
if (item[key] !== undefined) {
|
|
12
|
+
ret[key] = item[key];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return ret;
|
|
18
|
+
}
|
|
19
|
+
export default mergeProps;
|
package/lib/Dom/focus.js
CHANGED
|
@@ -183,6 +183,30 @@ function lockFocus(element, id) {
|
|
|
183
183
|
};
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Retry an effect until it reports ready.
|
|
188
|
+
* When `ready` is `false`, it will schedule one more effect cycle and call `func` again
|
|
189
|
+
* with the next `retryTimes`.
|
|
190
|
+
*/
|
|
191
|
+
|
|
192
|
+
function useRetryEffect(func, deps) {
|
|
193
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
194
|
+
const retryTimesRef = (0, _react.useRef)(0);
|
|
195
|
+
const [retryMark, setRetryMark] = (0, _react.useState)(0);
|
|
196
|
+
(0, _react.useEffect)(() => {
|
|
197
|
+
retryTimesRef.current = 0;
|
|
198
|
+
}, deps);
|
|
199
|
+
(0, _react.useEffect)(() => {
|
|
200
|
+
const [clearFn, ready] = func(retryTimesRef.current);
|
|
201
|
+
if (!ready) {
|
|
202
|
+
retryTimesRef.current += 1;
|
|
203
|
+
setRetryMark(count => count + 1);
|
|
204
|
+
}
|
|
205
|
+
return clearFn;
|
|
206
|
+
}, [...deps, retryMark]);
|
|
207
|
+
/* eslint-enable react-hooks/exhaustive-deps */
|
|
208
|
+
}
|
|
209
|
+
|
|
186
210
|
/**
|
|
187
211
|
* Lock focus within an element.
|
|
188
212
|
* When locked, focus will be restricted to focusable elements within the specified element.
|
|
@@ -191,14 +215,19 @@ function lockFocus(element, id) {
|
|
|
191
215
|
*/
|
|
192
216
|
function useLockFocus(lock, getElement) {
|
|
193
217
|
const id = (0, _useId.default)();
|
|
194
|
-
(0, _react.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
218
|
+
const getElementRef = (0, _react.useRef)(getElement);
|
|
219
|
+
getElementRef.current = getElement;
|
|
220
|
+
const lockEffect = retryTimes => {
|
|
221
|
+
if (!lock) {
|
|
222
|
+
return [undefined, true];
|
|
223
|
+
}
|
|
224
|
+
const element = getElementRef.current();
|
|
225
|
+
if (element) {
|
|
226
|
+
return [lockFocus(element, id), true];
|
|
200
227
|
}
|
|
201
|
-
|
|
228
|
+
return [undefined, retryTimes >= 1];
|
|
229
|
+
};
|
|
230
|
+
useRetryEffect(lockEffect, [id, lock]);
|
|
202
231
|
const ignoreElement = ele => {
|
|
203
232
|
if (ele) {
|
|
204
233
|
// Set the ignored element using stable ID
|
package/lib/getScrollBarSize.js
CHANGED
|
@@ -57,8 +57,8 @@ ${heightStyle}
|
|
|
57
57
|
document.body.appendChild(measureEle);
|
|
58
58
|
|
|
59
59
|
// Measure. Get fallback style if provided
|
|
60
|
-
const scrollWidth = ele && fallbackWidth && !isNaN(fallbackWidth) ? fallbackWidth : measureEle.offsetWidth - measureEle.clientWidth;
|
|
61
|
-
const scrollHeight = ele && fallbackHeight && !isNaN(fallbackHeight) ? fallbackHeight : measureEle.offsetHeight - measureEle.clientHeight;
|
|
60
|
+
const scrollWidth = ele && fallbackWidth && !Number.isNaN(fallbackWidth) ? fallbackWidth : measureEle.offsetWidth - measureEle.clientWidth;
|
|
61
|
+
const scrollHeight = ele && fallbackHeight && !Number.isNaN(fallbackHeight) ? fallbackHeight : measureEle.offsetHeight - measureEle.clientHeight;
|
|
62
62
|
|
|
63
63
|
// Clean up
|
|
64
64
|
document.body.removeChild(measureEle);
|
package/lib/hooks/useEvent.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare
|
|
1
|
+
declare const useEvent: <T extends (...args: any[]) => any>(callback: T) => undefined extends T ? (...args: Parameters<NonNullable<T>>) => ReturnType<NonNullable<T>> | undefined : T;
|
|
2
2
|
export default useEvent;
|
package/lib/hooks/useEvent.js
CHANGED
|
@@ -7,13 +7,10 @@ exports.default = void 0;
|
|
|
7
7
|
var React = _interopRequireWildcard(require("react"));
|
|
8
8
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
9
9
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
10
|
-
|
|
11
|
-
/* eslint-disable react-hooks/exhaustive-deps */
|
|
12
|
-
|
|
13
|
-
function useEvent(callback) {
|
|
10
|
+
const useEvent = callback => {
|
|
14
11
|
const fnRef = React.useRef(callback);
|
|
15
12
|
fnRef.current = callback;
|
|
16
13
|
const memoFn = React.useCallback((...args) => fnRef.current?.(...args), []);
|
|
17
14
|
return memoFn;
|
|
18
|
-
}
|
|
15
|
+
};
|
|
19
16
|
var _default = exports.default = useEvent;
|
package/lib/index.d.ts
CHANGED
|
@@ -7,3 +7,4 @@ export { default as set, merge, mergeWith } from './utils/set';
|
|
|
7
7
|
export { default as warning, noteOnce } from './warning';
|
|
8
8
|
export { default as omit } from './omit';
|
|
9
9
|
export { default as toArray } from './Children/toArray';
|
|
10
|
+
export { default as mergeProps } from './mergeProps';
|
package/lib/index.js
CHANGED
|
@@ -15,6 +15,12 @@ Object.defineProperty(exports, "merge", {
|
|
|
15
15
|
return _set.merge;
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
+
Object.defineProperty(exports, "mergeProps", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _mergeProps.default;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
18
24
|
Object.defineProperty(exports, "mergeWith", {
|
|
19
25
|
enumerable: true,
|
|
20
26
|
get: function () {
|
|
@@ -96,6 +102,7 @@ var _set = _interopRequireWildcard(require("./utils/set"));
|
|
|
96
102
|
var _warning = _interopRequireWildcard(require("./warning"));
|
|
97
103
|
var _omit = _interopRequireDefault(require("./omit"));
|
|
98
104
|
var _toArray = _interopRequireDefault(require("./Children/toArray"));
|
|
105
|
+
var _mergeProps = _interopRequireDefault(require("./mergeProps"));
|
|
99
106
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
100
107
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
101
108
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/lib/isMobile.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const
|
|
2
|
-
export default
|
|
1
|
+
declare const getIsMobile: () => boolean;
|
|
2
|
+
export default getIsMobile;
|
package/lib/isMobile.js
CHANGED
|
@@ -7,10 +7,10 @@ exports.default = void 0;
|
|
|
7
7
|
var _isMobile = _interopRequireDefault(require("is-mobile"));
|
|
8
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
9
|
let cached;
|
|
10
|
-
|
|
10
|
+
const getIsMobile = () => {
|
|
11
11
|
if (typeof cached === 'undefined') {
|
|
12
12
|
cached = (0, _isMobile.default)();
|
|
13
13
|
}
|
|
14
14
|
return cached;
|
|
15
15
|
};
|
|
16
|
-
exports.default =
|
|
16
|
+
var _default = exports.default = getIsMobile;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges multiple props objects into one. Unlike `Object.assign()` or `{ ...a, ...b }`, it skips
|
|
3
|
+
* properties whose value is explicitly set to `undefined`.
|
|
4
|
+
*/
|
|
5
|
+
declare function mergeProps<A, B>(a: A, b: B): B & A;
|
|
6
|
+
declare function mergeProps<A, B, C>(a: A, b: B, c: C): C & B & A;
|
|
7
|
+
declare function mergeProps<A, B, C, D>(a: A, b: B, c: C, d: D): D & C & B & A;
|
|
8
|
+
export default mergeProps;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Merges multiple props objects into one. Unlike `Object.assign()` or `{ ...a, ...b }`, it skips
|
|
9
|
+
* properties whose value is explicitly set to `undefined`.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
function mergeProps(...items) {
|
|
13
|
+
const ret = {};
|
|
14
|
+
for (const item of items) {
|
|
15
|
+
if (item) {
|
|
16
|
+
for (const key of Object.keys(item)) {
|
|
17
|
+
if (item[key] !== undefined) {
|
|
18
|
+
ret[key] = item[key];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return ret;
|
|
24
|
+
}
|
|
25
|
+
var _default = exports.default = mergeProps;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rc-component/util",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "Common Utils For React Component",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@rc-component/np": "^1.0.3",
|
|
47
47
|
"@testing-library/react": "^16.0.0",
|
|
48
48
|
"@types/jest": "^30.0.0",
|
|
49
|
-
"@types/node": "^
|
|
49
|
+
"@types/node": "^25.0.3",
|
|
50
50
|
"@types/react": "^19.2.7",
|
|
51
51
|
"@types/react-dom": "^19.2.2",
|
|
52
52
|
"@types/react-is": "^19.0.0",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"eslint-plugin-jest": "^29.0.1",
|
|
60
60
|
"eslint-plugin-unicorn": "^56.0.1",
|
|
61
61
|
"father": "^4.1.3",
|
|
62
|
-
"glob": "^
|
|
62
|
+
"glob": "^13.0.0",
|
|
63
63
|
"husky": "^9.1.6",
|
|
64
|
-
"lint-staged": "^
|
|
64
|
+
"lint-staged": "^16.2.7",
|
|
65
65
|
"prettier": "^3.3.2",
|
|
66
66
|
"rc-test": "^7.0.14",
|
|
67
67
|
"react": "^18.0.0",
|