You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
8.5 KiB
241 lines
8.5 KiB
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var vue = require('vue');
|
|
var shared = require('@vue/shared');
|
|
var core = require('@vueuse/core');
|
|
var scrollbarWidth = require('../../../utils/scrollbar-width.js');
|
|
var util = require('./util.js');
|
|
|
|
class TableLayout {
|
|
constructor(options) {
|
|
this.observers = [];
|
|
this.table = null;
|
|
this.store = null;
|
|
this.columns = [];
|
|
this.fit = true;
|
|
this.showHeader = true;
|
|
this.height = vue.ref(null);
|
|
this.scrollX = vue.ref(false);
|
|
this.scrollY = vue.ref(false);
|
|
this.bodyWidth = vue.ref(null);
|
|
this.fixedWidth = vue.ref(null);
|
|
this.rightFixedWidth = vue.ref(null);
|
|
this.tableHeight = vue.ref(null);
|
|
this.headerHeight = vue.ref(44);
|
|
this.appendHeight = vue.ref(0);
|
|
this.footerHeight = vue.ref(44);
|
|
this.viewportHeight = vue.ref(null);
|
|
this.bodyHeight = vue.ref(null);
|
|
this.bodyScrollHeight = vue.ref(0);
|
|
this.fixedBodyHeight = vue.ref(null);
|
|
this.gutterWidth = scrollbarWidth["default"]();
|
|
for (const name in options) {
|
|
if (shared.hasOwn(options, name)) {
|
|
if (vue.isRef(this[name])) {
|
|
this[name].value = options[name];
|
|
} else {
|
|
this[name] = options[name];
|
|
}
|
|
}
|
|
}
|
|
if (!this.table) {
|
|
throw new Error("Table is required for Table Layout");
|
|
}
|
|
if (!this.store) {
|
|
throw new Error("Store is required for Table Layout");
|
|
}
|
|
}
|
|
updateScrollY() {
|
|
const height = this.height.value;
|
|
if (height === null)
|
|
return false;
|
|
const bodyWrapper = this.table.refs.bodyWrapper;
|
|
if (this.table.vnode.el && bodyWrapper) {
|
|
let scrollY = true;
|
|
const prevScrollY = this.scrollY.value;
|
|
if (this.bodyHeight.value === null) {
|
|
scrollY = false;
|
|
} else {
|
|
scrollY = bodyWrapper.scrollHeight > this.bodyHeight.value;
|
|
}
|
|
this.scrollY.value = scrollY;
|
|
return prevScrollY !== scrollY;
|
|
}
|
|
return false;
|
|
}
|
|
setHeight(value, prop = "height") {
|
|
if (!core.isClient)
|
|
return;
|
|
const el = this.table.vnode.el;
|
|
value = util.parseHeight(value);
|
|
this.height.value = Number(value);
|
|
if (!el && (value || value === 0))
|
|
return vue.nextTick(() => this.setHeight(value, prop));
|
|
if (typeof value === "number") {
|
|
el.style[prop] = `${value}px`;
|
|
this.updateElsHeight();
|
|
} else if (typeof value === "string") {
|
|
el.style[prop] = value;
|
|
this.updateElsHeight();
|
|
}
|
|
}
|
|
setMaxHeight(value) {
|
|
this.setHeight(value, "max-height");
|
|
}
|
|
getFlattenColumns() {
|
|
const flattenColumns = [];
|
|
const columns = this.table.store.states.columns.value;
|
|
columns.forEach((column) => {
|
|
if (column.isColumnGroup) {
|
|
flattenColumns.push.apply(flattenColumns, column.columns);
|
|
} else {
|
|
flattenColumns.push(column);
|
|
}
|
|
});
|
|
return flattenColumns;
|
|
}
|
|
updateElsHeight() {
|
|
var _a;
|
|
if (!this.table.$ready)
|
|
return vue.nextTick(() => this.updateElsHeight());
|
|
const { headerWrapper, appendWrapper, footerWrapper, bodyWrapper } = this.table.refs;
|
|
this.appendHeight.value = appendWrapper ? appendWrapper.offsetHeight : 0;
|
|
if (this.showHeader && !headerWrapper)
|
|
return;
|
|
const headerTrElm = headerWrapper ? headerWrapper.querySelector(".el-table__header tr") : null;
|
|
const noneHeader = this.headerDisplayNone(headerTrElm);
|
|
const headerHeight = this.headerHeight.value = !this.showHeader ? 0 : headerWrapper.offsetHeight;
|
|
if (this.showHeader && !noneHeader && headerWrapper.offsetWidth > 0 && (this.table.store.states.columns.value || []).length > 0 && headerHeight < 2) {
|
|
return vue.nextTick(() => this.updateElsHeight());
|
|
}
|
|
const tableHeight = this.tableHeight.value = this.table.vnode.el.clientHeight;
|
|
const footerHeight = this.footerHeight.value = footerWrapper ? footerWrapper.offsetHeight : 0;
|
|
if (this.height.value !== null) {
|
|
if (this.bodyHeight.value === null) {
|
|
requestAnimationFrame(() => this.updateElsHeight());
|
|
}
|
|
this.bodyHeight.value = tableHeight - headerHeight - footerHeight + (footerWrapper ? 1 : 0);
|
|
this.bodyScrollHeight.value = (_a = bodyWrapper.querySelector(".el-table__body")) == null ? void 0 : _a.scrollHeight;
|
|
}
|
|
this.fixedBodyHeight.value = this.scrollX.value ? this.bodyHeight.value - this.gutterWidth : this.bodyHeight.value;
|
|
this.viewportHeight.value = this.scrollX.value ? tableHeight - this.gutterWidth : tableHeight;
|
|
this.updateScrollY();
|
|
this.notifyObservers("scrollable");
|
|
}
|
|
headerDisplayNone(elm) {
|
|
if (!elm)
|
|
return true;
|
|
let headerChild = elm;
|
|
while (headerChild.tagName !== "DIV") {
|
|
if (getComputedStyle(headerChild).display === "none") {
|
|
return true;
|
|
}
|
|
headerChild = headerChild.parentElement;
|
|
}
|
|
return false;
|
|
}
|
|
updateColumnsWidth() {
|
|
if (!core.isClient)
|
|
return;
|
|
const fit = this.fit;
|
|
const bodyWidth = this.table.vnode.el.clientWidth;
|
|
let bodyMinWidth = 0;
|
|
const flattenColumns = this.getFlattenColumns();
|
|
const flexColumns = flattenColumns.filter((column) => typeof column.width !== "number");
|
|
flattenColumns.forEach((column) => {
|
|
if (typeof column.width === "number" && column.realWidth)
|
|
column.realWidth = null;
|
|
});
|
|
if (flexColumns.length > 0 && fit) {
|
|
flattenColumns.forEach((column) => {
|
|
bodyMinWidth += Number(column.width || column.minWidth || 80);
|
|
});
|
|
const scrollYWidth = this.scrollY.value ? this.gutterWidth : 0;
|
|
if (bodyMinWidth <= bodyWidth - scrollYWidth) {
|
|
this.scrollX.value = false;
|
|
const totalFlexWidth = bodyWidth - scrollYWidth - bodyMinWidth;
|
|
if (flexColumns.length === 1) {
|
|
flexColumns[0].realWidth = Number(flexColumns[0].minWidth || 80) + totalFlexWidth;
|
|
} else {
|
|
const allColumnsWidth = flexColumns.reduce((prev, column) => prev + Number(column.minWidth || 80), 0);
|
|
const flexWidthPerPixel = totalFlexWidth / allColumnsWidth;
|
|
let noneFirstWidth = 0;
|
|
flexColumns.forEach((column, index) => {
|
|
if (index === 0)
|
|
return;
|
|
const flexWidth = Math.floor(Number(column.minWidth || 80) * flexWidthPerPixel);
|
|
noneFirstWidth += flexWidth;
|
|
column.realWidth = Number(column.minWidth || 80) + flexWidth;
|
|
});
|
|
flexColumns[0].realWidth = Number(flexColumns[0].minWidth || 80) + totalFlexWidth - noneFirstWidth;
|
|
}
|
|
} else {
|
|
this.scrollX.value = true;
|
|
flexColumns.forEach(function(column) {
|
|
column.realWidth = Number(column.minWidth);
|
|
});
|
|
}
|
|
this.bodyWidth.value = Math.max(bodyMinWidth, bodyWidth);
|
|
this.table.state.resizeState.value.width = this.bodyWidth.value;
|
|
} else {
|
|
flattenColumns.forEach((column) => {
|
|
if (!column.width && !column.minWidth) {
|
|
column.realWidth = 80;
|
|
} else {
|
|
column.realWidth = Number(column.width || column.minWidth);
|
|
}
|
|
bodyMinWidth += column.realWidth;
|
|
});
|
|
this.scrollX.value = bodyMinWidth > bodyWidth;
|
|
this.bodyWidth.value = bodyMinWidth;
|
|
}
|
|
const fixedColumns = this.store.states.fixedColumns.value;
|
|
if (fixedColumns.length > 0) {
|
|
let fixedWidth = 0;
|
|
fixedColumns.forEach(function(column) {
|
|
fixedWidth += Number(column.realWidth || column.width);
|
|
});
|
|
this.fixedWidth.value = fixedWidth;
|
|
}
|
|
const rightFixedColumns = this.store.states.rightFixedColumns.value;
|
|
if (rightFixedColumns.length > 0) {
|
|
let rightFixedWidth = 0;
|
|
rightFixedColumns.forEach(function(column) {
|
|
rightFixedWidth += Number(column.realWidth || column.width);
|
|
});
|
|
this.rightFixedWidth.value = rightFixedWidth;
|
|
}
|
|
this.notifyObservers("columns");
|
|
}
|
|
addObserver(observer) {
|
|
this.observers.push(observer);
|
|
}
|
|
removeObserver(observer) {
|
|
const index = this.observers.indexOf(observer);
|
|
if (index !== -1) {
|
|
this.observers.splice(index, 1);
|
|
}
|
|
}
|
|
notifyObservers(event) {
|
|
const observers = this.observers;
|
|
observers.forEach((observer) => {
|
|
var _a, _b;
|
|
switch (event) {
|
|
case "columns":
|
|
(_a = observer.state) == null ? void 0 : _a.onColumnsChange(this);
|
|
break;
|
|
case "scrollable":
|
|
(_b = observer.state) == null ? void 0 : _b.onScrollableChange(this);
|
|
break;
|
|
default:
|
|
throw new Error(`Table Layout don't have event ${event}.`);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
exports["default"] = TableLayout;
|
|
//# sourceMappingURL=table-layout.js.map
|