@rc-component/util 1.12.0 → 1.14.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.
@@ -30,6 +30,9 @@ function getOrder(prepend) {
30
30
  * Find style which inject by rc-util
31
31
  */
32
32
  function findStyles(container) {
33
+ if (!container) {
34
+ return [];
35
+ }
33
36
  return Array.from((containerCache.get(container) || container).children).filter(node => node.tagName === 'STYLE');
34
37
  }
35
38
  export function injectCSS(css, option = {}) {
@@ -53,6 +56,9 @@ export function injectCSS(css, option = {}) {
53
56
  }
54
57
  styleNode.innerHTML = css;
55
58
  const container = getContainer(option);
59
+ if (!container) {
60
+ return null;
61
+ }
56
62
  const {
57
63
  firstChild
58
64
  } = container;
@@ -93,7 +99,7 @@ export function removeCSS(key, option = {}) {
93
99
  const existNode = findExistNode(key, option);
94
100
  if (existNode) {
95
101
  const container = getContainer(option);
96
- container.removeChild(existNode);
102
+ container?.removeChild(existNode);
97
103
  }
98
104
  }
99
105
 
@@ -106,6 +112,9 @@ function syncRealContainer(container, option) {
106
112
  // Find real container when not cached or cached container removed
107
113
  if (!cachedRealContainer || !contains(document, cachedRealContainer)) {
108
114
  const placeholderStyle = injectCSS('', option);
115
+ if (!placeholderStyle) {
116
+ return;
117
+ }
109
118
  const {
110
119
  parentNode
111
120
  } = placeholderStyle;
@@ -122,6 +131,9 @@ export function clearContainerCache() {
122
131
  }
123
132
  export function updateCSS(css, key, originOption = {}) {
124
133
  const container = getContainer(originOption);
134
+ if (!container) {
135
+ return null;
136
+ }
125
137
  const styles = findStyles(container);
126
138
  const option = {
127
139
  ...originOption,
@@ -141,6 +153,9 @@ export function updateCSS(css, key, originOption = {}) {
141
153
  return existNode;
142
154
  }
143
155
  const newNode = injectCSS(css, option);
156
+ if (!newNode) {
157
+ return null;
158
+ }
144
159
  newNode.setAttribute(getMark(option), key);
145
160
  return newNode;
146
161
  }
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ export interface AllowClearConfig {
3
+ clearIcon?: React.ReactNode;
4
+ /** Disable the clear entry without rendering a button or reserving space. */
5
+ disabled?: boolean;
6
+ tabIndex?: number;
7
+ /** Accessible name for the clear button. */
8
+ label?: string;
9
+ }
10
+ /** Normalize clear configuration. Components should apply their defaults first. */
11
+ export default function useAllowClear(allowClear?: boolean | AllowClearConfig): AllowClearConfig;
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ /** Normalize clear configuration. Components should apply their defaults first. */
3
+ export default function useAllowClear(allowClear) {
4
+ return React.useMemo(() => allowClear && typeof allowClear === 'object' ? {
5
+ ...allowClear,
6
+ disabled: allowClear.disabled ?? false
7
+ } : {
8
+ disabled: !allowClear
9
+ }, [allowClear]);
10
+ }
@@ -19,6 +19,7 @@ export default function useDelayState(defaultValue) {
19
19
  delayRef.current = null;
20
20
  }
21
21
  });
22
+ React.useEffect(() => cancelPending, [cancelPending]);
22
23
  const setDelayValue = useEvent((nextValue, immediatelyOrDelay) => {
23
24
  const delayConfig = immediatelyOrDelay || {
24
25
  frame: 1
package/es/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { default as useAllowClear } from './hooks/useAllowClear';
2
+ export type { AllowClearConfig } from './hooks/useAllowClear';
1
3
  export { default as useEvent } from './hooks/useEvent';
2
4
  export { default as useMergedState } from './hooks/useMergedState';
3
5
  export { default as useControlledState } from './hooks/useControlledState';
@@ -22,6 +24,7 @@ export { isStyleSupport } from './Dom/styleChecker';
22
24
  export { default as KeyCode } from './KeyCode';
23
25
  export { default as getScrollBarSize, getTargetScrollBarSize, } from './getScrollBarSize';
24
26
  export { default as isEqual } from './isEqual';
27
+ export { isNonNullable, isReactRenderable } from './is';
25
28
  export { default as isMobile } from './isMobile';
26
29
  export { default as omit } from './omit';
27
30
  export { default as pickAttrs } from './pickAttrs';
package/es/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { default as useAllowClear } from "./hooks/useAllowClear";
1
2
  export { default as useEvent } from "./hooks/useEvent";
2
3
  export { default as useMergedState } from "./hooks/useMergedState";
3
4
  export { default as useControlledState } from "./hooks/useControlledState";
@@ -19,6 +20,7 @@ export { isStyleSupport } from "./Dom/styleChecker";
19
20
  export { default as KeyCode } from "./KeyCode";
20
21
  export { default as getScrollBarSize, getTargetScrollBarSize } from "./getScrollBarSize";
21
22
  export { default as isEqual } from "./isEqual";
23
+ export { isNonNullable, isReactRenderable } from "./is";
22
24
  export { default as isMobile } from "./isMobile";
23
25
  export { default as omit } from "./omit";
24
26
  export { default as pickAttrs } from "./pickAttrs";
package/es/is.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Check if a value is neither `null` nor `undefined`.
3
+ */
4
+ export declare function isNonNullable<T>(value: T): value is NonNullable<T>;
5
+ /**
6
+ * Check whether a value should be treated as renderable content.
7
+ *
8
+ * Returns `false` only for `null`, `undefined`, `false`, and `''`; all other
9
+ * values, including `0` and `true`, are treated as renderable.
10
+ *
11
+ * This is a compatibility-oriented presence check, not a complete React node
12
+ * validator.
13
+ */
14
+ export declare function isReactRenderable<T>(value: T): value is Exclude<NonNullable<T>, false | ''>;
package/es/is.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Check if a value is neither `null` nor `undefined`.
3
+ */
4
+ export function isNonNullable(value) {
5
+ return value !== undefined && value !== null;
6
+ }
7
+
8
+ /**
9
+ * Check whether a value should be treated as renderable content.
10
+ *
11
+ * Returns `false` only for `null`, `undefined`, `false`, and `''`; all other
12
+ * values, including `0` and `true`, are treated as renderable.
13
+ *
14
+ * This is a compatibility-oriented presence check, not a complete React node
15
+ * validator.
16
+ */
17
+ export function isReactRenderable(value) {
18
+ return isNonNullable(value) && value !== false && value !== '';
19
+ }
package/es/ref.js CHANGED
@@ -2,7 +2,7 @@ import { isValidElement, version } from 'react';
2
2
  import { ForwardRef, isMemo } from 'react-is';
3
3
  import useMemo from "./hooks/useMemo";
4
4
  import isFragment from "./React/isFragment";
5
- const ReactMajorVersion = Number(version.split('.')[0]);
5
+ const ReactMajorVersion = Number(version?.split('.')[0]);
6
6
  export const fillRef = (ref, node) => {
7
7
  if (typeof ref === 'function') {
8
8
  ref(node);
package/es/utils/set.js CHANGED
@@ -17,7 +17,14 @@ function internalSet(entity, paths, value, removeIfUndefined) {
17
17
 
18
18
  // Delete prop if `removeIfUndefined` and value is undefined
19
19
  if (removeIfUndefined && value === undefined && restPath.length === 1) {
20
- delete clone[path][restPath[0]];
20
+ const origin = clone[path];
21
+ if (origin && typeof origin === 'object') {
22
+ const child = Array.isArray(origin) ? [...origin] : {
23
+ ...origin
24
+ };
25
+ delete child[restPath[0]];
26
+ clone[path] = child;
27
+ }
21
28
  } else {
22
29
  clone[path] = internalSet(clone[path], restPath, value, removeIfUndefined);
23
30
  }
@@ -40,6 +40,9 @@ function getOrder(prepend) {
40
40
  * Find style which inject by rc-util
41
41
  */
42
42
  function findStyles(container) {
43
+ if (!container) {
44
+ return [];
45
+ }
43
46
  return Array.from((containerCache.get(container) || container).children).filter(node => node.tagName === 'STYLE');
44
47
  }
45
48
  function injectCSS(css, option = {}) {
@@ -63,6 +66,9 @@ function injectCSS(css, option = {}) {
63
66
  }
64
67
  styleNode.innerHTML = css;
65
68
  const container = getContainer(option);
69
+ if (!container) {
70
+ return null;
71
+ }
66
72
  const {
67
73
  firstChild
68
74
  } = container;
@@ -103,7 +109,7 @@ function removeCSS(key, option = {}) {
103
109
  const existNode = findExistNode(key, option);
104
110
  if (existNode) {
105
111
  const container = getContainer(option);
106
- container.removeChild(existNode);
112
+ container?.removeChild(existNode);
107
113
  }
108
114
  }
109
115
 
@@ -116,6 +122,9 @@ function syncRealContainer(container, option) {
116
122
  // Find real container when not cached or cached container removed
117
123
  if (!cachedRealContainer || !(0, _contains.default)(document, cachedRealContainer)) {
118
124
  const placeholderStyle = injectCSS('', option);
125
+ if (!placeholderStyle) {
126
+ return;
127
+ }
119
128
  const {
120
129
  parentNode
121
130
  } = placeholderStyle;
@@ -132,6 +141,9 @@ function clearContainerCache() {
132
141
  }
133
142
  function updateCSS(css, key, originOption = {}) {
134
143
  const container = getContainer(originOption);
144
+ if (!container) {
145
+ return null;
146
+ }
135
147
  const styles = findStyles(container);
136
148
  const option = {
137
149
  ...originOption,
@@ -151,6 +163,9 @@ function updateCSS(css, key, originOption = {}) {
151
163
  return existNode;
152
164
  }
153
165
  const newNode = injectCSS(css, option);
166
+ if (!newNode) {
167
+ return null;
168
+ }
154
169
  newNode.setAttribute(getMark(option), key);
155
170
  return newNode;
156
171
  }
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ export interface AllowClearConfig {
3
+ clearIcon?: React.ReactNode;
4
+ /** Disable the clear entry without rendering a button or reserving space. */
5
+ disabled?: boolean;
6
+ tabIndex?: number;
7
+ /** Accessible name for the clear button. */
8
+ label?: string;
9
+ }
10
+ /** Normalize clear configuration. Components should apply their defaults first. */
11
+ export default function useAllowClear(allowClear?: boolean | AllowClearConfig): AllowClearConfig;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = useAllowClear;
7
+ var React = _interopRequireWildcard(require("react"));
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
+ 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
+ /** Normalize clear configuration. Components should apply their defaults first. */
11
+ function useAllowClear(allowClear) {
12
+ return React.useMemo(() => allowClear && typeof allowClear === 'object' ? {
13
+ ...allowClear,
14
+ disabled: allowClear.disabled ?? false
15
+ } : {
16
+ disabled: !allowClear
17
+ }, [allowClear]);
18
+ }
@@ -28,6 +28,7 @@ function useDelayState(defaultValue) {
28
28
  delayRef.current = null;
29
29
  }
30
30
  });
31
+ React.useEffect(() => cancelPending, [cancelPending]);
31
32
  const setDelayValue = (0, _useEvent.default)((nextValue, immediatelyOrDelay) => {
32
33
  const delayConfig = immediatelyOrDelay || {
33
34
  frame: 1
package/lib/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { default as useAllowClear } from './hooks/useAllowClear';
2
+ export type { AllowClearConfig } from './hooks/useAllowClear';
1
3
  export { default as useEvent } from './hooks/useEvent';
2
4
  export { default as useMergedState } from './hooks/useMergedState';
3
5
  export { default as useControlledState } from './hooks/useControlledState';
@@ -22,6 +24,7 @@ export { isStyleSupport } from './Dom/styleChecker';
22
24
  export { default as KeyCode } from './KeyCode';
23
25
  export { default as getScrollBarSize, getTargetScrollBarSize, } from './getScrollBarSize';
24
26
  export { default as isEqual } from './isEqual';
27
+ export { isNonNullable, isReactRenderable } from './is';
25
28
  export { default as isMobile } from './isMobile';
26
29
  export { default as omit } from './omit';
27
30
  export { default as pickAttrs } from './pickAttrs';
package/lib/index.js CHANGED
@@ -111,6 +111,18 @@ Object.defineProperty(exports, "isMobile", {
111
111
  return _isMobile.default;
112
112
  }
113
113
  });
114
+ Object.defineProperty(exports, "isNonNullable", {
115
+ enumerable: true,
116
+ get: function () {
117
+ return _is.isNonNullable;
118
+ }
119
+ });
120
+ Object.defineProperty(exports, "isReactRenderable", {
121
+ enumerable: true,
122
+ get: function () {
123
+ return _is.isReactRenderable;
124
+ }
125
+ });
114
126
  Object.defineProperty(exports, "isStyleSupport", {
115
127
  enumerable: true,
116
128
  get: function () {
@@ -249,6 +261,12 @@ Object.defineProperty(exports, "updateCSS", {
249
261
  return _dynamicCSS.updateCSS;
250
262
  }
251
263
  });
264
+ Object.defineProperty(exports, "useAllowClear", {
265
+ enumerable: true,
266
+ get: function () {
267
+ return _useAllowClear.default;
268
+ }
269
+ });
252
270
  Object.defineProperty(exports, "useComposeRef", {
253
271
  enumerable: true,
254
272
  get: function () {
@@ -327,6 +345,7 @@ Object.defineProperty(exports, "warning", {
327
345
  return _warning.default;
328
346
  }
329
347
  });
348
+ var _useAllowClear = _interopRequireDefault(require("./hooks/useAllowClear"));
330
349
  var _useEvent = _interopRequireDefault(require("./hooks/useEvent"));
331
350
  var _useMergedState = _interopRequireDefault(require("./hooks/useMergedState"));
332
351
  var _useControlledState = _interopRequireDefault(require("./hooks/useControlledState"));
@@ -348,6 +367,7 @@ var _styleChecker = require("./Dom/styleChecker");
348
367
  var _KeyCode = _interopRequireDefault(require("./KeyCode"));
349
368
  var _getScrollBarSize = _interopRequireWildcard(require("./getScrollBarSize"));
350
369
  var _isEqual = _interopRequireDefault(require("./isEqual"));
370
+ var _is = require("./is");
351
371
  var _isMobile = _interopRequireDefault(require("./isMobile"));
352
372
  var _omit = _interopRequireDefault(require("./omit"));
353
373
  var _pickAttrs = _interopRequireDefault(require("./pickAttrs"));
package/lib/is.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Check if a value is neither `null` nor `undefined`.
3
+ */
4
+ export declare function isNonNullable<T>(value: T): value is NonNullable<T>;
5
+ /**
6
+ * Check whether a value should be treated as renderable content.
7
+ *
8
+ * Returns `false` only for `null`, `undefined`, `false`, and `''`; all other
9
+ * values, including `0` and `true`, are treated as renderable.
10
+ *
11
+ * This is a compatibility-oriented presence check, not a complete React node
12
+ * validator.
13
+ */
14
+ export declare function isReactRenderable<T>(value: T): value is Exclude<NonNullable<T>, false | ''>;
package/lib/is.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isNonNullable = isNonNullable;
7
+ exports.isReactRenderable = isReactRenderable;
8
+ /**
9
+ * Check if a value is neither `null` nor `undefined`.
10
+ */
11
+ function isNonNullable(value) {
12
+ return value !== undefined && value !== null;
13
+ }
14
+
15
+ /**
16
+ * Check whether a value should be treated as renderable content.
17
+ *
18
+ * Returns `false` only for `null`, `undefined`, `false`, and `''`; all other
19
+ * values, including `0` and `true`, are treated as renderable.
20
+ *
21
+ * This is a compatibility-oriented presence check, not a complete React node
22
+ * validator.
23
+ */
24
+ function isReactRenderable(value) {
25
+ return isNonNullable(value) && value !== false && value !== '';
26
+ }
package/lib/ref.js CHANGED
@@ -9,7 +9,7 @@ var _reactIs = require("react-is");
9
9
  var _useMemo = _interopRequireDefault(require("./hooks/useMemo"));
10
10
  var _isFragment = _interopRequireDefault(require("./React/isFragment"));
11
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
- const ReactMajorVersion = Number(_react.version.split('.')[0]);
12
+ const ReactMajorVersion = Number(_react.version?.split('.')[0]);
13
13
  const fillRef = (ref, node) => {
14
14
  if (typeof ref === 'function') {
15
15
  ref(node);
package/lib/utils/set.js CHANGED
@@ -26,7 +26,14 @@ function internalSet(entity, paths, value, removeIfUndefined) {
26
26
 
27
27
  // Delete prop if `removeIfUndefined` and value is undefined
28
28
  if (removeIfUndefined && value === undefined && restPath.length === 1) {
29
- delete clone[path][restPath[0]];
29
+ const origin = clone[path];
30
+ if (origin && typeof origin === 'object') {
31
+ const child = Array.isArray(origin) ? [...origin] : {
32
+ ...origin
33
+ };
34
+ delete child[restPath[0]];
35
+ clone[path] = child;
36
+ }
30
37
  } else {
31
38
  clone[path] = internalSet(clone[path], restPath, value, removeIfUndefined);
32
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rc-component/util",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "Shared React utilities for rc-component packages.",
5
5
  "keywords": [
6
6
  "react",