126 lines
3.8 KiB
Vue
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;
|