@itcase/storybook-config 1.2.46 → 1.2.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
- import React__default, { useEffect, useContext, useState, useRef, createContext, useReducer, useCallback, isValidElement, cloneElement, memo, useMemo, useImperativeHandle } from 'react';
2
+ import React__default, { version, isValidElement, useState, useMemo as useMemo$1, useEffect, useRef, useLayoutEffect as useLayoutEffect$1, useContext, createContext, useReducer, useCallback, cloneElement, memo, useImperativeHandle } from 'react';
3
+ import { createPortal, flushSync } from 'react-dom';
3
4
  import camelCase from 'lodash/camelCase';
4
5
  import castArray from 'lodash/castArray';
5
6
  import upperFirst from 'lodash/upperFirst';
@@ -1375,6 +1376,3654 @@ var jsxRuntimeExports = requireJsxRuntime();
1375
1376
 
1376
1377
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
1377
1378
 
1379
+ function canUseDom() {
1380
+ return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1381
+ }
1382
+
1383
+ var reactIs$1 = {exports: {}};
1384
+
1385
+ var reactIs_production_min$1 = {};
1386
+
1387
+ /**
1388
+ * @license React
1389
+ * react-is.production.min.js
1390
+ *
1391
+ * Copyright (c) Facebook, Inc. and its affiliates.
1392
+ *
1393
+ * This source code is licensed under the MIT license found in the
1394
+ * LICENSE file in the root directory of this source tree.
1395
+ */
1396
+
1397
+ var hasRequiredReactIs_production_min$1;
1398
+
1399
+ function requireReactIs_production_min$1 () {
1400
+ if (hasRequiredReactIs_production_min$1) return reactIs_production_min$1;
1401
+ hasRequiredReactIs_production_min$1 = 1;
1402
+ var b=Symbol.for("react.element"),c=Symbol.for("react.portal"),d=Symbol.for("react.fragment"),e=Symbol.for("react.strict_mode"),f=Symbol.for("react.profiler"),g=Symbol.for("react.provider"),h=Symbol.for("react.context"),k=Symbol.for("react.server_context"),l=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),n=Symbol.for("react.suspense_list"),p=Symbol.for("react.memo"),q=Symbol.for("react.lazy"),t=Symbol.for("react.offscreen"),u;u=Symbol.for("react.module.reference");
1403
+ function v(a){if("object"===typeof a&&null!==a){var r=a.$$typeof;switch(r){case b:switch(a=a.type,a){case d:case f:case e:case m:case n:return a;default:switch(a=a&&a.$$typeof,a){case k:case h:case l:case q:case p:case g:return a;default:return r}}case c:return r}}}reactIs_production_min$1.ContextConsumer=h;reactIs_production_min$1.ContextProvider=g;reactIs_production_min$1.Element=b;reactIs_production_min$1.ForwardRef=l;reactIs_production_min$1.Fragment=d;reactIs_production_min$1.Lazy=q;reactIs_production_min$1.Memo=p;reactIs_production_min$1.Portal=c;reactIs_production_min$1.Profiler=f;reactIs_production_min$1.StrictMode=e;reactIs_production_min$1.Suspense=m;
1404
+ reactIs_production_min$1.SuspenseList=n;reactIs_production_min$1.isAsyncMode=function(){return false};reactIs_production_min$1.isConcurrentMode=function(){return false};reactIs_production_min$1.isContextConsumer=function(a){return v(a)===h};reactIs_production_min$1.isContextProvider=function(a){return v(a)===g};reactIs_production_min$1.isElement=function(a){return "object"===typeof a&&null!==a&&a.$$typeof===b};reactIs_production_min$1.isForwardRef=function(a){return v(a)===l};reactIs_production_min$1.isFragment=function(a){return v(a)===d};reactIs_production_min$1.isLazy=function(a){return v(a)===q};reactIs_production_min$1.isMemo=function(a){return v(a)===p};
1405
+ reactIs_production_min$1.isPortal=function(a){return v(a)===c};reactIs_production_min$1.isProfiler=function(a){return v(a)===f};reactIs_production_min$1.isStrictMode=function(a){return v(a)===e};reactIs_production_min$1.isSuspense=function(a){return v(a)===m};reactIs_production_min$1.isSuspenseList=function(a){return v(a)===n};
1406
+ reactIs_production_min$1.isValidElementType=function(a){return "string"===typeof a||"function"===typeof a||a===d||a===f||a===e||a===m||a===n||a===t||"object"===typeof a&&null!==a&&(a.$$typeof===q||a.$$typeof===p||a.$$typeof===g||a.$$typeof===h||a.$$typeof===l||a.$$typeof===u||void 0!==a.getModuleId)?true:false};reactIs_production_min$1.typeOf=v;
1407
+ return reactIs_production_min$1;
1408
+ }
1409
+
1410
+ var reactIs_development$1 = {};
1411
+
1412
+ /**
1413
+ * @license React
1414
+ * react-is.development.js
1415
+ *
1416
+ * Copyright (c) Facebook, Inc. and its affiliates.
1417
+ *
1418
+ * This source code is licensed under the MIT license found in the
1419
+ * LICENSE file in the root directory of this source tree.
1420
+ */
1421
+
1422
+ var hasRequiredReactIs_development$1;
1423
+
1424
+ function requireReactIs_development$1 () {
1425
+ if (hasRequiredReactIs_development$1) return reactIs_development$1;
1426
+ hasRequiredReactIs_development$1 = 1;
1427
+
1428
+ if (process.env.NODE_ENV !== "production") {
1429
+ (function() {
1430
+
1431
+ // ATTENTION
1432
+ // When adding new symbols to this file,
1433
+ // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
1434
+ // The Symbol used to tag the ReactElement-like types.
1435
+ var REACT_ELEMENT_TYPE = Symbol.for('react.element');
1436
+ var REACT_PORTAL_TYPE = Symbol.for('react.portal');
1437
+ var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
1438
+ var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
1439
+ var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
1440
+ var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
1441
+ var REACT_CONTEXT_TYPE = Symbol.for('react.context');
1442
+ var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
1443
+ var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
1444
+ var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
1445
+ var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
1446
+ var REACT_MEMO_TYPE = Symbol.for('react.memo');
1447
+ var REACT_LAZY_TYPE = Symbol.for('react.lazy');
1448
+ var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
1449
+
1450
+ // -----------------------------------------------------------------------------
1451
+
1452
+ var enableScopeAPI = false; // Experimental Create Event Handle API.
1453
+ var enableCacheElement = false;
1454
+ var enableTransitionTracing = false; // No known bugs, but needs performance testing
1455
+
1456
+ var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
1457
+ // stuff. Intended to enable React core members to more easily debug scheduling
1458
+ // issues in DEV builds.
1459
+
1460
+ var enableDebugTracing = false; // Track which Fiber(s) schedule render work.
1461
+
1462
+ var REACT_MODULE_REFERENCE;
1463
+
1464
+ {
1465
+ REACT_MODULE_REFERENCE = Symbol.for('react.module.reference');
1466
+ }
1467
+
1468
+ function isValidElementType(type) {
1469
+ if (typeof type === 'string' || typeof type === 'function') {
1470
+ return true;
1471
+ } // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
1472
+
1473
+
1474
+ if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing ) {
1475
+ return true;
1476
+ }
1477
+
1478
+ if (typeof type === 'object' && type !== null) {
1479
+ if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object
1480
+ // types supported by any Flight configuration anywhere since
1481
+ // we don't know which Flight build this will end up being used
1482
+ // with.
1483
+ type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== undefined) {
1484
+ return true;
1485
+ }
1486
+ }
1487
+
1488
+ return false;
1489
+ }
1490
+
1491
+ function typeOf(object) {
1492
+ if (typeof object === 'object' && object !== null) {
1493
+ var $$typeof = object.$$typeof;
1494
+
1495
+ switch ($$typeof) {
1496
+ case REACT_ELEMENT_TYPE:
1497
+ var type = object.type;
1498
+
1499
+ switch (type) {
1500
+ case REACT_FRAGMENT_TYPE:
1501
+ case REACT_PROFILER_TYPE:
1502
+ case REACT_STRICT_MODE_TYPE:
1503
+ case REACT_SUSPENSE_TYPE:
1504
+ case REACT_SUSPENSE_LIST_TYPE:
1505
+ return type;
1506
+
1507
+ default:
1508
+ var $$typeofType = type && type.$$typeof;
1509
+
1510
+ switch ($$typeofType) {
1511
+ case REACT_SERVER_CONTEXT_TYPE:
1512
+ case REACT_CONTEXT_TYPE:
1513
+ case REACT_FORWARD_REF_TYPE:
1514
+ case REACT_LAZY_TYPE:
1515
+ case REACT_MEMO_TYPE:
1516
+ case REACT_PROVIDER_TYPE:
1517
+ return $$typeofType;
1518
+
1519
+ default:
1520
+ return $$typeof;
1521
+ }
1522
+
1523
+ }
1524
+
1525
+ case REACT_PORTAL_TYPE:
1526
+ return $$typeof;
1527
+ }
1528
+ }
1529
+
1530
+ return undefined;
1531
+ }
1532
+ var ContextConsumer = REACT_CONTEXT_TYPE;
1533
+ var ContextProvider = REACT_PROVIDER_TYPE;
1534
+ var Element = REACT_ELEMENT_TYPE;
1535
+ var ForwardRef = REACT_FORWARD_REF_TYPE;
1536
+ var Fragment = REACT_FRAGMENT_TYPE;
1537
+ var Lazy = REACT_LAZY_TYPE;
1538
+ var Memo = REACT_MEMO_TYPE;
1539
+ var Portal = REACT_PORTAL_TYPE;
1540
+ var Profiler = REACT_PROFILER_TYPE;
1541
+ var StrictMode = REACT_STRICT_MODE_TYPE;
1542
+ var Suspense = REACT_SUSPENSE_TYPE;
1543
+ var SuspenseList = REACT_SUSPENSE_LIST_TYPE;
1544
+ var hasWarnedAboutDeprecatedIsAsyncMode = false;
1545
+ var hasWarnedAboutDeprecatedIsConcurrentMode = false; // AsyncMode should be deprecated
1546
+
1547
+ function isAsyncMode(object) {
1548
+ {
1549
+ if (!hasWarnedAboutDeprecatedIsAsyncMode) {
1550
+ hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint
1551
+
1552
+ console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 18+.');
1553
+ }
1554
+ }
1555
+
1556
+ return false;
1557
+ }
1558
+ function isConcurrentMode(object) {
1559
+ {
1560
+ if (!hasWarnedAboutDeprecatedIsConcurrentMode) {
1561
+ hasWarnedAboutDeprecatedIsConcurrentMode = true; // Using console['warn'] to evade Babel and ESLint
1562
+
1563
+ console['warn']('The ReactIs.isConcurrentMode() alias has been deprecated, ' + 'and will be removed in React 18+.');
1564
+ }
1565
+ }
1566
+
1567
+ return false;
1568
+ }
1569
+ function isContextConsumer(object) {
1570
+ return typeOf(object) === REACT_CONTEXT_TYPE;
1571
+ }
1572
+ function isContextProvider(object) {
1573
+ return typeOf(object) === REACT_PROVIDER_TYPE;
1574
+ }
1575
+ function isElement(object) {
1576
+ return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
1577
+ }
1578
+ function isForwardRef(object) {
1579
+ return typeOf(object) === REACT_FORWARD_REF_TYPE;
1580
+ }
1581
+ function isFragment(object) {
1582
+ return typeOf(object) === REACT_FRAGMENT_TYPE;
1583
+ }
1584
+ function isLazy(object) {
1585
+ return typeOf(object) === REACT_LAZY_TYPE;
1586
+ }
1587
+ function isMemo(object) {
1588
+ return typeOf(object) === REACT_MEMO_TYPE;
1589
+ }
1590
+ function isPortal(object) {
1591
+ return typeOf(object) === REACT_PORTAL_TYPE;
1592
+ }
1593
+ function isProfiler(object) {
1594
+ return typeOf(object) === REACT_PROFILER_TYPE;
1595
+ }
1596
+ function isStrictMode(object) {
1597
+ return typeOf(object) === REACT_STRICT_MODE_TYPE;
1598
+ }
1599
+ function isSuspense(object) {
1600
+ return typeOf(object) === REACT_SUSPENSE_TYPE;
1601
+ }
1602
+ function isSuspenseList(object) {
1603
+ return typeOf(object) === REACT_SUSPENSE_LIST_TYPE;
1604
+ }
1605
+
1606
+ reactIs_development$1.ContextConsumer = ContextConsumer;
1607
+ reactIs_development$1.ContextProvider = ContextProvider;
1608
+ reactIs_development$1.Element = Element;
1609
+ reactIs_development$1.ForwardRef = ForwardRef;
1610
+ reactIs_development$1.Fragment = Fragment;
1611
+ reactIs_development$1.Lazy = Lazy;
1612
+ reactIs_development$1.Memo = Memo;
1613
+ reactIs_development$1.Portal = Portal;
1614
+ reactIs_development$1.Profiler = Profiler;
1615
+ reactIs_development$1.StrictMode = StrictMode;
1616
+ reactIs_development$1.Suspense = Suspense;
1617
+ reactIs_development$1.SuspenseList = SuspenseList;
1618
+ reactIs_development$1.isAsyncMode = isAsyncMode;
1619
+ reactIs_development$1.isConcurrentMode = isConcurrentMode;
1620
+ reactIs_development$1.isContextConsumer = isContextConsumer;
1621
+ reactIs_development$1.isContextProvider = isContextProvider;
1622
+ reactIs_development$1.isElement = isElement;
1623
+ reactIs_development$1.isForwardRef = isForwardRef;
1624
+ reactIs_development$1.isFragment = isFragment;
1625
+ reactIs_development$1.isLazy = isLazy;
1626
+ reactIs_development$1.isMemo = isMemo;
1627
+ reactIs_development$1.isPortal = isPortal;
1628
+ reactIs_development$1.isProfiler = isProfiler;
1629
+ reactIs_development$1.isStrictMode = isStrictMode;
1630
+ reactIs_development$1.isSuspense = isSuspense;
1631
+ reactIs_development$1.isSuspenseList = isSuspenseList;
1632
+ reactIs_development$1.isValidElementType = isValidElementType;
1633
+ reactIs_development$1.typeOf = typeOf;
1634
+ })();
1635
+ }
1636
+ return reactIs_development$1;
1637
+ }
1638
+
1639
+ var hasRequiredReactIs$1;
1640
+
1641
+ function requireReactIs$1 () {
1642
+ if (hasRequiredReactIs$1) return reactIs$1.exports;
1643
+ hasRequiredReactIs$1 = 1;
1644
+
1645
+ if (process.env.NODE_ENV === 'production') {
1646
+ reactIs$1.exports = requireReactIs_production_min$1();
1647
+ } else {
1648
+ reactIs$1.exports = requireReactIs_development$1();
1649
+ }
1650
+ return reactIs$1.exports;
1651
+ }
1652
+
1653
+ var reactIsExports = requireReactIs$1();
1654
+
1655
+ function useMemo(getValue, condition, shouldUpdate) {
1656
+ const cacheRef = React.useRef({});
1657
+ if (!('value' in cacheRef.current) || shouldUpdate(cacheRef.current.condition, condition)) {
1658
+ cacheRef.current.value = getValue();
1659
+ cacheRef.current.condition = condition;
1660
+ }
1661
+ return cacheRef.current.value;
1662
+ }
1663
+
1664
+ const REACT_ELEMENT_TYPE_18 = Symbol.for('react.element');
1665
+ const REACT_ELEMENT_TYPE_19 = Symbol.for('react.transitional.element');
1666
+ const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
1667
+
1668
+ /**
1669
+ * Compatible with React 18 or 19 to check if node is a Fragment.
1670
+ */
1671
+ function isFragment(object) {
1672
+ return (
1673
+ // Base object type
1674
+ object && typeof object === 'object' && (
1675
+ // React Element type
1676
+ object.$$typeof === REACT_ELEMENT_TYPE_18 || object.$$typeof === REACT_ELEMENT_TYPE_19) &&
1677
+ // React Fragment type
1678
+ object.type === REACT_FRAGMENT_TYPE
1679
+ );
1680
+ }
1681
+
1682
+ const ReactMajorVersion = Number(version.split('.')[0]);
1683
+ const fillRef = (ref, node) => {
1684
+ if (typeof ref === 'function') {
1685
+ ref(node);
1686
+ } else if (typeof ref === 'object' && ref && 'current' in ref) {
1687
+ ref.current = node;
1688
+ }
1689
+ };
1690
+
1691
+ /**
1692
+ * Merge refs into one ref function to support ref passing.
1693
+ */
1694
+ const composeRef = (...refs) => {
1695
+ const refList = refs.filter(Boolean);
1696
+ if (refList.length <= 1) {
1697
+ return refList[0];
1698
+ }
1699
+ return node => {
1700
+ refs.forEach(ref => {
1701
+ fillRef(ref, node);
1702
+ });
1703
+ };
1704
+ };
1705
+ const useComposeRef = (...refs) => {
1706
+ return useMemo(() => composeRef(...refs),
1707
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1708
+ refs, (prev, next) => prev.length !== next.length || prev.every((ref, i) => ref !== next[i]));
1709
+ };
1710
+ const supportRef = nodeOrComponent => {
1711
+ if (!nodeOrComponent) {
1712
+ return false;
1713
+ }
1714
+
1715
+ // React 19 no need `forwardRef` anymore. So just pass if is a React element.
1716
+ if (isReactElement(nodeOrComponent) && ReactMajorVersion >= 19) {
1717
+ return true;
1718
+ }
1719
+ const type = reactIsExports.isMemo(nodeOrComponent) ? nodeOrComponent.type.type : nodeOrComponent.type;
1720
+
1721
+ // Function component node
1722
+ if (typeof type === 'function' && !type.prototype?.render && type.$$typeof !== reactIsExports.ForwardRef) {
1723
+ return false;
1724
+ }
1725
+
1726
+ // Class component
1727
+ if (typeof nodeOrComponent === 'function' && !nodeOrComponent.prototype?.render && nodeOrComponent.$$typeof !== reactIsExports.ForwardRef) {
1728
+ return false;
1729
+ }
1730
+ return true;
1731
+ };
1732
+ function isReactElement(node) {
1733
+ return /*#__PURE__*/isValidElement(node) && !isFragment(node);
1734
+ }
1735
+
1736
+ /**
1737
+ * In React 19. `ref` is not a property from node.
1738
+ * But a property from `props.ref`.
1739
+ * To check if `props.ref` exist or fallback to `ref`.
1740
+ */
1741
+ const getNodeRef = node => {
1742
+ if (node && isReactElement(node)) {
1743
+ const ele = node;
1744
+
1745
+ // Source from:
1746
+ // https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/getReactNodeRef/getReactNodeRef.ts
1747
+ return ele.props.propertyIsEnumerable('ref') ? ele.props.ref : ele.ref;
1748
+ }
1749
+ return null;
1750
+ };
1751
+
1752
+ /* eslint-disable no-console */
1753
+ let warned = {};
1754
+ const preWarningFns = [];
1755
+
1756
+ /**
1757
+ * Pre warning enable you to parse content before console.error.
1758
+ * Modify to null will prevent warning.
1759
+ */
1760
+ const preMessage = fn => {
1761
+ preWarningFns.push(fn);
1762
+ };
1763
+
1764
+ /**
1765
+ * Warning if condition not match.
1766
+ * @param valid Condition
1767
+ * @param message Warning message
1768
+ * @example
1769
+ * ```js
1770
+ * warning(false, 'some error'); // print some error
1771
+ * warning(true, 'some error'); // print nothing
1772
+ * warning(1 === 2, 'some error'); // print some error
1773
+ * ```
1774
+ */
1775
+ function warning(valid, message) {
1776
+ if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
1777
+ const finalMessage = preWarningFns.reduce((msg, preMessageFn) => preMessageFn(msg ?? '', 'warning'), message);
1778
+ if (finalMessage) {
1779
+ console.error(`Warning: ${finalMessage}`);
1780
+ }
1781
+ }
1782
+ }
1783
+
1784
+ /** @see Similar to {@link warning} */
1785
+ function note(valid, message) {
1786
+ if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
1787
+ const finalMessage = preWarningFns.reduce((msg, preMessageFn) => preMessageFn(msg ?? '', 'note'), message);
1788
+ if (finalMessage) {
1789
+ console.warn(`Note: ${finalMessage}`);
1790
+ }
1791
+ }
1792
+ }
1793
+ function resetWarned() {
1794
+ warned = {};
1795
+ }
1796
+ function call(method, valid, message) {
1797
+ if (!valid && !warned[message]) {
1798
+ method(false, message);
1799
+ warned[message] = true;
1800
+ }
1801
+ }
1802
+
1803
+ /** @see Same as {@link warning}, but only warn once for the same message */
1804
+ function warningOnce(valid, message) {
1805
+ call(warning, valid, message);
1806
+ }
1807
+
1808
+ /** @see Same as {@link warning}, but only warn once for the same message */
1809
+ function noteOnce(valid, message) {
1810
+ call(note, valid, message);
1811
+ }
1812
+ warningOnce.preMessage = preMessage;
1813
+ warningOnce.resetWarned = resetWarned;
1814
+ warningOnce.noteOnce = noteOnce;
1815
+
1816
+ const OrderContext = /*#__PURE__*/React.createContext(null);
1817
+
1818
+ let inline = false;
1819
+ function inlineMock(nextInline) {
1820
+ return inline;
1821
+ }
1822
+
1823
+ /**
1824
+ * Wrap `React.useLayoutEffect` which will not throw warning message in test env
1825
+ */
1826
+ const useInternalLayoutEffect = process.env.NODE_ENV !== 'test' && canUseDom() ? React.useLayoutEffect : React.useEffect;
1827
+ const useLayoutEffect = (callback, deps) => {
1828
+ const firstMountRef = React.useRef(true);
1829
+ useInternalLayoutEffect(() => {
1830
+ return callback(firstMountRef.current);
1831
+ }, deps);
1832
+
1833
+ // We tell react that first mount has passed
1834
+ useInternalLayoutEffect(() => {
1835
+ firstMountRef.current = false;
1836
+ return () => {
1837
+ firstMountRef.current = true;
1838
+ };
1839
+ }, []);
1840
+ };
1841
+
1842
+ const EMPTY_LIST = [];
1843
+
1844
+ /**
1845
+ * Will add `div` to document. Nest call will keep order
1846
+ * @param render Render DOM in document
1847
+ */
1848
+ function useDom(render, debug) {
1849
+ const [ele] = React.useState(() => {
1850
+ if (!canUseDom()) {
1851
+ return null;
1852
+ }
1853
+ const defaultEle = document.createElement('div');
1854
+ if (process.env.NODE_ENV !== 'production' && debug) {
1855
+ defaultEle.setAttribute('data-debug', debug);
1856
+ }
1857
+ return defaultEle;
1858
+ });
1859
+
1860
+ // ========================== Order ==========================
1861
+ const appendedRef = React.useRef(false);
1862
+ const queueCreate = React.useContext(OrderContext);
1863
+ const [queue, setQueue] = React.useState(EMPTY_LIST);
1864
+ const mergedQueueCreate = queueCreate || (appendedRef.current ? undefined : appendFn => {
1865
+ setQueue(origin => {
1866
+ const newQueue = [appendFn, ...origin];
1867
+ return newQueue;
1868
+ });
1869
+ });
1870
+
1871
+ // =========================== DOM ===========================
1872
+ function append() {
1873
+ if (!ele.parentElement) {
1874
+ document.body.appendChild(ele);
1875
+ }
1876
+ appendedRef.current = true;
1877
+ }
1878
+ function cleanup() {
1879
+ ele.parentElement?.removeChild(ele);
1880
+ appendedRef.current = false;
1881
+ }
1882
+ useLayoutEffect(() => {
1883
+ if (render) {
1884
+ if (queueCreate) {
1885
+ queueCreate(append);
1886
+ } else {
1887
+ append();
1888
+ }
1889
+ } else {
1890
+ cleanup();
1891
+ }
1892
+ return cleanup;
1893
+ }, [render]);
1894
+ useLayoutEffect(() => {
1895
+ if (queue.length) {
1896
+ queue.forEach(appendFn => appendFn());
1897
+ setQueue(EMPTY_LIST);
1898
+ }
1899
+ }, [queue]);
1900
+ return [ele, mergedQueueCreate];
1901
+ }
1902
+
1903
+ function contains(root, n) {
1904
+ if (!root) {
1905
+ return false;
1906
+ }
1907
+
1908
+ // Use native if support
1909
+ if (root.contains) {
1910
+ return root.contains(n);
1911
+ }
1912
+
1913
+ // `document.contains` not support with IE11
1914
+ let node = n;
1915
+ while (node) {
1916
+ if (node === root) {
1917
+ return true;
1918
+ }
1919
+ node = node.parentNode;
1920
+ }
1921
+ return false;
1922
+ }
1923
+
1924
+ const APPEND_ORDER = 'data-rc-order';
1925
+ const APPEND_PRIORITY = 'data-rc-priority';
1926
+ const MARK_KEY = `rc-util-key`;
1927
+ const containerCache = new Map();
1928
+ function getMark({
1929
+ mark
1930
+ } = {}) {
1931
+ if (mark) {
1932
+ return mark.startsWith('data-') ? mark : `data-${mark}`;
1933
+ }
1934
+ return MARK_KEY;
1935
+ }
1936
+ function getContainer(option) {
1937
+ if (option.attachTo) {
1938
+ return option.attachTo;
1939
+ }
1940
+ const head = document.querySelector('head');
1941
+ return head || document.body;
1942
+ }
1943
+ function getOrder(prepend) {
1944
+ if (prepend === 'queue') {
1945
+ return 'prependQueue';
1946
+ }
1947
+ return prepend ? 'prepend' : 'append';
1948
+ }
1949
+
1950
+ /**
1951
+ * Find style which inject by rc-util
1952
+ */
1953
+ function findStyles(container) {
1954
+ return Array.from((containerCache.get(container) || container).children).filter(node => node.tagName === 'STYLE');
1955
+ }
1956
+ function injectCSS(css, option = {}) {
1957
+ if (!canUseDom()) {
1958
+ return null;
1959
+ }
1960
+ const {
1961
+ csp,
1962
+ prepend,
1963
+ priority = 0
1964
+ } = option;
1965
+ const mergedOrder = getOrder(prepend);
1966
+ const isPrependQueue = mergedOrder === 'prependQueue';
1967
+ const styleNode = document.createElement('style');
1968
+ styleNode.setAttribute(APPEND_ORDER, mergedOrder);
1969
+ if (isPrependQueue && priority) {
1970
+ styleNode.setAttribute(APPEND_PRIORITY, `${priority}`);
1971
+ }
1972
+ if (csp?.nonce) {
1973
+ styleNode.nonce = csp?.nonce;
1974
+ }
1975
+ styleNode.innerHTML = css;
1976
+ const container = getContainer(option);
1977
+ const {
1978
+ firstChild
1979
+ } = container;
1980
+ if (prepend) {
1981
+ // If is queue `prepend`, it will prepend first style and then append rest style
1982
+ if (isPrependQueue) {
1983
+ const existStyle = (option.styles || findStyles(container)).filter(node => {
1984
+ // Ignore style which not injected by rc-util with prepend
1985
+ if (!['prepend', 'prependQueue'].includes(node.getAttribute(APPEND_ORDER))) {
1986
+ return false;
1987
+ }
1988
+
1989
+ // Ignore style which priority less then new style
1990
+ const nodePriority = Number(node.getAttribute(APPEND_PRIORITY) || 0);
1991
+ return priority >= nodePriority;
1992
+ });
1993
+ if (existStyle.length) {
1994
+ container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling);
1995
+ return styleNode;
1996
+ }
1997
+ }
1998
+
1999
+ // Use `insertBefore` as `prepend`
2000
+ container.insertBefore(styleNode, firstChild);
2001
+ } else {
2002
+ container.appendChild(styleNode);
2003
+ }
2004
+ return styleNode;
2005
+ }
2006
+ function findExistNode(key, option = {}) {
2007
+ let {
2008
+ styles
2009
+ } = option;
2010
+ styles ||= findStyles(getContainer(option));
2011
+ return styles.find(node => node.getAttribute(getMark(option)) === key);
2012
+ }
2013
+ function removeCSS(key, option = {}) {
2014
+ const existNode = findExistNode(key, option);
2015
+ if (existNode) {
2016
+ const container = getContainer(option);
2017
+ container.removeChild(existNode);
2018
+ }
2019
+ }
2020
+
2021
+ /**
2022
+ * qiankun will inject `appendChild` to insert into other
2023
+ */
2024
+ function syncRealContainer(container, option) {
2025
+ const cachedRealContainer = containerCache.get(container);
2026
+
2027
+ // Find real container when not cached or cached container removed
2028
+ if (!cachedRealContainer || !contains(document, cachedRealContainer)) {
2029
+ const placeholderStyle = injectCSS('', option);
2030
+ const {
2031
+ parentNode
2032
+ } = placeholderStyle;
2033
+ containerCache.set(container, parentNode);
2034
+ container.removeChild(placeholderStyle);
2035
+ }
2036
+ }
2037
+ function updateCSS(css, key, originOption = {}) {
2038
+ const container = getContainer(originOption);
2039
+ const styles = findStyles(container);
2040
+ const option = {
2041
+ ...originOption,
2042
+ styles
2043
+ };
2044
+
2045
+ // Sync real parent
2046
+ syncRealContainer(container, option);
2047
+ const existNode = findExistNode(key, option);
2048
+ if (existNode) {
2049
+ if (option.csp?.nonce && existNode.nonce !== option.csp?.nonce) {
2050
+ existNode.nonce = option.csp?.nonce;
2051
+ }
2052
+ if (existNode.innerHTML !== css) {
2053
+ existNode.innerHTML = css;
2054
+ }
2055
+ return existNode;
2056
+ }
2057
+ const newNode = injectCSS(css, option);
2058
+ newNode.setAttribute(getMark(option), key);
2059
+ return newNode;
2060
+ }
2061
+
2062
+ /* eslint-disable no-param-reassign */
2063
+ function measureScrollbarSize(ele) {
2064
+ const randomId = `rc-scrollbar-measure-${Math.random().toString(36).substring(7)}`;
2065
+ const measureEle = document.createElement('div');
2066
+ measureEle.id = randomId;
2067
+
2068
+ // Create Style
2069
+ const measureStyle = measureEle.style;
2070
+ measureStyle.position = 'absolute';
2071
+ measureStyle.left = '0';
2072
+ measureStyle.top = '0';
2073
+ measureStyle.width = '100px';
2074
+ measureStyle.height = '100px';
2075
+ measureStyle.overflow = 'scroll';
2076
+
2077
+ // Clone Style if needed
2078
+ let fallbackWidth;
2079
+ let fallbackHeight;
2080
+ if (ele) {
2081
+ const targetStyle = getComputedStyle(ele);
2082
+ measureStyle.scrollbarColor = targetStyle.scrollbarColor;
2083
+ measureStyle.scrollbarWidth = targetStyle.scrollbarWidth;
2084
+
2085
+ // Set Webkit style
2086
+ const webkitScrollbarStyle = getComputedStyle(ele, '::-webkit-scrollbar');
2087
+ const width = parseInt(webkitScrollbarStyle.width, 10);
2088
+ const height = parseInt(webkitScrollbarStyle.height, 10);
2089
+
2090
+ // Try wrap to handle CSP case
2091
+ try {
2092
+ const widthStyle = width ? `width: ${webkitScrollbarStyle.width};` : '';
2093
+ const heightStyle = height ? `height: ${webkitScrollbarStyle.height};` : '';
2094
+ updateCSS(`
2095
+ #${randomId}::-webkit-scrollbar {
2096
+ ${widthStyle}
2097
+ ${heightStyle}
2098
+ }`, randomId);
2099
+ } catch (e) {
2100
+ // Can't wrap, just log error
2101
+ console.error(e);
2102
+
2103
+ // Get from style directly
2104
+ fallbackWidth = width;
2105
+ fallbackHeight = height;
2106
+ }
2107
+ }
2108
+ document.body.appendChild(measureEle);
2109
+
2110
+ // Measure. Get fallback style if provided
2111
+ const scrollWidth = ele && fallbackWidth && !Number.isNaN(fallbackWidth) ? fallbackWidth : measureEle.offsetWidth - measureEle.clientWidth;
2112
+ const scrollHeight = ele && fallbackHeight && !Number.isNaN(fallbackHeight) ? fallbackHeight : measureEle.offsetHeight - measureEle.clientHeight;
2113
+
2114
+ // Clean up
2115
+ document.body.removeChild(measureEle);
2116
+ removeCSS(randomId);
2117
+ return {
2118
+ width: scrollWidth,
2119
+ height: scrollHeight
2120
+ };
2121
+ }
2122
+ function getTargetScrollBarSize(target) {
2123
+ if (typeof document === 'undefined' || !target || !(target instanceof Element)) {
2124
+ return {
2125
+ width: 0,
2126
+ height: 0
2127
+ };
2128
+ }
2129
+ return measureScrollbarSize(target);
2130
+ }
2131
+
2132
+ /**
2133
+ * Test usage export. Do not use in your production
2134
+ */
2135
+ function isBodyOverflowing() {
2136
+ return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) && window.innerWidth > document.body.offsetWidth;
2137
+ }
2138
+
2139
+ const UNIQUE_ID = `rc-util-locker-${Date.now()}`;
2140
+ let uuid$1 = 0;
2141
+ function useScrollLocker(lock) {
2142
+ const mergedLock = !!lock;
2143
+ const [id] = React.useState(() => {
2144
+ uuid$1 += 1;
2145
+ return `${UNIQUE_ID}_${uuid$1}`;
2146
+ });
2147
+ useLayoutEffect(() => {
2148
+ if (mergedLock) {
2149
+ const scrollbarSize = getTargetScrollBarSize(document.body).width;
2150
+ const isOverflow = isBodyOverflowing();
2151
+ updateCSS(`
2152
+ html body {
2153
+ overflow-y: hidden;
2154
+ ${isOverflow ? `width: calc(100% - ${scrollbarSize}px);` : ''}
2155
+ }`, id);
2156
+ } else {
2157
+ removeCSS(id);
2158
+ }
2159
+ return () => {
2160
+ removeCSS(id);
2161
+ };
2162
+ }, [mergedLock, id]);
2163
+ }
2164
+
2165
+ const useEvent = callback => {
2166
+ const fnRef = React.useRef(callback);
2167
+ fnRef.current = callback;
2168
+ const memoFn = React.useCallback((...args) => fnRef.current?.(...args), []);
2169
+ return memoFn;
2170
+ };
2171
+
2172
+ /**
2173
+ * Same as React.useState but `setState` accept `ignoreDestroy` param to not to setState after destroyed.
2174
+ * We do not make this auto is to avoid real memory leak.
2175
+ * Developer should confirm it's safe to ignore themselves.
2176
+ */
2177
+ const useSafeState = defaultValue => {
2178
+ const destroyRef = React.useRef(false);
2179
+ const [value, setValue] = React.useState(defaultValue);
2180
+ React.useEffect(() => {
2181
+ destroyRef.current = false;
2182
+ return () => {
2183
+ destroyRef.current = true;
2184
+ };
2185
+ }, []);
2186
+ function safeSetState(updater, ignoreDestroy) {
2187
+ if (ignoreDestroy && destroyRef.current) {
2188
+ return;
2189
+ }
2190
+ setValue(updater);
2191
+ }
2192
+ return [value, safeSetState];
2193
+ };
2194
+
2195
+ /**
2196
+ * Similar to `useState` but will use props value if provided.
2197
+ * From React 18, we do not need safe `useState` since it will not throw for unmounted update.
2198
+ * This hooks remove the `onChange` & `postState` logic since we only need basic merged state logic.
2199
+ */
2200
+ function useControlledState(defaultStateValue, value) {
2201
+ const [innerValue, setInnerValue] = useState(defaultStateValue);
2202
+ const mergedValue = value !== undefined ? value : innerValue;
2203
+ useLayoutEffect(mount => {
2204
+ if (!mount) {
2205
+ setInnerValue(value);
2206
+ }
2207
+ }, [value]);
2208
+ return [
2209
+ // Value
2210
+ mergedValue,
2211
+ // Update function
2212
+ setInnerValue];
2213
+ }
2214
+
2215
+ function toArray$1(children, option = {}) {
2216
+ let ret = [];
2217
+ React__default.Children.forEach(children, child => {
2218
+ if ((child === undefined || child === null) && !option.keepEmpty) {
2219
+ return;
2220
+ }
2221
+ if (Array.isArray(child)) {
2222
+ ret = ret.concat(toArray$1(child));
2223
+ } else if (isFragment(child) && child.props) {
2224
+ ret = ret.concat(toArray$1(child.props.children, option));
2225
+ } else {
2226
+ ret.push(child);
2227
+ }
2228
+ });
2229
+ return ret;
2230
+ }
2231
+
2232
+ function getUseId() {
2233
+ // We need fully clone React function here to avoid webpack warning React 17 do not export `useId`
2234
+ const fullClone = {
2235
+ ...React
2236
+ };
2237
+ return fullClone.useId;
2238
+ }
2239
+ let uuid = 0;
2240
+ const useOriginId = getUseId();
2241
+ var useId = useOriginId ?
2242
+ // Use React `useId`
2243
+ function useId(id) {
2244
+ const reactId = useOriginId();
2245
+
2246
+ // Developer passed id is single source of truth
2247
+ if (id) {
2248
+ return id;
2249
+ }
2250
+
2251
+ // Test env always return mock id
2252
+ if (process.env.NODE_ENV === 'test') {
2253
+ return 'test-id';
2254
+ }
2255
+ return reactId;
2256
+ } :
2257
+ // Use compatible of `useId`
2258
+ function useCompatId(id) {
2259
+ // Inner id for accessibility usage. Only work in client side
2260
+ const [innerId, setInnerId] = React.useState('ssr-id');
2261
+ React.useEffect(() => {
2262
+ const nextId = uuid;
2263
+ uuid += 1;
2264
+ setInnerId(`rc_unique_${nextId}`);
2265
+ }, []);
2266
+
2267
+ // Developer passed id is single source of truth
2268
+ if (id) {
2269
+ return id;
2270
+ }
2271
+
2272
+ // Test env always return mock id
2273
+ if (process.env.NODE_ENV === 'test') {
2274
+ return 'test-id';
2275
+ }
2276
+
2277
+ // Return react native id or inner id
2278
+ return innerId;
2279
+ };
2280
+
2281
+ let stack = [];
2282
+ const IME_LOCK_DURATION = 200;
2283
+ let lastCompositionEndTime = 0;
2284
+
2285
+ // Export for testing
2286
+ process.env.NODE_ENV === 'test' ? () => ({
2287
+ stack,
2288
+ reset: () => {
2289
+ // Not reset stack to ensure effect will clean up correctly
2290
+ lastCompositionEndTime = 0;
2291
+ }
2292
+ }) : null;
2293
+
2294
+ // Global event handlers
2295
+ const onGlobalKeyDown = event => {
2296
+ if (event.key === 'Escape' && !event.isComposing) {
2297
+ const now = Date.now();
2298
+ if (now - lastCompositionEndTime < IME_LOCK_DURATION) {
2299
+ return;
2300
+ }
2301
+ const len = stack.length;
2302
+ for (let i = len - 1; i >= 0; i -= 1) {
2303
+ stack[i].onEsc({
2304
+ top: i === len - 1,
2305
+ event
2306
+ });
2307
+ }
2308
+ }
2309
+ };
2310
+ const onGlobalCompositionEnd = () => {
2311
+ lastCompositionEndTime = Date.now();
2312
+ };
2313
+ function attachGlobalEventListeners() {
2314
+ window.addEventListener('keydown', onGlobalKeyDown);
2315
+ window.addEventListener('compositionend', onGlobalCompositionEnd);
2316
+ }
2317
+ function detachGlobalEventListeners() {
2318
+ if (stack.length === 0) {
2319
+ window.removeEventListener('keydown', onGlobalKeyDown);
2320
+ window.removeEventListener('compositionend', onGlobalCompositionEnd);
2321
+ }
2322
+ }
2323
+ function useEscKeyDown(open, onEsc) {
2324
+ const id = useId();
2325
+ const onEventEsc = useEvent(onEsc);
2326
+ const ensure = () => {
2327
+ if (!stack.find(item => item.id === id)) {
2328
+ stack.push({
2329
+ id,
2330
+ onEsc: onEventEsc
2331
+ });
2332
+ }
2333
+ };
2334
+ const clear = () => {
2335
+ stack = stack.filter(item => item.id !== id);
2336
+ };
2337
+ useMemo$1(() => {
2338
+ if (open) {
2339
+ ensure();
2340
+ } else if (!open) {
2341
+ clear();
2342
+ }
2343
+ }, [open]);
2344
+ useEffect(() => {
2345
+ if (open) {
2346
+ ensure();
2347
+ // Attach global event listeners
2348
+ attachGlobalEventListeners();
2349
+ return () => {
2350
+ clear();
2351
+ // Remove global event listeners if instances is empty
2352
+ detachGlobalEventListeners();
2353
+ };
2354
+ }
2355
+ }, [open]);
2356
+ }
2357
+
2358
+ const getPortalContainer = getContainer => {
2359
+ if (getContainer === false) {
2360
+ return false;
2361
+ }
2362
+ if (!canUseDom() || !getContainer) {
2363
+ return null;
2364
+ }
2365
+ if (typeof getContainer === 'string') {
2366
+ return document.querySelector(getContainer);
2367
+ }
2368
+ if (typeof getContainer === 'function') {
2369
+ return getContainer();
2370
+ }
2371
+ return getContainer;
2372
+ };
2373
+ const Portal = /*#__PURE__*/React.forwardRef((props, ref) => {
2374
+ const {
2375
+ open,
2376
+ autoLock,
2377
+ getContainer,
2378
+ debug,
2379
+ autoDestroy = true,
2380
+ children,
2381
+ onEsc
2382
+ } = props;
2383
+ const [shouldRender, setShouldRender] = React.useState(open);
2384
+ const mergedRender = shouldRender || open;
2385
+
2386
+ // ========================= Warning =========================
2387
+ if (process.env.NODE_ENV !== 'production') {
2388
+ warningOnce(canUseDom() || !open, `Portal only work in client side. Please call 'useEffect' to show Portal instead default render in SSR.`);
2389
+ }
2390
+
2391
+ // ====================== Should Render ======================
2392
+ React.useEffect(() => {
2393
+ if (autoDestroy || open) {
2394
+ setShouldRender(open);
2395
+ }
2396
+ }, [open, autoDestroy]);
2397
+
2398
+ // ======================== Container ========================
2399
+ const [innerContainer, setInnerContainer] = React.useState(() => getPortalContainer(getContainer));
2400
+ React.useEffect(() => {
2401
+ const customizeContainer = getPortalContainer(getContainer);
2402
+
2403
+ // Tell component that we check this in effect which is safe to be `null`
2404
+ setInnerContainer(() =>
2405
+ // React do the state update even the value is the same,
2406
+ // Use function call to force React to compare update
2407
+ customizeContainer ?? null);
2408
+ });
2409
+ const [defaultContainer, queueCreate] = useDom(mergedRender && !innerContainer, debug);
2410
+ const mergedContainer = innerContainer ?? defaultContainer;
2411
+
2412
+ // ========================= Locker ==========================
2413
+ useScrollLocker(autoLock && open && canUseDom() && (mergedContainer === defaultContainer || mergedContainer === document.body));
2414
+
2415
+ // ========================= Esc Keydown ==========================
2416
+ useEscKeyDown(open, onEsc);
2417
+
2418
+ // =========================== Ref ===========================
2419
+ let childRef = null;
2420
+ if (children && supportRef(children) && ref) {
2421
+ childRef = getNodeRef(children);
2422
+ }
2423
+ const mergedRef = useComposeRef(childRef, ref);
2424
+
2425
+ // ========================= Render ==========================
2426
+ // Do not render when nothing need render
2427
+ // When innerContainer is `undefined`, it may not ready since user use ref in the same render
2428
+ if (!mergedRender || !canUseDom() || innerContainer === undefined) {
2429
+ return null;
2430
+ }
2431
+
2432
+ // Render inline
2433
+ const renderInline = mergedContainer === false || inlineMock();
2434
+ let reffedChildren = children;
2435
+ if (ref) {
2436
+ reffedChildren = /*#__PURE__*/React.cloneElement(children, {
2437
+ ref: mergedRef
2438
+ });
2439
+ }
2440
+ return /*#__PURE__*/React.createElement(OrderContext.Provider, {
2441
+ value: queueCreate
2442
+ }, renderInline ? reffedChildren : /*#__PURE__*/createPortal(reffedChildren, mergedContainer));
2443
+ });
2444
+ if (process.env.NODE_ENV !== 'production') {
2445
+ Portal.displayName = 'Portal';
2446
+ }
2447
+
2448
+ function isDOM(node) {
2449
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element
2450
+ // Since XULElement is also subclass of Element, we only need HTMLElement and SVGElement
2451
+ return node instanceof HTMLElement || node instanceof SVGElement;
2452
+ }
2453
+
2454
+ /**
2455
+ * Retrieves a DOM node via a ref, and does not invoke `findDOMNode`.
2456
+ */
2457
+ function getDOM(node) {
2458
+ if (node && typeof node === 'object' && isDOM(node.nativeElement)) {
2459
+ return node.nativeElement;
2460
+ }
2461
+ if (isDOM(node)) {
2462
+ return node;
2463
+ }
2464
+ return null;
2465
+ }
2466
+
2467
+ const CollectionContext = /*#__PURE__*/React.createContext(null);
2468
+ /**
2469
+ * Collect all the resize event from children ResizeObserver
2470
+ */
2471
+ function Collection({
2472
+ children,
2473
+ onBatchResize
2474
+ }) {
2475
+ const resizeIdRef = React.useRef(0);
2476
+ const resizeInfosRef = React.useRef([]);
2477
+ const onCollectionResize = React.useContext(CollectionContext);
2478
+ const onResize = React.useCallback((size, element, data) => {
2479
+ resizeIdRef.current += 1;
2480
+ const currentId = resizeIdRef.current;
2481
+ resizeInfosRef.current.push({
2482
+ size,
2483
+ element,
2484
+ data
2485
+ });
2486
+ Promise.resolve().then(() => {
2487
+ if (currentId === resizeIdRef.current) {
2488
+ onBatchResize?.(resizeInfosRef.current);
2489
+ resizeInfosRef.current = [];
2490
+ }
2491
+ });
2492
+
2493
+ // Continue bubbling if parent exist
2494
+ onCollectionResize?.(size, element, data);
2495
+ }, [onBatchResize, onCollectionResize]);
2496
+ return /*#__PURE__*/React.createElement(CollectionContext.Provider, {
2497
+ value: onResize
2498
+ }, children);
2499
+ }
2500
+
2501
+ // =============================== Const ===============================
2502
+ const elementListeners = new Map();
2503
+ function onResize(entities) {
2504
+ entities.forEach(entity => {
2505
+ const {
2506
+ target
2507
+ } = entity;
2508
+ elementListeners.get(target)?.forEach(listener => listener(target));
2509
+ });
2510
+ }
2511
+
2512
+ // Delay create ResizeObserver since it's not supported in server side
2513
+ let observer;
2514
+ function ensureResizeObserver() {
2515
+ if (!observer) {
2516
+ observer = new ResizeObserver(onResize);
2517
+ }
2518
+ return observer;
2519
+ }
2520
+
2521
+ // Dev env only
2522
+ process.env.NODE_ENV !== 'production' ? elementListeners : null; // eslint-disable-line
2523
+ process.env.NODE_ENV !== 'production' ? onResize : null; // eslint-disable-line
2524
+
2525
+ // ============================== Observe ==============================
2526
+ function observe(element, callback) {
2527
+ if (!elementListeners.has(element)) {
2528
+ elementListeners.set(element, new Set());
2529
+ ensureResizeObserver().observe(element);
2530
+ }
2531
+ elementListeners.get(element).add(callback);
2532
+ }
2533
+ function unobserve(element, callback) {
2534
+ if (elementListeners.has(element)) {
2535
+ elementListeners.get(element).delete(callback);
2536
+ if (!elementListeners.get(element).size) {
2537
+ ensureResizeObserver().unobserve(element);
2538
+ elementListeners.delete(element);
2539
+ }
2540
+ }
2541
+ }
2542
+
2543
+ function useResizeObserver(enabled, getTarget, onDelayResize, onSyncResize) {
2544
+ // ============================= Size =============================
2545
+ const sizeRef = React.useRef({
2546
+ width: -1,
2547
+ height: -1,
2548
+ offsetWidth: -1,
2549
+ offsetHeight: -1
2550
+ });
2551
+
2552
+ // =========================== Observe ============================
2553
+
2554
+ // Handler
2555
+ const onInternalResize = useEvent(target => {
2556
+ const {
2557
+ width,
2558
+ height
2559
+ } = target.getBoundingClientRect();
2560
+ const {
2561
+ offsetWidth,
2562
+ offsetHeight
2563
+ } = target;
2564
+
2565
+ /**
2566
+ * Resize observer trigger when content size changed.
2567
+ * In most case we just care about element size,
2568
+ * let's use `boundary` instead of `contentRect` here to avoid shaking.
2569
+ */
2570
+ const fixedWidth = Math.floor(width);
2571
+ const fixedHeight = Math.floor(height);
2572
+ if (sizeRef.current.width !== fixedWidth || sizeRef.current.height !== fixedHeight || sizeRef.current.offsetWidth !== offsetWidth || sizeRef.current.offsetHeight !== offsetHeight) {
2573
+ const size = {
2574
+ width: fixedWidth,
2575
+ height: fixedHeight,
2576
+ offsetWidth,
2577
+ offsetHeight
2578
+ };
2579
+ sizeRef.current = size;
2580
+
2581
+ // IE is strange, right?
2582
+ const mergedOffsetWidth = offsetWidth === Math.round(width) ? width : offsetWidth;
2583
+ const mergedOffsetHeight = offsetHeight === Math.round(height) ? height : offsetHeight;
2584
+ const sizeInfo = {
2585
+ ...size,
2586
+ offsetWidth: mergedOffsetWidth,
2587
+ offsetHeight: mergedOffsetHeight
2588
+ };
2589
+
2590
+ // Call the callback immediately, let the caller decide whether to defer
2591
+ // onResize(sizeInfo, target);
2592
+ onSyncResize?.(sizeInfo, target);
2593
+
2594
+ // defer the callback but not defer to next frame
2595
+ Promise.resolve().then(() => {
2596
+ onDelayResize?.(sizeInfo, target);
2597
+ });
2598
+ }
2599
+ });
2600
+
2601
+ // Dynamic observe
2602
+ const isFuncTarget = typeof getTarget === 'function';
2603
+ React.useEffect(() => {
2604
+ const target = isFuncTarget ? getTarget() : getTarget;
2605
+ if (target && enabled) {
2606
+ observe(target, onInternalResize);
2607
+ }
2608
+ return () => {
2609
+ if (target) {
2610
+ unobserve(target, onInternalResize);
2611
+ }
2612
+ };
2613
+ }, [enabled,
2614
+ // When is function, no need to watch it
2615
+ isFuncTarget ? 0 : getTarget]);
2616
+ }
2617
+
2618
+ function SingleObserver(props, ref) {
2619
+ const {
2620
+ children,
2621
+ disabled,
2622
+ onResize,
2623
+ data
2624
+ } = props;
2625
+ const elementRef = React.useRef(null);
2626
+ const onCollectionResize = React.useContext(CollectionContext);
2627
+
2628
+ // =========================== Children ===========================
2629
+ const isRenderProps = typeof children === 'function';
2630
+ const mergedChildren = isRenderProps ? children(elementRef) : children;
2631
+
2632
+ // ============================= Ref ==============================
2633
+ const canRef = !isRenderProps && /*#__PURE__*/React.isValidElement(mergedChildren) && supportRef(mergedChildren);
2634
+ const originRef = canRef ? getNodeRef(mergedChildren) : null;
2635
+ const mergedRef = useComposeRef(originRef, elementRef);
2636
+ const getDomElement = () => {
2637
+ return getDOM(elementRef.current);
2638
+ };
2639
+ React.useImperativeHandle(ref, () => getDomElement());
2640
+
2641
+ // =========================== Observe ============================
2642
+ useResizeObserver(!disabled, getDomElement, onResize, (sizeInfo, target) => {
2643
+ onCollectionResize?.(sizeInfo, target, data);
2644
+ });
2645
+
2646
+ // ============================ Render ============================
2647
+ return canRef ? /*#__PURE__*/React.cloneElement(mergedChildren, {
2648
+ ref: mergedRef
2649
+ }) : mergedChildren;
2650
+ }
2651
+ const RefSingleObserver = /*#__PURE__*/React.forwardRef(SingleObserver);
2652
+ if (process.env.NODE_ENV !== 'production') {
2653
+ RefSingleObserver.displayName = 'SingleObserver';
2654
+ }
2655
+
2656
+ function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
2657
+ const INTERNAL_PREFIX_KEY = 'rc-observer-key';
2658
+ function ResizeObserver$1(props, ref) {
2659
+ const {
2660
+ children
2661
+ } = props;
2662
+ const childNodes = typeof children === 'function' ? [children] : toArray$1(children);
2663
+ if (process.env.NODE_ENV !== 'production') {
2664
+ if (childNodes.length > 1) {
2665
+ warning(false, 'Find more than one child node with `children` in ResizeObserver. Please use ResizeObserver.Collection instead.');
2666
+ } else if (childNodes.length === 0) {
2667
+ warning(false, '`children` of ResizeObserver is empty. Nothing is in observe.');
2668
+ }
2669
+ }
2670
+ return childNodes.map((child, index) => {
2671
+ const key = child?.key || `${INTERNAL_PREFIX_KEY}-${index}`;
2672
+ return /*#__PURE__*/React.createElement(RefSingleObserver, _extends$2({}, props, {
2673
+ key: key,
2674
+ ref: index === 0 ? ref : undefined
2675
+ }), child);
2676
+ });
2677
+ }
2678
+ const RefResizeObserver = /*#__PURE__*/React.forwardRef(ResizeObserver$1);
2679
+ if (process.env.NODE_ENV !== 'production') {
2680
+ RefResizeObserver.displayName = 'ResizeObserver';
2681
+ }
2682
+ RefResizeObserver.Collection = Collection;
2683
+
2684
+ function getRoot(ele) {
2685
+ return ele?.getRootNode?.();
2686
+ }
2687
+
2688
+ /**
2689
+ * Check if is in shadowRoot
2690
+ */
2691
+ function inShadow(ele) {
2692
+ return getRoot(ele) instanceof ShadowRoot;
2693
+ }
2694
+
2695
+ /**
2696
+ * Return shadowRoot if possible
2697
+ */
2698
+ function getShadowRoot(ele) {
2699
+ return inShadow(ele) ? getRoot(ele) : null;
2700
+ }
2701
+
2702
+ const Context$1 = /*#__PURE__*/React.createContext({});
2703
+
2704
+ /**
2705
+ * Same as React.useState but will always get latest state.
2706
+ * This is useful when React merge multiple state updates into one.
2707
+ * e.g. onTransitionEnd trigger multiple event at once will be merged state update in React.
2708
+ */
2709
+ function useSyncState(defaultValue) {
2710
+ const [, forceUpdate] = React.useReducer(x => x + 1, 0);
2711
+ const currentValueRef = React.useRef(defaultValue);
2712
+ const getValue = useEvent(() => {
2713
+ return currentValueRef.current;
2714
+ });
2715
+ const setValue = useEvent(updater => {
2716
+ currentValueRef.current = typeof updater === 'function' ? updater(currentValueRef.current) : updater;
2717
+ forceUpdate();
2718
+ });
2719
+ return [getValue, setValue];
2720
+ }
2721
+
2722
+ const STATUS_NONE = 'none';
2723
+ const STATUS_APPEAR = 'appear';
2724
+ const STATUS_ENTER = 'enter';
2725
+ const STATUS_LEAVE = 'leave';
2726
+ const STEP_NONE = 'none';
2727
+ const STEP_PREPARE = 'prepare';
2728
+ const STEP_START = 'start';
2729
+ const STEP_ACTIVE = 'active';
2730
+ const STEP_ACTIVATED = 'end';
2731
+ /**
2732
+ * Used for disabled motion case.
2733
+ * Prepare stage will still work but start & active will be skipped.
2734
+ */
2735
+ const STEP_PREPARED = 'prepared';
2736
+
2737
+ // ================= Transition =================
2738
+ // Event wrapper. Copy from react source code
2739
+ function makePrefixMap(styleProp, eventName) {
2740
+ const prefixes = {};
2741
+ prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
2742
+ prefixes[`Webkit${styleProp}`] = `webkit${eventName}`;
2743
+ prefixes[`Moz${styleProp}`] = `moz${eventName}`;
2744
+ prefixes[`ms${styleProp}`] = `MS${eventName}`;
2745
+ prefixes[`O${styleProp}`] = `o${eventName.toLowerCase()}`;
2746
+ return prefixes;
2747
+ }
2748
+ function getVendorPrefixes(domSupport, win) {
2749
+ const prefixes = {
2750
+ animationend: makePrefixMap('Animation', 'AnimationEnd'),
2751
+ transitionend: makePrefixMap('Transition', 'TransitionEnd')
2752
+ };
2753
+ if (domSupport) {
2754
+ if (!('AnimationEvent' in win)) {
2755
+ delete prefixes.animationend.animation;
2756
+ }
2757
+ if (!('TransitionEvent' in win)) {
2758
+ delete prefixes.transitionend.transition;
2759
+ }
2760
+ }
2761
+ return prefixes;
2762
+ }
2763
+ const vendorPrefixes = getVendorPrefixes(canUseDom(), typeof window !== 'undefined' ? window : {});
2764
+ let style = {};
2765
+ if (canUseDom()) {
2766
+ ({
2767
+ style
2768
+ } = document.createElement('div'));
2769
+ }
2770
+ const prefixedEventNames = {};
2771
+ function getVendorPrefixedEventName(eventName) {
2772
+ if (prefixedEventNames[eventName]) {
2773
+ return prefixedEventNames[eventName];
2774
+ }
2775
+ const prefixMap = vendorPrefixes[eventName];
2776
+ if (prefixMap) {
2777
+ const stylePropList = Object.keys(prefixMap);
2778
+ const len = stylePropList.length;
2779
+ for (let i = 0; i < len; i += 1) {
2780
+ const styleProp = stylePropList[i];
2781
+ if (Object.prototype.hasOwnProperty.call(prefixMap, styleProp) && styleProp in style) {
2782
+ prefixedEventNames[eventName] = prefixMap[styleProp];
2783
+ return prefixedEventNames[eventName];
2784
+ }
2785
+ }
2786
+ }
2787
+ return '';
2788
+ }
2789
+ const internalAnimationEndName = getVendorPrefixedEventName('animationend');
2790
+ const internalTransitionEndName = getVendorPrefixedEventName('transitionend');
2791
+ const supportTransition = !!(internalAnimationEndName && internalTransitionEndName);
2792
+ const animationEndName = internalAnimationEndName || 'animationend';
2793
+ const transitionEndName = internalTransitionEndName || 'transitionend';
2794
+ function getTransitionName(transitionName, transitionType) {
2795
+ if (!transitionName) return null;
2796
+ if (typeof transitionName === 'object') {
2797
+ const type = transitionType.replace(/-\w/g, match => match[1].toUpperCase());
2798
+ return transitionName[type];
2799
+ }
2800
+ return `${transitionName}-${transitionType}`;
2801
+ }
2802
+
2803
+ var useDomMotionEvents = (onInternalMotionEnd => {
2804
+ const cacheElementRef = useRef();
2805
+
2806
+ // Remove events
2807
+ function removeMotionEvents(element) {
2808
+ if (element) {
2809
+ element.removeEventListener(transitionEndName, onInternalMotionEnd);
2810
+ element.removeEventListener(animationEndName, onInternalMotionEnd);
2811
+ }
2812
+ }
2813
+
2814
+ // Patch events
2815
+ function patchMotionEvents(element) {
2816
+ if (cacheElementRef.current && cacheElementRef.current !== element) {
2817
+ removeMotionEvents(cacheElementRef.current);
2818
+ }
2819
+ if (element && element !== cacheElementRef.current) {
2820
+ element.addEventListener(transitionEndName, onInternalMotionEnd);
2821
+ element.addEventListener(animationEndName, onInternalMotionEnd);
2822
+
2823
+ // Save as cache in case dom removed trigger by `motionDeadline`
2824
+ cacheElementRef.current = element;
2825
+ }
2826
+ }
2827
+
2828
+ // Clean up when removed
2829
+ React.useEffect(() => () => {
2830
+ removeMotionEvents(cacheElementRef.current);
2831
+ cacheElementRef.current = null;
2832
+ }, []);
2833
+ return [patchMotionEvents, removeMotionEvents];
2834
+ });
2835
+
2836
+ // It's safe to use `useLayoutEffect` but the warning is annoying
2837
+ const useIsomorphicLayoutEffect = canUseDom() ? useLayoutEffect$1 : useEffect;
2838
+
2839
+ let raf = callback => +setTimeout(callback, 16);
2840
+ let caf = num => clearTimeout(num);
2841
+ if (typeof window !== 'undefined' && 'requestAnimationFrame' in window) {
2842
+ raf = callback => window.requestAnimationFrame(callback);
2843
+ caf = handle => window.cancelAnimationFrame(handle);
2844
+ }
2845
+ let rafUUID = 0;
2846
+ const rafIds = new Map();
2847
+ function cleanup(id) {
2848
+ rafIds.delete(id);
2849
+ }
2850
+ const wrapperRaf = (callback, times = 1) => {
2851
+ rafUUID += 1;
2852
+ const id = rafUUID;
2853
+ function callRef(leftTimes) {
2854
+ if (leftTimes === 0) {
2855
+ // Clean up
2856
+ cleanup(id);
2857
+
2858
+ // Trigger
2859
+ callback();
2860
+ } else {
2861
+ // Next raf
2862
+ const realId = raf(() => {
2863
+ callRef(leftTimes - 1);
2864
+ });
2865
+
2866
+ // Bind real raf id
2867
+ rafIds.set(id, realId);
2868
+ }
2869
+ }
2870
+ callRef(times);
2871
+ return id;
2872
+ };
2873
+ wrapperRaf.cancel = id => {
2874
+ const realId = rafIds.get(id);
2875
+ cleanup(id);
2876
+ return caf(realId);
2877
+ };
2878
+ if (process.env.NODE_ENV !== 'production') {
2879
+ wrapperRaf.ids = () => rafIds;
2880
+ }
2881
+
2882
+ var useNextFrame = (() => {
2883
+ const nextFrameRef = React.useRef(null);
2884
+ function cancelNextFrame() {
2885
+ wrapperRaf.cancel(nextFrameRef.current);
2886
+ }
2887
+ function nextFrame(callback, delay = 2) {
2888
+ cancelNextFrame();
2889
+ const nextFrameId = wrapperRaf(() => {
2890
+ if (delay <= 1) {
2891
+ callback({
2892
+ isCanceled: () => nextFrameId !== nextFrameRef.current
2893
+ });
2894
+ } else {
2895
+ nextFrame(callback, delay - 1);
2896
+ }
2897
+ });
2898
+ nextFrameRef.current = nextFrameId;
2899
+ }
2900
+ React.useEffect(() => () => {
2901
+ cancelNextFrame();
2902
+ }, []);
2903
+ return [nextFrame, cancelNextFrame];
2904
+ });
2905
+
2906
+ const FULL_STEP_QUEUE = [STEP_PREPARE, STEP_START, STEP_ACTIVE, STEP_ACTIVATED];
2907
+ const SIMPLE_STEP_QUEUE = [STEP_PREPARE, STEP_PREPARED];
2908
+
2909
+ /** Skip current step */
2910
+ const SkipStep = false;
2911
+ /** Current step should be update in */
2912
+ const DoStep = true;
2913
+ function isActive(step) {
2914
+ return step === STEP_ACTIVE || step === STEP_ACTIVATED;
2915
+ }
2916
+ var useStepQueue = ((status, prepareOnly, callback) => {
2917
+ const [step, setStep] = useSafeState(STEP_NONE);
2918
+ const [nextFrame, cancelNextFrame] = useNextFrame();
2919
+ function startQueue() {
2920
+ setStep(STEP_PREPARE, true);
2921
+ }
2922
+ const STEP_QUEUE = prepareOnly ? SIMPLE_STEP_QUEUE : FULL_STEP_QUEUE;
2923
+ useIsomorphicLayoutEffect(() => {
2924
+ if (step !== STEP_NONE && step !== STEP_ACTIVATED) {
2925
+ const index = STEP_QUEUE.indexOf(step);
2926
+ const nextStep = STEP_QUEUE[index + 1];
2927
+ const result = callback(step);
2928
+ if (result === SkipStep) {
2929
+ // Skip when no needed
2930
+ setStep(nextStep, true);
2931
+ } else if (nextStep) {
2932
+ // Do as frame for step update
2933
+ nextFrame(info => {
2934
+ function doNext() {
2935
+ // Skip since current queue is ood
2936
+ if (info.isCanceled()) return;
2937
+ setStep(nextStep, true);
2938
+ }
2939
+ if (result === true) {
2940
+ doNext();
2941
+ } else {
2942
+ // Only promise should be async
2943
+ Promise.resolve(result).then(doNext);
2944
+ }
2945
+ });
2946
+ }
2947
+ }
2948
+ }, [status, step]);
2949
+ React.useEffect(() => () => {
2950
+ cancelNextFrame();
2951
+ }, []);
2952
+ return [startQueue, step];
2953
+ });
2954
+
2955
+ function useStatus(supportMotion, visible, getElement, {
2956
+ motionEnter = true,
2957
+ motionAppear = true,
2958
+ motionLeave = true,
2959
+ motionDeadline,
2960
+ motionLeaveImmediately,
2961
+ onAppearPrepare,
2962
+ onEnterPrepare,
2963
+ onLeavePrepare,
2964
+ onAppearStart,
2965
+ onEnterStart,
2966
+ onLeaveStart,
2967
+ onAppearActive,
2968
+ onEnterActive,
2969
+ onLeaveActive,
2970
+ onAppearEnd,
2971
+ onEnterEnd,
2972
+ onLeaveEnd,
2973
+ onVisibleChanged
2974
+ }) {
2975
+ // Used for outer render usage to avoid `visible: false & status: none` to render nothing
2976
+ const [asyncVisible, setAsyncVisible] = React.useState();
2977
+ const [getStatus, setStatus] = useSyncState(STATUS_NONE);
2978
+ const [style, setStyle] = React.useState([null, null]);
2979
+ const currentStatus = getStatus();
2980
+ const mountedRef = useRef(false);
2981
+ const deadlineRef = useRef(null);
2982
+
2983
+ // =========================== Dom Node ===========================
2984
+ function getDomElement() {
2985
+ return getElement();
2986
+ }
2987
+
2988
+ // ========================== Motion End ==========================
2989
+ const activeRef = useRef(false);
2990
+
2991
+ /**
2992
+ * Clean up status & style
2993
+ */
2994
+ function updateMotionEndStatus() {
2995
+ setStatus(STATUS_NONE);
2996
+ setStyle([null, null]);
2997
+ }
2998
+ const onInternalMotionEnd = useEvent(event => {
2999
+ const status = getStatus();
3000
+ // Do nothing since not in any transition status.
3001
+ // This may happen when `motionDeadline` trigger.
3002
+ if (status === STATUS_NONE) {
3003
+ return;
3004
+ }
3005
+ const element = getDomElement();
3006
+ if (event && !event.deadline && event.target !== element) {
3007
+ // event exists
3008
+ // not initiated by deadline
3009
+ // transitionEnd not fired by inner elements
3010
+ return;
3011
+ }
3012
+ const currentActive = activeRef.current;
3013
+ let canEnd;
3014
+ if (status === STATUS_APPEAR && currentActive) {
3015
+ canEnd = onAppearEnd?.(element, event);
3016
+ } else if (status === STATUS_ENTER && currentActive) {
3017
+ canEnd = onEnterEnd?.(element, event);
3018
+ } else if (status === STATUS_LEAVE && currentActive) {
3019
+ canEnd = onLeaveEnd?.(element, event);
3020
+ }
3021
+
3022
+ // Only update status when `canEnd` and not destroyed
3023
+ if (currentActive && canEnd !== false) {
3024
+ updateMotionEndStatus();
3025
+ }
3026
+ });
3027
+ const [patchMotionEvents] = useDomMotionEvents(onInternalMotionEnd);
3028
+
3029
+ // ============================= Step =============================
3030
+ const getEventHandlers = targetStatus => {
3031
+ switch (targetStatus) {
3032
+ case STATUS_APPEAR:
3033
+ return {
3034
+ [STEP_PREPARE]: onAppearPrepare,
3035
+ [STEP_START]: onAppearStart,
3036
+ [STEP_ACTIVE]: onAppearActive
3037
+ };
3038
+ case STATUS_ENTER:
3039
+ return {
3040
+ [STEP_PREPARE]: onEnterPrepare,
3041
+ [STEP_START]: onEnterStart,
3042
+ [STEP_ACTIVE]: onEnterActive
3043
+ };
3044
+ case STATUS_LEAVE:
3045
+ return {
3046
+ [STEP_PREPARE]: onLeavePrepare,
3047
+ [STEP_START]: onLeaveStart,
3048
+ [STEP_ACTIVE]: onLeaveActive
3049
+ };
3050
+ default:
3051
+ return {};
3052
+ }
3053
+ };
3054
+ const eventHandlers = React.useMemo(() => getEventHandlers(currentStatus), [currentStatus]);
3055
+ const [startStep, step] = useStepQueue(currentStatus, !supportMotion, newStep => {
3056
+ // Only prepare step can be skip
3057
+ if (newStep === STEP_PREPARE) {
3058
+ const onPrepare = eventHandlers[STEP_PREPARE];
3059
+ if (!onPrepare) {
3060
+ return SkipStep;
3061
+ }
3062
+ return onPrepare(getDomElement());
3063
+ }
3064
+
3065
+ // Rest step is sync update
3066
+ if (newStep in eventHandlers) {
3067
+ setStyle([eventHandlers[newStep]?.(getDomElement(), null) || null, newStep]);
3068
+ }
3069
+ if (newStep === STEP_ACTIVE && currentStatus !== STATUS_NONE) {
3070
+ // Patch events when motion needed
3071
+ patchMotionEvents(getDomElement());
3072
+ if (motionDeadline > 0) {
3073
+ clearTimeout(deadlineRef.current);
3074
+ deadlineRef.current = setTimeout(() => {
3075
+ onInternalMotionEnd({
3076
+ deadline: true
3077
+ });
3078
+ }, motionDeadline);
3079
+ }
3080
+ }
3081
+ if (newStep === STEP_PREPARED) {
3082
+ updateMotionEndStatus();
3083
+ }
3084
+ return DoStep;
3085
+ });
3086
+ const active = isActive(step);
3087
+ activeRef.current = active;
3088
+
3089
+ // ============================ Status ============================
3090
+ const visibleRef = useRef(null);
3091
+
3092
+ // Update with new status
3093
+ useIsomorphicLayoutEffect(() => {
3094
+ // When use Suspense, the `visible` will repeat trigger,
3095
+ // But not real change of the `visible`, we need to skip it.
3096
+ // https://github.com/ant-design/ant-design/issues/44379
3097
+ if (mountedRef.current && visibleRef.current === visible) {
3098
+ return;
3099
+ }
3100
+ setAsyncVisible(visible);
3101
+ const isMounted = mountedRef.current;
3102
+ mountedRef.current = true;
3103
+
3104
+ // if (!supportMotion) {
3105
+ // return;
3106
+ // }
3107
+
3108
+ let nextStatus;
3109
+
3110
+ // Appear
3111
+ if (!isMounted && visible && motionAppear) {
3112
+ nextStatus = STATUS_APPEAR;
3113
+ }
3114
+
3115
+ // Enter
3116
+ if (isMounted && visible && motionEnter) {
3117
+ nextStatus = STATUS_ENTER;
3118
+ }
3119
+
3120
+ // Leave
3121
+ if (isMounted && !visible && motionLeave || !isMounted && motionLeaveImmediately && !visible && motionLeave) {
3122
+ nextStatus = STATUS_LEAVE;
3123
+ }
3124
+ const nextEventHandlers = getEventHandlers(nextStatus);
3125
+
3126
+ // Update to next status
3127
+ if (nextStatus && (supportMotion || nextEventHandlers[STEP_PREPARE])) {
3128
+ setStatus(nextStatus);
3129
+ startStep();
3130
+ } else {
3131
+ // Set back in case no motion but prev status has prepare step
3132
+ setStatus(STATUS_NONE);
3133
+ }
3134
+ visibleRef.current = visible;
3135
+ }, [visible]);
3136
+
3137
+ // ============================ Effect ============================
3138
+ // Reset when motion changed
3139
+ useEffect(() => {
3140
+ if (
3141
+ // Cancel appear
3142
+ currentStatus === STATUS_APPEAR && !motionAppear ||
3143
+ // Cancel enter
3144
+ currentStatus === STATUS_ENTER && !motionEnter ||
3145
+ // Cancel leave
3146
+ currentStatus === STATUS_LEAVE && !motionLeave) {
3147
+ setStatus(STATUS_NONE);
3148
+ }
3149
+ }, [motionAppear, motionEnter, motionLeave]);
3150
+ useEffect(() => () => {
3151
+ mountedRef.current = false;
3152
+ clearTimeout(deadlineRef.current);
3153
+ }, []);
3154
+
3155
+ // Trigger `onVisibleChanged`
3156
+ const firstMountChangeRef = React.useRef(false);
3157
+ useEffect(() => {
3158
+ // [visible & motion not end] => [!visible & motion end] still need trigger onVisibleChanged
3159
+ if (asyncVisible) {
3160
+ firstMountChangeRef.current = true;
3161
+ }
3162
+ if (asyncVisible !== undefined && currentStatus === STATUS_NONE) {
3163
+ // Skip first render is invisible since it's nothing changed
3164
+ if (firstMountChangeRef.current || asyncVisible) {
3165
+ onVisibleChanged?.(asyncVisible);
3166
+ }
3167
+ firstMountChangeRef.current = true;
3168
+ }
3169
+ }, [asyncVisible, currentStatus]);
3170
+
3171
+ // ============================ Styles ============================
3172
+ let mergedStyle = style[0];
3173
+ if (eventHandlers[STEP_PREPARE] && step === STEP_START) {
3174
+ mergedStyle = {
3175
+ transition: 'none',
3176
+ ...mergedStyle
3177
+ };
3178
+ }
3179
+ const styleStep = style[1];
3180
+ return [getStatus, step, mergedStyle, asyncVisible ?? visible,
3181
+ // Appear Check
3182
+ !mountedRef.current && currentStatus === STATUS_NONE && supportMotion && motionAppear ? 'NONE' :
3183
+ // Enter or Leave check
3184
+ step === STEP_START || step === STEP_ACTIVE ? styleStep === step : true];
3185
+ }
3186
+
3187
+ /* eslint-disable react/default-props-match-prop-types, react/no-multi-comp, react/prop-types */
3188
+ /**
3189
+ * `transitionSupport` is used for none transition test case.
3190
+ * Default we use browser transition event support check.
3191
+ */
3192
+ function genCSSMotion(config) {
3193
+ let transitionSupport = config;
3194
+ if (typeof config === 'object') {
3195
+ ({
3196
+ transitionSupport
3197
+ } = config);
3198
+ }
3199
+ function isSupportTransition(props, contextMotion) {
3200
+ return !!(props.motionName && transitionSupport && contextMotion !== false);
3201
+ }
3202
+ const CSSMotion = /*#__PURE__*/React.forwardRef((props, ref) => {
3203
+ const {
3204
+ // Default config
3205
+ visible = true,
3206
+ removeOnLeave = true,
3207
+ forceRender,
3208
+ children,
3209
+ motionName,
3210
+ leavedClassName,
3211
+ eventProps
3212
+ } = props;
3213
+ const {
3214
+ motion: contextMotion
3215
+ } = React.useContext(Context$1);
3216
+ const supportMotion = isSupportTransition(props, contextMotion);
3217
+
3218
+ // Ref to the react node, it may be a HTMLElement
3219
+ const nodeRef = useRef();
3220
+ function getDomElement() {
3221
+ return getDOM(nodeRef.current);
3222
+ }
3223
+ const [getStatus, statusStep, statusStyle, mergedVisible, styleReady] = useStatus(supportMotion, visible, getDomElement, props);
3224
+ const status = getStatus();
3225
+
3226
+ // Record whether content has rendered
3227
+ // Will return null for un-rendered even when `removeOnLeave={false}`
3228
+ const renderedRef = React.useRef(mergedVisible);
3229
+ if (mergedVisible) {
3230
+ renderedRef.current = true;
3231
+ }
3232
+
3233
+ // ====================== Refs ======================
3234
+ const refObj = React.useMemo(() => {
3235
+ const obj = {};
3236
+ Object.defineProperties(obj, {
3237
+ nativeElement: {
3238
+ enumerable: true,
3239
+ get: getDomElement
3240
+ },
3241
+ inMotion: {
3242
+ enumerable: true,
3243
+ get: () => () => getStatus() !== STATUS_NONE
3244
+ },
3245
+ enableMotion: {
3246
+ enumerable: true,
3247
+ get: () => () => supportMotion
3248
+ }
3249
+ });
3250
+ return obj;
3251
+ }, []);
3252
+
3253
+ // We lock `deps` here since function return object
3254
+ // will repeat trigger ref from `refConfig` -> `null` -> `refConfig`
3255
+ React.useImperativeHandle(ref, () => refObj, []);
3256
+
3257
+ // ===================== Render =====================
3258
+ // return motionChildren as React.ReactElement;
3259
+ const idRef = React.useRef(0);
3260
+ if (styleReady) {
3261
+ idRef.current += 1;
3262
+ }
3263
+
3264
+ // We should render children when motionStyle is sync with stepStatus
3265
+ return React.useMemo(() => {
3266
+ if (styleReady === 'NONE') {
3267
+ return null;
3268
+ }
3269
+ let motionChildren;
3270
+ const mergedProps = {
3271
+ ...eventProps,
3272
+ visible
3273
+ };
3274
+ if (!children) {
3275
+ // No children
3276
+ motionChildren = null;
3277
+ } else if (status === STATUS_NONE) {
3278
+ // Stable children
3279
+ if (mergedVisible) {
3280
+ motionChildren = children({
3281
+ ...mergedProps
3282
+ }, nodeRef);
3283
+ } else if (!removeOnLeave && renderedRef.current && leavedClassName) {
3284
+ motionChildren = children({
3285
+ ...mergedProps,
3286
+ className: leavedClassName
3287
+ }, nodeRef);
3288
+ } else if (forceRender || !removeOnLeave && !leavedClassName) {
3289
+ motionChildren = children({
3290
+ ...mergedProps,
3291
+ style: {
3292
+ display: 'none'
3293
+ }
3294
+ }, nodeRef);
3295
+ } else {
3296
+ motionChildren = null;
3297
+ }
3298
+ } else {
3299
+ // In motion
3300
+ let statusSuffix;
3301
+ if (statusStep === STEP_PREPARE) {
3302
+ statusSuffix = 'prepare';
3303
+ } else if (isActive(statusStep)) {
3304
+ statusSuffix = 'active';
3305
+ } else if (statusStep === STEP_START) {
3306
+ statusSuffix = 'start';
3307
+ }
3308
+ const motionCls = getTransitionName(motionName, `${status}-${statusSuffix}`);
3309
+ motionChildren = children({
3310
+ ...mergedProps,
3311
+ className: clsx(getTransitionName(motionName, status), {
3312
+ [motionCls]: motionCls && statusSuffix,
3313
+ [motionName]: typeof motionName === 'string'
3314
+ }),
3315
+ style: statusStyle
3316
+ }, nodeRef);
3317
+ }
3318
+
3319
+ // Auto inject ref if child node not have `ref` props
3320
+ if ( /*#__PURE__*/React.isValidElement(motionChildren) && supportRef(motionChildren)) {
3321
+ const originNodeRef = getNodeRef(motionChildren);
3322
+ if (!originNodeRef) {
3323
+ motionChildren = /*#__PURE__*/React.cloneElement(motionChildren, {
3324
+ ref: nodeRef
3325
+ });
3326
+ }
3327
+ }
3328
+ return motionChildren;
3329
+ }, [idRef.current]);
3330
+ });
3331
+ CSSMotion.displayName = 'CSSMotion';
3332
+ return CSSMotion;
3333
+ }
3334
+ var CSSMotion = genCSSMotion(supportTransition);
3335
+
3336
+ function Arrow(props) {
3337
+ const {
3338
+ prefixCls,
3339
+ align,
3340
+ arrow,
3341
+ arrowPos
3342
+ } = props;
3343
+ const {
3344
+ className,
3345
+ content,
3346
+ style
3347
+ } = arrow || {};
3348
+ const {
3349
+ x = 0,
3350
+ y = 0
3351
+ } = arrowPos;
3352
+ const arrowRef = React.useRef(null);
3353
+
3354
+ // Skip if no align
3355
+ if (!align || !align.points) {
3356
+ return null;
3357
+ }
3358
+ const alignStyle = {
3359
+ position: 'absolute'
3360
+ };
3361
+
3362
+ // Skip if no need to align
3363
+ if (align.autoArrow !== false) {
3364
+ const popupPoints = align.points[0];
3365
+ const targetPoints = align.points[1];
3366
+ const popupTB = popupPoints[0];
3367
+ const popupLR = popupPoints[1];
3368
+ const targetTB = targetPoints[0];
3369
+ const targetLR = targetPoints[1];
3370
+
3371
+ // Top & Bottom
3372
+ if (popupTB === targetTB || !['t', 'b'].includes(popupTB)) {
3373
+ alignStyle.top = y;
3374
+ } else if (popupTB === 't') {
3375
+ alignStyle.top = 0;
3376
+ } else {
3377
+ alignStyle.bottom = 0;
3378
+ }
3379
+
3380
+ // Left & Right
3381
+ if (popupLR === targetLR || !['l', 'r'].includes(popupLR)) {
3382
+ alignStyle.left = x;
3383
+ } else if (popupLR === 'l') {
3384
+ alignStyle.left = 0;
3385
+ } else {
3386
+ alignStyle.right = 0;
3387
+ }
3388
+ }
3389
+ return /*#__PURE__*/React.createElement("div", {
3390
+ ref: arrowRef,
3391
+ className: clsx(`${prefixCls}-arrow`, className),
3392
+ style: {
3393
+ ...alignStyle,
3394
+ ...style
3395
+ }
3396
+ }, content);
3397
+ }
3398
+
3399
+ function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
3400
+ function Mask(props) {
3401
+ const {
3402
+ prefixCls,
3403
+ open,
3404
+ zIndex,
3405
+ mask,
3406
+ motion,
3407
+ mobile
3408
+ } = props;
3409
+ if (!mask) {
3410
+ return null;
3411
+ }
3412
+ return /*#__PURE__*/React.createElement(CSSMotion, _extends$1({}, motion, {
3413
+ motionAppear: true,
3414
+ visible: open,
3415
+ removeOnLeave: true
3416
+ }), ({
3417
+ className
3418
+ }) => /*#__PURE__*/React.createElement("div", {
3419
+ style: {
3420
+ zIndex
3421
+ },
3422
+ className: clsx(`${prefixCls}-mask`, mobile && `${prefixCls}-mobile-mask`, className)
3423
+ }));
3424
+ }
3425
+
3426
+ const PopupContent = /*#__PURE__*/React.memo(({
3427
+ children
3428
+ }) => children, (_, next) => next.cache);
3429
+ if (process.env.NODE_ENV !== 'production') {
3430
+ PopupContent.displayName = 'PopupContent';
3431
+ }
3432
+
3433
+ function useOffsetStyle(isMobile, ready, open, align, offsetR, offsetB, offsetX, offsetY) {
3434
+ // >>>>> Offset
3435
+ const AUTO = 'auto';
3436
+ const offsetStyle = isMobile ? {} : {
3437
+ left: '-1000vw',
3438
+ top: '-1000vh',
3439
+ right: AUTO,
3440
+ bottom: AUTO
3441
+ };
3442
+
3443
+ // Set align style
3444
+ if (!isMobile && (ready || !open)) {
3445
+ const {
3446
+ points
3447
+ } = align;
3448
+ const dynamicInset = align.dynamicInset || align._experimental?.dynamicInset;
3449
+ const alignRight = dynamicInset && points[0][1] === 'r';
3450
+ const alignBottom = dynamicInset && points[0][0] === 'b';
3451
+ if (alignRight) {
3452
+ offsetStyle.right = offsetR;
3453
+ offsetStyle.left = AUTO;
3454
+ } else {
3455
+ offsetStyle.left = offsetX;
3456
+ offsetStyle.right = AUTO;
3457
+ }
3458
+ if (alignBottom) {
3459
+ offsetStyle.bottom = offsetB;
3460
+ offsetStyle.top = AUTO;
3461
+ } else {
3462
+ offsetStyle.top = offsetY;
3463
+ offsetStyle.bottom = AUTO;
3464
+ }
3465
+ }
3466
+ return offsetStyle;
3467
+ }
3468
+
3469
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
3470
+ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
3471
+ const {
3472
+ onEsc,
3473
+ popup,
3474
+ className,
3475
+ prefixCls,
3476
+ style,
3477
+ target,
3478
+ onVisibleChanged,
3479
+ // Open
3480
+ open,
3481
+ keepDom,
3482
+ fresh,
3483
+ // Click
3484
+ onClick,
3485
+ // Mask
3486
+ mask,
3487
+ // Arrow
3488
+ arrow,
3489
+ arrowPos,
3490
+ align,
3491
+ // Motion
3492
+ motion,
3493
+ maskMotion,
3494
+ // Mobile
3495
+ mobile,
3496
+ // Portal
3497
+ forceRender,
3498
+ getPopupContainer,
3499
+ autoDestroy,
3500
+ portal: Portal,
3501
+ children,
3502
+ zIndex,
3503
+ onMouseEnter,
3504
+ onMouseLeave,
3505
+ onPointerEnter,
3506
+ onPointerDownCapture,
3507
+ ready,
3508
+ offsetX,
3509
+ offsetY,
3510
+ offsetR,
3511
+ offsetB,
3512
+ onAlign,
3513
+ onPrepare,
3514
+ // Resize
3515
+ onResize,
3516
+ stretch,
3517
+ targetWidth,
3518
+ targetHeight
3519
+ } = props;
3520
+ const popupContent = typeof popup === 'function' ? popup() : popup;
3521
+
3522
+ // We can not remove holder only when motion finished.
3523
+ const isNodeVisible = open || keepDom;
3524
+
3525
+ // ========================= Mobile =========================
3526
+ const isMobile = !!mobile;
3527
+
3528
+ // ========================== Mask ==========================
3529
+ const [mergedMask, mergedMaskMotion, mergedPopupMotion] = React.useMemo(() => {
3530
+ if (mobile) {
3531
+ return [mobile.mask, mobile.maskMotion, mobile.motion];
3532
+ }
3533
+ return [mask, maskMotion, motion];
3534
+ }, [mobile, mask, maskMotion, motion]);
3535
+
3536
+ // ======================= Container ========================
3537
+ const getPopupContainerNeedParams = getPopupContainer?.length > 0;
3538
+ const [show, setShow] = React.useState(!getPopupContainer || !getPopupContainerNeedParams);
3539
+
3540
+ // Delay to show since `getPopupContainer` need target element
3541
+ useLayoutEffect(() => {
3542
+ if (!show && getPopupContainerNeedParams && target) {
3543
+ setShow(true);
3544
+ }
3545
+ }, [show, getPopupContainerNeedParams, target]);
3546
+
3547
+ // ========================= Resize =========================
3548
+ const onInternalResize = useEvent((size, ele) => {
3549
+ onResize?.(size, ele);
3550
+ onAlign();
3551
+ });
3552
+
3553
+ // ========================= Styles =========================
3554
+ const offsetStyle = useOffsetStyle(isMobile, ready, open, align, offsetR, offsetB, offsetX, offsetY);
3555
+
3556
+ // ========================= Render =========================
3557
+ if (!show) {
3558
+ return null;
3559
+ }
3560
+
3561
+ // >>>>> Misc
3562
+ const miscStyle = {};
3563
+ if (stretch) {
3564
+ if (stretch.includes('height') && targetHeight) {
3565
+ miscStyle.height = targetHeight;
3566
+ } else if (stretch.includes('minHeight') && targetHeight) {
3567
+ miscStyle.minHeight = targetHeight;
3568
+ }
3569
+ if (stretch.includes('width') && targetWidth) {
3570
+ miscStyle.width = targetWidth;
3571
+ } else if (stretch.includes('minWidth') && targetWidth) {
3572
+ miscStyle.minWidth = targetWidth;
3573
+ }
3574
+ }
3575
+ if (!open) {
3576
+ miscStyle.pointerEvents = 'none';
3577
+ }
3578
+ return /*#__PURE__*/React.createElement(Portal, {
3579
+ open: forceRender || isNodeVisible,
3580
+ getContainer: getPopupContainer && (() => getPopupContainer(target)),
3581
+ autoDestroy: autoDestroy,
3582
+ onEsc: onEsc
3583
+ }, /*#__PURE__*/React.createElement(Mask, {
3584
+ prefixCls: prefixCls,
3585
+ open: open,
3586
+ zIndex: zIndex,
3587
+ mask: mergedMask,
3588
+ motion: mergedMaskMotion,
3589
+ mobile: isMobile
3590
+ }), /*#__PURE__*/React.createElement(RefResizeObserver, {
3591
+ onResize: onInternalResize,
3592
+ disabled: !open
3593
+ }, resizeObserverRef => {
3594
+ return /*#__PURE__*/React.createElement(CSSMotion, _extends({
3595
+ motionAppear: true,
3596
+ motionEnter: true,
3597
+ motionLeave: true,
3598
+ removeOnLeave: false,
3599
+ forceRender: forceRender,
3600
+ leavedClassName: `${prefixCls}-hidden`
3601
+ }, mergedPopupMotion, {
3602
+ onAppearPrepare: onPrepare,
3603
+ onEnterPrepare: onPrepare,
3604
+ visible: open,
3605
+ onVisibleChanged: nextVisible => {
3606
+ motion?.onVisibleChanged?.(nextVisible);
3607
+ onVisibleChanged(nextVisible);
3608
+ }
3609
+ }), ({
3610
+ className: motionClassName,
3611
+ style: motionStyle
3612
+ }, motionRef) => {
3613
+ const cls = clsx(prefixCls, motionClassName, className, {
3614
+ [`${prefixCls}-mobile`]: isMobile
3615
+ });
3616
+ return /*#__PURE__*/React.createElement("div", {
3617
+ ref: composeRef(resizeObserverRef, ref, motionRef),
3618
+ className: cls,
3619
+ style: {
3620
+ '--arrow-x': `${arrowPos.x || 0}px`,
3621
+ '--arrow-y': `${arrowPos.y || 0}px`,
3622
+ ...offsetStyle,
3623
+ ...miscStyle,
3624
+ ...motionStyle,
3625
+ boxSizing: 'border-box',
3626
+ zIndex,
3627
+ ...style
3628
+ },
3629
+ onMouseEnter: onMouseEnter,
3630
+ onMouseLeave: onMouseLeave,
3631
+ onPointerEnter: onPointerEnter,
3632
+ onClick: onClick,
3633
+ onPointerDownCapture: onPointerDownCapture
3634
+ }, arrow && /*#__PURE__*/React.createElement(Arrow, {
3635
+ prefixCls: prefixCls,
3636
+ arrow: arrow,
3637
+ arrowPos: arrowPos,
3638
+ align: align
3639
+ }), /*#__PURE__*/React.createElement(PopupContent, {
3640
+ cache: !open && !fresh
3641
+ }, popupContent));
3642
+ });
3643
+ }), children);
3644
+ });
3645
+ if (process.env.NODE_ENV !== 'production') {
3646
+ Popup.displayName = 'Popup';
3647
+ }
3648
+
3649
+ // ===================== Nest =====================
3650
+
3651
+ const TriggerContext = /*#__PURE__*/React.createContext(null);
3652
+
3653
+ // ==================== Unique ====================
3654
+
3655
+ const UniqueContext = /*#__PURE__*/React.createContext(null);
3656
+
3657
+ function toArray(val) {
3658
+ return val ? Array.isArray(val) ? val : [val] : [];
3659
+ }
3660
+ function useAction(action, showAction, hideAction) {
3661
+ return React.useMemo(() => {
3662
+ const mergedShowAction = toArray(showAction ?? action);
3663
+ const mergedHideAction = toArray(hideAction ?? action);
3664
+ const showActionSet = new Set(mergedShowAction);
3665
+ const hideActionSet = new Set(mergedHideAction);
3666
+ if (showActionSet.has('hover') && !showActionSet.has('click')) {
3667
+ showActionSet.add('touch');
3668
+ }
3669
+ if (hideActionSet.has('hover') && !hideActionSet.has('click')) {
3670
+ hideActionSet.add('touch');
3671
+ }
3672
+ return [showActionSet, hideActionSet];
3673
+ }, [action, showAction, hideAction]);
3674
+ }
3675
+
3676
+ var isVisible = (element => {
3677
+ if (!element) {
3678
+ return false;
3679
+ }
3680
+ if (element instanceof Element) {
3681
+ if (element.offsetParent) {
3682
+ return true;
3683
+ }
3684
+ if (element.getBBox) {
3685
+ const {
3686
+ width,
3687
+ height
3688
+ } = element.getBBox();
3689
+ if (width || height) {
3690
+ return true;
3691
+ }
3692
+ }
3693
+ if (element.getBoundingClientRect) {
3694
+ const {
3695
+ width,
3696
+ height
3697
+ } = element.getBoundingClientRect();
3698
+ if (width || height) {
3699
+ return true;
3700
+ }
3701
+ }
3702
+ }
3703
+ return false;
3704
+ });
3705
+
3706
+ function isPointsEq(a1 = [], a2 = [], isAlignPoint) {
3707
+ const getVal = (a, index) => a[index] || '';
3708
+ if (isAlignPoint) {
3709
+ return getVal(a1, 0) === getVal(a2, 0);
3710
+ }
3711
+ return getVal(a1, 0) === getVal(a2, 0) && getVal(a1, 1) === getVal(a2, 1);
3712
+ }
3713
+ function getAlignPopupClassName(builtinPlacements, prefixCls, align, isAlignPoint) {
3714
+ const {
3715
+ points
3716
+ } = align;
3717
+ const placements = Object.keys(builtinPlacements);
3718
+ for (let i = 0; i < placements.length; i += 1) {
3719
+ const placement = placements[i];
3720
+ if (isPointsEq(builtinPlacements[placement]?.points, points, isAlignPoint)) {
3721
+ return `${prefixCls}-placement-${placement}`;
3722
+ }
3723
+ }
3724
+ return '';
3725
+ }
3726
+ function getWin(ele) {
3727
+ return ele.ownerDocument.defaultView;
3728
+ }
3729
+
3730
+ /**
3731
+ * Get all the scrollable parent elements of the element
3732
+ * @param ele The element to be detected
3733
+ * @param areaOnly Only return the parent which will cut visible area
3734
+ */
3735
+ function collectScroller(ele) {
3736
+ const scrollerList = [];
3737
+ let current = ele?.parentElement;
3738
+ const scrollStyle = ['hidden', 'scroll', 'clip', 'auto'];
3739
+ while (current) {
3740
+ const {
3741
+ overflowX,
3742
+ overflowY,
3743
+ overflow
3744
+ } = getWin(current).getComputedStyle(current);
3745
+ if ([overflowX, overflowY, overflow].some(o => scrollStyle.includes(o))) {
3746
+ scrollerList.push(current);
3747
+ }
3748
+ current = current.parentElement;
3749
+ }
3750
+ return scrollerList;
3751
+ }
3752
+ function toNum(num, defaultValue = 1) {
3753
+ return Number.isNaN(num) ? defaultValue : num;
3754
+ }
3755
+ function getPxValue(val) {
3756
+ return toNum(parseFloat(val), 0);
3757
+ }
3758
+ /**
3759
+ *
3760
+ *
3761
+ * **************************************
3762
+ * * Border *
3763
+ * * ************************** *
3764
+ * * * * * *
3765
+ * * B * * S * B *
3766
+ * * o * * c * o *
3767
+ * * r * Content * r * r *
3768
+ * * d * * o * d *
3769
+ * * e * * l * e *
3770
+ * * r ******************** l * r *
3771
+ * * * Scroll * *
3772
+ * * ************************** *
3773
+ * * Border *
3774
+ * **************************************
3775
+ *
3776
+ */
3777
+ /**
3778
+ * Get visible area of element
3779
+ */
3780
+ function getVisibleArea(initArea, scrollerList) {
3781
+ const visibleArea = {
3782
+ ...initArea
3783
+ };
3784
+ (scrollerList || []).forEach(ele => {
3785
+ if (ele instanceof HTMLBodyElement || ele instanceof HTMLHtmlElement) {
3786
+ return;
3787
+ }
3788
+
3789
+ // Skip if static position which will not affect visible area
3790
+ const {
3791
+ overflow,
3792
+ overflowClipMargin,
3793
+ borderTopWidth,
3794
+ borderBottomWidth,
3795
+ borderLeftWidth,
3796
+ borderRightWidth
3797
+ } = getWin(ele).getComputedStyle(ele);
3798
+ const eleRect = ele.getBoundingClientRect();
3799
+ const {
3800
+ offsetHeight: eleOutHeight,
3801
+ clientHeight: eleInnerHeight,
3802
+ offsetWidth: eleOutWidth,
3803
+ clientWidth: eleInnerWidth
3804
+ } = ele;
3805
+ const borderTopNum = getPxValue(borderTopWidth);
3806
+ const borderBottomNum = getPxValue(borderBottomWidth);
3807
+ const borderLeftNum = getPxValue(borderLeftWidth);
3808
+ const borderRightNum = getPxValue(borderRightWidth);
3809
+ const scaleX = toNum(Math.round(eleRect.width / eleOutWidth * 1000) / 1000);
3810
+ const scaleY = toNum(Math.round(eleRect.height / eleOutHeight * 1000) / 1000);
3811
+
3812
+ // Original visible area
3813
+ const eleScrollWidth = (eleOutWidth - eleInnerWidth - borderLeftNum - borderRightNum) * scaleX;
3814
+ const eleScrollHeight = (eleOutHeight - eleInnerHeight - borderTopNum - borderBottomNum) * scaleY;
3815
+
3816
+ // Cut border size
3817
+ const scaledBorderTopWidth = borderTopNum * scaleY;
3818
+ const scaledBorderBottomWidth = borderBottomNum * scaleY;
3819
+ const scaledBorderLeftWidth = borderLeftNum * scaleX;
3820
+ const scaledBorderRightWidth = borderRightNum * scaleX;
3821
+
3822
+ // Clip margin
3823
+ let clipMarginWidth = 0;
3824
+ let clipMarginHeight = 0;
3825
+ if (overflow === 'clip') {
3826
+ const clipNum = getPxValue(overflowClipMargin);
3827
+ clipMarginWidth = clipNum * scaleX;
3828
+ clipMarginHeight = clipNum * scaleY;
3829
+ }
3830
+
3831
+ // Region
3832
+ const eleLeft = eleRect.x + scaledBorderLeftWidth - clipMarginWidth;
3833
+ const eleTop = eleRect.y + scaledBorderTopWidth - clipMarginHeight;
3834
+ const eleRight = eleLeft + eleRect.width + 2 * clipMarginWidth - scaledBorderLeftWidth - scaledBorderRightWidth - eleScrollWidth;
3835
+ const eleBottom = eleTop + eleRect.height + 2 * clipMarginHeight - scaledBorderTopWidth - scaledBorderBottomWidth - eleScrollHeight;
3836
+ visibleArea.left = Math.max(visibleArea.left, eleLeft);
3837
+ visibleArea.top = Math.max(visibleArea.top, eleTop);
3838
+ visibleArea.right = Math.min(visibleArea.right, eleRight);
3839
+ visibleArea.bottom = Math.min(visibleArea.bottom, eleBottom);
3840
+ });
3841
+ return visibleArea;
3842
+ }
3843
+
3844
+ function getUnitOffset(size, offset = 0) {
3845
+ const offsetStr = `${offset}`;
3846
+ const cells = offsetStr.match(/^(.*)\%$/);
3847
+ if (cells) {
3848
+ return size * (parseFloat(cells[1]) / 100);
3849
+ }
3850
+ return parseFloat(offsetStr);
3851
+ }
3852
+ function getNumberOffset(rect, offset) {
3853
+ const [offsetX, offsetY] = offset || [];
3854
+ return [getUnitOffset(rect.width, offsetX), getUnitOffset(rect.height, offsetY)];
3855
+ }
3856
+ function splitPoints(points = '') {
3857
+ return [points[0], points[1]];
3858
+ }
3859
+ function getAlignPoint(rect, points) {
3860
+ const topBottom = points[0];
3861
+ const leftRight = points[1];
3862
+ let x;
3863
+ let y;
3864
+
3865
+ // Top & Bottom
3866
+ if (topBottom === 't') {
3867
+ y = rect.y;
3868
+ } else if (topBottom === 'b') {
3869
+ y = rect.y + rect.height;
3870
+ } else {
3871
+ y = rect.y + rect.height / 2;
3872
+ }
3873
+
3874
+ // Left & Right
3875
+ if (leftRight === 'l') {
3876
+ x = rect.x;
3877
+ } else if (leftRight === 'r') {
3878
+ x = rect.x + rect.width;
3879
+ } else {
3880
+ x = rect.x + rect.width / 2;
3881
+ }
3882
+ return {
3883
+ x,
3884
+ y
3885
+ };
3886
+ }
3887
+ function reversePoints(points, index) {
3888
+ const reverseMap = {
3889
+ t: 'b',
3890
+ b: 't',
3891
+ l: 'r',
3892
+ r: 'l'
3893
+ };
3894
+ const clone = [...points];
3895
+ clone[index] = reverseMap[points[index]] || 'c';
3896
+ return clone;
3897
+ }
3898
+ function flatPoints(points) {
3899
+ return points.join('');
3900
+ }
3901
+ function useAlign(open, popupEle, target, placement, builtinPlacements, popupAlign, onPopupAlign, mobile) {
3902
+ const [offsetInfo, setOffsetInfo] = React.useState({
3903
+ ready: false,
3904
+ offsetX: 0,
3905
+ offsetY: 0,
3906
+ offsetR: 0,
3907
+ offsetB: 0,
3908
+ arrowX: 0,
3909
+ arrowY: 0,
3910
+ scaleX: 1,
3911
+ scaleY: 1,
3912
+ align: builtinPlacements[placement] || {}
3913
+ });
3914
+ const alignCountRef = React.useRef(0);
3915
+ const scrollerList = React.useMemo(() => {
3916
+ if (!popupEle || mobile) {
3917
+ return [];
3918
+ }
3919
+ return collectScroller(popupEle);
3920
+ }, [popupEle]);
3921
+
3922
+ // ========================= Flip ==========================
3923
+ // We will memo flip info.
3924
+ // If size change to make flip, it will memo the flip info and use it in next align.
3925
+ const prevFlipRef = React.useRef({});
3926
+ const resetFlipCache = () => {
3927
+ prevFlipRef.current = {};
3928
+ };
3929
+ if (!open) {
3930
+ resetFlipCache();
3931
+ }
3932
+
3933
+ // ========================= Align =========================
3934
+ const onAlign = useEvent(() => {
3935
+ if (popupEle && target && open && !mobile) {
3936
+ const popupElement = popupEle;
3937
+ const doc = popupElement.ownerDocument;
3938
+ const win = getWin(popupElement);
3939
+ const {
3940
+ position: popupPosition
3941
+ } = win.getComputedStyle(popupElement);
3942
+ const originLeft = popupElement.style.left;
3943
+ const originTop = popupElement.style.top;
3944
+ const originRight = popupElement.style.right;
3945
+ const originBottom = popupElement.style.bottom;
3946
+ const originOverflow = popupElement.style.overflow;
3947
+
3948
+ // Placement
3949
+ const placementInfo = {
3950
+ ...builtinPlacements[placement],
3951
+ ...popupAlign
3952
+ };
3953
+
3954
+ // placeholder element
3955
+ const placeholderElement = doc.createElement('div');
3956
+ popupElement.parentElement?.appendChild(placeholderElement);
3957
+ placeholderElement.style.left = `${popupElement.offsetLeft}px`;
3958
+ placeholderElement.style.top = `${popupElement.offsetTop}px`;
3959
+ placeholderElement.style.position = popupPosition;
3960
+ placeholderElement.style.height = `${popupElement.offsetHeight}px`;
3961
+ placeholderElement.style.width = `${popupElement.offsetWidth}px`;
3962
+
3963
+ // Reset first
3964
+ popupElement.style.left = '0';
3965
+ popupElement.style.top = '0';
3966
+ popupElement.style.right = 'auto';
3967
+ popupElement.style.bottom = 'auto';
3968
+ popupElement.style.overflow = 'hidden';
3969
+
3970
+ // Calculate align style, we should consider `transform` case
3971
+ let targetRect;
3972
+ if (Array.isArray(target)) {
3973
+ targetRect = {
3974
+ x: target[0],
3975
+ y: target[1],
3976
+ width: 0,
3977
+ height: 0
3978
+ };
3979
+ } else {
3980
+ const rect = target.getBoundingClientRect();
3981
+ rect.x = rect.x ?? rect.left;
3982
+ rect.y = rect.y ?? rect.top;
3983
+ targetRect = {
3984
+ x: rect.x,
3985
+ y: rect.y,
3986
+ width: rect.width,
3987
+ height: rect.height
3988
+ };
3989
+ }
3990
+ const popupRect = popupElement.getBoundingClientRect();
3991
+ const {
3992
+ height,
3993
+ width
3994
+ } = win.getComputedStyle(popupElement);
3995
+ popupRect.x = popupRect.x ?? popupRect.left;
3996
+ popupRect.y = popupRect.y ?? popupRect.top;
3997
+ const {
3998
+ clientWidth,
3999
+ clientHeight,
4000
+ scrollWidth,
4001
+ scrollHeight,
4002
+ scrollTop,
4003
+ scrollLeft
4004
+ } = doc.documentElement;
4005
+ const popupHeight = popupRect.height;
4006
+ const popupWidth = popupRect.width;
4007
+ const targetHeight = targetRect.height;
4008
+ const targetWidth = targetRect.width;
4009
+
4010
+ // Get bounding of visible area
4011
+ const visibleRegion = {
4012
+ left: 0,
4013
+ top: 0,
4014
+ right: clientWidth,
4015
+ bottom: clientHeight
4016
+ };
4017
+ const scrollRegion = {
4018
+ left: -scrollLeft,
4019
+ top: -scrollTop,
4020
+ right: scrollWidth - scrollLeft,
4021
+ bottom: scrollHeight - scrollTop
4022
+ };
4023
+ let {
4024
+ htmlRegion
4025
+ } = placementInfo;
4026
+ const VISIBLE = 'visible';
4027
+ const VISIBLE_FIRST = 'visibleFirst';
4028
+ if (htmlRegion !== 'scroll' && htmlRegion !== VISIBLE_FIRST) {
4029
+ htmlRegion = VISIBLE;
4030
+ }
4031
+ const isVisibleFirst = htmlRegion === VISIBLE_FIRST;
4032
+ const scrollRegionArea = getVisibleArea(scrollRegion, scrollerList);
4033
+ const visibleRegionArea = getVisibleArea(visibleRegion, scrollerList);
4034
+ const visibleArea = htmlRegion === VISIBLE ? visibleRegionArea : scrollRegionArea;
4035
+
4036
+ // When set to `visibleFirst`,
4037
+ // the check `adjust` logic will use `visibleRegion` for check first.
4038
+ const adjustCheckVisibleArea = isVisibleFirst ? visibleRegionArea : visibleArea;
4039
+
4040
+ // Record right & bottom align data
4041
+ popupElement.style.left = 'auto';
4042
+ popupElement.style.top = 'auto';
4043
+ popupElement.style.right = '0';
4044
+ popupElement.style.bottom = '0';
4045
+ const popupMirrorRect = popupElement.getBoundingClientRect();
4046
+
4047
+ // Reset back
4048
+ popupElement.style.left = originLeft;
4049
+ popupElement.style.top = originTop;
4050
+ popupElement.style.right = originRight;
4051
+ popupElement.style.bottom = originBottom;
4052
+ popupElement.style.overflow = originOverflow;
4053
+ popupElement.parentElement?.removeChild(placeholderElement);
4054
+
4055
+ // Calculate scale
4056
+ const scaleX = toNum(Math.round(popupWidth / parseFloat(width) * 1000) / 1000);
4057
+ const scaleY = toNum(Math.round(popupHeight / parseFloat(height) * 1000) / 1000);
4058
+
4059
+ // No need to align since it's not visible in view
4060
+ if (scaleX === 0 || scaleY === 0 || isDOM(target) && !isVisible(target)) {
4061
+ return;
4062
+ }
4063
+
4064
+ // Offset
4065
+ const {
4066
+ offset,
4067
+ targetOffset
4068
+ } = placementInfo;
4069
+ let [popupOffsetX, popupOffsetY] = getNumberOffset(popupRect, offset);
4070
+ const [targetOffsetX, targetOffsetY] = getNumberOffset(targetRect, targetOffset);
4071
+ targetRect.x -= targetOffsetX;
4072
+ targetRect.y -= targetOffsetY;
4073
+
4074
+ // Points
4075
+ const [popupPoint, targetPoint] = placementInfo.points || [];
4076
+ const targetPoints = splitPoints(targetPoint);
4077
+ const popupPoints = splitPoints(popupPoint);
4078
+ const targetAlignPoint = getAlignPoint(targetRect, targetPoints);
4079
+ const popupAlignPoint = getAlignPoint(popupRect, popupPoints);
4080
+
4081
+ // Real align info may not same as origin one
4082
+ const nextAlignInfo = {
4083
+ ...placementInfo
4084
+ };
4085
+ let nextPoints = [popupPoints, targetPoints];
4086
+
4087
+ // Next Offset
4088
+ let nextOffsetX = targetAlignPoint.x - popupAlignPoint.x + popupOffsetX;
4089
+ let nextOffsetY = targetAlignPoint.y - popupAlignPoint.y + popupOffsetY;
4090
+
4091
+ // ============== Intersection ===============
4092
+ // Get area by position. Used for check if flip area is better
4093
+ function getIntersectionVisibleArea(offsetX, offsetY, area = visibleArea) {
4094
+ const l = popupRect.x + offsetX;
4095
+ const t = popupRect.y + offsetY;
4096
+ const r = l + popupWidth;
4097
+ const b = t + popupHeight;
4098
+ const visibleL = Math.max(l, area.left);
4099
+ const visibleT = Math.max(t, area.top);
4100
+ const visibleR = Math.min(r, area.right);
4101
+ const visibleB = Math.min(b, area.bottom);
4102
+ return Math.max(0, (visibleR - visibleL) * (visibleB - visibleT));
4103
+ }
4104
+ const originIntersectionVisibleArea = getIntersectionVisibleArea(nextOffsetX, nextOffsetY);
4105
+
4106
+ // As `visibleFirst`, we prepare this for check
4107
+ const originIntersectionRecommendArea = getIntersectionVisibleArea(nextOffsetX, nextOffsetY, visibleRegionArea);
4108
+
4109
+ // ========================== Overflow ===========================
4110
+ const targetAlignPointTL = getAlignPoint(targetRect, ['t', 'l']);
4111
+ const popupAlignPointTL = getAlignPoint(popupRect, ['t', 'l']);
4112
+ const targetAlignPointBR = getAlignPoint(targetRect, ['b', 'r']);
4113
+ const popupAlignPointBR = getAlignPoint(popupRect, ['b', 'r']);
4114
+ const overflow = placementInfo.overflow || {};
4115
+ const {
4116
+ adjustX,
4117
+ adjustY,
4118
+ shiftX,
4119
+ shiftY
4120
+ } = overflow;
4121
+ const supportAdjust = val => {
4122
+ if (typeof val === 'boolean') {
4123
+ return val;
4124
+ }
4125
+ return val >= 0;
4126
+ };
4127
+
4128
+ // Prepare position
4129
+ let nextPopupY;
4130
+ let nextPopupBottom;
4131
+ let nextPopupX;
4132
+ let nextPopupRight;
4133
+ function syncNextPopupPosition() {
4134
+ nextPopupY = popupRect.y + nextOffsetY;
4135
+ nextPopupBottom = nextPopupY + popupHeight;
4136
+ nextPopupX = popupRect.x + nextOffsetX;
4137
+ nextPopupRight = nextPopupX + popupWidth;
4138
+ }
4139
+ syncNextPopupPosition();
4140
+
4141
+ // >>>>>>>>>> Top & Bottom
4142
+ const needAdjustY = supportAdjust(adjustY);
4143
+ const sameTB = popupPoints[0] === targetPoints[0];
4144
+
4145
+ // Bottom to Top
4146
+ if (needAdjustY && popupPoints[0] === 't' && (nextPopupBottom > adjustCheckVisibleArea.bottom || prevFlipRef.current.bt)) {
4147
+ let tmpNextOffsetY = nextOffsetY;
4148
+ if (sameTB) {
4149
+ tmpNextOffsetY -= popupHeight - targetHeight;
4150
+ } else {
4151
+ tmpNextOffsetY = targetAlignPointTL.y - popupAlignPointBR.y - popupOffsetY;
4152
+ }
4153
+ const newVisibleArea = getIntersectionVisibleArea(nextOffsetX, tmpNextOffsetY);
4154
+ const newVisibleRecommendArea = getIntersectionVisibleArea(nextOffsetX, tmpNextOffsetY, visibleRegionArea);
4155
+ if (
4156
+ // Of course use larger one
4157
+ newVisibleArea > originIntersectionVisibleArea || newVisibleArea === originIntersectionVisibleArea && (!isVisibleFirst ||
4158
+ // Choose recommend one
4159
+ newVisibleRecommendArea >= originIntersectionRecommendArea)) {
4160
+ prevFlipRef.current.bt = true;
4161
+ nextOffsetY = tmpNextOffsetY;
4162
+ popupOffsetY = -popupOffsetY;
4163
+ nextPoints = [reversePoints(nextPoints[0], 0), reversePoints(nextPoints[1], 0)];
4164
+ } else {
4165
+ prevFlipRef.current.bt = false;
4166
+ }
4167
+ }
4168
+
4169
+ // Top to Bottom
4170
+ if (needAdjustY && popupPoints[0] === 'b' && (nextPopupY < adjustCheckVisibleArea.top || prevFlipRef.current.tb)) {
4171
+ let tmpNextOffsetY = nextOffsetY;
4172
+ if (sameTB) {
4173
+ tmpNextOffsetY += popupHeight - targetHeight;
4174
+ } else {
4175
+ tmpNextOffsetY = targetAlignPointBR.y - popupAlignPointTL.y - popupOffsetY;
4176
+ }
4177
+ const newVisibleArea = getIntersectionVisibleArea(nextOffsetX, tmpNextOffsetY);
4178
+ const newVisibleRecommendArea = getIntersectionVisibleArea(nextOffsetX, tmpNextOffsetY, visibleRegionArea);
4179
+ if (
4180
+ // Of course use larger one
4181
+ newVisibleArea > originIntersectionVisibleArea || newVisibleArea === originIntersectionVisibleArea && (!isVisibleFirst ||
4182
+ // Choose recommend one
4183
+ newVisibleRecommendArea >= originIntersectionRecommendArea)) {
4184
+ prevFlipRef.current.tb = true;
4185
+ nextOffsetY = tmpNextOffsetY;
4186
+ popupOffsetY = -popupOffsetY;
4187
+ nextPoints = [reversePoints(nextPoints[0], 0), reversePoints(nextPoints[1], 0)];
4188
+ } else {
4189
+ prevFlipRef.current.tb = false;
4190
+ }
4191
+ }
4192
+
4193
+ // >>>>>>>>>> Left & Right
4194
+ const needAdjustX = supportAdjust(adjustX);
4195
+
4196
+ // >>>>> Flip
4197
+ const sameLR = popupPoints[1] === targetPoints[1];
4198
+
4199
+ // Right to Left
4200
+ if (needAdjustX && popupPoints[1] === 'l' && (nextPopupRight > adjustCheckVisibleArea.right || prevFlipRef.current.rl)) {
4201
+ let tmpNextOffsetX = nextOffsetX;
4202
+ if (sameLR) {
4203
+ tmpNextOffsetX -= popupWidth - targetWidth;
4204
+ } else {
4205
+ tmpNextOffsetX = targetAlignPointTL.x - popupAlignPointBR.x - popupOffsetX;
4206
+ }
4207
+ const newVisibleArea = getIntersectionVisibleArea(tmpNextOffsetX, nextOffsetY);
4208
+ const newVisibleRecommendArea = getIntersectionVisibleArea(tmpNextOffsetX, nextOffsetY, visibleRegionArea);
4209
+ if (
4210
+ // Of course use larger one
4211
+ newVisibleArea > originIntersectionVisibleArea || newVisibleArea === originIntersectionVisibleArea && (!isVisibleFirst ||
4212
+ // Choose recommend one
4213
+ newVisibleRecommendArea >= originIntersectionRecommendArea)) {
4214
+ prevFlipRef.current.rl = true;
4215
+ nextOffsetX = tmpNextOffsetX;
4216
+ popupOffsetX = -popupOffsetX;
4217
+ nextPoints = [reversePoints(nextPoints[0], 1), reversePoints(nextPoints[1], 1)];
4218
+ } else {
4219
+ prevFlipRef.current.rl = false;
4220
+ }
4221
+ }
4222
+
4223
+ // Left to Right
4224
+ if (needAdjustX && popupPoints[1] === 'r' && (nextPopupX < adjustCheckVisibleArea.left || prevFlipRef.current.lr)) {
4225
+ let tmpNextOffsetX = nextOffsetX;
4226
+ if (sameLR) {
4227
+ tmpNextOffsetX += popupWidth - targetWidth;
4228
+ } else {
4229
+ tmpNextOffsetX = targetAlignPointBR.x - popupAlignPointTL.x - popupOffsetX;
4230
+ }
4231
+ const newVisibleArea = getIntersectionVisibleArea(tmpNextOffsetX, nextOffsetY);
4232
+ const newVisibleRecommendArea = getIntersectionVisibleArea(tmpNextOffsetX, nextOffsetY, visibleRegionArea);
4233
+ if (
4234
+ // Of course use larger one
4235
+ newVisibleArea > originIntersectionVisibleArea || newVisibleArea === originIntersectionVisibleArea && (!isVisibleFirst ||
4236
+ // Choose recommend one
4237
+ newVisibleRecommendArea >= originIntersectionRecommendArea)) {
4238
+ prevFlipRef.current.lr = true;
4239
+ nextOffsetX = tmpNextOffsetX;
4240
+ popupOffsetX = -popupOffsetX;
4241
+ nextPoints = [reversePoints(nextPoints[0], 1), reversePoints(nextPoints[1], 1)];
4242
+ } else {
4243
+ prevFlipRef.current.lr = false;
4244
+ }
4245
+ }
4246
+ nextAlignInfo.points = [flatPoints(nextPoints[0]), flatPoints(nextPoints[1])];
4247
+
4248
+ // ============================ Shift ============================
4249
+ syncNextPopupPosition();
4250
+ const numShiftX = shiftX === true ? 0 : shiftX;
4251
+ if (typeof numShiftX === 'number') {
4252
+ // Left
4253
+ if (nextPopupX < visibleRegionArea.left) {
4254
+ nextOffsetX -= nextPopupX - visibleRegionArea.left - popupOffsetX;
4255
+ if (targetRect.x + targetWidth < visibleRegionArea.left + numShiftX) {
4256
+ nextOffsetX += targetRect.x - visibleRegionArea.left + targetWidth - numShiftX;
4257
+ }
4258
+ }
4259
+
4260
+ // Right
4261
+ if (nextPopupRight > visibleRegionArea.right) {
4262
+ nextOffsetX -= nextPopupRight - visibleRegionArea.right - popupOffsetX;
4263
+ if (targetRect.x > visibleRegionArea.right - numShiftX) {
4264
+ nextOffsetX += targetRect.x - visibleRegionArea.right + numShiftX;
4265
+ }
4266
+ }
4267
+ }
4268
+ const numShiftY = shiftY === true ? 0 : shiftY;
4269
+ if (typeof numShiftY === 'number') {
4270
+ // Top
4271
+ if (nextPopupY < visibleRegionArea.top) {
4272
+ nextOffsetY -= nextPopupY - visibleRegionArea.top - popupOffsetY;
4273
+
4274
+ // When target if far away from visible area
4275
+ // Stop shift
4276
+ if (targetRect.y + targetHeight < visibleRegionArea.top + numShiftY) {
4277
+ nextOffsetY += targetRect.y - visibleRegionArea.top + targetHeight - numShiftY;
4278
+ }
4279
+ }
4280
+
4281
+ // Bottom
4282
+ if (nextPopupBottom > visibleRegionArea.bottom) {
4283
+ nextOffsetY -= nextPopupBottom - visibleRegionArea.bottom - popupOffsetY;
4284
+ if (targetRect.y > visibleRegionArea.bottom - numShiftY) {
4285
+ nextOffsetY += targetRect.y - visibleRegionArea.bottom + numShiftY;
4286
+ }
4287
+ }
4288
+ }
4289
+
4290
+ // ============================ Arrow ============================
4291
+ // Arrow center align
4292
+ const popupLeft = popupRect.x + nextOffsetX;
4293
+ const popupRight = popupLeft + popupWidth;
4294
+ const popupTop = popupRect.y + nextOffsetY;
4295
+ const popupBottom = popupTop + popupHeight;
4296
+ const targetLeft = targetRect.x;
4297
+ const targetRight = targetLeft + targetWidth;
4298
+ const targetTop = targetRect.y;
4299
+ const targetBottom = targetTop + targetHeight;
4300
+
4301
+ /** Max left of the popup and target element */
4302
+ const maxLeft = Math.max(popupLeft, targetLeft);
4303
+ /** Min right of the popup and target element */
4304
+ const minRight = Math.min(popupRight, targetRight);
4305
+
4306
+ /** The center X of popup & target cross area */
4307
+ const xCenter = (maxLeft + minRight) / 2;
4308
+ /** Arrow X of popup offset */
4309
+ const nextArrowX = xCenter - popupLeft;
4310
+ const maxTop = Math.max(popupTop, targetTop);
4311
+ const minBottom = Math.min(popupBottom, targetBottom);
4312
+ const yCenter = (maxTop + minBottom) / 2;
4313
+ const nextArrowY = yCenter - popupTop;
4314
+ onPopupAlign?.(popupEle, nextAlignInfo);
4315
+
4316
+ // Additional calculate right & bottom position
4317
+ let offsetX4Right = popupMirrorRect.right - popupRect.x - (nextOffsetX + popupRect.width);
4318
+ let offsetY4Bottom = popupMirrorRect.bottom - popupRect.y - (nextOffsetY + popupRect.height);
4319
+ if (scaleX === 1) {
4320
+ nextOffsetX = Math.floor(nextOffsetX);
4321
+ offsetX4Right = Math.floor(offsetX4Right);
4322
+ }
4323
+ if (scaleY === 1) {
4324
+ nextOffsetY = Math.floor(nextOffsetY);
4325
+ offsetY4Bottom = Math.floor(offsetY4Bottom);
4326
+ }
4327
+ const nextOffsetInfo = {
4328
+ ready: true,
4329
+ offsetX: nextOffsetX / scaleX,
4330
+ offsetY: nextOffsetY / scaleY,
4331
+ offsetR: offsetX4Right / scaleX,
4332
+ offsetB: offsetY4Bottom / scaleY,
4333
+ arrowX: nextArrowX / scaleX,
4334
+ arrowY: nextArrowY / scaleY,
4335
+ scaleX,
4336
+ scaleY,
4337
+ align: nextAlignInfo
4338
+ };
4339
+ setOffsetInfo(nextOffsetInfo);
4340
+ }
4341
+ });
4342
+ const triggerAlign = () => {
4343
+ alignCountRef.current += 1;
4344
+ const id = alignCountRef.current;
4345
+
4346
+ // Merge all align requirement into one frame
4347
+ Promise.resolve().then(() => {
4348
+ if (alignCountRef.current === id) {
4349
+ onAlign();
4350
+ }
4351
+ });
4352
+ };
4353
+
4354
+ // Reset ready status when placement & open changed
4355
+ const resetReady = () => {
4356
+ setOffsetInfo(ori => ({
4357
+ ...ori,
4358
+ ready: false
4359
+ }));
4360
+ };
4361
+ useLayoutEffect(resetReady, [placement]);
4362
+ useLayoutEffect(() => {
4363
+ if (!open) {
4364
+ resetReady();
4365
+ }
4366
+ }, [open]);
4367
+ return [offsetInfo.ready, offsetInfo.offsetX, offsetInfo.offsetY, offsetInfo.offsetR, offsetInfo.offsetB, offsetInfo.arrowX, offsetInfo.arrowY, offsetInfo.scaleX, offsetInfo.scaleY, offsetInfo.align, triggerAlign];
4368
+ }
4369
+
4370
+ function useDelay() {
4371
+ const delayRef = React.useRef(null);
4372
+ const clearDelay = () => {
4373
+ if (delayRef.current) {
4374
+ clearTimeout(delayRef.current);
4375
+ delayRef.current = null;
4376
+ }
4377
+ };
4378
+ const delayInvoke = (callback, delay) => {
4379
+ clearDelay();
4380
+ if (delay === 0) {
4381
+ callback();
4382
+ } else {
4383
+ delayRef.current = setTimeout(() => {
4384
+ callback();
4385
+ }, delay * 1000);
4386
+ }
4387
+ };
4388
+
4389
+ // Clean up on unmount
4390
+ React.useEffect(() => {
4391
+ return () => {
4392
+ clearDelay();
4393
+ };
4394
+ }, []);
4395
+ return delayInvoke;
4396
+ }
4397
+
4398
+ function useWatch(open, target, popup, onAlign, onScroll) {
4399
+ useLayoutEffect(() => {
4400
+ if (open && target && popup) {
4401
+ const targetElement = target;
4402
+ const popupElement = popup;
4403
+ const targetScrollList = collectScroller(targetElement);
4404
+ const popupScrollList = collectScroller(popupElement);
4405
+ const win = getWin(popupElement);
4406
+ const mergedList = new Set([win, ...targetScrollList, ...popupScrollList]);
4407
+ function notifyScroll() {
4408
+ onAlign();
4409
+ onScroll();
4410
+ }
4411
+ mergedList.forEach(scroller => {
4412
+ scroller.addEventListener('scroll', notifyScroll, {
4413
+ passive: true
4414
+ });
4415
+ });
4416
+ win.addEventListener('resize', notifyScroll, {
4417
+ passive: true
4418
+ });
4419
+
4420
+ // First time always do align
4421
+ onAlign();
4422
+ return () => {
4423
+ mergedList.forEach(scroller => {
4424
+ scroller.removeEventListener('scroll', notifyScroll);
4425
+ win.removeEventListener('resize', notifyScroll);
4426
+ });
4427
+ };
4428
+ }
4429
+ }, [open, target, popup]);
4430
+ }
4431
+
4432
+ /**
4433
+ * Close if click on the window.
4434
+ * Return the function that click on the Popup element.
4435
+ */
4436
+ function useWinClick(open, clickToHide, targetEle, popupEle, mask, maskClosable, inPopupOrChild, triggerOpen) {
4437
+ const openRef = React.useRef(open);
4438
+ openRef.current = open;
4439
+ const popupPointerDownRef = React.useRef(false);
4440
+
4441
+ // Click to hide is special action since click popup element should not hide
4442
+ React.useEffect(() => {
4443
+ if (clickToHide && popupEle && (!mask || maskClosable)) {
4444
+ const onPointerDown = () => {
4445
+ popupPointerDownRef.current = false;
4446
+ };
4447
+ const onTriggerClose = e => {
4448
+ if (openRef.current && !inPopupOrChild(e.composedPath?.()?.[0] || e.target) && !popupPointerDownRef.current) {
4449
+ triggerOpen(false);
4450
+ }
4451
+ };
4452
+ const win = getWin(popupEle);
4453
+ win.addEventListener('pointerdown', onPointerDown, true);
4454
+ win.addEventListener('mousedown', onTriggerClose, true);
4455
+ win.addEventListener('contextmenu', onTriggerClose, true);
4456
+
4457
+ // shadow root
4458
+ const targetShadowRoot = getShadowRoot(targetEle);
4459
+ if (targetShadowRoot) {
4460
+ targetShadowRoot.addEventListener('mousedown', onTriggerClose, true);
4461
+ targetShadowRoot.addEventListener('contextmenu', onTriggerClose, true);
4462
+ }
4463
+
4464
+ // Warning if target and popup not in same root
4465
+ if (process.env.NODE_ENV !== 'production' && targetEle) {
4466
+ const targetRoot = targetEle.getRootNode?.();
4467
+ const popupRoot = popupEle.getRootNode?.();
4468
+ warning(targetRoot === popupRoot, `trigger element and popup element should in same shadow root.`);
4469
+ }
4470
+ return () => {
4471
+ win.removeEventListener('pointerdown', onPointerDown, true);
4472
+ win.removeEventListener('mousedown', onTriggerClose, true);
4473
+ win.removeEventListener('contextmenu', onTriggerClose, true);
4474
+ if (targetShadowRoot) {
4475
+ targetShadowRoot.removeEventListener('mousedown', onTriggerClose, true);
4476
+ targetShadowRoot.removeEventListener('contextmenu', onTriggerClose, true);
4477
+ }
4478
+ };
4479
+ }
4480
+ }, [clickToHide, targetEle, popupEle, mask, maskClosable]);
4481
+ function onPopupPointerDown() {
4482
+ popupPointerDownRef.current = true;
4483
+ }
4484
+ return onPopupPointerDown;
4485
+ }
4486
+
4487
+ // Removed Props List
4488
+ // Seems this can be auto
4489
+ // getDocument?: (element?: HTMLElement) => Document;
4490
+
4491
+ // New version will not wrap popup with `rc-trigger-popup-content` when multiple children
4492
+
4493
+ function generateTrigger(PortalComponent = Portal) {
4494
+ const Trigger = /*#__PURE__*/React.forwardRef((props, ref) => {
4495
+ const {
4496
+ prefixCls = 'rc-trigger-popup',
4497
+ children,
4498
+ // Action
4499
+ action = 'hover',
4500
+ showAction,
4501
+ hideAction,
4502
+ // Open
4503
+ popupVisible,
4504
+ defaultPopupVisible,
4505
+ onOpenChange,
4506
+ afterOpenChange,
4507
+ onPopupVisibleChange,
4508
+ afterPopupVisibleChange,
4509
+ // Delay
4510
+ mouseEnterDelay,
4511
+ mouseLeaveDelay = 0.1,
4512
+ focusDelay,
4513
+ blurDelay,
4514
+ // Mask
4515
+ mask,
4516
+ maskClosable = true,
4517
+ // Portal
4518
+ getPopupContainer,
4519
+ forceRender,
4520
+ autoDestroy,
4521
+ // Popup
4522
+ popup,
4523
+ popupClassName,
4524
+ uniqueContainerClassName,
4525
+ uniqueContainerStyle,
4526
+ popupStyle,
4527
+ popupPlacement,
4528
+ builtinPlacements = {},
4529
+ popupAlign,
4530
+ zIndex,
4531
+ stretch,
4532
+ getPopupClassNameFromAlign,
4533
+ fresh,
4534
+ unique,
4535
+ alignPoint,
4536
+ onPopupClick,
4537
+ onPopupAlign,
4538
+ // Arrow
4539
+ arrow,
4540
+ // Motion
4541
+ popupMotion,
4542
+ maskMotion,
4543
+ // Private
4544
+ mobile,
4545
+ ...restProps
4546
+ } = props;
4547
+ const mergedAutoDestroy = autoDestroy || false;
4548
+ const openUncontrolled = popupVisible === undefined;
4549
+
4550
+ // =========================== Mobile ===========================
4551
+ const isMobile = !!mobile;
4552
+
4553
+ // ========================== Context ===========================
4554
+ const subPopupElements = React.useRef({});
4555
+ const parentContext = React.useContext(TriggerContext);
4556
+ const context = React.useMemo(() => {
4557
+ return {
4558
+ registerSubPopup: (id, subPopupEle) => {
4559
+ subPopupElements.current[id] = subPopupEle;
4560
+ parentContext?.registerSubPopup(id, subPopupEle);
4561
+ }
4562
+ };
4563
+ }, [parentContext]);
4564
+
4565
+ // ======================== UniqueContext =========================
4566
+ const uniqueContext = React.useContext(UniqueContext);
4567
+
4568
+ // =========================== Popup ============================
4569
+ const id = useId();
4570
+ const [popupEle, setPopupEle] = React.useState(null);
4571
+
4572
+ // Used for forwardRef popup. Not use internal
4573
+ const externalPopupRef = React.useRef(null);
4574
+ const setPopupRef = useEvent(node => {
4575
+ externalPopupRef.current = node;
4576
+ if (isDOM(node) && popupEle !== node) {
4577
+ setPopupEle(node);
4578
+ }
4579
+ parentContext?.registerSubPopup(id, node);
4580
+ });
4581
+
4582
+ // =========================== Target ===========================
4583
+ // Use state to control here since `useRef` update not trigger render
4584
+ const [targetEle, setTargetEle] = React.useState(null);
4585
+
4586
+ // Used for forwardRef target. Not use internal
4587
+ const externalForwardRef = React.useRef(null);
4588
+ const setTargetRef = useEvent(node => {
4589
+ const domNode = getDOM(node);
4590
+ if (isDOM(domNode) && targetEle !== domNode) {
4591
+ setTargetEle(domNode);
4592
+ externalForwardRef.current = domNode;
4593
+ }
4594
+ });
4595
+ const cloneProps = {};
4596
+ const inPopupOrChild = useEvent(ele => {
4597
+ const childDOM = targetEle;
4598
+ return childDOM?.contains(ele) || getShadowRoot(childDOM)?.host === ele || ele === childDOM || popupEle?.contains(ele) || getShadowRoot(popupEle)?.host === ele || ele === popupEle || Object.values(subPopupElements.current).some(subPopupEle => subPopupEle?.contains(ele) || ele === subPopupEle);
4599
+ });
4600
+
4601
+ // =========================== Arrow ============================
4602
+ const innerArrow = arrow ? {
4603
+ // true and Object likely
4604
+ ...(arrow !== true ? arrow : {})
4605
+ } : null;
4606
+
4607
+ // ============================ Open ============================
4608
+ const [internalOpen, setInternalOpen] = useControlledState(defaultPopupVisible || false, popupVisible);
4609
+ const mergedOpen = internalOpen || false;
4610
+
4611
+ // ========================== Children ==========================
4612
+ const child = React.useMemo(() => {
4613
+ const nextChild = typeof children === 'function' ? children({
4614
+ open: mergedOpen
4615
+ }) : children;
4616
+ return React.Children.only(nextChild);
4617
+ }, [children, mergedOpen]);
4618
+ const originChildProps = child?.props || {};
4619
+
4620
+ // Support ref
4621
+ const isOpen = useEvent(() => mergedOpen);
4622
+
4623
+ // Extract common options for UniqueProvider
4624
+ const getUniqueOptions = useEvent((delay = 0) => ({
4625
+ popup,
4626
+ target: targetEle,
4627
+ delay,
4628
+ prefixCls,
4629
+ popupClassName,
4630
+ uniqueContainerClassName,
4631
+ uniqueContainerStyle,
4632
+ popupStyle,
4633
+ popupPlacement,
4634
+ builtinPlacements,
4635
+ popupAlign,
4636
+ zIndex,
4637
+ mask,
4638
+ maskClosable,
4639
+ popupMotion,
4640
+ maskMotion,
4641
+ arrow: innerArrow,
4642
+ getPopupContainer,
4643
+ getPopupClassNameFromAlign,
4644
+ id,
4645
+ onEsc
4646
+ }));
4647
+
4648
+ // Handle controlled state changes for UniqueProvider
4649
+ // Only sync to UniqueProvider when it's controlled mode
4650
+ // If there is a parentContext, don't call uniqueContext methods
4651
+ useLayoutEffect(() => {
4652
+ if (uniqueContext && unique && targetEle && !openUncontrolled && !parentContext) {
4653
+ if (mergedOpen) {
4654
+ uniqueContext.show(getUniqueOptions(mouseEnterDelay), isOpen);
4655
+ } else {
4656
+ uniqueContext.hide(mouseLeaveDelay);
4657
+ }
4658
+ }
4659
+ }, [mergedOpen, targetEle]);
4660
+ const openRef = React.useRef(mergedOpen);
4661
+ openRef.current = mergedOpen;
4662
+ const internalTriggerOpen = useEvent(nextOpen => {
4663
+ flushSync(() => {
4664
+ if (mergedOpen !== nextOpen) {
4665
+ setInternalOpen(nextOpen);
4666
+ onOpenChange?.(nextOpen);
4667
+ onPopupVisibleChange?.(nextOpen);
4668
+ }
4669
+ });
4670
+ });
4671
+
4672
+ // Trigger for delay
4673
+ const delayInvoke = useDelay();
4674
+ const triggerOpen = (nextOpen, delay = 0) => {
4675
+ // If it's controlled mode, always use internal trigger logic
4676
+ // UniqueProvider will be synced through useLayoutEffect
4677
+ if (popupVisible !== undefined) {
4678
+ delayInvoke(() => {
4679
+ internalTriggerOpen(nextOpen);
4680
+ }, delay);
4681
+ return;
4682
+ }
4683
+
4684
+ // If UniqueContext exists and not controlled, pass delay to Provider instead of handling it internally
4685
+ // If there is a parentContext, don't call uniqueContext methods
4686
+ if (uniqueContext && unique && openUncontrolled && !parentContext) {
4687
+ if (nextOpen) {
4688
+ uniqueContext.show(getUniqueOptions(delay), isOpen);
4689
+ } else {
4690
+ uniqueContext.hide(delay);
4691
+ }
4692
+ return;
4693
+ }
4694
+ delayInvoke(() => {
4695
+ internalTriggerOpen(nextOpen);
4696
+ }, delay);
4697
+ };
4698
+ function onEsc({
4699
+ top
4700
+ }) {
4701
+ if (top) {
4702
+ triggerOpen(false);
4703
+ }
4704
+ }
4705
+
4706
+ // ========================== Motion ============================
4707
+ const [inMotion, setInMotion] = React.useState(false);
4708
+ useLayoutEffect(firstMount => {
4709
+ if (!firstMount || mergedOpen) {
4710
+ setInMotion(true);
4711
+ }
4712
+ }, [mergedOpen]);
4713
+ const [motionPrepareResolve, setMotionPrepareResolve] = React.useState(null);
4714
+
4715
+ // =========================== Align ============================
4716
+ const [mousePos, setMousePos] = React.useState(null);
4717
+ const setMousePosByEvent = event => {
4718
+ setMousePos([event.clientX, event.clientY]);
4719
+ };
4720
+ const [ready, offsetX, offsetY, offsetR, offsetB, arrowX, arrowY, scaleX, scaleY, alignInfo, onAlign] = useAlign(mergedOpen, popupEle, alignPoint && mousePos !== null ? mousePos : targetEle, popupPlacement, builtinPlacements, popupAlign, onPopupAlign, isMobile);
4721
+ const [showActions, hideActions] = useAction(action, showAction, hideAction);
4722
+ const clickToShow = showActions.has('click');
4723
+ const clickToHide = hideActions.has('click') || hideActions.has('contextMenu');
4724
+ const triggerAlign = useEvent(() => {
4725
+ if (!inMotion) {
4726
+ onAlign();
4727
+ }
4728
+ });
4729
+ const onScroll = () => {
4730
+ if (openRef.current && alignPoint && clickToHide) {
4731
+ triggerOpen(false);
4732
+ }
4733
+ };
4734
+ useWatch(mergedOpen, targetEle, popupEle, triggerAlign, onScroll);
4735
+ useLayoutEffect(() => {
4736
+ triggerAlign();
4737
+ }, [mousePos, popupPlacement]);
4738
+
4739
+ // When no builtinPlacements and popupAlign changed
4740
+ useLayoutEffect(() => {
4741
+ if (mergedOpen && !builtinPlacements?.[popupPlacement]) {
4742
+ triggerAlign();
4743
+ }
4744
+ }, [JSON.stringify(popupAlign)]);
4745
+ const alignedClassName = React.useMemo(() => {
4746
+ const baseClassName = getAlignPopupClassName(builtinPlacements, prefixCls, alignInfo, alignPoint);
4747
+ return clsx(baseClassName, getPopupClassNameFromAlign?.(alignInfo));
4748
+ }, [alignInfo, getPopupClassNameFromAlign, builtinPlacements, prefixCls, alignPoint]);
4749
+
4750
+ // ============================ Refs ============================
4751
+ React.useImperativeHandle(ref, () => ({
4752
+ nativeElement: externalForwardRef.current,
4753
+ popupElement: externalPopupRef.current,
4754
+ forceAlign: triggerAlign
4755
+ }));
4756
+
4757
+ // ========================== Stretch ===========================
4758
+ const [targetWidth, setTargetWidth] = React.useState(0);
4759
+ const [targetHeight, setTargetHeight] = React.useState(0);
4760
+ const syncTargetSize = () => {
4761
+ if (stretch && targetEle) {
4762
+ const rect = targetEle.getBoundingClientRect();
4763
+ setTargetWidth(rect.width);
4764
+ setTargetHeight(rect.height);
4765
+ }
4766
+ };
4767
+ const onTargetResize = () => {
4768
+ syncTargetSize();
4769
+ triggerAlign();
4770
+ };
4771
+
4772
+ // ========================== Motion ============================
4773
+ const onVisibleChanged = visible => {
4774
+ setInMotion(false);
4775
+ onAlign();
4776
+ afterOpenChange?.(visible);
4777
+ afterPopupVisibleChange?.(visible);
4778
+ };
4779
+
4780
+ // We will trigger align when motion is in prepare
4781
+ const onPrepare = () => new Promise(resolve => {
4782
+ syncTargetSize();
4783
+ setMotionPrepareResolve(() => resolve);
4784
+ });
4785
+ useLayoutEffect(() => {
4786
+ if (motionPrepareResolve) {
4787
+ onAlign();
4788
+ motionPrepareResolve();
4789
+ setMotionPrepareResolve(null);
4790
+ }
4791
+ }, [motionPrepareResolve]);
4792
+
4793
+ // =========================== Action ===========================
4794
+ /**
4795
+ * Util wrapper for trigger action
4796
+ * @param eventName Listen event name
4797
+ * @param nextOpen Next open state after trigger
4798
+ * @param delay Delay to trigger open change
4799
+ * @param callback Callback if current event need additional action
4800
+ * @param ignoreCheck Ignore current event if check return true
4801
+ */
4802
+ function wrapperAction(eventName, nextOpen, delay, callback, ignoreCheck) {
4803
+ cloneProps[eventName] = (event, ...args) => {
4804
+ if (!ignoreCheck || !ignoreCheck()) {
4805
+ callback?.(event);
4806
+ triggerOpen(nextOpen, delay);
4807
+ }
4808
+
4809
+ // Pass to origin
4810
+ originChildProps[eventName]?.(event, ...args);
4811
+ };
4812
+ }
4813
+
4814
+ // ======================= Action: Touch ========================
4815
+ const touchToShow = showActions.has('touch');
4816
+ const touchToHide = hideActions.has('touch');
4817
+
4818
+ /** Used for prevent `hover` event conflict with mobile env */
4819
+ const touchedRef = React.useRef(false);
4820
+ if (touchToShow || touchToHide) {
4821
+ cloneProps.onTouchStart = (...args) => {
4822
+ touchedRef.current = true;
4823
+ if (openRef.current && touchToHide) {
4824
+ triggerOpen(false);
4825
+ } else if (!openRef.current && touchToShow) {
4826
+ triggerOpen(true);
4827
+ }
4828
+
4829
+ // Pass to origin
4830
+ originChildProps.onTouchStart?.(...args);
4831
+ };
4832
+ }
4833
+
4834
+ // ======================= Action: Click ========================
4835
+ if (clickToShow || clickToHide) {
4836
+ cloneProps.onClick = (event, ...args) => {
4837
+ if (openRef.current && clickToHide) {
4838
+ triggerOpen(false);
4839
+ } else if (!openRef.current && clickToShow) {
4840
+ setMousePosByEvent(event);
4841
+ triggerOpen(true);
4842
+ }
4843
+
4844
+ // Pass to origin
4845
+ originChildProps.onClick?.(event, ...args);
4846
+ touchedRef.current = false;
4847
+ };
4848
+ }
4849
+
4850
+ // Click to hide is special action since click popup element should not hide
4851
+ const onPopupPointerDown = useWinClick(mergedOpen, clickToHide || touchToHide, targetEle, popupEle, mask, maskClosable, inPopupOrChild, triggerOpen);
4852
+
4853
+ // ======================= Action: Hover ========================
4854
+ const hoverToShow = showActions.has('hover');
4855
+ const hoverToHide = hideActions.has('hover');
4856
+ let onPopupMouseEnter;
4857
+ let onPopupMouseLeave;
4858
+ const ignoreMouseTrigger = () => {
4859
+ return touchedRef.current;
4860
+ };
4861
+ if (hoverToShow) {
4862
+ const onMouseEnterCallback = event => {
4863
+ setMousePosByEvent(event);
4864
+ };
4865
+
4866
+ // Compatible with old browser which not support pointer event
4867
+ wrapperAction('onMouseEnter', true, mouseEnterDelay, onMouseEnterCallback, ignoreMouseTrigger);
4868
+ wrapperAction('onPointerEnter', true, mouseEnterDelay, onMouseEnterCallback, ignoreMouseTrigger);
4869
+ onPopupMouseEnter = event => {
4870
+ // Only trigger re-open when popup is visible
4871
+ if ((mergedOpen || inMotion) && popupEle?.contains(event.target)) {
4872
+ triggerOpen(true, mouseEnterDelay);
4873
+ }
4874
+ };
4875
+
4876
+ // Align Point
4877
+ if (alignPoint) {
4878
+ cloneProps.onMouseMove = event => {
4879
+ originChildProps.onMouseMove?.(event);
4880
+ };
4881
+ }
4882
+ }
4883
+ if (hoverToHide) {
4884
+ wrapperAction('onMouseLeave', false, mouseLeaveDelay, undefined, ignoreMouseTrigger);
4885
+ wrapperAction('onPointerLeave', false, mouseLeaveDelay, undefined, ignoreMouseTrigger);
4886
+ onPopupMouseLeave = () => {
4887
+ triggerOpen(false, mouseLeaveDelay);
4888
+ };
4889
+ }
4890
+
4891
+ // ======================= Action: Focus ========================
4892
+ if (showActions.has('focus')) {
4893
+ wrapperAction('onFocus', true, focusDelay);
4894
+ }
4895
+ if (hideActions.has('focus')) {
4896
+ wrapperAction('onBlur', false, blurDelay);
4897
+ }
4898
+
4899
+ // ==================== Action: ContextMenu =====================
4900
+ if (showActions.has('contextMenu')) {
4901
+ cloneProps.onContextMenu = (event, ...args) => {
4902
+ if (openRef.current && hideActions.has('contextMenu')) {
4903
+ triggerOpen(false);
4904
+ } else {
4905
+ setMousePosByEvent(event);
4906
+ triggerOpen(true);
4907
+ }
4908
+ event.preventDefault();
4909
+
4910
+ // Pass to origin
4911
+ originChildProps.onContextMenu?.(event, ...args);
4912
+ };
4913
+ }
4914
+
4915
+ // ============================ Perf ============================
4916
+ const rendedRef = React.useRef(false);
4917
+ rendedRef.current ||= forceRender || mergedOpen || inMotion;
4918
+
4919
+ // =========================== Render ===========================
4920
+ const mergedChildrenProps = {
4921
+ ...originChildProps,
4922
+ ...cloneProps
4923
+ };
4924
+
4925
+ // Pass props into cloneProps for nest usage
4926
+ const passedProps = {};
4927
+ const passedEventList = ['onContextMenu', 'onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur'];
4928
+ passedEventList.forEach(eventName => {
4929
+ if (restProps[eventName]) {
4930
+ passedProps[eventName] = (...args) => {
4931
+ mergedChildrenProps[eventName]?.(...args);
4932
+ restProps[eventName](...args);
4933
+ };
4934
+ }
4935
+ });
4936
+ const arrowPos = {
4937
+ x: arrowX,
4938
+ y: arrowY
4939
+ };
4940
+
4941
+ // =================== Resize Observer ===================
4942
+ // Use hook to observe target element resize
4943
+ // Pass targetEle directly instead of a function so the hook will re-observe when target changes
4944
+ useResizeObserver(mergedOpen, targetEle, onTargetResize);
4945
+
4946
+ // Compose refs
4947
+ const mergedRef = useComposeRef(setTargetRef, getNodeRef(child));
4948
+
4949
+ // Child Node
4950
+ const triggerNode = /*#__PURE__*/React.cloneElement(child, {
4951
+ ...mergedChildrenProps,
4952
+ ...passedProps,
4953
+ ref: mergedRef
4954
+ });
4955
+
4956
+ // Render
4957
+ return /*#__PURE__*/React.createElement(React.Fragment, null, triggerNode, rendedRef.current && (!uniqueContext || !unique) && /*#__PURE__*/React.createElement(TriggerContext.Provider, {
4958
+ value: context
4959
+ }, /*#__PURE__*/React.createElement(Popup, {
4960
+ portal: PortalComponent,
4961
+ ref: setPopupRef,
4962
+ prefixCls: prefixCls,
4963
+ popup: popup,
4964
+ className: clsx(popupClassName, !isMobile && alignedClassName),
4965
+ style: popupStyle,
4966
+ target: targetEle,
4967
+ onMouseEnter: onPopupMouseEnter,
4968
+ onMouseLeave: onPopupMouseLeave
4969
+ // https://github.com/ant-design/ant-design/issues/43924
4970
+ ,
4971
+ onPointerEnter: onPopupMouseEnter,
4972
+ zIndex: zIndex
4973
+ // Open
4974
+ ,
4975
+ open: mergedOpen,
4976
+ keepDom: inMotion,
4977
+ fresh: fresh
4978
+ // Click
4979
+ ,
4980
+ onClick: onPopupClick,
4981
+ onPointerDownCapture: onPopupPointerDown
4982
+ // Mask
4983
+ ,
4984
+ mask: mask
4985
+ // Motion
4986
+ ,
4987
+ motion: popupMotion,
4988
+ maskMotion: maskMotion,
4989
+ onVisibleChanged: onVisibleChanged,
4990
+ onPrepare: onPrepare
4991
+ // Portal
4992
+ ,
4993
+ forceRender: forceRender,
4994
+ autoDestroy: mergedAutoDestroy,
4995
+ getPopupContainer: getPopupContainer,
4996
+ onEsc: onEsc
4997
+ // Arrow
4998
+ ,
4999
+ align: alignInfo,
5000
+ arrow: innerArrow,
5001
+ arrowPos: arrowPos
5002
+ // Align
5003
+ ,
5004
+ ready: ready,
5005
+ offsetX: offsetX,
5006
+ offsetY: offsetY,
5007
+ offsetR: offsetR,
5008
+ offsetB: offsetB,
5009
+ onAlign: triggerAlign
5010
+ // Stretch
5011
+ ,
5012
+ stretch: stretch,
5013
+ targetWidth: targetWidth / scaleX,
5014
+ targetHeight: targetHeight / scaleY
5015
+ // Mobile
5016
+ ,
5017
+ mobile: mobile
5018
+ })));
5019
+ });
5020
+ if (process.env.NODE_ENV !== 'production') {
5021
+ Trigger.displayName = 'Trigger';
5022
+ }
5023
+ return Trigger;
5024
+ }
5025
+ generateTrigger(Portal);
5026
+
1378
5027
  const byteToHex = [];
