This commit is contained in:
2025-09-19 14:25:20 +08:00
parent 269893a435
commit fbf3f77229
24949 changed files with 2839404 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
import type { EmitFn } from 'element-plus/es/utils';
import type { TableHeaderProps } from '.';
import type { TableColumnCtx } from '../table-column/defaults';
import type { DefaultRow, TableSortOrder } from '../table/defaults';
declare function useEvent<T extends DefaultRow>(props: TableHeaderProps<T>, emit: EmitFn<string[]>): {
handleHeaderClick: (event: Event, column: TableColumnCtx<T>) => void;
handleHeaderContextMenu: (event: Event, column: TableColumnCtx<T>) => void;
handleMouseDown: (event: MouseEvent, column: TableColumnCtx<T>) => void;
handleMouseMove: (event: MouseEvent, column: TableColumnCtx<T>) => void;
handleMouseOut: () => void;
handleSortClick: (event: Event, column: TableColumnCtx<T>, givenOrder?: TableSortOrder | boolean) => void;
handleFilterClick: (event: Event) => void;
};
export default useEvent;

View File

@@ -0,0 +1,183 @@
import { getCurrentInstance, inject, ref } from 'vue';
import { isNull } from 'lodash-unified';
import { TABLE_INJECTION_KEY } from '../tokens.mjs';
import { isClient } from '@vueuse/core';
import { addClass, hasClass, removeClass } from '../../../../utils/dom/style.mjs';
import { isElement } from '../../../../utils/types.mjs';
function useEvent(props, emit) {
const instance = getCurrentInstance();
const parent = inject(TABLE_INJECTION_KEY);
const handleFilterClick = (event) => {
event.stopPropagation();
return;
};
const handleHeaderClick = (event, column) => {
if (!column.filters && column.sortable) {
handleSortClick(event, column, false);
} else if (column.filterable && !column.sortable) {
handleFilterClick(event);
}
parent == null ? void 0 : parent.emit("header-click", column, event);
};
const handleHeaderContextMenu = (event, column) => {
parent == null ? void 0 : parent.emit("header-contextmenu", column, event);
};
const draggingColumn = ref(null);
const dragging = ref(false);
const dragState = ref();
const handleMouseDown = (event, column) => {
var _a, _b;
if (!isClient)
return;
if (column.children && column.children.length > 0)
return;
if (draggingColumn.value && props.border) {
dragging.value = true;
const table = parent;
emit("set-drag-visible", true);
const tableEl = table == null ? void 0 : table.vnode.el;
const tableLeft = tableEl == null ? void 0 : tableEl.getBoundingClientRect().left;
const columnEl = (_b = (_a = instance == null ? void 0 : instance.vnode) == null ? void 0 : _a.el) == null ? void 0 : _b.querySelector(`th.${column.id}`);
const columnRect = columnEl.getBoundingClientRect();
const minLeft = columnRect.left - tableLeft + 30;
addClass(columnEl, "noclick");
dragState.value = {
startMouseLeft: event.clientX,
startLeft: columnRect.right - tableLeft,
startColumnLeft: columnRect.left - tableLeft,
tableLeft
};
const resizeProxy = table == null ? void 0 : table.refs.resizeProxy;
resizeProxy.style.left = `${dragState.value.startLeft}px`;
document.onselectstart = function() {
return false;
};
document.ondragstart = function() {
return false;
};
const handleMouseMove2 = (event2) => {
const deltaLeft = event2.clientX - dragState.value.startMouseLeft;
const proxyLeft = dragState.value.startLeft + deltaLeft;
resizeProxy.style.left = `${Math.max(minLeft, proxyLeft)}px`;
};
const handleMouseUp = () => {
if (dragging.value) {
const { startColumnLeft, startLeft } = dragState.value;
const finalLeft = Number.parseInt(resizeProxy.style.left, 10);
const columnWidth = finalLeft - startColumnLeft;
column.width = column.realWidth = columnWidth;
table == null ? void 0 : table.emit("header-dragend", column.width, startLeft - startColumnLeft, column, event);
requestAnimationFrame(() => {
props.store.scheduleLayout(false, true);
});
document.body.style.cursor = "";
dragging.value = false;
draggingColumn.value = null;
dragState.value = void 0;
emit("set-drag-visible", false);
}
document.removeEventListener("mousemove", handleMouseMove2);
document.removeEventListener("mouseup", handleMouseUp);
document.onselectstart = null;
document.ondragstart = null;
setTimeout(() => {
removeClass(columnEl, "noclick");
}, 0);
};
document.addEventListener("mousemove", handleMouseMove2);
document.addEventListener("mouseup", handleMouseUp);
}
};
const handleMouseMove = (event, column) => {
var _a;
if (column.children && column.children.length > 0)
return;
const el = event.target;
if (!isElement(el)) {
return;
}
const target = el == null ? void 0 : el.closest("th");
if (!column || !column.resizable || !target)
return;
if (!dragging.value && props.border) {
const rect = target.getBoundingClientRect();
const bodyStyle = document.body.style;
const isLastTh = ((_a = target.parentNode) == null ? void 0 : _a.lastElementChild) === target;
const allowDarg = props.allowDragLastColumn || !isLastTh;
if (rect.width > 12 && rect.right - event.clientX < 8 && allowDarg) {
bodyStyle.cursor = "col-resize";
if (hasClass(target, "is-sortable")) {
target.style.cursor = "col-resize";
}
draggingColumn.value = column;
} else if (!dragging.value) {
bodyStyle.cursor = "";
if (hasClass(target, "is-sortable")) {
target.style.cursor = "pointer";
}
draggingColumn.value = null;
}
}
};
const handleMouseOut = () => {
if (!isClient)
return;
document.body.style.cursor = "";
};
const toggleOrder = ({ order, sortOrders }) => {
if (order === "")
return sortOrders[0];
const index = sortOrders.indexOf(order || null);
return sortOrders[index > sortOrders.length - 2 ? 0 : index + 1];
};
const handleSortClick = (event, column, givenOrder) => {
var _a;
event.stopPropagation();
const order = column.order === givenOrder ? null : givenOrder || toggleOrder(column);
const target = (_a = event.target) == null ? void 0 : _a.closest("th");
if (target) {
if (hasClass(target, "noclick")) {
removeClass(target, "noclick");
return;
}
}
if (!column.sortable)
return;
const clickTarget = event.currentTarget;
if (["ascending", "descending"].some((str) => hasClass(clickTarget, str) && !column.sortOrders.includes(str))) {
return;
}
const states = props.store.states;
let sortProp = states.sortProp.value;
let sortOrder;
const sortingColumn = states.sortingColumn.value;
if (sortingColumn !== column || sortingColumn === column && isNull(sortingColumn.order)) {
if (sortingColumn) {
sortingColumn.order = null;
}
states.sortingColumn.value = column;
sortProp = column.property;
}
if (!order) {
sortOrder = column.order = null;
} else {
sortOrder = column.order = order;
}
states.sortProp.value = sortProp;
states.sortOrder.value = sortOrder;
parent == null ? void 0 : parent.store.commit("changeSortCondition");
};
return {
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleMouseOut,
handleSortClick,
handleFilterClick
};
}
export { useEvent as default };
//# sourceMappingURL=event-helper.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,111 @@
import type TableLayout from '../table-layout';
import type { ComponentInternalInstance, PropType, Ref } from 'vue';
import type { DefaultRow, Sort } from '../table/defaults';
import type { Store } from '../store';
export interface TableHeader extends ComponentInternalInstance {
state: {
onColumnsChange: (layout: TableLayout<any>) => void;
onScrollableChange: (layout: TableLayout<any>) => void;
};
filterPanels: Ref<DefaultRow>;
}
export interface TableHeaderProps<T extends DefaultRow> {
fixed: string;
store: Store<T>;
border: boolean;
defaultSort: Sort;
allowDragLastColumn: boolean;
}
declare const _default: import("vue").DefineComponent<{
fixed: {
type: StringConstructor;
default: string;
};
store: {
required: true;
type: PropType<TableHeaderProps<any>["store"]>;
};
border: BooleanConstructor;
defaultSort: {
type: PropType<TableHeaderProps<any>["defaultSort"]>;
default: () => {
prop: string;
order: string;
};
};
appendFilterPanelTo: {
type: StringConstructor;
};
allowDragLastColumn: {
type: BooleanConstructor;
};
}, {
ns: {
namespace: import("vue").ComputedRef<string>;
b: (blockSuffix?: string) => string;
e: (element?: string) => string;
m: (modifier?: string) => string;
be: (blockSuffix?: string, element?: string) => string;
em: (element?: string, modifier?: string) => string;
bm: (blockSuffix?: string, modifier?: string) => string;
bem: (blockSuffix?: string, element?: string, modifier?: string) => string;
is: {
(name: string, state: boolean | undefined): string;
(name: string): string;
};
cssVar: (object: Record<string, string>) => Record<string, string>;
cssVarName: (name: string) => string;
cssVarBlock: (object: Record<string, string>) => Record<string, string>;
cssVarBlockName: (name: string) => string;
};
filterPanels: Ref<{}>;
onColumnsChange: (layout: TableLayout<DefaultRow>) => void;
onScrollableChange: (layout: TableLayout<DefaultRow>) => void;
columnRows: import("vue").ComputedRef<import("../table-column/defaults.js").TableColumnCtx<any>[][]>;
getHeaderRowClass: (rowIndex: number) => string;
getHeaderRowStyle: (rowIndex: number) => any;
getHeaderCellClass: (rowIndex: number, columnIndex: number, row: any, column: import("../table-column/defaults.js").TableColumnCtx<any>) => string;
getHeaderCellStyle: (rowIndex: number, columnIndex: number, row: any, column: import("../table-column/defaults.js").TableColumnCtx<any>) => import("vue").CSSProperties;
handleHeaderClick: (event: Event, column: import("../table-column/defaults.js").TableColumnCtx<any>) => void;
handleHeaderContextMenu: (event: Event, column: import("../table-column/defaults.js").TableColumnCtx<any>) => void;
handleMouseDown: (event: MouseEvent, column: import("../table-column/defaults.js").TableColumnCtx<any>) => void;
handleMouseMove: (event: MouseEvent, column: import("../table-column/defaults.js").TableColumnCtx<any>) => void;
handleMouseOut: () => void;
handleSortClick: (event: Event, column: import("../table-column/defaults.js").TableColumnCtx<any>, givenOrder?: import("../table/defaults").TableSortOrder | boolean) => void;
handleFilterClick: (event: Event) => void;
isGroup: import("vue").ComputedRef<boolean>;
toggleAllSelection: (event: Event) => void;
saveIndexSelection: Map<any, any>;
isTableLayoutAuto: boolean;
theadRef: Ref<any>;
updateFixedColumnStyle: () => void;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
fixed: {
type: StringConstructor;
default: string;
};
store: {
required: true;
type: PropType<TableHeaderProps<any>["store"]>;
};
border: BooleanConstructor;
defaultSort: {
type: PropType<TableHeaderProps<any>["defaultSort"]>;
default: () => {
prop: string;
order: string;
};
};
appendFilterPanelTo: {
type: StringConstructor;
};
allowDragLastColumn: {
type: BooleanConstructor;
};
}>>, {
fixed: string;
border: boolean;
defaultSort: Sort;
allowDragLastColumn: boolean;
}>;
export default _default;

