@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
132 lines • 4.47 kB
JavaScript
import _map from "lodash/map";
import _find from "lodash/find";
import _clone from "lodash/clone";
import _merge from "lodash/merge";
import Logger from '@douyinfe/semi-foundation/lib/es/utils/Logger';
import { numbers, strings } from '@douyinfe/semi-foundation/lib/es/table/constants';
import { cloneDeep } from '../_utils';
import { getColumnKey } from '@douyinfe/semi-foundation/lib/es/table/utils';
let scrollbarVerticalSize, scrollbarHorizontalSize;
// Measure scrollbar width for padding body during modal show/hide
const scrollbarMeasure = {
position: 'absolute',
top: '-9999px',
width: '50px',
height: '50px'
};
/**
* @param {'vertical'|'horizontal'} [direction]
* @returns {number}
*/
export function measureScrollbar() {
let direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'vertical';
if (typeof document === 'undefined' || typeof window === 'undefined') {
return 0;
}
const isVertical = direction === 'vertical';
if (isVertical && scrollbarVerticalSize) {
return scrollbarVerticalSize;
} else if (!isVertical && scrollbarHorizontalSize) {
return scrollbarHorizontalSize;
}
const scrollDiv = document.createElement('div');
Object.keys(scrollbarMeasure).forEach(scrollProp => {
scrollDiv.style[scrollProp] = scrollbarMeasure[scrollProp];
});
// Append related overflow style
if (isVertical) {
scrollDiv.style.overflowY = 'scroll';
} else {
scrollDiv.style.overflowX = 'scroll';
}
document.body.appendChild(scrollDiv);
let size = 0;
if (isVertical) {
// clientWidth is the inner width (excluding borders and scrollbars)
// offsetWidth is the outer width (including padding and borders)
size = scrollDiv.offsetWidth - scrollDiv.clientWidth;
scrollbarVerticalSize = size;
} else {
size = scrollDiv.offsetHeight - scrollDiv.clientHeight;
scrollbarHorizontalSize = size;
}
document.body.removeChild(scrollDiv);
// console.log(size);
return size;
}
export function amendTableWidth(tableWidth) {
return typeof tableWidth === 'number' ? tableWidth - numbers.DEFAULT_CELL_PADDING_LEFT - numbers.DEFAULT_CELL_PADDING_RIGHT - numbers.DEFAULT_CELL_BORDER_WIDTH_LEFT - numbers.DEFAULT_CELL_BORDER_WIDTH_RIGHT - measureScrollbar('vertical') : undefined;
}
/**
* The user can pass a component to define the rendering method of each level of the table
* This function merges the components passed in by the user with the default components
* @param {Object} components
* @param {Boolean|Object} virtualized
* @returns
*/
export function mergeComponents(components, virtualized) {
return _merge({}, {
table: 'table',
header: {
outer: 'table',
wrapper: 'thead',
row: 'tr',
cell: 'th'
},
body: virtualized ? {
outer: 'div',
wrapper: 'div',
row: 'div',
cell: 'div',
colgroup: {
wrapper: 'div',
col: 'div'
}
} : {
outer: 'table',
wrapper: 'tbody',
row: 'tr',
cell: 'td',
colgroup: {
wrapper: 'colgroup',
col: 'col'
}
},
footer: {
wrapper: 'tfoot',
row: 'tr',
cell: 'td'
}
}, components);
}
export const logger = new Logger('[@douyinfe/semi-ui Table]');
export function mergeColumns() {
let oldColumns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
let newColumns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
let keyPropNames = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let deep = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
const finalColumns = [];
const clone = deep ? cloneDeep : _clone;
_map(newColumns, newColumn => {
newColumn = Object.assign({}, newColumn);
const key = getColumnKey(newColumn, keyPropNames);
const oldColumn = key != null && _find(oldColumns, item => getColumnKey(item, keyPropNames) === key);
if (oldColumn) {
finalColumns.push(clone(Object.assign(Object.assign({}, oldColumn), newColumn)));
} else {
finalColumns.push(clone(newColumn));
}
});
return finalColumns;
}
export function getNextSortOrder(sortOrder) {
switch (sortOrder) {
case strings.SORT_DIRECTIONS[0]:
return strings.SORT_DIRECTIONS[1];
case strings.SORT_DIRECTIONS[1]:
return 'cancelSort';
default:
return strings.SORT_DIRECTIONS[0];
}
}
export { cloneDeep };