UNPKG

@antmjs/vantui

Version:

一套适用于Taro3及React的vantui组件库

225 lines (218 loc) 10.5 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; var _excluded = ["height"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import { useEffect, useMemo, useRef } from 'react'; import { useNextTick } from './hooks/useNextTick'; import { useForceUpdate, usePersistFn } from './hooks'; /** * @description 当某一项的size变化时的回调 * @param item 变化的项 * @param size 变化后的size */ /** * @description 当某一项被移除时的回调 * @param item 被移除的项 */ export var useWaterfallAttributes = function useWaterfallAttributes(columnNum, gutter) { var forceUpdate = useForceUpdate(); var _useMemo = useMemo(function () { if (Array.isArray(gutter)) { return gutter; } if (typeof gutter === 'number') { return [gutter, gutter]; } return [0, 0]; }, [gutter]), _useMemo2 = _slicedToArray(_useMemo, 2), horizontalGutter = _useMemo2[0], verticalGutter = _useMemo2[1]; // 记录每一项的位置信息 var attributesRef = useRef(new Map()); var columnsRef = useRef(_toConsumableArray(Array(columnNum)).map(function () { return { height: 0, items: [] }; })); // 一个队列,用来存储各个元素的尺寸变化,然后统一计算更新,Taro.nextTick? var initItemsQueueRef = useRef([]); var itemResizeStatusRef = useRef(new Map()); useEffect(function () { attributesRef.current = new Map(); columnsRef.current = _toConsumableArray(Array(columnNum)).map(function () { return { height: 0, items: [] }; }); forceUpdate(); }, [columnNum, forceUpdate]); var initItem = usePersistFn(function (item, size) { var columnHeights = columnsRef.current.map(function (column) { return column.height; }); var minHeight = Math.min.apply(Math, _toConsumableArray(columnHeights)); var minHeightIndex = columnHeights.indexOf(minHeight); var increaseHeight = minHeight ? verticalGutter : 0; attributesRef.current.set(item.key, { // 计算每一项的位置、宽高、列索引 key: item.key, left: minHeightIndex * (size.width + horizontalGutter), top: minHeight + increaseHeight, width: size.width, height: size.height, columnIndex: minHeightIndex }); columnsRef.current[minHeightIndex].height += size.height + increaseHeight; columnsRef.current[minHeightIndex].items.push(item.key); }); // 初始化 useNextTick(function () { var _initItemsQueueRef$cu; var hasInit = ((_initItemsQueueRef$cu = initItemsQueueRef.current) === null || _initItemsQueueRef$cu === void 0 ? void 0 : _initItemsQueueRef$cu.length) > 0; while (((_initItemsQueueRef$cu2 = initItemsQueueRef.current) === null || _initItemsQueueRef$cu2 === void 0 ? void 0 : _initItemsQueueRef$cu2.length) > 0) { var _initItemsQueueRef$cu2, _initItemsQueueRef$cu3; var _ref = (_initItemsQueueRef$cu3 = initItemsQueueRef.current.shift()) !== null && _initItemsQueueRef$cu3 !== void 0 ? _initItemsQueueRef$cu3 : {}, _item = _ref.item, _size = _ref.size; initItem(_item, _size); } hasInit && forceUpdate(); }); var refreshColumns = usePersistFn(function (item, size) { var _attributesRef$curren; var positionItem = attributesRef.current.get(item === null || item === void 0 ? void 0 : item.key); if (typeof (positionItem === null || positionItem === void 0 ? void 0 : positionItem.columnIndex) !== 'number') { return; } // 计算出当前项在所在列的索引,然后更新该列的高度 var columnIndex = positionItem.columnIndex; var _ref2 = columnsRef.current[columnIndex], items = _ref2.items; // 获取当前项所在的索引 var index = items.indexOf(item === null || item === void 0 ? void 0 : item.key); var _ref3 = (_attributesRef$curren = attributesRef.current.get(item === null || item === void 0 ? void 0 : item.key)) !== null && _attributesRef$curren !== void 0 ? _attributesRef$curren : {}, _ref3$height = _ref3.height, height = _ref3$height === void 0 ? 0 : _ref3$height, otherProps = _objectWithoutProperties(_ref3, _excluded); // 计算出当前项的高度和间隔的差值 var minusHeight = height - size.height; attributesRef.current.set(item === null || item === void 0 ? void 0 : item.key, _objectSpread(_objectSpread({}, otherProps), {}, { height: size.height })); for (var i = index + 1; i < items.length; i++) { var _attributesRef$curren2; var nextKey = items[i]; var nextItem = (_attributesRef$curren2 = attributesRef.current.get(nextKey)) !== null && _attributesRef$curren2 !== void 0 ? _attributesRef$curren2 : {}; var nextTop = nextItem.top; // 当前列的后续项的top值需要减去当前项的高度和间隔 attributesRef.current.set(nextKey, _objectSpread(_objectSpread({}, nextItem), {}, { top: nextTop - minusHeight })); } columnsRef.current[columnIndex].height -= minusHeight; }); // 处理resize useNextTick(function () { var entries = _toConsumableArray(itemResizeStatusRef.current); var hasResizing = entries.some(function (_ref4) { var _ref5 = _slicedToArray(_ref4, 2), isResizing = _ref5[1].isResizing; return isResizing; }); if (!hasResizing) { return; } entries.forEach(function (_ref6) { var _ref7 = _slicedToArray(_ref6, 2), key = _ref7[0], resizeStatus = _ref7[1]; var lastSize = resizeStatus.lastSize, isResizing = resizeStatus.isResizing, item = resizeStatus.item; if (isResizing) { refreshColumns(item, lastSize); itemResizeStatusRef.current.set(key, _objectSpread(_objectSpread({}, resizeStatus), {}, { isResizing: false })); } }); forceUpdate(); }); var onResize = usePersistFn(function (item, size) { var _ref8, _size$width, _attributesRef$curren3; if (!((_ref8 = (_size$width = size === null || size === void 0 ? void 0 : size.width) !== null && _size$width !== void 0 ? _size$width : size === null || size === void 0 ? void 0 : size.height) !== null && _ref8 !== void 0 ? _ref8 : false)) { return; } var _ref9 = (_attributesRef$curren3 = attributesRef.current.get(item === null || item === void 0 ? void 0 : item.key)) !== null && _attributesRef$curren3 !== void 0 ? _attributesRef$curren3 : {}, columnIndex = _ref9.columnIndex; // 如果已经计算好所在列,则走更新逻辑 if (typeof columnIndex === 'number') { itemResizeStatusRef.current.set(item === null || item === void 0 ? void 0 : item.key, { lastSize: size, isResizing: true, item: item }); } else { initItemsQueueRef.current.push({ item: item, size: size }); } forceUpdate(); }); var onRemove = usePersistFn(function (item) { var _attributesRef$curren4; var positionItem = attributesRef.current.get(item === null || item === void 0 ? void 0 : item.key); if (typeof (positionItem === null || positionItem === void 0 ? void 0 : positionItem.columnIndex) !== 'number') { return; } // 计算出当前项在所在列的索引,然后更新该列的高度 var columnIndex = positionItem.columnIndex; var _ref10 = columnsRef.current[columnIndex], items = _ref10.items; var index = items.indexOf(item === null || item === void 0 ? void 0 : item.key); var _ref11 = (_attributesRef$curren4 = attributesRef.current.get(item === null || item === void 0 ? void 0 : item.key)) !== null && _attributesRef$curren4 !== void 0 ? _attributesRef$curren4 : {}, _ref11$top = _ref11.top, top = _ref11$top === void 0 ? 0 : _ref11$top, _ref11$height = _ref11.height, minusHeight = _ref11$height === void 0 ? 0 : _ref11$height; var columnHeight = top; for (var i = index + 1; i < items.length; i++) { var _attributesRef$curren5; var nextKey = items[i]; var nextItem = (_attributesRef$curren5 = attributesRef.current.get(nextKey)) !== null && _attributesRef$curren5 !== void 0 ? _attributesRef$curren5 : {}; var nextTop = nextItem.top, nextHeight = nextItem.height; // 当前列的后续项的top值需要减去当前项的高度和间隔 attributesRef.current.set(nextKey, _objectSpread(_objectSpread({}, nextItem), {}, { top: nextTop - minusHeight - verticalGutter })); var increaseGutter = columnHeight && verticalGutter; columnHeight += nextHeight + increaseGutter; } columnsRef.current[columnIndex].height = columnHeight; columnsRef.current[columnIndex].items.splice(index, 1); attributesRef.current.delete(item === null || item === void 0 ? void 0 : item.key); forceUpdate(); }); var positionRecord = Object.assign.apply(Object, [{}].concat(_toConsumableArray(_toConsumableArray(attributesRef.current.entries()).map(function (_ref12) { var _ref13 = _slicedToArray(_ref12, 2), key = _ref13[0], value = _ref13[1]; return _defineProperty({}, key, value); })))); var columnHeights = columnsRef.current.map(function (column) { return column.height; }); var containerHeight = Math.max.apply(Math, _toConsumableArray(columnHeights)); return [containerHeight, positionRecord, { onResize: onResize, onRemove: onRemove }]; };