UNPKG

ali-react-table

Version:
1,196 lines (1,161 loc) 113 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var pipeline = require('./chunks/ali-react-table-pipeline-d381df96.js'); var React = require('react'); var styled = require('styled-components'); var rxjs = require('rxjs'); var op = require('rxjs/operators'); var cx = require('classnames'); require('resize-observer-polyfill'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n['default'] = e; return Object.freeze(n); } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled); var op__namespace = /*#__PURE__*/_interopNamespace(op); var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx); function groupBy(list, iteratee) { const groups = {}; for (const item of list) { const key = iteratee(item); if (groups[key] == null) { groups[key] = []; } groups[key].push(item); } return groups; } /** * 以 input 作为输入,按序使用 transform. * * `applyTransforms(input, f1, f2, f3)` 等价于 `f3(f2(f1(input)))` */ function applyTransforms(input, ...transforms) { return transforms.reduce((v, fn) => fn(v), input); } /** * 根据 idProp 与 parentIdProp 从对象数组中构建对应的树 * 当 A[parentIdProp] === B[idProp] 时,对象A会被移动到对象B的children。 * 当一个对象的 parentIdProp 不与其他对象的 idProp 字段相等时,该对象被作为树的顶层节点 * @example * const array = [ * { id: 'node-1', parent: 'root' }, * { id: 'node-2', parent: 'root' }, * { id: 'node-3', parent: 'node-2' }, * { id: 'node-4', parent: 'node-2' }, * { id: 'node-5', parent: 'node-4' }, * ] * const tree = buildTree('id', 'parent', array) * expect(tree).toEqual([ * { id: 'node-1', parent: 'root' }, * { * id: 'node-2', * parent: 'root', * children: [ * { id: 'node-3', parent: 'node-2' }, * { * id: 'node-4', * parent: 'node-2', * children: [{ id: 'node-5', parent: 'node-4' }], * }, * ], * }, * ]) */ function buildTree$1(idProp, parentIdProp, items) { const wrapperMap = new Map(); const ensure = (id) => { if (wrapperMap.has(id)) { return wrapperMap.get(id); } const wrapper = { id, parent: null, item: null, children: [] }; wrapperMap.set(id, wrapper); return wrapper; }; for (const item of items) { const parentWrapper = ensure(item[parentIdProp]); const itemWrapper = ensure(item[idProp]); itemWrapper.parent = parentWrapper; parentWrapper.children.push(itemWrapper); itemWrapper.item = item; } const topLevelWrappers = pipeline.flatMap(Array.from(wrapperMap.values()).filter((wrapper) => wrapper.parent == null), (wrapper) => wrapper.children); return unwrapRecursively(topLevelWrappers); function unwrapRecursively(wrapperArray) { const result = []; for (const wrapper of wrapperArray) { if (wrapper.children.length === 0) { result.push(wrapper.item); } else { result.push(Object.assign(Object.assign({}, wrapper.item), { children: unwrapRecursively(wrapper.children) })); } } return result; } } function safeGetSpanRect(column, record, rowIndex, colIndex) { let colSpan = 1; let rowSpan = 1; if (column.getSpanRect) { const value = pipeline.internals.safeGetValue(column, record, rowIndex); const spanRect = column.getSpanRect(value, record, rowIndex); colSpan = spanRect == null ? 1 : spanRect.right - colIndex; rowSpan = spanRect == null ? 1 : spanRect.bottom - rowIndex; } else { const cellProps = pipeline.internals.safeGetCellProps(column, record, rowIndex); if (cellProps.colSpan != null) { colSpan = cellProps.colSpan; } if (cellProps.rowSpan != null) { rowSpan = cellProps.rowSpan; } } // 注意这里没有考虑「rowSpan/colSpan 不能过大,避免 rowSpan/colSpan 影响因虚拟滚动而未渲染的单元格」 return { top: rowIndex, bottom: rowIndex + rowSpan, left: colIndex, right: colIndex + colSpan, }; } function move({ c, r }, dx, dy) { return { c: c + dx, r: r + dy }; } function sanitizeCellDatum(value) { if (value === Infinity || value === -Infinity || (typeof value === 'number' && isNaN(value))) { return null; } else { return value; } } /** 根据 BaseTable 的 dataSource 和 column,将表格数据导出为 Excel 文件 */ function exportTableAsExcel(xlsxPackage, dataSource, columns, filename) { const sheet = xlsxPackage.utils.aoa_to_sheet([]); const topHeaderHeight = pipeline.getTreeDepth(columns) + 1; const origin = { c: 0, r: 0 }; addTopHeaders(origin); addDataPart(move(origin, 0, topHeaderHeight)); xlsxPackage.writeFile({ SheetNames: ['Sheet1'], Sheets: { Sheet1: sheet }, }, filename); function addTopHeaders(origin) { dfs(columns, 0, 0); function dfs(cols, startDx, startDy) { var _a; const start = move(origin, startDx, startDy); let offsetX = 0; for (const col of cols) { if ((_a = col.features) === null || _a === void 0 ? void 0 : _a.noExport) { continue; } const current = move(start, offsetX, 0); addOne(col.name, current); if (pipeline.isLeafNode(col)) { offsetX += 1; mergeCells(current, 1, topHeaderHeight - startDy); } else { const childrenWidth = dfs(col.children, startDx + offsetX, startDy + 1); mergeCells(current, childrenWidth, 1); offsetX += childrenWidth; } } return offsetX; } } function addDataPart(origin) { const leafColumns = pipeline.collectNodes(columns, 'leaf-only').filter((col) => { var _a; return !((_a = col.features) === null || _a === void 0 ? void 0 : _a.noExport); }); const spanManager = new pipeline.SpanManager(); const dataPart = dataSource.map((record, rowIndex) => { spanManager.stripUpwards(rowIndex); return leafColumns.map((col, colIndex) => { if (spanManager.testSkip(rowIndex, colIndex)) { return null; } const spanRect = safeGetSpanRect(col, record, rowIndex, colIndex); const rowSpan = spanRect.bottom - spanRect.top; const colSpan = spanRect.right - spanRect.left; if (rowSpan > 1 || colSpan > 1) { spanManager.add(spanRect.top, spanRect.left, colSpan, rowSpan); mergeCells(move(origin, spanRect.left, spanRect.top), colSpan, rowSpan); } return sanitizeCellDatum(pipeline.internals.safeGetValue(col, record, rowIndex)); }); }); add(dataPart, origin); } function add(data, origin) { xlsxPackage.utils.sheet_add_aoa(sheet, data, { origin }); } function addOne(datum, origin) { xlsxPackage.utils.sheet_add_aoa(sheet, [[datum]], { origin }); } function mergeCells(addr, width, height) { if (width === 1 && height === 1) { return; } if (sheet['!merges'] == null) { sheet['!merges'] = []; } sheet['!merges'].push({ s: addr, e: move(addr, width - 1, height - 1) }); } } /** 对树状结构的数据进行排序. * layeredSort 是一个递归的过程,针对树上的每一个父节点,该函数都会重新对其子节点数组(children) 进行排序. * */ function layeredSort(array, compare) { return dfs(array); function dfs(rows) { if (!Array.isArray(array)) { return array; } return rows .map((row) => { if (pipeline.isLeafNode(row)) { return row; } return Object.assign(Object.assign({}, row), { children: dfs(row.children) }); }) .sort(compare); } } const factorySymbol = Symbol('factory-symbol'); function isProtoFactory(v) { return v && v[factorySymbol]; } function proto(baseRecord, ensureArray = 'auto') { const baseKeys = Object.keys(baseRecord); function process(record) { const result = Object.assign({}, record); baseKeys.forEach((key) => { var _a; if (result[key] === proto.empty) { delete result[key]; return; } const base = baseRecord[key]; if (isProtoFactory(base)) { result[key] = base(result[key]); } else { result[key] = (_a = result[key]) !== null && _a !== void 0 ? _a : base; } }); return result; } function factory(arg) { const isEnsureArray = ensureArray === 'auto' ? Array.isArray(arg) : ensureArray; if (isEnsureArray) { if (arg == null) { return []; } return arg.map(process); } else { return process(arg); } } // @ts-ignore factory[factorySymbol] = true; factory.extends = (extRecord) => { const extFactory = proto(extRecord, ensureArray); return (arg) => factory(extFactory(arg)); }; return factory; } proto.empty = Symbol('proto.empty'); proto.string = ((v) => { if (v != null && typeof v !== 'string') { throw new Error('must be string'); } return v; }); proto.string[factorySymbol] = true; proto.number = ((v) => { if (v != null && typeof v !== 'number') { throw new Error('must be number'); } return v; }); proto.number[factorySymbol] = true; proto.notNull = ((v) => { if (v == null) { throw new Error('must be not null'); } return v; }); proto.notNull[factorySymbol] = true; proto.object = (baseRecord) => proto(baseRecord, false); proto.array = (baseRecord) => proto(baseRecord, true); function makeRecursiveMapper(fn) { return (tree) => { return dfs(tree, 0, []).result; function dfs(nodes, parentStartIndex, path) { let flatCount = 0; const result = []; for (const node of nodes) { path.push(node); const startIndex = parentStartIndex + flatCount; let subResult; if (pipeline.isLeafNode(node)) { subResult = fn(node, { startIndex, endIndex: startIndex + 1, path: path.slice(), isLeaf: true, }); flatCount += 1; } else { const dfsResult = dfs(node.children, startIndex, path); subResult = fn(Object.assign(Object.assign({}, node), { children: dfsResult.result }), { startIndex, endIndex: startIndex + dfsResult.flatCount, path: path.slice(), isLeaf: false }); flatCount += dfsResult.flatCount; } if (Array.isArray(subResult)) { result.push(...subResult); } else if (subResult != null) { result.push(subResult); } path.pop(); } return { result, flatCount }; } }; } /** 比较函数,支持字符串、数字、数组和 null。 * * 对于字符串将比较两者的字典序; * * 对数字将比较两者大小; * * null 值在比较时总是小于另一个值; * * 对于数组来说,将逐个比较数组中的元素,第一个不相等的比较结果将作为整个数组的比较结果 * * 数组的比较可参考 python 中的元祖比较: * https://stackoverflow.com/questions/5292303/how-does-tuple-comparison-work-in-python */ function smartCompare(x, y) { // 将 null 排在最后面 if (x == null) { return 1; } if (y == null) { return -1; } if (typeof x === 'number' && typeof y === 'number') { return x - y; } if (typeof x === 'string' && typeof y === 'string') { // 字符串使用 默认的字典序 if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } } if (Array.isArray(x) && Array.isArray(y)) { const len = Math.min(x.length, y.length); for (let i = 0; i < len; i++) { const cmp = smartCompare(x[i], y[i]); if (cmp !== 0) { return cmp; } } // 数组长度不等时,元素少的字段放在前面 return x.length - y.length; } // 对于不认识的数据类型,返回 0 return 0; } function normalizeAsArray(input) { if (input == null) { return []; } else if (Array.isArray(input)) { return input; } else { return [input]; } } /** @deprecated 该 API 已经过时,请使用 makeRecursiveMapper */ function traverseColumn(fn) { return ({ columns, dataSource }) => { return { dataSource, columns: dfs(columns, 0).result }; function dfs(columns, parentStartColIndex) { let flatColCount = 0; const result = []; for (const col of columns) { const startColIndex = parentStartColIndex + flatColCount; let unNormalized; if (pipeline.isLeafNode(col)) { unNormalized = fn(col, { range: { start: startColIndex, end: startColIndex + 1 }, dataSource, }); flatColCount += 1; } else { const dfsResult = dfs(col.children, startColIndex); unNormalized = fn(Object.assign(Object.assign({}, col), { children: dfsResult.result }), { range: { start: startColIndex, end: startColIndex + dfsResult.flatColCount, }, dataSource, }); flatColCount += dfsResult.flatColCount; } result.push(...normalizeAsArray(unNormalized)); } return { result, flatColCount }; } }; } const warnedSet = new Set(); function warnTransformsDeprecated(apiName) { if (!warnedSet.has(apiName)) { warnedSet.add(apiName); console.warn(`[ali-react-table] transform 用法已经过时,请使用 pipeline 来对表格进行拓展` + `\n 请移除以下 API 的调用:${apiName}`); } } function isIdentity$1(x, y) { return x === y; } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeAutoRowSpanTransform() { warnTransformsDeprecated('makeAutoRowSpanTransform'); return traverseColumn((col, { dataSource, range }) => { var _a; if (!((_a = col.features) === null || _a === void 0 ? void 0 : _a.autoRowSpan)) { return col; } if (!pipeline.isLeafNode(col)) { return col; } const isFunc = typeof col.features.autoRowSpan === 'function'; const shouldMergeCell = isFunc ? col.features.autoRowSpan : isIdentity$1; const spanRects = []; let lastBottom = 0; let prevValue = null; let prevRow = null; for (let rowIndex = 0; rowIndex < dataSource.length; rowIndex++) { const row = dataSource[rowIndex]; const value = pipeline.internals.safeGetValue(col, row, rowIndex); if (rowIndex === 0 || !shouldMergeCell(prevValue, value, prevRow, row)) { const spanRect = { top: lastBottom, bottom: rowIndex, left: range.start, right: range.end, }; for (let i = lastBottom; i < rowIndex; i++) { spanRects.push(spanRect); } lastBottom = rowIndex; } prevValue = value; prevRow = row; } for (let i = lastBottom; i < dataSource.length; i++) { spanRects.push({ top: lastBottom, bottom: dataSource.length, left: range.start, right: range.end, }); } return Object.assign(Object.assign({}, col), { getSpanRect(value, row, rowIndex) { return spanRects[rowIndex]; } }); }); } const AUTO_WIDTH_WRAPPER_CLS = 'auto-width-wrapper'; const AUTO_WIDTH_EXPANDER_CLS = 'auto-width-expander'; const AutoWidthWrapper = styled__default['default'].div ` height: 100%; display: inline-flex; align-items: center; white-space: nowrap; padding: 8px 12px; `; function isSameArray(arr1, arr2) { return arr1.length === arr2.length && arr1.every((x, i) => x === arr2[i]); } /** 自适应列宽 * * @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 * * @param tableRef BaseTable 的 ref * @param options 参数 * @param deps 重新调整列宽的依赖数组,每当依赖数组发生变化时, useAutoWidthTransform 会根据单元格内容的实际渲染宽度 设置单元格的宽度 * * options 说明: * - options.appendExpander 是否在列的末尾追加可伸缩列 * - options.expanderVisibility 设置为 `'hidden'` 可以隐藏可伸缩列 * - options.wrapperStyle 单元格中 div.auto-width-wrapper 的样式 * - options.initColumnWidth 自适应的初始列宽 * * 注意 useAutoWidthTransform 是一个 React hooks,要遵循 hooks 的用法规范 * */ function useAutoWidthTransform(tableRef, options, deps) { warnTransformsDeprecated('useAutoWidthTransform'); const [widthList, setWidthList] = React.useState([]); React.useEffect(() => { const artTable = tableRef.current.getDoms().artTable; const rows = Array.from(artTable.querySelectorAll(`.${pipeline.Classes.tableRow}`)); if (rows.length === 0) { return; } const preferredWidthList = []; for (const row of rows) { const autoWidthDivList = row.querySelectorAll(`.${AUTO_WIDTH_WRAPPER_CLS}`); autoWidthDivList.forEach((div, i) => { var _a; preferredWidthList[i] = Math.max((_a = preferredWidthList[i]) !== null && _a !== void 0 ? _a : 0, div.scrollWidth); }); } if (!isSameArray(preferredWidthList, widthList)) { setWidthList(preferredWidthList); } }, deps); let i = 0; const innerTransform = traverseColumn((col) => { var _a, _b, _c; if (!pipeline.isLeafNode(col)) { return col; } if (!((_a = col.features) === null || _a === void 0 ? void 0 : _a.autoWidth)) { return col; } const { max = Infinity, min = -Infinity } = col.features.autoWidth; const width = (_c = (_b = widthList[i++]) !== null && _b !== void 0 ? _b : col.width) !== null && _c !== void 0 ? _c : options === null || options === void 0 ? void 0 : options.initColumnWidth; const clampedWidth = Math.max(min, Math.min(max, width)); return Object.assign(Object.assign({}, col), { width: clampedWidth, getCellProps(_, record, rowIndex) { return pipeline.mergeCellProps(pipeline.internals.safeGetCellProps(col, record, rowIndex), { style: { padding: 0 }, }); }, render(_, record, rowIndex) { return (React__default['default'].createElement(AutoWidthWrapper, { className: AUTO_WIDTH_WRAPPER_CLS, style: options === null || options === void 0 ? void 0 : options.wrapperStyle }, pipeline.internals.safeRender(col, record, rowIndex))); } }); }); return (input) => { var _a; const { columns, dataSource } = innerTransform(input); const expanderVisibility = (_a = options === null || options === void 0 ? void 0 : options.expanderVisibility) !== null && _a !== void 0 ? _a : 'visible'; return { columns: (options === null || options === void 0 ? void 0 : options.appendExpander) ? columns.concat([ { name: '', headerCellProps: { className: AUTO_WIDTH_EXPANDER_CLS, style: { background: expanderVisibility === 'hidden' ? 'var(--bgcolor)' : undefined, border: expanderVisibility === 'hidden' ? 'none' : undefined, }, }, getCellProps() { return { className: AUTO_WIDTH_EXPANDER_CLS, style: { visibility: expanderVisibility }, }; }, }, ]) : columns, dataSource, }; }; } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeBuildTreeTransform(idProp, parentIdProp) { warnTransformsDeprecated('makeBuildTreeTransform'); return ({ columns, dataSource }) => { return { columns, dataSource: buildTree$1(idProp, parentIdProp, dataSource) }; }; } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeColumnHoverTransform({ hoverColor = 'var(--hover-bgcolor)', hoverColIndex, onChangeHoverColIndex, }) { warnTransformsDeprecated('makeColumnHoverTransform'); return traverseColumn((col, { range }) => { if (!pipeline.isLeafNode(col)) { return col; } const colIndexMatched = range.start <= hoverColIndex && hoverColIndex < range.end; const prevGetCellProps = col.getCellProps; return Object.assign(Object.assign({}, col), { getCellProps(value, record, rowIndex) { const prevCellProps = prevGetCellProps === null || prevGetCellProps === void 0 ? void 0 : prevGetCellProps(value, record, rowIndex); return pipeline.mergeCellProps(prevCellProps, { style: { '--bgcolor': colIndexMatched ? hoverColor : undefined }, onMouseEnter() { onChangeHoverColIndex(range.start); }, onMouseLeave() { onChangeHoverColIndex(-1); }, }); } }); }); } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function useColumnHoverTransform({ hoverColor, defaultHoverColIndex = -1, } = {}) { const [hoverColIndex, onChangeHoverColIndex] = React.useState(defaultHoverColIndex); return makeColumnHoverTransform({ hoverColor, hoverColIndex, onChangeHoverColIndex }); } const EMPTY_RANGE$1 = { start: -1, end: -1, }; /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeColumnRangeHoverTransform({ hoverColor = 'var(--hover-bgcolor)', headerHoverColor = 'var(--header-hover-bgcolor)', hoverRange, onChangeHoverRange, }) { warnTransformsDeprecated('makeColumnRangeHoverTransform'); return traverseColumn((col, { range: colRange }) => { const match = colRange.end > hoverRange.start && hoverRange.end > colRange.start; if (!pipeline.isLeafNode(col)) { if (headerHoverColor == null) { return col; } return Object.assign(Object.assign({}, col), { headerCellProps: pipeline.mergeCellProps(col.headerCellProps, { onMouseEnter() { onChangeHoverRange(colRange); }, onMouseLeave() { onChangeHoverRange(EMPTY_RANGE$1); }, style: { '--header-bgcolor': match ? headerHoverColor : undefined }, }) }); } const prevGetCellProps = col.getCellProps; return Object.assign(Object.assign({}, col), { headerCellProps: pipeline.mergeCellProps(col.headerCellProps, { onMouseEnter() { onChangeHoverRange(colRange); }, onMouseLeave() { onChangeHoverRange(EMPTY_RANGE$1); }, style: { '--header-bgcolor': match ? headerHoverColor : undefined }, }), getCellProps(value, record, rowIndex) { const prevCellProps = prevGetCellProps === null || prevGetCellProps === void 0 ? void 0 : prevGetCellProps(value, record, rowIndex); return pipeline.mergeCellProps(prevCellProps, { onMouseEnter() { onChangeHoverRange(colRange); }, onMouseLeave() { onChangeHoverRange(EMPTY_RANGE$1); }, style: { '--bgcolor': match ? hoverColor : undefined }, }); } }); }); } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function useColumnHoverRangeTransform({ hoverColor, headerHoverColor, defaultHoverRange = EMPTY_RANGE$1, } = {}) { const [hoverRange, onChangeHoverRange] = React.useState(defaultHoverRange); return makeColumnRangeHoverTransform({ hoverColor, headerHoverColor, hoverRange, onChangeHoverRange }); } function clamp$1(min, x, max) { return Math.max(min, Math.min(max, x)); } const RESIZE_EXPANDER_CLS = 'resize-expander'; const ResizeHandle$1 = styled__default['default'].span ` position: absolute; top: 0; bottom: 0; right: -5px; width: 10px; cursor: col-resize; z-index: 1; `; /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeColumnResizeTransform({ sizes, onChangeSizes, minSize = 40, maxSize = Infinity, appendExpander, expanderVisibility = 'visible', disableUserSelectWhenResizing, }) { warnTransformsDeprecated('makeColumnResizeTransform'); const startResize = (colIndex, e) => { const startX = e.clientX; const startSize = sizes[colIndex]; const nextSizes$ = rxjs.fromEvent(window, 'mousemove').pipe(op__namespace.takeUntil(rxjs.fromEvent(window, 'mouseup')), op__namespace.map((e) => { const movingX = e.clientX; const nextSizes = sizes.slice(); nextSizes[colIndex] = clamp$1(minSize, startSize + (movingX - startX), maxSize); return nextSizes; })); let prevUserSelect = ''; let docElemStyle; if (disableUserSelectWhenResizing) { docElemStyle = document.documentElement.style; prevUserSelect = docElemStyle.userSelect; docElemStyle.userSelect = 'none'; } nextSizes$.subscribe({ next: onChangeSizes, complete() { if (disableUserSelectWhenResizing) { docElemStyle.userSelect = prevUserSelect; } }, }); }; const innerTransform = traverseColumn((col, { range }) => { var _a; if (!pipeline.isLeafNode(col)) { return col; } const prevTitle = pipeline.internals.safeRenderHeader(col); return Object.assign(Object.assign({}, col), { width: sizes[range.start], title: (React__default['default'].createElement(React__default['default'].Fragment, null, prevTitle, React__default['default'].createElement(ResizeHandle$1, { className: "resize-handle", onMouseDown: (e) => startResize(range.start, e) }))), headerCellProps: Object.assign(Object.assign({}, col.headerCellProps), { style: Object.assign(Object.assign({}, (_a = col.headerCellProps) === null || _a === void 0 ? void 0 : _a.style), { overflow: 'visible', position: 'relative' }) }) }); }); return (input) => { const { columns, dataSource } = innerTransform(input); return { columns: appendExpander ? columns.concat([ { name: '', headerCellProps: { className: RESIZE_EXPANDER_CLS, style: { background: expanderVisibility === 'hidden' ? 'var(--bgcolor)' : undefined, border: expanderVisibility === 'hidden' ? 'none' : undefined, }, }, getCellProps() { return { className: RESIZE_EXPANDER_CLS, style: { visibility: expanderVisibility }, }; }, }, ]) : columns, dataSource, }; }; } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function useColumnResizeTransform(_a) { var { defaultSizes } = _a, others = pipeline.__rest(_a, ["defaultSizes"]); const [sizes, onChangeSizes] = React.useState(defaultSizes); return makeColumnResizeTransform(Object.assign({ sizes, onChangeSizes }, others)); } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeFlattenTransform() { warnTransformsDeprecated('makeFlattenTransform'); return traverseColumn((column) => { var _a; if (pipeline.isLeafNode(column)) { return column; } return ((_a = column.features) === null || _a === void 0 ? void 0 : _a.flatten) ? column.children : column; }); } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeOrderFieldTransform(startOrder = 1) { warnTransformsDeprecated('makeOrderFieldTransform'); return traverseColumn((column) => { var _a, _b; if (((_a = column.features) === null || _a === void 0 ? void 0 : _a.order) || ((_b = column.features) === null || _b === void 0 ? void 0 : _b.orderField)) { return Object.assign(Object.assign({}, column), { getValue(record, index) { return index + startOrder; } }); } return column; }); } function SortIcon$1({ size = 32, style, className, order, }) { return (React__default['default'].createElement("svg", { style: style, className: className, focusable: "false", preserveAspectRatio: "xMidYMid meet", width: size, height: size, viewBox: "0 0 32 32", "aria-hidden": "true" }, React__default['default'].createElement("path", { fill: order === 'asc' ? '#23A3FF' : '#bfbfbf', transform: "translate(0, 4)", d: "M8 8L16 0 24 8z" }), React__default['default'].createElement("path", { fill: order === 'desc' ? '#23A3FF' : '#bfbfbf', transform: "translate(0, -4)", d: "M24 24L16 32 8 24z " }))); } function DefaultSortHeaderCell$1({ children, column, onToggle, sortOrder, sortIndex, sortOptions }) { // 通过 justify-content 来与 col.align 保持对齐方向一致 const justifyContent = column.align === 'right' ? 'flex-end' : column.align === 'center' ? 'center' : 'flex-start'; return (React__default['default'].createElement(TableHeaderCell$1, { onClick: onToggle, style: { justifyContent } }, children, React__default['default'].createElement(SortIcon$1, { style: { userSelect: 'none', marginLeft: 2, flexShrink: 0 }, size: 16, order: sortOrder }), sortOptions.mode === 'multiple' && sortIndex != -1 && (React__default['default'].createElement("div", { style: { userSelect: 'none', marginLeft: 2, color: '#666', flex: '0 0 auto', fontSize: 10, fontFamily: 'monospace', } }, sortIndex + 1)))); } function hasAnySortableColumns$1(cols) { return cols.some((col) => { var _a; return Boolean((_a = col.features) === null || _a === void 0 ? void 0 : _a.sortable) || (!pipeline.isLeafNode(col) && hasAnySortableColumns$1(col.children)); }); } const TableHeaderCell$1 = styled__default['default'].div ` cursor: pointer; display: flex; align-items: center; `; /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeSortTransform({ sorts: inputSorts, onChangeSorts: inputOnChangeSorts, orders = ['desc', 'asc', 'none'], mode = 'multiple', SortHeaderCell = DefaultSortHeaderCell$1, keepDataSource, highlightColumnWhenActive, stopClickEventPropagation, }) { warnTransformsDeprecated('makeSortTransform'); const filteredInputSorts = inputSorts.filter((s) => s.order !== 'none'); // 单字段排序的情况下 sorts 中只有第一个排序字段才会生效 const sorts = mode === 'multiple' ? filteredInputSorts : filteredInputSorts.slice(0, 1); const onChangeSorts = mode === 'multiple' ? inputOnChangeSorts : (nextSorts) => { // 单字段排序的情况下,nextSorts 中只有最后一个排序字段才会生效 const len = nextSorts.length; inputOnChangeSorts(nextSorts.slice(len - 1)); }; const sortOptions = { sorts, onChangeSorts, orders, mode, keepDataSource, highlightColumnWhenActive, stopClickEventPropagation, }; const sortMap = new Map(sorts.map((sort, index) => [sort.code, Object.assign({ index }, sort)])); return ({ dataSource, columns }) => { if (process.env.NODE_ENV !== 'production') { if (!hasAnySortableColumns$1(columns)) { console.warn('[ali-react-table] commonTransform.sort 缺少可排序的列,请通过 column.features.sortable 来指定哪些列可排序', columns); } } return { columns: processColumns(columns), dataSource: processDataSource(dataSource) }; function processDataSource(dataSource) { if (keepDataSource) { return dataSource; } const sortColumnsMap = new Map(pipeline.collectNodes(columns, 'leaf-only') .filter((col) => { var _a; return ((_a = col.features) === null || _a === void 0 ? void 0 : _a.sortable) != null; }) .map((col) => [col.code, col])); return layeredSort(dataSource, (x, y) => { for (const { code, order } of sorts) { const column = sortColumnsMap.get(code); // 如果 code 对应的 column 不可排序,我们跳过该 code if (column == null) { continue; } const sortable = column.features.sortable; const compareFn = typeof sortable === 'function' ? sortable : smartCompare; const xValue = pipeline.internals.safeGetValue(column, x, -1); const yValue = pipeline.internals.safeGetValue(column, y, -1); const cmp = compareFn(xValue, yValue); if (cmp !== 0) { return cmp * (order === 'asc' ? 1 : -1); } } return 0; }); } // 在「升序 - 降序 - 不排序」之间不断切换 function toggle(code) { const sort = sortMap.get(code); if (sort == null) { onChangeSorts(sorts.concat([{ code, order: orders[0] }])); } else { const index = sorts.findIndex((s) => s.code === code); const nextSorts = sorts.slice(0, index + 1); const nextOrder = getNextOrder(sort.order); if (nextOrder === 'none') { nextSorts.pop(); } else { nextSorts[index] = Object.assign(Object.assign({}, nextSorts[index]), { order: nextOrder }); } onChangeSorts(nextSorts); } } function processColumns(columns) { return columns.map(dfs); function dfs(col) { var _a; const result = Object.assign({}, col); const sortable = col.code && (((_a = col.features) === null || _a === void 0 ? void 0 : _a.sortable) || sortMap.has(col.code)); const active = sortable && sortMap.has(col.code); if (sortable) { let sortIndex = -1; let sortOrder = 'none'; if (active) { const { order, index } = sortMap.get(col.code); sortOrder = order; sortIndex = index; if (highlightColumnWhenActive) { result.headerCellProps = pipeline.mergeCellProps(col.headerCellProps, { style: { background: 'var(--header-highlight-bgcolor)' }, }); result.getCellProps = (value, row, rowIndex) => { const prevCellProps = pipeline.internals.safeGetCellProps(col, row, rowIndex); return pipeline.mergeCellProps(prevCellProps, { style: { background: 'var(--highlight-bgcolor)' }, }); }; } } result.title = (React__default['default'].createElement(SortHeaderCell, { onToggle: (e) => { if (stopClickEventPropagation) { e.stopPropagation(); } toggle(col.code); }, sortOrder: sortOrder, column: col, sortIndex: sortIndex, sortOptions: sortOptions }, pipeline.internals.safeRenderHeader(col))); } if (!pipeline.isLeafNode(col)) { result.children = col.children.map(dfs); } return result; } } }; function getNextOrder(order) { const idx = orders.indexOf(order); return orders[idx === orders.length - 1 ? 0 : idx + 1]; } } /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function useSortTransform(_a = {}) { var { defaultSorts = [] } = _a, others = pipeline.__rest(_a, ["defaultSorts"]); const [sorts, onChangeSorts] = React.useState(defaultSorts); return makeSortTransform(Object.assign({ sorts, onChangeSorts }, others)); } const HeaderCellWithTips$1 = styled__default['default'].div ` display: flex; align-items: center; .tip-icon-wrapper { margin-left: 2px; } .tip-icon { display: flex; fill: currentColor; } `; /** @deprecated transform 用法已经过时,请使用 pipeline 来对表格进行拓展 */ function makeTipsTransform({ Balloon, Tooltip }) { warnTransformsDeprecated('makeTipsTransform'); return traverseColumn((col) => { var _a; if (!((_a = col.features) === null || _a === void 0 ? void 0 : _a.tips)) { return col; } const justifyContent = col.align === 'right' ? 'flex-end' : col.align === 'center' ? 'center' : 'flex-start'; return Object.assign(Object.assign({}, col), { title: (React__default['default'].createElement(HeaderCellWithTips$1, { style: { justifyContent } }, pipeline.internals.safeRenderHeader(col), Balloon ? ( // fusion/hippo React__default['default'].createElement(Balloon, { closable: false, trigger: React__default['default'].createElement("div", { className: "tip-icon-wrapper" }, React__default['default'].createElement(pipeline.icons.Info, { className: "tip-icon" })) }, col.features.tips)) : ( // antd React__default['default'].createElement(Tooltip, { title: col.features.tips }, React__default['default'].createElement("div", { className: "tip-icon-wrapper" }, React__default['default'].createElement(pipeline.icons.Info, { className: "tip-icon" })))))) }); }); } function isIdentity(x, y) { return x === y; } function autoRowSpan() { return function autoRowSpanStep(pipeline$1) { const dataSource = pipeline$1.getDataSource(); return pipeline$1.mapColumns(makeRecursiveMapper((col, { startIndex, endIndex }) => { var _a; if (!((_a = col.features) === null || _a === void 0 ? void 0 : _a.autoRowSpan)) { return col; } if (!pipeline.isLeafNode(col)) { return col; } const isFunc = typeof col.features.autoRowSpan === 'function'; const shouldMergeCell = isFunc ? col.features.autoRowSpan : isIdentity; const spanRects = []; let lastBottom = 0; let prevValue = null; let prevRow = null; for (let rowIndex = 0; rowIndex < dataSource.length; rowIndex++) { const row = dataSource[rowIndex]; const value = pipeline.internals.safeGetValue(col, row, rowIndex); if (rowIndex === 0 || !shouldMergeCell(prevValue, value, prevRow, row)) { const spanRect = { top: lastBottom, bottom: rowIndex, left: startIndex, right: endIndex, }; for (let i = lastBottom; i < rowIndex; i++) { spanRects.push(spanRect); } lastBottom = rowIndex; } prevValue = value; prevRow = row; } for (let i = lastBottom; i < dataSource.length; i++) { spanRects.push({ top: lastBottom, bottom: dataSource.length, left: startIndex, right: endIndex, }); } return Object.assign(Object.assign({}, col), { getSpanRect(value, row, rowIndex) { return spanRects[rowIndex]; } }); })); }; } function buildTree(idProp, parentIdProp) { return (pipeline) => pipeline.mapDataSource((rows) => buildTree$1(idProp, parentIdProp, rows)); } function columnHover(opts = {}) { const stateKey = 'columnHover'; return (pipeline$1) => { var _a, _b, _c, _d; const hoverColor = (_a = opts.hoverColor) !== null && _a !== void 0 ? _a : 'var(--hover-bgcolor)'; const hoverColIndex = (_d = (_c = (_b = opts.hoverColIndex) !== null && _b !== void 0 ? _b : pipeline$1.getStateAtKey(stateKey)) !== null && _c !== void 0 ? _c : opts.defaultHoverColIndex) !== null && _d !== void 0 ? _d : -1; const onChangeHoverColIndex = (nextColIndex) => { var _a; pipeline$1.setStateAtKey(stateKey, nextColIndex); (_a = opts.onChangeHoverColIndex) === null || _a === void 0 ? void 0 : _a.call(opts, nextColIndex); }; return pipeline$1.mapColumns(makeRecursiveMapper((col, { startIndex, endIndex }) => { const range = { start: startIndex, end: endIndex }; if (!pipeline.isLeafNode(col)) { return col; } const colIndexMatched = range.start <= hoverColIndex && hoverColIndex < range.end; const prevGetCellProps = col.getCellProps; return Object.assign(Object.assign({}, col), { getCellProps(value, record, rowIndex) { const prevCellProps = prevGetCellProps === null || prevGetCellProps === void 0 ? void 0 : prevGetCellProps(value, record, rowIndex); return pipeline.mergeCellProps(prevCellProps, { style: { '--bgcolor': colIndexMatched ? hoverColor : undefined }, onMouseEnter() { onChangeHoverColIndex(range.start); }, onMouseLeave() { onChangeHoverColIndex(-1); }, }); } }); })); }; } const EMPTY_RANGE = { start: -1, end: -1, }; function columnRangeHover(opts = {}) { const stateKey = 'columnHover'; return function columnRangeHoverStep(pipeline$1) { var _a, _b, _c, _d, _e; const hoverRange = (_c = (_b = (_a = opts.hoverRange) !== null && _a !== void 0 ? _a : pipeline$1.getStateAtKey(stateKey)) !== null && _b !== void 0 ? _b : opts.defaultHoverRange) !== null && _c !== void 0 ? _c : EMPTY_RANGE; const hoverColor = (_d = opts.hoverColor) !== null && _d !== void 0 ? _d : 'var(--hover-bgcolor)'; const headerHoverColor = (_e = opts.headerHoverColor) !== null && _e !== void 0 ? _e : 'var(--header-hover-bgcolor)'; const onChangeHoverRange = (nextColIndexRange) => { var _a; pipeline$1.setStateAtKey(stateKey, nextColIndexRange); (_a = opts.onChangeHoverRange) === null || _a === void 0 ? void 0 : _a.call(opts, nextColIndexRange); }; return pipeline$1.mapColumns(makeRecursiveMapper((col, { startIndex, endIndex }) => { const colRange = { start: startIndex, end: endIndex }; const match = colRange.end > hoverRange.start && hoverRange.end > colRange.start; if (!pipeline.isLeafNode(col)) { if (headerHoverColor == null) { return col; } return Object.assign(Object.assign({}, col), { headerCellProps: pipeline.mergeCellProps(col.headerCellProps, { onMouseEnter() { onChangeHoverRange(colRange); }, onMouseLeave() { onChangeHoverRange(EMPTY_RANGE); }, style: { '--header-bgcolor': match ? headerHoverColor : undefined }, }) }); } const prevGetCellProps = col.getCellProps; return Object.assign(Object.assign({}, col), { headerCellProps: pipeline.mergeCellProps(col.headerCellProps, { onMouseEnter() { onChangeHoverRange(colRange); }, onMouseLeave() { onChangeHoverRange(EMPTY_RANGE); }, style: { '--header-bgcolor': match ? headerHoverColor : undefined }, }), getCellProps(value, record, rowIndex) { const prevCellProps = prevGetCellProps === null || prevGetCellProps === void 0 ? void 0 : prevGetCellProps(value, record, rowIndex); return pipeline.mergeCellProps(prevCellProps, { onMouseEnter() { onChangeHoverRange(colRange); }, onMouseLeave() { onChangeHoverRange(EMPTY_RANGE); }, style: { '--bgcolor': match ? hoverColor : undefined }, }); } }); })); }; } function clamp(min, x, max) { return Math.max(min, Math.min(max, x)); } const ResizeHandle = styled__default['default'].span ` position: absolute; top: 0; bottom: 0; right: -5px; width: 10px; cursor: col-resize; z-index: 1; transition: background-color 200ms; background: ${(props) => { return props['var-handleBackground']; }}; &:hover { background: ${(props) => { return props['var-handleHoverBackground']; }}; } `; function columnResize(opts = {}) { var _a, _b, _c, _d; const stateKey = 'columnResize'; const disableUserSelectWhenResizing = (_a = opts.disableUserSelectWhenResizing) !== null && _a !== void 0 ? _a : true; const minSize = (_b = opts.minSize) !== null && _b !== void 0 ? _b : 60; const fallbackSize = (_c = opts.fallbackSize) !== null && _c !== void 0 ? _c : 150; const maxSize = (_d = opts.maxSize) !== null && _d !== void 0 ? _d : 1000; return function columnResizeFeature(pipeline$1) { var _a, _b, _c; const sizes = (_c = (_b = (_a = opts.sizes) !== null && _a !== void 0 ? _a : pipeline$1.getStateAtKey(stateKey)) !== null && _b !== void 0 ? _b : opts.defaultSizes) !== null && _c !== void 0 ? _c : []; const leafColumns = pipeline.collectNodes(pipeline$1.getColumns(), 'leaf-only'); leafColumns.forEach((col, colIndex) => { if (sizes[colIndex] == null) { if (typeof col.width === 'number') { sizes[colIndex] = col.width; } else { sizes[colIndex] = fallbackSize; } } }); const onChangeSizes = (nextSizes) => { var _a;