UNPKG

song-ui-u

Version:

vue3 + js的PC前端组件库

203 lines (199 loc) 6.69 kB
'use strict'; var vue = require('vue'); var column = require('./column.cjs'); var index = require('../../../hook/use-namespace/index.cjs'); require('song-ui-pro-icon'); require('../../../hook/use-zindex/index.cjs'); var table = /* @__PURE__ */ vue.defineComponent({ name: "x-table", props: { data: { type: Array, required: true }, stripe: { type: Boolean, default: false }, border: { type: Boolean, default: false }, height: { type: [String, Number], default: "auto" } }, setup(props, { slots, emit }) { const ns = index.useNamespace("table"); const columns = vue.ref([]); const selectedRows = vue.ref(/* @__PURE__ */ new Set()); const expandedRows = vue.ref(/* @__PURE__ */ new Set()); const indeterminateValue = vue.ref(false); const getAllChildren = (row) => { const children = []; const stack = [row]; while (stack.length) { const current = stack.pop(); if (current.children?.length) { stack.push(...current.children); children.push(...current.children); } } return children; }; const getParentRow = (row, data = props.data) => { for (const item of data) { if (item.children?.find((child) => child.id === row.id)) { return item; } if (item.children?.length) { const parent = getParentRow(row, item.children); if (parent) return parent; } } return null; }; const handleSelect = (row) => { const children = getAllChildren(row); if (selectedRows.value.has(row)) { selectedRows.value.delete(row); children.forEach((child) => selectedRows.value.delete(child)); } else { selectedRows.value.add(row); children.forEach((child) => selectedRows.value.add(child)); } let parent = getParentRow(row); while (parent) { const allChildren = getAllChildren(parent); const allSelected = allChildren.every((child) => selectedRows.value.has(child)); if (allSelected) { selectedRows.value.add(parent); } else { selectedRows.value.delete(parent); } parent = getParentRow(parent); } indeterminateValue.value = selectedRows.value.size > 0 && !isAllSelected.value; emit("selection-change", Array.from(selectedRows.value)); }; const isSelected = (row) => { return selectedRows.value.has(row); }; if (slots.default) { const children = slots.default(); columns.value = children.map((child) => ({ prop: child.props.prop, label: child.props.label, width: child.props.width || "auto", slots: child?.children?.default, align: child.props.align || "left", type: child.props.type, selectable: child.props.selectable || (() => true) })); } const isAllSelected = vue.computed(() => { const selectionColumn = columns.value.find((col) => col.type === "selection"); const getAllSelectableRows = (data) => { let rows = []; data.forEach((row) => { if (selectionColumn?.selectable?.(row) ?? true) { rows.push(row); } if (row.children?.length) { rows = rows.concat(getAllSelectableRows(row.children)); } }); return rows; }; const selectableRows = getAllSelectableRows(props.data); const selectedSelectableRows = Array.from(selectedRows.value).filter((row) => selectionColumn?.selectable?.(row) ?? true); return selectableRows.length > 0 && selectedSelectableRows.length === selectableRows.length; }); const handleSelectAll = (checked) => { const processRow = (row) => { if (checked) { selectedRows.value.add(row); } else { selectedRows.value.delete(row); } row.children?.forEach(processRow); }; props.data.forEach(processRow); indeterminateValue.value = false; emit("selection-change", Array.from(selectedRows.value)); }; const handleExpand = (row) => { if (expandedRows.value.has(row.id)) { expandedRows.value.delete(row.id); } else { expandedRows.value.add(row.id); } }; const isExpanded = (rowId) => expandedRows.value.has(rowId); const renderRows = (data, level = 0) => { const rows = []; data.forEach((row, rowIndex) => { rows.push(vue.createVNode("tr", { "key": row.id, "class": [ns.e("row"), ns.is("stripe", props.stripe && rowIndex % 2 === 0)] }, [columns.value.map((column$1) => { const Column = column.setColumn({ column: column$1, row, level, columns: columns.value, hasChildren: !!row.children?.length, isExpanded: isExpanded(row.id), onExpand: () => handleExpand(row), getAllChildren, isSelected, onSelect: handleSelect, isAllSelected, onSelectAll: handleSelectAll, indeterminate: indeterminateValue }); return vue.createVNode("td", { "class": [ns.e("cell"), ns.is("border", props.border)] }, [vue.createVNode(Column, null, null)]); })])); if (row.children?.length && isExpanded(row.id)) { rows.push(...renderRows(row.children, level + 1)); } }); return rows; }; return () => vue.createVNode("div", { "class": [ns.b(), ns.is("border", props.border)], "style": { height: typeof props.height == "number" ? `${props.height}px` : props.height } }, [vue.createVNode("table", { "class": [ns.e("container")] }, [vue.createVNode("thead", { "class": [ns.e("header")] }, [vue.createVNode("tr", null, [columns.value.map((column$1) => { const Column = column.setColumn({ column: column$1, row: null, columns: columns.value, isAllSelected, onSelectAll: handleSelectAll, indeterminate: indeterminateValue }); return vue.createVNode("th", { "style": { width: column$1.width + "px", textAlign: column$1.align }, "class": [ns.e("cell"), ns.is("border", props.border)], "key": column$1.prop }, [column$1.type === "selection" ? vue.createVNode(Column, null, null) : column$1.label]); })])]), vue.createVNode("tbody", null, [renderRows(props.data)])])]); } }); module.exports = table; //# sourceMappingURL=table.cjs.map