feat: initial commit - Phase 1 & 2 core features

This commit is contained in:
hiderfong
2026-04-22 17:07:33 +08:00
commit 1773bda06b
25005 changed files with 6252106 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
import { SFCWithInstall } from "../../utils/vue/typescript.js";
import "../../utils/index.js";
import { TableColumnCtx } from "./src/table-column/defaults.js";
import { CellCls, CellStyle, ColumnCls, ColumnStyle, Filter, RenderRowData, Sort, SummaryMethod, Table, TableConfigContext, TableProps, TableRefs, TableTooltipData, TreeNode } from "./src/table/defaults.js";
import { _default } from "./src/table.vue.js";
import _default$1 from "./src/table-column/index.js";
import "./src/tableColumn.js";
//#region ../../packages/components/table/index.d.ts
declare const ElTable: SFCWithInstall<typeof _default> & {
TableColumn: typeof _default$1;
};
declare const ElTableColumn: SFCWithInstall<typeof _default$1>;
type TableInstance = InstanceType<typeof _default> & unknown;
type TableColumnInstance = InstanceType<typeof _default$1> & unknown;
//#endregion
export { type CellCls, type CellStyle, type ColumnCls, type ColumnStyle, ElTable, ElTable as default, ElTableColumn, type Filter, type RenderRowData, type Sort, type SummaryMethod, type Table, type TableColumnCtx, TableColumnInstance, type TableConfigContext, TableInstance, type TableProps, type TableRefs, type TableTooltipData, type TreeNode };
+11
View File
@@ -0,0 +1,11 @@
import { withInstall, withNoopInstall } from "../../utils/vue/install.mjs";
import table_default from "./src/table.mjs";
import tableColumn_default from "./src/tableColumn.mjs";
//#region ../../packages/components/table/index.ts
const ElTable = withInstall(table_default, { TableColumn: tableColumn_default });
const ElTableColumn = withNoopInstall(tableColumn_default);
//#endregion
export { ElTable, ElTable as default, ElTableColumn };
//# sourceMappingURL=index.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","names":["Table","TableColumn"],"sources":["../../../../../packages/components/table/index.ts"],"sourcesContent":["import { withInstall, withNoopInstall } from '@element-plus/utils'\nimport Table from './src/table.vue'\nimport TableColumn from './src/tableColumn'\n\nimport type { SFCWithInstall } from '@element-plus/utils'\n\nexport const ElTable: SFCWithInstall<typeof Table> & {\n TableColumn: typeof TableColumn\n} = withInstall(Table, {\n TableColumn,\n})\nexport default ElTable\nexport const ElTableColumn: SFCWithInstall<typeof TableColumn> =\n withNoopInstall(TableColumn)\n\nexport type TableInstance = InstanceType<typeof Table> & unknown\n\nexport type TableColumnInstance = InstanceType<typeof TableColumn> & unknown\n\nexport type {\n SummaryMethod,\n Table,\n TableProps,\n TableRefs,\n ColumnCls,\n ColumnStyle,\n CellCls,\n CellStyle,\n TreeNode,\n RenderRowData,\n Sort,\n Filter,\n TableColumnCtx,\n TableTooltipData,\n TableConfigContext,\n} from './src/table/defaults'\n"],"mappings":";;;;;AAMA,MAAa,UAET,YAAYA,eAAO,EACrB,kCACD,CAAC;AAEF,MAAa,gBACX,gBAAgBC,oBAAY"}
@@ -0,0 +1,27 @@
import { isNumber } from "../../../../utils/types.mjs";
import { ref } from "vue";
//#region ../../packages/components/table/src/composables/use-scrollbar.ts
const useScrollbar = () => {
const scrollBarRef = ref();
const scrollTo = (options, yCoord) => {
const scrollbar = scrollBarRef.value;
if (scrollbar) scrollbar.scrollTo(options, yCoord);
};
const setScrollPosition = (position, offset) => {
const scrollbar = scrollBarRef.value;
if (scrollbar && isNumber(offset) && ["Top", "Left"].includes(position)) scrollbar[`setScroll${position}`](offset);
};
const setScrollTop = (top) => setScrollPosition("Top", top);
const setScrollLeft = (left) => setScrollPosition("Left", left);
return {
scrollBarRef,
scrollTo,
setScrollTop,
setScrollLeft
};
};
//#endregion
export { useScrollbar };
//# sourceMappingURL=use-scrollbar.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"use-scrollbar.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/composables/use-scrollbar.ts"],"sourcesContent":["import { ref } from 'vue'\nimport { isNumber } from '@element-plus/utils'\n\nexport const useScrollbar = () => {\n const scrollBarRef = ref()\n\n const scrollTo = (options: ScrollToOptions | number, yCoord?: number) => {\n const scrollbar = scrollBarRef.value\n if (scrollbar) {\n scrollbar.scrollTo(options, yCoord)\n }\n }\n\n const setScrollPosition = (position: 'Top' | 'Left', offset?: number) => {\n const scrollbar = scrollBarRef.value\n if (scrollbar && isNumber(offset) && ['Top', 'Left'].includes(position)) {\n scrollbar[`setScroll${position}`](offset)\n }\n }\n\n const setScrollTop = (top?: number) => setScrollPosition('Top', top)\n const setScrollLeft = (left?: number) => setScrollPosition('Left', left)\n\n return {\n scrollBarRef,\n scrollTo,\n setScrollTop,\n setScrollLeft,\n }\n}\n"],"mappings":";;;;AAGA,MAAa,qBAAqB;CAChC,MAAM,eAAe,KAAK;CAE1B,MAAM,YAAY,SAAmC,WAAoB;EACvE,MAAM,YAAY,aAAa;AAC/B,MAAI,UACF,WAAU,SAAS,SAAS,OAAO;;CAIvC,MAAM,qBAAqB,UAA0B,WAAoB;EACvE,MAAM,YAAY,aAAa;AAC/B,MAAI,aAAa,SAAS,OAAO,IAAI,CAAC,OAAO,OAAO,CAAC,SAAS,SAAS,CACrE,WAAU,YAAY,YAAY,OAAO;;CAI7C,MAAM,gBAAgB,QAAiB,kBAAkB,OAAO,IAAI;CACpE,MAAM,iBAAiB,SAAkB,kBAAkB,QAAQ,KAAK;AAExE,QAAO;EACL;EACA;EACA;EACA;EACD"}
+156
View File
@@ -0,0 +1,156 @@
import { isBoolean, isFunction, isNumber } from "../../../utils/types.mjs";
import { getProp } from "../../../utils/objects.mjs";
import { ElIcon } from "../../icon/index.mjs";
import { ElCheckbox } from "../../checkbox/index.mjs";
import { ArrowRight, Loading } from "@element-plus/icons-vue";
import { h } from "vue";
//#region ../../packages/components/table/src/config.ts
const defaultClassNames = {
selection: "table-column--selection",
expand: "table__expand-column"
};
const cellStarts = {
default: { order: "" },
selection: {
width: 48,
minWidth: 48,
realWidth: 48,
order: ""
},
expand: {
width: 48,
minWidth: 48,
realWidth: 48,
order: ""
},
index: {
width: 48,
minWidth: 48,
realWidth: 48,
order: ""
}
};
const getDefaultClassName = (type) => {
return defaultClassNames[type] || "";
};
const cellForced = {
selection: {
renderHeader({ store }) {
function isDisabled() {
return store.states.data.value && store.states.data.value.length === 0;
}
return h(ElCheckbox, {
disabled: isDisabled(),
size: store.states.tableSize.value,
indeterminate: store.states.selection.value.length > 0 && !store.states.isAllSelected.value,
"onUpdate:modelValue": store.toggleAllSelection ?? void 0,
modelValue: store.states.isAllSelected.value,
ariaLabel: store.t("el.table.selectAllLabel")
});
},
renderCell({ row, column, store, $index }) {
return h(ElCheckbox, {
disabled: column.selectable ? !column.selectable.call(null, row, $index) : false,
size: store.states.tableSize.value,
onChange: () => {
store.commit("rowSelectedChanged", row);
},
onClick: (event) => event.stopPropagation(),
modelValue: store.isSelected(row),
ariaLabel: store.t("el.table.selectRowLabel")
});
},
sortable: false,
resizable: false
},
index: {
renderHeader({ column }) {
return column.label || "#";
},
renderCell({ column, $index }) {
let i = $index + 1;
const index = column.index;
if (isNumber(index)) i = $index + index;
else if (isFunction(index)) i = index($index);
return h("div", {}, [i]);
},
sortable: false
},
expand: {
renderHeader({ column }) {
return column.label || "";
},
renderCell({ column, row, store, expanded, $index }) {
const { ns } = store;
const classes = [ns.e("expand-icon")];
if (!column.renderExpand && expanded) classes.push(ns.em("expand-icon", "expanded"));
const callback = function(e) {
e.stopPropagation();
store.toggleRowExpansion(row);
};
const isRowExpandable = store.states.rowExpandable.value?.(row, $index) ?? true;
if (!isRowExpandable) classes.push(ns.is("disabled"));
return h("button", {
type: "button",
disabled: !isRowExpandable,
"aria-label": store.t(expanded ? "el.table.collapseRowLabel" : "el.table.expandRowLabel"),
"aria-expanded": expanded,
class: classes,
onClick: callback
}, { default: () => {
if (column.renderExpand) return [column.renderExpand({
expanded,
expandable: isRowExpandable
})];
return [h(ElIcon, null, { default: () => {
return [h(ArrowRight)];
} })];
} });
},
sortable: false,
resizable: false
}
};
function defaultRenderCell({ row, column, $index }) {
const property = column.property;
const value = property && getProp(row, property).value;
if (column && column.formatter) return column.formatter(row, column, value, $index);
return value?.toString?.() || "";
}
function treeCellPrefix({ row, treeNode, store }, createPlaceholder = false) {
const { ns } = store;
if (!treeNode) {
if (createPlaceholder) return [h("span", { class: ns.e("placeholder") })];
return null;
}
const ele = [];
const callback = function(e) {
e.stopPropagation();
if (treeNode.loading) return;
store.loadOrToggle(row);
};
if (treeNode.indent) ele.push(h("span", {
class: ns.e("indent"),
style: { "padding-left": `${treeNode.indent}px` }
}));
if (isBoolean(treeNode.expanded) && !treeNode.noLazyChildren) {
const expandClasses = [ns.e("expand-icon"), treeNode.expanded ? ns.em("expand-icon", "expanded") : ""];
let icon = ArrowRight;
if (treeNode.loading) icon = Loading;
ele.push(h("button", {
type: "button",
"aria-label": store.t(treeNode.expanded ? "el.table.collapseRowLabel" : "el.table.expandRowLabel"),
"aria-expanded": treeNode.expanded,
class: expandClasses,
onClick: callback
}, { default: () => {
return [h(ElIcon, { class: ns.is("loading", treeNode.loading) }, { default: () => [h(icon)] })];
} }));
} else ele.push(h("span", { class: ns.e("placeholder") }));
return ele;
}
//#endregion
export { cellForced, cellStarts, defaultRenderCell, getDefaultClassName, treeCellPrefix };
//# sourceMappingURL=config.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,114 @@
import _plugin_vue_export_helper_default from "../../../_virtual/_plugin-vue_export-helper.mjs";
import filter_panel_vue_vue_type_script_lang_default from "./filter-panel.vue_vue_type_script_lang.mjs";
import { Fragment, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, normalizeClass, openBlock, renderList, renderSlot, resolveComponent, toDisplayString, withCtx } from "vue";
//#region ../../packages/components/table/src/filter-panel.vue
const _hoisted_1 = ["disabled"];
const _hoisted_2 = ["tabindex", "aria-checked"];
const _hoisted_3 = [
"tabindex",
"aria-checked",
"onClick"
];
const _hoisted_4 = ["aria-label"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_el_checkbox = resolveComponent("el-checkbox");
const _component_el_checkbox_group = resolveComponent("el-checkbox-group");
const _component_el_scrollbar = resolveComponent("el-scrollbar");
const _component_arrow_up = resolveComponent("arrow-up");
const _component_arrow_down = resolveComponent("arrow-down");
const _component_el_icon = resolveComponent("el-icon");
const _component_el_tooltip = resolveComponent("el-tooltip");
return openBlock(), createBlock(_component_el_tooltip, {
ref: "tooltipRef",
offset: 0,
placement: _ctx.placement,
"show-arrow": false,
trigger: "click",
role: "dialog",
teleported: "",
effect: "light",
pure: "",
loop: "",
"popper-class": _ctx.filterClassName,
persistent: "",
"append-to": _ctx.appendTo,
onShow: _ctx.handleShowTooltip,
onHide: _ctx.handleHideTooltip
}, {
content: withCtx(() => [_ctx.multiple ? (openBlock(), createElementBlock("div", {
key: 0,
ref: "rootRef",
tabindex: "-1",
class: normalizeClass(_ctx.ns.e("multiple"))
}, [createElementVNode("div", { class: normalizeClass(_ctx.ns.e("content")) }, [createVNode(_component_el_scrollbar, { "wrap-class": _ctx.ns.e("wrap") }, {
default: withCtx(() => [createVNode(_component_el_checkbox_group, {
modelValue: _ctx.filteredValue,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.filteredValue = $event),
class: normalizeClass(_ctx.ns.e("checkbox-group"))
}, {
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.filters, (filter) => {
return openBlock(), createBlock(_component_el_checkbox, {
key: filter.value,
value: filter.value
}, {
default: withCtx(() => [createTextVNode(toDisplayString(filter.text), 1)]),
_: 2
}, 1032, ["value"]);
}), 128))]),
_: 1
}, 8, ["modelValue", "class"])]),
_: 1
}, 8, ["wrap-class"])], 2), createElementVNode("div", { class: normalizeClass(_ctx.ns.e("bottom")) }, [createElementVNode("button", {
class: normalizeClass(_ctx.ns.is("disabled", _ctx.filteredValue.length === 0)),
disabled: _ctx.filteredValue.length === 0,
type: "button",
onClick: _cache[1] || (_cache[1] = (...args) => _ctx.handleConfirm && _ctx.handleConfirm(...args))
}, toDisplayString(_ctx.t("el.table.confirmFilter")), 11, _hoisted_1), createElementVNode("button", {
type: "button",
onClick: _cache[2] || (_cache[2] = (...args) => _ctx.handleReset && _ctx.handleReset(...args))
}, toDisplayString(_ctx.t("el.table.resetFilter")), 1)], 2)], 2)) : (openBlock(), createElementBlock("ul", {
key: 1,
ref: "rootRef",
tabindex: "-1",
role: "radiogroup",
class: normalizeClass(_ctx.ns.e("list")),
onKeydown: _cache[4] || (_cache[4] = (...args) => _ctx.handleKeydown && _ctx.handleKeydown(...args))
}, [createElementVNode("li", {
role: "radio",
class: normalizeClass([_ctx.ns.e("list-item"), _ctx.ns.is("active", _ctx.isPropAbsent(_ctx.filterValue))]),
tabindex: _ctx.checkedIndex === 0 ? 0 : -1,
"aria-checked": _ctx.isPropAbsent(_ctx.filterValue),
onClick: _cache[3] || (_cache[3] = ($event) => _ctx.handleSelect(null, 0))
}, toDisplayString(_ctx.t("el.table.clearFilter")), 11, _hoisted_2), (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.filters, (filter, idx) => {
return openBlock(), createElementBlock("li", {
key: filter.value,
role: "radio",
class: normalizeClass([_ctx.ns.e("list-item"), _ctx.ns.is("active", _ctx.isActive(filter))]),
tabindex: _ctx.checkedIndex === idx + 1 ? 0 : -1,
"aria-checked": _ctx.isActive(filter),
onClick: ($event) => _ctx.handleSelect(filter.value, idx + 1)
}, toDisplayString(filter.text), 11, _hoisted_3);
}), 128))], 34))]),
default: withCtx(() => [createElementVNode("button", {
type: "button",
class: normalizeClass(`${_ctx.ns.namespace.value}-table__column-filter-trigger`),
"aria-label": _ctx.t("el.table.filterLabel", { column: _ctx.column?.label || "" })
}, [createVNode(_component_el_icon, null, {
default: withCtx(() => [renderSlot(_ctx.$slots, "filter-icon", {}, () => [_ctx.column?.filterOpened ? (openBlock(), createBlock(_component_arrow_up, { key: 0 })) : (openBlock(), createBlock(_component_arrow_down, { key: 1 }))])]),
_: 3
})], 10, _hoisted_4)]),
_: 3
}, 8, [
"placement",
"popper-class",
"append-to",
"onShow",
"onHide"
]);
}
var filter_panel_default = /* @__PURE__ */ _plugin_vue_export_helper_default(filter_panel_vue_vue_type_script_lang_default, [["render", _sfc_render]]);
//#endregion
export { filter_panel_default as default };
//# sourceMappingURL=filter-panel.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,178 @@
import { EVENT_CODE } from "../../../constants/aria.mjs";
import { getEventCode } from "../../../utils/dom/event.mjs";
import { isPropAbsent } from "../../../utils/types.mjs";
import { useLocale } from "../../../hooks/use-locale/index.mjs";
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { ElIcon } from "../../icon/index.mjs";
import { useTooltipContentProps } from "../../tooltip/src/content.mjs";
import { ElTooltip } from "../../tooltip/index.mjs";
import { ElScrollbar } from "../../scrollbar/index.mjs";
import { ElCheckbox, ElCheckboxGroup } from "../../checkbox/index.mjs";
import { ArrowDown, ArrowUp } from "@element-plus/icons-vue";
import { computed, defineComponent, getCurrentInstance, ref } from "vue";
//#region ../../packages/components/table/src/filter-panel.vue?vue&type=script&lang.ts
var filter_panel_vue_vue_type_script_lang_default = defineComponent({
name: "ElTableFilterPanel",
components: {
ElCheckbox,
ElCheckboxGroup,
ElScrollbar,
ElTooltip,
ElIcon,
ArrowDown,
ArrowUp
},
props: {
placement: {
type: String,
default: "bottom-start"
},
store: { type: Object },
column: { type: Object },
upDataColumn: { type: Function },
appendTo: useTooltipContentProps.appendTo
},
setup(props) {
const instance = getCurrentInstance();
const { t } = useLocale();
const ns = useNamespace("table-filter");
const parent = instance?.parent;
if (props.column && !parent.filterPanels.value[props.column.id]) parent.filterPanels.value[props.column.id] = instance;
const tooltipRef = ref(null);
const rootRef = ref(null);
const checkedIndex = ref(0);
const filters = computed(() => {
return props.column && props.column.filters;
});
const filterClassName = computed(() => {
if (props.column && props.column.filterClassName) return `${ns.b()} ${props.column.filterClassName}`;
return ns.b();
});
const filterValue = computed({
get: () => (props.column?.filteredValue || [])[0],
set: (value) => {
if (filteredValue.value) if (!isPropAbsent(value)) filteredValue.value.splice(0, 1, value);
else filteredValue.value.splice(0, 1);
}
});
const filteredValue = computed({
get() {
if (props.column) return props.column.filteredValue || [];
return [];
},
set(value) {
if (props.column) props.upDataColumn?.("filteredValue", value);
}
});
const multiple = computed(() => {
if (props.column) return props.column.filterMultiple;
return true;
});
const isActive = (filter) => {
return filter.value === filterValue.value;
};
const hidden = () => {
tooltipRef.value?.onClose();
};
const handleConfirm = () => {
confirmFilter(filteredValue.value);
hidden();
};
const handleReset = () => {
filteredValue.value = [];
confirmFilter(filteredValue.value);
hidden();
};
const handleSelect = (_filterValue, index) => {
filterValue.value = _filterValue;
checkedIndex.value = index;
if (!isPropAbsent(_filterValue)) confirmFilter(filteredValue.value);
else confirmFilter([]);
hidden();
};
const confirmFilter = (filteredValue) => {
props.store?.commit("filterChange", {
column: props.column,
values: filteredValue
});
props.store?.updateAllSelected();
};
const handleShowTooltip = () => {
rootRef.value?.focus();
!multiple.value && initCheckedIndex();
if (props.column) props.upDataColumn?.("filterOpened", true);
};
const handleHideTooltip = () => {
if (props.column) props.upDataColumn?.("filterOpened", false);
};
const initCheckedIndex = () => {
if (isPropAbsent(filterValue)) {
checkedIndex.value = 0;
return;
}
const idx = (filters.value || []).findIndex((item) => {
return item.value === filterValue.value;
});
checkedIndex.value = idx >= 0 ? idx + 1 : 0;
};
const handleKeydown = (event) => {
const code = getEventCode(event);
const len = (filters.value ? filters.value.length : 0) + 1;
let index = checkedIndex.value;
let isPreventDefault = true;
switch (code) {
case EVENT_CODE.down:
case EVENT_CODE.right:
index = (index + 1) % len;
break;
case EVENT_CODE.up:
case EVENT_CODE.left:
index = (index - 1 + len) % len;
break;
case EVENT_CODE.tab:
hidden();
isPreventDefault = false;
break;
case EVENT_CODE.enter:
case EVENT_CODE.space:
if (index === 0) handleSelect(null, 0);
else {
const item = (filters.value || [])[index - 1];
item.value && handleSelect(item.value, index);
}
break;
default:
isPreventDefault = false;
break;
}
isPreventDefault && event.preventDefault();
checkedIndex.value = index;
rootRef.value?.querySelector(`.${ns.e("list-item")}:nth-child(${index + 1})`)?.focus();
};
return {
multiple,
filterClassName,
filteredValue,
filterValue,
filters,
handleConfirm,
handleReset,
handleSelect,
isPropAbsent,
isActive,
t,
ns,
tooltipRef,
rootRef,
checkedIndex,
handleShowTooltip,
handleHideTooltip,
handleKeydown
};
}
});
//#endregion
export { filter_panel_vue_vue_type_script_lang_default as default };
//# sourceMappingURL=filter-panel.vue_vue_type_script_lang.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
import { TableColumnCtx } from "./table-column/defaults.js";
import { DefaultRow } from "./table/defaults.js";
import * as vue from "vue";
//#region ../../packages/components/table/src/h-helper.d.ts
type Props = {
tableLayout: 'fixed' | 'auto';
columns?: TableColumnCtx<DefaultRow>[];
};
declare function hColgroup(props: Props): vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>;
declare namespace hColgroup {
var props: string[];
}
//#endregion
export { hColgroup };
@@ -0,0 +1,27 @@
import { isUndefined } from "../../../utils/types.mjs";
import { h } from "vue";
//#region ../../packages/components/table/src/h-helper.ts
function hColgroup(props) {
const isAuto = props.tableLayout === "auto";
let columns = props.columns || [];
if (isAuto) {
if (columns.every(({ width }) => isUndefined(width))) columns = [];
}
const getPropsData = (column) => {
const propsData = {
key: `${props.tableLayout}_${column.id}`,
style: {},
name: void 0
};
if (isAuto) propsData.style = { width: `${column.width}px` };
else propsData.name = column.id;
return propsData;
};
return h("colgroup", {}, columns.map((column) => h("col", getPropsData(column))));
}
hColgroup.props = ["columns", "tableLayout"];
//#endregion
export { hColgroup };
//# sourceMappingURL=h-helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"h-helper.mjs","names":[],"sources":["../../../../../../packages/components/table/src/h-helper.ts"],"sourcesContent":["import { h } from 'vue'\nimport { isUndefined } from '@element-plus/utils'\n\nimport type { TableColumnCtx } from './table-column/defaults'\nimport type { DefaultRow } from './table/defaults'\n\ntype Props = {\n tableLayout: 'fixed' | 'auto'\n columns?: TableColumnCtx<DefaultRow>[]\n}\n\nexport function hColgroup(props: Props) {\n const isAuto = props.tableLayout === 'auto'\n let columns = props.columns || []\n if (isAuto) {\n if (columns.every(({ width }) => isUndefined(width))) {\n columns = []\n }\n }\n const getPropsData = (column: TableColumnCtx<DefaultRow>) => {\n const propsData = {\n key: `${props.tableLayout}_${column.id}`,\n style: {},\n name: undefined as string | undefined,\n }\n if (isAuto) {\n propsData.style = {\n width: `${column.width}px`,\n }\n } else {\n propsData.name = column.id\n }\n return propsData\n }\n\n return h(\n 'colgroup',\n {},\n columns.map((column) => h('col', getPropsData(column)))\n )\n}\n\nhColgroup.props = ['columns', 'tableLayout']\n"],"mappings":";;;;AAWA,SAAgB,UAAU,OAAc;CACtC,MAAM,SAAS,MAAM,gBAAgB;CACrC,IAAI,UAAU,MAAM,WAAW,EAAE;AACjC,KAAI,QACF;MAAI,QAAQ,OAAO,EAAE,YAAY,YAAY,MAAM,CAAC,CAClD,WAAU,EAAE;;CAGhB,MAAM,gBAAgB,WAAuC;EAC3D,MAAM,YAAY;GAChB,KAAK,GAAG,MAAM,YAAY,GAAG,OAAO;GACpC,OAAO,EAAE;GACT,MAAM;GACP;AACD,MAAI,OACF,WAAU,QAAQ,EAChB,OAAO,GAAG,OAAO,MAAM,KACxB;MAED,WAAU,OAAO,OAAO;AAE1B,SAAO;;AAGT,QAAO,EACL,YACA,EAAE,EACF,QAAQ,KAAK,WAAW,EAAE,OAAO,aAAa,OAAO,CAAC,CAAC,CACxD;;AAGH,UAAU,QAAQ,CAAC,WAAW,cAAc"}
@@ -0,0 +1,58 @@
import { computed, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, onUpdated } from "vue";
//#region ../../packages/components/table/src/layout-observer.ts
function useLayoutObserver(root) {
const instance = getCurrentInstance();
onBeforeMount(() => {
tableLayout.value.addObserver(instance);
});
onMounted(() => {
onColumnsChange(tableLayout.value);
onScrollableChange(tableLayout.value);
});
onUpdated(() => {
onColumnsChange(tableLayout.value);
onScrollableChange(tableLayout.value);
});
onUnmounted(() => {
tableLayout.value.removeObserver(instance);
});
const tableLayout = computed(() => {
const layout = root.layout;
if (!layout) throw new Error("Can not find table layout.");
return layout;
});
const onColumnsChange = (layout) => {
const cols = root.vnode.el?.querySelectorAll("colgroup > col") || [];
if (!cols.length) return;
const flattenColumns = layout.getFlattenColumns();
const columnsMap = {};
flattenColumns.forEach((column) => {
columnsMap[column.id] = column;
});
for (let i = 0, j = cols.length; i < j; i++) {
const col = cols[i];
const column = columnsMap[col.getAttribute("name")];
if (column) col.setAttribute("width", column.realWidth || column.width);
}
};
const onScrollableChange = (layout) => {
const cols = root.vnode.el?.querySelectorAll("colgroup > col[name=gutter]") || [];
for (let i = 0, j = cols.length; i < j; i++) cols[i].setAttribute("width", layout.scrollY.value ? layout.gutterWidth : "0");
const ths = root.vnode.el?.querySelectorAll("th.gutter") || [];
for (let i = 0, j = ths.length; i < j; i++) {
const th = ths[i];
th.style.width = layout.scrollY.value ? `${layout.gutterWidth}px` : "0";
th.style.display = layout.scrollY.value ? "" : "none";
}
};
return {
tableLayout: tableLayout.value,
onColumnsChange,
onScrollableChange
};
}
//#endregion
export { useLayoutObserver as default };
//# sourceMappingURL=layout-observer.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"layout-observer.mjs","names":[],"sources":["../../../../../../packages/components/table/src/layout-observer.ts"],"sourcesContent":["import {\n computed,\n getCurrentInstance,\n onBeforeMount,\n onMounted,\n onUnmounted,\n onUpdated,\n} from 'vue'\n\nimport type { TableHeader } from './table-header'\nimport type TableLayout from './table-layout'\nimport type { DefaultRow, Table, TableColumnCtx } from './table/defaults'\n\nfunction useLayoutObserver<T extends DefaultRow>(root: Table<T>) {\n const instance = getCurrentInstance() as TableHeader\n onBeforeMount(() => {\n tableLayout.value.addObserver(instance)\n })\n onMounted(() => {\n onColumnsChange(tableLayout.value)\n onScrollableChange(tableLayout.value)\n })\n onUpdated(() => {\n onColumnsChange(tableLayout.value)\n onScrollableChange(tableLayout.value)\n })\n onUnmounted(() => {\n tableLayout.value.removeObserver(instance)\n })\n const tableLayout = computed(() => {\n const layout = root.layout as TableLayout<T>\n if (!layout) {\n throw new Error('Can not find table layout.')\n }\n return layout\n })\n const onColumnsChange = (layout: TableLayout<T>) => {\n const cols = root.vnode.el?.querySelectorAll('colgroup > col') || []\n if (!cols.length) return\n const flattenColumns = layout.getFlattenColumns()\n const columnsMap: Record<string, TableColumnCtx<T>> = {}\n flattenColumns.forEach((column) => {\n columnsMap[column.id] = column\n })\n for (let i = 0, j = cols.length; i < j; i++) {\n const col = cols[i]\n const name = col.getAttribute('name')\n const column = columnsMap[name]\n if (column) {\n col.setAttribute('width', column.realWidth || column.width)\n }\n }\n }\n\n const onScrollableChange = (layout: TableLayout<T>) => {\n const cols =\n root.vnode.el?.querySelectorAll('colgroup > col[name=gutter]') || []\n for (let i = 0, j = cols.length; i < j; i++) {\n const col = cols[i]\n col.setAttribute('width', layout.scrollY.value ? layout.gutterWidth : '0')\n }\n const ths = root.vnode.el?.querySelectorAll('th.gutter') || []\n for (let i = 0, j = ths.length; i < j; i++) {\n const th = ths[i]\n th.style.width = layout.scrollY.value ? `${layout.gutterWidth}px` : '0'\n th.style.display = layout.scrollY.value ? '' : 'none'\n }\n }\n\n return {\n tableLayout: tableLayout.value,\n onColumnsChange,\n onScrollableChange,\n }\n}\n\nexport default useLayoutObserver\n"],"mappings":";;;AAaA,SAAS,kBAAwC,MAAgB;CAC/D,MAAM,WAAW,oBAAoB;AACrC,qBAAoB;AAClB,cAAY,MAAM,YAAY,SAAS;GACvC;AACF,iBAAgB;AACd,kBAAgB,YAAY,MAAM;AAClC,qBAAmB,YAAY,MAAM;GACrC;AACF,iBAAgB;AACd,kBAAgB,YAAY,MAAM;AAClC,qBAAmB,YAAY,MAAM;GACrC;AACF,mBAAkB;AAChB,cAAY,MAAM,eAAe,SAAS;GAC1C;CACF,MAAM,cAAc,eAAe;EACjC,MAAM,SAAS,KAAK;AACpB,MAAI,CAAC,OACH,OAAM,IAAI,MAAM,6BAA6B;AAE/C,SAAO;GACP;CACF,MAAM,mBAAmB,WAA2B;EAClD,MAAM,OAAO,KAAK,MAAM,IAAI,iBAAiB,iBAAiB,IAAI,EAAE;AACpE,MAAI,CAAC,KAAK,OAAQ;EAClB,MAAM,iBAAiB,OAAO,mBAAmB;EACjD,MAAM,aAAgD,EAAE;AACxD,iBAAe,SAAS,WAAW;AACjC,cAAW,OAAO,MAAM;IACxB;AACF,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAI,GAAG,KAAK;GAC3C,MAAM,MAAM,KAAK;GAEjB,MAAM,SAAS,WADF,IAAI,aAAa,OAAO;AAErC,OAAI,OACF,KAAI,aAAa,SAAS,OAAO,aAAa,OAAO,MAAM;;;CAKjE,MAAM,sBAAsB,WAA2B;EACrD,MAAM,OACJ,KAAK,MAAM,IAAI,iBAAiB,8BAA8B,IAAI,EAAE;AACtE,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAI,GAAG,IAEtC,CADY,KAAK,GACb,aAAa,SAAS,OAAO,QAAQ,QAAQ,OAAO,cAAc,IAAI;EAE5E,MAAM,MAAM,KAAK,MAAM,IAAI,iBAAiB,YAAY,IAAI,EAAE;AAC9D,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAI,GAAG,KAAK;GAC1C,MAAM,KAAK,IAAI;AACf,MAAG,MAAM,QAAQ,OAAO,QAAQ,QAAQ,GAAG,OAAO,YAAY,MAAM;AACpE,MAAG,MAAM,UAAU,OAAO,QAAQ,QAAQ,KAAK;;;AAInD,QAAO;EACL,aAAa,YAAY;EACzB;EACA;EACD"}
@@ -0,0 +1,66 @@
import { getRowIdentity } from "../util.mjs";
import { getCurrentInstance, ref, unref } from "vue";
//#region ../../packages/components/table/src/store/current.ts
function useCurrent(watcherData) {
const instance = getCurrentInstance();
const _currentRowKey = ref(null);
const currentRow = ref(null);
const setCurrentRowKey = (key) => {
instance.store.assertRowKey();
_currentRowKey.value = key;
setCurrentRowByKey(key);
};
const restoreCurrentRowKey = () => {
_currentRowKey.value = null;
};
const setCurrentRowByKey = (key) => {
const { data, rowKey } = watcherData;
const oldCurrentRow = currentRow.value;
let _currentRow = null;
if (rowKey.value) _currentRow = (unref(data) || []).find((item) => getRowIdentity(item, rowKey.value) === key) ?? null;
currentRow.value = _currentRow ?? null;
instance.emit("current-change", currentRow.value, oldCurrentRow);
};
const updateCurrentRow = (_currentRow) => {
const oldCurrentRow = currentRow.value;
if (_currentRow && _currentRow !== oldCurrentRow) {
currentRow.value = _currentRow;
instance.emit("current-change", currentRow.value, oldCurrentRow);
return;
}
if (!_currentRow && oldCurrentRow) {
currentRow.value = null;
instance.emit("current-change", null, oldCurrentRow);
}
};
const updateCurrentRowData = () => {
const rowKey = watcherData.rowKey.value;
const data = watcherData.data.value || [];
const oldCurrentRow = currentRow.value;
if (oldCurrentRow && !data.includes(oldCurrentRow)) if (rowKey) setCurrentRowByKey(getRowIdentity(oldCurrentRow, rowKey));
else {
currentRow.value = null;
instance.emit("current-change", null, oldCurrentRow);
}
else if (_currentRowKey.value) {
setCurrentRowByKey(_currentRowKey.value);
restoreCurrentRowKey();
}
};
return {
setCurrentRowKey,
restoreCurrentRowKey,
setCurrentRowByKey,
updateCurrentRow,
updateCurrentRowData,
states: {
_currentRowKey,
currentRow
}
};
}
//#endregion
export { useCurrent as default };
//# sourceMappingURL=current.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"current.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/store/current.ts"],"sourcesContent":["import { getCurrentInstance, ref, unref } from 'vue'\nimport { getRowIdentity } from '../util'\n\nimport type { Ref } from 'vue'\nimport type { DefaultRow, Table } from '../table/defaults'\nimport type { WatcherPropsData } from '.'\n\nfunction useCurrent<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {\n const instance = getCurrentInstance() as Table<T>\n const _currentRowKey: Ref<string | null> = ref(null)\n const currentRow: Ref<T | null> = ref(null)\n\n const setCurrentRowKey = (key: string) => {\n instance.store.assertRowKey()\n _currentRowKey.value = key\n setCurrentRowByKey(key)\n }\n\n const restoreCurrentRowKey = () => {\n _currentRowKey.value = null\n }\n\n const setCurrentRowByKey = (key: string) => {\n const { data, rowKey } = watcherData\n const oldCurrentRow = currentRow.value\n let _currentRow: T | null = null\n if (rowKey.value) {\n _currentRow =\n (unref(data) || []).find(\n (item) => getRowIdentity(item, rowKey.value) === key\n ) ?? null\n }\n currentRow.value = _currentRow ?? null\n instance.emit('current-change', currentRow.value, oldCurrentRow)\n }\n\n const updateCurrentRow = (_currentRow: T) => {\n const oldCurrentRow = currentRow.value\n if (_currentRow && _currentRow !== oldCurrentRow) {\n currentRow.value = _currentRow\n instance.emit('current-change', currentRow.value, oldCurrentRow)\n return\n }\n if (!_currentRow && oldCurrentRow) {\n currentRow.value = null\n instance.emit('current-change', null, oldCurrentRow)\n }\n }\n\n const updateCurrentRowData = () => {\n const rowKey = watcherData.rowKey.value\n // data 为 null 时,解构时的默认值会被忽略\n const data = watcherData.data.value || []\n const oldCurrentRow = currentRow.value\n // 当 currentRow 不在 data 中时尝试更新数据\n if (oldCurrentRow && !data.includes(oldCurrentRow)) {\n if (rowKey) {\n const currentRowKey = getRowIdentity(oldCurrentRow, rowKey)\n setCurrentRowByKey(currentRowKey)\n } else {\n currentRow.value = null\n instance.emit('current-change', null, oldCurrentRow)\n }\n } else if (_currentRowKey.value) {\n // 把初始时下设置的 rowKey 转化成 rowData\n setCurrentRowByKey(_currentRowKey.value)\n restoreCurrentRowKey()\n }\n }\n\n return {\n setCurrentRowKey,\n restoreCurrentRowKey,\n setCurrentRowByKey,\n updateCurrentRow,\n updateCurrentRowData,\n states: {\n _currentRowKey,\n currentRow,\n },\n }\n}\n\nexport default useCurrent\n"],"mappings":";;;;AAOA,SAAS,WAAiC,aAAkC;CAC1E,MAAM,WAAW,oBAAoB;CACrC,MAAM,iBAAqC,IAAI,KAAK;CACpD,MAAM,aAA4B,IAAI,KAAK;CAE3C,MAAM,oBAAoB,QAAgB;AACxC,WAAS,MAAM,cAAc;AAC7B,iBAAe,QAAQ;AACvB,qBAAmB,IAAI;;CAGzB,MAAM,6BAA6B;AACjC,iBAAe,QAAQ;;CAGzB,MAAM,sBAAsB,QAAgB;EAC1C,MAAM,EAAE,MAAM,WAAW;EACzB,MAAM,gBAAgB,WAAW;EACjC,IAAI,cAAwB;AAC5B,MAAI,OAAO,MACT,gBACG,MAAM,KAAK,IAAI,EAAE,EAAE,MACjB,SAAS,eAAe,MAAM,OAAO,MAAM,KAAK,IAClD,IAAI;AAET,aAAW,QAAQ,eAAe;AAClC,WAAS,KAAK,kBAAkB,WAAW,OAAO,cAAc;;CAGlE,MAAM,oBAAoB,gBAAmB;EAC3C,MAAM,gBAAgB,WAAW;AACjC,MAAI,eAAe,gBAAgB,eAAe;AAChD,cAAW,QAAQ;AACnB,YAAS,KAAK,kBAAkB,WAAW,OAAO,cAAc;AAChE;;AAEF,MAAI,CAAC,eAAe,eAAe;AACjC,cAAW,QAAQ;AACnB,YAAS,KAAK,kBAAkB,MAAM,cAAc;;;CAIxD,MAAM,6BAA6B;EACjC,MAAM,SAAS,YAAY,OAAO;EAElC,MAAM,OAAO,YAAY,KAAK,SAAS,EAAE;EACzC,MAAM,gBAAgB,WAAW;AAEjC,MAAI,iBAAiB,CAAC,KAAK,SAAS,cAAc,CAChD,KAAI,OAEF,oBADsB,eAAe,eAAe,OAAO,CAC1B;OAC5B;AACL,cAAW,QAAQ;AACnB,YAAS,KAAK,kBAAkB,MAAM,cAAc;;WAE7C,eAAe,OAAO;AAE/B,sBAAmB,eAAe,MAAM;AACxC,yBAAsB;;;AAI1B,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,QAAQ;GACN;GACA;GACD;EACF"}
@@ -0,0 +1,59 @@
import { getKeysMap, getRowIdentity, toggleRowStatus } from "../util.mjs";
import { getCurrentInstance, ref } from "vue";
//#region ../../packages/components/table/src/store/expand.ts
function useExpand(watcherData) {
const instance = getCurrentInstance();
const defaultExpandAll = ref(false);
const expandRows = ref([]);
const canRowExpand = (row, index) => {
const expandableFn = instance.store.states.rowExpandable.value;
return expandableFn?.(row, index) ?? true;
};
const updateExpandRows = () => {
const data = watcherData.data.value || [];
const rowKey = watcherData.rowKey.value;
if (defaultExpandAll.value) expandRows.value = instance.store.states.rowExpandable.value ? data.filter(canRowExpand) : data.slice();
else if (rowKey) {
const expandRowsMap = getKeysMap(expandRows.value, rowKey);
expandRows.value = data.filter((row, index) => {
return !!expandRowsMap[getRowIdentity(row, rowKey)] && canRowExpand(row, index);
});
} else expandRows.value = [];
};
const toggleRowExpansion = (row, expanded) => {
const rowIndex = (watcherData.data.value || []).indexOf(row);
if (rowIndex > -1 && !canRowExpand(row, rowIndex)) return;
if (toggleRowStatus(expandRows.value, row, expanded, void 0, void 0, void 0, watcherData.rowKey.value)) instance.emit("expand-change", row, expandRows.value.slice());
};
const setExpandRowKeys = (rowKeys) => {
instance.store.assertRowKey();
const data = watcherData.data.value || [];
const rowKey = watcherData.rowKey.value;
const keysMap = getKeysMap(data, rowKey);
expandRows.value = rowKeys.reduce((prev, cur) => {
const info = keysMap[cur];
if (info && canRowExpand(info.row, info.index)) prev.push(info.row);
return prev;
}, []);
};
const isRowExpanded = (row) => {
const rowKey = watcherData.rowKey.value;
if (rowKey) return !!getKeysMap(expandRows.value, rowKey)[getRowIdentity(row, rowKey)];
return expandRows.value.includes(row);
};
return {
updateExpandRows,
toggleRowExpansion,
setExpandRowKeys,
isRowExpanded,
states: {
expandRows,
defaultExpandAll
}
};
}
//#endregion
export { useExpand as default };
//# sourceMappingURL=expand.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"expand.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/store/expand.ts"],"sourcesContent":["import { getCurrentInstance, ref } from 'vue'\nimport { getKeysMap, getRowIdentity, toggleRowStatus } from '../util'\n\nimport type { Ref } from 'vue'\nimport type { WatcherPropsData } from '.'\nimport type { DefaultRow, Table } from '../table/defaults'\n\nfunction useExpand<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {\n const instance = getCurrentInstance() as Table<T>\n const defaultExpandAll = ref(false)\n const expandRows: Ref<T[]> = ref([])\n\n const canRowExpand = (row: T, index: number) => {\n const expandableFn = instance.store.states.rowExpandable.value\n return expandableFn?.(row, index) ?? true\n }\n\n const updateExpandRows = () => {\n const data = watcherData.data.value || []\n const rowKey = watcherData.rowKey.value\n if (defaultExpandAll.value) {\n expandRows.value = instance.store.states.rowExpandable.value\n ? data.filter(canRowExpand)\n : data.slice()\n } else if (rowKey) {\n // TODO:这里的代码可以优化\n const expandRowsMap = getKeysMap(expandRows.value, rowKey)\n expandRows.value = data.filter((row, index) => {\n const rowId = getRowIdentity(row, rowKey)\n return !!expandRowsMap[rowId] && canRowExpand(row, index)\n })\n } else {\n expandRows.value = []\n }\n }\n\n const toggleRowExpansion = (row: T, expanded?: boolean) => {\n const dataArr = watcherData.data.value || []\n const rowIndex = dataArr.indexOf(row)\n if (rowIndex > -1 && !canRowExpand(row, rowIndex)) return\n\n const changed = toggleRowStatus(\n expandRows.value,\n row,\n expanded,\n undefined,\n undefined,\n undefined,\n watcherData.rowKey.value\n )\n if (changed) {\n instance.emit('expand-change', row, expandRows.value.slice())\n }\n }\n\n const setExpandRowKeys = (rowKeys: (string | number)[]) => {\n instance.store.assertRowKey()\n // TODO:这里的代码可以优化\n const data = watcherData.data.value || []\n const rowKey = watcherData.rowKey.value\n const keysMap = getKeysMap(data, rowKey)\n expandRows.value = rowKeys.reduce((prev: T[], cur) => {\n const info = keysMap[cur]\n if (info && canRowExpand(info.row, info.index)) {\n prev.push(info.row)\n }\n return prev\n }, [])\n }\n\n const isRowExpanded = (row: T): boolean => {\n const rowKey = watcherData.rowKey.value\n if (rowKey) {\n const expandMap = getKeysMap(expandRows.value, rowKey)\n return !!expandMap[getRowIdentity(row, rowKey)]\n }\n return expandRows.value.includes(row)\n }\n return {\n updateExpandRows,\n toggleRowExpansion,\n setExpandRowKeys,\n isRowExpanded,\n states: {\n expandRows,\n defaultExpandAll,\n },\n }\n}\n\nexport default useExpand\n"],"mappings":";;;;AAOA,SAAS,UAAgC,aAAkC;CACzE,MAAM,WAAW,oBAAoB;CACrC,MAAM,mBAAmB,IAAI,MAAM;CACnC,MAAM,aAAuB,IAAI,EAAE,CAAC;CAEpC,MAAM,gBAAgB,KAAQ,UAAkB;EAC9C,MAAM,eAAe,SAAS,MAAM,OAAO,cAAc;AACzD,SAAO,eAAe,KAAK,MAAM,IAAI;;CAGvC,MAAM,yBAAyB;EAC7B,MAAM,OAAO,YAAY,KAAK,SAAS,EAAE;EACzC,MAAM,SAAS,YAAY,OAAO;AAClC,MAAI,iBAAiB,MACnB,YAAW,QAAQ,SAAS,MAAM,OAAO,cAAc,QACnD,KAAK,OAAO,aAAa,GACzB,KAAK,OAAO;WACP,QAAQ;GAEjB,MAAM,gBAAgB,WAAW,WAAW,OAAO,OAAO;AAC1D,cAAW,QAAQ,KAAK,QAAQ,KAAK,UAAU;AAE7C,WAAO,CAAC,CAAC,cADK,eAAe,KAAK,OAAO,KACR,aAAa,KAAK,MAAM;KACzD;QAEF,YAAW,QAAQ,EAAE;;CAIzB,MAAM,sBAAsB,KAAQ,aAAuB;EAEzD,MAAM,YADU,YAAY,KAAK,SAAS,EAAE,EACnB,QAAQ,IAAI;AACrC,MAAI,WAAW,MAAM,CAAC,aAAa,KAAK,SAAS,CAAE;AAWnD,MATgB,gBACd,WAAW,OACX,KACA,UACA,QACA,QACA,QACA,YAAY,OAAO,MACpB,CAEC,UAAS,KAAK,iBAAiB,KAAK,WAAW,MAAM,OAAO,CAAC;;CAIjE,MAAM,oBAAoB,YAAiC;AACzD,WAAS,MAAM,cAAc;EAE7B,MAAM,OAAO,YAAY,KAAK,SAAS,EAAE;EACzC,MAAM,SAAS,YAAY,OAAO;EAClC,MAAM,UAAU,WAAW,MAAM,OAAO;AACxC,aAAW,QAAQ,QAAQ,QAAQ,MAAW,QAAQ;GACpD,MAAM,OAAO,QAAQ;AACrB,OAAI,QAAQ,aAAa,KAAK,KAAK,KAAK,MAAM,CAC5C,MAAK,KAAK,KAAK,IAAI;AAErB,UAAO;KACN,EAAE,CAAC;;CAGR,MAAM,iBAAiB,QAAoB;EACzC,MAAM,SAAS,YAAY,OAAO;AAClC,MAAI,OAEF,QAAO,CAAC,CADU,WAAW,WAAW,OAAO,OAAO,CACnC,eAAe,KAAK,OAAO;AAEhD,SAAO,WAAW,MAAM,SAAS,IAAI;;AAEvC,QAAO;EACL;EACA;EACA;EACA;EACA,QAAQ;GACN;GACA;GACD;EACF"}
@@ -0,0 +1,66 @@
import { isObject } from "../../../../utils/types.mjs";
import useStore from "./index.mjs";
import { debounce } from "lodash-unified";
import { watch } from "vue";
//#region ../../packages/components/table/src/store/helper.ts
const InitialStateMap = {
rowKey: "rowKey",
defaultExpandAll: "defaultExpandAll",
rowExpandable: "rowExpandable",
selectOnIndeterminate: "selectOnIndeterminate",
indent: "indent",
lazy: "lazy",
["treeProps.hasChildren"]: {
key: "lazyColumnIdentifier",
default: "hasChildren"
},
["treeProps.children"]: {
key: "childrenColumnName",
default: "children"
},
["treeProps.checkStrictly"]: {
key: "checkStrictly",
default: false
}
};
function createStore(table, props) {
if (!table) throw new Error("Table is required.");
const store = useStore();
store.toggleAllSelection = debounce(store._toggleAllSelection, 10);
Object.keys(InitialStateMap).forEach((key) => {
handleValue(getArrKeysValue(props, key), key, store);
});
proxyTableProps(store, props);
return store;
}
function proxyTableProps(store, props) {
Object.keys(InitialStateMap).forEach((key) => {
watch(() => getArrKeysValue(props, key), (value) => {
handleValue(value, key, store);
});
});
}
function handleValue(value, propsKey, store) {
let newVal = value;
let storeKey = InitialStateMap[propsKey];
if (isObject(storeKey)) {
newVal = newVal || storeKey.default;
storeKey = storeKey.key;
}
store.states[storeKey].value = newVal;
}
function getArrKeysValue(props, key) {
if (key.includes(".")) {
const keyList = key.split(".");
let value = props;
keyList.forEach((k) => {
value = value[k];
});
return value;
} else return props[key];
}
//#endregion
export { createStore };
//# sourceMappingURL=helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"helper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/store/helper.ts"],"sourcesContent":["import { watch } from 'vue'\nimport { debounce } from 'lodash-unified'\nimport { isObject } from '@element-plus/utils'\nimport useStore from '.'\n\nimport type { Store } from '.'\nimport type { DefaultRow, Table, TableProps } from '../table/defaults'\n\nconst InitialStateMap = {\n rowKey: 'rowKey',\n defaultExpandAll: 'defaultExpandAll',\n rowExpandable: 'rowExpandable',\n selectOnIndeterminate: 'selectOnIndeterminate',\n indent: 'indent',\n lazy: 'lazy',\n ['treeProps.hasChildren']: {\n key: 'lazyColumnIdentifier',\n default: 'hasChildren',\n },\n ['treeProps.children']: {\n key: 'childrenColumnName',\n default: 'children',\n },\n ['treeProps.checkStrictly']: {\n key: 'checkStrictly',\n default: false,\n },\n}\n\nexport function createStore<T extends DefaultRow>(\n table: Table<T>,\n props: TableProps<T>\n) {\n if (!table) {\n throw new Error('Table is required.')\n }\n\n const store = useStore<T>()\n // fix https://github.com/ElemeFE/element/issues/14075\n // related pr https://github.com/ElemeFE/element/pull/14146\n store.toggleAllSelection = debounce(store._toggleAllSelection, 10)\n Object.keys(InitialStateMap).forEach((key) => {\n handleValue(getArrKeysValue(props, key), key, store)\n })\n proxyTableProps(store, props)\n return store\n}\n\nfunction proxyTableProps<T extends DefaultRow>(\n store: Store<T>,\n props: TableProps<T>\n) {\n Object.keys(InitialStateMap).forEach((key) => {\n watch(\n () => getArrKeysValue(props, key),\n (value) => {\n handleValue(value, key, store)\n }\n )\n })\n}\n\nfunction handleValue<T extends DefaultRow>(\n value: string | boolean | Record<string, any>,\n propsKey: string,\n store: Store<T>\n) {\n let newVal = value\n let storeKey = InitialStateMap[propsKey as keyof typeof InitialStateMap]\n if (isObject(storeKey)) {\n newVal = newVal || storeKey.default\n storeKey = storeKey.key\n }\n ;((store.states as any)[storeKey] as any).value = newVal\n}\n\nfunction getArrKeysValue<T extends DefaultRow>(\n props: TableProps<T>,\n key: string\n) {\n if ((key as keyof typeof props).includes('.')) {\n const keyList = (key as keyof typeof props).split('.')\n let value: string | Record<string, any> = props\n keyList.forEach((k) => {\n value = (value as Record<string, any>)[k]\n })\n return value\n } else {\n return (props as any)[key] as boolean | string\n }\n}\n"],"mappings":";;;;;;AAQA,MAAM,kBAAkB;CACtB,QAAQ;CACR,kBAAkB;CAClB,eAAe;CACf,uBAAuB;CACvB,QAAQ;CACR,MAAM;EACL,0BAA0B;EACzB,KAAK;EACL,SAAS;EACV;EACA,uBAAuB;EACtB,KAAK;EACL,SAAS;EACV;EACA,4BAA4B;EAC3B,KAAK;EACL,SAAS;EACV;CACF;AAED,SAAgB,YACd,OACA,OACA;AACA,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,qBAAqB;CAGvC,MAAM,QAAQ,UAAa;AAG3B,OAAM,qBAAqB,SAAS,MAAM,qBAAqB,GAAG;AAClE,QAAO,KAAK,gBAAgB,CAAC,SAAS,QAAQ;AAC5C,cAAY,gBAAgB,OAAO,IAAI,EAAE,KAAK,MAAM;GACpD;AACF,iBAAgB,OAAO,MAAM;AAC7B,QAAO;;AAGT,SAAS,gBACP,OACA,OACA;AACA,QAAO,KAAK,gBAAgB,CAAC,SAAS,QAAQ;AAC5C,cACQ,gBAAgB,OAAO,IAAI,GAChC,UAAU;AACT,eAAY,OAAO,KAAK,MAAM;IAEjC;GACD;;AAGJ,SAAS,YACP,OACA,UACA,OACA;CACA,IAAI,SAAS;CACb,IAAI,WAAW,gBAAgB;AAC/B,KAAI,SAAS,SAAS,EAAE;AACtB,WAAS,UAAU,SAAS;AAC5B,aAAW,SAAS;;AAErB,CAAE,MAAM,OAAe,UAAkB,QAAQ;;AAGpD,SAAS,gBACP,OACA,KACA;AACA,KAAK,IAA2B,SAAS,IAAI,EAAE;EAC7C,MAAM,UAAW,IAA2B,MAAM,IAAI;EACtD,IAAI,QAAsC;AAC1C,UAAQ,SAAS,MAAM;AACrB,WAAS,MAA8B;IACvC;AACF,SAAO;OAEP,QAAQ,MAAc"}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,159 @@
import { useLocale } from "../../../../hooks/use-locale/index.mjs";
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import useWatcher from "./watcher.mjs";
import { isNull } from "lodash-unified";
import { getCurrentInstance, nextTick, unref } from "vue";
//#region ../../packages/components/table/src/store/index.ts
function replaceColumn(array, column) {
return array.map((item) => {
if (item.id === column.id) return column;
else if (item.children?.length) item.children = replaceColumn(item.children, column);
return item;
});
}
function sortColumn(array) {
array.forEach((item) => {
item.no = item.getColumnIndex?.();
if (item.children?.length) sortColumn(item.children);
});
array.sort((cur, pre) => cur.no - pre.no);
}
function useStore() {
const instance = getCurrentInstance();
const watcher = useWatcher();
const ns = useNamespace("table");
const { t } = useLocale();
const mutations = {
setData(states, data) {
const dataInstanceChanged = unref(states._data) !== data;
states.data.value = data;
states._data.value = data;
instance.store.execQuery();
instance.store.updateCurrentRowData();
instance.store.updateExpandRows();
instance.store.updateTreeData(instance.store.states.defaultExpandAll.value);
if (unref(states.reserveSelection)) instance.store.assertRowKey();
else if (dataInstanceChanged) instance.store.clearSelection();
else instance.store.cleanSelection();
instance.store.updateAllSelected();
if (instance.$ready) instance.store.scheduleLayout();
},
insertColumn(states, column, parent, updateColumnOrder) {
const array = unref(states._columns);
let newColumns = [];
if (!parent) {
array.push(column);
newColumns = array;
} else {
if (parent && !parent.children) parent.children = [];
parent.children?.push(column);
newColumns = replaceColumn(array, parent);
}
sortColumn(newColumns);
states._columns.value = newColumns;
states.updateOrderFns.push(updateColumnOrder);
if (column.type === "selection") {
states.selectable.value = column.selectable;
states.reserveSelection.value = column.reserveSelection;
}
if (instance.$ready) {
instance.store.updateColumns();
instance.store.scheduleLayout();
}
},
updateColumnOrder(states, column) {
if (column.getColumnIndex?.() === column.no) return;
sortColumn(states._columns.value);
if (instance.$ready) instance.store.updateColumns();
},
removeColumn(states, column, parent, updateColumnOrder) {
const array = unref(states._columns) || [];
if (parent) {
parent.children?.splice(parent.children.findIndex((item) => item.id === column.id), 1);
nextTick(() => {
if (parent.children?.length === 0) delete parent.children;
});
states._columns.value = replaceColumn(array, parent);
} else {
const index = array.indexOf(column);
if (index > -1) {
array.splice(index, 1);
states._columns.value = array;
}
}
const updateFnIndex = states.updateOrderFns.indexOf(updateColumnOrder);
updateFnIndex > -1 && states.updateOrderFns.splice(updateFnIndex, 1);
if (instance.$ready) {
instance.store.updateColumns();
instance.store.scheduleLayout();
}
},
sort(states, options) {
const { prop, order, init } = options;
if (prop) {
const column = unref(states.columns).find((column) => column.property === prop);
if (column) {
column.order = order;
instance.store.updateSort(column, prop, order);
instance.store.commit("changeSortCondition", { init });
}
}
},
changeSortCondition(states, options) {
const { sortingColumn, sortProp, sortOrder } = states;
const columnValue = unref(sortingColumn), propValue = unref(sortProp), orderValue = unref(sortOrder);
if (isNull(orderValue)) {
states.sortingColumn.value = null;
states.sortProp.value = null;
}
instance.store.execQuery({ filter: true });
if (!options || !(options.silent || options.init)) instance.emit("sort-change", {
column: columnValue,
prop: propValue,
order: orderValue
});
instance.store.updateTableScrollY();
},
filterChange(_states, options) {
const { column, values, silent } = options;
const newFilters = instance.store.updateFilters(column, values);
instance.store.execQuery();
if (!silent) instance.emit("filter-change", newFilters);
instance.store.updateTableScrollY();
},
toggleAllSelection() {
instance.store.toggleAllSelection?.();
},
rowSelectedChanged(_states, row) {
instance.store.toggleRowSelection(row);
instance.store.updateAllSelected();
},
setHoverRow(states, row) {
states.hoverRow.value = row;
},
setCurrentRow(_states, row) {
instance.store.updateCurrentRow(row);
}
};
const commit = function(name, ...args) {
const mutations = instance.store.mutations;
if (mutations[name]) mutations[name].apply(instance, [instance.store.states, ...args]);
else throw new Error(`Action not found: ${name}`);
};
const updateTableScrollY = function() {
nextTick(() => instance.layout.updateScrollY.apply(instance.layout));
};
return {
ns,
t,
...watcher,
mutations,
commit,
updateTableScrollY
};
}
//#endregion
export { useStore as default };
//# sourceMappingURL=index.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
import "./index.js";
import { TreeNode } from "../table/defaults.js";
import "vue";
//#region ../../packages/components/table/src/store/tree.d.ts
interface TreeData extends TreeNode {
children?: string[];
lazy?: boolean;
loaded?: boolean;
}
//#endregion
export { TreeData };
@@ -0,0 +1,188 @@
import { isArray, isUndefined } from "../../../../utils/types.mjs";
import { getRowIdentity, walkTreeNode } from "../util.mjs";
import { computed, getCurrentInstance, ref, unref, watch } from "vue";
//#region ../../packages/components/table/src/store/tree.ts
function useTree(watcherData) {
const expandRowKeys = ref([]);
const treeData = ref({});
const indent = ref(16);
const lazy = ref(false);
const lazyTreeNodeMap = ref({});
const lazyColumnIdentifier = ref("hasChildren");
const childrenColumnName = ref("children");
const checkStrictly = ref(false);
const instance = getCurrentInstance();
const normalizedData = computed(() => {
if (!watcherData.rowKey.value) return {};
return normalize(watcherData.data.value || []);
});
const normalizedLazyNode = computed(() => {
const rowKey = watcherData.rowKey.value;
const keys = Object.keys(lazyTreeNodeMap.value);
const res = {};
if (!keys.length) return res;
keys.forEach((key) => {
if (lazyTreeNodeMap.value[key].length) {
const item = { children: [] };
lazyTreeNodeMap.value[key].forEach((row) => {
const currentRowKey = getRowIdentity(row, rowKey);
item.children.push(currentRowKey);
if (row[lazyColumnIdentifier.value] && !res[currentRowKey]) res[currentRowKey] = { children: [] };
});
res[key] = item;
}
});
return res;
});
const normalize = (data) => {
const rowKey = watcherData.rowKey.value;
const res = {};
walkTreeNode(data, (parent, children, level) => {
const parentId = getRowIdentity(parent, rowKey);
if (isArray(children)) res[parentId] = {
children: children.map((row) => getRowIdentity(row, rowKey)),
level
};
else if (lazy.value) res[parentId] = {
children: [],
lazy: true,
level
};
}, childrenColumnName.value, lazyColumnIdentifier.value, lazy.value);
return res;
};
const updateTreeData = (ifChangeExpandRowKeys = false, ifExpandAll) => {
ifExpandAll ||= instance.store?.states.defaultExpandAll.value;
const nested = normalizedData.value;
const normalizedLazyNode_ = normalizedLazyNode.value;
const keys = Object.keys(nested);
const newTreeData = {};
if (keys.length) {
const oldTreeData = unref(treeData);
const rootLazyRowKeys = [];
const getExpanded = (oldValue, key) => {
if (ifChangeExpandRowKeys) if (expandRowKeys.value) return ifExpandAll || expandRowKeys.value.includes(key);
else return !!(ifExpandAll || oldValue?.expanded);
else {
const included = ifExpandAll || expandRowKeys.value && expandRowKeys.value.includes(key);
return !!(oldValue?.expanded || included);
}
};
keys.forEach((key) => {
const oldValue = oldTreeData[key];
const newValue = { ...nested[key] };
newValue.expanded = getExpanded(oldValue, key);
if (newValue.lazy) {
const { loaded = false, loading = false } = oldValue || {};
newValue.loaded = !!loaded;
newValue.loading = !!loading;
rootLazyRowKeys.push(key);
}
newTreeData[key] = newValue;
});
const lazyKeys = Object.keys(normalizedLazyNode_);
if (lazy.value && lazyKeys.length && rootLazyRowKeys.length) lazyKeys.forEach((key) => {
const oldValue = oldTreeData[key];
const lazyNodeChildren = normalizedLazyNode_[key].children;
if (rootLazyRowKeys.includes(key)) {
if (newTreeData[key].children?.length !== 0) throw new Error("[ElTable]children must be an empty array.");
newTreeData[key].children = lazyNodeChildren;
} else {
const { loaded = false, loading = false } = oldValue || {};
newTreeData[key] = {
lazy: true,
loaded: !!loaded,
loading: !!loading,
expanded: getExpanded(oldValue, key),
children: lazyNodeChildren,
level: void 0
};
}
});
}
treeData.value = newTreeData;
instance.store?.updateTableScrollY();
};
watch(() => expandRowKeys.value, () => {
updateTreeData(true);
}, { deep: true });
watch(() => normalizedData.value, () => {
updateTreeData();
});
watch(() => normalizedLazyNode.value, () => {
updateTreeData();
});
const updateTreeExpandKeys = (value) => {
expandRowKeys.value = value;
updateTreeData();
};
const isUseLazy = (data) => {
return lazy.value && data && "loaded" in data && !data.loaded;
};
const toggleTreeExpansion = (row, expanded) => {
instance.store.assertRowKey();
const rowKey = watcherData.rowKey.value;
const id = getRowIdentity(row, rowKey);
const data = id && treeData.value[id];
if (id && data && "expanded" in data) {
const oldExpanded = data.expanded;
expanded = isUndefined(expanded) ? !data.expanded : expanded;
treeData.value[id].expanded = expanded;
if (oldExpanded !== expanded) instance.emit("expand-change", row, expanded);
expanded && isUseLazy(data) && loadData(row, id, data);
instance.store.updateTableScrollY();
}
};
const loadOrToggle = (row) => {
instance.store.assertRowKey();
const rowKey = watcherData.rowKey.value;
const id = getRowIdentity(row, rowKey);
const data = treeData.value[id];
if (isUseLazy(data)) loadData(row, id, data);
else toggleTreeExpansion(row, void 0);
};
const loadData = (row, key, treeNode) => {
const { load } = instance.props;
if (load && !treeData.value[key].loaded) {
treeData.value[key].loading = true;
load(row, treeNode, (data) => {
if (!isArray(data)) throw new TypeError("[ElTable] data must be an array");
treeData.value[key].loading = false;
treeData.value[key].loaded = true;
treeData.value[key].expanded = true;
if (data.length) lazyTreeNodeMap.value[key] = data;
instance.emit("expand-change", row, true);
});
}
};
const updateKeyChildren = (key, data) => {
const { lazy, rowKey } = instance.props;
if (!lazy) return;
if (!rowKey) throw new Error("[Table] rowKey is required in updateKeyChild");
if (lazyTreeNodeMap.value[key]) lazyTreeNodeMap.value[key] = data;
};
return {
loadData,
loadOrToggle,
toggleTreeExpansion,
updateTreeExpandKeys,
updateTreeData,
updateKeyChildren,
normalize,
states: {
expandRowKeys,
treeData,
indent,
lazy,
lazyTreeNodeMap,
lazyColumnIdentifier,
childrenColumnName,
checkStrictly
}
};
}
//#endregion
export { useTree as default };
//# sourceMappingURL=tree.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,358 @@
import { isArray, isString } from "../../../../utils/types.mjs";
import { hasOwn } from "../../../../utils/objects.mjs";
import { ensureArray } from "../../../../utils/arrays.mjs";
import { getColumnById, getColumnByKey, getKeysMap, getRowIdentity, orderBy, toggleRowStatus } from "../util.mjs";
import useExpand from "./expand.mjs";
import useCurrent from "./current.mjs";
import useTree from "./tree.mjs";
import { computed, getCurrentInstance, ref, toRefs, unref, watch } from "vue";
//#region ../../packages/components/table/src/store/watcher.ts
const sortData = (data, states) => {
const sortingColumn = states.sortingColumn;
if (!sortingColumn || isString(sortingColumn.sortable)) return data;
return orderBy(data, states.sortProp, states.sortOrder, sortingColumn.sortMethod, sortingColumn.sortBy);
};
const doFlattenColumns = (columns) => {
const result = [];
columns.forEach((column) => {
if (column.children && column.children.length > 0) result.push.apply(result, doFlattenColumns(column.children));
else result.push(column);
});
return result;
};
function useWatcher() {
const instance = getCurrentInstance();
const { size: tableSize } = toRefs(instance.proxy?.$props);
const rowKey = ref(null);
const data = ref([]);
const _data = ref([]);
const isComplex = ref(false);
const _columns = ref([]);
const originColumns = ref([]);
const columns = ref([]);
const fixedColumns = ref([]);
const rightFixedColumns = ref([]);
const leafColumns = ref([]);
const fixedLeafColumns = ref([]);
const rightFixedLeafColumns = ref([]);
const updateOrderFns = [];
const leafColumnsLength = ref(0);
const fixedLeafColumnsLength = ref(0);
const rightFixedLeafColumnsLength = ref(0);
const isAllSelected = ref(false);
const selection = ref([]);
const reserveSelection = ref(false);
const selectOnIndeterminate = ref(false);
const selectable = ref(null);
const rowExpandable = ref(null);
const filters = ref({});
const filteredData = ref(null);
const sortingColumn = ref(null);
const sortProp = ref(null);
const sortOrder = ref(null);
const hoverRow = ref(null);
const selectedMap = computed(() => {
return rowKey.value ? getKeysMap(selection.value, rowKey.value) : void 0;
});
watch(data, () => {
if (instance.state) {
scheduleLayout(false);
if (instance.props.tableLayout === "auto") instance.refs.tableHeaderRef?.updateFixedColumnStyle();
}
}, { deep: true });
const assertRowKey = () => {
if (!rowKey.value) throw new Error("[ElTable] prop row-key is required");
};
const updateChildFixed = (column) => {
column.children?.forEach((childColumn) => {
childColumn.fixed = column.fixed;
updateChildFixed(childColumn);
});
};
const updateColumns = () => {
_columns.value.forEach((column) => {
updateChildFixed(column);
});
fixedColumns.value = _columns.value.filter((column) => [true, "left"].includes(column.fixed));
const selectColumn = _columns.value.find((column) => column.type === "selection");
let selectColFixLeft;
if (selectColumn && selectColumn.fixed !== "right" && !fixedColumns.value.includes(selectColumn)) {
if (_columns.value.indexOf(selectColumn) === 0 && fixedColumns.value.length) {
fixedColumns.value.unshift(selectColumn);
selectColFixLeft = true;
}
}
rightFixedColumns.value = _columns.value.filter((column) => column.fixed === "right");
const notFixedColumns = _columns.value.filter((column) => (selectColFixLeft ? column.type !== "selection" : true) && !column.fixed);
originColumns.value = Array.from(fixedColumns.value).concat(notFixedColumns).concat(rightFixedColumns.value);
const leafColumns = doFlattenColumns(notFixedColumns);
const fixedLeafColumns = doFlattenColumns(fixedColumns.value);
const rightFixedLeafColumns = doFlattenColumns(rightFixedColumns.value);
leafColumnsLength.value = leafColumns.length;
fixedLeafColumnsLength.value = fixedLeafColumns.length;
rightFixedLeafColumnsLength.value = rightFixedLeafColumns.length;
columns.value = Array.from(fixedLeafColumns).concat(leafColumns).concat(rightFixedLeafColumns);
isComplex.value = fixedColumns.value.length > 0 || rightFixedColumns.value.length > 0;
};
const scheduleLayout = (needUpdateColumns, immediate = false) => {
if (needUpdateColumns) updateColumns();
if (immediate) instance.state.doLayout();
else instance.state.debouncedUpdateLayout();
};
const isSelected = (row) => {
if (selectedMap.value) return !!selectedMap.value[getRowIdentity(row, rowKey.value)];
else return selection.value.includes(row);
};
const clearSelection = () => {
isAllSelected.value = false;
const oldSelection = selection.value;
selection.value = [];
if (oldSelection.length) instance.emit("selection-change", []);
};
const cleanSelection = () => {
let deleted;
if (rowKey.value) {
deleted = [];
const childrenKey = instance?.store?.states?.childrenColumnName.value;
const dataMap = getKeysMap(data.value, rowKey.value, true, childrenKey);
for (const key in selectedMap.value) if (hasOwn(selectedMap.value, key) && !dataMap[key]) deleted.push(selectedMap.value[key].row);
} else deleted = selection.value.filter((item) => !data.value.includes(item));
if (deleted.length) {
const newSelection = selection.value.filter((item) => !deleted.includes(item));
selection.value = newSelection;
instance.emit("selection-change", newSelection.slice());
}
};
const getSelectionRows = () => {
return (selection.value || []).slice();
};
const toggleRowSelection = (row, selected, emitChange = true, ignoreSelectable = false) => {
const treeProps = {
children: instance?.store?.states?.childrenColumnName.value,
checkStrictly: instance?.store?.states?.checkStrictly.value
};
if (toggleRowStatus(selection.value, row, selected, treeProps, ignoreSelectable ? void 0 : selectable.value, data.value.indexOf(row), rowKey.value)) {
const newSelection = (selection.value || []).slice();
if (emitChange) instance.emit("select", newSelection, row);
instance.emit("selection-change", newSelection);
}
};
const _toggleAllSelection = () => {
const value = selectOnIndeterminate.value ? !isAllSelected.value : !(isAllSelected.value || selection.value.length);
isAllSelected.value = value;
let selectionChanged = false;
let childrenCount = 0;
const rowKey = instance?.store?.states?.rowKey.value;
const { childrenColumnName } = instance.store.states;
const treeProps = {
children: childrenColumnName.value,
checkStrictly: false
};
data.value.forEach((row, index) => {
const rowIndex = index + childrenCount;
if (toggleRowStatus(selection.value, row, value, treeProps, selectable.value, rowIndex, rowKey)) selectionChanged = true;
childrenCount += getChildrenCount(getRowIdentity(row, rowKey));
});
if (selectionChanged) instance.emit("selection-change", selection.value ? selection.value.slice() : []);
instance.emit("select-all", (selection.value || []).slice());
};
const updateAllSelected = () => {
if (data.value?.length === 0) {
isAllSelected.value = false;
return;
}
const { childrenColumnName } = instance.store.states;
let rowIndex = 0;
let selectedCount = 0;
const checkSelectedStatus = (data) => {
for (const row of data) {
const isRowSelectable = selectable.value && selectable.value.call(null, row, rowIndex);
if (!isSelected(row)) {
if (!selectable.value || isRowSelectable) return false;
} else selectedCount++;
rowIndex++;
if (row[childrenColumnName.value]?.length && !checkSelectedStatus(row[childrenColumnName.value])) return false;
}
return true;
};
const isAllSelected_ = checkSelectedStatus(data.value || []);
isAllSelected.value = selectedCount === 0 ? false : isAllSelected_;
};
const getChildrenCount = (rowKey) => {
if (!instance || !instance.store) return 0;
const { treeData } = instance.store.states;
let count = 0;
const children = treeData.value[rowKey]?.children;
if (children) {
count += children.length;
children.forEach((childKey) => {
count += getChildrenCount(childKey);
});
}
return count;
};
const updateFilters = (column, values) => {
const filters_ = {};
ensureArray(column).forEach((col) => {
filters.value[col.id] = values;
filters_[col.columnKey || col.id] = values;
});
return filters_;
};
const updateSort = (column, prop, order) => {
if (sortingColumn.value && sortingColumn.value !== column) sortingColumn.value.order = null;
sortingColumn.value = column;
sortProp.value = prop;
sortOrder.value = order;
};
const execFilter = () => {
let sourceData = unref(_data);
Object.keys(filters.value).forEach((columnId) => {
const values = filters.value[columnId];
if (!values || values.length === 0) return;
const column = getColumnById({ columns: columns.value }, columnId);
if (column && column.filterMethod) sourceData = sourceData.filter((row) => {
return values.some((value) => column.filterMethod.call(null, value, row, column));
});
});
filteredData.value = sourceData;
};
const execSort = () => {
data.value = sortData(filteredData.value ?? [], {
sortingColumn: sortingColumn.value,
sortProp: sortProp.value,
sortOrder: sortOrder.value
});
};
const execQuery = (ignore = void 0) => {
if (!ignore?.filter) execFilter();
execSort();
};
const clearFilter = (columnKeys) => {
const { tableHeaderRef } = instance.refs;
if (!tableHeaderRef) return;
const panels = Object.assign({}, tableHeaderRef.filterPanels);
const keys = Object.keys(panels);
if (!keys.length) return;
if (isString(columnKeys)) columnKeys = [columnKeys];
if (isArray(columnKeys)) {
const columns_ = columnKeys.map((key) => getColumnByKey({ columns: columns.value }, key));
keys.forEach((key) => {
const column = columns_.find((col) => col.id === key);
if (column) column.filteredValue = [];
});
instance.store.commit("filterChange", {
column: columns_,
values: [],
silent: true,
multi: true
});
} else {
keys.forEach((key) => {
const column = columns.value.find((col) => col.id === key);
if (column) column.filteredValue = [];
});
filters.value = {};
instance.store.commit("filterChange", {
column: {},
values: [],
silent: true
});
}
};
const clearSort = () => {
if (!sortingColumn.value) return;
updateSort(null, null, null);
instance.store.commit("changeSortCondition", { silent: true });
};
const { setExpandRowKeys, toggleRowExpansion, updateExpandRows, states: expandStates, isRowExpanded } = useExpand({
data,
rowKey
});
const { updateTreeExpandKeys, toggleTreeExpansion, updateTreeData, updateKeyChildren, loadOrToggle, states: treeStates } = useTree({
data,
rowKey
});
const { updateCurrentRowData, updateCurrentRow, setCurrentRowKey, states: currentData } = useCurrent({
data,
rowKey
});
const setExpandRowKeysAdapter = (val) => {
setExpandRowKeys(val);
updateTreeExpandKeys(val);
};
const toggleRowExpansionAdapter = (row, expanded) => {
if (columns.value.some(({ type }) => type === "expand")) toggleRowExpansion(row, expanded);
else toggleTreeExpansion(row, expanded);
};
return {
assertRowKey,
updateColumns,
scheduleLayout,
isSelected,
clearSelection,
cleanSelection,
getSelectionRows,
toggleRowSelection,
_toggleAllSelection,
toggleAllSelection: null,
updateAllSelected,
updateFilters,
updateCurrentRow,
updateSort,
execFilter,
execSort,
execQuery,
clearFilter,
clearSort,
toggleRowExpansion,
setExpandRowKeysAdapter,
setCurrentRowKey,
toggleRowExpansionAdapter,
isRowExpanded,
updateExpandRows,
updateCurrentRowData,
loadOrToggle,
updateTreeData,
updateKeyChildren,
states: {
tableSize,
rowKey,
data,
_data,
isComplex,
_columns,
originColumns,
columns,
fixedColumns,
rightFixedColumns,
leafColumns,
fixedLeafColumns,
rightFixedLeafColumns,
updateOrderFns,
leafColumnsLength,
fixedLeafColumnsLength,
rightFixedLeafColumnsLength,
isAllSelected,
selection,
reserveSelection,
selectOnIndeterminate,
selectable,
rowExpandable,
filters,
filteredData,
sortingColumn,
sortProp,
sortOrder,
hoverRow,
...expandStates,
...treeStates,
...currentData
}
};
}
//#endregion
export { useWatcher as default };
//# sourceMappingURL=watcher.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
import { TableOverflowTooltipOptions } from "../util.js";
import { Store } from "../store/index.js";
import { ColumnCls, ColumnStyle, DefaultRow, Table } from "../table/defaults.js";
import { PropType } from "vue";
//#region ../../packages/components/table/src/table-body/defaults.d.ts
interface TableBodyProps<T extends DefaultRow> {
store: Store<T>;
stripe?: boolean;
context: Table<T>;
rowClassName: ColumnCls<T>;
rowStyle: ColumnStyle<T>;
fixed: string;
highlight: boolean;
tooltipEffect?: string;
tooltipOptions?: TableOverflowTooltipOptions;
}
//#endregion
export { TableBodyProps };
@@ -0,0 +1,25 @@
//#region ../../packages/components/table/src/table-body/defaults.ts
const defaultProps = {
store: {
required: true,
type: Object
},
stripe: Boolean,
tooltipEffect: String,
tooltipOptions: { type: Object },
context: {
default: () => ({}),
type: Object
},
rowClassName: [String, Function],
rowStyle: [Object, Function],
fixed: {
type: String,
default: ""
},
highlight: Boolean
};
//#endregion
export { defaultProps as default };
//# sourceMappingURL=defaults.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"defaults.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table-body/defaults.ts"],"sourcesContent":["import type { PropType } from 'vue'\nimport type { Store } from '../store'\nimport type {\n ColumnCls,\n ColumnStyle,\n DefaultRow,\n Table,\n} from '../table/defaults'\nimport type { TableOverflowTooltipOptions } from '../util'\n\ninterface TableBodyProps<T extends DefaultRow> {\n store: Store<T>\n stripe?: boolean\n context: Table<T>\n rowClassName: ColumnCls<T>\n rowStyle: ColumnStyle<T>\n fixed: string\n highlight: boolean\n tooltipEffect?: string\n tooltipOptions?: TableOverflowTooltipOptions\n}\n\nconst defaultProps = {\n store: {\n required: true,\n type: Object as PropType<TableBodyProps<any>['store']>,\n },\n stripe: Boolean,\n tooltipEffect: String,\n tooltipOptions: {\n type: Object as PropType<TableBodyProps<any>['tooltipOptions']>,\n },\n context: {\n default: () => ({}),\n type: Object as PropType<TableBodyProps<any>['context']>,\n },\n rowClassName: [String, Function] as PropType<\n TableBodyProps<any>['rowClassName']\n >,\n rowStyle: [Object, Function] as PropType<TableBodyProps<any>['rowStyle']>,\n fixed: {\n type: String,\n default: '',\n },\n highlight: Boolean,\n}\n\nexport { TableBodyProps }\nexport default defaultProps\n"],"mappings":";AAsBA,MAAM,eAAe;CACnB,OAAO;EACL,UAAU;EACV,MAAM;EACP;CACD,QAAQ;CACR,eAAe;CACf,gBAAgB,EACd,MAAM,QACP;CACD,SAAS;EACP,gBAAgB,EAAE;EAClB,MAAM;EACP;CACD,cAAc,CAAC,QAAQ,SAAS;CAGhC,UAAU,CAAC,QAAQ,SAAS;CAC5B,OAAO;EACL,MAAM;EACN,SAAS;EACV;CACD,WAAW;CACZ"}
@@ -0,0 +1,120 @@
import { addClass, hasClass, removeClass } from "../../../../utils/dom/style.mjs";
import { isGreaterThan } from "../../../../utils/numbers.mjs";
import { createTablePopper, getCell, getColumnByCell, removePopper } from "../util.mjs";
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import { debounce } from "lodash-unified";
import { h, inject, ref } from "vue";
//#region ../../packages/components/table/src/table-body/events-helper.ts
function useEvents(props) {
const parent = inject(TABLE_INJECTION_KEY);
const tooltipContent = ref("");
const tooltipTrigger = ref(h("div"));
const handleEvent = (event, row, name) => {
const table = parent;
const cell = getCell(event);
let column = null;
const namespace = table?.vnode.el?.dataset.prefix;
if (cell) {
column = getColumnByCell({ columns: props.store?.states.columns.value ?? [] }, cell, namespace);
if (column) table?.emit(`cell-${name}`, row, column, cell, event);
}
table?.emit(`row-${name}`, row, column, event);
};
const handleDoubleClick = (event, row) => {
handleEvent(event, row, "dblclick");
};
const handleClick = (event, row) => {
props.store?.commit("setCurrentRow", row);
handleEvent(event, row, "click");
};
const handleContextMenu = (event, row) => {
handleEvent(event, row, "contextmenu");
};
const handleMouseEnter = debounce((index) => {
props.store?.commit("setHoverRow", index);
}, 30);
const handleMouseLeave = debounce(() => {
props.store?.commit("setHoverRow", null);
}, 30);
const getPadding = (el) => {
const style = window.getComputedStyle(el, null);
return {
left: Number.parseInt(style.paddingLeft, 10) || 0,
right: Number.parseInt(style.paddingRight, 10) || 0,
top: Number.parseInt(style.paddingTop, 10) || 0,
bottom: Number.parseInt(style.paddingBottom, 10) || 0
};
};
const toggleRowClassByCell = (rowSpan, event, toggle) => {
let node = (event?.target)?.parentNode;
while (rowSpan > 1) {
node = node?.nextSibling;
if (!node || node.nodeName !== "TR") break;
toggle(node, "hover-row hover-fixed-row");
rowSpan--;
}
};
const handleCellMouseEnter = (event, row, tooltipOptions) => {
if (!parent) return;
const table = parent;
const cell = getCell(event);
const namespace = table?.vnode.el?.dataset.prefix;
let column = null;
if (cell) {
column = getColumnByCell({ columns: props.store?.states.columns.value ?? [] }, cell, namespace);
if (!column) return;
if (cell.rowSpan > 1) toggleRowClassByCell(cell.rowSpan, event, addClass);
const hoverState = table.hoverState = {
cell,
column,
row
};
table?.emit("cell-mouse-enter", hoverState.row, hoverState.column, hoverState.cell, event);
}
if (!tooltipOptions) {
if (removePopper?.trigger === cell) removePopper?.();
return;
}
const cellChild = event.target.querySelector(".cell");
if (!(hasClass(cellChild, `${namespace}-tooltip`) && cellChild.childNodes.length && cellChild.textContent?.trim())) return;
const range = document.createRange();
range.setStart(cellChild, 0);
range.setEnd(cellChild, cellChild.childNodes.length);
/** detail: https://github.com/element-plus/element-plus/issues/10790
* What went wrong?
* UI > Browser > Zoom, In Blink/WebKit, getBoundingClientRect() sometimes returns inexact values, probably due to lost precision during internal calculations. In the example above:
* - Expected: 188
* - Actual: 188.00000762939453
*/
const { width: rangeWidth, height: rangeHeight } = range.getBoundingClientRect();
const { width: cellChildWidth, height: cellChildHeight } = cellChild.getBoundingClientRect();
const { top, left, right, bottom } = getPadding(cellChild);
const horizontalPadding = left + right;
const verticalPadding = top + bottom;
if (isGreaterThan(rangeWidth + horizontalPadding, cellChildWidth) || isGreaterThan(rangeHeight + verticalPadding, cellChildHeight) || isGreaterThan(cellChild.scrollWidth, cellChildWidth)) createTablePopper(tooltipOptions, (cell?.innerText || cell?.textContent) ?? "", row, column, cell, table);
else if (removePopper?.trigger === cell) removePopper?.();
};
const handleCellMouseLeave = (event) => {
const cell = getCell(event);
if (!cell) return;
if (cell.rowSpan > 1) toggleRowClassByCell(cell.rowSpan, event, removeClass);
const oldHoverState = parent?.hoverState;
parent?.emit("cell-mouse-leave", oldHoverState?.row, oldHoverState?.column, oldHoverState?.cell, event);
};
return {
handleDoubleClick,
handleClick,
handleContextMenu,
handleMouseEnter,
handleMouseLeave,
handleCellMouseEnter,
handleCellMouseLeave,
tooltipContent,
tooltipTrigger
};
}
//#endregion
export { useEvents as default };
//# sourceMappingURL=events-helper.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,92 @@
import { TableLayout } from "../table-layout.js";
import { DefaultRow, Table } from "../table/defaults.js";
import { TableBodyProps } from "./defaults.js";
import "../../../../index.js";
import * as vue from "vue";
import { VNode } from "vue";
//#region ../../packages/components/table/src/table-body/index.d.ts
declare const _default: vue.DefineComponent<vue.ExtractPropTypes<{
store: {
required: boolean;
type: vue.PropType<TableBodyProps<any>["store"]>;
};
stripe: BooleanConstructor;
tooltipEffect: StringConstructor;
tooltipOptions: {
type: vue.PropType<TableBodyProps<any>["tooltipOptions"]>;
};
context: {
default: () => {};
type: vue.PropType<TableBodyProps<any>["context"]>;
};
rowClassName: vue.PropType<TableBodyProps<any>["rowClassName"]>;
rowStyle: vue.PropType<TableBodyProps<any>["rowStyle"]>;
fixed: {
type: StringConstructor;
default: string;
};
highlight: BooleanConstructor;
}>, {
ns: {
namespace: 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;
};
onColumnsChange: (layout: TableLayout<DefaultRow>) => void;
onScrollableChange: (layout: TableLayout<DefaultRow>) => void;
wrappedRowRender: (row: any, $index: number) => VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}> | VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[] | VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[][];
tooltipContent: vue.Ref<string, string>;
tooltipTrigger: vue.Ref<VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>, VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>>;
}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
store: {
required: boolean;
type: vue.PropType<TableBodyProps<any>["store"]>;
};
stripe: BooleanConstructor;
tooltipEffect: StringConstructor;
tooltipOptions: {
type: vue.PropType<TableBodyProps<any>["tooltipOptions"]>;
};
context: {
default: () => {};
type: vue.PropType<TableBodyProps<any>["context"]>;
};
rowClassName: vue.PropType<TableBodyProps<any>["rowClassName"]>;
rowStyle: vue.PropType<TableBodyProps<any>["rowStyle"]>;
fixed: {
type: StringConstructor;
default: string;
};
highlight: BooleanConstructor;
}>> & Readonly<{}>, {
fixed: string;
context: Table<any>;
stripe: boolean;
highlight: boolean;
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
//#endregion
export { _default as default };
@@ -0,0 +1,81 @@
import { isClient } from "../../../../utils/browser.mjs";
import { rAF } from "../../../../utils/raf.mjs";
import { addClass, removeClass } from "../../../../utils/dom/style.mjs";
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import { removePopper } from "../util.mjs";
import useLayoutObserver from "../layout-observer.mjs";
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import useRender from "./render-helper.mjs";
import defaultProps from "./defaults.mjs";
import { defineComponent, getCurrentInstance, h, inject, onUnmounted, watch } from "vue";
//#region ../../packages/components/table/src/table-body/index.ts
var table_body_default = defineComponent({
name: "ElTableBody",
props: defaultProps,
setup(props) {
const instance = getCurrentInstance();
const parent = inject(TABLE_INJECTION_KEY);
const ns = useNamespace("table");
const { wrappedRowRender, tooltipContent, tooltipTrigger } = useRender(props);
const { onColumnsChange, onScrollableChange } = useLayoutObserver(parent);
const hoveredCellList = [];
watch(props.store?.states.hoverRow, (newVal, oldVal) => {
const el = instance?.vnode.el;
const rows = Array.from(el?.children || []).filter((e) => e?.classList.contains(`${ns.e("row")}`));
let rowNum = newVal;
const childNodes = rows[rowNum]?.childNodes;
if (childNodes?.length) {
let control = 0;
Array.from(childNodes).reduce((acc, item, index) => {
if (childNodes[index]?.colSpan > 1) control = childNodes[index]?.colSpan;
if (item.nodeName !== "TD" && control === 0) acc.push(index);
control > 0 && control--;
return acc;
}, []).forEach((rowIndex) => {
rowNum = newVal;
while (rowNum > 0) {
const preChildNodes = rows[rowNum - 1]?.childNodes;
if (preChildNodes[rowIndex] && preChildNodes[rowIndex].nodeName === "TD" && preChildNodes[rowIndex].rowSpan > 1) {
addClass(preChildNodes[rowIndex], "hover-cell");
hoveredCellList.push(preChildNodes[rowIndex]);
break;
}
rowNum--;
}
});
} else {
hoveredCellList.forEach((item) => removeClass(item, "hover-cell"));
hoveredCellList.length = 0;
}
if (!props.store?.states.isComplex.value || !isClient) return;
rAF(() => {
const oldRow = rows[oldVal];
const newRow = rows[newVal];
if (oldRow && !oldRow.classList.contains("hover-fixed-row")) removeClass(oldRow, "hover-row");
if (newRow) addClass(newRow, "hover-row");
});
});
onUnmounted(() => {
removePopper?.();
});
return {
ns,
onColumnsChange,
onScrollableChange,
wrappedRowRender,
tooltipContent,
tooltipTrigger
};
},
render() {
const { wrappedRowRender, store } = this;
return h("tbody", { tabIndex: -1 }, [(store?.states.data.value || []).reduce((acc, row) => {
return acc.concat(wrappedRowRender(row, acc.length));
}, [])]);
}
});
//#endregion
export { table_body_default as default };
//# sourceMappingURL=index.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,179 @@
import { isBoolean, isPropAbsent } from "../../../../utils/types.mjs";
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import { getRowIdentity } from "../util.mjs";
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import useEvents from "./events-helper.mjs";
import useStyles from "./styles-helper.mjs";
import td_wrapper_default from "./td-wrapper.mjs";
import { merge } from "lodash-unified";
import { computed, h, inject } from "vue";
//#region ../../packages/components/table/src/table-body/render-helper.ts
function useRender(props) {
const parent = inject(TABLE_INJECTION_KEY);
const ns = useNamespace("table");
const { handleDoubleClick, handleClick, handleContextMenu, handleMouseEnter, handleMouseLeave, handleCellMouseEnter, handleCellMouseLeave, tooltipContent, tooltipTrigger } = useEvents(props);
const { getRowStyle, getRowClass, getCellStyle, getCellClass, getSpan, getColspanRealWidth } = useStyles(props);
let displayIndex = -1;
const firstDefaultColumnIndex = computed(() => {
return props.store?.states.columns.value.findIndex(({ type }) => type === "default");
});
const getKeyOfRow = (row, index) => {
const rowKey = (parent?.props)?.rowKey;
if (rowKey) return getRowIdentity(row, rowKey);
return index;
};
const rowRender = (row, $index, treeRowData, expanded = false) => {
const { tooltipEffect, tooltipOptions, store } = props;
const { indent, columns } = store.states;
const rowClasses = [];
let display = true;
if (treeRowData) {
rowClasses.push(ns.em("row", `level-${treeRowData.level}`));
display = !!treeRowData.display;
}
if ($index === 0) displayIndex = -1;
if (props.stripe && display) displayIndex++;
rowClasses.push(...getRowClass(row, $index, displayIndex));
return h("tr", {
style: [display ? null : { display: "none" }, getRowStyle(row, $index)],
class: rowClasses,
key: getKeyOfRow(row, $index),
onDblclick: ($event) => handleDoubleClick($event, row),
onClick: ($event) => handleClick($event, row),
onContextmenu: ($event) => handleContextMenu($event, row),
onMouseenter: () => handleMouseEnter($index),
onMouseleave: handleMouseLeave
}, columns.value.map((column, cellIndex) => {
const { rowspan, colspan } = getSpan(row, column, $index, cellIndex);
if (!rowspan || !colspan) return null;
const columnData = Object.assign({}, column);
columnData.realWidth = getColspanRealWidth(columns.value, colspan, cellIndex);
const data = {
store,
_self: props.context || parent,
column: columnData,
row,
$index,
cellIndex,
expanded
};
if (cellIndex === firstDefaultColumnIndex.value && treeRowData) {
data.treeNode = {
indent: treeRowData.level && treeRowData.level * indent.value,
level: treeRowData.level
};
if (isBoolean(treeRowData.expanded)) {
data.treeNode.expanded = treeRowData.expanded;
if ("loading" in treeRowData) data.treeNode.loading = treeRowData.loading;
if ("noLazyChildren" in treeRowData) data.treeNode.noLazyChildren = treeRowData.noLazyChildren;
}
}
const baseKey = `${getKeyOfRow(row, $index)},${cellIndex}`;
const patchKey = columnData.columnKey || columnData.rawColumnKey || "";
const mergedTooltipOptions = column.showOverflowTooltip && merge({ effect: tooltipEffect }, tooltipOptions, column.showOverflowTooltip);
return h(td_wrapper_default, {
style: getCellStyle($index, cellIndex, row, column),
class: getCellClass($index, cellIndex, row, column, colspan - 1),
key: `${patchKey}${baseKey}`,
rowspan,
colspan,
onMouseenter: ($event) => handleCellMouseEnter($event, row, mergedTooltipOptions),
onMouseleave: handleCellMouseLeave
}, { default: () => cellChildren(cellIndex, column, data) });
}));
};
const cellChildren = (_cellIndex, column, data) => {
return column.renderCell(data);
};
const wrappedRowRender = (row, $index) => {
const store = props.store;
const { isRowExpanded, assertRowKey } = store;
const { treeData, lazyTreeNodeMap, childrenColumnName, rowKey } = store.states;
const columns = store.states.columns.value;
if (columns.some(({ type }) => type === "expand")) {
const expanded = isRowExpanded(row);
const tr = rowRender(row, $index, void 0, expanded);
const renderExpanded = parent?.renderExpanded;
if (!renderExpanded) {
console.error("[Element Error]renderExpanded is required.");
return tr;
}
const rows = [[tr]];
if (parent.props.preserveExpandedContent || expanded) rows[0].push(h("tr", {
key: `expanded-row__${tr.key}`,
style: { display: expanded ? "" : "none" }
}, [h("td", {
colspan: columns.length,
class: `${ns.e("cell")} ${ns.e("expanded-cell")}`
}, [renderExpanded({
row,
$index,
store,
expanded
})])]));
return rows;
} else if (Object.keys(treeData.value).length) {
assertRowKey();
const key = getRowIdentity(row, rowKey.value);
let cur = treeData.value[key];
let treeRowData = null;
if (cur) {
treeRowData = {
expanded: cur.expanded,
level: cur.level,
display: true,
noLazyChildren: void 0,
loading: void 0
};
if (isBoolean(cur.lazy)) {
if (treeRowData && isBoolean(cur.loaded) && cur.loaded) treeRowData.noLazyChildren = !(cur.children && cur.children.length);
treeRowData.loading = cur.loading;
}
}
const tmp = [rowRender(row, $index, treeRowData ?? void 0)];
if (cur) {
let i = 0;
const traverse = (children, parent) => {
if (!(children && children.length && parent)) return;
children.forEach((node) => {
const innerTreeRowData = {
display: parent.display && parent.expanded,
level: parent.level + 1,
expanded: false,
noLazyChildren: false,
loading: false
};
const childKey = getRowIdentity(node, rowKey.value);
if (isPropAbsent(childKey)) throw new Error("For nested data item, row-key is required.");
cur = { ...treeData.value[childKey] };
if (cur) {
innerTreeRowData.expanded = cur.expanded;
cur.level = cur.level || innerTreeRowData.level;
cur.display = !!(cur.expanded && innerTreeRowData.display);
if (isBoolean(cur.lazy)) {
if (isBoolean(cur.loaded) && cur.loaded) innerTreeRowData.noLazyChildren = !(cur.children && cur.children.length);
innerTreeRowData.loading = cur.loading;
}
}
i++;
tmp.push(rowRender(node, $index + i, innerTreeRowData));
if (cur) traverse(lazyTreeNodeMap.value[childKey] || node[childrenColumnName.value], cur);
});
};
cur.display = true;
traverse(lazyTreeNodeMap.value[key] || row[childrenColumnName.value], cur);
}
return tmp;
} else return rowRender(row, $index, void 0);
};
return {
wrappedRowRender,
tooltipContent,
tooltipTrigger
};
}
//#endregion
export { useRender as default };
//# sourceMappingURL=render-helper.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,105 @@
import { isArray, isFunction, isObject, isString } from "../../../../utils/types.mjs";
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import { ensurePosition, getFixedColumnOffset, getFixedColumnsClass } from "../util.mjs";
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import { inject } from "vue";
//#region ../../packages/components/table/src/table-body/styles-helper.ts
function useStyles(props) {
const parent = inject(TABLE_INJECTION_KEY);
const ns = useNamespace("table");
const getRowStyle = (row, rowIndex) => {
const rowStyle = parent?.props.rowStyle;
if (isFunction(rowStyle)) return rowStyle.call(null, {
row,
rowIndex
});
return rowStyle || null;
};
const getRowClass = (row, rowIndex, displayIndex) => {
const classes = [ns.e("row")];
if (parent?.props.highlightCurrentRow && row === props.store?.states.currentRow.value) classes.push("current-row");
if (props.stripe && displayIndex % 2 === 1) classes.push(ns.em("row", "striped"));
const rowClassName = parent?.props.rowClassName;
if (isString(rowClassName)) classes.push(rowClassName);
else if (isFunction(rowClassName)) classes.push(rowClassName.call(null, {
row,
rowIndex
}));
return classes;
};
const getCellStyle = (rowIndex, columnIndex, row, column) => {
const cellStyle = parent?.props.cellStyle;
let cellStyles = cellStyle ?? {};
if (isFunction(cellStyle)) cellStyles = cellStyle.call(null, {
rowIndex,
columnIndex,
row,
column
});
const fixedStyle = getFixedColumnOffset(columnIndex, props?.fixed, props.store);
ensurePosition(fixedStyle, "left");
ensurePosition(fixedStyle, "right");
return Object.assign({}, cellStyles, fixedStyle);
};
const getCellClass = (rowIndex, columnIndex, row, column, offset) => {
const fixedClasses = getFixedColumnsClass(ns.b(), columnIndex, props?.fixed, props.store, void 0, offset);
const classes = [
column.id,
column.align,
column.className,
...fixedClasses
];
const cellClassName = parent?.props.cellClassName;
if (isString(cellClassName)) classes.push(cellClassName);
else if (isFunction(cellClassName)) classes.push(cellClassName.call(null, {
rowIndex,
columnIndex,
row,
column
}));
classes.push(ns.e("cell"));
return classes.filter((className) => Boolean(className)).join(" ");
};
const getSpan = (row, column, rowIndex, columnIndex) => {
let rowspan = 1;
let colspan = 1;
const fn = parent?.props.spanMethod;
if (isFunction(fn)) {
const result = fn({
row,
column,
rowIndex,
columnIndex
});
if (isArray(result)) {
rowspan = result[0];
colspan = result[1];
} else if (isObject(result)) {
rowspan = result.rowspan;
colspan = result.colspan;
}
}
return {
rowspan,
colspan
};
};
const getColspanRealWidth = (columns, colspan, index) => {
if (colspan < 1) return columns[index].realWidth;
const widthArr = columns.map(({ realWidth, width }) => realWidth || width).slice(index, index + colspan);
return Number(widthArr.reduce((acc, width) => Number(acc) + Number(width), -1));
};
return {
getRowStyle,
getRowClass,
getCellStyle,
getCellClass,
getSpan,
getColspanRealWidth
};
}
//#endregion
export { useStyles as default };
//# sourceMappingURL=styles-helper.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
import td_wrapper_vue_vue_type_script_setup_true_lang_default from "./td-wrapper.vue_vue_type_script_setup_true_lang.mjs";
//#region ../../packages/components/table/src/table-body/td-wrapper.vue
var td_wrapper_default = td_wrapper_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { td_wrapper_default as default };
//# sourceMappingURL=td-wrapper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"td-wrapper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table-body/td-wrapper.vue"],"sourcesContent":["<template>\n <td :colspan=\"colspan\" :rowspan=\"rowspan\"><slot /></td>\n</template>\n\n<script setup lang=\"ts\">\ndefineOptions({\n name: 'TableTdWrapper',\n})\n\ndefineProps({\n colspan: {\n type: Number,\n default: 1,\n },\n rowspan: {\n type: Number,\n default: 1,\n },\n})\n</script>\n"],"mappings":""}
@@ -0,0 +1,30 @@
import { createElementBlock, defineComponent, openBlock, renderSlot } from "vue";
//#region ../../packages/components/table/src/table-body/td-wrapper.vue?vue&type=script&setup=true&lang.ts
const _hoisted_1 = ["colspan", "rowspan"];
var td_wrapper_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
name: "TableTdWrapper",
__name: "td-wrapper",
props: {
colspan: {
type: Number,
default: 1
},
rowspan: {
type: Number,
default: 1
}
},
setup(__props) {
return (_ctx, _cache) => {
return openBlock(), createElementBlock("td", {
colspan: __props.colspan,
rowspan: __props.rowspan
}, [renderSlot(_ctx.$slots, "default")], 8, _hoisted_1);
};
}
});
//#endregion
export { td_wrapper_vue_vue_type_script_setup_true_lang_default as default };
//# sourceMappingURL=td-wrapper.vue_vue_type_script_setup_true_lang.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"td-wrapper.vue_vue_type_script_setup_true_lang.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table-body/td-wrapper.vue"],"sourcesContent":["<template>\n <td :colspan=\"colspan\" :rowspan=\"rowspan\"><slot /></td>\n</template>\n\n<script setup lang=\"ts\">\ndefineOptions({\n name: 'TableTdWrapper',\n})\n\ndefineProps({\n colspan: {\n type: Number,\n default: 1,\n },\n rowspan: {\n type: Number,\n default: 1,\n },\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;uBACE,mBAAuD,MAAA;IAAlD,SAAS,QAAA;IAAU,SAAS,QAAA;OAAS,WAAQ,KAAA,QAAA,UAAA"}
@@ -0,0 +1,69 @@
import { TableOverflowTooltipFormatter, TableOverflowTooltipOptions } from "../util.js";
import { Store } from "../store/index.js";
import { DefaultRow, TableSortOrder } from "../table/defaults.js";
import { ComponentInternalInstance, PropType, Ref, VNode } from "vue";
//#region ../../packages/components/table/src/table-column/defaults.d.ts
type CI<T extends DefaultRow> = {
column: TableColumnCtx<T>;
$index: number;
store: Store<T>;
_self: any;
};
type Filters = {
text: string;
value: string;
}[];
type FilterMethods<T extends DefaultRow> = (value: string, row: T, column: TableColumnCtx<T>) => void;
type TableColumnCtx<T extends DefaultRow = DefaultRow> = {
id: string;
realWidth: number | null;
type: string;
label: string;
className: string;
labelClassName: string;
property: string;
prop: string;
width?: string | number;
minWidth: string | number;
renderHeader: (data: CI<T>) => VNode;
sortable: boolean | string;
sortMethod: (a: T, b: T) => number;
sortBy: string | ((row: T, index: number, array?: T[]) => string) | string[];
resizable: boolean;
columnKey: string;
rawColumnKey: string;
align: string;
headerAlign: string;
showOverflowTooltip?: boolean | TableOverflowTooltipOptions;
tooltipFormatter?: TableOverflowTooltipFormatter<T>;
fixed: boolean | string;
formatter: (row: T, column: TableColumnCtx<T>, cellValue: any, index: number) => VNode | string;
selectable: (row: T, index: number) => boolean;
reserveSelection: boolean;
filterMethod: FilterMethods<T>;
filteredValue: string[];
filters: Filters;
filterPlacement: string;
filterMultiple: boolean;
filterClassName: string;
index: number | ((index: number) => number);
sortOrders: (TableSortOrder | null)[];
renderCell: (data: any) => VNode | VNode[];
colSpan: number;
rowSpan: number;
children?: TableColumnCtx<T>[];
level: number;
filterable: boolean | FilterMethods<T> | Filters;
order: TableSortOrder | null;
isColumnGroup: boolean;
isSubColumn: boolean;
columns: TableColumnCtx<T>[];
getColumnIndex: () => number;
no: number;
filterOpened?: boolean;
renderFilterIcon?: (scope: any) => VNode;
renderExpand?: (scope: any) => VNode;
};
//#endregion
export { type TableColumnCtx };
@@ -0,0 +1,78 @@
//#region ../../packages/components/table/src/table-column/defaults.ts
var defaults_default = {
type: {
type: String,
default: "default"
},
label: String,
className: String,
labelClassName: String,
property: String,
prop: String,
width: {
type: [String, Number],
default: ""
},
minWidth: {
type: [String, Number],
default: ""
},
renderHeader: Function,
sortable: {
type: [Boolean, String],
default: false
},
sortMethod: Function,
sortBy: [
String,
Function,
Array
],
resizable: {
type: Boolean,
default: true
},
columnKey: String,
align: String,
headerAlign: String,
showOverflowTooltip: {
type: [Boolean, Object],
default: void 0
},
tooltipFormatter: Function,
fixed: [Boolean, String],
formatter: Function,
selectable: Function,
reserveSelection: Boolean,
filterMethod: Function,
filteredValue: Array,
filters: Array,
filterPlacement: String,
filterMultiple: {
type: Boolean,
default: true
},
filterClassName: String,
index: [Number, Function],
sortOrders: {
type: Array,
default: () => {
return [
"ascending",
"descending",
null
];
},
validator: (val) => {
return val.every((order) => [
"ascending",
"descending",
null
].includes(order));
}
}
};
//#endregion
export { defaults_default as default };
//# sourceMappingURL=defaults.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,232 @@
import { ComponentSize } from "../../../../constants/size.js";
import { CheckboxProps, CheckboxValueType } from "../../../checkbox/src/checkbox.js";
import { _default as _default$1 } from "../../../checkbox/src/checkbox-button.vue.js";
import { _default as _default$2 } from "../../../checkbox/src/checkbox-group.vue.js";
import "../../../checkbox/index.js";
import { UseTooltipProps } from "../../../tooltip/src/tooltip.js";
import { TableColumnCtx } from "./defaults.js";
import { TableSortOrder } from "../table/defaults.js";
import "../../../../index.js";
import * as vue from "vue";
//#region ../../packages/components/table/src/table-column/index.d.ts
declare const _default: vue.DefineComponent<vue.ExtractPropTypes<{
type: {
type: StringConstructor;
default: string;
};
label: StringConstructor;
className: StringConstructor;
labelClassName: StringConstructor;
property: StringConstructor;
prop: StringConstructor;
width: {
type: (NumberConstructor | StringConstructor)[];
default: string;
};
minWidth: {
type: (NumberConstructor | StringConstructor)[];
default: string;
};
renderHeader: vue.PropType<TableColumnCtx<any>["renderHeader"]>;
sortable: {
type: (BooleanConstructor | StringConstructor)[];
default: boolean;
};
sortMethod: vue.PropType<TableColumnCtx<any>["sortMethod"]>;
sortBy: vue.PropType<TableColumnCtx<any>["sortBy"]>;
resizable: {
type: BooleanConstructor;
default: boolean;
};
columnKey: StringConstructor;
align: StringConstructor;
headerAlign: StringConstructor;
showOverflowTooltip: {
type: vue.PropType<TableColumnCtx<any>["showOverflowTooltip"]>;
default: undefined;
};
tooltipFormatter: vue.PropType<TableColumnCtx<any>["tooltipFormatter"]>;
fixed: (BooleanConstructor | StringConstructor)[];
formatter: vue.PropType<TableColumnCtx<any>["formatter"]>;
selectable: vue.PropType<TableColumnCtx<any>["selectable"]>;
reserveSelection: BooleanConstructor;
filterMethod: vue.PropType<TableColumnCtx<any>["filterMethod"]>;
filteredValue: vue.PropType<TableColumnCtx<any>["filteredValue"]>;
filters: vue.PropType<TableColumnCtx<any>["filters"]>;
filterPlacement: StringConstructor;
filterMultiple: {
type: BooleanConstructor;
default: boolean;
};
filterClassName: StringConstructor;
index: vue.PropType<TableColumnCtx<any>["index"]>;
sortOrders: {
type: vue.PropType<TableColumnCtx<any>["sortOrders"]>;
default: () => (string | null)[];
validator: (val: TableColumnCtx<any>["sortOrders"]) => boolean;
};
}>, void, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
type: {
type: StringConstructor;
default: string;
};
label: StringConstructor;
className: StringConstructor;
labelClassName: StringConstructor;
property: StringConstructor;
prop: StringConstructor;
width: {
type: (NumberConstructor | StringConstructor)[];
default: string;
};
minWidth: {
type: (NumberConstructor | StringConstructor)[];
default: string;
};
renderHeader: vue.PropType<TableColumnCtx<any>["renderHeader"]>;
sortable: {
type: (BooleanConstructor | StringConstructor)[];
default: boolean;
};
sortMethod: vue.PropType<TableColumnCtx<any>["sortMethod"]>;
sortBy: vue.PropType<TableColumnCtx<any>["sortBy"]>;
resizable: {
type: BooleanConstructor;
default: boolean;
};
columnKey: StringConstructor;
align: StringConstructor;
headerAlign: StringConstructor;
showOverflowTooltip: {
type: vue.PropType<TableColumnCtx<any>["showOverflowTooltip"]>;
default: undefined;
};
tooltipFormatter: vue.PropType<TableColumnCtx<any>["tooltipFormatter"]>;
fixed: (BooleanConstructor | StringConstructor)[];
formatter: vue.PropType<TableColumnCtx<any>["formatter"]>;
selectable: vue.PropType<TableColumnCtx<any>["selectable"]>;
reserveSelection: BooleanConstructor;
filterMethod: vue.PropType<TableColumnCtx<any>["filterMethod"]>;
filteredValue: vue.PropType<TableColumnCtx<any>["filteredValue"]>;
filters: vue.PropType<TableColumnCtx<any>["filters"]>;
filterPlacement: StringConstructor;
filterMultiple: {
type: BooleanConstructor;
default: boolean;
};
filterClassName: StringConstructor;
index: vue.PropType<TableColumnCtx<any>["index"]>;
sortOrders: {
type: vue.PropType<TableColumnCtx<any>["sortOrders"]>;
default: () => (string | null)[];
validator: (val: TableColumnCtx<any>["sortOrders"]) => boolean;
};
}>> & Readonly<{}>, {
type: string;
minWidth: string | number;
width: string | number;
resizable: boolean;
showOverflowTooltip: boolean | Partial<Pick<UseTooltipProps, "offset" | "appendTo" | "effect" | "enterable" | "popperClass" | "placement" | "popperOptions" | "showArrow" | "transition" | "showAfter" | "hideAfter">> | undefined;
sortOrders: (TableSortOrder | null)[];
sortable: string | boolean;
reserveSelection: boolean;
filterMultiple: boolean;
}, {}, {
ElCheckbox: {
new (...args: any[]): vue.CreateComponentPublicInstanceWithMixins<Readonly<CheckboxProps> & Readonly<{
onChange?: ((val: CheckboxValueType) => any) | undefined;
"onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
change: (val: CheckboxValueType) => void;
"update:modelValue": (val: CheckboxValueType) => void;
}, vue.PublicProps, {
id: string;
disabled: boolean;
modelValue: number | string | boolean;
validateEvent: boolean;
name: string;
value: string | boolean | number | object;
label: string | boolean | number | object;
trueValue: string | number;
falseValue: string | number;
trueLabel: string | number;
falseLabel: string | number;
}, false, {}, {}, vue.GlobalComponents, vue.GlobalDirectives, string, {}, any, vue.ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, Readonly<CheckboxProps> & Readonly<{
onChange?: ((val: CheckboxValueType) => any) | undefined;
"onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
}>, {}, {}, {}, {}, {
id: string;
disabled: boolean;
modelValue: number | string | boolean;
validateEvent: boolean;
name: string;
value: string | boolean | number | object;
label: string | boolean | number | object;
trueValue: string | number;
falseValue: string | number;
trueLabel: string | number;
falseLabel: string | number;
}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & vue.ComponentOptionsBase<Readonly<CheckboxProps> & Readonly<{
onChange?: ((val: CheckboxValueType) => any) | undefined;
"onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
change: (val: CheckboxValueType) => void;
"update:modelValue": (val: CheckboxValueType) => void;
}, string, {
id: string;
disabled: boolean;
modelValue: number | string | boolean;
validateEvent: boolean;
name: string;
value: string | boolean | number | object;
label: string | boolean | number | object;
trueValue: string | number;
falseValue: string | number;
trueLabel: string | number;
falseLabel: string | number;
}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
$slots: {
default?: (props: {}) => any;
};
}) & vue.ObjectPlugin & {
setPropsDefaults: (defaults: Partial<Omit<{
readonly modelValue?: (number | string | boolean) | undefined;
readonly label?: (string | boolean | number | object) | undefined;
readonly value?: (string | boolean | number | object) | undefined;
readonly indeterminate?: boolean | undefined;
readonly disabled?: boolean | undefined;
readonly checked?: boolean | undefined;
readonly name?: string | undefined;
readonly trueValue?: (string | number) | undefined;
readonly falseValue?: (string | number) | undefined;
readonly trueLabel?: (string | number) | undefined;
readonly falseLabel?: (string | number) | undefined;
readonly id?: string | undefined;
readonly border?: boolean | undefined;
readonly size?: ComponentSize | undefined;
readonly tabindex?: (string | number) | undefined;
readonly validateEvent?: boolean | undefined;
readonly ariaLabel?: string | undefined;
readonly ariaControls?: string | undefined;
readonly onChange?: ((val: CheckboxValueType) => any) | undefined;
readonly "onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
} & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, "onChange" | "onUpdate:modelValue" | keyof vue.VNodeProps | keyof vue.AllowedComponentProps>>) => void;
} & {
CheckboxButton: typeof _default$1;
CheckboxGroup: typeof _default$2;
};
}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
//#endregion
export { _default as default };
@@ -0,0 +1,122 @@
import { isArray, isString, isUndefined } from "../../../../utils/types.mjs";
import { useGlobalConfig } from "../../../config-provider/src/hooks/use-global-config.mjs";
import { ElCheckbox } from "../../../checkbox/index.mjs";
import { compose, mergeOptions } from "../util.mjs";
import { cellStarts } from "../config.mjs";
import useWatcher from "./watcher-helper.mjs";
import useRender from "./render-helper.mjs";
import defaults_default from "./defaults.mjs";
import { Fragment, computed, defineComponent, getCurrentInstance, h, onBeforeMount, onBeforeUnmount, onMounted, ref } from "vue";
//#region ../../packages/components/table/src/table-column/index.ts
let columnIdSeed = 1;
var table_column_default = defineComponent({
name: "ElTableColumn",
components: { ElCheckbox },
props: defaults_default,
setup(props, { slots }) {
const instance = getCurrentInstance();
const globalConfig = useGlobalConfig("table");
const columnConfig = ref({});
const owner = computed(() => {
let parent = instance.parent;
while (parent && !parent.tableId) parent = parent.parent;
return parent;
});
const { registerNormalWatchers, registerComplexWatchers } = useWatcher(owner, props);
const { columnId, isSubColumn, realHeaderAlign, columnOrTableParent, setColumnWidth, setColumnForcedProps, setColumnRenders, getPropsData, getColumnElIndex, realAlign, updateColumnOrder } = useRender(props, slots, owner);
const parent = columnOrTableParent.value;
columnId.value = `${"tableId" in parent && parent.tableId || "columnId" in parent && parent.columnId}_column_${columnIdSeed++}`;
onBeforeMount(() => {
isSubColumn.value = owner.value !== parent;
const type = props.type || "default";
const sortable = props.sortable === "" ? true : props.sortable;
const showOverflowTooltip = type === "selection" ? false : isUndefined(props.showOverflowTooltip) ? parent.props.showOverflowTooltip ?? globalConfig.value?.showOverflowTooltip : props.showOverflowTooltip;
const tooltipFormatter = isUndefined(props.tooltipFormatter) ? parent.props.tooltipFormatter ?? globalConfig.value?.tooltipFormatter : props.tooltipFormatter;
const defaults = {
...cellStarts[type],
id: columnId.value,
type,
property: props.prop || props.property,
align: realAlign,
headerAlign: realHeaderAlign,
showOverflowTooltip,
tooltipFormatter,
filterable: props.filters || props.filterMethod,
filteredValue: [],
filterPlacement: "",
filterClassName: "",
isColumnGroup: false,
isSubColumn: false,
filterOpened: false,
sortable,
index: props.index,
rawColumnKey: instance.vnode.key
};
let column = getPropsData([
"columnKey",
"label",
"className",
"labelClassName",
"type",
"renderHeader",
"formatter",
"fixed",
"resizable"
], [
"sortMethod",
"sortBy",
"sortOrders"
], ["selectable", "reserveSelection"], [
"filterMethod",
"filters",
"filterMultiple",
"filterOpened",
"filteredValue",
"filterPlacement",
"filterClassName"
]);
column = mergeOptions(defaults, column);
column = compose(setColumnRenders, setColumnWidth, setColumnForcedProps)(column);
columnConfig.value = column;
registerNormalWatchers();
registerComplexWatchers();
});
onMounted(() => {
const parent = columnOrTableParent.value;
const children = isSubColumn.value ? parent.vnode.el?.children : parent.refs.hiddenColumns?.children;
const getColumnIndex = () => getColumnElIndex(children || [], instance.vnode.el);
columnConfig.value.getColumnIndex = getColumnIndex;
getColumnIndex() > -1 && owner.value.store.commit("insertColumn", columnConfig.value, isSubColumn.value ? "columnConfig" in parent && parent.columnConfig.value : null, updateColumnOrder);
});
onBeforeUnmount(() => {
const getColumnIndex = columnConfig.value.getColumnIndex;
(getColumnIndex ? getColumnIndex() : -1) > -1 && owner.value.store.commit("removeColumn", columnConfig.value, isSubColumn.value ? "columnConfig" in parent && parent.columnConfig.value : null, updateColumnOrder);
});
instance.columnId = columnId.value;
instance.columnConfig = columnConfig;
},
render() {
try {
const renderDefault = this.$slots.default?.({
row: {},
column: {},
$index: -1
});
const children = [];
if (isArray(renderDefault)) {
for (const childNode of renderDefault) if (childNode.type?.name === "ElTableColumn" || childNode.shapeFlag & 2) children.push(childNode);
else if (childNode.type === Fragment && isArray(childNode.children)) childNode.children.forEach((vnode) => {
if (vnode?.patchFlag !== 1024 && !isString(vnode?.children)) children.push(vnode);
});
}
return h("div", children);
} catch {
return h("div", []);
}
}
});
//#endregion
export { table_column_default as default };
//# sourceMappingURL=index.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,145 @@
import { isArray, isUndefined } from "../../../../utils/types.mjs";
import { debugWarn } from "../../../../utils/error.mjs";
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import { ensureValidVNode, parseMinWidth, parseWidth } from "../util.mjs";
import { cellForced, defaultRenderCell, getDefaultClassName, treeCellPrefix } from "../config.mjs";
import { Comment, Fragment, computed, createTextVNode, getCurrentInstance, h, ref, renderSlot, unref, watchEffect } from "vue";
//#region ../../packages/components/table/src/table-column/render-helper.ts
function useRender(props, slots, owner) {
const instance = getCurrentInstance();
const columnId = ref("");
const isSubColumn = ref(false);
const realAlign = ref();
const realHeaderAlign = ref();
const ns = useNamespace("table");
watchEffect(() => {
realAlign.value = props.align ? `is-${props.align}` : null;
realAlign.value;
});
watchEffect(() => {
realHeaderAlign.value = props.headerAlign ? `is-${props.headerAlign}` : realAlign.value;
realHeaderAlign.value;
});
const columnOrTableParent = computed(() => {
let parent = instance.vnode.vParent || instance.parent;
while (parent && !parent.tableId && !parent.columnId) parent = parent.vnode.vParent || parent.parent;
return parent;
});
const hasTreeColumn = computed(() => {
const { store } = instance.parent;
if (!store) return false;
const { treeData } = store.states;
const treeDataValue = treeData.value;
return treeDataValue && Object.keys(treeDataValue).length > 0;
});
const realWidth = ref(parseWidth(props.width));
const realMinWidth = ref(parseMinWidth(props.minWidth));
const setColumnWidth = (column) => {
if (realWidth.value) column.width = realWidth.value;
if (realMinWidth.value) column.minWidth = realMinWidth.value;
if (!realWidth.value && realMinWidth.value) column.width = void 0;
if (!column.minWidth) column.minWidth = 80;
column.realWidth = Number(isUndefined(column.width) ? column.minWidth : column.width);
return column;
};
const setColumnForcedProps = (column) => {
const type = column.type;
const source = cellForced[type] || {};
Object.keys(source).forEach((prop) => {
const value = source[prop];
if (prop !== "className" && !isUndefined(value)) column[prop] = value;
});
const className = getDefaultClassName(type);
if (className) {
const forceClass = `${unref(ns.namespace)}-${className}`;
column.className = column.className ? `${column.className} ${forceClass}` : forceClass;
}
return column;
};
const checkSubColumn = (children) => {
if (isArray(children)) children.forEach((child) => check(child));
else check(children);
function check(item) {
if (item?.type?.name === "ElTableColumn") item.vParent = instance;
}
};
const setColumnRenders = (column) => {
if (props.renderHeader) debugWarn("TableColumn", "Comparing to render-header, scoped-slot header is easier to use. We recommend users to use scoped-slot header.");
else if (column.type !== "selection") column.renderHeader = (scope) => {
instance.columnConfig.value["label"];
if (slots.header) {
const slotResult = slots.header(scope);
if (ensureValidVNode(slotResult)) return h(Fragment, slotResult);
}
return createTextVNode(column.label);
};
if (slots["filter-icon"]) column.renderFilterIcon = (scope) => {
return renderSlot(slots, "filter-icon", scope);
};
if (slots.expand) column.renderExpand = (scope) => {
return renderSlot(slots, "expand", scope);
};
let originRenderCell = column.renderCell;
if (column.type === "expand") {
column.renderCell = (data) => h("div", { class: "cell" }, [originRenderCell(data)]);
owner.value.renderExpanded = (row) => {
return slots.default ? slots.default(row) : slots.default;
};
} else {
originRenderCell = originRenderCell || defaultRenderCell;
column.renderCell = (data) => {
let children = null;
if (slots.default) {
const vnodes = slots.default(data);
children = vnodes.some((v) => v.type !== Comment) ? vnodes : originRenderCell(data);
} else children = originRenderCell(data);
const { columns } = owner.value.store.states;
const firstUserColumnIndex = columns.value.findIndex((item) => item.type === "default");
const prefix = treeCellPrefix(data, hasTreeColumn.value && data.cellIndex === firstUserColumnIndex);
const props = {
class: "cell",
style: {}
};
if (column.showOverflowTooltip) {
props.class = `${props.class} ${unref(ns.namespace)}-tooltip`;
props.style = { width: `${(data.column.realWidth || Number(data.column.width)) - 1}px` };
}
checkSubColumn(children);
return h("div", props, [prefix, children]);
};
}
return column;
};
const getPropsData = (...propsKey) => {
return propsKey.reduce((prev, cur) => {
if (isArray(cur)) cur.forEach((key) => {
prev[key] = props[key];
});
return prev;
}, {});
};
const getColumnElIndex = (children, child) => {
return Array.prototype.indexOf.call(children, child);
};
const updateColumnOrder = () => {
owner.value.store.commit("updateColumnOrder", instance.columnConfig.value);
};
return {
columnId,
realAlign,
isSubColumn,
realHeaderAlign,
columnOrTableParent,
setColumnWidth,
setColumnForcedProps,
setColumnRenders,
getPropsData,
getColumnElIndex,
updateColumnOrder
};
}
//#endregion
export { useRender as default };
//# sourceMappingURL=render-helper.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,88 @@
import { isUndefined } from "../../../../utils/types.mjs";
import { hasOwn } from "../../../../utils/objects.mjs";
import { useGlobalConfig } from "../../../config-provider/src/hooks/use-global-config.mjs";
import { parseMinWidth, parseWidth } from "../util.mjs";
import { getCurrentInstance, watch } from "vue";
//#region ../../packages/components/table/src/table-column/watcher-helper.ts
function getAllAliases(props, aliases) {
return props.reduce((prev, cur) => {
prev[cur] = cur;
return prev;
}, aliases);
}
function useWatcher(owner, props_) {
const instance = getCurrentInstance();
const registerComplexWatchers = () => {
const props = ["fixed"];
const aliases = {
realWidth: "width",
realMinWidth: "minWidth"
};
const allAliases = getAllAliases(props, aliases);
Object.keys(allAliases).forEach((key) => {
const columnKey = aliases[key];
if (hasOwn(props_, columnKey)) watch(() => props_[columnKey], (newVal) => {
let value = newVal;
if (columnKey === "width" && key === "realWidth") value = parseWidth(newVal);
if (columnKey === "minWidth" && key === "realMinWidth") value = parseMinWidth(newVal);
instance.columnConfig.value[columnKey] = value;
instance.columnConfig.value[key] = value;
const updateColumns = columnKey === "fixed";
owner.value.store.scheduleLayout(updateColumns);
});
});
};
const registerNormalWatchers = () => {
const props = [
"label",
"filters",
"filterMultiple",
"filteredValue",
"sortable",
"index",
"formatter",
"className",
"labelClassName",
"filterClassName",
"showOverflowTooltip",
"tooltipFormatter",
"resizable"
];
const parentProps = ["showOverflowTooltip"];
const aliases = {
property: "prop",
align: "realAlign",
headerAlign: "realHeaderAlign"
};
const allAliases = getAllAliases(props, aliases);
Object.keys(allAliases).forEach((key) => {
const columnKey = aliases[key];
if (hasOwn(props_, columnKey)) watch(() => props_[columnKey], (newVal) => {
instance.columnConfig.value[key] = newVal;
if (key === "filters" || key === "filterMethod") instance.columnConfig.value["filterable"] = !!(instance.columnConfig.value["filters"] || instance.columnConfig.value["filterMethod"]);
});
});
parentProps.forEach((key) => {
if (hasOwn(owner.value.props, key)) watch(() => owner.value.props[key], (newVal) => {
if (instance.columnConfig.value.type === "selection") return;
if (!isUndefined(props_[key])) return;
instance.columnConfig.value[key] = newVal;
});
});
const globalConfig = useGlobalConfig("table");
if (globalConfig.value && hasOwn(globalConfig.value, "showOverflowTooltip")) watch(() => globalConfig.value?.showOverflowTooltip, (newVal) => {
if (instance.columnConfig.value.type === "selection") return;
if (!isUndefined(props_.showOverflowTooltip) || !isUndefined(owner.value.props.showOverflowTooltip)) return;
instance.columnConfig.value.showOverflowTooltip = newVal;
});
};
return {
registerComplexWatchers,
registerNormalWatchers
};
}
//#endregion
export { useWatcher as default };
//# sourceMappingURL=watcher-helper.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,85 @@
import { TableColumnCtx } from "../table-column/defaults.js";
import { Store } from "../store/index.js";
import { TableLayout } from "../table-layout.js";
import { DefaultRow, Sort, SummaryMethod } from "../table/defaults.js";
import * as vue from "vue";
import { PropType } from "vue";
//#region ../../packages/components/table/src/table-footer/index.d.ts
interface TableFooter<T extends DefaultRow> {
fixed: string;
store: Store<T>;
summaryMethod: SummaryMethod<T>;
sumText: string;
border: boolean;
defaultSort: Sort;
}
declare const _default: vue.DefineComponent<vue.ExtractPropTypes<{
fixed: {
type: StringConstructor;
default: string;
};
store: {
required: true;
type: PropType<TableFooter<any>["store"]>;
};
summaryMethod: PropType<TableFooter<any>["summaryMethod"]>;
sumText: StringConstructor;
border: BooleanConstructor;
defaultSort: {
type: PropType<TableFooter<any>["defaultSort"]>;
default: () => {
prop: string;
order: string;
};
};
}>, {
ns: {
namespace: 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;
};
onScrollableChange: (layout: TableLayout<any>) => void;
onColumnsChange: (layout: TableLayout<any>) => void;
getCellClasses: (columns: TableColumnCtx<any>[], cellIndex: number) => string[];
getCellStyles: (column: TableColumnCtx<any>, cellIndex: number) => vue.CSSProperties | undefined;
columns: vue.ComputedRef<TableColumnCtx<DefaultRow>[]>;
}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
fixed: {
type: StringConstructor;
default: string;
};
store: {
required: true;
type: PropType<TableFooter<any>["store"]>;
};
summaryMethod: PropType<TableFooter<any>["summaryMethod"]>;
sumText: StringConstructor;
border: BooleanConstructor;
defaultSort: {
type: PropType<TableFooter<any>["defaultSort"]>;
default: () => {
prop: string;
order: string;
};
};
}>> & Readonly<{}>, {
fixed: string;
border: boolean;
defaultSort: Sort;
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
//#endregion
export { TableFooter, _default as default };
@@ -0,0 +1,89 @@
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import useLayoutObserver from "../layout-observer.mjs";
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import useStyle from "./style-helper.mjs";
import { defineComponent, h, inject } from "vue";
//#region ../../packages/components/table/src/table-footer/index.ts
var table_footer_default = defineComponent({
name: "ElTableFooter",
props: {
fixed: {
type: String,
default: ""
},
store: {
required: true,
type: Object
},
summaryMethod: Function,
sumText: String,
border: Boolean,
defaultSort: {
type: Object,
default: () => {
return {
prop: "",
order: ""
};
}
}
},
setup(props) {
const parent = inject(TABLE_INJECTION_KEY);
const ns = useNamespace("table");
const { getCellClasses, getCellStyles, columns } = useStyle(props);
const { onScrollableChange, onColumnsChange } = useLayoutObserver(parent);
return {
ns,
onScrollableChange,
onColumnsChange,
getCellClasses,
getCellStyles,
columns
};
},
render() {
const { columns, getCellStyles, getCellClasses, summaryMethod, sumText } = this;
const data = this.store.states.data.value;
let sums = [];
if (summaryMethod) sums = summaryMethod({
columns,
data
});
else columns.forEach((column, index) => {
if (index === 0) {
sums[index] = sumText;
return;
}
const values = data.map((item) => Number(item[column.property]));
const precisions = [];
let notNumber = true;
values.forEach((value) => {
if (!Number.isNaN(+value)) {
notNumber = false;
const decimal = `${value}`.split(".")[1];
precisions.push(decimal ? decimal.length : 0);
}
});
const precision = Math.max.apply(null, precisions);
if (!notNumber) sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!Number.isNaN(+value)) return Number.parseFloat((prev + curr).toFixed(Math.min(precision, 20)));
else return prev;
}, 0);
else sums[index] = "";
});
return h(h("tfoot", [h("tr", {}, [...columns.map((column, cellIndex) => h("td", {
key: cellIndex,
colspan: column.colSpan,
rowspan: column.rowSpan,
class: getCellClasses(columns, cellIndex),
style: getCellStyles(column, cellIndex)
}, [h("div", { class: ["cell", column.labelClassName] }, [sums[cellIndex]])]))])]));
}
});
//#endregion
export { table_footer_default as default };
//# sourceMappingURL=index.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,29 @@
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import { computed, inject } from "vue";
//#region ../../packages/components/table/src/table-footer/mapState-helper.ts
function useMapState() {
const store = inject(TABLE_INJECTION_KEY)?.store;
return {
leftFixedLeafCount: computed(() => {
return store?.states.fixedLeafColumnsLength.value ?? 0;
}),
rightFixedLeafCount: computed(() => {
return store?.states.rightFixedColumns.value.length ?? 0;
}),
columnsCount: computed(() => {
return store?.states.columns.value.length ?? 0;
}),
leftFixedCount: computed(() => {
return store?.states.fixedColumns.value.length ?? 0;
}),
rightFixedCount: computed(() => {
return store?.states.rightFixedColumns.value.length ?? 0;
}),
columns: computed(() => store?.states.columns.value ?? [])
};
}
//#endregion
export { useMapState as default };
//# sourceMappingURL=mapState-helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"mapState-helper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table-footer/mapState-helper.ts"],"sourcesContent":["import { computed, inject } from 'vue'\nimport { TABLE_INJECTION_KEY } from '../tokens'\n\nfunction useMapState() {\n const table = inject(TABLE_INJECTION_KEY)\n const store = table?.store\n const leftFixedLeafCount = computed(() => {\n return store?.states.fixedLeafColumnsLength.value ?? 0\n })\n const rightFixedLeafCount = computed(() => {\n return store?.states.rightFixedColumns.value.length ?? 0\n })\n const columnsCount = computed(() => {\n return store?.states.columns.value.length ?? 0\n })\n const leftFixedCount = computed(() => {\n return store?.states.fixedColumns.value.length ?? 0\n })\n const rightFixedCount = computed(() => {\n return store?.states.rightFixedColumns.value.length ?? 0\n })\n\n return {\n leftFixedLeafCount,\n rightFixedLeafCount,\n columnsCount,\n leftFixedCount,\n rightFixedCount,\n columns: computed(() => store?.states.columns.value ?? []),\n }\n}\n\nexport default useMapState\n"],"mappings":";;;;AAGA,SAAS,cAAc;CAErB,MAAM,QADQ,OAAO,oBAAoB,EACpB;AAiBrB,QAAO;EACL,oBAjByB,eAAe;AACxC,UAAO,OAAO,OAAO,uBAAuB,SAAS;IACrD;EAgBA,qBAf0B,eAAe;AACzC,UAAO,OAAO,OAAO,kBAAkB,MAAM,UAAU;IACvD;EAcA,cAbmB,eAAe;AAClC,UAAO,OAAO,OAAO,QAAQ,MAAM,UAAU;IAC7C;EAYA,gBAXqB,eAAe;AACpC,UAAO,OAAO,OAAO,aAAa,MAAM,UAAU;IAClD;EAUA,iBATsB,eAAe;AACrC,UAAO,OAAO,OAAO,kBAAkB,MAAM,UAAU;IACvD;EAQA,SAAS,eAAe,OAAO,OAAO,QAAQ,SAAS,EAAE,CAAC;EAC3D"}
@@ -0,0 +1,37 @@
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import { ensurePosition, getFixedColumnOffset, getFixedColumnsClass } from "../util.mjs";
import useMapState from "./mapState-helper.mjs";
//#region ../../packages/components/table/src/table-footer/style-helper.ts
function useStyle(props) {
const { columns } = useMapState();
const ns = useNamespace("table");
const getCellClasses = (columns, cellIndex) => {
const column = columns[cellIndex];
const classes = [
ns.e("cell"),
column.id,
column.align,
column.labelClassName,
...getFixedColumnsClass(ns.b(), cellIndex, column.fixed, props.store)
];
if (column.className) classes.push(column.className);
if (!column.children) classes.push(ns.is("leaf"));
return classes;
};
const getCellStyles = (column, cellIndex) => {
const fixedStyle = getFixedColumnOffset(cellIndex, column.fixed, props.store);
ensurePosition(fixedStyle, "left");
ensurePosition(fixedStyle, "right");
return fixedStyle;
};
return {
getCellClasses,
getCellStyles,
columns
};
}
//#endregion
export { useStyle as default };
//# sourceMappingURL=style-helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"style-helper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table-footer/style-helper.ts"],"sourcesContent":["import { useNamespace } from '@element-plus/hooks'\nimport {\n ensurePosition,\n getFixedColumnOffset,\n getFixedColumnsClass,\n} from '../util'\nimport useMapState from './mapState-helper'\n\nimport type { TableColumnCtx } from '../table-column/defaults'\nimport type { DefaultRow } from '../table/defaults'\nimport type { TableFooter } from '.'\n\nfunction useStyle<T extends DefaultRow>(props: TableFooter<T>) {\n const { columns } = useMapState()\n const ns = useNamespace('table')\n\n const getCellClasses = (columns: TableColumnCtx<T>[], cellIndex: number) => {\n const column = columns[cellIndex]\n const classes = [\n ns.e('cell'),\n column.id,\n column.align,\n column.labelClassName,\n ...getFixedColumnsClass(ns.b(), cellIndex, column.fixed, props.store),\n ]\n if (column.className) {\n classes.push(column.className)\n }\n if (!column.children) {\n classes.push(ns.is('leaf'))\n }\n return classes\n }\n\n const getCellStyles = (column: TableColumnCtx<T>, cellIndex: number) => {\n const fixedStyle = getFixedColumnOffset(\n cellIndex,\n column.fixed,\n props.store\n )\n ensurePosition(fixedStyle, 'left')\n ensurePosition(fixedStyle, 'right')\n return fixedStyle\n }\n\n return {\n getCellClasses,\n getCellStyles,\n columns,\n }\n}\n\nexport default useStyle\n"],"mappings":";;;;;AAYA,SAAS,SAA+B,OAAuB;CAC7D,MAAM,EAAE,YAAY,aAAa;CACjC,MAAM,KAAK,aAAa,QAAQ;CAEhC,MAAM,kBAAkB,SAA8B,cAAsB;EAC1E,MAAM,SAAS,QAAQ;EACvB,MAAM,UAAU;GACd,GAAG,EAAE,OAAO;GACZ,OAAO;GACP,OAAO;GACP,OAAO;GACP,GAAG,qBAAqB,GAAG,GAAG,EAAE,WAAW,OAAO,OAAO,MAAM,MAAM;GACtE;AACD,MAAI,OAAO,UACT,SAAQ,KAAK,OAAO,UAAU;AAEhC,MAAI,CAAC,OAAO,SACV,SAAQ,KAAK,GAAG,GAAG,OAAO,CAAC;AAE7B,SAAO;;CAGT,MAAM,iBAAiB,QAA2B,cAAsB;EACtE,MAAM,aAAa,qBACjB,WACA,OAAO,OACP,MAAM,MACP;AACD,iBAAe,YAAY,OAAO;AAClC,iBAAe,YAAY,QAAQ;AACnC,SAAO;;AAGT,QAAO;EACL;EACA;EACA;EACD"}
@@ -0,0 +1,159 @@
import { isClient } from "../../../../utils/browser.mjs";
import { isElement } from "../../../../utils/types.mjs";
import { addClass, hasClass, removeClass } from "../../../../utils/dom/style.mjs";
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import { isNull } from "lodash-unified";
import { getCurrentInstance, inject, ref } from "vue";
//#region ../../packages/components/table/src/table-header/event-helper.ts
function useEvent(props, emit) {
const instance = getCurrentInstance();
const parent = inject(TABLE_INJECTION_KEY);
const handleFilterClick = (event) => {
event.stopPropagation();
};
const handleHeaderClick = (event, column) => {
if (!column.filters && column.sortable) handleSortClick(event, column, false);
else if (column.filterable && !column.sortable) handleFilterClick(event);
parent?.emit("header-click", column, event);
};
const handleHeaderContextMenu = (event, column) => {
parent?.emit("header-contextmenu", column, event);
};
const draggingColumn = ref(null);
const dragging = ref(false);
const dragState = ref();
const handleMouseDown = (event, column) => {
if (!isClient) return;
if (column.children && column.children.length > 0) return;
/* istanbul ignore if */
if (draggingColumn.value && props.border && draggingColumn.value.id === column.id) {
dragging.value = true;
const table = parent;
emit("set-drag-visible", true);
const tableLeft = (table?.vnode.el)?.getBoundingClientRect().left;
const columnEl = instance?.vnode?.el?.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?.refs.resizeProxy;
resizeProxy.style.left = `${dragState.value.startLeft}px`;
document.onselectstart = function() {
return false;
};
document.ondragstart = function() {
return false;
};
const handleMouseMove = (event) => {
const deltaLeft = event.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;
column.width = column.realWidth = Number.parseInt(resizeProxy.style.left, 10) - startColumnLeft;
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", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
document.onselectstart = null;
document.ondragstart = null;
setTimeout(() => {
removeClass(columnEl, "noclick");
}, 0);
};
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
}
};
const handleMouseMove = (event, column) => {
if (!props.border || column.children && column.children.length > 0) return;
const el = event.target;
const target = isElement(el) ? el.closest("th") : null;
if (!target) return;
const isSortable = hasClass(target, "is-sortable");
if (isSortable) {
const cursor = dragging.value ? "col-resize" : "";
target.style.cursor = cursor;
const caret = target.querySelector(".caret-wrapper");
if (caret) caret.style.cursor = cursor;
}
if (!column.resizable || dragging.value) {
draggingColumn.value = null;
return;
}
const rect = target.getBoundingClientRect();
const isLastTh = target.parentNode?.lastElementChild === target;
const allowDrag = props.allowDragLastColumn || !isLastTh;
const isResizeHandleActive = rect.width > 12 && rect.right - event.clientX < 8 && allowDrag;
const cursor = isResizeHandleActive ? "col-resize" : "";
document.body.style.cursor = cursor;
draggingColumn.value = isResizeHandleActive ? column : null;
if (isSortable) target.style.cursor = cursor;
};
const handleMouseOut = () => {
if (!isClient || dragging.value) 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) => {
event.stopPropagation();
const order = column.order === givenOrder ? null : givenOrder || toggleOrder(column);
const target = event.target?.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?.store.commit("changeSortCondition");
};
return {
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleMouseOut,
handleSortClick,
handleFilterClick
};
}
//#endregion
export { useEvent as default };
//# sourceMappingURL=event-helper.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,220 @@
import { ComponentSize } from "../../../../constants/size.js";
import { Translator } from "../../../../hooks/use-locale/index.js";
import "../../../../hooks/index.js";
import { CheckboxProps, CheckboxValueType } from "../../../checkbox/src/checkbox.js";
import { _default as _default$1 } from "../../../checkbox/src/checkbox-button.vue.js";
import { _default as _default$2 } from "../../../checkbox/src/checkbox-group.vue.js";
import "../../../checkbox/index.js";
import { TableColumnCtx } from "../table-column/defaults.js";
import { Store } from "../store/index.js";
import { TableLayout } from "../table-layout.js";
import { DefaultRow, Sort, TableSortOrder } from "../table/defaults.js";
import "../../../../index.js";
import * as vue from "vue";
import { ComponentInternalInstance, PropType, Ref } from "vue";
//#region ../../packages/components/table/src/table-header/index.d.ts
interface TableHeader extends ComponentInternalInstance {
state: {
onColumnsChange: (layout: TableLayout<any>) => void;
onScrollableChange: (layout: TableLayout<any>) => void;
};
filterPanels: Ref<DefaultRow>;
}
interface TableHeaderProps<T extends DefaultRow> {
fixed: string;
store: Store<T>;
border: boolean;
defaultSort: Sort;
allowDragLastColumn: boolean;
}
declare const _default: vue.DefineComponent<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;
};
}>, {
ns: {
namespace: 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;
};
t: Translator;
filterPanels: Ref<{}, {}>;
onColumnsChange: (layout: TableLayout<DefaultRow>) => void;
onScrollableChange: (layout: TableLayout<DefaultRow>) => void;
columnRows: vue.ComputedRef<TableColumnCtx<any>[][]>;
getHeaderRowClass: (rowIndex: number) => string;
getHeaderRowStyle: (rowIndex: number) => any;
getHeaderCellClass: (rowIndex: number, columnIndex: number, row: any, column: TableColumnCtx<any>) => string;
getHeaderCellStyle: (rowIndex: number, columnIndex: number, row: any, column: TableColumnCtx<any>) => vue.CSSProperties;
handleHeaderClick: (event: Event, column: TableColumnCtx<any>) => void;
handleHeaderContextMenu: (event: Event, column: TableColumnCtx<any>) => void;
handleMouseDown: (event: MouseEvent, column: TableColumnCtx<any>) => void;
handleMouseMove: (event: MouseEvent, column: TableColumnCtx<any>) => void;
handleMouseOut: () => void;
handleSortClick: (event: Event, column: TableColumnCtx<any>, givenOrder?: TableSortOrder | boolean) => void;
handleFilterClick: (event: Event) => void;
isGroup: vue.ComputedRef<boolean>;
toggleAllSelection: (event: Event) => void;
saveIndexSelection: vue.Reactive<Map<any, any>>;
isTableLayoutAuto: boolean;
theadRef: Ref<any, any>;
updateFixedColumnStyle: () => void;
}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<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;
};
}>> & Readonly<{}>, {
fixed: string;
border: boolean;
defaultSort: Sort;
allowDragLastColumn: boolean;
}, {}, {
ElCheckbox: {
new (...args: any[]): vue.CreateComponentPublicInstanceWithMixins<Readonly<CheckboxProps> & Readonly<{
onChange?: ((val: CheckboxValueType) => any) | undefined;
"onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
change: (val: CheckboxValueType) => void;
"update:modelValue": (val: CheckboxValueType) => void;
}, vue.PublicProps, {
id: string;
disabled: boolean;
modelValue: number | string | boolean;
validateEvent: boolean;
name: string;
value: string | boolean | number | object;
label: string | boolean | number | object;
trueValue: string | number;
falseValue: string | number;
trueLabel: string | number;
falseLabel: string | number;
}, false, {}, {}, vue.GlobalComponents, vue.GlobalDirectives, string, {}, any, vue.ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, Readonly<CheckboxProps> & Readonly<{
onChange?: ((val: CheckboxValueType) => any) | undefined;
"onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
}>, {}, {}, {}, {}, {
id: string;
disabled: boolean;
modelValue: number | string | boolean;
validateEvent: boolean;
name: string;
value: string | boolean | number | object;
label: string | boolean | number | object;
trueValue: string | number;
falseValue: string | number;
trueLabel: string | number;
falseLabel: string | number;
}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & vue.ComponentOptionsBase<Readonly<CheckboxProps> & Readonly<{
onChange?: ((val: CheckboxValueType) => any) | undefined;
"onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
change: (val: CheckboxValueType) => void;
"update:modelValue": (val: CheckboxValueType) => void;
}, string, {
id: string;
disabled: boolean;
modelValue: number | string | boolean;
validateEvent: boolean;
name: string;
value: string | boolean | number | object;
label: string | boolean | number | object;
trueValue: string | number;
falseValue: string | number;
trueLabel: string | number;
falseLabel: string | number;
}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
$slots: {
default?: (props: {}) => any;
};
}) & vue.ObjectPlugin & {
setPropsDefaults: (defaults: Partial<Omit<{
readonly modelValue?: (number | string | boolean) | undefined;
readonly label?: (string | boolean | number | object) | undefined;
readonly value?: (string | boolean | number | object) | undefined;
readonly indeterminate?: boolean | undefined;
readonly disabled?: boolean | undefined;
readonly checked?: boolean | undefined;
readonly name?: string | undefined;
readonly trueValue?: (string | number) | undefined;
readonly falseValue?: (string | number) | undefined;
readonly trueLabel?: (string | number) | undefined;
readonly falseLabel?: (string | number) | undefined;
readonly id?: string | undefined;
readonly border?: boolean | undefined;
readonly size?: ComponentSize | undefined;
readonly tabindex?: (string | number) | undefined;
readonly validateEvent?: boolean | undefined;
readonly ariaLabel?: string | undefined;
readonly ariaControls?: string | undefined;
readonly onChange?: ((val: CheckboxValueType) => any) | undefined;
readonly "onUpdate:modelValue"?: ((val: CheckboxValueType) => any) | undefined;
} & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, "onChange" | "onUpdate:modelValue" | keyof vue.VNodeProps | keyof vue.AllowedComponentProps>>) => void;
} & {
CheckboxButton: typeof _default$1;
CheckboxGroup: typeof _default$2;
};
}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
//#endregion
export { TableHeader, TableHeaderProps, _default as default };
@@ -0,0 +1,177 @@
import { useLocale } from "../../../../hooks/use-locale/index.mjs";
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import { ElCheckbox } from "../../../checkbox/index.mjs";
import filter_panel_default 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 { defineComponent, getCurrentInstance, h, inject, nextTick, onBeforeUnmount, onMounted, reactive, ref, watch } from "vue";
//#region ../../packages/components/table/src/table-header/index.ts
var table_header_default = 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?.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) column.width = el.getBoundingClientRect().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?.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);
const { t } = useLocale();
instance.state = {
onColumnsChange,
onScrollableChange
};
instance.filterPanels = filterPanels;
return {
ns,
t,
filterPanels,
onColumnsChange,
onScrollableChange,
columnRows,
getHeaderRowClass,
getHeaderRowStyle,
getHeaderCellClass,
getHeaderCellStyle,
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleMouseOut,
handleSortClick,
handleFilterClick,
isGroup,
toggleAllSelection,
saveIndexSelection,
isTableLayoutAuto,
theadRef,
updateFixedColumnStyle
};
},
render() {
const { ns, t, 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,
scope: column.colSpan > 1 ? "colgroup" : "col",
ariaSort: column.sortable ? column.order : void 0,
style: getHeaderCellStyle(rowIndex, cellIndex, subColumns, column),
onClick: ($event) => {
if ($event.currentTarget?.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("button", {
type: "button",
class: "caret-wrapper",
"aria-label": t("el.table.sortLabel", { column: column.label || "" }),
onClick: ($event) => handleSortClick($event, column)
}, [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(filter_panel_default, {
store,
placement: column.filterPlacement || "bottom-start",
appendTo: $parent?.appendFilterPanelTo,
column,
upDataColumn: (key, value) => {
column[key] = value;
}
}, { "filter-icon": () => column.renderFilterIcon ? column.renderFilterIcon({ filterOpened: column.filterOpened }) : null })
])]);
}))));
}
});
//#endregion
export { table_header_default as default };
//# sourceMappingURL=index.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,69 @@
import { isFunction, isString } from "../../../../utils/types.mjs";
import { useNamespace } from "../../../../hooks/use-namespace/index.mjs";
import { ensurePosition, getFixedColumnOffset, getFixedColumnsClass } from "../util.mjs";
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import { inject } from "vue";
//#region ../../packages/components/table/src/table-header/style.helper.ts
function useStyle(props) {
const parent = inject(TABLE_INJECTION_KEY);
const ns = useNamespace("table");
const getHeaderRowStyle = (rowIndex) => {
const headerRowStyle = parent?.props.headerRowStyle;
if (isFunction(headerRowStyle)) return headerRowStyle.call(null, { rowIndex });
return headerRowStyle;
};
const getHeaderRowClass = (rowIndex) => {
const classes = [];
const headerRowClassName = 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) => {
let headerCellStyles = parent?.props.headerCellStyle ?? {};
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?.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
};
}
//#endregion
export { useStyle as default };
//# sourceMappingURL=style.helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"style.helper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table-header/style.helper.ts"],"sourcesContent":["import { inject } from 'vue'\nimport { useNamespace } from '@element-plus/hooks'\nimport { isFunction, isString } from '@element-plus/utils'\nimport {\n ensurePosition,\n getFixedColumnOffset,\n getFixedColumnsClass,\n} from '../util'\nimport { TABLE_INJECTION_KEY } from '../tokens'\n\nimport type { TableColumnCtx } from '../table-column/defaults'\nimport type { DefaultRow } from '../table/defaults'\nimport type { TableHeaderProps } from '.'\n\nfunction useStyle<T extends DefaultRow>(props: TableHeaderProps<T>) {\n const parent = inject(TABLE_INJECTION_KEY)\n const ns = useNamespace('table')\n\n const getHeaderRowStyle = (rowIndex: number) => {\n const headerRowStyle = parent?.props.headerRowStyle\n if (isFunction(headerRowStyle)) {\n return headerRowStyle.call(null, { rowIndex })\n }\n return headerRowStyle\n }\n\n const getHeaderRowClass = (rowIndex: number): string => {\n const classes: string[] = []\n const headerRowClassName = parent?.props.headerRowClassName\n if (isString(headerRowClassName)) {\n classes.push(headerRowClassName)\n } else if (isFunction(headerRowClassName)) {\n classes.push(headerRowClassName.call(null, { rowIndex }))\n }\n\n return classes.join(' ')\n }\n\n const getHeaderCellStyle = (\n rowIndex: number,\n columnIndex: number,\n row: T,\n column: TableColumnCtx<T>\n ) => {\n let headerCellStyles = parent?.props.headerCellStyle ?? {}\n if (isFunction(headerCellStyles)) {\n headerCellStyles = headerCellStyles.call(null, {\n rowIndex,\n columnIndex,\n row,\n column,\n })\n }\n const fixedStyle = getFixedColumnOffset<T>(\n columnIndex,\n column.fixed,\n props.store,\n row as unknown as TableColumnCtx<T>[]\n )\n ensurePosition(fixedStyle, 'left')\n ensurePosition(fixedStyle, 'right')\n return Object.assign({}, headerCellStyles, fixedStyle)\n }\n\n const getHeaderCellClass = (\n rowIndex: number,\n columnIndex: number,\n row: T,\n column: TableColumnCtx<T>\n ) => {\n const fixedClasses = getFixedColumnsClass<T>(\n ns.b(),\n columnIndex,\n column.fixed,\n props.store,\n row as unknown as TableColumnCtx<T>[]\n )\n const classes = [\n column.id,\n column.order,\n column.headerAlign,\n column.className,\n column.labelClassName,\n ...fixedClasses,\n ]\n\n if (!column.children) {\n classes.push('is-leaf')\n }\n\n if (column.sortable) {\n classes.push('is-sortable')\n }\n\n const headerCellClassName = parent?.props.headerCellClassName\n if (isString(headerCellClassName)) {\n classes.push(headerCellClassName)\n } else if (isFunction(headerCellClassName)) {\n classes.push(\n headerCellClassName.call(null, {\n rowIndex,\n columnIndex,\n row,\n column,\n })\n )\n }\n\n classes.push(ns.e('cell'))\n\n return classes.filter((className) => Boolean(className)).join(' ')\n }\n\n return {\n getHeaderRowStyle,\n getHeaderRowClass,\n getHeaderCellStyle,\n getHeaderCellClass,\n }\n}\n\nexport default useStyle\n"],"mappings":";;;;;;;AAcA,SAAS,SAA+B,OAA4B;CAClE,MAAM,SAAS,OAAO,oBAAoB;CAC1C,MAAM,KAAK,aAAa,QAAQ;CAEhC,MAAM,qBAAqB,aAAqB;EAC9C,MAAM,iBAAiB,QAAQ,MAAM;AACrC,MAAI,WAAW,eAAe,CAC5B,QAAO,eAAe,KAAK,MAAM,EAAE,UAAU,CAAC;AAEhD,SAAO;;CAGT,MAAM,qBAAqB,aAA6B;EACtD,MAAM,UAAoB,EAAE;EAC5B,MAAM,qBAAqB,QAAQ,MAAM;AACzC,MAAI,SAAS,mBAAmB,CAC9B,SAAQ,KAAK,mBAAmB;WACvB,WAAW,mBAAmB,CACvC,SAAQ,KAAK,mBAAmB,KAAK,MAAM,EAAE,UAAU,CAAC,CAAC;AAG3D,SAAO,QAAQ,KAAK,IAAI;;CAG1B,MAAM,sBACJ,UACA,aACA,KACA,WACG;EACH,IAAI,mBAAmB,QAAQ,MAAM,mBAAmB,EAAE;AAC1D,MAAI,WAAW,iBAAiB,CAC9B,oBAAmB,iBAAiB,KAAK,MAAM;GAC7C;GACA;GACA;GACA;GACD,CAAC;EAEJ,MAAM,aAAa,qBACjB,aACA,OAAO,OACP,MAAM,OACN,IACD;AACD,iBAAe,YAAY,OAAO;AAClC,iBAAe,YAAY,QAAQ;AACnC,SAAO,OAAO,OAAO,EAAE,EAAE,kBAAkB,WAAW;;CAGxD,MAAM,sBACJ,UACA,aACA,KACA,WACG;EACH,MAAM,eAAe,qBACnB,GAAG,GAAG,EACN,aACA,OAAO,OACP,MAAM,OACN,IACD;EACD,MAAM,UAAU;GACd,OAAO;GACP,OAAO;GACP,OAAO;GACP,OAAO;GACP,OAAO;GACP,GAAG;GACJ;AAED,MAAI,CAAC,OAAO,SACV,SAAQ,KAAK,UAAU;AAGzB,MAAI,OAAO,SACT,SAAQ,KAAK,cAAc;EAG7B,MAAM,sBAAsB,QAAQ,MAAM;AAC1C,MAAI,SAAS,oBAAoB,CAC/B,SAAQ,KAAK,oBAAoB;WACxB,WAAW,oBAAoB,CACxC,SAAQ,KACN,oBAAoB,KAAK,MAAM;GAC7B;GACA;GACA;GACA;GACD,CAAC,CACH;AAGH,UAAQ,KAAK,GAAG,EAAE,OAAO,CAAC;AAE1B,SAAO,QAAQ,QAAQ,cAAc,QAAQ,UAAU,CAAC,CAAC,KAAK,IAAI;;AAGpE,QAAO;EACL;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,70 @@
import { TABLE_INJECTION_KEY } from "../tokens.mjs";
import { computed, inject } from "vue";
//#region ../../packages/components/table/src/table-header/utils-helper.ts
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([]);
getAllColumns(originColumns).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?.store.commit("toggleAllSelection");
};
return {
isGroup,
toggleAllSelection,
columnRows
};
}
//#endregion
export { convertToRows, useUtils as default };
//# sourceMappingURL=utils-helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"utils-helper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table-header/utils-helper.ts"],"sourcesContent":["import { computed, inject } from 'vue'\nimport { TABLE_INJECTION_KEY } from '../tokens'\n\nimport type { DefaultRow } from '../table/defaults'\nimport type { TableColumnCtx } from '../table-column/defaults'\nimport type { TableHeaderProps } from '.'\n\nconst getAllColumns = <T extends DefaultRow>(\n columns: TableColumnCtx<T>[]\n): TableColumnCtx<T>[] => {\n const result: TableColumnCtx<T>[] = []\n columns.forEach((column) => {\n if (column.children) {\n result.push(column)\n // eslint-disable-next-line prefer-spread\n result.push.apply(result, getAllColumns(column.children))\n } else {\n result.push(column)\n }\n })\n return result\n}\n\nexport const convertToRows = <T extends DefaultRow>(\n originColumns: TableColumnCtx<T>[]\n): TableColumnCtx<T>[][] => {\n let maxLevel = 1\n const traverse = (column: TableColumnCtx<T>, parent?: TableColumnCtx<T>) => {\n if (parent) {\n column.level = parent.level + 1\n if (maxLevel < column.level) {\n maxLevel = column.level\n }\n }\n if (column.children) {\n let colSpan = 0\n column.children.forEach((subColumn) => {\n traverse(subColumn, column)\n colSpan += subColumn.colSpan\n })\n column.colSpan = colSpan\n } else {\n column.colSpan = 1\n }\n }\n\n originColumns.forEach((column) => {\n column.level = 1\n traverse(column, undefined)\n })\n\n const rows: TableColumnCtx<T>[][] = []\n for (let i = 0; i < maxLevel; i++) {\n rows.push([])\n }\n\n const allColumns: TableColumnCtx<T>[] = getAllColumns(originColumns)\n\n allColumns.forEach((column) => {\n if (!column.children) {\n column.rowSpan = maxLevel - column.level + 1\n } else {\n column.rowSpan = 1\n column.children.forEach((col) => (col.isSubColumn = true))\n }\n rows[column.level - 1].push(column)\n })\n\n return rows\n}\n\nfunction useUtils<T extends DefaultRow>(props: TableHeaderProps<T>) {\n const parent = inject(TABLE_INJECTION_KEY)\n const columnRows = computed(() => {\n return convertToRows(props.store.states.originColumns.value)\n })\n const isGroup = computed(() => {\n const result = columnRows.value.length > 1\n if (result && parent) {\n parent.state.isGroup.value = true\n }\n return result\n })\n const toggleAllSelection = (event: Event) => {\n event.stopPropagation()\n parent?.store.commit('toggleAllSelection')\n }\n return {\n isGroup,\n toggleAllSelection,\n columnRows,\n }\n}\n\nexport default useUtils\n"],"mappings":";;;;AAOA,MAAM,iBACJ,YACwB;CACxB,MAAM,SAA8B,EAAE;AACtC,SAAQ,SAAS,WAAW;AAC1B,MAAI,OAAO,UAAU;AACnB,UAAO,KAAK,OAAO;AAEnB,UAAO,KAAK,MAAM,QAAQ,cAAc,OAAO,SAAS,CAAC;QAEzD,QAAO,KAAK,OAAO;GAErB;AACF,QAAO;;AAGT,MAAa,iBACX,kBAC0B;CAC1B,IAAI,WAAW;CACf,MAAM,YAAY,QAA2B,WAA+B;AAC1E,MAAI,QAAQ;AACV,UAAO,QAAQ,OAAO,QAAQ;AAC9B,OAAI,WAAW,OAAO,MACpB,YAAW,OAAO;;AAGtB,MAAI,OAAO,UAAU;GACnB,IAAI,UAAU;AACd,UAAO,SAAS,SAAS,cAAc;AACrC,aAAS,WAAW,OAAO;AAC3B,eAAW,UAAU;KACrB;AACF,UAAO,UAAU;QAEjB,QAAO,UAAU;;AAIrB,eAAc,SAAS,WAAW;AAChC,SAAO,QAAQ;AACf,WAAS,QAAQ,OAAU;GAC3B;CAEF,MAAM,OAA8B,EAAE;AACtC,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,IAC5B,MAAK,KAAK,EAAE,CAAC;AAKf,CAFwC,cAAc,cAAc,CAEzD,SAAS,WAAW;AAC7B,MAAI,CAAC,OAAO,SACV,QAAO,UAAU,WAAW,OAAO,QAAQ;OACtC;AACL,UAAO,UAAU;AACjB,UAAO,SAAS,SAAS,QAAS,IAAI,cAAc,KAAM;;AAE5D,OAAK,OAAO,QAAQ,GAAG,KAAK,OAAO;GACnC;AAEF,QAAO;;AAGT,SAAS,SAA+B,OAA4B;CAClE,MAAM,SAAS,OAAO,oBAAoB;CAC1C,MAAM,aAAa,eAAe;AAChC,SAAO,cAAc,MAAM,MAAM,OAAO,cAAc,MAAM;GAC5D;CACF,MAAM,UAAU,eAAe;EAC7B,MAAM,SAAS,WAAW,MAAM,SAAS;AACzC,MAAI,UAAU,OACZ,QAAO,MAAM,QAAQ,QAAQ;AAE/B,SAAO;GACP;CACF,MAAM,sBAAsB,UAAiB;AAC3C,QAAM,iBAAiB;AACvB,UAAQ,MAAM,OAAO,qBAAqB;;AAE5C,QAAO;EACL;EACA;EACA;EACD"}
@@ -0,0 +1,39 @@
import { TableColumnCtx } from "./table-column/defaults.js";
import { Store } from "./store/index.js";
import { TableHeader } from "./table-header/index.js";
import { DefaultRow, Table } from "./table/defaults.js";
import { Ref } from "vue";
//#region ../../packages/components/table/src/table-layout.d.ts
declare class TableLayout<T extends DefaultRow> {
observers: TableHeader[];
table: Table<T>;
store: Store<T>;
columns: TableColumnCtx<T>[];
fit: boolean;
showHeader: boolean;
height: Ref<null | number>;
scrollX: Ref<boolean>;
scrollY: Ref<boolean>;
bodyWidth: Ref<null | number>;
fixedWidth: Ref<null | number>;
rightFixedWidth: Ref<null | number>;
tableHeight: Ref<null | number>;
headerHeight: Ref<null | number>;
appendHeight: Ref<null | number>;
footerHeight: Ref<null | number>;
gutterWidth: number;
constructor(options: Record<string, any>);
updateScrollY(): boolean;
setHeight(value: string | number | null, prop?: string): void;
setMaxHeight(value: string | number | null): void;
getFlattenColumns(): TableColumnCtx<T>[];
updateElsHeight(): void;
headerDisplayNone(elm: HTMLElement): boolean;
updateColumnsWidth(): void;
addObserver(observer: TableHeader): void;
removeObserver(observer: TableHeader): void;
notifyObservers(event: string): void;
}
//#endregion
export { TableLayout };
@@ -0,0 +1,175 @@
import { isClient } from "../../../utils/browser.mjs";
import { isNumber, isString } from "../../../utils/types.mjs";
import { hasOwn } from "../../../utils/objects.mjs";
import { parseHeight } from "./util.mjs";
import { isNull } from "lodash-unified";
import { isRef, nextTick, ref } from "vue";
//#region ../../packages/components/table/src/table-layout.ts
var TableLayout = class {
constructor(options) {
this.observers = [];
this.table = null;
this.store = null;
this.columns = [];
this.fit = true;
this.showHeader = true;
this.height = ref(null);
this.scrollX = ref(false);
this.scrollY = ref(false);
this.bodyWidth = ref(null);
this.fixedWidth = ref(null);
this.rightFixedWidth = ref(null);
this.gutterWidth = 0;
for (const name in options) if (hasOwn(options, name)) if (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;
/**
* When the height is not initialized, it is null.
* After the table is initialized, when the height is not configured, the height is 0.
*/
if (isNull(height)) return false;
const scrollBarRef = this.table.refs.scrollBarRef;
if (this.table.vnode.el && scrollBarRef?.wrapRef) {
let scrollY = true;
const prevScrollY = this.scrollY.value;
scrollY = scrollBarRef.wrapRef.scrollHeight > scrollBarRef.wrapRef.clientHeight;
this.scrollY.value = scrollY;
return prevScrollY !== scrollY;
}
return false;
}
setHeight(value, prop = "height") {
if (!isClient) return;
const el = this.table.vnode.el;
value = parseHeight(value);
this.height.value = Number(value);
if (!el && (value || value === 0)) {
nextTick(() => this.setHeight(value, prop));
return;
}
if (el && isNumber(value)) {
el.style[prop] = `${value}px`;
this.updateElsHeight();
} else if (el && isString(value)) {
el.style[prop] = value;
this.updateElsHeight();
}
}
setMaxHeight(value) {
this.setHeight(value, "max-height");
}
getFlattenColumns() {
const flattenColumns = [];
this.table.store.states.columns.value.forEach((column) => {
if (column.isColumnGroup) flattenColumns.push.apply(flattenColumns, column.columns);
else flattenColumns.push(column);
});
return flattenColumns;
}
updateElsHeight() {
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 (!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) => !isNumber(column.width));
flattenColumns.forEach((column) => {
if (isNumber(column.width) && column.realWidth) column.realWidth = null;
});
if (flexColumns.length > 0 && fit) {
flattenColumns.forEach((column) => {
bodyMinWidth += Number(column.width || column.minWidth || 80);
});
if (bodyMinWidth <= bodyWidth) {
this.scrollX.value = false;
const totalFlexWidth = bodyWidth - bodyMinWidth;
if (flexColumns.length === 1) flexColumns[0].realWidth = Number(flexColumns[0].minWidth || 80) + totalFlexWidth;
else {
const flexWidthPerPixel = totalFlexWidth / flexColumns.reduce((prev, column) => prev + Number(column.minWidth || 80), 0);
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((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((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((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) {
this.observers.forEach((observer) => {
switch (event) {
case "columns":
observer.state?.onColumnsChange(this);
break;
case "scrollable":
observer.state?.onScrollableChange(this);
break;
default: throw new Error(`Table Layout don't have event ${event}.`);
}
});
}
};
//#endregion
export { TableLayout as default };
//# sourceMappingURL=table-layout.mjs.map
File diff suppressed because one or more lines are too long
+217
View File
@@ -0,0 +1,217 @@
import _plugin_vue_export_helper_default from "../../../_virtual/_plugin-vue_export-helper.mjs";
import table_vue_vue_type_script_lang_default from "./table.vue_vue_type_script_lang.mjs";
import { createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, normalizeClass, normalizeStyle, openBlock, renderSlot, resolveComponent, resolveDirective, toDisplayString, vShow, withCtx, withDirectives } from "vue";
//#region ../../packages/components/table/src/table.vue
const _hoisted_1 = ["data-prefix"];
const _hoisted_2 = {
ref: "hiddenColumns",
class: "hidden-columns"
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_hColgroup = resolveComponent("hColgroup");
const _component_table_header = resolveComponent("table-header");
const _component_table_body = resolveComponent("table-body");
const _component_table_footer = resolveComponent("table-footer");
const _component_el_scrollbar = resolveComponent("el-scrollbar");
const _directive_mousewheel = resolveDirective("mousewheel");
return openBlock(), createElementBlock("div", {
ref: "tableWrapper",
class: normalizeClass([
{
[_ctx.ns.m("fit")]: _ctx.fit,
[_ctx.ns.m("striped")]: _ctx.stripe,
[_ctx.ns.m("border")]: _ctx.border || _ctx.isGroup,
[_ctx.ns.m("hidden")]: _ctx.isHidden,
[_ctx.ns.m("group")]: _ctx.isGroup,
[_ctx.ns.m("fluid-height")]: _ctx.maxHeight,
[_ctx.ns.m("scrollable-x")]: _ctx.layout.scrollX.value,
[_ctx.ns.m("scrollable-y")]: _ctx.layout.scrollY.value,
[_ctx.ns.m("enable-row-hover")]: !_ctx.store.states.isComplex.value,
[_ctx.ns.m("enable-row-transition")]: (_ctx.store.states.data.value || []).length !== 0 && (_ctx.store.states.data.value || []).length < 100,
"has-footer": _ctx.showSummary
},
_ctx.ns.m(_ctx.tableSize),
_ctx.className,
_ctx.ns.b(),
_ctx.ns.m(`layout-${_ctx.tableLayout}`)
]),
style: normalizeStyle(_ctx.style),
"data-prefix": _ctx.ns.namespace.value,
onMouseleave: _cache[1] || (_cache[1] = (...args) => _ctx.handleMouseLeave && _ctx.handleMouseLeave(...args))
}, [createElementVNode("div", {
ref: "tableInnerWrapper",
class: normalizeClass(_ctx.ns.e("inner-wrapper"))
}, [
createElementVNode("div", _hoisted_2, [renderSlot(_ctx.$slots, "default")], 512),
_ctx.showHeader && _ctx.tableLayout === "fixed" ? withDirectives((openBlock(), createElementBlock("div", {
key: 0,
ref: "headerWrapper",
class: normalizeClass(_ctx.ns.e("header-wrapper"))
}, [createElementVNode("table", {
ref: "tableHeader",
class: normalizeClass(_ctx.ns.e("header")),
style: normalizeStyle(_ctx.tableBodyStyles),
border: "0",
cellpadding: "0",
cellspacing: "0"
}, [createVNode(_component_hColgroup, {
columns: _ctx.store.states.columns.value,
"table-layout": _ctx.tableLayout
}, null, 8, ["columns", "table-layout"]), createVNode(_component_table_header, {
ref: "tableHeaderRef",
border: _ctx.border,
"default-sort": _ctx.defaultSort,
store: _ctx.store,
"append-filter-panel-to": _ctx.appendFilterPanelTo,
"allow-drag-last-column": _ctx.allowDragLastColumn,
onSetDragVisible: _ctx.setDragVisible
}, null, 8, [
"border",
"default-sort",
"store",
"append-filter-panel-to",
"allow-drag-last-column",
"onSetDragVisible"
])], 6)], 2)), [[_directive_mousewheel, _ctx.handleHeaderFooterMousewheel]]) : createCommentVNode("v-if", true),
createElementVNode("div", {
ref: "bodyWrapper",
class: normalizeClass(_ctx.ns.e("body-wrapper"))
}, [createVNode(_component_el_scrollbar, {
ref: "scrollBarRef",
"view-style": _ctx.scrollbarViewStyle,
"wrap-style": _ctx.scrollbarStyle,
always: _ctx.scrollbarAlwaysOn,
tabindex: _ctx.scrollbarTabindex,
native: _ctx.nativeScrollbar,
onScroll: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("scroll", $event))
}, {
default: withCtx(() => [
createElementVNode("table", {
ref: "tableBody",
class: normalizeClass(_ctx.ns.e("body")),
cellspacing: "0",
cellpadding: "0",
border: "0",
style: normalizeStyle({
width: _ctx.bodyWidth,
tableLayout: _ctx.tableLayout
})
}, [
createVNode(_component_hColgroup, {
columns: _ctx.store.states.columns.value,
"table-layout": _ctx.tableLayout
}, null, 8, ["columns", "table-layout"]),
_ctx.showHeader && _ctx.tableLayout === "auto" ? (openBlock(), createBlock(_component_table_header, {
key: 0,
ref: "tableHeaderRef",
class: normalizeClass(_ctx.ns.e("body-header")),
border: _ctx.border,
"default-sort": _ctx.defaultSort,
store: _ctx.store,
"append-filter-panel-to": _ctx.appendFilterPanelTo,
onSetDragVisible: _ctx.setDragVisible
}, null, 8, [
"class",
"border",
"default-sort",
"store",
"append-filter-panel-to",
"onSetDragVisible"
])) : createCommentVNode("v-if", true),
createVNode(_component_table_body, {
context: _ctx.context,
highlight: _ctx.highlightCurrentRow,
"row-class-name": _ctx.rowClassName,
"tooltip-effect": _ctx.computedTooltipEffect,
"tooltip-options": _ctx.computedTooltipOptions,
"row-style": _ctx.rowStyle,
store: _ctx.store,
stripe: _ctx.stripe
}, null, 8, [
"context",
"highlight",
"row-class-name",
"tooltip-effect",
"tooltip-options",
"row-style",
"store",
"stripe"
]),
_ctx.showSummary && _ctx.tableLayout === "auto" ? (openBlock(), createBlock(_component_table_footer, {
key: 1,
class: normalizeClass(_ctx.ns.e("body-footer")),
border: _ctx.border,
"default-sort": _ctx.defaultSort,
store: _ctx.store,
"sum-text": _ctx.computedSumText,
"summary-method": _ctx.summaryMethod
}, null, 8, [
"class",
"border",
"default-sort",
"store",
"sum-text",
"summary-method"
])) : createCommentVNode("v-if", true)
], 6),
_ctx.isEmpty ? (openBlock(), createElementBlock("div", {
key: 0,
ref: "emptyBlock",
style: normalizeStyle(_ctx.emptyBlockStyle),
class: normalizeClass(_ctx.ns.e("empty-block"))
}, [createElementVNode("span", { class: normalizeClass(_ctx.ns.e("empty-text")) }, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(toDisplayString(_ctx.computedEmptyText), 1)])], 2)], 6)) : createCommentVNode("v-if", true),
_ctx.$slots.append ? (openBlock(), createElementBlock("div", {
key: 1,
ref: "appendWrapper",
class: normalizeClass(_ctx.ns.e("append-wrapper"))
}, [renderSlot(_ctx.$slots, "append")], 2)) : createCommentVNode("v-if", true)
]),
_: 3
}, 8, [
"view-style",
"wrap-style",
"always",
"tabindex",
"native"
])], 2),
_ctx.showSummary && _ctx.tableLayout === "fixed" ? withDirectives((openBlock(), createElementBlock("div", {
key: 1,
ref: "footerWrapper",
class: normalizeClass(_ctx.ns.e("footer-wrapper"))
}, [createElementVNode("table", {
class: normalizeClass(_ctx.ns.e("footer")),
cellspacing: "0",
cellpadding: "0",
border: "0",
style: normalizeStyle(_ctx.tableBodyStyles)
}, [createVNode(_component_hColgroup, {
columns: _ctx.store.states.columns.value,
"table-layout": _ctx.tableLayout
}, null, 8, ["columns", "table-layout"]), createVNode(_component_table_footer, {
border: _ctx.border,
"default-sort": _ctx.defaultSort,
store: _ctx.store,
"sum-text": _ctx.computedSumText,
"summary-method": _ctx.summaryMethod
}, null, 8, [
"border",
"default-sort",
"store",
"sum-text",
"summary-method"
])], 6)], 2)), [[vShow, !_ctx.isEmpty], [_directive_mousewheel, _ctx.handleHeaderFooterMousewheel]]) : createCommentVNode("v-if", true),
_ctx.border || _ctx.isGroup ? (openBlock(), createElementBlock("div", {
key: 2,
class: normalizeClass(_ctx.ns.e("border-left-patch"))
}, null, 2)) : createCommentVNode("v-if", true)
], 2), withDirectives(createElementVNode("div", {
ref: "resizeProxy",
class: normalizeClass(_ctx.ns.e("column-resize-proxy"))
}, null, 2), [[vShow, _ctx.resizeProxyVisible]])], 46, _hoisted_1);
}
var table_default = /* @__PURE__ */ _plugin_vue_export_helper_default(table_vue_vue_type_script_lang_default, [["render", _sfc_render]]);
//#endregion
export { table_default as default };
//# sourceMappingURL=table.mjs.map
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,151 @@
import Mousewheel from "../../../directives/mousewheel/index.mjs";
import { useLocale } from "../../../hooks/use-locale/index.mjs";
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { ElScrollbar } from "../../scrollbar/index.mjs";
import { useGlobalConfig } from "../../config-provider/src/hooks/use-global-config.mjs";
import { createStore } from "./store/helper.mjs";
import TableLayout from "./table-layout.mjs";
import { TABLE_INJECTION_KEY } from "./tokens.mjs";
import { convertToRows } from "./table-header/utils-helper.mjs";
import table_header_default from "./table-header/index.mjs";
import table_body_default from "./table-body/index.mjs";
import table_footer_default from "./table-footer/index.mjs";
import useUtils from "./table/utils-helper.mjs";
import useStyle from "./table/style-helper.mjs";
import useKeyRender from "./table/key-render-helper.mjs";
import defaults_default from "./table/defaults.mjs";
import { hColgroup } from "./h-helper.mjs";
import { useScrollbar } from "./composables/use-scrollbar.mjs";
import { debounce } from "lodash-unified";
import { computed, defineComponent, getCurrentInstance, onBeforeUnmount, provide } from "vue";
//#region ../../packages/components/table/src/table.vue?vue&type=script&lang.ts
let tableIdSeed = 1;
var table_vue_vue_type_script_lang_default = defineComponent({
name: "ElTable",
directives: { Mousewheel },
components: {
TableHeader: table_header_default,
TableBody: table_body_default,
TableFooter: table_footer_default,
ElScrollbar,
hColgroup
},
props: defaults_default,
emits: [
"select",
"select-all",
"selection-change",
"cell-mouse-enter",
"cell-mouse-leave",
"cell-contextmenu",
"cell-click",
"cell-dblclick",
"row-click",
"row-contextmenu",
"row-dblclick",
"header-click",
"header-contextmenu",
"sort-change",
"filter-change",
"current-change",
"header-dragend",
"expand-change",
"scroll"
],
setup(props) {
const { t } = useLocale();
const ns = useNamespace("table");
const globalConfig = useGlobalConfig("table");
const table = getCurrentInstance();
provide(TABLE_INJECTION_KEY, table);
const store = createStore(table, props);
table.store = store;
const layout = new TableLayout({
store: table.store,
table,
fit: props.fit,
showHeader: props.showHeader
});
table.layout = layout;
const isEmpty = computed(() => (store.states.data.value || []).length === 0);
/**
* open functions
*/
const { setCurrentRow, getSelectionRows, toggleRowSelection, clearSelection, clearFilter, toggleAllSelection, toggleRowExpansion, clearSort, sort, updateKeyChildren } = useUtils(store);
const { isHidden, renderExpanded, setDragVisible, isGroup, handleMouseLeave, handleHeaderFooterMousewheel, tableSize, emptyBlockStyle, resizeProxyVisible, bodyWidth, resizeState, doLayout, tableBodyStyles, tableLayout, scrollbarViewStyle, scrollbarStyle } = useStyle(props, layout, store, table);
const { scrollBarRef, scrollTo, setScrollLeft, setScrollTop } = useScrollbar();
const debouncedUpdateLayout = debounce(doLayout, 50);
const tableId = `${ns.namespace.value}-table_${tableIdSeed++}`;
table.tableId = tableId;
table.state = {
isGroup,
resizeState,
doLayout,
debouncedUpdateLayout
};
const computedSumText = computed(() => props.sumText ?? t("el.table.sumText"));
const computedEmptyText = computed(() => {
return props.emptyText ?? t("el.table.emptyText");
});
const computedTooltipEffect = computed(() => props.tooltipEffect ?? globalConfig.value?.tooltipEffect);
const computedTooltipOptions = computed(() => props.tooltipOptions ?? globalConfig.value?.tooltipOptions);
const columns = computed(() => {
return convertToRows(store.states.originColumns.value)[0];
});
useKeyRender(table);
onBeforeUnmount(() => {
debouncedUpdateLayout.cancel();
});
return {
ns,
layout,
store,
columns,
handleHeaderFooterMousewheel,
handleMouseLeave,
tableId,
tableSize,
isHidden,
isEmpty,
renderExpanded,
resizeProxyVisible,
resizeState,
isGroup,
bodyWidth,
tableBodyStyles,
emptyBlockStyle,
debouncedUpdateLayout,
setCurrentRow,
getSelectionRows,
toggleRowSelection,
clearSelection,
clearFilter,
toggleAllSelection,
toggleRowExpansion,
clearSort,
doLayout,
sort,
updateKeyChildren,
t,
setDragVisible,
context: table,
computedSumText,
computedEmptyText,
computedTooltipEffect,
computedTooltipOptions,
tableLayout,
scrollbarViewStyle,
scrollbarStyle,
scrollBarRef,
scrollTo,
setScrollLeft,
setScrollTop,
allowDragLastColumn: props.allowDragLastColumn
};
}
});
//#endregion
export { table_vue_vue_type_script_lang_default as default };
//# sourceMappingURL=table.vue_vue_type_script_lang.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,183 @@
import { ComponentSize } from "../../../../constants/size.js";
import { Nullable } from "../../../../utils/typescript.js";
import "../../../../utils/index.js";
import { TableOverflowTooltipFormatter, TableOverflowTooltipOptions } from "../util.js";
import { TableColumnCtx } from "../table-column/defaults.js";
import { Store } from "../store/index.js";
import { TableLayout } from "../table-layout.js";
import { CSSProperties, ComponentInternalInstance, PropType, Ref, StyleValue, VNode } from "vue";
//#region ../../packages/components/table/src/table/defaults.d.ts
type DefaultRow = Record<PropertyKey, any>;
interface TableRefs {
tableWrapper: HTMLElement;
headerWrapper: HTMLElement;
footerWrapper: HTMLElement;
fixedBodyWrapper: HTMLElement;
rightFixedBodyWrapper: HTMLElement;
bodyWrapper: HTMLElement;
appendWrapper: HTMLElement;
[key: string]: any;
}
interface TableState {
isGroup: Ref<boolean>;
resizeState: Ref<{
width: any;
height: any;
}>;
doLayout: () => void;
debouncedUpdateLayout: () => void;
}
interface TreeProps {
hasChildren?: string;
children?: string;
checkStrictly?: boolean;
}
type HoverState<T extends DefaultRow> = Nullable<{
cell: HTMLElement;
column: TableColumnCtx<T>;
row: T;
}>;
type RIS<T extends DefaultRow> = {
row: T;
$index: number;
store: Store<T>;
expanded: boolean;
};
type RenderExpanded<T extends DefaultRow> = ({
row,
$index,
store,
expanded
}: RIS<T>) => VNode[] | undefined;
type SummaryMethod<T extends DefaultRow> = (data: {
columns: TableColumnCtx<T>[];
data: T[];
}) => (string | VNode)[];
interface Table<T extends DefaultRow = any> extends ComponentInternalInstance {
$ready: boolean;
hoverState?: HoverState<T> | null;
renderExpanded: RenderExpanded<T>;
store: Store<T>;
layout: TableLayout<T>;
refs: TableRefs;
tableId: string;
state: TableState;
}
type ColumnCls<T> = string | ((data: {
row: T;
rowIndex: number;
}) => string);
type ColumnStyle<T> = CSSProperties | ((data: {
row: T;
rowIndex: number;
}) => CSSProperties);
type CellCls<T extends DefaultRow> = string | ((data: {
row: T;
rowIndex: number;
column: TableColumnCtx<T>;
columnIndex: number;
}) => string);
type CellStyle<T extends DefaultRow> = CSSProperties | ((data: {
row: T;
rowIndex: number;
column: TableColumnCtx<T>;
columnIndex: number;
}) => CSSProperties);
type Layout = 'fixed' | 'auto';
interface TableProps<T extends DefaultRow> {
data: T[];
size?: ComponentSize;
width?: string | number;
height?: string | number;
maxHeight?: string | number;
fit?: boolean;
stripe?: boolean;
border?: boolean;
rowKey?: string | ((row: T) => string);
context?: Table<T>;
showHeader?: boolean;
showSummary?: boolean;
sumText?: string;
summaryMethod?: SummaryMethod<T>;
rowClassName?: ColumnCls<T>;
rowStyle?: ColumnStyle<T>;
cellClassName?: CellCls<T>;
cellStyle?: CellStyle<T>;
headerRowClassName?: ColumnCls<T>;
headerRowStyle?: ColumnStyle<T>;
headerCellClassName?: CellCls<T>;
headerCellStyle?: CellStyle<T>;
highlightCurrentRow?: boolean;
currentRowKey?: string | number;
emptyText?: string;
expandRowKeys?: Array<string>;
defaultExpandAll?: boolean;
rowExpandable?: (row: T, index: number) => boolean;
defaultSort?: Sort;
tooltipEffect?: string;
tooltipOptions?: TableOverflowTooltipOptions;
spanMethod?: (data: {
row: T;
rowIndex: number;
column: TableColumnCtx<T>;
columnIndex: number;
}) => number[] | {
rowspan: number;
colspan: number;
} | undefined;
selectOnIndeterminate?: boolean;
indent?: number;
treeProps?: TreeProps;
lazy?: boolean;
load?: (row: T, treeNode: TreeNode, resolve: (data: T[]) => void) => void;
className?: string;
style?: StyleValue;
tableLayout?: Layout;
scrollbarAlwaysOn?: boolean;
flexible?: boolean;
showOverflowTooltip?: boolean | TableOverflowTooltipOptions;
tooltipFormatter?: TableOverflowTooltipFormatter<T>;
appendFilterPanelTo?: string;
scrollbarTabindex?: number | string;
nativeScrollbar?: boolean;
}
type TableTooltipData<T extends DefaultRow> = Parameters<TableOverflowTooltipFormatter<T>>[0];
type TableSortOrder = 'ascending' | 'descending';
interface Sort {
prop: string;
order: TableSortOrder;
init?: any;
silent?: any;
}
interface Filter<T extends DefaultRow> {
column: TableColumnCtx<T>;
values: string[];
silent: any;
}
interface TreeNode {
expanded?: boolean;
loading?: boolean;
noLazyChildren?: boolean;
indent?: number;
level?: number;
display?: boolean;
}
interface RenderRowData<T extends DefaultRow> {
store: Store<T>;
_self: Table<T>;
column: TableColumnCtx<T>;
row: T;
$index: number;
cellIndex: number;
treeNode?: TreeNode;
expanded: boolean;
}
interface TableConfigContext {
showOverflowTooltip?: boolean | TableOverflowTooltipOptions;
tooltipEffect?: string;
tooltipOptions?: TableOverflowTooltipOptions;
tooltipFormatter?: TableOverflowTooltipFormatter<any>;
}
//#endregion
export { type CellCls, type CellStyle, type ColumnCls, type ColumnStyle, type DefaultRow, type Filter, type RenderExpanded, type RenderRowData, type Sort, type SummaryMethod, type Table, type TableConfigContext, type TableProps, type TableRefs, type TableSortOrder, type TableTooltipData, type TreeNode, type TreeProps };
@@ -0,0 +1,103 @@
import { useSizeProp } from "../../../../hooks/use-size/index.mjs";
//#region ../../packages/components/table/src/table/defaults.ts
var defaults_default = {
data: {
type: Array,
default: () => []
},
size: useSizeProp,
width: [String, Number],
height: [String, Number],
maxHeight: [String, Number],
fit: {
type: Boolean,
default: true
},
stripe: Boolean,
border: Boolean,
rowKey: [String, Function],
showHeader: {
type: Boolean,
default: true
},
showSummary: Boolean,
sumText: String,
summaryMethod: Function,
rowClassName: [String, Function],
rowStyle: [Object, Function],
cellClassName: [String, Function],
cellStyle: [Object, Function],
headerRowClassName: [String, Function],
headerRowStyle: [Object, Function],
headerCellClassName: [String, Function],
headerCellStyle: [Object, Function],
highlightCurrentRow: Boolean,
currentRowKey: [String, Number],
emptyText: String,
expandRowKeys: Array,
defaultExpandAll: Boolean,
rowExpandable: { type: Function },
defaultSort: Object,
tooltipEffect: String,
tooltipOptions: Object,
spanMethod: Function,
selectOnIndeterminate: {
type: Boolean,
default: true
},
indent: {
type: Number,
default: 16
},
treeProps: {
type: Object,
default: () => {
return {
hasChildren: "hasChildren",
children: "children",
checkStrictly: false
};
}
},
lazy: Boolean,
load: Function,
style: {
type: [
String,
Object,
Array
],
default: () => ({})
},
className: {
type: String,
default: ""
},
tableLayout: {
type: String,
default: "fixed"
},
scrollbarAlwaysOn: Boolean,
flexible: Boolean,
showOverflowTooltip: {
type: [Boolean, Object],
default: void 0
},
tooltipFormatter: Function,
appendFilterPanelTo: String,
scrollbarTabindex: {
type: [Number, String],
default: void 0
},
allowDragLastColumn: {
type: Boolean,
default: true
},
preserveExpandedContent: Boolean,
nativeScrollbar: Boolean
};
//#endregion
export { defaults_default as default };
//# sourceMappingURL=defaults.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,28 @@
import { onMounted, onUnmounted } from "vue";
//#region ../../packages/components/table/src/table/key-render-helper.ts
function useKeyRender(table) {
let observer;
const initWatchDom = () => {
const columnsWrapper = table.vnode.el.querySelector(".hidden-columns");
const config = {
childList: true,
subtree: true
};
const updateOrderFns = table.store.states.updateOrderFns;
observer = new MutationObserver(() => {
updateOrderFns.forEach((fn) => fn());
});
observer.observe(columnsWrapper, config);
};
onMounted(() => {
initWatchDom();
});
onUnmounted(() => {
observer?.disconnect();
});
}
//#endregion
export { useKeyRender as default };
//# sourceMappingURL=key-render-helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"key-render-helper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table/key-render-helper.ts"],"sourcesContent":["import { onMounted, onUnmounted } from 'vue'\n\nimport type { Table } from './defaults'\n\nexport default function useKeyRender(table: Table<[]>) {\n let observer: MutationObserver | undefined\n\n const initWatchDom = () => {\n const el = table.vnode.el\n const columnsWrapper = (el as HTMLElement).querySelector('.hidden-columns')\n const config = { childList: true, subtree: true }\n const updateOrderFns = table.store.states.updateOrderFns\n observer = new MutationObserver(() => {\n updateOrderFns.forEach((fn: () => void) => fn())\n })\n\n observer.observe(columnsWrapper!, config)\n }\n\n onMounted(() => {\n // fix https://github.com/element-plus/element-plus/issues/8528\n initWatchDom()\n })\n\n onUnmounted(() => {\n observer?.disconnect()\n })\n}\n"],"mappings":";;;AAIA,SAAwB,aAAa,OAAkB;CACrD,IAAI;CAEJ,MAAM,qBAAqB;EAEzB,MAAM,iBADK,MAAM,MAAM,GACoB,cAAc,kBAAkB;EAC3E,MAAM,SAAS;GAAE,WAAW;GAAM,SAAS;GAAM;EACjD,MAAM,iBAAiB,MAAM,MAAM,OAAO;AAC1C,aAAW,IAAI,uBAAuB;AACpC,kBAAe,SAAS,OAAmB,IAAI,CAAC;IAChD;AAEF,WAAS,QAAQ,gBAAiB,OAAO;;AAG3C,iBAAgB;AAEd,gBAAc;GACd;AAEF,mBAAkB;AAChB,YAAU,YAAY;GACtB"}
@@ -0,0 +1,201 @@
import { useFormSize } from "../../../form/src/hooks/use-form-common-props.mjs";
import { useEventListener, useResizeObserver } from "@vueuse/core";
import { computed, nextTick, onMounted, ref, unref, watch, watchEffect } from "vue";
//#region ../../packages/components/table/src/table/style-helper.ts
function useStyle(props, layout, store, table) {
const isHidden = ref(false);
const renderExpanded = ref(null);
const resizeProxyVisible = ref(false);
const setDragVisible = (visible) => {
resizeProxyVisible.value = visible;
};
const resizeState = ref({
width: null,
height: null,
headerHeight: null
});
const isGroup = ref(false);
const scrollbarViewStyle = {
display: "inline-block",
verticalAlign: "middle"
};
const tableWidth = ref();
const tableScrollHeight = ref(0);
const bodyScrollHeight = ref(0);
const headerScrollHeight = ref(0);
const footerScrollHeight = ref(0);
const appendScrollHeight = ref(0);
watch(() => props.height, (value) => {
layout.setHeight(value ?? null);
}, { immediate: true });
watch(() => props.maxHeight, (value) => {
layout.setMaxHeight(value ?? null);
}, { immediate: true });
watch(() => [props.currentRowKey, store.states.rowKey], ([currentRowKey, rowKey]) => {
if (!unref(rowKey) || !unref(currentRowKey)) return;
store.setCurrentRowKey(`${currentRowKey}`);
}, { immediate: true });
watch(() => props.data, (data) => {
table.store.commit("setData", data);
}, {
immediate: true,
deep: true
});
watchEffect(() => {
if (props.expandRowKeys) store.setExpandRowKeysAdapter(props.expandRowKeys);
});
const handleMouseLeave = () => {
table.store.commit("setHoverRow", null);
if (table.hoverState) table.hoverState = null;
};
const handleHeaderFooterMousewheel = (_event, data) => {
const { pixelX, pixelY } = data;
if (Math.abs(pixelX) >= Math.abs(pixelY)) table.refs.bodyWrapper.scrollLeft += data.pixelX / 5;
};
const shouldUpdateHeight = computed(() => {
return props.height || props.maxHeight || store.states.fixedColumns.value.length > 0 || store.states.rightFixedColumns.value.length > 0;
});
const tableBodyStyles = computed(() => {
return { width: layout.bodyWidth.value ? `${layout.bodyWidth.value}px` : "" };
});
const doLayout = () => {
if (shouldUpdateHeight.value) layout.updateElsHeight();
layout.updateColumnsWidth();
if (typeof window === "undefined") return;
requestAnimationFrame(syncPosition);
};
onMounted(async () => {
await nextTick();
store.updateColumns();
bindEvents();
requestAnimationFrame(doLayout);
const el = table.vnode.el;
const tableHeader = table.refs.headerWrapper;
if (props.flexible && el && el.parentElement) el.parentElement.style.minWidth = "0";
resizeState.value = {
width: tableWidth.value = el.offsetWidth,
height: el.offsetHeight,
headerHeight: props.showHeader && tableHeader ? tableHeader.offsetHeight : null
};
store.states.columns.value.forEach((column) => {
if (column.filteredValue && column.filteredValue.length) table.store.commit("filterChange", {
column,
values: column.filteredValue,
silent: true
});
});
table.$ready = true;
});
const setScrollClassByEl = (el, className) => {
if (!el) return;
const classList = Array.from(el.classList).filter((item) => !item.startsWith("is-scrolling-"));
classList.push(layout.scrollX.value ? className : "is-scrolling-none");
el.className = classList.join(" ");
};
const setScrollClass = (className) => {
const { tableWrapper } = table.refs;
setScrollClassByEl(tableWrapper, className);
};
const hasScrollClass = (className) => {
const { tableWrapper } = table.refs;
return !!(tableWrapper && tableWrapper.classList.contains(className));
};
const syncPosition = function() {
if (!table.refs.scrollBarRef) return;
if (!layout.scrollX.value) {
const scrollingNoneClass = "is-scrolling-none";
if (!hasScrollClass(scrollingNoneClass)) setScrollClass(scrollingNoneClass);
return;
}
const scrollContainer = table.refs.scrollBarRef.wrapRef;
if (!scrollContainer) return;
const { scrollLeft, offsetWidth, scrollWidth } = scrollContainer;
const { headerWrapper, footerWrapper } = table.refs;
if (headerWrapper) headerWrapper.scrollLeft = scrollLeft;
if (footerWrapper) footerWrapper.scrollLeft = scrollLeft;
if (scrollLeft >= scrollWidth - offsetWidth - 1) setScrollClass("is-scrolling-right");
else if (scrollLeft === 0) setScrollClass("is-scrolling-left");
else setScrollClass("is-scrolling-middle");
};
const bindEvents = () => {
if (!table.refs.scrollBarRef) return;
if (table.refs.scrollBarRef.wrapRef) useEventListener(table.refs.scrollBarRef.wrapRef, "scroll", syncPosition, { passive: true });
if (props.fit) useResizeObserver(table.vnode.el, resizeListener);
else useEventListener(window, "resize", resizeListener);
useResizeObserver(table.refs.tableInnerWrapper, () => {
resizeListener();
table.refs?.scrollBarRef?.update();
});
};
const resizeListener = () => {
const el = table.vnode.el;
if (!table.$ready || !el) return;
let shouldUpdateLayout = false;
const { width: oldWidth, height: oldHeight, headerHeight: oldHeaderHeight } = resizeState.value;
const width = tableWidth.value = el.offsetWidth;
if (oldWidth !== width) shouldUpdateLayout = true;
const height = el.offsetHeight;
if ((props.height || shouldUpdateHeight.value) && oldHeight !== height) shouldUpdateLayout = true;
const tableHeader = props.tableLayout === "fixed" ? table.refs.headerWrapper : table.refs.tableHeaderRef?.$el;
if (props.showHeader && tableHeader?.offsetHeight !== oldHeaderHeight) shouldUpdateLayout = true;
tableScrollHeight.value = table.refs.tableWrapper?.scrollHeight || 0;
headerScrollHeight.value = tableHeader?.scrollHeight || 0;
footerScrollHeight.value = table.refs.footerWrapper?.offsetHeight || 0;
appendScrollHeight.value = table.refs.appendWrapper?.offsetHeight || 0;
bodyScrollHeight.value = tableScrollHeight.value - headerScrollHeight.value - footerScrollHeight.value - appendScrollHeight.value;
if (shouldUpdateLayout) {
resizeState.value = {
width,
height,
headerHeight: props.showHeader && tableHeader?.offsetHeight || 0
};
doLayout();
}
};
const tableSize = useFormSize();
const bodyWidth = computed(() => {
const { bodyWidth: bodyWidth_, scrollY, gutterWidth } = layout;
return bodyWidth_.value ? `${bodyWidth_.value - (scrollY.value ? gutterWidth : 0)}px` : "";
});
const tableLayout = computed(() => {
if (props.maxHeight) return "fixed";
return props.tableLayout;
});
return {
isHidden,
renderExpanded,
setDragVisible,
isGroup,
handleMouseLeave,
handleHeaderFooterMousewheel,
tableSize,
emptyBlockStyle: computed(() => {
if (props.data && props.data.length) return;
let height = "100%";
if (props.height && bodyScrollHeight.value) height = `${bodyScrollHeight.value}px`;
const width = tableWidth.value;
return {
width: width ? `${width}px` : "",
height
};
}),
resizeProxyVisible,
bodyWidth,
resizeState,
doLayout,
tableBodyStyles,
tableLayout,
scrollbarViewStyle,
scrollbarStyle: computed(() => {
if (props.height) return { height: "100%" };
if (props.maxHeight) if (!Number.isNaN(Number(props.maxHeight))) return { maxHeight: `${+props.maxHeight - headerScrollHeight.value - footerScrollHeight.value}px` };
else return { maxHeight: `calc(${props.maxHeight} - ${headerScrollHeight.value + footerScrollHeight.value}px)` };
return {};
})
};
}
//#endregion
export { useStyle as default };
//# sourceMappingURL=style-helper.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,53 @@
//#region ../../packages/components/table/src/table/utils-helper.ts
function useUtils(store) {
const setCurrentRow = (row) => {
store.commit("setCurrentRow", row);
};
const getSelectionRows = () => {
return store.getSelectionRows();
};
const toggleRowSelection = (row, selected, ignoreSelectable = true) => {
store.toggleRowSelection(row, selected, false, ignoreSelectable);
store.updateAllSelected();
};
const clearSelection = () => {
store.clearSelection();
};
const clearFilter = (columnKeys) => {
store.clearFilter(columnKeys);
};
const toggleAllSelection = () => {
store.commit("toggleAllSelection");
};
const toggleRowExpansion = (row, expanded) => {
store.toggleRowExpansionAdapter(row, expanded);
};
const clearSort = () => {
store.clearSort();
};
const sort = (prop, order) => {
store.commit("sort", {
prop,
order
});
};
const updateKeyChildren = (key, data) => {
store.updateKeyChildren(key, data);
};
return {
setCurrentRow,
getSelectionRows,
toggleRowSelection,
clearSelection,
clearFilter,
toggleAllSelection,
toggleRowExpansion,
clearSort,
sort,
updateKeyChildren
};
}
//#endregion
export { useUtils as default };
//# sourceMappingURL=utils-helper.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"utils-helper.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/table/utils-helper.ts"],"sourcesContent":["import type { Store } from '../store'\nimport type { DefaultRow } from './defaults'\n\nfunction useUtils<T extends DefaultRow>(store: Store<T>) {\n const setCurrentRow = (row: T) => {\n store.commit('setCurrentRow', row)\n }\n const getSelectionRows = () => {\n return store.getSelectionRows()\n }\n const toggleRowSelection = (\n row: T,\n selected?: boolean,\n ignoreSelectable = true\n ) => {\n store.toggleRowSelection(row, selected, false, ignoreSelectable)\n store.updateAllSelected()\n }\n const clearSelection = () => {\n store.clearSelection()\n }\n const clearFilter = (columnKeys?: string[] | string) => {\n store.clearFilter(columnKeys)\n }\n const toggleAllSelection = () => {\n store.commit('toggleAllSelection')\n }\n const toggleRowExpansion = (row: T, expanded?: boolean) => {\n store.toggleRowExpansionAdapter(row, expanded)\n }\n const clearSort = () => {\n store.clearSort()\n }\n const sort = (prop: string, order: string) => {\n store.commit('sort', { prop, order })\n }\n const updateKeyChildren = (key: string, data: T[]) => {\n store.updateKeyChildren(key, data)\n }\n\n return {\n setCurrentRow,\n getSelectionRows,\n toggleRowSelection,\n clearSelection,\n clearFilter,\n toggleAllSelection,\n toggleRowExpansion,\n clearSort,\n sort,\n updateKeyChildren,\n }\n}\n\nexport default useUtils\n"],"mappings":";AAGA,SAAS,SAA+B,OAAiB;CACvD,MAAM,iBAAiB,QAAW;AAChC,QAAM,OAAO,iBAAiB,IAAI;;CAEpC,MAAM,yBAAyB;AAC7B,SAAO,MAAM,kBAAkB;;CAEjC,MAAM,sBACJ,KACA,UACA,mBAAmB,SAChB;AACH,QAAM,mBAAmB,KAAK,UAAU,OAAO,iBAAiB;AAChE,QAAM,mBAAmB;;CAE3B,MAAM,uBAAuB;AAC3B,QAAM,gBAAgB;;CAExB,MAAM,eAAe,eAAmC;AACtD,QAAM,YAAY,WAAW;;CAE/B,MAAM,2BAA2B;AAC/B,QAAM,OAAO,qBAAqB;;CAEpC,MAAM,sBAAsB,KAAQ,aAAuB;AACzD,QAAM,0BAA0B,KAAK,SAAS;;CAEhD,MAAM,kBAAkB;AACtB,QAAM,WAAW;;CAEnB,MAAM,QAAQ,MAAc,UAAkB;AAC5C,QAAM,OAAO,QAAQ;GAAE;GAAM;GAAO,CAAC;;CAEvC,MAAM,qBAAqB,KAAa,SAAc;AACpD,QAAM,kBAAkB,KAAK,KAAK;;AAGpC,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD"}
@@ -0,0 +1 @@
import _default from "./table-column/index.js";
@@ -0,0 +1,8 @@
import table_column_default from "./table-column/index.mjs";
//#region ../../packages/components/table/src/tableColumn.ts
var tableColumn_default = table_column_default;
//#endregion
export { tableColumn_default as default };
//# sourceMappingURL=tableColumn.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"tableColumn.mjs","names":["ElTableColumn"],"sources":["../../../../../../packages/components/table/src/tableColumn.ts"],"sourcesContent":["import ElTableColumn from './table-column'\n\nexport default ElTableColumn\n"],"mappings":";;;AAEA,0BAAeA"}
@@ -0,0 +1,6 @@
//#region ../../packages/components/table/src/tokens.ts
const TABLE_INJECTION_KEY = Symbol("ElTable");
//#endregion
export { TABLE_INJECTION_KEY };
//# sourceMappingURL=tokens.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"tokens.mjs","names":[],"sources":["../../../../../../packages/components/table/src/tokens.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\nimport type { DefaultRow, Table } from './table/defaults'\n\nexport const TABLE_INJECTION_KEY: InjectionKey<Table<DefaultRow>> =\n Symbol('ElTable')\n"],"mappings":";AAGA,MAAa,sBACX,OAAO,UAAU"}
+15
View File
@@ -0,0 +1,15 @@
import { ElTooltipProps } from "../../tooltip/src/tooltip.js";
import "../../tooltip/index.js";
import { TableColumnCtx } from "./table-column/defaults.js";
import { DefaultRow } from "./table/defaults.js";
import { CSSProperties, VNode } from "vue";
//#region ../../packages/components/table/src/util.d.ts
type TableOverflowTooltipOptions = Partial<Pick<ElTooltipProps, 'appendTo' | 'effect' | 'enterable' | 'hideAfter' | 'offset' | 'placement' | 'popperClass' | 'popperOptions' | 'showAfter' | 'showArrow' | 'transition'>>;
type TableOverflowTooltipFormatter<T extends DefaultRow> = (data: {
row: T;
column: TableColumnCtx<T>;
cellValue: any;
}) => VNode | string;
//#endregion
export { TableOverflowTooltipFormatter, TableOverflowTooltipOptions };
+336
View File
@@ -0,0 +1,336 @@
import { isArray, isBoolean, isFunction, isNumber, isObject, isString, isUndefined as isUndefined$1 } from "../../../utils/types.mjs";
import { getProp, hasOwn } from "../../../utils/objects.mjs";
import { throwError } from "../../../utils/error.mjs";
import { ensureArray } from "../../../utils/arrays.mjs";
import { ElTooltip } from "../../tooltip/index.mjs";
import { flatMap, get, isNull, merge } from "lodash-unified";
import { Comment, Fragment, createVNode, isVNode, render } from "vue";
//#region ../../packages/components/table/src/util.ts
const getCell = function(event) {
return event.target?.closest("td");
};
const orderBy = function(array, sortKey, reverse, sortMethod, sortBy) {
if (!sortKey && !sortMethod && (!sortBy || isArray(sortBy) && !sortBy.length)) return array;
if (isString(reverse)) reverse = reverse === "descending" ? -1 : 1;
else reverse = reverse && reverse < 0 ? -1 : 1;
const getKey = sortMethod ? null : function(value, index) {
if (sortBy) return flatMap(ensureArray(sortBy), (by) => {
if (isString(by)) return get(value, by);
else return by(value, index, array);
});
if (sortKey !== "$key") {
if (isObject(value) && "$value" in value) value = value.$value;
}
return [isObject(value) ? sortKey ? get(value, sortKey) : null : value];
};
const compare = function(a, b) {
if (sortMethod) return sortMethod(a.value, b.value);
for (let i = 0, len = a.key?.length ?? 0; i < len; i++) {
if (a.key?.[i] < b.key?.[i]) return -1;
if (a.key?.[i] > b.key?.[i]) return 1;
}
return 0;
};
return array.map((value, index) => {
return {
value,
index,
key: getKey ? getKey(value, index) : null
};
}).sort((a, b) => {
let order = compare(a, b);
if (!order) order = a.index - b.index;
return order * +reverse;
}).map((item) => item.value);
};
const getColumnById = function(table, columnId) {
let column = null;
table.columns.forEach((item) => {
if (item.id === columnId) column = item;
});
return column;
};
const getColumnByKey = function(table, columnKey) {
let column = null;
for (let i = 0; i < table.columns.length; i++) {
const item = table.columns[i];
if (item.columnKey === columnKey) {
column = item;
break;
}
}
if (!column) throwError("ElTable", `No column matching with column-key: ${columnKey}`);
return column;
};
const getColumnByCell = function(table, cell, namespace) {
const matches = (cell.className || "").match(new RegExp(`${namespace}-table_[^\\s]+`, "gm"));
if (matches) return getColumnById(table, matches[0]);
return null;
};
const getRowIdentity = (row, rowKey) => {
if (!row) throw new Error("Row is required when get row identity");
if (isString(rowKey)) {
if (!rowKey.includes(".")) return `${row[rowKey]}`;
const key = rowKey.split(".");
let current = row;
for (const element of key) current = current[element];
return `${current}`;
} else if (isFunction(rowKey)) return rowKey.call(null, row);
return "";
};
const getKeysMap = function(array, rowKey, flatten = false, childrenKey = "children") {
const data = array || [];
const arrayMap = {};
data.forEach((row, index) => {
arrayMap[getRowIdentity(row, rowKey)] = {
row,
index
};
if (flatten) {
const children = row[childrenKey];
if (isArray(children)) Object.assign(arrayMap, getKeysMap(children, rowKey, true, childrenKey));
}
});
return arrayMap;
};
function mergeOptions(defaults, config) {
const options = {};
let key;
for (key in defaults) options[key] = defaults[key];
for (key in config) if (hasOwn(config, key)) {
const value = config[key];
if (!isUndefined$1(value)) options[key] = value;
}
return options;
}
function parseWidth(width) {
if (width === "") return width;
if (!isUndefined$1(width)) {
width = Number.parseInt(width, 10);
if (Number.isNaN(width)) width = "";
}
return width;
}
function parseMinWidth(minWidth) {
if (minWidth === "") return minWidth;
if (!isUndefined$1(minWidth)) {
minWidth = parseWidth(minWidth);
if (Number.isNaN(minWidth)) minWidth = 80;
}
return minWidth;
}
function parseHeight(height) {
if (isNumber(height)) return height;
if (isString(height)) if (/^\d+(?:px)?$/.test(height)) return Number.parseInt(height, 10);
else return height;
return null;
}
function compose(...funcs) {
if (funcs.length === 0) return (arg) => arg;
if (funcs.length === 1) return funcs[0];
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
function toggleRowStatus(statusArr, row, newVal, tableTreeProps, selectable, rowIndex, rowKey) {
let _rowIndex = rowIndex ?? 0;
let changed = false;
const getIndex = () => {
if (!rowKey) return statusArr.indexOf(row);
const id = getRowIdentity(row, rowKey);
return statusArr.findIndex((item) => getRowIdentity(item, rowKey) === id);
};
const index = getIndex();
const included = index !== -1;
const isRowSelectable = selectable?.call(null, row, _rowIndex);
const toggleStatus = (type) => {
if (type === "add") statusArr.push(row);
else statusArr.splice(index, 1);
changed = true;
};
const getChildrenCount = (row) => {
let count = 0;
const children = tableTreeProps?.children && row[tableTreeProps.children];
if (children && isArray(children)) {
count += children.length;
children.forEach((item) => {
count += getChildrenCount(item);
});
}
return count;
};
if (!selectable || isRowSelectable) if (isBoolean(newVal)) {
if (newVal && !included) toggleStatus("add");
else if (!newVal && included) toggleStatus("remove");
} else included ? toggleStatus("remove") : toggleStatus("add");
if (!tableTreeProps?.checkStrictly && tableTreeProps?.children && isArray(row[tableTreeProps.children])) row[tableTreeProps.children].forEach((item) => {
const childChanged = toggleRowStatus(statusArr, item, newVal ?? !included, tableTreeProps, selectable, _rowIndex + 1, rowKey);
_rowIndex += getChildrenCount(item) + 1;
if (childChanged) changed = childChanged;
});
return changed;
}
function walkTreeNode(root, cb, childrenKey = "children", lazyKey = "hasChildren", lazy = false) {
const isNil = (array) => !(isArray(array) && array.length);
function _walker(parent, children, level) {
cb(parent, children, level);
children.forEach((item) => {
if (item[lazyKey] && lazy) {
cb(item, null, level + 1);
return;
}
const children = item[childrenKey];
if (!isNil(children)) _walker(item, children, level + 1);
});
}
root.forEach((item) => {
if (item[lazyKey] && lazy) {
cb(item, null, 0);
return;
}
const children = item[childrenKey];
if (!isNil(children)) _walker(item, children, 0);
});
}
const getTableOverflowTooltipProps = (props, innerText, row, column) => {
const popperOptions = {
strategy: "fixed",
...props.popperOptions
};
const tooltipFormatterContent = isFunction(column?.tooltipFormatter) ? column.tooltipFormatter({
row,
column,
cellValue: getProp(row, column.property).value
}) : void 0;
if (isVNode(tooltipFormatterContent)) return {
slotContent: tooltipFormatterContent,
content: null,
...props,
popperOptions
};
return {
slotContent: null,
content: tooltipFormatterContent ?? innerText,
...props,
popperOptions
};
};
let removePopper = null;
function createTablePopper(props, popperContent, row, column, trigger, table) {
const tableOverflowTooltipProps = getTableOverflowTooltipProps(props, popperContent, row, column);
const mergedProps = {
...tableOverflowTooltipProps,
slotContent: void 0
};
if (removePopper?.trigger === trigger) {
const comp = removePopper.vm?.component;
merge(comp?.props, mergedProps);
if (comp && tableOverflowTooltipProps.slotContent) comp.slots.content = () => [tableOverflowTooltipProps.slotContent];
return;
}
removePopper?.();
const parentNode = table?.refs.tableWrapper;
const ns = parentNode?.dataset.prefix;
const vm = createVNode(ElTooltip, {
virtualTriggering: true,
virtualRef: trigger,
appendTo: parentNode,
placement: "top",
transition: "none",
offset: 0,
hideAfter: 0,
...mergedProps
}, tableOverflowTooltipProps.slotContent ? { content: () => tableOverflowTooltipProps.slotContent } : void 0);
vm.appContext = {
...table.appContext,
...table
};
const container = document.createElement("div");
render(vm, container);
vm.component.exposed.onOpen();
const scrollContainer = parentNode?.querySelector(`.${ns}-scrollbar__wrap`);
removePopper = () => {
if (vm.component?.exposed?.onClose) vm.component.exposed.onClose();
render(null, container);
const currentRemovePopper = removePopper;
scrollContainer?.removeEventListener("scroll", currentRemovePopper);
currentRemovePopper.trigger = void 0;
currentRemovePopper.vm = void 0;
removePopper = null;
};
removePopper.trigger = trigger ?? void 0;
removePopper.vm = vm;
scrollContainer?.addEventListener("scroll", removePopper);
}
function getCurrentColumns(column) {
if (column.children) return flatMap(column.children, getCurrentColumns);
else return [column];
}
function getColSpan(colSpan, column) {
return colSpan + column.colSpan;
}
const isFixedColumn = (index, fixed, store, realColumns) => {
let start = 0;
let after = index;
const columns = store.states.columns.value;
if (realColumns) {
const curColumns = getCurrentColumns(realColumns[index]);
start = columns.slice(0, columns.indexOf(curColumns[0])).reduce(getColSpan, 0);
after = start + curColumns.reduce(getColSpan, 0) - 1;
} else start = index;
let fixedLayout;
switch (fixed) {
case "left":
if (after < store.states.fixedLeafColumnsLength.value) fixedLayout = "left";
break;
case "right":
if (start >= columns.length - store.states.rightFixedLeafColumnsLength.value) fixedLayout = "right";
break;
default: if (after < store.states.fixedLeafColumnsLength.value) fixedLayout = "left";
else if (start >= columns.length - store.states.rightFixedLeafColumnsLength.value) fixedLayout = "right";
}
return fixedLayout ? {
direction: fixedLayout,
start,
after
} : {};
};
const getFixedColumnsClass = (namespace, index, fixed, store, realColumns, offset = 0) => {
const classes = [];
const { direction, start, after } = isFixedColumn(index, fixed, store, realColumns);
if (direction) {
const isLeft = direction === "left";
classes.push(`${namespace}-fixed-column--${direction}`);
if (isLeft && after + offset === store.states.fixedLeafColumnsLength.value - 1) classes.push("is-last-column");
else if (!isLeft && start - offset === store.states.columns.value.length - store.states.rightFixedLeafColumnsLength.value) classes.push("is-first-column");
}
return classes;
};
function getOffset(offset, column) {
return offset + (isNull(column.realWidth) || Number.isNaN(column.realWidth) ? Number(column.width) : column.realWidth);
}
const getFixedColumnOffset = (index, fixed, store, realColumns) => {
const { direction, start = 0, after = 0 } = isFixedColumn(index, fixed, store, realColumns);
if (!direction) return;
const styles = {};
const isLeft = direction === "left";
const columns = store.states.columns.value;
if (isLeft) styles.left = columns.slice(0, start).reduce(getOffset, 0);
else styles.right = columns.slice(after + 1).reverse().reduce(getOffset, 0);
return styles;
};
const ensurePosition = (style, key) => {
if (!style) return;
if (!Number.isNaN(style[key])) style[key] = `${style[key]}px`;
};
function ensureValidVNode(vnodes) {
return vnodes.some((child) => {
if (!isVNode(child)) return true;
if (child.type === Comment) return false;
if (child.type === Fragment && !ensureValidVNode(child.children)) return false;
return true;
}) ? vnodes : null;
}
//#endregion
export { compose, createTablePopper, ensurePosition, ensureValidVNode, getCell, getColumnByCell, getColumnById, getColumnByKey, getFixedColumnOffset, getFixedColumnsClass, getKeysMap, getRowIdentity, isFixedColumn, mergeOptions, orderBy, parseHeight, parseMinWidth, parseWidth, removePopper, toggleRowStatus, walkTreeNode };
//# sourceMappingURL=util.mjs.map
File diff suppressed because one or more lines are too long
+5
View File
@@ -0,0 +1,5 @@
import "../../base/style/css.mjs";
import "../../scrollbar/style/css.mjs";
import "../../tooltip/style/css.mjs";
import "../../checkbox/style/css.mjs";
import "element-plus/theme-chalk/el-table.css";
@@ -0,0 +1,5 @@
import "../../base/style/index.mjs";
import "../../scrollbar/style/index.mjs";
import "../../tooltip/style/index.mjs";
import "../../checkbox/style/index.mjs";
import "element-plus/theme-chalk/src/table.scss";