View File

@@ -0,0 +1,225 @@
import { defineComponent, getCurrentInstance, inject, ref, reactive, watch, onBeforeUnmount, onMounted, nextTick, h } from 'vue';
import { ElCheckbox } from '../../../checkbox/index.mjs';
import FilterPanel from '../filter-panel.mjs';
import useLayoutObserver from '../layout-observer.mjs';
import { TABLE_INJECTION_KEY } from '../tokens.mjs';
import useEvent from './event-helper.mjs';
import useStyle from './style.helper.mjs';
import useUtils from './utils-helper.mjs';
import { useNamespace } from '../../../../hooks/use-namespace/index.mjs';
var TableHeader = defineComponent({
name: "ElTableHeader",
components: {
ElCheckbox
},
props: {
fixed: {
type: String,
default: ""
},
store: {
required: true,
type: Object
},
border: Boolean,
defaultSort: {
type: Object,
default: () => {
return {
prop: "",
order: ""
};
}
},
appendFilterPanelTo: {
type: String
},
allowDragLastColumn: {
type: Boolean
}
},
setup(props, { emit }) {
const instance = getCurrentInstance();
const parent = inject(TABLE_INJECTION_KEY);
const ns = useNamespace("table");
const filterPanels = ref({});
const { onColumnsChange, onScrollableChange } = useLayoutObserver(parent);
const isTableLayoutAuto = (parent == null ? void 0 : parent.props.tableLayout) === "auto";
const saveIndexSelection = reactive(/* @__PURE__ */ new Map());
const theadRef = ref();
let delayId;
const updateFixedColumnStyle = () => {
delayId = setTimeout(() => {
if (saveIndexSelection.size > 0) {
saveIndexSelection.forEach((column, key) => {
const el = theadRef.value.querySelector(`.${key.replace(/\s/g, ".")}`);
if (el) {
const width = el.getBoundingClientRect().width;
column.width = width || column.width;
}
});
saveIndexSelection.clear();
}
});
};
watch(saveIndexSelection, updateFixedColumnStyle);
onBeforeUnmount(() => {
if (delayId) {
clearTimeout(delayId);
delayId = void 0;
}
});
onMounted(async () => {
await nextTick();
await nextTick();
const { prop, order } = props.defaultSort;
parent == null ? void 0 : parent.store.commit("sort", { prop, order, init: true });
updateFixedColumnStyle();
});
const {
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleMouseOut,
handleSortClick,
handleFilterClick
} = useEvent(props, emit);
const {
getHeaderRowStyle,
getHeaderRowClass,
getHeaderCellStyle,
getHeaderCellClass
} = useStyle(props);
const { isGroup, toggleAllSelection, columnRows } = useUtils(props);
instance.state = {
onColumnsChange,
onScrollableChange
};
instance.filterPanels = filterPanels;
return {
ns,
filterPanels,
onColumnsChange,
onScrollableChange,
columnRows,
getHeaderRowClass,
getHeaderRowStyle,
getHeaderCellClass,
getHeaderCellStyle,
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleMouseOut,
handleSortClick,
handleFilterClick,
isGroup,
toggleAllSelection,
saveIndexSelection,
isTableLayoutAuto,
theadRef,
updateFixedColumnStyle
};
},
render() {
const {
ns,
isGroup,
columnRows,
getHeaderCellStyle,
getHeaderCellClass,
getHeaderRowClass,
getHeaderRowStyle,
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleSortClick,
handleMouseOut,
store,
$parent,
saveIndexSelection,
isTableLayoutAuto
} = this;
let rowSpan = 1;
return h("thead", {
ref: "theadRef",
class: { [ns.is("group")]: isGroup }
}, columnRows.map((subColumns, rowIndex) => h("tr", {
class: getHeaderRowClass(rowIndex),
key: rowIndex,
style: getHeaderRowStyle(rowIndex)
}, subColumns.map((column, cellIndex) => {
if (column.rowSpan > rowSpan) {
rowSpan = column.rowSpan;
}
const _class = getHeaderCellClass(rowIndex, cellIndex, subColumns, column);
if (isTableLayoutAuto && column.fixed) {
saveIndexSelection.set(_class, column);
}
return h("th", {
class: _class,
colspan: column.colSpan,
key: `${column.id}-thead`,
rowspan: column.rowSpan,
style: getHeaderCellStyle(rowIndex, cellIndex, subColumns, column),
onClick: ($event) => {
var _a;
if ((_a = $event.currentTarget) == null ? void 0 : _a.classList.contains("noclick")) {
return;
}
handleHeaderClick($event, column);
},
onContextmenu: ($event) => handleHeaderContextMenu($event, column),
onMousedown: ($event) => handleMouseDown($event, column),
onMousemove: ($event) => handleMouseMove($event, column),
onMouseout: handleMouseOut
}, [
h("div", {
class: [
"cell",
column.filteredValue && column.filteredValue.length > 0 ? "highlight" : ""
]
}, [
column.renderHeader ? column.renderHeader({
column,
$index: cellIndex,
store,
_self: $parent
}) : column.label,
column.sortable && h("span", {
onClick: ($event) => handleSortClick($event, column),
class: "caret-wrapper"
}, [
h("i", {
onClick: ($event) => handleSortClick($event, column, "ascending"),
class: "sort-caret ascending"
}),
h("i", {
onClick: ($event) => handleSortClick($event, column, "descending"),
class: "sort-caret descending"
})
]),
column.filterable && h(FilterPanel, {
store,
placement: column.filterPlacement || "bottom-start",
appendTo: $parent == null ? void 0 : $parent.appendFilterPanelTo,
column,
upDataColumn: (key, value) => {
column[key] = value;
}
}, {
"filter-icon": () => column.renderFilterIcon ? column.renderFilterIcon({
filterOpened: column.filterOpened
}) : null
})
])
]);
}))));
}
});
export { TableHeader as default };
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
import type { TableColumnCtx } from '../table-column/defaults';
import type { DefaultRow } from '../table/defaults';
import type { TableHeaderProps } from '.';
declare function useStyle<T extends DefaultRow>(props: TableHeaderProps<T>): {
getHeaderRowStyle: (rowIndex: number) => any;
getHeaderRowClass: (rowIndex: number) => string;
getHeaderCellStyle: (rowIndex: number, columnIndex: number, row: T, column: TableColumnCtx<T>) => import("vue").CSSProperties;
getHeaderCellClass: (rowIndex: number, columnIndex: number, row: T, column: TableColumnCtx<T>) => string;
};
export default useStyle;

