2018-03-25 10:07:04 +00:00
|
|
|
import PropTypes from '../../_util/vue-types'
|
|
|
|
import { connect } from '../../_util/store'
|
2018-03-24 14:02:24 +00:00
|
|
|
import TableCell from './TableCell'
|
|
|
|
import { warningOnce } from './utils'
|
2018-03-26 15:05:29 +00:00
|
|
|
import { initDefaultProps, mergeProps, getStyle } from '../../_util/props-util'
|
2018-03-25 10:07:04 +00:00
|
|
|
import BaseMixin from '../../_util/BaseMixin'
|
2018-03-25 14:23:04 +00:00
|
|
|
function noop () {}
|
2018-03-25 10:07:04 +00:00
|
|
|
const TableRow = {
|
|
|
|
name: 'TableRow',
|
|
|
|
mixins: [BaseMixin],
|
|
|
|
props: initDefaultProps({
|
2018-03-31 09:46:35 +00:00
|
|
|
customRow: PropTypes.func,
|
2018-03-25 10:07:04 +00:00
|
|
|
// onRowClick: PropTypes.func,
|
|
|
|
// onRowDoubleClick: PropTypes.func,
|
|
|
|
// onRowContextMenu: PropTypes.func,
|
|
|
|
// onRowMouseEnter: PropTypes.func,
|
|
|
|
// onRowMouseLeave: PropTypes.func,
|
2018-03-24 14:02:24 +00:00
|
|
|
record: PropTypes.object,
|
|
|
|
prefixCls: PropTypes.string,
|
2018-03-25 10:07:04 +00:00
|
|
|
// onHover: PropTypes.func,
|
2018-03-24 14:02:24 +00:00
|
|
|
columns: PropTypes.array,
|
|
|
|
height: PropTypes.oneOfType([
|
|
|
|
PropTypes.string,
|
|
|
|
PropTypes.number,
|
|
|
|
]),
|
|
|
|
index: PropTypes.number,
|
|
|
|
rowKey: PropTypes.oneOfType([
|
|
|
|
PropTypes.string,
|
|
|
|
PropTypes.number,
|
|
|
|
]).isRequired,
|
|
|
|
className: PropTypes.string,
|
|
|
|
indent: PropTypes.number,
|
|
|
|
indentSize: PropTypes.number,
|
|
|
|
hasExpandIcon: PropTypes.func.isRequired,
|
|
|
|
hovered: PropTypes.bool.isRequired,
|
|
|
|
visible: PropTypes.bool.isRequired,
|
|
|
|
store: PropTypes.object.isRequired,
|
|
|
|
fixed: PropTypes.oneOfType([
|
|
|
|
PropTypes.string,
|
|
|
|
PropTypes.bool,
|
|
|
|
]),
|
|
|
|
renderExpandIcon: PropTypes.func,
|
|
|
|
renderExpandIconCell: PropTypes.func,
|
|
|
|
components: PropTypes.any,
|
|
|
|
expandedRow: PropTypes.bool,
|
|
|
|
isAnyColumnsFixed: PropTypes.bool,
|
|
|
|
ancestorKeys: PropTypes.array.isRequired,
|
2018-03-25 10:07:04 +00:00
|
|
|
expandIconColumnIndex: PropTypes.number,
|
|
|
|
expandRowByClick: PropTypes.bool,
|
|
|
|
// visible: PropTypes.bool,
|
|
|
|
// hovered: PropTypes.bool,
|
|
|
|
// height: PropTypes.any,
|
|
|
|
}, {
|
2018-03-24 14:02:24 +00:00
|
|
|
expandIconColumnIndex: 0,
|
|
|
|
expandRowByClick: false,
|
|
|
|
hasExpandIcon () {},
|
|
|
|
renderExpandIcon () {},
|
|
|
|
renderExpandIconCell () {},
|
2018-03-25 10:07:04 +00:00
|
|
|
}),
|
2018-03-24 14:02:24 +00:00
|
|
|
|
2018-03-25 10:07:04 +00:00
|
|
|
data () {
|
|
|
|
this.shouldRender = this.visible
|
|
|
|
return {}
|
|
|
|
},
|
2018-03-24 14:02:24 +00:00
|
|
|
|
2018-03-25 10:07:04 +00:00
|
|
|
mounted () {
|
2018-03-24 14:02:24 +00:00
|
|
|
if (this.shouldRender) {
|
2018-03-25 10:07:04 +00:00
|
|
|
this.$nextTick(() => {
|
|
|
|
this.saveRowRef()
|
|
|
|
})
|
2018-03-24 14:02:24 +00:00
|
|
|
}
|
2018-03-25 10:07:04 +00:00
|
|
|
},
|
|
|
|
watch: {
|
2018-03-25 14:23:04 +00:00
|
|
|
visible (val) {
|
|
|
|
if (val) {
|
|
|
|
this.shouldRender = true
|
|
|
|
}
|
|
|
|
},
|
2018-03-25 10:07:04 +00:00
|
|
|
},
|
2018-03-24 14:02:24 +00:00
|
|
|
|
2018-03-25 10:07:04 +00:00
|
|
|
updated () {
|
2018-03-24 14:02:24 +00:00
|
|
|
if (this.shouldRender && !this.rowRef) {
|
2018-03-25 10:07:04 +00:00
|
|
|
this.$nextTick(() => {
|
|
|
|
this.saveRowRef()
|
|
|
|
})
|
2018-03-24 14:02:24 +00:00
|
|
|
}
|
2018-03-25 10:07:04 +00:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
onRowClick (event) {
|
|
|
|
const { record, index } = this
|
|
|
|
this.__emit('rowClick', record, index, event)
|
|
|
|
},
|
|
|
|
|
|
|
|
onRowDoubleClick (event) {
|
|
|
|
const { record, index } = this
|
|
|
|
this.__emit('rowDoubleClick', record, index, event)
|
|
|
|
},
|
|
|
|
|
|
|
|
onContextMenu (event) {
|
|
|
|
const { record, index } = this
|
|
|
|
this.__emit('rowContextmenu', record, index, event)
|
|
|
|
},
|
|
|
|
|
|
|
|
onMouseEnter (event) {
|
|
|
|
const { record, index, rowKey } = this
|
|
|
|
this.__emit('hover', true, rowKey)
|
|
|
|
this.__emit('rowMouseenter', record, index, event)
|
|
|
|
},
|
|
|
|
|
|
|
|
onMouseLeave (event) {
|
|
|
|
const { record, index, rowKey } = this
|
|
|
|
this.__emit('hover', false, rowKey)
|
|
|
|
this.__emit('rowMouseleave', record, index, event)
|
|
|
|
},
|
|
|
|
|
|
|
|
setExpanedRowHeight () {
|
|
|
|
const { store, rowKey } = this
|
|
|
|
let { expandedRowsHeight } = store.getState()
|
|
|
|
const height = this.rowRef.getBoundingClientRect().height
|
|
|
|
expandedRowsHeight = {
|
|
|
|
...expandedRowsHeight,
|
|
|
|
[rowKey]: height,
|
|
|
|
}
|
|
|
|
store.setState({ expandedRowsHeight })
|
|
|
|
},
|
|
|
|
|
|
|
|
setRowHeight () {
|
|
|
|
const { store, index } = this
|
|
|
|
const fixedColumnsBodyRowsHeight = store.getState().fixedColumnsBodyRowsHeight.slice()
|
|
|
|
const height = this.rowRef.getBoundingClientRect().height
|
|
|
|
fixedColumnsBodyRowsHeight[index] = height
|
|
|
|
store.setState({ fixedColumnsBodyRowsHeight })
|
|
|
|
},
|
|
|
|
|
|
|
|
getStyle () {
|
|
|
|
const { height, visible } = this
|
2018-03-26 15:05:29 +00:00
|
|
|
let style = getStyle(this)
|
|
|
|
if (height) {
|
|
|
|
style = { ...style, height }
|
2018-03-25 10:07:04 +00:00
|
|
|
}
|
|
|
|
|
2018-03-26 15:05:29 +00:00
|
|
|
if (!visible && !style.display) {
|
|
|
|
style = { ...style, display: 'none' }
|
2018-03-25 10:07:04 +00:00
|
|
|
}
|
|
|
|
|
2018-03-26 15:05:29 +00:00
|
|
|
return style
|
2018-03-25 10:07:04 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
saveRowRef () {
|
|
|
|
this.rowRef = this.$el
|
|
|
|
|
|
|
|
const { isAnyColumnsFixed, fixed, expandedRow, ancestorKeys } = this
|
|
|
|
|
|
|
|
if (!isAnyColumnsFixed) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!fixed && expandedRow) {
|
|
|
|
this.setExpanedRowHeight()
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!fixed && ancestorKeys.length >= 0) {
|
|
|
|
this.setRowHeight()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
2018-03-24 14:02:24 +00:00
|
|
|
|
|
|
|
render () {
|
|
|
|
if (!this.shouldRender) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
const {
|
|
|
|
prefixCls,
|
|
|
|
columns,
|
|
|
|
record,
|
|
|
|
index,
|
2018-03-31 09:46:35 +00:00
|
|
|
customRow = noop,
|
2018-03-24 14:02:24 +00:00
|
|
|
indent,
|
|
|
|
indentSize,
|
|
|
|
hovered,
|
|
|
|
height,
|
|
|
|
visible,
|
|
|
|
components,
|
|
|
|
hasExpandIcon,
|
|
|
|
renderExpandIcon,
|
|
|
|
renderExpandIconCell,
|
2018-03-25 10:07:04 +00:00
|
|
|
} = this
|
2018-03-24 14:02:24 +00:00
|
|
|
const BodyRow = components.body.row
|
|
|
|
const BodyCell = components.body.cell
|
|
|
|
|
2018-03-25 10:07:04 +00:00
|
|
|
let className = ''
|
2018-03-24 14:02:24 +00:00
|
|
|
|
|
|
|
if (hovered) {
|
|
|
|
className += ` ${prefixCls}-hover`
|
|
|
|
}
|
|
|
|
|
|
|
|
const cells = []
|
|
|
|
|
|
|
|
renderExpandIconCell(cells)
|
|
|
|
|
|
|
|
for (let i = 0; i < columns.length; i++) {
|
|
|
|
const column = columns[i]
|
|
|
|
|
|
|
|
warningOnce(
|
|
|
|
column.onCellClick === undefined,
|
|
|
|
'column[onCellClick] is deprecated, please use column[onCell] instead.',
|
|
|
|
)
|
|
|
|
|
|
|
|
cells.push(
|
|
|
|
<TableCell
|
|
|
|
prefixCls={prefixCls}
|
|
|
|
record={record}
|
|
|
|
indentSize={indentSize}
|
|
|
|
indent={indent}
|
|
|
|
index={index}
|
|
|
|
column={column}
|
|
|
|
key={column.key || column.dataIndex}
|
|
|
|
expandIcon={hasExpandIcon(i) && renderExpandIcon()}
|
|
|
|
component={BodyCell}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const rowClassName =
|
|
|
|
`${prefixCls} ${className} ${prefixCls}-level-${indent}`.trim()
|
|
|
|
|
2018-03-31 09:46:35 +00:00
|
|
|
const rowProps = customRow(record, index)
|
2018-03-24 14:02:24 +00:00
|
|
|
const customStyle = rowProps ? rowProps.style : {}
|
2018-03-26 15:05:29 +00:00
|
|
|
let style = { height: typeof height === 'number' ? `${height}px` : height }
|
2018-03-24 14:02:24 +00:00
|
|
|
|
|
|
|
if (!visible) {
|
|
|
|
style.display = 'none'
|
|
|
|
}
|
|
|
|
|
|
|
|
style = { ...style, ...customStyle }
|
2018-03-25 14:23:04 +00:00
|
|
|
const bodyRowProps = mergeProps({
|
|
|
|
on: {
|
|
|
|
click: this.onRowClick,
|
|
|
|
dblclick: this.onRowDoubleClick,
|
|
|
|
mouseenter: this.onMouseEnter,
|
|
|
|
mouseleave: this.onMouseLeave,
|
|
|
|
contextmenu: this.onContextMenu,
|
|
|
|
},
|
|
|
|
class: rowClassName,
|
|
|
|
}, { ...rowProps, style })
|
2018-03-24 14:02:24 +00:00
|
|
|
return (
|
|
|
|
<BodyRow
|
2018-03-25 14:23:04 +00:00
|
|
|
{...bodyRowProps}
|
2018-03-24 14:02:24 +00:00
|
|
|
>
|
|
|
|
{cells}
|
|
|
|
</BodyRow>
|
|
|
|
)
|
2018-03-25 10:07:04 +00:00
|
|
|
},
|
2018-03-24 14:02:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function getRowHeight (state, props) {
|
|
|
|
const { expandedRowsHeight, fixedColumnsBodyRowsHeight } = state
|
|
|
|
const { fixed, index, rowKey } = props
|
|
|
|
|
|
|
|
if (!fixed) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
if (expandedRowsHeight[rowKey]) {
|
|
|
|
return expandedRowsHeight[rowKey]
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fixedColumnsBodyRowsHeight[index]) {
|
|
|
|
return fixedColumnsBodyRowsHeight[index]
|
|
|
|
}
|
|
|
|
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connect((state, props) => {
|
|
|
|
const { currentHoverKey, expandedRowKeys } = state
|
|
|
|
const { rowKey, ancestorKeys } = props
|
|
|
|
const visible = ancestorKeys.length === 0 || ancestorKeys.every(k => ~expandedRowKeys.indexOf(k))
|
|
|
|
|
|
|
|
return ({
|
|
|
|
visible,
|
|
|
|
hovered: currentHoverKey === rowKey,
|
|
|
|
height: getRowHeight(state, props),
|
|
|
|
})
|
|
|
|
})(TableRow)
|