@rc-component/util 1.8.2 → 1.10.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/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/CI/badge.svg
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.d.ts CHANGED
@@ -9,11 +9,13 @@ export declare function triggerFocus(element?: HTMLElement, option?: InputFocusO
9
9
  /**
10
10
  * Lock focus in the element.
11
11
  * It will force back to the first focusable element when focus leaves the element.
12
+ * @param id - A stable ID for this lock instance
12
13
  */
13
- export declare function lockFocus(element: HTMLElement): VoidFunction;
14
+ export declare function lockFocus(element: HTMLElement, id: string): VoidFunction;
14
15
  /**
15
16
  * Lock focus within an element.
16
17
  * When locked, focus will be restricted to focusable elements within the specified element.
17
18
  * If multiple elements are locked, only the last locked element will be effective.
19
+ * @returns A function to mark an element as ignored, which will temporarily allow focus on that element even if it's outside the locked area.
18
20
  */
19
- export declare function useLockFocus(lock: boolean, getElement: () => HTMLElement | null): void;
21
+ export declare function useLockFocus(lock: boolean, getElement: () => HTMLElement | null): [ignoreElement: (ele: HTMLElement) => void];
package/es/Dom/focus.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { useEffect } from 'react';
2
2
  import isVisible from "./isVisible";
3
+ import useId from "../hooks/useId";
3
4
  function focusable(node, includePositive = false) {
4
5
  if (isVisible(node)) {
5
6
  const nodeName = node.nodeName.toLowerCase();
@@ -72,9 +73,29 @@ export function triggerFocus(element, option) {
72
73
  // ======================================================
73
74
  let lastFocusElement = null;
74
75
  let focusElements = [];
76
+ // Map stable ID to lock element
77
+ const idToElementMap = new Map();
78
+ // Map stable ID to ignored element
79
+ const ignoredElementMap = new Map();
75
80
  function getLastElement() {
76
81
  return focusElements[focusElements.length - 1];
77
82
  }
83
+ function isIgnoredElement(element) {
84
+ const lastElement = getLastElement();
85
+ if (element && lastElement) {
86
+ // Find the ID that maps to the last element
87
+ let lockId;
88
+ for (const [id, ele] of idToElementMap.entries()) {
89
+ if (ele === lastElement) {
90
+ lockId = id;
91
+ break;
92
+ }
93
+ }
94
+ const ignoredEle = ignoredElementMap.get(lockId);
95
+ return !!ignoredEle && (ignoredEle === element || ignoredEle.contains(element));
96
+ }
97
+ return false;
98
+ }
78
99
  function hasFocus(element) {
79
100
  const {
80
101
  activeElement
@@ -86,6 +107,11 @@ function syncFocus() {
86
107
  const {
87
108
  activeElement
88
109
  } = document;
110
+
111
+ // If current focus is on an ignored element, don't force it back
112
+ if (isIgnoredElement(activeElement)) {
113
+ return;
114
+ }
89
115
  if (lastElement && !hasFocus(lastElement)) {
90
116
  const focusableList = getFocusNodeList(lastElement);
91
117
  const matchElement = focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0];
@@ -117,9 +143,13 @@ function onWindowKeyDown(e) {
117
143
  /**
118
144
  * Lock focus in the element.
119
145
  * It will force back to the first focusable element when focus leaves the element.
146
+ * @param id - A stable ID for this lock instance
120
147
  */
121
- export function lockFocus(element) {
148
+ export function lockFocus(element, id) {
122
149
  if (element) {
150
+ // Store the mapping between ID and element
151
+ idToElementMap.set(id, element);
152
+
123
153
  // Refresh focus elements
124
154
  focusElements = focusElements.filter(ele => ele !== element);
125
155
  focusElements.push(element);
@@ -134,6 +164,8 @@ export function lockFocus(element) {
134
164
  return () => {
135
165
  lastFocusElement = null;
136
166
  focusElements = focusElements.filter(ele => ele !== element);
167
+ idToElementMap.delete(id);
168
+ ignoredElementMap.delete(id);
137
169
  if (focusElements.length === 0) {
138
170
  window.removeEventListener('focusin', syncFocus);
139
171
  window.removeEventListener('keydown', onWindowKeyDown, true);
@@ -145,14 +177,23 @@ export function lockFocus(element) {
145
177
  * Lock focus within an element.
146
178
  * When locked, focus will be restricted to focusable elements within the specified element.
147
179
  * If multiple elements are locked, only the last locked element will be effective.
180
+ * @returns A function to mark an element as ignored, which will temporarily allow focus on that element even if it's outside the locked area.
148
181
  */
149
182
  export function useLockFocus(lock, getElement) {
183
+ const id = useId();
150
184
  useEffect(() => {
151
185
  if (lock) {
152
186
  const element = getElement();
153
187
  if (element) {
154
- return lockFocus(element);
188
+ return lockFocus(element, id);
155
189
  }
156
190
  }
157
- }, [lock]);
191
+ }, [lock, id]);
192
+ const ignoreElement = ele => {
193
+ if (ele) {
194
+ // Set the ignored element using stable ID
195
+ ignoredElementMap.set(id, ele);
196
+ }
197
+ };
198
+ return [ignoreElement];
158
199
  }
@@ -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);
@@ -1,2 +1,2 @@
1
- declare function useEvent<T extends ((...args: any[]) => any) | undefined>(callback: T): undefined extends T ? (...args: Parameters<NonNullable<T>>) => ReturnType<NonNullable<T>> | undefined : T;
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;
@@ -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
- function useEvent(callback) {
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 _default: () => boolean;
2
- export default _default;
1
+ declare const getIsMobile: () => boolean;
2
+ export default getIsMobile;
package/es/isMobile.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import isMobile from 'is-mobile';
2
2
  let cached;
3
- export default (() => {
3
+ const getIsMobile = () => {
4
4
  if (typeof cached === 'undefined') {
5
5
  cached = isMobile();
6
6
  }
7
7
  return cached;
8
- });
8
+ };
9
+ export 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,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;
@@ -9,11 +9,13 @@ export declare function triggerFocus(element?: HTMLElement, option?: InputFocusO
9
9
  /**
10
10
  * Lock focus in the element.
11
11
  * It will force back to the first focusable element when focus leaves the element.
12
+ * @param id - A stable ID for this lock instance
12
13
  */
13
- export declare function lockFocus(element: HTMLElement): VoidFunction;
14
+ export declare function lockFocus(element: HTMLElement, id: string): VoidFunction;
14
15
  /**
15
16
  * Lock focus within an element.
16
17
  * When locked, focus will be restricted to focusable elements within the specified element.
17
18
  * If multiple elements are locked, only the last locked element will be effective.
19
+ * @returns A function to mark an element as ignored, which will temporarily allow focus on that element even if it's outside the locked area.
18
20
  */
19
- export declare function useLockFocus(lock: boolean, getElement: () => HTMLElement | null): void;
21
+ export declare function useLockFocus(lock: boolean, getElement: () => HTMLElement | null): [ignoreElement: (ele: HTMLElement) => void];
package/lib/Dom/focus.js CHANGED
@@ -9,6 +9,7 @@ exports.triggerFocus = triggerFocus;
9
9
  exports.useLockFocus = useLockFocus;
10
10
  var _react = require("react");
11
11
  var _isVisible = _interopRequireDefault(require("./isVisible"));
12
+ var _useId = _interopRequireDefault(require("../hooks/useId"));
12
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14
  function focusable(node, includePositive = false) {
14
15
  if ((0, _isVisible.default)(node)) {
@@ -82,9 +83,29 @@ function triggerFocus(element, option) {
82
83
  // ======================================================
83
84
  let lastFocusElement = null;
84
85
  let focusElements = [];
86
+ // Map stable ID to lock element
87
+ const idToElementMap = new Map();
88
+ // Map stable ID to ignored element
89
+ const ignoredElementMap = new Map();
85
90
  function getLastElement() {
86
91
  return focusElements[focusElements.length - 1];
87
92
  }
93
+ function isIgnoredElement(element) {
94
+ const lastElement = getLastElement();
95
+ if (element && lastElement) {
96
+ // Find the ID that maps to the last element
97
+ let lockId;
98
+ for (const [id, ele] of idToElementMap.entries()) {
99
+ if (ele === lastElement) {
100
+ lockId = id;
101
+ break;
102
+ }
103
+ }
104
+ const ignoredEle = ignoredElementMap.get(lockId);
105
+ return !!ignoredEle && (ignoredEle === element || ignoredEle.contains(element));
106
+ }
107
+ return false;
108
+ }
88
109
  function hasFocus(element) {
89
110
  const {
90
111
  activeElement
@@ -96,6 +117,11 @@ function syncFocus() {
96
117
  const {
97
118
  activeElement
98
119
  } = document;
120
+
121
+ // If current focus is on an ignored element, don't force it back
122
+ if (isIgnoredElement(activeElement)) {
123
+ return;
124
+ }
99
125
  if (lastElement && !hasFocus(lastElement)) {
100
126
  const focusableList = getFocusNodeList(lastElement);
101
127
  const matchElement = focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0];
@@ -127,9 +153,13 @@ function onWindowKeyDown(e) {
127
153
  /**
128
154
  * Lock focus in the element.
129
155
  * It will force back to the first focusable element when focus leaves the element.
156
+ * @param id - A stable ID for this lock instance
130
157
  */
131
- function lockFocus(element) {
158
+ function lockFocus(element, id) {
132
159
  if (element) {
160
+ // Store the mapping between ID and element
161
+ idToElementMap.set(id, element);
162
+
133
163
  // Refresh focus elements
134
164
  focusElements = focusElements.filter(ele => ele !== element);
135
165
  focusElements.push(element);
@@ -144,6 +174,8 @@ function lockFocus(element) {
144
174
  return () => {
145
175
  lastFocusElement = null;
146
176
  focusElements = focusElements.filter(ele => ele !== element);
177
+ idToElementMap.delete(id);
178
+ ignoredElementMap.delete(id);
147
179
  if (focusElements.length === 0) {
148
180
  window.removeEventListener('focusin', syncFocus);
149
181
  window.removeEventListener('keydown', onWindowKeyDown, true);
@@ -155,14 +187,23 @@ function lockFocus(element) {
155
187
  * Lock focus within an element.
156
188
  * When locked, focus will be restricted to focusable elements within the specified element.
157
189
  * If multiple elements are locked, only the last locked element will be effective.
190
+ * @returns A function to mark an element as ignored, which will temporarily allow focus on that element even if it's outside the locked area.
158
191
  */
159
192
  function useLockFocus(lock, getElement) {
193
+ const id = (0, _useId.default)();
160
194
  (0, _react.useEffect)(() => {
161
195
  if (lock) {
162
196
  const element = getElement();
163
197
  if (element) {
164
- return lockFocus(element);
198
+ return lockFocus(element, id);
165
199
  }
166
200
  }
167
- }, [lock]);
201
+ }, [lock, id]);
202
+ const ignoreElement = ele => {
203
+ if (ele) {
204
+ // Set the ignored element using stable ID
205
+ ignoredElementMap.set(id, ele);
206
+ }
207
+ };
208
+ return [ignoreElement];
168
209
  }
@@ -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);
@@ -1,2 +1,2 @@
1
- declare function useEvent<T extends ((...args: any[]) => any) | undefined>(callback: T): undefined extends T ? (...args: Parameters<NonNullable<T>>) => ReturnType<NonNullable<T>> | undefined : T;
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;
@@ -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
- /* eslint-disable @typescript-eslint/ban-types */
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 _default: () => boolean;
2
- export default _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
- var _default = () => {
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 = _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.8.2",
3
+ "version": "1.10.0",
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": "^24.6.1",
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": "^11.0.3",
62
+ "glob": "^13.0.0",
63
63
  "husky": "^9.1.6",
64
- "lint-staged": "^15.1.0",
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",