useResize.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = useResize;
  8. var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
  9. var React = _interopRequireWildcard(require("react"));
  10. var _useSizes = require("./useSizes");
  11. /**
  12. * Handle user drag resize logic.
  13. */
  14. function useResize(items, resizableInfos, percentSizes, containerSize, updateSizes, isRTL) {
  15. const limitSizes = items.map(item => [item.min, item.max]);
  16. const mergedContainerSize = containerSize || 0;
  17. const ptg2px = ptg => ptg * mergedContainerSize;
  18. // ======================== Resize ========================
  19. function getLimitSize(str, defaultLimit) {
  20. if (typeof str === 'string') {
  21. return ptg2px((0, _useSizes.getPtg)(str));
  22. }
  23. return str !== null && str !== void 0 ? str : defaultLimit;
  24. }
  25. // Real px sizes
  26. const [cacheSizes, setCacheSizes] = React.useState([]);
  27. const cacheCollapsedSize = React.useRef([]);
  28. /**
  29. * When start drag, check the direct is `start` or `end`.
  30. * This will handle when 2 splitter bar are in the same position.
  31. */
  32. const [movingIndex, setMovingIndex] = React.useState(null);
  33. const getPxSizes = () => percentSizes.map(ptg2px);
  34. const onOffsetStart = index => {
  35. setCacheSizes(getPxSizes());
  36. setMovingIndex({
  37. index,
  38. confirmed: false
  39. });
  40. };
  41. const onOffsetUpdate = (index, offset) => {
  42. var _a;
  43. // First time trigger move index update is not sync in the state
  44. let confirmedIndex = null;
  45. // We need to know what the real index is.
  46. if ((!movingIndex || !movingIndex.confirmed) && offset !== 0) {
  47. // Search for the real index
  48. if (offset > 0) {
  49. confirmedIndex = index;
  50. setMovingIndex({
  51. index,
  52. confirmed: true
  53. });
  54. } else {
  55. for (let i = index; i >= 0; i -= 1) {
  56. if (cacheSizes[i] > 0 && resizableInfos[i].resizable) {
  57. confirmedIndex = i;
  58. setMovingIndex({
  59. index: i,
  60. confirmed: true
  61. });
  62. break;
  63. }
  64. }
  65. }
  66. }
  67. const mergedIndex = (_a = confirmedIndex !== null && confirmedIndex !== void 0 ? confirmedIndex : movingIndex === null || movingIndex === void 0 ? void 0 : movingIndex.index) !== null && _a !== void 0 ? _a : index;
  68. const numSizes = (0, _toConsumableArray2.default)(cacheSizes);
  69. const nextIndex = mergedIndex + 1;
  70. // Get boundary
  71. const startMinSize = getLimitSize(limitSizes[mergedIndex][0], 0);
  72. const endMinSize = getLimitSize(limitSizes[nextIndex][0], 0);
  73. const startMaxSize = getLimitSize(limitSizes[mergedIndex][1], mergedContainerSize);
  74. const endMaxSize = getLimitSize(limitSizes[nextIndex][1], mergedContainerSize);
  75. let mergedOffset = offset;
  76. // Align with the boundary
  77. if (numSizes[mergedIndex] + mergedOffset < startMinSize) {
  78. mergedOffset = startMinSize - numSizes[mergedIndex];
  79. }
  80. if (numSizes[nextIndex] - mergedOffset < endMinSize) {
  81. mergedOffset = numSizes[nextIndex] - endMinSize;
  82. }
  83. if (numSizes[mergedIndex] + mergedOffset > startMaxSize) {
  84. mergedOffset = startMaxSize - numSizes[mergedIndex];
  85. }
  86. if (numSizes[nextIndex] - mergedOffset > endMaxSize) {
  87. mergedOffset = numSizes[nextIndex] - endMaxSize;
  88. }
  89. // Do offset
  90. numSizes[mergedIndex] += mergedOffset;
  91. numSizes[nextIndex] -= mergedOffset;
  92. updateSizes(numSizes);
  93. return numSizes;
  94. };
  95. const onOffsetEnd = () => {
  96. setMovingIndex(null);
  97. };
  98. // ======================= Collapse =======================
  99. const onCollapse = (index, type) => {
  100. const currentSizes = getPxSizes();
  101. const adjustedType = isRTL ? type === 'start' ? 'end' : 'start' : type;
  102. const currentIndex = adjustedType === 'start' ? index : index + 1;
  103. const targetIndex = adjustedType === 'start' ? index + 1 : index;
  104. const currentSize = currentSizes[currentIndex];
  105. const targetSize = currentSizes[targetIndex];
  106. if (currentSize !== 0 && targetSize !== 0) {
  107. // Collapse directly
  108. currentSizes[currentIndex] = 0;
  109. currentSizes[targetIndex] += currentSize;
  110. cacheCollapsedSize.current[index] = currentSize;
  111. } else {
  112. const totalSize = currentSize + targetSize;
  113. const currentSizeMin = getLimitSize(limitSizes[currentIndex][0], 0);
  114. const currentSizeMax = getLimitSize(limitSizes[currentIndex][1], mergedContainerSize);
  115. const targetSizeMin = getLimitSize(limitSizes[targetIndex][0], 0);
  116. const targetSizeMax = getLimitSize(limitSizes[targetIndex][1], mergedContainerSize);
  117. const limitStart = Math.max(currentSizeMin, totalSize - targetSizeMax);
  118. const limitEnd = Math.min(currentSizeMax, totalSize - targetSizeMin);
  119. const halfOffset = targetSizeMin || (limitEnd - limitStart) / 2;
  120. const targetCacheCollapsedSize = cacheCollapsedSize.current[index];
  121. const currentCacheCollapsedSize = totalSize - targetCacheCollapsedSize;
  122. const shouldUseCache = targetCacheCollapsedSize && targetCacheCollapsedSize <= targetSizeMax && targetCacheCollapsedSize >= targetSizeMin && currentCacheCollapsedSize <= currentSizeMax && currentCacheCollapsedSize >= currentSizeMin;
  123. if (shouldUseCache) {
  124. currentSizes[targetIndex] = targetCacheCollapsedSize;
  125. currentSizes[currentIndex] = currentCacheCollapsedSize;
  126. } else {
  127. currentSizes[currentIndex] -= halfOffset;
  128. currentSizes[targetIndex] += halfOffset;
  129. }
  130. }
  131. updateSizes(currentSizes);
  132. return currentSizes;
  133. };
  134. return [onOffsetStart, onOffsetUpdate, onOffsetEnd, onCollapse, movingIndex === null || movingIndex === void 0 ? void 0 : movingIndex.index];
  135. }