UNPKG

element-plus

Version:

A Component Library for Vue3.0

571 lines (559 loc) 19.4 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var util = require('../utils/util'); var ElCheckbox = require('../el-checkbox'); require('../utils/dom'); require('@popperjs/core'); require('../utils/popup-manager'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var ElCheckbox__default = /*#__PURE__*/_interopDefaultLegacy(ElCheckbox); const cellStarts = { default: { order: '', }, selection: { width: 48, minWidth: 48, realWidth: 48, order: '', className: 'el-table-column--selection', }, expand: { width: 48, minWidth: 48, realWidth: 48, order: '', }, index: { width: 48, minWidth: 48, realWidth: 48, order: '', }, }; const cellForced = { selection: { renderHeader: function ({ store: store_ }) { const store = store_; function isDisabled() { return store.states.data.value && store.states.data.value.length === 0; } return vue.h(ElCheckbox__default['default'], { disabled: isDisabled(), indeterminate: store.states.selection.value.length > 0 && !store.states.isAllSelected.value, 'onUpdate:modelValue': store.toggleAllSelection, modelValue: store.states.isAllSelected.value, }); }, renderCell: function ({ row, column, store, $index, }) { return vue.h(ElCheckbox__default['default'], { disabled: column.selectable ? !column.selectable.call(null, row, $index) : false, onInput: () => { store.commit('rowSelectedChanged', row); }, onClick: (event) => event.stopPropagation(), modelValue: store.isSelected(row), }); }, sortable: false, resizable: false, }, index: { renderHeader: function ({ column: column_ }) { const column = column_; return column.label || '#'; }, renderCell: function ({ column, $index, }) { let i = $index + 1; const index = column.index; if (typeof index === 'number') { i = $index + index; } else if (typeof index === 'function') { i = index($index); } return vue.h('div', {}, [i]); }, sortable: false, }, expand: { renderHeader: function ({ column: column_ }) { const column = column_; return column.label || ''; }, renderCell: function ({ row: row_, store: store_ }) { const store = store_; const row = row_; const classes = ['el-table__expand-icon']; if (store.states.expandRows.value.indexOf(row) > -1) { classes.push('el-table__expand-icon--expanded'); } const callback = function (e) { e.stopPropagation(); store.toggleRowExpansion(row); }; return vue.h('div', { class: classes, onClick: callback, }, [ vue.h('i', { class: 'el-icon el-icon-arrow-right', }), ]); }, sortable: false, resizable: false, className: 'el-table__expand-column', }, }; function defaultRenderCell({ row, column, $index, }) { const property = column.property; const value = property && util.getPropByPath(row, property, false).v; if (column && column.formatter) { return column.formatter(row, column, value, $index); } return value; } function treeCellPrefix({ row: row_, treeNode: treeNode_, store: store_, }) { const row = row_; const store = store_; const treeNode = treeNode_; if (!treeNode) return null; const ele = []; const callback = function (e) { e.stopPropagation(); store.loadOrToggle(row); }; if (treeNode.indent) { ele.push(vue.h('span', { class: 'el-table__indent', style: { 'padding-left': treeNode.indent + 'px' }, })); } if (typeof treeNode.expanded === 'boolean' && !treeNode.noLazyChildren) { const expandClasses = [ 'el-table__expand-icon', treeNode.expanded ? 'el-table__expand-icon--expanded' : '', ]; let iconClasses = ['el-icon-arrow-right']; if (treeNode.loading) { iconClasses = ['el-icon-loading']; } ele.push(vue.h('div', { class: expandClasses, onClick: callback, }, [ vue.h('i', { class: iconClasses, }), ])); } else { ele.push(vue.h('span', { class: 'el-table__placeholder', })); } return ele; } function hasOwn(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } 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 (typeof value !== 'undefined') { options[key] = value; } } } return options; } function parseWidth(width) { if (width !== undefined) { width = parseInt(width, 10); if (isNaN(width)) { width = null; } } return width; } function parseMinWidth(minWidth) { if (typeof minWidth !== 'undefined') { minWidth = parseWidth(minWidth); if (isNaN(minWidth)) { minWidth = 80; } } return minWidth; } 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 useWatcher(owner, props_) { const instance = vue.getCurrentInstance(); const registerComplexWatchers = () => { const props = ['fixed']; const aliases = { realWidth: 'width', realMinWidth: 'minWidth', }; const allAliases = props.reduce((prev, cur) => { prev[cur] = cur; return prev; }, aliases); Object.keys(allAliases).forEach(key => { const columnKey = aliases[key]; if (props_.hasOwnProperty(columnKey)) { vue.watch(() => props_[columnKey], newVal => { instance.columnConfig.value[columnKey] = newVal; instance.columnConfig.value[key] = newVal; const updateColumns = columnKey === 'fixed'; owner.value.store.scheduleLayout(updateColumns); }); } }); }; const registerNormalWatchers = () => { const props = [ 'label', 'property', 'filters', 'filterMultiple', 'sortable', 'index', 'formatter', 'className', 'labelClassName', 'showOverflowTooltip', ]; const aliases = { prop: 'property', realAlign: 'align', realHeaderAlign: 'headerAlign', }; const allAliases = props.reduce((prev, cur) => { prev[cur] = cur; return prev; }, aliases); Object.keys(allAliases).forEach(key => { const columnKey = aliases[key]; if (props_.hasOwnProperty(columnKey)) { vue.watch(() => props_[columnKey], newVal => { instance.columnConfig.value[columnKey] = newVal; }); } }); }; return { registerComplexWatchers, registerNormalWatchers, }; } function useRender(props, slots, owner) { const instance = vue.getCurrentInstance(); const columnId = vue.ref(''); const isSubColumn = vue.ref(false); const realAlign = vue.ref(); const realHeaderAlign = vue.ref(); vue.watchEffect(() => { realAlign.value = !!props.align ? 'is-' + props.align : null; realAlign.value; }); vue.watchEffect(() => { realHeaderAlign.value = !!props.headerAlign ? 'is-' + props.headerAlign : realAlign.value; realHeaderAlign.value; }); const columnOrTableParent = vue.computed(() => { let parent = instance.vnode.vParent || instance.parent; while (parent && !parent.tableId && !parent.columnId) { parent = parent.vnode.vParent || parent.parent; } return parent; }); const realWidth = vue.ref(parseWidth(props.width)); const realMinWidth = vue.ref(parseMinWidth(props.minWidth)); const setColumnWidth = column => { if (realWidth.value) column.width = realWidth.value; if (realMinWidth.value) { column.minWidth = realMinWidth.value; } if (!column.minWidth) { column.minWidth = 80; } column.realWidth = column.width === undefined ? 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 (value !== undefined) { column[prop] = prop === 'className' ? `${column[prop]} ${value}` : value; } }); return column; }; const checkSubColumn = children => { if (children instanceof Array) { children.forEach(child => check(child)); } else { check(children); } function check(item) { var _a; if (((_a = item === null || item === void 0 ? void 0 : item.type) === null || _a === void 0 ? void 0 : _a.name) === 'ElTableColumn') { item.vParent = instance; } } }; const setColumnRenders = column => { if (props.renderHeader) { console.warn('[Element Warn][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']; const renderHeader = slots.header; return renderHeader ? renderHeader(scope) : column.label; }; } let originRenderCell = column.renderCell; if (column.type === 'expand') { column.renderCell = data => vue.h('div', { class: 'cell', }, [originRenderCell(data)]); owner.value.renderExpanded = data => { return slots.default ? slots.default(data) : slots.default; }; } else { originRenderCell = originRenderCell || defaultRenderCell; column.renderCell = data => { let children = null; if (slots.default) { children = slots.default(data); } else { children = originRenderCell(data); } const prefix = treeCellPrefix(data); const props = { class: 'cell', style: {}, }; if (column.showOverflowTooltip) { props.class += ' el-tooltip'; props.style = { width: (data.column.realWidth || data.column.width) - 1 + 'px', }; } checkSubColumn(children); return vue.h('div', props, [prefix, children]); }; } return column; }; const getPropsData = (...propsKey) => { return propsKey.reduce((prev, cur) => { if (Array.isArray(cur)) { cur.forEach(key => { prev[key] = props[key]; }); } return prev; }, {}); }; const getColumnElIndex = (children, child) => { return [].indexOf.call(children, child); }; return { columnId, realAlign, isSubColumn, realHeaderAlign, columnOrTableParent, setColumnWidth, setColumnForcedProps, setColumnRenders, getPropsData, getColumnElIndex, }; } let columnIdSeed = 1; var ElTableColumn = vue.defineComponent({ name: 'ElTableColumn', components: { ElCheckbox: ElCheckbox__default['default'], }, props: { type: { type: String, default: 'default', }, label: String, className: String, labelClassName: String, property: String, prop: String, width: { type: [Object, Number, String], default: () => { return {}; }, }, minWidth: { type: [Object, Number, String], default: () => { return {}; }, }, 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, showTooltipWhenOverflow: Boolean, showOverflowTooltip: Boolean, fixed: [Boolean, String], formatter: Function, selectable: Function, reserveSelection: Boolean, filterMethod: Function, filteredValue: Array, filters: Array, filterPlacement: String, filterMultiple: { type: Boolean, default: true, }, index: [Number, Function], sortOrders: { type: Array, default() { return ['ascending', 'descending', null]; }, validator(val) { return val.every((order) => ['ascending', 'descending', null].indexOf(order) > -1); }, }, }, setup(prop, { slots }) { const instance = vue.getCurrentInstance(); const columnConfig = vue.ref({}); const props = prop; const owner = vue.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, } = useRender(props, slots, owner); const parent = columnOrTableParent.value; columnId.value = (parent.tableId || parent.columnId) + '_column_' + columnIdSeed++; vue.onBeforeMount(() => { isSubColumn.value = owner.value !== parent; const type = props.type || 'default'; const sortable = props.sortable === '' ? true : props.sortable; const defaults = Object.assign(Object.assign({}, cellStarts[type]), { id: columnId.value, type: type, property: props.prop || props.property, align: realAlign, headerAlign: realHeaderAlign, showOverflowTooltip: props.showOverflowTooltip || props.showTooltipWhenOverflow, filterable: props.filters || props.filterMethod, filteredValue: [], filterPlacement: '', isColumnGroup: false, filterOpened: false, sortable: sortable, index: props.index }); const basicProps = [ 'columnKey', 'label', 'className', 'labelClassName', 'type', 'renderHeader', 'formatter', 'fixed', 'resizable', ]; const sortProps = ['sortMethod', 'sortBy', 'sortOrders']; const selectProps = ['selectable', 'reserveSelection']; const filterProps = [ 'filterMethod', 'filters', 'filterMultiple', 'filterOpened', 'filteredValue', 'filterPlacement', ]; let column = getPropsData(basicProps, sortProps, selectProps, filterProps); column = mergeOptions(defaults, column); const chains = compose(setColumnRenders, setColumnWidth, setColumnForcedProps); column = chains(column); columnConfig.value = column; registerNormalWatchers(); registerComplexWatchers(); }); vue.onMounted(() => { var _a; const parent = columnOrTableParent.value; const children = isSubColumn.value ? parent.vnode.el.children : (_a = parent.refs.hiddenColumns) === null || _a === void 0 ? void 0 : _a.children; const getColumnIndex = () => getColumnElIndex(children || [], instance.vnode.el); columnConfig.value.getColumnIndex = getColumnIndex; const columnIndex = getColumnIndex(); columnIndex > -1 && owner.value.store.commit('insertColumn', columnConfig.value, isSubColumn.value ? parent.columnConfig.value : null); }); vue.onBeforeUnmount(() => { owner.value.store.commit('removeColumn', columnConfig.value, isSubColumn.value ? parent.columnConfig.value : null); }); instance.columnId = columnId.value; instance.columnConfig = columnConfig; return; }, render() { var _a, _b; try { return vue.h('div', (_b = (_a = this.$slots).default) === null || _b === void 0 ? void 0 : _b.call(_a, { store: {}, _self: {}, column: {}, row: {}, $index: -1, })); } catch (_c) { return vue.h('div'); } }, }); ElTableColumn.install = (app) => { app.component(ElTableColumn.name, ElTableColumn); }; exports.default = ElTableColumn;