View File

@@ -0,0 +1,82 @@
import { inject } from 'vue';
import { getFixedColumnOffset, ensurePosition, getFixedColumnsClass } from '../util.mjs';
import { TABLE_INJECTION_KEY } from '../tokens.mjs';
import { useNamespace } from '../../../../hooks/use-namespace/index.mjs';
import { isFunction, isString } from '@vue/shared';
function useStyle(props) {
const parent = inject(TABLE_INJECTION_KEY);
const ns = useNamespace("table");
const getHeaderRowStyle = (rowIndex) => {
const headerRowStyle = parent == null ? void 0 : parent.props.headerRowStyle;
if (isFunction(headerRowStyle)) {
return headerRowStyle.call(null, { rowIndex });
}
return headerRowStyle;
};
const getHeaderRowClass = (rowIndex) => {
const classes = [];
const headerRowClassName = parent == null ? void 0 : parent.props.headerRowClassName;
if (isString(headerRowClassName)) {
classes.push(headerRowClassName);
} else if (isFunction(headerRowClassName)) {
classes.push(headerRowClassName.call(null, { rowIndex }));
}
return classes.join(" ");
};
const getHeaderCellStyle = (rowIndex, columnIndex, row, column) => {
var _a;
let headerCellStyles = (_a = parent == null ? void 0 : parent.props.headerCellStyle) != null ? _a : {};
if (isFunction(headerCellStyles)) {
headerCellStyles = headerCellStyles.call(null, {
rowIndex,
columnIndex,
row,
column
});
}
const fixedStyle = getFixedColumnOffset(columnIndex, column.fixed, props.store, row);
ensurePosition(fixedStyle, "left");
ensurePosition(fixedStyle, "right");
return Object.assign({}, headerCellStyles, fixedStyle);
};
const getHeaderCellClass = (rowIndex, columnIndex, row, column) => {
const fixedClasses = getFixedColumnsClass(ns.b(), columnIndex, column.fixed, props.store, row);
const classes = [
column.id,
column.order,
column.headerAlign,
column.className,
column.labelClassName,
...fixedClasses
];
if (!column.children) {
classes.push("is-leaf");
}
if (column.sortable) {
classes.push("is-sortable");
}
const headerCellClassName = parent == null ? void 0 : parent.props.headerCellClassName;
if (isString(headerCellClassName)) {
classes.push(headerCellClassName);
} else if (isFunction(headerCellClassName)) {
classes.push(headerCellClassName.call(null, {
rowIndex,
columnIndex,
row,
column
}));
}
classes.push(ns.e("cell"));
return classes.filter((className) => Boolean(className)).join(" ");
};
return {
getHeaderRowStyle,
getHeaderRowClass,
getHeaderCellStyle,
getHeaderCellClass
};
}
export { useStyle as default };
//# sourceMappingURL=style.helper.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
import type { DefaultRow } from '../table/defaults';
import type { TableColumnCtx } from '../table-column/defaults';
import type { TableHeaderProps } from '.';
export declare const convertToRows: <T extends DefaultRow>(originColumns: TableColumnCtx<T>[]) => TableColumnCtx<T>[][];
declare function useUtils<T extends DefaultRow>(props: TableHeaderProps<T>): {
isGroup: import("vue").ComputedRef<boolean>;
toggleAllSelection: (event: Event) => void;
columnRows: import("vue").ComputedRef<TableColumnCtx<T>[][]>;
};
export default useUtils;

