This commit is contained in:
2026-05-25 17:08:18 +08:00
parent df501f6151
commit f1259b71b5
9178 changed files with 1626125 additions and 0 deletions
@@ -0,0 +1,5 @@
import React from 'react';
export interface Option {
keepEmpty?: boolean;
}
export default function toArray(children: React.ReactNode, option?: Option): React.ReactElement[];
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = toArray;
var _isFragment = _interopRequireDefault(require("../React/isFragment"));
var _react = _interopRequireDefault(require("react"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function toArray(children, option = {}) {
let ret = [];
_react.default.Children.forEach(children, child => {
if ((child === undefined || child === null) && !option.keepEmpty) {
return;
}
if (Array.isArray(child)) {
ret = ret.concat(toArray(child));
} else if ((0, _isFragment.default)(child) && child.props) {
ret = ret.concat(toArray(child.props.children, option));
} else {
ret.push(child);
}
});
return ret;
}
@@ -0,0 +1 @@
export default function canUseDom(): boolean;
+9
View File
@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = canUseDom;
function canUseDom() {
return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
}
@@ -0,0 +1 @@
export default function contains(root: Node | null | undefined, n?: Node): boolean;
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = contains;
function contains(root, n) {
if (!root) {
return false;
}
// Use native if support
if (root.contains) {
return root.contains(n);
}
// `document.contains` not support with IE11
let node = n;
while (node) {
if (node === root) {
return true;
}
node = node.parentNode;
}
return false;
}
@@ -0,0 +1,25 @@
export type ContainerType = Element | ShadowRoot;
export type Prepend = boolean | 'queue';
export type AppendType = 'prependQueue' | 'append' | 'prepend';
interface Options {
attachTo?: ContainerType;
csp?: {
nonce?: string;
};
prepend?: Prepend;
/**
* Config the `priority` of `prependQueue`. Default is `0`.
* It's useful if you need to insert style before other style.
*/
priority?: number;
mark?: string;
styles?: HTMLElement[];
}
export declare function injectCSS(css: string, option?: Options): HTMLStyleElement;
export declare function removeCSS(key: string, option?: Options): void;
/**
* manually clear container cache to avoid global cache in unit testes
*/
export declare function clearContainerCache(): void;
export declare function updateCSS(css: string, key: string, originOption?: Options): HTMLElement;
export {};
+156
View File
@@ -0,0 +1,156 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.clearContainerCache = clearContainerCache;
exports.injectCSS = injectCSS;
exports.removeCSS = removeCSS;
exports.updateCSS = updateCSS;
var _canUseDom = _interopRequireDefault(require("./canUseDom"));
var _contains = _interopRequireDefault(require("./contains"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const APPEND_ORDER = 'data-rc-order';
const APPEND_PRIORITY = 'data-rc-priority';
const MARK_KEY = `rc-util-key`;
const containerCache = new Map();
function getMark({
mark
} = {}) {
if (mark) {
return mark.startsWith('data-') ? mark : `data-${mark}`;
}
return MARK_KEY;
}
function getContainer(option) {
if (option.attachTo) {
return option.attachTo;
}
const head = document.querySelector('head');
return head || document.body;
}
function getOrder(prepend) {
if (prepend === 'queue') {
return 'prependQueue';
}
return prepend ? 'prepend' : 'append';
}
/**
* Find style which inject by rc-util
*/
function findStyles(container) {
return Array.from((containerCache.get(container) || container).children).filter(node => node.tagName === 'STYLE');
}
function injectCSS(css, option = {}) {
if (!(0, _canUseDom.default)()) {
return null;
}
const {
csp,
prepend,
priority = 0
} = option;
const mergedOrder = getOrder(prepend);
const isPrependQueue = mergedOrder === 'prependQueue';
const styleNode = document.createElement('style');
styleNode.setAttribute(APPEND_ORDER, mergedOrder);
if (isPrependQueue && priority) {
styleNode.setAttribute(APPEND_PRIORITY, `${priority}`);
}
if (csp?.nonce) {
styleNode.nonce = csp?.nonce;
}
styleNode.innerHTML = css;
const container = getContainer(option);
const {
firstChild
} = container;
if (prepend) {
// If is queue `prepend`, it will prepend first style and then append rest style
if (isPrependQueue) {
const existStyle = (option.styles || findStyles(container)).filter(node => {
// Ignore style which not injected by rc-util with prepend
if (!['prepend', 'prependQueue'].includes(node.getAttribute(APPEND_ORDER))) {
return false;
}
// Ignore style which priority less then new style
const nodePriority = Number(node.getAttribute(APPEND_PRIORITY) || 0);
return priority >= nodePriority;
});
if (existStyle.length) {
container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling);
return styleNode;
}
}
// Use `insertBefore` as `prepend`
container.insertBefore(styleNode, firstChild);
} else {
container.appendChild(styleNode);
}
return styleNode;
}
function findExistNode(key, option = {}) {
let {
styles
} = option;
styles ||= findStyles(getContainer(option));
return styles.find(node => node.getAttribute(getMark(option)) === key);
}
function removeCSS(key, option = {}) {
const existNode = findExistNode(key, option);
if (existNode) {
const container = getContainer(option);
container.removeChild(existNode);
}
}
/**
* qiankun will inject `appendChild` to insert into other
*/
function syncRealContainer(container, option) {
const cachedRealContainer = containerCache.get(container);
// Find real container when not cached or cached container removed
if (!cachedRealContainer || !(0, _contains.default)(document, cachedRealContainer)) {
const placeholderStyle = injectCSS('', option);
const {
parentNode
} = placeholderStyle;
containerCache.set(container, parentNode);
container.removeChild(placeholderStyle);
}
}
/**
* manually clear container cache to avoid global cache in unit testes
*/
function clearContainerCache() {
containerCache.clear();
}
function updateCSS(css, key, originOption = {}) {
const container = getContainer(originOption);
const styles = findStyles(container);
const option = {
...originOption,
styles
};
// Sync real parent
syncRealContainer(container, option);
const existNode = findExistNode(key, option);
if (existNode) {
if (option.csp?.nonce && existNode.nonce !== option.csp?.nonce) {
existNode.nonce = option.csp?.nonce;
}
if (existNode.innerHTML !== css) {
existNode.innerHTML = css;
}
return existNode;
}
const newNode = injectCSS(css, option);
newNode.setAttribute(getMark(option), key);
return newNode;
}
@@ -0,0 +1,14 @@
import React from 'react';
export declare function isDOM(node: any): node is HTMLElement | SVGElement;
/**
* Retrieves a DOM node via a ref, and does not invoke `findDOMNode`.
*/
export declare function getDOM(node: any): HTMLElement | SVGElement | null;
/**
* Return if a node is a DOM node. Else will return by `findDOMNode`
*/
export default function findDOMNode<T = Element | Text>(node: React.ReactInstance | HTMLElement | SVGElement | {
nativeElement: T;
} | {
current: T;
}): T | null;
+43
View File
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = findDOMNode;
exports.getDOM = getDOM;
exports.isDOM = isDOM;
function isDOM(node) {
// https://developer.mozilla.org/en-US/docs/Web/API/Element
// Since XULElement is also subclass of Element, we only need HTMLElement and SVGElement
return node instanceof HTMLElement || node instanceof SVGElement;
}
/**
* Retrieves a DOM node via a ref, and does not invoke `findDOMNode`.
*/
function getDOM(node) {
if (node && typeof node === 'object' && isDOM(node.nativeElement)) {
return node.nativeElement;
}
if (isDOM(node)) {
return node;
}
return null;
}
/**
* Return if a node is a DOM node. Else will return by `findDOMNode`
*/
function findDOMNode(node) {
const domNode = getDOM(node);
if (domNode) {
return domNode;
}
if (node && typeof node === 'object' && 'current' in node) {
const refDomNode = getDOM(node.current);
if (refDomNode) {
return refDomNode;
}
}
return null;
}
+21
View File
@@ -0,0 +1,21 @@
export declare function getFocusNodeList(node: HTMLElement, includePositive?: boolean): HTMLElement[];
export interface InputFocusOptions extends FocusOptions {
cursor?: 'start' | 'end' | 'all';
}
/**
* Focus element and set cursor position for input/textarea elements.
*/
export declare function triggerFocus(element?: HTMLElement, option?: InputFocusOptions): void;
/**
* Lock focus in the element.
* It will force back to the first focusable element when focus leaves the element.
* @param id - A stable ID for this lock instance
*/
export declare function lockFocus(element: HTMLElement, id: string): VoidFunction;
/**
* Lock focus within an element.
* When locked, focus will be restricted to focusable elements within the specified element.
* If multiple elements are locked, only the last locked element will be effective.
* @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.
*/
export declare function useLockFocus(lock: boolean, getElement: () => HTMLElement | null): [ignoreElement: (ele: HTMLElement) => void];
+238
View File
@@ -0,0 +1,238 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getFocusNodeList = getFocusNodeList;
exports.lockFocus = lockFocus;
exports.triggerFocus = triggerFocus;
exports.useLockFocus = useLockFocus;
var _react = require("react");
var _isVisible = _interopRequireDefault(require("./isVisible"));
var _useId = _interopRequireDefault(require("../hooks/useId"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function focusable(node, includePositive = false) {
if ((0, _isVisible.default)(node)) {
const nodeName = node.nodeName.toLowerCase();
const isFocusableElement =
// Focusable element
['input', 'select', 'textarea', 'button'].includes(nodeName) ||
// Editable element
node.isContentEditable ||
// Anchor with href element
nodeName === 'a' && !!node.getAttribute('href');
// Get tabIndex
const tabIndexAttr = node.getAttribute('tabindex');
const tabIndexNum = Number(tabIndexAttr);
// Parse as number if validate
let tabIndex = null;
if (tabIndexAttr && !Number.isNaN(tabIndexNum)) {
tabIndex = tabIndexNum;
} else if (isFocusableElement && tabIndex === null) {
tabIndex = 0;
}
// Block focusable if disabled
if (isFocusableElement && node.disabled) {
tabIndex = null;
}
return tabIndex !== null && (tabIndex >= 0 || includePositive && tabIndex < 0);
}
return false;
}
function getFocusNodeList(node, includePositive = false) {
const res = [...node.querySelectorAll('*')].filter(child => {
return focusable(child, includePositive);
});
if (focusable(node, includePositive)) {
res.unshift(node);
}
return res;
}
// Used for `rc-input` `rc-textarea` `rc-input-number`
/**
* Focus element and set cursor position for input/textarea elements.
*/
function triggerFocus(element, option) {
if (!element) return;
element.focus(option);
// Selection content
const {
cursor
} = option || {};
if (cursor && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement)) {
const len = element.value.length;
switch (cursor) {
case 'start':
element.setSelectionRange(0, 0);
break;
case 'end':
element.setSelectionRange(len, len);
break;
default:
element.setSelectionRange(0, len);
}
}
}
// ======================================================
// == Lock Focus ==
// ======================================================
let lastFocusElement = null;
let focusElements = [];
// Map stable ID to lock element
const idToElementMap = new Map();
// Map stable ID to ignored element
const ignoredElementMap = new Map();
function getLastElement() {
return focusElements[focusElements.length - 1];
}
function isIgnoredElement(element) {
const lastElement = getLastElement();
if (element && lastElement) {
// Find the ID that maps to the last element
let lockId;
for (const [id, ele] of idToElementMap.entries()) {
if (ele === lastElement) {
lockId = id;
break;
}
}
const ignoredEle = ignoredElementMap.get(lockId);
return !!ignoredEle && (ignoredEle === element || ignoredEle.contains(element));
}
return false;
}
function hasFocus(element) {
const {
activeElement
} = document;
return element === activeElement || element.contains(activeElement);
}
function syncFocus() {
const lastElement = getLastElement();
const {
activeElement
} = document;
// If current focus is on an ignored element, don't force it back
if (isIgnoredElement(activeElement)) {
return;
}
if (lastElement && !hasFocus(lastElement)) {
const focusableList = getFocusNodeList(lastElement);
const matchElement = focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0];
matchElement?.focus({
preventScroll: true
});
} else {
lastFocusElement = activeElement;
}
}
function onWindowKeyDown(e) {
if (e.key === 'Tab') {
const {
activeElement
} = document;
const lastElement = getLastElement();
const focusableList = getFocusNodeList(lastElement);
const last = focusableList[focusableList.length - 1];
if (e.shiftKey && activeElement === focusableList[0]) {
// Tab backward on first focusable element
lastFocusElement = last;
} else if (!e.shiftKey && activeElement === last) {
// Tab forward on last focusable element
lastFocusElement = focusableList[0];
}
}
}
/**
* Lock focus in the element.
* It will force back to the first focusable element when focus leaves the element.
* @param id - A stable ID for this lock instance
*/
function lockFocus(element, id) {
if (element) {
// Store the mapping between ID and element
idToElementMap.set(id, element);
// Refresh focus elements
focusElements = focusElements.filter(ele => ele !== element);
focusElements.push(element);
// Just add event since it will de-duplicate
window.addEventListener('focusin', syncFocus);
window.addEventListener('keydown', onWindowKeyDown, true);
syncFocus();
}
// Always return unregister function
return () => {
lastFocusElement = null;
focusElements = focusElements.filter(ele => ele !== element);
idToElementMap.delete(id);
ignoredElementMap.delete(id);
if (focusElements.length === 0) {
window.removeEventListener('focusin', syncFocus);
window.removeEventListener('keydown', onWindowKeyDown, true);
}
};
}
/**
* Retry an effect until it reports ready.
* When `ready` is `false`, it will schedule one more effect cycle and call `func` again
* with the next `retryTimes`.
*/
function useRetryEffect(func, deps) {
/* eslint-disable react-hooks/exhaustive-deps */
const retryTimesRef = (0, _react.useRef)(0);
const [retryMark, setRetryMark] = (0, _react.useState)(0);
(0, _react.useEffect)(() => {
retryTimesRef.current = 0;
}, deps);
(0, _react.useEffect)(() => {
const [clearFn, ready] = func(retryTimesRef.current);
if (!ready) {
retryTimesRef.current += 1;
setRetryMark(count => count + 1);
}
return clearFn;
}, [...deps, retryMark]);
/* eslint-enable react-hooks/exhaustive-deps */
}
/**
* Lock focus within an element.
* When locked, focus will be restricted to focusable elements within the specified element.
* If multiple elements are locked, only the last locked element will be effective.
* @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.
*/
function useLockFocus(lock, getElement) {
const id = (0, _useId.default)();
const getElementRef = (0, _react.useRef)(getElement);
getElementRef.current = getElement;
const lockEffect = retryTimes => {
if (!lock) {
return [undefined, true];
}
const element = getElementRef.current();
if (element) {
return [lockFocus(element, id), true];
}
return [undefined, retryTimes >= 1];
};
useRetryEffect(lockEffect, [id, lock]);
const ignoreElement = ele => {
if (ele) {
// Set the ignored element using stable ID
ignoredElementMap.set(id, ele);
}
};
return [ignoreElement];
}
@@ -0,0 +1,2 @@
declare const _default: (element: Element) => boolean;
export default _default;
+36
View File
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = element => {
if (!element) {
return false;
}
if (element instanceof Element) {
if (element.offsetParent) {
return true;
}
if (element.getBBox) {
const {
width,
height
} = element.getBBox();
if (width || height) {
return true;
}
}
if (element.getBoundingClientRect) {
const {
width,
height
} = element.getBoundingClientRect();
if (width || height) {
return true;
}
}
}
return false;
};
exports.default = _default;
@@ -0,0 +1,12 @@
export interface scrollLockOptions {
container: HTMLElement;
}
export default class ScrollLocker {
private lockTarget;
private options;
constructor(options?: scrollLockOptions);
getContainer: () => HTMLElement | undefined;
reLock: (options?: scrollLockOptions) => void;
lock: () => void;
unLock: () => void;
}
+117
View File
@@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _getScrollBarSize = _interopRequireDefault(require("../getScrollBarSize"));
var _setStyle = _interopRequireDefault(require("../setStyle"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
let uuid = 0;
let locks = [];
const scrollingEffectClassName = 'ant-scrolling-effect';
const scrollingEffectClassNameReg = new RegExp(`${scrollingEffectClassName}`, 'g');
// https://github.com/ant-design/ant-design/issues/19340
// https://github.com/ant-design/ant-design/issues/19332
const cacheStyle = new Map();
class ScrollLocker {
lockTarget;
options;
constructor(options) {
// eslint-disable-next-line no-plusplus
this.lockTarget = uuid++;
this.options = options;
}
getContainer = () => {
return this.options?.container;
};
// if options change...
reLock = options => {
const findLock = locks.find(({
target
}) => target === this.lockTarget);
if (findLock) {
this.unLock();
}
this.options = options;
if (findLock) {
findLock.options = options;
this.lock();
}
};
lock = () => {
// If lockTarget exist return
if (locks.some(({
target
}) => target === this.lockTarget)) {
return;
}
// If same container effect, return
if (locks.some(({
options
}) => options?.container === this.options?.container)) {
locks = [...locks, {
target: this.lockTarget,
options: this.options
}];
return;
}
let scrollBarSize = 0;
const container = this.options?.container || document.body;
if (container === document.body && window.innerWidth - document.documentElement.clientWidth > 0 || container.scrollHeight > container.clientHeight) {
if (getComputedStyle(container).overflow !== 'hidden') {
scrollBarSize = (0, _getScrollBarSize.default)();
}
}
const containerClassName = container.className;
if (locks.filter(({
options
}) => options?.container === this.options?.container).length === 0) {
cacheStyle.set(container, (0, _setStyle.default)({
width: scrollBarSize !== 0 ? `calc(100% - ${scrollBarSize}px)` : undefined,
overflow: 'hidden',
overflowX: 'hidden',
overflowY: 'hidden'
}, {
element: container
}));
}
// https://github.com/ant-design/ant-design/issues/19729
if (!scrollingEffectClassNameReg.test(containerClassName)) {
const addClassName = `${containerClassName} ${scrollingEffectClassName}`;
container.className = addClassName.trim();
}
locks = [...locks, {
target: this.lockTarget,
options: this.options
}];
};
unLock = () => {
const findLock = locks.find(({
target
}) => target === this.lockTarget);
locks = locks.filter(({
target
}) => target !== this.lockTarget);
if (!findLock || locks.some(({
options
}) => options?.container === findLock.options?.container)) {
return;
}
// Remove Effect
const container = this.options?.container || document.body;
const containerClassName = container.className;
if (!scrollingEffectClassNameReg.test(containerClassName)) return;
(0, _setStyle.default)(cacheStyle.get(container), {
element: container
});
cacheStyle.delete(container);
container.className = container.className.replace(scrollingEffectClassNameReg, '').trim();
};
}
exports.default = ScrollLocker;
+8
View File
@@ -0,0 +1,8 @@
/**
* Check if is in shadowRoot
*/
export declare function inShadow(ele: Node): boolean;
/**
* Return shadowRoot if possible
*/
export declare function getShadowRoot(ele: Node): ShadowRoot;
+24
View File
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getShadowRoot = getShadowRoot;
exports.inShadow = inShadow;
function getRoot(ele) {
return ele?.getRootNode?.();
}
/**
* Check if is in shadowRoot
*/
function inShadow(ele) {
return getRoot(ele) instanceof ShadowRoot;
}
/**
* Return shadowRoot if possible
*/
function getShadowRoot(ele) {
return inShadow(ele) ? getRoot(ele) : null;
}
@@ -0,0 +1,2 @@
export declare function isStyleSupport(styleName: string | string[]): boolean;
export declare function isStyleSupport(styleName: string, styleValue: any): boolean;
@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isStyleSupport = isStyleSupport;
var _canUseDom = _interopRequireDefault(require("./canUseDom"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const isStyleNameSupport = styleName => {
if ((0, _canUseDom.default)() && window.document.documentElement) {
const styleNameList = Array.isArray(styleName) ? styleName : [styleName];
const {
documentElement
} = window.document;
return styleNameList.some(name => name in documentElement.style);
}
return false;
};
const isStyleValueSupport = (styleName, value) => {
if (!isStyleNameSupport(styleName)) {
return false;
}
const ele = document.createElement('div');
const origin = ele.style[styleName];
ele.style[styleName] = value;
return ele.style[styleName] !== origin;
};
function isStyleSupport(styleName, styleValue) {
if (!Array.isArray(styleName) && styleValue !== undefined) {
return isStyleValueSupport(styleName, styleValue);
}
return isStyleNameSupport(styleName);
}
+437
View File
@@ -0,0 +1,437 @@
/**
* @ignore
* some key-codes definition and utils from closure-library
* @author yiminghe@gmail.com
*/
declare const KeyCode: {
/**
* MAC_ENTER
*/
MAC_ENTER: number;
/**
* BACKSPACE
*/
BACKSPACE: number;
/**
* TAB
*/
TAB: number;
/**
* NUMLOCK on FF/Safari Mac
*/
NUM_CENTER: number;
/**
* ENTER
*/
ENTER: number;
/**
* SHIFT
*/
SHIFT: number;
/**
* CTRL
*/
CTRL: number;
/**
* ALT
*/
ALT: number;
/**
* PAUSE
*/
PAUSE: number;
/**
* CAPS_LOCK
*/
CAPS_LOCK: number;
/**
* ESC
*/
ESC: number;
/**
* SPACE
*/
SPACE: number;
/**
* PAGE_UP
*/
PAGE_UP: number;
/**
* PAGE_DOWN
*/
PAGE_DOWN: number;
/**
* END
*/
END: number;
/**
* HOME
*/
HOME: number;
/**
* LEFT
*/
LEFT: number;
/**
* UP
*/
UP: number;
/**
* RIGHT
*/
RIGHT: number;
/**
* DOWN
*/
DOWN: number;
/**
* PRINT_SCREEN
*/
PRINT_SCREEN: number;
/**
* INSERT
*/
INSERT: number;
/**
* DELETE
*/
DELETE: number;
/**
* ZERO
*/
ZERO: number;
/**
* ONE
*/
ONE: number;
/**
* TWO
*/
TWO: number;
/**
* THREE
*/
THREE: number;
/**
* FOUR
*/
FOUR: number;
/**
* FIVE
*/
FIVE: number;
/**
* SIX
*/
SIX: number;
/**
* SEVEN
*/
SEVEN: number;
/**
* EIGHT
*/
EIGHT: number;
/**
* NINE
*/
NINE: number;
/**
* QUESTION_MARK
*/
QUESTION_MARK: number;
/**
* A
*/
A: number;
/**
* B
*/
B: number;
/**
* C
*/
C: number;
/**
* D
*/
D: number;
/**
* E
*/
E: number;
/**
* F
*/
F: number;
/**
* G
*/
G: number;
/**
* H
*/
H: number;
/**
* I
*/
I: number;
/**
* J
*/
J: number;
/**
* K
*/
K: number;
/**
* L
*/
L: number;
/**
* M
*/
M: number;
/**
* N
*/
N: number;
/**
* O
*/
O: number;
/**
* P
*/
P: number;
/**
* Q
*/
Q: number;
/**
* R
*/
R: number;
/**
* S
*/
S: number;
/**
* T
*/
T: number;
/**
* U
*/
U: number;
/**
* V
*/
V: number;
/**
* W
*/
W: number;
/**
* X
*/
X: number;
/**
* Y
*/
Y: number;
/**
* Z
*/
Z: number;
/**
* META
*/
META: number;
/**
* WIN_KEY_RIGHT
*/
WIN_KEY_RIGHT: number;
/**
* CONTEXT_MENU
*/
CONTEXT_MENU: number;
/**
* NUM_ZERO
*/
NUM_ZERO: number;
/**
* NUM_ONE
*/
NUM_ONE: number;
/**
* NUM_TWO
*/
NUM_TWO: number;
/**
* NUM_THREE
*/
NUM_THREE: number;
/**
* NUM_FOUR
*/
NUM_FOUR: number;
/**
* NUM_FIVE
*/
NUM_FIVE: number;
/**
* NUM_SIX
*/
NUM_SIX: number;
/**
* NUM_SEVEN
*/
NUM_SEVEN: number;
/**
* NUM_EIGHT
*/
NUM_EIGHT: number;
/**
* NUM_NINE
*/
NUM_NINE: number;
/**
* NUM_MULTIPLY
*/
NUM_MULTIPLY: number;
/**
* NUM_PLUS
*/
NUM_PLUS: number;
/**
* NUM_MINUS
*/
NUM_MINUS: number;
/**
* NUM_PERIOD
*/
NUM_PERIOD: number;
/**
* NUM_DIVISION
*/
NUM_DIVISION: number;
/**
* F1
*/
F1: number;
/**
* F2
*/
F2: number;
/**
* F3
*/
F3: number;
/**
* F4
*/
F4: number;
/**
* F5
*/
F5: number;
/**
* F6
*/
F6: number;
/**
* F7
*/
F7: number;
/**
* F8
*/
F8: number;
/**
* F9
*/
F9: number;
/**
* F10
*/
F10: number;
/**
* F11
*/
F11: number;
/**
* F12
*/
F12: number;
/**
* NUMLOCK
*/
NUMLOCK: number;
/**
* SEMICOLON
*/
SEMICOLON: number;
/**
* DASH
*/
DASH: number;
/**
* EQUALS
*/
EQUALS: number;
/**
* COMMA
*/
COMMA: number;
/**
* PERIOD
*/
PERIOD: number;
/**
* SLASH
*/
SLASH: number;
/**
* APOSTROPHE
*/
APOSTROPHE: number;
/**
* SINGLE_QUOTE
*/
SINGLE_QUOTE: number;
/**
* OPEN_SQUARE_BRACKET
*/
OPEN_SQUARE_BRACKET: number;
/**
* BACKSLASH
*/
BACKSLASH: number;
/**
* CLOSE_SQUARE_BRACKET
*/
CLOSE_SQUARE_BRACKET: number;
/**
* WIN_KEY
*/
WIN_KEY: number;
/**
* MAC_FF_META
*/
MAC_FF_META: number;
/**
* WIN_IME
*/
WIN_IME: number;
/**
* whether text and modified key is entered at the same time.
*/
isTextModifyingKeyEvent: (e: KeyboardEvent) => boolean;
/**
* whether character is entered.
*/
isCharacterKey: (keyCode: number) => boolean;
isEditableTarget: (e: KeyboardEvent) => boolean;
};
export default KeyCode;
+557
View File
@@ -0,0 +1,557 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/**
* @ignore
* some key-codes definition and utils from closure-library
* @author yiminghe@gmail.com
*/
const KeyCode = {
/**
* MAC_ENTER
*/
MAC_ENTER: 3,
/**
* BACKSPACE
*/
BACKSPACE: 8,
/**
* TAB
*/
TAB: 9,
/**
* NUMLOCK on FF/Safari Mac
*/
NUM_CENTER: 12,
// NUMLOCK on FF/Safari Mac
/**
* ENTER
*/
ENTER: 13,
/**
* SHIFT
*/
SHIFT: 16,
/**
* CTRL
*/
CTRL: 17,
/**
* ALT
*/
ALT: 18,
/**
* PAUSE
*/
PAUSE: 19,
/**
* CAPS_LOCK
*/
CAPS_LOCK: 20,
/**
* ESC
*/
ESC: 27,
/**
* SPACE
*/
SPACE: 32,
/**
* PAGE_UP
*/
PAGE_UP: 33,
// also NUM_NORTH_EAST
/**
* PAGE_DOWN
*/
PAGE_DOWN: 34,
// also NUM_SOUTH_EAST
/**
* END
*/
END: 35,
// also NUM_SOUTH_WEST
/**
* HOME
*/
HOME: 36,
// also NUM_NORTH_WEST
/**
* LEFT
*/
LEFT: 37,
// also NUM_WEST
/**
* UP
*/
UP: 38,
// also NUM_NORTH
/**
* RIGHT
*/
RIGHT: 39,
// also NUM_EAST
/**
* DOWN
*/
DOWN: 40,
// also NUM_SOUTH
/**
* PRINT_SCREEN
*/
PRINT_SCREEN: 44,
/**
* INSERT
*/
INSERT: 45,
// also NUM_INSERT
/**
* DELETE
*/
DELETE: 46,
// also NUM_DELETE
/**
* ZERO
*/
ZERO: 48,
/**
* ONE
*/
ONE: 49,
/**
* TWO
*/
TWO: 50,
/**
* THREE
*/
THREE: 51,
/**
* FOUR
*/
FOUR: 52,
/**
* FIVE
*/
FIVE: 53,
/**
* SIX
*/
SIX: 54,
/**
* SEVEN
*/
SEVEN: 55,
/**
* EIGHT
*/
EIGHT: 56,
/**
* NINE
*/
NINE: 57,
/**
* QUESTION_MARK
*/
QUESTION_MARK: 63,
// needs localization
/**
* A
*/
A: 65,
/**
* B
*/
B: 66,
/**
* C
*/
C: 67,
/**
* D
*/
D: 68,
/**
* E
*/
E: 69,
/**
* F
*/
F: 70,
/**
* G
*/
G: 71,
/**
* H
*/
H: 72,
/**
* I
*/
I: 73,
/**
* J
*/
J: 74,
/**
* K
*/
K: 75,
/**
* L
*/
L: 76,
/**
* M
*/
M: 77,
/**
* N
*/
N: 78,
/**
* O
*/
O: 79,
/**
* P
*/
P: 80,
/**
* Q
*/
Q: 81,
/**
* R
*/
R: 82,
/**
* S
*/
S: 83,
/**
* T
*/
T: 84,
/**
* U
*/
U: 85,
/**
* V
*/
V: 86,
/**
* W
*/
W: 87,
/**
* X
*/
X: 88,
/**
* Y
*/
Y: 89,
/**
* Z
*/
Z: 90,
/**
* META
*/
META: 91,
// WIN_KEY_LEFT
/**
* WIN_KEY_RIGHT
*/
WIN_KEY_RIGHT: 92,
/**
* CONTEXT_MENU
*/
CONTEXT_MENU: 93,
/**
* NUM_ZERO
*/
NUM_ZERO: 96,
/**
* NUM_ONE
*/
NUM_ONE: 97,
/**
* NUM_TWO
*/
NUM_TWO: 98,
/**
* NUM_THREE
*/
NUM_THREE: 99,
/**
* NUM_FOUR
*/
NUM_FOUR: 100,
/**
* NUM_FIVE
*/
NUM_FIVE: 101,
/**
* NUM_SIX
*/
NUM_SIX: 102,
/**
* NUM_SEVEN
*/
NUM_SEVEN: 103,
/**
* NUM_EIGHT
*/
NUM_EIGHT: 104,
/**
* NUM_NINE
*/
NUM_NINE: 105,
/**
* NUM_MULTIPLY
*/
NUM_MULTIPLY: 106,
/**
* NUM_PLUS
*/
NUM_PLUS: 107,
/**
* NUM_MINUS
*/
NUM_MINUS: 109,
/**
* NUM_PERIOD
*/
NUM_PERIOD: 110,
/**
* NUM_DIVISION
*/
NUM_DIVISION: 111,
/**
* F1
*/
F1: 112,
/**
* F2
*/
F2: 113,
/**
* F3
*/
F3: 114,
/**
* F4
*/
F4: 115,
/**
* F5
*/
F5: 116,
/**
* F6
*/
F6: 117,
/**
* F7
*/
F7: 118,
/**
* F8
*/
F8: 119,
/**
* F9
*/
F9: 120,
/**
* F10
*/
F10: 121,
/**
* F11
*/
F11: 122,
/**
* F12
*/
F12: 123,
/**
* NUMLOCK
*/
NUMLOCK: 144,
/**
* SEMICOLON
*/
SEMICOLON: 186,
// needs localization
/**
* DASH
*/
DASH: 189,
// needs localization
/**
* EQUALS
*/
EQUALS: 187,
// needs localization
/**
* COMMA
*/
COMMA: 188,
// needs localization
/**
* PERIOD
*/
PERIOD: 190,
// needs localization
/**
* SLASH
*/
SLASH: 191,
// needs localization
/**
* APOSTROPHE
*/
APOSTROPHE: 192,
// needs localization
/**
* SINGLE_QUOTE
*/
SINGLE_QUOTE: 222,
// needs localization
/**
* OPEN_SQUARE_BRACKET
*/
OPEN_SQUARE_BRACKET: 219,
// needs localization
/**
* BACKSLASH
*/
BACKSLASH: 220,
// needs localization
/**
* CLOSE_SQUARE_BRACKET
*/
CLOSE_SQUARE_BRACKET: 221,
// needs localization
/**
* WIN_KEY
*/
WIN_KEY: 224,
/**
* MAC_FF_META
*/
MAC_FF_META: 224,
// Firefox (Gecko) fires this for the meta key instead of 91
/**
* WIN_IME
*/
WIN_IME: 229,
// ======================== Function ========================
/**
* whether text and modified key is entered at the same time.
*/
isTextModifyingKeyEvent: function isTextModifyingKeyEvent(e) {
const {
keyCode
} = e;
if (e.altKey && !e.ctrlKey || e.metaKey ||
// Function keys don't generate text
keyCode >= KeyCode.F1 && keyCode <= KeyCode.F12) {
return false;
}
// The following keys are quite harmless, even in combination with
// CTRL, ALT or SHIFT.
switch (keyCode) {
case KeyCode.ALT:
case KeyCode.CAPS_LOCK:
case KeyCode.CONTEXT_MENU:
case KeyCode.CTRL:
case KeyCode.DOWN:
case KeyCode.END:
case KeyCode.ESC:
case KeyCode.HOME:
case KeyCode.INSERT:
case KeyCode.LEFT:
case KeyCode.MAC_FF_META:
case KeyCode.META:
case KeyCode.NUMLOCK:
case KeyCode.NUM_CENTER:
case KeyCode.PAGE_DOWN:
case KeyCode.PAGE_UP:
case KeyCode.PAUSE:
case KeyCode.PRINT_SCREEN:
case KeyCode.RIGHT:
case KeyCode.SHIFT:
case KeyCode.UP:
case KeyCode.WIN_KEY:
case KeyCode.WIN_KEY_RIGHT:
return false;
default:
return true;
}
},
/**
* whether character is entered.
*/
isCharacterKey: function isCharacterKey(keyCode) {
if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) {
return true;
}
if (keyCode >= KeyCode.NUM_ZERO && keyCode <= KeyCode.NUM_MULTIPLY) {
return true;
}
if (keyCode >= KeyCode.A && keyCode <= KeyCode.Z) {
return true;
}
// Safari sends zero key code for non-latin characters.
if (window.navigator.userAgent.indexOf('WebKit') !== -1 && keyCode === 0) {
return true;
}
switch (keyCode) {
case KeyCode.SPACE:
case KeyCode.QUESTION_MARK:
case KeyCode.NUM_PLUS:
case KeyCode.NUM_MINUS:
case KeyCode.NUM_PERIOD:
case KeyCode.NUM_DIVISION:
case KeyCode.SEMICOLON:
case KeyCode.DASH:
case KeyCode.EQUALS:
case KeyCode.COMMA:
case KeyCode.PERIOD:
case KeyCode.SLASH:
case KeyCode.APOSTROPHE:
case KeyCode.SINGLE_QUOTE:
case KeyCode.OPEN_SQUARE_BRACKET:
case KeyCode.BACKSLASH:
case KeyCode.CLOSE_SQUARE_BRACKET:
return true;
default:
return false;
}
},
isEditableTarget: function isEditableTarget(e) {
const target = e.target;
if (!(target instanceof HTMLElement)) {
return false;
}
const tagName = target.tagName;
if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT' || target.isContentEditable) {
return true;
}
return false;
}
};
var _default = exports.default = KeyCode;
+9
View File
@@ -0,0 +1,9 @@
import type * as React from 'react';
export type PortalRef = {};
export interface PortalProps {
didUpdate?: (prevProps: PortalProps) => void;
getContainer: () => HTMLElement;
children?: React.ReactNode;
}
declare const Portal: React.ForwardRefExoticComponent<PortalProps & React.RefAttributes<PortalRef>>;
export default Portal;
+50
View File
@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = require("react");
var _reactDom = _interopRequireDefault(require("react-dom"));
var _canUseDom = _interopRequireDefault(require("./Dom/canUseDom"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const Portal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
const {
didUpdate,
getContainer,
children
} = props;
const parentRef = (0, _react.useRef)(null);
const containerRef = (0, _react.useRef)(null);
// Ref return nothing, only for wrapper check exist
(0, _react.useImperativeHandle)(ref, () => ({}));
// Create container in client side with sync to avoid useEffect not get ref
const initRef = (0, _react.useRef)(false);
if (!initRef.current && (0, _canUseDom.default)()) {
containerRef.current = getContainer();
parentRef.current = containerRef.current.parentNode;
initRef.current = true;
}
// [Legacy] Used by `rc-trigger`
(0, _react.useEffect)(() => {
didUpdate?.(props);
});
(0, _react.useEffect)(() => {
// Restore container to original place
// React 18 StrictMode will unmount first and mount back for effect test:
// https://reactjs.org/blog/2022/03/29/react-v18.html#new-strict-mode-behaviors
if (containerRef.current.parentNode === null && parentRef.current !== null) {
parentRef.current.appendChild(containerRef.current);
}
return () => {
// [Legacy] This should not be handle by Portal but parent PortalWrapper instead.
// Since some component use `Portal` directly, we have to keep the logic here.
containerRef.current?.parentNode?.removeChild(containerRef.current);
};
}, []);
return containerRef.current ? /*#__PURE__*/_reactDom.default.createPortal(children, containerRef.current) : null;
});
var _default = exports.default = Portal;
+51
View File
@@ -0,0 +1,51 @@
import * as React from 'react';
import type { PortalRef } from './Portal';
import ScrollLocker from './Dom/scrollLocker';
/** @private Test usage only */
export declare function getOpenCount(): number;
export type GetContainer = string | HTMLElement | (() => HTMLElement);
export interface PortalWrapperProps {
visible?: boolean;
getContainer?: GetContainer;
wrapperClassName?: string;
forceRender?: boolean;
children: (info: {
getOpenCount: () => number;
getContainer: () => HTMLElement;
switchScrollingEffect: () => void;
scrollLocker: ScrollLocker;
ref?: (c: any) => void;
}) => React.ReactNode;
}
declare class PortalWrapper extends React.Component<PortalWrapperProps> {
container?: HTMLElement;
componentRef: React.RefObject<PortalRef>;
rafId?: number;
scrollLocker: ScrollLocker;
constructor(props: PortalWrapperProps);
renderComponent?: (info: {
afterClose: (...params: any[]) => void;
onClose: (...params: any[]) => void;
visible: boolean;
}) => void;
componentDidMount(): void;
componentDidUpdate(prevProps: PortalWrapperProps): void;
updateScrollLocker: (prevProps?: Partial<PortalWrapperProps>) => void;
updateOpenCount: (prevProps?: Partial<PortalWrapperProps>) => void;
componentWillUnmount(): void;
attachToParent: (force?: boolean) => boolean;
getContainer: () => HTMLElement;
setWrapperClassName: () => void;
removeCurrentContainer: () => void;
/**
* Enhance ./switchScrollingEffect
* 1. Simulate document body scroll bar with
* 2. Record body has overflow style and recover when all of PortalWrapper invisible
* 3. Disable body scroll when PortalWrapper has open
*
* @memberof PortalWrapper
*/
switchScrollingEffect: () => void;
render(): any;
}
export default PortalWrapper;
+203
View File
@@ -0,0 +1,203 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.getOpenCount = getOpenCount;
var React = _interopRequireWildcard(require("react"));
var _raf = _interopRequireDefault(require("./raf"));
var _Portal = _interopRequireDefault(require("./Portal"));
var _canUseDom = _interopRequireDefault(require("./Dom/canUseDom"));
var _setStyle = _interopRequireDefault(require("./setStyle"));
var _scrollLocker = _interopRequireDefault(require("./Dom/scrollLocker"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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); }
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; }
/* eslint-disable no-underscore-dangle,react/require-default-props */
let openCount = 0;
const supportDom = (0, _canUseDom.default)();
/** @private Test usage only */
function getOpenCount() {
return process.env.NODE_ENV === 'test' ? openCount : 0;
}
// https://github.com/ant-design/ant-design/issues/19340
// https://github.com/ant-design/ant-design/issues/19332
let cacheOverflow = {};
const getParent = getContainer => {
if (!supportDom) {
return null;
}
if (getContainer) {
if (typeof getContainer === 'string') {
return document.querySelectorAll(getContainer)[0];
}
if (typeof getContainer === 'function') {
return getContainer();
}
if (typeof getContainer === 'object' && getContainer instanceof window.HTMLElement) {
return getContainer;
}
}
return document.body;
};
class PortalWrapper extends React.Component {
container;
componentRef = /*#__PURE__*/React.createRef();
rafId;
scrollLocker;
constructor(props) {
super(props);
this.scrollLocker = new _scrollLocker.default({
container: getParent(props.getContainer)
});
}
renderComponent;
componentDidMount() {
this.updateOpenCount();
if (!this.attachToParent()) {
this.rafId = (0, _raf.default)(() => {
this.forceUpdate();
});
}
}
componentDidUpdate(prevProps) {
this.updateOpenCount(prevProps);
this.updateScrollLocker(prevProps);
this.setWrapperClassName();
this.attachToParent();
}
updateScrollLocker = prevProps => {
const {
visible: prevVisible
} = prevProps || {};
const {
getContainer,
visible
} = this.props;
if (visible && visible !== prevVisible && supportDom && getParent(getContainer) !== this.scrollLocker.getContainer()) {
this.scrollLocker.reLock({
container: getParent(getContainer)
});
}
};
updateOpenCount = prevProps => {
const {
visible: prevVisible,
getContainer: prevGetContainer
} = prevProps || {};
const {
visible,
getContainer
} = this.props;
// Update count
if (visible !== prevVisible && supportDom && getParent(getContainer) === document.body) {
if (visible && !prevVisible) {
openCount += 1;
} else if (prevProps) {
openCount -= 1;
}
}
// Clean up container if needed
const getContainerIsFunc = typeof getContainer === 'function' && typeof prevGetContainer === 'function';
if (getContainerIsFunc ? getContainer.toString() !== prevGetContainer.toString() : getContainer !== prevGetContainer) {
this.removeCurrentContainer();
}
};
componentWillUnmount() {
const {
visible,
getContainer
} = this.props;
if (supportDom && getParent(getContainer) === document.body) {
// 离开时不会 render, 导到离开时数值不变,改用 func 。。
openCount = visible && openCount ? openCount - 1 : openCount;
}
this.removeCurrentContainer();
_raf.default.cancel(this.rafId);
}
attachToParent = (force = false) => {
if (force || this.container && !this.container.parentNode) {
const parent = getParent(this.props.getContainer);
if (parent) {
parent.appendChild(this.container);
return true;
}
return false;
}
return true;
};
getContainer = () => {
if (!supportDom) {
return null;
}
if (!this.container) {
this.container = document.createElement('div');
this.attachToParent(true);
}
this.setWrapperClassName();
return this.container;
};
setWrapperClassName = () => {
const {
wrapperClassName
} = this.props;
if (this.container && wrapperClassName && wrapperClassName !== this.container.className) {
this.container.className = wrapperClassName;
}
};
removeCurrentContainer = () => {
// Portal will remove from `parentNode`.
// Let's handle this again to avoid refactor issue.
this.container?.parentNode?.removeChild(this.container);
};
/**
* Enhance ./switchScrollingEffect
* 1. Simulate document body scroll bar with
* 2. Record body has overflow style and recover when all of PortalWrapper invisible
* 3. Disable body scroll when PortalWrapper has open
*
* @memberof PortalWrapper
*/
switchScrollingEffect = () => {
if (openCount === 1 && !Object.keys(cacheOverflow).length) {
// Must be set after switchScrollingEffect
cacheOverflow = (0, _setStyle.default)({
overflow: 'hidden',
overflowX: 'hidden',
overflowY: 'hidden'
});
} else if (!openCount) {
(0, _setStyle.default)(cacheOverflow);
cacheOverflow = {};
}
};
render() {
const {
children,
forceRender,
visible
} = this.props;
let portal = null;
const childProps = {
getOpenCount: () => openCount,
getContainer: this.getContainer,
switchScrollingEffect: this.switchScrollingEffect,
scrollLocker: this.scrollLocker
};
if (forceRender || visible || this.componentRef.current) {
portal = /*#__PURE__*/React.createElement(_Portal.default, {
getContainer: this.getContainer,
ref: this.componentRef
}, children(childProps));
}
return portal;
}
}
var _default = exports.default = PortalWrapper;
@@ -0,0 +1,4 @@
/**
* Compatible with React 18 or 19 to check if node is a Fragment.
*/
export default function isFragment(object: any): boolean;
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = isFragment;
const REACT_ELEMENT_TYPE_18 = Symbol.for('react.element');
const REACT_ELEMENT_TYPE_19 = Symbol.for('react.transitional.element');
const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
/**
* Compatible with React 18 or 19 to check if node is a Fragment.
*/
function isFragment(object) {
return (
// Base object type
object && typeof object === 'object' && (
// React Element type
object.$$typeof === REACT_ELEMENT_TYPE_18 || object.$$typeof === REACT_ELEMENT_TYPE_19) &&
// React Fragment type
object.type === REACT_FRAGMENT_TYPE
);
}
@@ -0,0 +1,9 @@
import type * as React from 'react';
import type { Root } from 'react-dom/client';
declare const MARK = "__rc_react_root__";
type ContainerType = (Element | DocumentFragment) & {
[MARK]?: Root;
};
export declare function render(node: React.ReactElement, container: ContainerType): void;
export declare function unmount(container: ContainerType): Promise<void>;
export {};
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.render = render;
exports.unmount = unmount;
var _client = require("react-dom/client");
const MARK = '__rc_react_root__';
// ========================== Render ==========================
function render(node, container) {
const root = container[MARK] || (0, _client.createRoot)(container);
root.render(node);
container[MARK] = root;
}
// ========================= Unmount ==========================
async function unmount(container) {
// Delay to unmount to avoid React 18 sync warning
return Promise.resolve().then(() => {
container[MARK]?.unmount();
delete container[MARK];
});
}
@@ -0,0 +1,2 @@
declare function composeProps<T extends Record<string, any>>(originProps: T, patchProps: Partial<T>, isAll?: boolean): T;
export default composeProps;
+23
View File
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function composeProps(originProps, patchProps, isAll) {
const composedProps = {
...originProps,
...(isAll ? patchProps : {})
};
Object.keys(patchProps).forEach(key => {
const func = patchProps[key];
if (typeof func === 'function') {
composedProps[key] = (...args) => {
func(...args);
return originProps[key]?.(...args);
};
}
});
return composedProps;
}
var _default = exports.default = composeProps;
@@ -0,0 +1,7 @@
type ScrollBarSize = {
width: number;
height: number;
};
export default function getScrollBarSize(fresh?: boolean): number;
export declare function getTargetScrollBarSize(target: HTMLElement): ScrollBarSize;
export {};
@@ -0,0 +1,88 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getScrollBarSize;
exports.getTargetScrollBarSize = getTargetScrollBarSize;
var _dynamicCSS = require("./Dom/dynamicCSS");
/* eslint-disable no-param-reassign */
let cached;
function measureScrollbarSize(ele) {
const randomId = `rc-scrollbar-measure-${Math.random().toString(36).substring(7)}`;
const measureEle = document.createElement('div');
measureEle.id = randomId;
// Create Style
const measureStyle = measureEle.style;
measureStyle.position = 'absolute';
measureStyle.left = '0';
measureStyle.top = '0';
measureStyle.width = '100px';
measureStyle.height = '100px';
measureStyle.overflow = 'scroll';
// Clone Style if needed
let fallbackWidth;
let fallbackHeight;
if (ele) {
const targetStyle = getComputedStyle(ele);
measureStyle.scrollbarColor = targetStyle.scrollbarColor;
measureStyle.scrollbarWidth = targetStyle.scrollbarWidth;
// Set Webkit style
const webkitScrollbarStyle = getComputedStyle(ele, '::-webkit-scrollbar');
const width = parseInt(webkitScrollbarStyle.width, 10);
const height = parseInt(webkitScrollbarStyle.height, 10);
// Try wrap to handle CSP case
try {
const widthStyle = width ? `width: ${webkitScrollbarStyle.width};` : '';
const heightStyle = height ? `height: ${webkitScrollbarStyle.height};` : '';
(0, _dynamicCSS.updateCSS)(`
#${randomId}::-webkit-scrollbar {
${widthStyle}
${heightStyle}
}`, randomId);
} catch (e) {
// Can't wrap, just log error
console.error(e);
// Get from style directly
fallbackWidth = width;
fallbackHeight = height;
}
}
document.body.appendChild(measureEle);
// Measure. Get fallback style if provided
const scrollWidth = ele && fallbackWidth && !Number.isNaN(fallbackWidth) ? fallbackWidth : measureEle.offsetWidth - measureEle.clientWidth;
const scrollHeight = ele && fallbackHeight && !Number.isNaN(fallbackHeight) ? fallbackHeight : measureEle.offsetHeight - measureEle.clientHeight;
// Clean up
document.body.removeChild(measureEle);
(0, _dynamicCSS.removeCSS)(randomId);
return {
width: scrollWidth,
height: scrollHeight
};
}
function getScrollBarSize(fresh) {
if (typeof document === 'undefined') {
return 0;
}
if (fresh || cached === undefined) {
cached = measureScrollbarSize();
}
return cached.width;
}
function getTargetScrollBarSize(target) {
if (typeof document === 'undefined' || !target || !(target instanceof Element)) {
return {
width: 0,
height: 0
};
}
return measureScrollbarSize(target);
}
@@ -0,0 +1,8 @@
type Updater<T> = (updater: T | ((origin: T) => T)) => void;
/**
* Similar to `useState` but will use props value if provided.
* From React 18, we do not need safe `useState` since it will not throw for unmounted update.
* This hooks remove the `onChange` & `postState` logic since we only need basic merged state logic.
*/
export default function useControlledState<T>(defaultStateValue: T | (() => T), value?: T): [T, Updater<T>];
export {};
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useControlledState;
var _react = require("react");
var _useLayoutEffect = _interopRequireDefault(require("./useLayoutEffect"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Similar to `useState` but will use props value if provided.
* From React 18, we do not need safe `useState` since it will not throw for unmounted update.
* This hooks remove the `onChange` & `postState` logic since we only need basic merged state logic.
*/
function useControlledState(defaultStateValue, value) {
const [innerValue, setInnerValue] = (0, _react.useState)(defaultStateValue);
const mergedValue = value !== undefined ? value : innerValue;
(0, _useLayoutEffect.default)(mount => {
if (!mount) {
setInnerValue(value);
}
}, [value]);
return [
// Value
mergedValue,
// Update function
setInnerValue];
}
@@ -0,0 +1,3 @@
/** As `React.useEffect` but pass origin value in callback and not need care deps length change. */
declare function useEffect(callback: (prevDeps: any[]) => void, deps: any[]): void;
export default useEffect;
+20
View File
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
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); }
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; }
/** As `React.useEffect` but pass origin value in callback and not need care deps length change. */
function useEffect(callback, deps) {
const prevRef = React.useRef(deps);
React.useEffect(() => {
if (deps.length !== prevRef.current.length || deps.some((dep, index) => dep !== prevRef.current[index])) {
callback(prevRef.current);
}
prevRef.current = deps;
});
}
var _default = exports.default = useEffect;
@@ -0,0 +1,2 @@
declare const useEvent: <T extends (...args: any[]) => any>(callback: T) => undefined extends T ? (...args: Parameters<NonNullable<T>>) => ReturnType<NonNullable<T>> | undefined : T;
export default useEvent;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
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); }
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; }
const useEvent = callback => {
const fnRef = React.useRef(callback);
fnRef.current = callback;
const memoFn = React.useCallback((...args) => fnRef.current?.(...args), []);
return memoFn;
};
var _default = exports.default = useEvent;
+13
View File
@@ -0,0 +1,13 @@
import * as React from 'react';
/** @private Note only worked in develop env. Not work in production. */
export declare function resetUuid(): void;
/**
* Generate a valid HTML id from prefix and key.
* Sanitizes the key by replacing invalid characters with hyphens.
* @param prefix - The prefix for the id
* @param key - The key from React element, may contain spaces or invalid characters
* @returns A valid HTML id string
*/
export declare function getId(prefix: string, key: React.Key): string;
declare const _default: (id?: string) => string;
export default _default;
+83
View File
@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.getId = getId;
exports.resetUuid = resetUuid;
var React = _interopRequireWildcard(require("react"));
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); }
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; }
function getUseId() {
// We need fully clone React function here to avoid webpack warning React 17 do not export `useId`
const fullClone = {
...React
};
return fullClone.useId;
}
let uuid = 0;
/** @private Note only worked in develop env. Not work in production. */
function resetUuid() {
if (process.env.NODE_ENV !== 'production') {
uuid = 0;
}
}
/**
* Generate a valid HTML id from prefix and key.
* Sanitizes the key by replacing invalid characters with hyphens.
* @param prefix - The prefix for the id
* @param key - The key from React element, may contain spaces or invalid characters
* @returns A valid HTML id string
*/
function getId(prefix, key) {
// React.Key can be string | number, convert to string first
const keyStr = String(key);
// Valid id characters: letters, digits, hyphen, underscore, colon, period
// Replace all invalid characters (including spaces) with hyphens to preserve length
const sanitizedKey = keyStr.replace(/[^a-zA-Z0-9_.:-]/g, '-');
return `${prefix}-${sanitizedKey}`;
}
const useOriginId = getUseId();
var _default = exports.default = useOriginId ?
// Use React `useId`
function useId(id) {
const reactId = useOriginId();
// Developer passed id is single source of truth
if (id) {
return id;
}
// Test env always return mock id
if (process.env.NODE_ENV === 'test') {
return 'test-id';
}
return reactId;
} :
// Use compatible of `useId`
function useCompatId(id) {
// Inner id for accessibility usage. Only work in client side
const [innerId, setInnerId] = React.useState('ssr-id');
React.useEffect(() => {
const nextId = uuid;
uuid += 1;
setInnerId(`rc_unique_${nextId}`);
}, []);
// Developer passed id is single source of truth
if (id) {
return id;
}
// Test env always return mock id
if (process.env.NODE_ENV === 'test') {
return 'test-id';
}
// Return react native id or inner id
return innerId;
};
@@ -0,0 +1,4 @@
import * as React from 'react';
declare const useLayoutEffect: (callback: (mount: boolean) => void | VoidFunction, deps?: React.DependencyList) => void;
export declare const useLayoutUpdateEffect: typeof React.useEffect;
export default useLayoutEffect;
@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useLayoutUpdateEffect = exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _canUseDom = _interopRequireDefault(require("../Dom/canUseDom"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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); }
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; }
/**
* Wrap `React.useLayoutEffect` which will not throw warning message in test env
*/
const useInternalLayoutEffect = process.env.NODE_ENV !== 'test' && (0, _canUseDom.default)() ? React.useLayoutEffect : React.useEffect;
const useLayoutEffect = (callback, deps) => {
const firstMountRef = React.useRef(true);
useInternalLayoutEffect(() => {
return callback(firstMountRef.current);
}, deps);
// We tell react that first mount has passed
useInternalLayoutEffect(() => {
firstMountRef.current = false;
return () => {
firstMountRef.current = true;
};
}, []);
};
const useLayoutUpdateEffect = (callback, deps) => {
useLayoutEffect(firstMount => {
if (!firstMount) {
return callback();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);
};
exports.useLayoutUpdateEffect = useLayoutUpdateEffect;
var _default = exports.default = useLayoutEffect;
@@ -0,0 +1 @@
export default function useMemo<Value, Condition = any[]>(getValue: () => Value, condition: Condition, shouldUpdate: (prev: Condition, next: Condition) => boolean): Value;
+17
View File
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useMemo;
var React = _interopRequireWildcard(require("react"));
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); }
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; }
function useMemo(getValue, condition, shouldUpdate) {
const cacheRef = React.useRef({});
if (!('value' in cacheRef.current) || shouldUpdate(cacheRef.current.condition, condition)) {
cacheRef.current.value = getValue();
cacheRef.current.condition = condition;
}
return cacheRef.current.value;
}
@@ -0,0 +1,13 @@
type Updater<T> = (updater: T | ((origin: T) => T), ignoreDestroy?: boolean) => void;
/**
* @deprecated Please use `useControlledState` instead if not need support < React 18.
* Similar to `useState` but will use props value if provided.
* Note that internal use rc-util `useState` hook.
*/
export default function useMergedState<T, R = T>(defaultStateValue: T | (() => T), option?: {
defaultValue?: T | (() => T);
value?: T;
onChange?: (value: T, prevValue: T) => void;
postState?: (value: T) => T;
}): [R, Updater<T>];
export {};
@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useMergedState;
var _useEvent = _interopRequireDefault(require("./useEvent"));
var _useLayoutEffect = require("./useLayoutEffect");
var _useState = _interopRequireDefault(require("./useState"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** We only think `undefined` is empty */
function hasValue(value) {
return value !== undefined;
}
/**
* @deprecated Please use `useControlledState` instead if not need support < React 18.
* Similar to `useState` but will use props value if provided.
* Note that internal use rc-util `useState` hook.
*/
function useMergedState(defaultStateValue, option) {
const {
defaultValue,
value,
onChange,
postState
} = option || {};
// ======================= Init =======================
const [innerValue, setInnerValue] = (0, _useState.default)(() => {
if (hasValue(value)) {
return value;
} else if (hasValue(defaultValue)) {
return typeof defaultValue === 'function' ? defaultValue() : defaultValue;
} else {
return typeof defaultStateValue === 'function' ? defaultStateValue() : defaultStateValue;
}
});
const mergedValue = value !== undefined ? value : innerValue;
const postMergedValue = postState ? postState(mergedValue) : mergedValue;
// ====================== Change ======================
const onChangeFn = (0, _useEvent.default)(onChange);
const [prevValue, setPrevValue] = (0, _useState.default)([mergedValue]);
(0, _useLayoutEffect.useLayoutUpdateEffect)(() => {
const prev = prevValue[0];
if (innerValue !== prev) {
onChangeFn(innerValue, prev);
}
}, [prevValue]);
// Sync value back to `undefined` when it from control to un-control
(0, _useLayoutEffect.useLayoutUpdateEffect)(() => {
if (!hasValue(value)) {
setInnerValue(value);
}
}, [value]);
// ====================== Update ======================
const triggerChange = (0, _useEvent.default)((updater, ignoreDestroy) => {
setInnerValue(updater, ignoreDestroy);
setPrevValue([mergedValue], ignoreDestroy);
});
return [postMergedValue, triggerChange];
}
@@ -0,0 +1,6 @@
/**
* Hook to detect if the user is on a mobile device
* Notice that this hook will only detect the device type in effect, so it will always be false in server side
*/
declare const useMobile: () => boolean;
export default useMobile;
+22
View File
@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = require("react");
var _isMobile = _interopRequireDefault(require("../isMobile"));
var _useLayoutEffect = _interopRequireDefault(require("./useLayoutEffect"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Hook to detect if the user is on a mobile device
* Notice that this hook will only detect the device type in effect, so it will always be false in server side
*/
const useMobile = () => {
const [mobile, setMobile] = (0, _react.useState)(false);
(0, _useLayoutEffect.default)(() => {
setMobile((0, _isMobile.default)());
}, []);
return mobile;
};
var _default = exports.default = useMobile;
@@ -0,0 +1,14 @@
type Updater<T> = T | ((prevValue: T) => T);
export type SetState<T> = (nextValue: Updater<T>,
/**
* Will not update state when destroyed.
* Developer should make sure this is safe to ignore.
*/
ignoreDestroy?: boolean) => void;
/**
* Same as React.useState but `setState` accept `ignoreDestroy` param to not to setState after destroyed.
* We do not make this auto is to avoid real memory leak.
* Developer should confirm it's safe to ignore themselves.
*/
declare const useSafeState: <T>(defaultValue?: T | (() => T)) => [T, SetState<T>];
export default useSafeState;
+32
View File
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
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); }
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; }
/**
* Same as React.useState but `setState` accept `ignoreDestroy` param to not to setState after destroyed.
* We do not make this auto is to avoid real memory leak.
* Developer should confirm it's safe to ignore themselves.
*/
const useSafeState = defaultValue => {
const destroyRef = React.useRef(false);
const [value, setValue] = React.useState(defaultValue);
React.useEffect(() => {
destroyRef.current = false;
return () => {
destroyRef.current = true;
};
}, []);
function safeSetState(updater, ignoreDestroy) {
if (ignoreDestroy && destroyRef.current) {
return;
}
setValue(updater);
}
return [value, safeSetState];
};
var _default = exports.default = useSafeState;
@@ -0,0 +1,9 @@
type Updater<T> = T | ((prevValue: T) => T);
export type SetState<T> = (nextValue: Updater<T>) => void;
/**
* Same as React.useState but will always get latest state.
* This is useful when React merge multiple state updates into one.
* e.g. onTransitionEnd trigger multiple event at once will be merged state update in React.
*/
declare function useSyncState<T>(defaultValue?: T): [get: () => T, set: SetState<T>];
export default useSyncState;
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _useEvent = _interopRequireDefault(require("./useEvent"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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); }
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; }
/**
* Same as React.useState but will always get latest state.
* This is useful when React merge multiple state updates into one.
* e.g. onTransitionEnd trigger multiple event at once will be merged state update in React.
*/
function useSyncState(defaultValue) {
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
const currentValueRef = React.useRef(defaultValue);
const getValue = (0, _useEvent.default)(() => {
return currentValueRef.current;
});
const setValue = (0, _useEvent.default)(updater => {
currentValueRef.current = typeof updater === 'function' ? updater(currentValueRef.current) : updater;
forceUpdate();
});
return [getValue, setValue];
}
var _default = exports.default = useSyncState;
+10
View File
@@ -0,0 +1,10 @@
export { default as useEvent } from './hooks/useEvent';
export { default as useMergedState } from './hooks/useMergedState';
export { default as useControlledState } from './hooks/useControlledState';
export { supportNodeRef, supportRef, useComposeRef } from './ref';
export { default as get } from './utils/get';
export { default as set, merge, mergeWith } from './utils/set';
export { default as warning, noteOnce } from './warning';
export { default as omit } from './omit';
export { default as toArray } from './Children/toArray';
export { default as mergeProps } from './mergeProps';
+108
View File
@@ -0,0 +1,108 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "get", {
enumerable: true,
get: function () {
return _get.default;
}
});
Object.defineProperty(exports, "merge", {
enumerable: true,
get: function () {
return _set.merge;
}
});
Object.defineProperty(exports, "mergeProps", {
enumerable: true,
get: function () {
return _mergeProps.default;
}
});
Object.defineProperty(exports, "mergeWith", {
enumerable: true,
get: function () {
return _set.mergeWith;
}
});
Object.defineProperty(exports, "noteOnce", {
enumerable: true,
get: function () {
return _warning.noteOnce;
}
});
Object.defineProperty(exports, "omit", {
enumerable: true,
get: function () {
return _omit.default;
}
});
Object.defineProperty(exports, "set", {
enumerable: true,
get: function () {
return _set.default;
}
});
Object.defineProperty(exports, "supportNodeRef", {
enumerable: true,
get: function () {
return _ref.supportNodeRef;
}
});
Object.defineProperty(exports, "supportRef", {
enumerable: true,
get: function () {
return _ref.supportRef;
}
});
Object.defineProperty(exports, "toArray", {
enumerable: true,
get: function () {
return _toArray.default;
}
});
Object.defineProperty(exports, "useComposeRef", {
enumerable: true,
get: function () {
return _ref.useComposeRef;
}
});
Object.defineProperty(exports, "useControlledState", {
enumerable: true,
get: function () {
return _useControlledState.default;
}
});
Object.defineProperty(exports, "useEvent", {
enumerable: true,
get: function () {
return _useEvent.default;
}
});
Object.defineProperty(exports, "useMergedState", {
enumerable: true,
get: function () {
return _useMergedState.default;
}
});
Object.defineProperty(exports, "warning", {
enumerable: true,
get: function () {
return _warning.default;
}
});
var _useEvent = _interopRequireDefault(require("./hooks/useEvent"));
var _useMergedState = _interopRequireDefault(require("./hooks/useMergedState"));
var _useControlledState = _interopRequireDefault(require("./hooks/useControlledState"));
var _ref = require("./ref");
var _get = _interopRequireDefault(require("./utils/get"));
var _set = _interopRequireWildcard(require("./utils/set"));
var _warning = _interopRequireWildcard(require("./warning"));
var _omit = _interopRequireDefault(require("./omit"));
var _toArray = _interopRequireDefault(require("./Children/toArray"));
var _mergeProps = _interopRequireDefault(require("./mergeProps"));
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); }
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; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+9
View File
@@ -0,0 +1,9 @@
/**
* Deeply compares two object literals.
* @param obj1 object 1
* @param obj2 object 2
* @param shallow shallow compare
* @returns
*/
declare function isEqual(obj1: any, obj2: any, shallow?: boolean): boolean;
export default isEqual;
+56
View File
@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _warning = _interopRequireDefault(require("./warning"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Deeply compares two object literals.
* @param obj1 object 1
* @param obj2 object 2
* @param shallow shallow compare
* @returns
*/
function isEqual(obj1, obj2, shallow = false) {
// https://github.com/mapbox/mapbox-gl-js/pull/5979/files#diff-fde7145050c47cc3a306856efd5f9c3016e86e859de9afbd02c879be5067e58f
const refSet = new Set();
function deepEqual(a, b, level = 1) {
const circular = refSet.has(a);
(0, _warning.default)(!circular, 'Warning: There may be circular references');
if (circular) {
return false;
}
if (a === b) {
return true;
}
if (shallow && level > 1) {
return false;
}
refSet.add(a);
const newLevel = level + 1;
if (Array.isArray(a)) {
if (!Array.isArray(b) || a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (!deepEqual(a[i], b[i], newLevel)) {
return false;
}
}
return true;
}
if (a && b && typeof a === 'object' && typeof b === 'object') {
const keys = Object.keys(a);
if (keys.length !== Object.keys(b).length) {
return false;
}
return keys.every(key => deepEqual(a[key], b[key], newLevel));
}
// other
return false;
}
return deepEqual(obj1, obj2);
}
var _default = exports.default = isEqual;
+2
View File
@@ -0,0 +1,2 @@
declare const getIsMobile: () => boolean;
export default getIsMobile;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _isMobile = _interopRequireDefault(require("is-mobile"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
let cached;
const getIsMobile = () => {
if (typeof cached === 'undefined') {
cached = (0, _isMobile.default)();
}
return cached;
};
var _default = exports.default = getIsMobile;
+8
View File
@@ -0,0 +1,8 @@
/**
* Merges multiple props objects into one. Unlike `Object.assign()` or `{ ...a, ...b }`, it skips
* properties whose value is explicitly set to `undefined`.
*/
declare function mergeProps<A, B>(a: A, b: B): B & A;
declare function mergeProps<A, B, C>(a: A, b: B, c: C): C & B & A;
declare function mergeProps<A, B, C, D>(a: A, b: B, c: C, d: D): D & C & B & A;
export default mergeProps;
+25
View File
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/**
* Merges multiple props objects into one. Unlike `Object.assign()` or `{ ...a, ...b }`, it skips
* properties whose value is explicitly set to `undefined`.
*/
function mergeProps(...items) {
const ret = {};
for (const item of items) {
if (item) {
for (const key of Object.keys(item)) {
if (item[key] !== undefined) {
ret[key] = item[key];
}
}
}
}
return ret;
}
var _default = exports.default = mergeProps;
+1
View File
@@ -0,0 +1 @@
export default function omit<T extends object, K extends keyof T>(obj: T, fields: K[] | readonly K[]): Omit<T, K>;
+15
View File
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = omit;
function omit(obj, fields) {
const clone = Object.assign({}, obj);
if (Array.isArray(fields)) {
fields.forEach(key => {
delete clone[key];
});
}
return clone;
}
+11
View File
@@ -0,0 +1,11 @@
export interface PickConfig {
aria?: boolean;
data?: boolean;
attr?: boolean;
}
/**
* Picker props from exist props with filter
* @param props Passed props
* @param ariaOnly boolean | { aria?: boolean; data?: boolean; attr?: boolean; } filter config
*/
export default function pickAttrs(props: object, ariaOnly?: boolean | PickConfig): {};
+69
View File
@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = pickAttrs;
const attributes = `accept acceptCharset accessKey action allowFullScreen allowTransparency
alt async autoComplete autoFocus autoPlay capture cellPadding cellSpacing challenge
charSet checked classID className colSpan cols content contentEditable contextMenu
controls coords crossOrigin data dateTime default defer dir disabled download draggable
encType form formAction formEncType formMethod formNoValidate formTarget frameBorder
headers height hidden high href hrefLang htmlFor httpEquiv icon id inputMode integrity
is keyParams keyType kind label lang list loop low manifest marginHeight marginWidth max maxLength media
mediaGroup method min minLength multiple muted name noValidate nonce open
optimum pattern placeholder poster preload radioGroup readOnly rel required
reversed role rowSpan rows sandbox scope scoped scrolling seamless selected
shape size sizes span spellCheck src srcDoc srcLang srcSet start step style
summary tabIndex target title type useMap value width wmode wrap`;
const eventsName = `onCopy onCut onPaste onCompositionEnd onCompositionStart onCompositionUpdate onKeyDown
onKeyPress onKeyUp onFocus onBlur onChange onInput onSubmit onClick onContextMenu onDoubleClick
onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown
onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp onSelect onTouchCancel
onTouchEnd onTouchMove onTouchStart onScroll onWheel onAbort onCanPlay onCanPlayThrough
onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata
onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting onLoad onError`;
const propList = `${attributes} ${eventsName}`.split(/[\s\n]+/);
/* eslint-enable max-len */
const ariaPrefix = 'aria-';
const dataPrefix = 'data-';
function match(key, prefix) {
return key.indexOf(prefix) === 0;
}
/**
* Picker props from exist props with filter
* @param props Passed props
* @param ariaOnly boolean | { aria?: boolean; data?: boolean; attr?: boolean; } filter config
*/
function pickAttrs(props, ariaOnly = false) {
let mergedConfig;
if (ariaOnly === false) {
mergedConfig = {
aria: true,
data: true,
attr: true
};
} else if (ariaOnly === true) {
mergedConfig = {
aria: true
};
} else {
mergedConfig = {
...ariaOnly
};
}
const attrs = {};
Object.keys(props).forEach(key => {
if (
// Aria
mergedConfig.aria && (key === 'role' || match(key, ariaPrefix)) ||
// Data
mergedConfig.data && match(key, dataPrefix) ||
// Attr
mergedConfig.attr && propList.includes(key)) {
attrs[key] = props[key];
}
});
return attrs;
}
+4
View File
@@ -0,0 +1,4 @@
/**
* Proxy object if environment supported
*/
export default function proxyObject<Obj extends object, ExtendObj extends object>(obj: Obj, extendProps: ExtendObj): Obj & ExtendObj;
+25
View File
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = proxyObject;
/**
* Proxy object if environment supported
*/
function proxyObject(obj, extendProps) {
if (typeof Proxy !== 'undefined' && obj) {
return new Proxy(obj, {
get(target, prop) {
if (extendProps[prop]) {
return extendProps[prop];
}
// Proxy origin property
const originProp = target[prop];
return typeof originProp === 'function' ? originProp.bind(target) : originProp;
}
});
}
return obj;
}
+6
View File
@@ -0,0 +1,6 @@
declare const wrapperRaf: {
(callback: () => void, times?: number): number;
cancel(id: number): void;
ids(): Map<number, number>;
};
export default wrapperRaf;
+49
View File
@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
let raf = callback => +setTimeout(callback, 16);
let caf = num => clearTimeout(num);
if (typeof window !== 'undefined' && 'requestAnimationFrame' in window) {
raf = callback => window.requestAnimationFrame(callback);
caf = handle => window.cancelAnimationFrame(handle);
}
let rafUUID = 0;
const rafIds = new Map();
function cleanup(id) {
rafIds.delete(id);
}
const wrapperRaf = (callback, times = 1) => {
rafUUID += 1;
const id = rafUUID;
function callRef(leftTimes) {
if (leftTimes === 0) {
// Clean up
cleanup(id);
// Trigger
callback();
} else {
// Next raf
const realId = raf(() => {
callRef(leftTimes - 1);
});
// Bind real raf id
rafIds.set(id, realId);
}
}
callRef(times);
return id;
};
wrapperRaf.cancel = id => {
const realId = rafIds.get(id);
cleanup(id);
return caf(realId);
};
if (process.env.NODE_ENV !== 'production') {
wrapperRaf.ids = () => rafIds;
}
var _default = exports.default = wrapperRaf;
+19
View File
@@ -0,0 +1,19 @@
import type * as React from 'react';
export declare const fillRef: <T>(ref: React.Ref<T>, node: T) => void;
/**
* Merge refs into one ref function to support ref passing.
*/
export declare const composeRef: <T>(...refs: React.Ref<T>[]) => React.Ref<T>;
export declare const useComposeRef: <T>(...refs: React.Ref<T>[]) => React.Ref<T>;
export declare const supportRef: (nodeOrComponent: any) => boolean;
interface RefAttributes<T> extends React.Attributes {
ref: React.Ref<T>;
}
export declare const supportNodeRef: <T = any>(node: React.ReactNode) => node is React.ReactElement<unknown, string | React.JSXElementConstructor<any>> & RefAttributes<T>;
/**
* In React 19. `ref` is not a property from node.
* But a property from `props.ref`.
* To check if `props.ref` exist or fallback to `ref`.
*/
export declare const getNodeRef: <T = any>(node: React.ReactNode) => React.Ref<T> | null;
export {};
+89
View File
@@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useComposeRef = exports.supportRef = exports.supportNodeRef = exports.getNodeRef = exports.fillRef = exports.composeRef = void 0;
var _react = require("react");
var _reactIs = require("react-is");
var _useMemo = _interopRequireDefault(require("./hooks/useMemo"));
var _isFragment = _interopRequireDefault(require("./React/isFragment"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const ReactMajorVersion = Number(_react.version.split('.')[0]);
const fillRef = (ref, node) => {
if (typeof ref === 'function') {
ref(node);
} else if (typeof ref === 'object' && ref && 'current' in ref) {
ref.current = node;
}
};
/**
* Merge refs into one ref function to support ref passing.
*/
exports.fillRef = fillRef;
const composeRef = (...refs) => {
const refList = refs.filter(Boolean);
if (refList.length <= 1) {
return refList[0];
}
return node => {
refs.forEach(ref => {
fillRef(ref, node);
});
};
};
exports.composeRef = composeRef;
const useComposeRef = (...refs) => {
return (0, _useMemo.default)(() => composeRef(...refs),
// eslint-disable-next-line react-hooks/exhaustive-deps
refs, (prev, next) => prev.length !== next.length || prev.every((ref, i) => ref !== next[i]));
};
exports.useComposeRef = useComposeRef;
const supportRef = nodeOrComponent => {
if (!nodeOrComponent) {
return false;
}
// React 19 no need `forwardRef` anymore. So just pass if is a React element.
if (isReactElement(nodeOrComponent) && ReactMajorVersion >= 19) {
return true;
}
const type = (0, _reactIs.isMemo)(nodeOrComponent) ? nodeOrComponent.type.type : nodeOrComponent.type;
// Function component node
if (typeof type === 'function' && !type.prototype?.render && type.$$typeof !== _reactIs.ForwardRef) {
return false;
}
// Class component
if (typeof nodeOrComponent === 'function' && !nodeOrComponent.prototype?.render && nodeOrComponent.$$typeof !== _reactIs.ForwardRef) {
return false;
}
return true;
};
exports.supportRef = supportRef;
function isReactElement(node) {
return /*#__PURE__*/(0, _react.isValidElement)(node) && !(0, _isFragment.default)(node);
}
const supportNodeRef = node => {
return isReactElement(node) && supportRef(node);
};
/**
* In React 19. `ref` is not a property from node.
* But a property from `props.ref`.
* To check if `props.ref` exist or fallback to `ref`.
*/
exports.supportNodeRef = supportNodeRef;
const getNodeRef = node => {
if (node && isReactElement(node)) {
const ele = node;
// Source from:
// https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/getReactNodeRef/getReactNodeRef.ts
return ele.props.propertyIsEnumerable('ref') ? ele.props.ref : ele.ref;
}
return null;
};
exports.getNodeRef = getNodeRef;
+12
View File
@@ -0,0 +1,12 @@
import type React from 'react';
export interface SetStyleOptions {
element?: HTMLElement;
}
/**
* Easy to set element style, return previous style
* IE browser compatible(IE browser doesn't merge overflow style, need to set it separately)
* https://github.com/ant-design/ant-design/issues/19393
*
*/
declare function setStyle(style: React.CSSProperties, options?: SetStyleOptions): React.CSSProperties;
export default setStyle;
+32
View File
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/**
* Easy to set element style, return previous style
* IE browser compatible(IE browser doesn't merge overflow style, need to set it separately)
* https://github.com/ant-design/ant-design/issues/19393
*
*/
function setStyle(style, options = {}) {
if (!style) {
return {};
}
const {
element = document.body
} = options;
const oldStyle = {};
const styleKeys = Object.keys(style);
// IE browser compatible
styleKeys.forEach(key => {
oldStyle[key] = element.style[key];
});
styleKeys.forEach(key => {
element.style[key] = style[key];
});
return oldStyle;
}
var _default = exports.default = setStyle;
@@ -0,0 +1,8 @@
export type ElementClass = Function;
export type Property = PropertyDescriptor | Function;
export declare function spyElementPrototypes<T extends ElementClass>(elementClass: T, properties: Record<string, Property>): {
mockRestore(): void;
};
export declare function spyElementPrototype(Element: ElementClass, propName: string, property: Property): {
mockRestore(): void;
};
+65
View File
@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.spyElementPrototype = spyElementPrototype;
exports.spyElementPrototypes = spyElementPrototypes;
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable no-param-reassign */
const NO_EXIST = {
__NOT_EXIST: true
};
function spyElementPrototypes(elementClass, properties) {
const propNames = Object.keys(properties);
const originDescriptors = {};
propNames.forEach(propName => {
const originDescriptor = Object.getOwnPropertyDescriptor(elementClass.prototype, propName);
originDescriptors[propName] = originDescriptor || NO_EXIST;
const spyProp = properties[propName];
if (typeof spyProp === 'function') {
// If is a function
elementClass.prototype[propName] = function spyFunc(...args) {
return spyProp.call(this, originDescriptor, ...args);
};
} else {
// Otherwise tread as a property
Object.defineProperty(elementClass.prototype, propName, {
...spyProp,
set(value) {
if (spyProp.set) {
return spyProp.set.call(this, originDescriptor, value);
}
return originDescriptor.set(value);
},
get() {
if (spyProp.get) {
return spyProp.get.call(this, originDescriptor);
}
return originDescriptor.get();
},
configurable: true
});
}
});
return {
mockRestore() {
propNames.forEach(propName => {
const originDescriptor = originDescriptors[propName];
if (originDescriptor === NO_EXIST) {
delete elementClass.prototype[propName];
} else if (typeof originDescriptor === 'function') {
elementClass.prototype[propName] = originDescriptor;
} else {
Object.defineProperty(elementClass.prototype, propName, originDescriptor);
}
});
}
};
}
function spyElementPrototype(Element, propName, property) {
return spyElementPrototypes(Element, {
[propName]: property
});
}
/* eslint-enable */
+1
View File
@@ -0,0 +1 @@
export default function get(entity: any, path: (string | number | symbol)[] | readonly (string | number | symbol)[]): any;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = get;
function get(entity, path) {
let current = entity;
for (let i = 0; i < path.length; i += 1) {
if (current === null || current === undefined) {
return undefined;
}
current = current[path[i]];
}
return current;
}
+18
View File
@@ -0,0 +1,18 @@
export type Path = (string | number | symbol)[];
export default function set<Entity = any, Output = Entity, Value = any>(entity: Entity, paths: Path, value: Value, removeIfUndefined?: boolean): Output;
export type MergeFn = (current: any, next: any) => any;
/**
* Merge multiple objects. Support custom merge logic.
* @param sources object sources
* @param config.prepareArray Customize array prepare function.
* It will return empty [] by default.
* So when match array, it will auto be override with next array in sources.
*/
export declare function mergeWith<T extends object>(sources: T[], config?: {
prepareArray?: MergeFn;
}): T;
/**
* Merge multiple objects into a new single object.
* Arrays will be replaced by default.
*/
export declare function merge<T extends object>(...sources: T[]): T;
+103
View File
@@ -0,0 +1,103 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = set;
exports.merge = merge;
exports.mergeWith = mergeWith;
var _get = _interopRequireDefault(require("./get"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function internalSet(entity, paths, value, removeIfUndefined) {
if (!paths.length) {
return value;
}
const [path, ...restPath] = paths;
let clone;
if (!entity && typeof path === 'number') {
clone = [];
} else if (Array.isArray(entity)) {
clone = [...entity];
} else {
clone = {
...entity
};
}
// Delete prop if `removeIfUndefined` and value is undefined
if (removeIfUndefined && value === undefined && restPath.length === 1) {
delete clone[path][restPath[0]];
} else {
clone[path] = internalSet(clone[path], restPath, value, removeIfUndefined);
}
return clone;
}
function set(entity, paths, value, removeIfUndefined = false) {
// Do nothing if `removeIfUndefined` and parent object not exist
if (paths.length && removeIfUndefined && value === undefined && !(0, _get.default)(entity, paths.slice(0, -1))) {
return entity;
}
return internalSet(entity, paths, value, removeIfUndefined);
}
function isObject(obj) {
return typeof obj === 'object' && obj !== null && Object.getPrototypeOf(obj) === Object.prototype;
}
function createEmpty(source) {
return Array.isArray(source) ? [] : {};
}
const keys = typeof Reflect === 'undefined' ? Object.keys : Reflect.ownKeys;
// ================================ Merge ================================
/**
* Merge multiple objects. Support custom merge logic.
* @param sources object sources
* @param config.prepareArray Customize array prepare function.
* It will return empty [] by default.
* So when match array, it will auto be override with next array in sources.
*/
function mergeWith(sources, config = {}) {
const {
prepareArray
} = config;
const finalPrepareArray = prepareArray || (() => []);
let clone = createEmpty(sources[0]);
sources.forEach(src => {
function internalMerge(path, parentLoopSet) {
const loopSet = new Set(parentLoopSet);
const value = (0, _get.default)(src, path);
const isArr = Array.isArray(value);
if (isArr || isObject(value)) {
// Only add not loop obj
if (!loopSet.has(value)) {
loopSet.add(value);
const originValue = (0, _get.default)(clone, path);
if (isArr) {
// Array will always be override
clone = set(clone, path, finalPrepareArray(originValue, value));
} else if (!originValue || typeof originValue !== 'object') {
// Init container if not exist
clone = set(clone, path, createEmpty(value));
}
keys(value).forEach(key => {
if (Object.getOwnPropertyDescriptor(value, key).enumerable) {
internalMerge([...path, key], loopSet);
}
});
}
} else {
clone = set(clone, path, value);
}
}
internalMerge([]);
});
return clone;
}
/**
* Merge multiple objects into a new single object.
* Arrays will be replaced by default.
*/
function merge(...sources) {
return mergeWith(sources);
}
+32
View File
@@ -0,0 +1,32 @@
export type preMessageFn = (message: string, type: 'warning' | 'note') => string | null | undefined | number;
/**
* Pre warning enable you to parse content before console.error.
* Modify to null will prevent warning.
*/
export declare const preMessage: (fn: preMessageFn) => void;
/**
* Warning if condition not match.
* @param valid Condition
* @param message Warning message
* @example
* ```js
* warning(false, 'some error'); // print some error
* warning(true, 'some error'); // print nothing
* warning(1 === 2, 'some error'); // print some error
* ```
*/
export declare function warning(valid: boolean, message: string): void;
/** @see Similar to {@link warning} */
export declare function note(valid: boolean, message: string): void;
export declare function resetWarned(): void;
export declare function call(method: (valid: boolean, message: string) => void, valid: boolean, message: string): void;
/** @see Same as {@link warning}, but only warn once for the same message */
export declare function warningOnce(valid: boolean, message: string): void;
export declare namespace warningOnce {
var preMessage: (fn: preMessageFn) => void;
var resetWarned: typeof import("./warning").resetWarned;
var noteOnce: typeof import("./warning").noteOnce;
}
/** @see Same as {@link warning}, but only warn once for the same message */
export declare function noteOnce(valid: boolean, message: string): void;
export default warningOnce;
+78
View File
@@ -0,0 +1,78 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.call = call;
exports.default = void 0;
exports.note = note;
exports.noteOnce = noteOnce;
exports.preMessage = void 0;
exports.resetWarned = resetWarned;
exports.warning = warning;
exports.warningOnce = warningOnce;
/* eslint-disable no-console */
let warned = {};
const preWarningFns = [];
/**
* Pre warning enable you to parse content before console.error.
* Modify to null will prevent warning.
*/
const preMessage = fn => {
preWarningFns.push(fn);
};
/**
* Warning if condition not match.
* @param valid Condition
* @param message Warning message
* @example
* ```js
* warning(false, 'some error'); // print some error
* warning(true, 'some error'); // print nothing
* warning(1 === 2, 'some error'); // print some error
* ```
*/
exports.preMessage = preMessage;
function warning(valid, message) {
if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
const finalMessage = preWarningFns.reduce((msg, preMessageFn) => preMessageFn(msg ?? '', 'warning'), message);
if (finalMessage) {
console.error(`Warning: ${finalMessage}`);
}
}
}
/** @see Similar to {@link warning} */
function note(valid, message) {
if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
const finalMessage = preWarningFns.reduce((msg, preMessageFn) => preMessageFn(msg ?? '', 'note'), message);
if (finalMessage) {
console.warn(`Note: ${finalMessage}`);
}
}
}
function resetWarned() {
warned = {};
}
function call(method, valid, message) {
if (!valid && !warned[message]) {
method(false, message);
warned[message] = true;
}
}
/** @see Same as {@link warning}, but only warn once for the same message */
function warningOnce(valid, message) {
call(warning, valid, message);
}
/** @see Same as {@link warning}, but only warn once for the same message */
function noteOnce(valid, message) {
call(note, valid, message);
}
warningOnce.preMessage = preMessage;
warningOnce.resetWarned = resetWarned;
warningOnce.noteOnce = noteOnce;
var _default = exports.default = warningOnce;