useKeyRecords.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  2. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  3. import * as React from 'react';
  4. import { useRef, useCallback } from 'react';
  5. import warning from "rc-util/es/warning";
  6. import { nextSlice } from "../utils/timeUtil";
  7. var PATH_SPLIT = '__RC_UTIL_PATH_SPLIT__';
  8. var getPathStr = function getPathStr(keyPath) {
  9. return keyPath.join(PATH_SPLIT);
  10. };
  11. var getPathKeys = function getPathKeys(keyPathStr) {
  12. return keyPathStr.split(PATH_SPLIT);
  13. };
  14. export var OVERFLOW_KEY = 'rc-menu-more';
  15. export default function useKeyRecords() {
  16. var _React$useState = React.useState({}),
  17. _React$useState2 = _slicedToArray(_React$useState, 2),
  18. internalForceUpdate = _React$useState2[1];
  19. var key2pathRef = useRef(new Map());
  20. var path2keyRef = useRef(new Map());
  21. var _React$useState3 = React.useState([]),
  22. _React$useState4 = _slicedToArray(_React$useState3, 2),
  23. overflowKeys = _React$useState4[0],
  24. setOverflowKeys = _React$useState4[1];
  25. var updateRef = useRef(0);
  26. var destroyRef = useRef(false);
  27. var forceUpdate = function forceUpdate() {
  28. if (!destroyRef.current) {
  29. internalForceUpdate({});
  30. }
  31. };
  32. var registerPath = useCallback(function (key, keyPath) {
  33. // Warning for invalidate or duplicated `key`
  34. if (process.env.NODE_ENV !== 'production') {
  35. warning(!key2pathRef.current.has(key), "Duplicated key '".concat(key, "' used in Menu by path [").concat(keyPath.join(' > '), "]"));
  36. }
  37. // Fill map
  38. var connectedPath = getPathStr(keyPath);
  39. path2keyRef.current.set(connectedPath, key);
  40. key2pathRef.current.set(key, connectedPath);
  41. updateRef.current += 1;
  42. var id = updateRef.current;
  43. nextSlice(function () {
  44. if (id === updateRef.current) {
  45. forceUpdate();
  46. }
  47. });
  48. }, []);
  49. var unregisterPath = useCallback(function (key, keyPath) {
  50. var connectedPath = getPathStr(keyPath);
  51. path2keyRef.current.delete(connectedPath);
  52. key2pathRef.current.delete(key);
  53. }, []);
  54. var refreshOverflowKeys = useCallback(function (keys) {
  55. setOverflowKeys(keys);
  56. }, []);
  57. var getKeyPath = useCallback(function (eventKey, includeOverflow) {
  58. var fullPath = key2pathRef.current.get(eventKey) || '';
  59. var keys = getPathKeys(fullPath);
  60. if (includeOverflow && overflowKeys.includes(keys[0])) {
  61. keys.unshift(OVERFLOW_KEY);
  62. }
  63. return keys;
  64. }, [overflowKeys]);
  65. var isSubPathKey = useCallback(function (pathKeys, eventKey) {
  66. return pathKeys.filter(function (item) {
  67. return item !== undefined;
  68. }).some(function (pathKey) {
  69. var pathKeyList = getKeyPath(pathKey, true);
  70. return pathKeyList.includes(eventKey);
  71. });
  72. }, [getKeyPath]);
  73. var getKeys = function getKeys() {
  74. var keys = _toConsumableArray(key2pathRef.current.keys());
  75. if (overflowKeys.length) {
  76. keys.push(OVERFLOW_KEY);
  77. }
  78. return keys;
  79. };
  80. /**
  81. * Find current key related child path keys
  82. */
  83. var getSubPathKeys = useCallback(function (key) {
  84. var connectedPath = "".concat(key2pathRef.current.get(key)).concat(PATH_SPLIT);
  85. var pathKeys = new Set();
  86. _toConsumableArray(path2keyRef.current.keys()).forEach(function (pathKey) {
  87. if (pathKey.startsWith(connectedPath)) {
  88. pathKeys.add(path2keyRef.current.get(pathKey));
  89. }
  90. });
  91. return pathKeys;
  92. }, []);
  93. React.useEffect(function () {
  94. return function () {
  95. destroyRef.current = true;
  96. };
  97. }, []);
  98. return {
  99. // Register
  100. registerPath: registerPath,
  101. unregisterPath: unregisterPath,
  102. refreshOverflowKeys: refreshOverflowKeys,
  103. // Util
  104. isSubPathKey: isSubPathKey,
  105. getKeyPath: getKeyPath,
  106. getKeys: getKeys,
  107. getSubPathKeys: getSubPathKeys
  108. };
  109. }