View File

@@ -0,0 +1,80 @@
import { inject, computed } from 'vue';
import { TABLE_INJECTION_KEY } from '../tokens.mjs';
const getAllColumns = (columns) => {
const result = [];
columns.forEach((column) => {
if (column.children) {
result.push(column);
result.push.apply(result, getAllColumns(column.children));
} else {
result.push(column);
}
});
return result;
};
const convertToRows = (originColumns) => {
let maxLevel = 1;
const traverse = (column, parent) => {
if (parent) {
column.level = parent.level + 1;
if (maxLevel < column.level) {
maxLevel = column.level;
}
}
if (column.children) {
let colSpan = 0;
column.children.forEach((subColumn) => {
traverse(subColumn, column);
colSpan += subColumn.colSpan;
});
column.colSpan = colSpan;
} else {
column.colSpan = 1;
}
};
originColumns.forEach((column) => {
column.level = 1;
traverse(column, void 0);
});
const rows = [];
for (let i = 0; i < maxLevel; i++) {
rows.push([]);
}
const allColumns = getAllColumns(originColumns);
allColumns.forEach((column) => {
if (!column.children) {
column.rowSpan = maxLevel - column.level + 1;
} else {
column.rowSpan = 1;
column.children.forEach((col) => col.isSubColumn = true);
}
rows[column.level - 1].push(column);
});
return rows;
};
function useUtils(props) {
const parent = inject(TABLE_INJECTION_KEY);
const columnRows = computed(() => {
return convertToRows(props.store.states.originColumns.value);
});
const isGroup = computed(() => {
const result = columnRows.value.length > 1;
if (result && parent) {
parent.state.isGroup.value = true;
}
return result;
});
const toggleAllSelection = (event) => {
event.stopPropagation();
parent == null ? void 0 : parent.store.commit("toggleAllSelection");
};
return {
isGroup,
toggleAllSelection,
columnRows
};
}
export { convertToRows, useUtils as default };
//# sourceMappingURL=utils-helper.mjs.map

File diff suppressed because one or more lines are too long