ali-react-table
Version:
1,196 lines (1,161 loc) • 113 kB
JavaScript
'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;