UNPKG

@arco-design/web-vue

Version:

Arco Design Vue 2.0: A Vue.js 3 UI Library

1,429 lines (1,428 loc) 52.9 kB
"use strict"; var vue = require("vue"); var globalConfig = require("../_utils/global-config.js"); var is = require("../_utils/is.js"); var debounce = require("../_utils/debounce.js"); var utils = require("./utils.js"); var useRowSelection = require("./hooks/use-row-selection.js"); var useExpand = require("./hooks/use-expand.js"); var usePagination = require("./hooks/use-pagination.js"); var index$5 = require("../icon/icon-plus/index.js"); var index$4 = require("../icon/icon-minus/index.js"); var index = require("../spin/index.js"); var index$2 = require("../pagination/index.js"); var index$3 = require("../empty/index.js"); var tableColGroup = require("./table-col-group.js"); var tableThead = require("./table-thead.js"); var tableTbody = require("./table-tbody.js"); var tableTr = require("./table-tr.js"); var tableTh = require("./table-th.js"); var tableTd = require("./table-td.js"); var tableOperationTh = require("./table-operation-th.js"); var tableOperationTd = require("./table-operation-td.js"); var virtualList = require("../_components/virtual-list-v2/virtual-list.js"); var resizeObserver = require("../_components/resize-observer.js"); var omit = require("../_utils/omit.js"); var context = require("../config-provider/context.js"); var useDrag = require("./hooks/use-drag.js"); var useColumnResize = require("./hooks/use-column-resize.js"); var context$1 = require("./context.js"); var useFilter = require("./hooks/use-filter.js"); var useSorter = require("./hooks/use-sorter.js"); var useSpan = require("./hooks/use-span.js"); var useChildrenComponents = require("../_hooks/use-children-components.js"); var index$1 = require("../scrollbar/index.js"); var useComponentRef = require("../_hooks/use-component-ref.js"); var useScrollbar = require("../_hooks/use-scrollbar.js"); var getValueByPath = require("../_utils/get-value-by-path.js"); function _isSlot(s) { return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !vue.isVNode(s); } const DEFAULT_BORDERED = { wrapper: true, cell: false, headerCell: false, bodyCell: false }; var _Table = vue.defineComponent({ name: "Table", props: { columns: { type: Array, default: () => [] }, data: { type: Array, default: () => [] }, bordered: { type: [Boolean, Object], default: true }, hoverable: { type: Boolean, default: true }, stripe: { type: Boolean, default: false }, size: { type: String, default: () => { var _a, _b; return (_b = (_a = vue.inject(context.configProviderInjectionKey, void 0)) == null ? void 0 : _a.size) != null ? _b : "large"; } }, tableLayoutFixed: { type: Boolean, default: false }, loading: { type: [Boolean, Object], default: false }, rowSelection: { type: Object }, expandable: { type: Object }, scroll: { type: Object }, pagination: { type: [Boolean, Object], default: true }, pagePosition: { type: String, default: "br" }, indentSize: { type: Number, default: 16 }, rowKey: { type: String, default: "key" }, showHeader: { type: Boolean, default: true }, virtualListProps: { type: Object }, spanMethod: { type: Function }, spanAll: { type: Boolean, default: false }, components: { type: Object }, loadMore: { type: Function }, filterIconAlignLeft: { type: Boolean, default: false }, hideExpandButtonOnEmpty: { type: Boolean, default: false }, rowClass: { type: [String, Array, Object, Function] }, draggable: { type: Object }, rowNumber: { type: [Boolean, Object] }, columnResizable: { type: Boolean }, summary: { type: [Boolean, Function] }, summaryText: { type: String, default: "Summary" }, summarySpanMethod: { type: Function }, selectedKeys: { type: Array }, defaultSelectedKeys: { type: Array }, expandedKeys: { type: Array }, defaultExpandedKeys: { type: Array }, defaultExpandAllRows: { type: Boolean, default: false }, stickyHeader: { type: [Boolean, Number], default: false }, scrollbar: { type: [Object, Boolean], default: true }, showEmptyTree: { type: Boolean, default: false } }, emits: { "update:selectedKeys": (rowKeys) => true, "update:expandedKeys": (rowKeys) => true, "expand": (rowKey, record) => true, "expandedChange": (rowKeys) => true, "select": (rowKeys, rowKey, record) => true, "selectAll": (checked) => true, "selectionChange": (rowKeys) => true, "sorterChange": (dataIndex, direction) => true, "filterChange": (dataIndex, filteredValues) => true, "pageChange": (page) => true, "pageSizeChange": (pageSize) => true, "change": (data, extra, currentData) => true, "cellMouseEnter": (record, column, ev) => true, "cellMouseLeave": (record, column, ev) => true, "cellClick": (record, column, ev) => true, "rowClick": (record, ev) => true, "headerClick": (column, ev) => true, "columnResize": (dataIndex, width) => true, "rowDblclick": (record, ev) => true, "cellDblclick": (record, column, ev) => true, "rowContextmenu": (record, ev) => true, "cellContextmenu": (record, column, ev) => true }, setup(props, { emit, slots }) { const { columns, rowKey, rowSelection, expandable, loadMore, filterIconAlignLeft, selectedKeys, defaultSelectedKeys, expandedKeys, defaultExpandedKeys, defaultExpandAllRows, spanMethod, draggable, summarySpanMethod, scrollbar, showEmptyTree } = vue.toRefs(props); const prefixCls = globalConfig.getPrefixCls("table"); const configCtx = vue.inject(context.configProviderInjectionKey, void 0); const bordered = vue.computed(() => { if (is.isObject(props.bordered)) { return { ...DEFAULT_BORDERED, ...props.bordered }; } return { ...DEFAULT_BORDERED, wrapper: props.bordered }; }); const { children, components } = useChildrenComponents.useChildrenComponents("TableColumn"); const checkStrictly = vue.computed(() => { var _a, _b; return (_b = (_a = rowSelection.value) == null ? void 0 : _a.checkStrictly) != null ? _b : true; }); const { displayScrollbar, scrollbarProps } = useScrollbar.useScrollbar(scrollbar); const isScroll = vue.computed(() => { var _a, _b, _c, _d; const x = Boolean(((_a = props.scroll) == null ? void 0 : _a.x) || ((_b = props.scroll) == null ? void 0 : _b.minWidth)); const y = Boolean(((_c = props.scroll) == null ? void 0 : _c.y) || ((_d = props.scroll) == null ? void 0 : _d.maxHeight)); return { x, y }; }); const summaryRef = vue.ref(); const thRefs = vue.ref({}); const { componentRef: contentComRef, elementRef: contentRef } = useComponentRef.useComponentRef("containerRef"); const { componentRef: tbodyComRef, elementRef: tbodyRef } = useComponentRef.useComponentRef("containerRef"); const { componentRef: virtualComRef, elementRef: virtualRef } = useComponentRef.useComponentRef("viewportRef"); const { componentRef: theadComRef, elementRef: theadRef } = useComponentRef.useComponentRef("containerRef"); const containerElement = vue.computed(() => { if (splitTable.value) { if (isVirtualList.value) { return virtualRef.value; } return tbodyRef.value; } return contentRef.value; }); const splitTable = vue.computed(() => isScroll.value.y || props.stickyHeader || isVirtualList.value || isScroll.value.x && flattenData.value.length === 0); const slotColumnMap = vue.reactive(/* @__PURE__ */ new Map()); const slotColumns = vue.ref(); vue.watch([components, slotColumnMap], ([components2, slotColumnMap2]) => { if (components2.length > 0) { const columns2 = []; components2.forEach((id) => { const column = slotColumnMap2.get(id); if (column) columns2.push(column); }); slotColumns.value = columns2; } else { slotColumns.value = void 0; } }); const dataColumnMap = /* @__PURE__ */ new Map(); const dataColumns = vue.ref([]); const groupColumns = vue.ref([]); const { resizingColumn, columnWidth, handleThMouseDown } = useColumnResize.useColumnResize(thRefs, emit); vue.watch([columns, slotColumns, columnWidth], ([columns2, slotColumns2]) => { var _a; const result = utils.getGroupColumns((_a = slotColumns2 != null ? slotColumns2 : columns2) != null ? _a : [], dataColumnMap, columnWidth); dataColumns.value = result.dataColumns; groupColumns.value = result.groupColumns; }, { immediate: true, deep: true }); const isPaginationTop = vue.computed(() => ["tl", "top", "tr"].includes(props.pagePosition)); const hasLeftFixedColumn = vue.ref(false); const hasRightFixedColumn = vue.ref(false); const hasLeftFixedDataColumns = vue.ref(false); vue.watchEffect(() => { var _a, _b, _c; let _hasLeftFixedColumn = false; let _hasRightFixedColumn = false; let _hasLeftFixedDataColumns = false; if (((_a = props.rowSelection) == null ? void 0 : _a.fixed) || ((_b = props.expandable) == null ? void 0 : _b.fixed) || ((_c = props.draggable) == null ? void 0 : _c.fixed)) { _hasLeftFixedColumn = true; } for (const column of dataColumns.value) { if (column.fixed === "left") { _hasLeftFixedColumn = true; _hasLeftFixedDataColumns = true; } else if (column.fixed === "right") { _hasRightFixedColumn = true; } } if (_hasLeftFixedColumn !== hasLeftFixedColumn.value) { hasLeftFixedColumn.value = _hasLeftFixedColumn; } if (_hasRightFixedColumn !== hasRightFixedColumn.value) { hasRightFixedColumn.value = _hasRightFixedColumn; } if (_hasLeftFixedDataColumns !== hasLeftFixedDataColumns.value) { hasLeftFixedDataColumns.value = _hasLeftFixedDataColumns; } }); const hasEllipsis = vue.computed(() => { for (const col of dataColumns.value) { if (col.ellipsis) { return true; } } return false; }); const handleChange = (type) => { const extra = { type, page: page.value, pageSize: pageSize.value, sorter: computedSorter.value, filters: computedFilters.value, dragTarget: type === "drag" ? dragState.data : void 0 }; emit("change", flattenRawData.value, extra, sortedData.value); }; const handleFilterChange = (dataIndex, filteredValues) => { _filters.value = { ...computedFilters.value, [dataIndex]: filteredValues }; emit("filterChange", dataIndex, filteredValues); handleChange("filter"); }; const handleSorterChange = (dataIndex, direction) => { _sorter.value = direction ? { field: dataIndex, direction } : void 0; emit("sorterChange", dataIndex, direction); handleChange("sorter"); }; const { _filters, computedFilters, resetFilters, clearFilters } = useFilter.useFilter({ columns: dataColumns, onFilterChange: handleFilterChange }); const { _sorter, computedSorter, resetSorters, clearSorters } = useSorter.useSorter({ columns: dataColumns, onSorterChange: handleSorterChange }); const disabledKeys = /* @__PURE__ */ new Set(); const allRowKeys = vue.computed(() => { const allRowKeys2 = []; disabledKeys.clear(); const travelData = (data) => { if (is.isArray(data) && data.length > 0) { for (const record of data) { allRowKeys2.push(record[rowKey.value]); if (record.disabled) { disabledKeys.add(record[rowKey.value]); } if (record.children) { travelData(record.children); } } } }; travelData(props.data); return allRowKeys2; }); const currentAllRowKeys = vue.computed(() => { const keys = []; const travel = (data) => { for (const record of data) { keys.push(record.key); if (record.children) { travel(record.children); } } }; travel(flattenData.value); return keys; }); const currentAllEnabledRowKeys = vue.computed(() => { const keys = []; const travel = (data) => { for (const record of data) { if (!record.disabled) { keys.push(record.key); } if (record.children) { travel(record.children); } } }; travel(flattenData.value); return keys; }); const { isRadio, selectedRowKeys, currentSelectedRowKeys, handleSelect, handleSelectAllLeafs, handleSelectAll, select, selectAll, clearSelected } = useRowSelection.useRowSelection({ selectedKeys, defaultSelectedKeys, rowSelection, currentAllRowKeys, currentAllEnabledRowKeys, emit }); const { expandedRowKeys, handleExpand, expand, expandAll } = useExpand.useExpand({ expandedKeys, defaultExpandedKeys, defaultExpandAllRows, expandable, allRowKeys, emit }); const lazyLoadData = vue.reactive({}); const addLazyLoadData = (children2, record) => { if (children2) { lazyLoadData[record.key] = children2; } }; const isValidRecord = (record) => { var _a, _b; for (const field of Object.keys(computedFilters.value)) { const filteredValues = computedFilters.value[field]; const column = dataColumnMap.get(field); if (column && ((_a = column.filterable) == null ? void 0 : _a.filter) && filteredValues.length > 0) { const result = (_b = column.filterable) == null ? void 0 : _b.filter(filteredValues, record.raw); if (!result) { return result; } } } return true; }; const { dragType, dragState, handleDragStart, handleDragEnter, handleDragLeave, handleDragover, handleDragEnd, handleDrop } = useDrag.useDrag(draggable); const processedData = vue.computed(() => { var _a; const travel = (data) => { const result = []; for (const _record of data) { const record = { raw: _record, key: _record[props.rowKey], disabled: _record.disabled, expand: _record.expand, isLeaf: _record.isLeaf }; if (_record.children) { record.isLeaf = false; record.children = travel(_record.children); } else if (props.loadMore && !_record.isLeaf) { record.isLeaf = false; if (lazyLoadData[record.key]) { record.children = travel(lazyLoadData[record.key]); } } else { record.isLeaf = true; } record.hasSubtree = Boolean(record.children ? props.hideExpandButtonOnEmpty ? record.children.length > 0 : true : props.loadMore && !record.isLeaf); result.push(record); } return result; }; return travel((_a = props.data) != null ? _a : []); }); const validData = vue.computed(() => { const travel = (data) => data.filter((record) => { if (isValidRecord(record)) { if (record.children) { record.children = travel(record.children); } return true; } return false; }); return Object.keys(computedFilters.value).length > 0 ? travel(processedData.value) : processedData.value; }); const sortedData = vue.computed(() => { var _a, _b, _c; const data = utils.mapArrayWithChildren(validData.value); if (data.length > 0) { if ((_a = computedSorter.value) == null ? void 0 : _a.field) { const column = dataColumnMap.get(computedSorter.value.field); if (column && ((_b = column.sortable) == null ? void 0 : _b.sorter) !== true) { const { field, direction } = computedSorter.value; data.sort((a, b) => { var _a2; const valueA = getValueByPath.getValueByPath(a.raw, field); const valueB = getValueByPath.getValueByPath(b.raw, field); if (((_a2 = column.sortable) == null ? void 0 : _a2.sorter) && is.isFunction(column.sortable.sorter)) { return column.sortable.sorter(a.raw, b.raw, { dataIndex: field, direction }); } const result = valueA > valueB ? 1 : -1; return direction === "descend" ? -result : result; }); } } const { sourcePath, targetPath } = dragState; if (dragState.dragging && targetPath.length && targetPath.toString() !== sourcePath.toString()) { if (sourcePath.length === targetPath.length && sourcePath.slice(0, -1).toString() === targetPath.slice(0, -1).toString()) { let children2 = data; for (let i = 0; i < sourcePath.length; i++) { const sourceIndex = sourcePath[i]; const isLast = i >= sourcePath.length - 1; if (isLast) { const sourceChild = children2[sourceIndex]; const targetIndex = targetPath[i]; if (targetIndex > sourceIndex) { children2.splice(targetIndex + 1, 0, sourceChild); children2.splice(sourceIndex, 1); } else { children2.splice(targetIndex, 0, sourceChild); children2.splice(sourceIndex + 1, 1); } } else { children2 = (_c = children2[sourceIndex].children) != null ? _c : []; } } } } } return data; }); const { page, pageSize, handlePageChange, handlePageSizeChange } = usePagination.usePagination(props, emit); const onlyCurrent = vue.computed(() => { var _a, _b; return (_b = (_a = rowSelection.value) == null ? void 0 : _a.onlyCurrent) != null ? _b : false; }); vue.watch(page, (cur, pre) => { if (cur !== pre && onlyCurrent.value) { clearSelected(); } }); const flattenData = vue.computed(() => { if (props.pagination && sortedData.value.length > pageSize.value) { return sortedData.value.slice((page.value - 1) * pageSize.value, page.value * pageSize.value); } return sortedData.value; }); const flattenRawData = vue.computed(() => utils.mapRawTableData(flattenData.value)); const getSummaryData = () => { return dataColumns.value.reduce((per, column, index2) => { if (column.dataIndex) { if (index2 === 0) { getValueByPath.setValueByPath(per, column.dataIndex, props.summaryText, { addPath: true }); } else { let count = 0; let isNotNumber = false; flattenData.value.forEach((data) => { if (column.dataIndex) { const _number = getValueByPath.getValueByPath(data.raw, column.dataIndex); if (is.isNumber(_number)) { count += _number; } else if (!is.isUndefined(_number) && !is.isNull(_number)) { isNotNumber = true; } } }); getValueByPath.setValueByPath(per, column.dataIndex, isNotNumber ? "" : count, { addPath: true }); } } return per; }, {}); }; const getTableDataWithRaw = (data) => { if (data && data.length > 0) { return data.map((raw) => { return { raw, key: raw[props.rowKey] }; }); } return []; }; const summaryData = vue.computed(() => { if (props.summary) { if (is.isFunction(props.summary)) { return getTableDataWithRaw(props.summary({ columns: dataColumns.value, data: flattenRawData.value })); } return getTableDataWithRaw([getSummaryData()]); } return []; }); const containerScrollLeft = vue.ref(0); const alignLeft = vue.ref(true); const alignRight = vue.ref(true); const setAlignPosition = () => { let _alignLeft = true; let _alignRight = true; const scrollContainer = containerElement.value; if (scrollContainer) { _alignLeft = containerScrollLeft.value === 0; _alignRight = Math.ceil(containerScrollLeft.value + scrollContainer.offsetWidth) >= scrollContainer.scrollWidth; } if (_alignLeft !== alignLeft.value) { alignLeft.value = _alignLeft; } if (_alignRight !== alignRight.value) { alignRight.value = _alignRight; } }; const getTableScrollCls = () => { if (alignLeft.value && alignRight.value) { return `${prefixCls}-scroll-position-both`; } if (alignLeft.value) { return `${prefixCls}-scroll-position-left`; } if (alignRight.value) { return `${prefixCls}-scroll-position-right`; } return `${prefixCls}-scroll-position-middle`; }; const getTableFixedCls = () => { const cls2 = []; if (hasLeftFixedColumn.value) { cls2.push(`${prefixCls}-has-fixed-col-left`); } if (hasRightFixedColumn.value) { cls2.push(`${prefixCls}-has-fixed-col-right`); } return cls2; }; const handleScroll = (e) => { if (e.target.scrollLeft !== containerScrollLeft.value) { containerScrollLeft.value = e.target.scrollLeft; } setAlignPosition(); }; const onTbodyScroll = (e) => { handleScroll(e); const { scrollLeft } = e.target; if (theadRef.value) { theadRef.value.scrollLeft = scrollLeft; } if (summaryRef.value) { summaryRef.value.scrollLeft = scrollLeft; } }; const handleRowClick = (record, ev) => { emit("rowClick", record.raw, ev); }; const handleRowDblclick = (record, ev) => { emit("rowDblclick", record.raw, ev); }; const handleRowContextMenu = (record, ev) => { emit("rowContextmenu", record.raw, ev); }; const handleCellClick = (record, column, ev) => { emit("cellClick", record.raw, column, ev); }; const handleCellMouseEnter = debounce.debounce((record, column, ev) => { emit("cellMouseEnter", record.raw, column, ev); }, 30); const handleCellMouseLeave = debounce.debounce((record, column, ev) => { emit("cellMouseLeave", record.raw, column, ev); }, 30); const handleCellDblclick = (record, column, ev) => { emit("cellDblclick", record.raw, column, ev); }; const handleCellContextmenu = (record, column, ev) => { emit("cellContextmenu", record.raw, column, ev); }; const handleHeaderClick = (column, ev) => { emit("headerClick", column, ev); }; const operations = vue.computed(() => { var _a, _b; const operations2 = []; const hasFixedColumn = hasLeftFixedColumn.value || hasRightFixedColumn.value; let dragHandle; let expand2; let selection; if (((_a = props.draggable) == null ? void 0 : _a.type) === "handle") { dragHandle = { name: "drag-handle", title: props.draggable.title, width: props.draggable.width, fixed: props.draggable.fixed || hasFixedColumn }; operations2.push(dragHandle); } if (props.expandable) { expand2 = { name: "expand", title: props.expandable.title, width: props.expandable.width, fixed: props.expandable.fixed || hasFixedColumn }; operations2.push(expand2); } if (props.rowSelection) { selection = { name: props.rowSelection.type === "radio" ? "selection-radio" : "selection-checkbox", title: props.rowSelection.title, width: props.rowSelection.width, fixed: props.rowSelection.fixed || hasFixedColumn }; operations2.push(selection); } if (!hasLeftFixedDataColumns.value && operations2.length > 0 && operations2[operations2.length - 1].fixed) { operations2[operations2.length - 1].isLastLeftFixed = true; } const operationsFn = (_b = props.components) == null ? void 0 : _b.operations; return is.isFunction(operationsFn) ? operationsFn({ dragHandle, expand: expand2, selection }) : operations2; }); const headerStyle = vue.computed(() => { var _a, _b, _c, _d; if (isScroll.value.x) { const style2 = { width: is.isNumber((_a = props.scroll) == null ? void 0 : _a.x) ? `${(_b = props.scroll) == null ? void 0 : _b.x}px` : (_c = props.scroll) == null ? void 0 : _c.x }; if ((_d = props.scroll) == null ? void 0 : _d.minWidth) { style2.minWidth = is.isNumber(props.scroll.minWidth) ? `${props.scroll.minWidth}px` : props.scroll.minWidth; } return style2; } return void 0; }); const contentStyle = vue.computed(() => { var _a, _b, _c, _d; if (isScroll.value.x && flattenData.value.length > 0) { const style2 = { width: is.isNumber((_a = props.scroll) == null ? void 0 : _a.x) ? `${(_b = props.scroll) == null ? void 0 : _b.x}px` : (_c = props.scroll) == null ? void 0 : _c.x }; if ((_d = props.scroll) == null ? void 0 : _d.minWidth) { style2.minWidth = is.isNumber(props.scroll.minWidth) ? `${props.scroll.minWidth}px` : props.scroll.minWidth; } return style2; } return void 0; }); const addColumn = (id, column) => { slotColumnMap.set(id, column); }; const removeColumn = (id) => { slotColumnMap.delete(id); }; vue.provide(context$1.tableInjectionKey, vue.reactive({ loadMore, addLazyLoadData, slots, sorter: computedSorter, filters: computedFilters, filterIconAlignLeft, resizingColumn, checkStrictly, currentAllEnabledRowKeys, currentSelectedRowKeys, addColumn, removeColumn, onSelectAll: handleSelectAll, onSelect: handleSelect, onSelectAllLeafs: handleSelectAllLeafs, onSorterChange: handleSorterChange, onFilterChange: handleFilterChange, onThMouseDown: handleThMouseDown })); const cls = vue.computed(() => [prefixCls, `${prefixCls}-size-${props.size}`, { [`${prefixCls}-border`]: bordered.value.wrapper, [`${prefixCls}-border-cell`]: bordered.value.cell, [`${prefixCls}-border-header-cell`]: !bordered.value.cell && bordered.value.headerCell, [`${prefixCls}-border-body-cell`]: !bordered.value.cell && bordered.value.bodyCell, [`${prefixCls}-stripe`]: props.stripe, [`${prefixCls}-hover`]: props.hoverable, [`${prefixCls}-dragging`]: dragState.dragging, [`${prefixCls}-type-selection`]: Boolean(props.rowSelection), [`${prefixCls}-empty`]: props.data && flattenData.value.length === 0, [`${prefixCls}-layout-fixed`]: props.tableLayoutFixed || isScroll.value.x || splitTable.value || hasEllipsis.value }]); const paginationCls = vue.computed(() => [`${prefixCls}-pagination`, { [`${prefixCls}-pagination-left`]: props.pagePosition === "tl" || props.pagePosition === "bl", [`${prefixCls}-pagination-center`]: props.pagePosition === "top" || props.pagePosition === "bottom", [`${prefixCls}-pagination-right`]: props.pagePosition === "tr" || props.pagePosition === "br", [`${prefixCls}-pagination-top`]: isPaginationTop.value }]); const tableCls = vue.computed(() => { const cls2 = getTableFixedCls(); if (isScroll.value.x) { cls2.push(getTableScrollCls()); } if (splitTable.value) { cls2.push(`${prefixCls}-scroll-y`); } return cls2; }); const isVirtualList = vue.computed(() => Boolean(props.virtualListProps)); const thWidth = vue.ref({}); const getThWidth = () => { const width = {}; for (const key of Object.keys(thRefs.value)) { width[key] = thRefs.value[key].offsetWidth; } thWidth.value = width; }; const hasScrollBar = vue.ref(false); const isTbodyHasScrollBar = () => { if (tbodyRef.value) { return tbodyRef.value.offsetWidth > tbodyRef.value.clientWidth; } return false; }; const handleTbodyResize = () => { const _hasScrollBar = isTbodyHasScrollBar(); if (hasScrollBar.value !== _hasScrollBar) { hasScrollBar.value = _hasScrollBar; } setAlignPosition(); getThWidth(); }; vue.onMounted(() => { hasScrollBar.value = isTbodyHasScrollBar(); getThWidth(); }); const spinProps = vue.computed(() => is.isObject(props.loading) ? props.loading : { loading: props.loading }); const renderEmpty = () => { return vue.createVNode(tableTr, { "empty": true }, { default: () => [vue.createVNode(tableTd, { "colSpan": dataColumns.value.length + operations.value.length }, { default: () => { var _a, _b, _c, _d, _e; return [(_e = (_d = (_a = slots.empty) == null ? void 0 : _a.call(slots)) != null ? _d : (_c = configCtx == null ? void 0 : (_b = configCtx.slots).empty) == null ? void 0 : _c.call(_b, { component: "table" })) != null ? _e : vue.createVNode(index$3, null, null)]; } })] }); }; const renderExpandContent = (record) => { var _a; if (record.expand) { return is.isFunction(record.expand) ? record.expand() : record.expand; } if (slots["expand-row"]) { return slots["expand-row"]({ record: record.raw }); } if ((_a = props.expandable) == null ? void 0 : _a.expandedRowRender) { return props.expandable.expandedRowRender(record.raw); } return void 0; }; const allColumns = vue.computed(() => [].concat(operations.value, dataColumns.value)); const spanColumns = vue.computed(() => props.spanAll ? allColumns.value : dataColumns.value); const { tableSpan, removedCells } = useSpan.useSpan({ spanMethod, data: flattenData, columns: spanColumns }); const { tableSpan: tableSummarySpan, removedCells: removedSummaryCells } = useSpan.useSpan({ spanMethod: summarySpanMethod, data: summaryData, columns: allColumns }); const getVirtualColumnStyle = (name) => { if (!isVirtualList.value || !name || !thWidth.value[name]) { return void 0; } return { width: `${thWidth.value[name]}px` }; }; const renderSummaryRow = (record, rowIndex) => { return vue.createVNode(tableTr, { "key": `table-summary-${rowIndex}`, "class": [`${prefixCls}-tr-summary`, is.isFunction(props.rowClass) ? props.rowClass(record.raw, rowIndex) : props.rowClass], "onClick": (ev) => handleRowClick(record, ev) }, { default: () => [operations.value.map((operation, index2) => { var _a; const cellId = `${rowIndex}-${index2}-${record.key}`; const [rowspan, colspan] = (_a = tableSummarySpan.value[cellId]) != null ? _a : [1, 1]; if (removedSummaryCells.value.includes(cellId)) { return null; } const style2 = getVirtualColumnStyle(operation.name); return vue.createVNode(tableOperationTd, { "style": style2, "operationColumn": operation, "operations": operations.value, "record": record, "rowSpan": rowspan, "colSpan": colspan, "summary": true }, null); }), dataColumns.value.map((column, index2) => { var _a; const cellId = `${rowIndex}-${operations.value.length + index2}-${record.key}`; const [rowspan, colspan] = (_a = tableSummarySpan.value[cellId]) != null ? _a : [1, 1]; if (removedSummaryCells.value.includes(cellId)) { return null; } const style2 = getVirtualColumnStyle(column.dataIndex); return vue.createVNode(tableTd, { "key": `td-${cellId}`, "style": style2, "rowIndex": rowIndex, "record": record, "column": column, "operations": operations.value, "dataColumns": dataColumns.value, "rowSpan": rowspan, "colSpan": colspan, "summary": true, "onClick": (ev) => handleCellClick(record, column, ev), "onDblclick": (ev) => handleCellDblclick(record, column, ev), "onMouseenter": (ev) => handleCellMouseEnter(record, column, ev), "onMouseleave": (ev) => handleCellMouseLeave(record, column, ev), "onContextmenu": (ev) => handleCellContextmenu(record, column, ev) }, { td: slots.td, cell: slots["summary-cell"] }); })], tr: slots.tr }); }; const renderSummary = () => { if (summaryData.value && summaryData.value.length > 0) { return vue.createVNode("tfoot", null, [summaryData.value.map((data, index2) => renderSummaryRow(data, index2))]); } return null; }; const renderExpandBtn = (record, stopPropagation = true) => { var _a, _b, _c, _d, _e; const currentKey = record.key; const expanded = expandedRowKeys.value.includes(currentKey); return vue.createVNode("button", { "type": "button", "class": `${prefixCls}-expand-btn`, "onClick": (ev) => { handleExpand(currentKey, record.raw); if (stopPropagation) { ev.stopPropagation(); } } }, [(_e = (_d = (_a = slots["expand-icon"]) == null ? void 0 : _a.call(slots, { expanded, record: record.raw })) != null ? _d : (_c = (_b = props.expandable) == null ? void 0 : _b.icon) == null ? void 0 : _c.call(_b, expanded, record.raw)) != null ? _e : expanded ? vue.createVNode(index$4, null, null) : vue.createVNode(index$5, null, null)]); }; const renderExpand = (record, { indentSize, indexPath, allowDrag, expandContent }) => { var _a, _b; if (record.hasSubtree) { if (((_a = record.children) == null ? void 0 : _a.length) === 0 && showEmptyTree.value) { return renderEmpty(); } return (_b = record.children) == null ? void 0 : _b.map((item, index2) => renderRecord(item, index2, { indentSize, indexPath, allowDrag })); } if (expandContent) { const scrollContainer = containerElement.value; return vue.createVNode(tableTr, { "key": `${record.key}-expand`, "expand": true }, { default: () => [vue.createVNode(tableTd, { "isFixedExpand": hasLeftFixedColumn.value || hasRightFixedColumn.value, "containerWidth": scrollContainer == null ? void 0 : scrollContainer.clientWidth, "colSpan": dataColumns.value.length + operations.value.length }, _isSlot(expandContent) ? expandContent : { default: () => [expandContent] })] }); } return null; }; const renderRecord = (record, rowIndex, { indentSize = 0, indexPath, allowDrag = true } = {}) => { var _a; const currentKey = record.key; const currentPath = (indexPath != null ? indexPath : []).concat(rowIndex); const expandContent = renderExpandContent(record); const showExpand = expandedRowKeys.value.includes(currentKey); const isDragTarget = dragState.sourceKey === record.key; const dragSourceEvent = dragType.value ? { draggable: allowDrag, onDragstart: (ev) => { if (!allowDrag) return; handleDragStart(ev, record.key, currentPath, record.raw); }, onDragend: (ev) => { if (!allowDrag) return; handleDragEnd(ev); } } : {}; const dragTargetEvent = dragType.value ? { onDragenter: (ev) => { if (!allowDrag) return; handleDragEnter(ev, currentPath); }, onDragover: (ev) => { if (!allowDrag) return; handleDragover(ev); }, onDrop: (ev) => { if (!allowDrag) return; handleChange("drag"); handleDrop(ev); } } : {}; return vue.createVNode(vue.Fragment, null, [vue.createVNode(tableTr, vue.mergeProps({ "key": currentKey, "class": [{ [`${prefixCls}-tr-draggable`]: dragType.value === "row", [`${prefixCls}-tr-drag`]: isDragTarget }, is.isFunction(props.rowClass) ? props.rowClass(record.raw, rowIndex) : props.rowClass], "rowIndex": rowIndex, "record": record, "checked": props.rowSelection && ((_a = selectedRowKeys.value) == null ? void 0 : _a.includes(currentKey)), "onClick": (ev) => handleRowClick(record, ev), "onDblclick": (ev) => handleRowDblclick(record, ev), "onContextmenu": (ev) => handleRowContextMenu(record, ev) }, dragType.value === "row" ? dragSourceEvent : {}, dragTargetEvent), { default: () => [operations.value.map((operation, index2) => { var _a2; const cellId = `${rowIndex}-${index2}-${record.key}`; const [rowspan, colspan] = props.spanAll ? (_a2 = tableSpan.value[cellId]) != null ? _a2 : [1, 1] : [1, 1]; if (props.spanAll && removedCells.value.includes(cellId)) { return null; } const style2 = getVirtualColumnStyle(operation.name); return vue.createVNode(tableOperationTd, vue.mergeProps({ "key": `operation-td-${index2}`, "style": style2, "operationColumn": operation, "operations": operations.value, "record": record, "hasExpand": Boolean(expandContent), "selectedRowKeys": currentSelectedRowKeys.value, "rowSpan": rowspan, "colSpan": colspan, "renderExpandBtn": renderExpandBtn }, dragType.value === "handle" ? dragSourceEvent : {}), { "drag-handle-icon": slots["drag-handle-icon"] }); }), dataColumns.value.map((column, index2) => { var _a2; const cellId = `${rowIndex}-${props.spanAll ? operations.value.length + index2 : index2}-${record.key}`; const [rowspan, colspan] = (_a2 = tableSpan.value[cellId]) != null ? _a2 : [1, 1]; if (removedCells.value.includes(cellId)) { return null; } const extraProps = index2 === 0 ? { showExpandBtn: record.hasSubtree, indentSize: record.hasSubtree ? indentSize - 20 : indentSize } : {}; const style2 = getVirtualColumnStyle(column.dataIndex); return vue.createVNode(tableTd, vue.mergeProps({ "key": `td-${index2}`, "style": style2, "rowIndex": rowIndex, "record": record, "column": column, "operations": operations.value, "dataColumns": dataColumns.value, "rowSpan": rowspan, "renderExpandBtn": renderExpandBtn, "colSpan": colspan }, extraProps, { "onClick": (ev) => handleCellClick(record, column, ev), "onDblclick": (ev) => handleCellDblclick(record, column, ev), "onMouseenter": (ev) => handleCellMouseEnter(record, column, ev), "onMouseleave": (ev) => handleCellMouseLeave(record, column, ev), "onContextmenu": (ev) => handleCellContextmenu(record, column, ev) }), { td: slots.td }); })], tr: slots.tr }), showExpand && renderExpand(record, { indentSize: indentSize + props.indentSize, indexPath: currentPath, allowDrag: allowDrag && !isDragTarget, expandContent })]); }; const renderBody = () => { const hasSubData = flattenData.value.some((record) => Boolean(record.hasSubtree)); return vue.createVNode(tableTbody, null, { default: () => [flattenData.value.length > 0 ? flattenData.value.map((record, index2) => renderRecord(record, index2, { indentSize: hasSubData ? 20 : 0 })) : renderEmpty()], tbody: slots.tbody }); }; const renderHeader = () => vue.createVNode(tableThead, null, { default: () => [groupColumns.value.map((row, index2) => vue.createVNode(tableTr, { "key": `header-row-${index2}` }, { default: () => [index2 === 0 && operations.value.map((operation, index3) => { var _a; return vue.createVNode(tableOperationTh, { "key": `operation-th-${index3}`, "ref": (ins) => { if ((ins == null ? void 0 : ins.$el) && operation.name) { thRefs.value[operation.name] = ins.$el; } }, "operationColumn": operation, "operations": operations.value, "selectAll": Boolean(operation.name === "selection-checkbox" && ((_a = props.rowSelection) == null ? void 0 : _a.showCheckedAll)), "rowSpan": groupColumns.value.length }, null); }), row.map((column, index3) => { const resizable = props.columnResizable && Boolean(column.dataIndex) && index3 < row.length - 1; return vue.createVNode(tableTh, { "key": `th-${index3}`, "ref": (ins) => { if ((ins == null ? void 0 : ins.$el) && column.dataIndex) { thRefs.value[column.dataIndex] = ins.$el; } }, "column": column, "operations": operations.value, "dataColumns": dataColumns.value, "resizable": resizable, "onClick": (ev) => handleHeaderClick(column, ev) }, { th: slots.th }); })] }))], thead: slots.thead }); const renderContent = () => { var _a, _b; if (splitTable.value) { const top = is.isNumber(props.stickyHeader) ? `${props.stickyHeader}px` : void 0; const mergeOuterClass = [(_a = scrollbarProps.value) == null ? void 0 : _a.outerClass]; if (props.stickyHeader) { mergeOuterClass.push(`${prefixCls}-header-sticky`); } const mergeOuterStyle = { top, ...(_b = scrollbarProps.value) == null ? void 0 : _b.outerStyle }; const Component = displayScrollbar.value ? index$1 : "div"; return vue.createVNode(vue.Fragment, null, [props.showHeader && vue.createVNode(Component, vue.mergeProps({ "ref": theadComRef, "class": [`${prefixCls}-header`, { [`${prefixCls}-header-sticky`]: props.stickyHeader && !displayScrollbar.value }], "style": { overflowY: hasScrollBar.value ? "scroll" : void 0, top: !displayScrollbar.value ? top : void 0 } }, scrollbar.value ? { hide: flattenData.value.length !== 0, disableVertical: true, ...scrollbarProps.value, outerClass: mergeOuterClass, outerStyle: mergeOuterStyle } : void 0), { default: () => [vue.createVNode("table", { "class": `${prefixCls}-element`, "style": headerStyle.value, "cellpadding": 0, "cellspacing": 0 }, [vue.createVNode(tableColGroup, { "dataColumns": dataColumns.value, "operations": operations.value, "columnWidth": columnWidth }, null), renderHeader()])] }), vue.createVNode(resizeObserver, { "onResize": handleTbodyResize }, { default: () => { var _a2, _b2; return [isVirtualList.value && flattenData.value.length ? vue.createVNode(virtualList, vue.mergeProps({ "ref": (ins) => { if (ins == null ? void 0 : ins.$el) tbodyRef.value = ins.$el; }, "class": `${prefixCls}-body`, "data": flattenData.value, "itemKey": "_key", "component": { list: "table", content: "tbody" }, "listAttrs": { class: `${prefixCls}-element`, style: contentStyle.value }, "paddingPosition": "list", "height": "auto" }, props.virtualListProps, { "onScroll": onTbodyScroll }), { item: ({ item, index: index2 }) => renderRecord(item, index2) }) : vue.createVNode(Component, vue.mergeProps({ "ref": tbodyComRef, "class": `${prefixCls}-body`, "style": { maxHeight: is.isNumber((_a2 = props.scroll) == null ? void 0 : _a2.y) ? `${(_b2 = props.scroll) == null ? void 0 : _b2.y}px` : "100%" } }, scrollbar.value ? { outerStyle: { display: "flex", minHeight: "0" }, ...scrollbarProps.value } : void 0, { "onScroll": onTbodyScroll }), { default: () => [vue.createVNode("table", { "class": `${prefixCls}-element`, "style": contentStyle.value, "cellpadding": 0, "cellspacing": 0 }, [flattenData.value.length !== 0 && vue.createVNode(tableColGroup, { "dataColumns": dataColumns.value, "operations": operations.value, "columnWidth": columnWidth }, null), renderBody()])] })]; } }), summaryData.value && summaryData.value.length > 0 && vue.createVNode("div", { "ref": summaryRef, "class": `${prefixCls}-tfoot`, "style": { overflowY: hasScrollBar.value ? "scroll" : "hidden" } }, [vue.createVNode("table", { "class": `${prefixCls}-element`, "style": contentStyle.value, "cellpadding": 0, "cellspacing": 0 }, [vue.createVNode(tableColGroup, { "dataColumns": dataColumns.value, "operations": operations.value, "columnWidth": columnWidth }, null), renderSummary()])])]); } return vue.createVNode(resizeObserver, { "onResize": () => setAlignPosition() }, { default: () => [vue.createVNode("table", { "class": `${prefixCls}-element`, "cellpadding": 0, "cellspacing": 0, "style": contentStyle.value }, [vue.createVNode(tableColGroup, { "dataColumns": dataColumns.value, "operations": operations.value, "columnWidth": columnWidth }, null), props.showHeader && renderHeader(), renderBody(), summaryData.value && summaryData.value.length > 0 && renderSummary()])] }); }; const renderTable = (content) => { var _a; const style2 = ((_a = props.scroll) == null ? void 0 : _a.maxHeight) ? { maxHeight: props.scroll.maxHeight } : void 0; const Component = displayScrollbar.value ? index$1 : "div"; return vue.createVNode(vue.Fragment, null, [vue.createVNode("div", { "class": [`${prefixCls}-container`, tableCls.value] }, [vue.createVNode(Component, vue.mergeProps({ "ref": contentComRef, "class": [`${prefixCls}-content`, { [`${prefixCls}-content-scroll-x`]: !splitTable.value }], "style": style2 }, scrollbar.value ? { outerStyle: { height: "100%" }, ...scrollbarProps.value } : void 0, { "onScroll": handleScroll }), { default: () => [content ? vue.createVNode("table", { "class": `${prefixCls}-element`, "cellpadding": 0, "cellspacing": 0 }, [content()]) : renderContent()] })]), slots.footer && vue.createVNode("div", { "class": `${prefixCls}-footer` }, [slots.footer()])]); }; const renderPagination = () => { var _a, _b;