1379
5028
  for (let i = 0; i < 256; ++i) {
1380
5029
  byteToHex.push((i + 0x100).toString(16).slice(1));
@@ -4191,7 +7840,7 @@ function InlineSVG(props) {
4191
7840
  }
4192
7841
 
4193
7842
  const useAppearanceConfig = (appearance, componentConfig, isDisabled) => {
4194
- const appearanceConfig = useMemo(() => {
7843
+ const appearanceConfig = useMemo$1(() => {
4195
7844
  if (appearance) {
4196
7845
  const appearanceProps = appearance.split(' ').reduce((resultConfig, appearanceKey) => ({
4197
7846
  ...resultConfig,
@@ -4284,7 +7933,7 @@ function NotificationsProvider(props) {
4284
7933
  // "hideNotifications" is never changed
4285
7934
  // eslint-disable-next-line react-hooks/exhaustive-deps
4286
7935
  []);
4287
- const notificationsAPI = useMemo(() => ({
7936
+ const notificationsAPI = useMemo$1(() => ({
4288
7937
  hideNotifications: hideNotifications,
4289
7938
  notificationStatuses: STATUSES,
4290
7939
  showNotification: showNotification,
@@ -4485,7 +8134,7 @@ function useMediaQueries(userDevice = {}) {
4485
8134
  const isDesktopMega = useMediaQuery({
4486
8135
  minWidth: mediaQueries['desktop-huge']
4487
8136
  });
4488
- const deviceTypes = useMemo(() => ({
8137
+ const deviceTypes = useMemo$1(() => ({
4489
8138
  // isWarning,
4490
8139
  isMobile: isMobile,
4491
8140
  // isMobileTiny,
@@ -4553,7 +8202,7 @@ const UIProvider = memo(function UIProvider(props) {
4553
8202
  (isTablet && 'tablet') ||
4554
8203
  (isDesktop && 'desktop') ||
4555
8204
  '';
4556
- const [deviceCurrentType, deviceTypesList] = useMemo(() => {
8205
+ const [deviceCurrentType, deviceTypesList] = useMemo$1(() => {
4557
8206
  const deviceTypesList = Object.keys(allDevicesTypes).map((key) => camelCase(key.replace('is', '')));
4558
8207
  // In same time "allDevicesTypes" can contain "isMobile" and "isMobileLarge" as true
4559
8208
  let deviceCurrentType = Object.keys(fullNamedDeviceTypes).find(
@@ -4567,7 +8216,7 @@ const UIProvider = memo(function UIProvider(props) {
4567
8216
  // On server side render we doesn't known user device and we need to set special word
4568
8217
  return [deviceCurrentType || '_none_', deviceTypesList];
4569
8218
  }, [allDevicesTypes, deviceCurrentMainType, fullNamedDeviceTypes]);
4570
- const deviceContextState = useMemo(() => {
8219
+ const deviceContextState = useMemo$1(() => {
4571
8220
  return {
4572
8221
  ...allDevicesTypes,
4573
8222
  deviceCurrentMainType: deviceCurrentMainType,
@@ -4758,7 +8407,7 @@ var styleAttributes = [
4758
8407
  */
4759
8408
  'backdropFilter',
4760
8409
  /**
4761
- * transition
8410
+ * Transition
4762
8411
  */
4763
8412
  'transition',
4764
8413
  'transitionBehavior',
@@ -4766,6 +8415,10 @@ var styleAttributes = [
4766
8415
  'transitionDuration',
4767
8416
  'transitionProperty',
4768
8417
  'transitionTimingFunction',
8418
+ /**
8419
+ * Control
8420
+ */
8421
+ 'pointerEvents',
4769
8422
  ];
4770
8423
 
4771
8424
  function useDevicePropsGenerator(componentProps, appearanceConfig) {
@@ -4803,7 +8456,7 @@ function useDevicePropsGenerator(componentProps, appearanceConfig) {
4803
8456
  * ---------
4804
8457
  **/
4805
8458
  const { deviceCurrentMainType } = useUserDeviceContext();
4806
- const devicePropsGenerator = useMemo(() => {
8459
+ const devicePropsGenerator = useMemo$1(() => {
4807
8460
  const propsGenerator = {
4808
8461
  getProp(propKey) {
4809
8462
  const propsForDeviceKey = `${propKey}${upperFirst(deviceCurrentMainType)}`;
@@ -4892,7 +8545,7 @@ function useDevicePropsGenerator(componentProps, appearanceConfig) {
4892
8545
  */
4893
8546
  function useStyles(props) {
4894
8547
  const { deviceCurrentMainType, deviceCurrentType, deviceTypesList } = useUserDeviceContext();
4895
- const propsStyleAttributes = useMemo(() => {
8548
+ const propsStyleAttributes = useMemo$1(() => {
4896
8549
  const styles = Object.entries(props).reduce((result, [propKey, propValue]) => {
4897
8550
  const styleAttributeKey = getTargetStyleAttributeKey(propKey, propValue);
4898
8551
  if (styleAttributeKey) {
@@ -4903,7 +8556,7 @@ function useStyles(props) {
4903
8556
  return styles;
4904
8557
  // "props" object maybe big and frequently changing
4905
8558
  }, [props]);
4906
- const collectedStyles = useMemo(() => {
8559
+ const collectedStyles = useMemo$1(() => {
4907
8560
  const resultStylesGroups = {};
4908
8561
  for (const [propKey, propValue] of Object.entries(propsStyleAttributes)) {
4909
8562
  let value = null;
@@ -5599,7 +9252,7 @@ function Title(props) {
5599
9252
  const propsGenerator = useDevicePropsGenerator(props, appearanceConfig);
5600
9253
  const { directionClass, size, fillClass, fillHoverClass, textAlignClass, textColorActiveClass, textColorActiveHoverClass, textColorClass, textColorDisabledClass, textColorHoverClass, textFontClass, textStyleClass, textTruncateClass, textWeightClass, textWrap, heightClass, iconAfter, iconAfterFill, iconAfterFillIcon, iconAfterFillSize, iconAfterShape, iconAfterSize, iconAfterSrc, iconBadgeAppearance, iconBadgeShape, iconBadgeSize, iconBadgeTextColor, iconBadgeTextSize, iconBadgeValue, iconBefore, iconBeforeFill, iconBeforeFillIcon, iconBeforeFillSize, iconBeforeShape, iconBeforeSize, iconBeforeSrc, svgFillClass, svgFillHoverClass, widthClass, wrapperDirectionClass, onClickIconAfter, onClickIconBefore, } = propsGenerator;
5601
9254
  const { styles: titleStyles, wrapper: titleWrapperStyles } = useStyles(props);
5602
- const Tag = useMemo(() => {
9255
+ const Tag = useMemo$1(() => {
5603
9256
  if (tag) {
5604
9257
  return tag;
5605
9258
  }
@@ -5645,8 +9298,8 @@ const tooltipAppearanceError = {
5645
9298
  errorPrimary: {
5646
9299
  fill: 'errorPrimary',
5647
9300
  fillHover: 'errorHoverPrimary',
5648
- borderColor: 'errorBorderPrimary',
5649
9301
  titleColor: 'errorTextPrimary',
9302
+ borderColor: 'errorBorderPrimary',
5650
9303
  textColor: 'errorTextPrimary',
5651
9304
  },
5652
9305
  };
@@ -5655,8 +9308,8 @@ const tooltipAppearanceRequire = {
5655
9308
  requirePrimary: {
5656
9309
  fill: 'warningPrimary',
5657
9310
  fillHover: 'warningHoverPrimary',
5658
- borderColor: 'warningBorderPrimary',
5659
9311
  titleColor: 'warningTextPrimary',
9312
+ borderColor: 'warningBorderPrimary',
5660
9313
  textColor: 'warningTextPrimary',
5661
9314
  },
5662
9315
  };
@@ -5722,8 +9375,8 @@ const tooltipAppearanceSuccess = {
5722
9375
  successPrimary: {
5723
9376
  fill: 'successPrimary',
5724
9377
  fillHover: 'successHoverPrimary',
5725
- borderColor: 'successBorderPrimary',
5726
9378
  titleColor: 'successTextPrimary',
9379
+ borderColor: 'successBorderPrimary',
5727
9380
  textColor: 'successTextPrimary',
5728
9381
  },
5729
9382
  };
@@ -5742,7 +9395,7 @@ const tooltipAppearance = {
5742
9395
  const tooltipConfig = {
5743
9396
  appearance: tooltipAppearance};
5744
9397
  const Tooltip = React__default.forwardRef(function Tooltip(props, ref) {
5745
- const { appearance, className, dataTestId, dataTour, initialIsVisible, title, text, before, after, openTimeoutDelay = 500, closeTimeoutDelay = 250, isSkeleton, isTooltipDisableState, children, } = props;
9398
+ const { appearance, className, dataTestId, dataTour, initialIsVisible, title, text, before, after, openTimeoutDelay = 500, closeTimeoutDelay = 250, isSkeleton, children, } = props;
5746
9399
  const tooltipElementRef = useRef(null);
5747
9400
  const tooltipTimeoutHideRef = useRef(null);
5748
9401
  const tooltipTimeoutShowRef = useRef(null);
@@ -5785,13 +9438,9 @@ const Tooltip = React__default.forwardRef(function Tooltip(props, ref) {
5785
9438
  }), [isTooltipVisible, openTooltip, closeTooltip]);
5786
9439
  const appearanceConfig = useAppearanceConfig(appearance, tooltipConfig);
5787
9440
  const propsGenerator = useDevicePropsGenerator(props, appearanceConfig);
5788
- const { alignClass, alignDirectionClass, alignmentClass, alignPosition, fillClass, titleColor, titleSize, titleWeight, borderColorClass, borderTypeClass, borderWidthClass, textColor, textSize, textWeight, arrowPosition, centeringClass, elevationClass, shapeClass, shapeStrengthClass, sizeClass, widthClass, } = propsGenerator;
9441
+ const { alignClass, alignDirectionClass, alignmentClass, alignPosition, fillClass, titleColor, titleSize, titleWeight, borderColorClass, borderTypeClass, borderWidthClass, textColor, textSize, textWeight, arrowPosition, elevationClass, shapeClass, shapeStrengthClass, sizeClass, widthClass, } = propsGenerator;
5789
9442
  const { styles: tooltipStyles } = useStyles(props);
5790
- return (jsxRuntimeExports.jsxs("div", { className: clsx(className, 'tooltip', !isTooltipDisableState
5791
- ? isTooltipVisible
5792
- ? 'tooltip_state_open'
5793
- : 'tooltip_state_close'
5794
- : null, alignPosition && `tooltip_align-position_${alignPosition}`, alignDirectionClass && `align_${alignDirectionClass}`, alignClass && `align_${alignClass}`, elevationClass && `elevation_${elevationClass}`, centeringClass && `centering_${centeringClass}`, alignmentClass && `alignment_${alignmentClass}`, sizeClass && `tooltip_size_${sizeClass}`, isSkeleton && 'tooltip_skeleton', widthClass && `width_${widthClass}`), ref: tooltipElementRef, "data-testid": dataTestId, "data-tour": dataTour, style: tooltipStyles, onAnimationEnd: onAnimationEnd, children: [arrowPosition && (jsxRuntimeExports.jsx("div", { className: clsx('tooltip__arrow', arrowPosition && `tooltip__arrow_position_${arrowPosition}`, fillClass && `fill_${fillClass}`), children: "\u00A0" })), before, jsxRuntimeExports.jsxs("div", { className: clsx('tooltip__inner', borderWidthClass && `border-width_${borderWidthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderTypeClass && `border_type_${borderTypeClass}`, fillClass && `fill_${fillClass}`, shapeClass && `shape_${shapeClass}`, shapeStrengthClass && `shape-strength_${shapeStrengthClass}`), children: [title && (jsxRuntimeExports.jsx(Title, { className: "tooltip__title text", size: titleSize, textColor: titleColor, textWeight: titleWeight, children: title })), text && (jsxRuntimeExports.jsx(Text, { className: "tooltip__text", size: textSize, textColor: textColor, textWeight: textWeight, children: text })), children] }), after] }));
9443
+ return (jsxRuntimeExports.jsxs("div", { className: clsx(className, 'tooltip', alignPosition && `tooltip_align-position_${alignPosition}`, alignDirectionClass && `align_${alignDirectionClass}`, alignClass && `align_${alignClass}`, elevationClass && `elevation_${elevationClass}`, alignmentClass && `alignment_${alignmentClass}`, sizeClass && `tooltip_size_${sizeClass}`, isSkeleton && 'tooltip_skeleton', widthClass && `width_${widthClass}`), ref: tooltipElementRef, "data-testid": dataTestId, "data-tour": dataTour, style: tooltipStyles, onAnimationEnd: onAnimationEnd, children: [arrowPosition && (jsxRuntimeExports.jsx("div", { className: clsx('tooltip__arrow', arrowPosition && `tooltip__arrow_position_${arrowPosition}`, fillClass && `fill_${fillClass}`), children: "\u00A0" })), before, jsxRuntimeExports.jsxs("div", { className: clsx('tooltip__inner', borderWidthClass && `border-width_${borderWidthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderTypeClass && `border_type_${borderTypeClass}`, fillClass && `fill_${fillClass}`, shapeClass && `shape_${shapeClass}`, shapeStrengthClass && `shape-strength_${shapeStrengthClass}`), children: [title && (jsxRuntimeExports.jsx(Title, { className: "tooltip__title text", size: titleSize, textColor: titleColor, textWeight: titleWeight, children: title })), text && (jsxRuntimeExports.jsx(Text, { className: "tooltip__text", size: textSize, textColor: textColor, textWeight: textWeight, children: text })), children] }), after] }));
5795
9444
  });
5796
9445
 
5797
9446
  const UrlAssetPrefixContext = createContext({
@@ -6226,7 +9875,7 @@ const iconConfig = {
6226
9875
  appearance: iconAppearance};
6227
9876
  const Icon = urlWithAssetPrefix(React__default.forwardRef(function Icon(props, ref) {
6228
9877
  const { id, appearance, className, dataTestId, dataTour, width, height, badgeClass, href, imageSrc, link, linkRel, linkTarget, notification, saveFillStroke, showTooltip, SvgImage, svgImageStyles, before, after, isActive, isDisabled, isSkeleton, onClick, onMouseEnter, onMouseLeave, } = props;
6229
- const ImageComponent = useMemo(() => {
9878
+ const ImageComponent = useMemo$1(() => {
6230
9879
  if (SvgImage) {
6231
9880
  const SvgComponent = SvgImage;
6232
9881
  const sizes = {};