ant-design-vue/components/vc-table/src/ExpandableRow.jsx

126 lines
3.8 KiB
Vue

import PropTypes, { withUndefined } from '../../_util/vue-types';
import ExpandIcon from './ExpandIcon';
import BaseMixin from '../../_util/BaseMixin';
import { getSlot } from '../../_util/props-util';
import { computed, inject } from 'vue';
const ExpandableRow = {
mixins: [BaseMixin],
name: 'ExpandableRow',
inheritAttrs: false,
props: {
prefixCls: PropTypes.string.isRequired,
rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
fixed: withUndefined(PropTypes.oneOfType([PropTypes.string, PropTypes.looseBool])),
record: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
indentSize: PropTypes.number,
needIndentSpaced: PropTypes.looseBool.isRequired,
expandRowByClick: PropTypes.looseBool,
expandIconAsCell: PropTypes.looseBool,
expandIconColumnIndex: PropTypes.number,
childrenColumnName: PropTypes.string,
expandedRowRender: PropTypes.func,
expandIcon: PropTypes.func,
// onExpandedChange: PropTypes.func.isRequired,
// onRowClick: PropTypes.func,
// children: PropTypes.func.isRequired,
},
setup(props) {
const store = inject('table-store', () => ({}));
return {
expanded: computed(() => store.expandedRowKeys.includes(props.rowKey)),
};
},
beforeUnmount() {
this.handleDestroy();
},
methods: {
hasExpandIcon(columnIndex) {
const { expandRowByClick, expandIcon } = this.$props;
if (this.tempExpandIconAsCell || columnIndex !== this.tempExpandIconColumnIndex) {
return false;
}
return !!expandIcon || !expandRowByClick;
},
handleExpandChange(record, event) {
const { expanded, rowKey } = this;
this.__emit('expandedChange', !expanded, record, event, rowKey);
},
handleDestroy() {
const { rowKey, record } = this;
this.__emit('expandedChange', false, record, null, rowKey, true);
},
handleRowClick(record, index, event) {
const { expandRowByClick } = this;
if (expandRowByClick) {
this.handleExpandChange(record, event);
}
this.__emit('rowClick', record, index, event);
},
renderExpandIcon() {
const { prefixCls, expanded, record, needIndentSpaced, expandIcon } = this;
if (expandIcon) {
return expandIcon({
prefixCls,
expanded,
record,
needIndentSpaced,
expandable: this.expandable,
onExpand: this.handleExpandChange,
});
}
return (
<ExpandIcon
expandable={this.expandable}
prefixCls={prefixCls}
onExpand={this.handleExpandChange}
needIndentSpaced={needIndentSpaced}
expanded={expanded}
record={record}
/>
);
},
renderExpandIconCell(cells) {
if (!this.tempExpandIconAsCell) {
return;
}
const { prefixCls } = this;
cells.push(
<td class={`${prefixCls}-expand-icon-cell`} key="rc-table-expand-icon-cell">
{this.renderExpandIcon()}
</td>,
);
},
},
render() {
const { childrenColumnName, expandedRowRender, indentSize, record, fixed, expanded } = this;
this.tempExpandIconAsCell = fixed !== 'right' ? this.expandIconAsCell : false;
this.tempExpandIconColumnIndex = fixed !== 'right' ? this.expandIconColumnIndex : -1;
const childrenData = record[childrenColumnName];
this.expandable = !!(childrenData || expandedRowRender);
const expandableRowProps = {
indentSize,
expanded, // not used in TableRow, but it's required to re-render TableRow when `expanded` changes
hasExpandIcon: this.hasExpandIcon,
renderExpandIcon: this.renderExpandIcon,
renderExpandIconCell: this.renderExpandIconCell,
onRowClick: this.handleRowClick,
};
return getSlot(this, 'default', expandableRowProps);
},
};
export default ExpandableRow;