Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/table/src/Body/BodyRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function getCellProps<RecordType>(
const fixedInfo = fixedInfoList[colIndex]

let appendCellNode: any
let hoverRowSpan: number | undefined
if (colIndex === (expandIconColumnIndex || 0) && nestExpandable.value) {
appendCellNode = (
<>
Expand All @@ -78,6 +79,7 @@ export function getCellProps<RecordType>(
if (expandedRowOffset) {
const { rowSpan = 1 } = additionalCellProps
if (expandable.value && rowSpan && colIndex < expandedRowOffset) {
hoverRowSpan = rowSpan
let currentRowSpan = rowSpan
for (let i = index; i < index + rowSpan; i += 1) {
const keyInRow = rowKeys[i]
Expand All @@ -94,6 +96,7 @@ export function getCellProps<RecordType>(
fixedInfo,
appendCellNode,
additionalCellProps,
hoverRowSpan,
}
}

Expand Down Expand Up @@ -188,7 +191,7 @@ const BodyRow = defineComponent<BodyRowProps<any>>({
{flattenColumns.map((column: ColumnType<any>, colIndex) => {
const { render, dataIndex, className: columnClassName } = column

const { key, fixedInfo, appendCellNode, additionalCellProps } = getCellProps(
const { key, fixedInfo, appendCellNode, additionalCellProps, hoverRowSpan } = getCellProps(
rowInfo,
record,
column,
Expand Down Expand Up @@ -219,6 +222,7 @@ const BodyRow = defineComponent<BodyRowProps<any>>({
rowType="body"
{...fixedInfo}
additionalProps={additionalCellProps}
hoverRowSpan={hoverRowSpan}
column={column}
appendNode={appendCellNode}
/>
Expand Down
8 changes: 6 additions & 2 deletions packages/table/src/Cell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface CellProps<RecordType extends DefaultRecordType> {
children?: any
colSpan?: number
rowSpan?: number
hoverRowSpan?: number
scope?: ScopeType
ellipsis?: CellEllipsisType
align?: AlignType
Expand Down Expand Up @@ -166,6 +167,7 @@ const Cell = defineComponent<CellProps<any>>({
'children',
'colSpan',
'rowSpan',
'hoverRowSpan',
'scope',
'ellipsis',
'align',
Expand Down Expand Up @@ -233,6 +235,7 @@ const Cell = defineComponent<CellProps<any>>({
rowType,
colSpan,
rowSpan,
hoverRowSpan,
fixStart,
fixEnd,
fixedStartShadow,
Expand Down Expand Up @@ -270,12 +273,13 @@ const Cell = defineComponent<CellProps<any>>({

const mergedColSpan = legacyCellProps?.colSpan ?? additionalProps.colSpan ?? colSpan ?? 1
const mergedRowSpan = legacyCellProps?.rowSpan ?? additionalProps.rowSpan ?? rowSpan ?? 1
const mergedHoverRowSpan = hoverRowSpan ?? mergedRowSpan

const [hovering, onHover] = useHoverState(index!, mergedRowSpan, tableContext)
const [hovering, onHover] = useHoverState(index!, mergedHoverRowSpan, tableContext)

const onMouseEnter = (event: MouseEvent) => {
if (record) {
onHover(index!, index! + mergedRowSpan - 1)
onHover(index!, index! + mergedHoverRowSpan - 1)
}
const onMouseEnterHandler = additionalProps.onMouseEnter || additionalProps.onMouseenter
onMouseEnterHandler?.(event)
Expand Down
3 changes: 2 additions & 1 deletion packages/table/src/VirtualTable/VirtualCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const VirtualCell = defineComponent<VirtualCellProps<any>>({
const { render, dataIndex, className: columnClassName, width: colWidth } = column
const columnsOffset = gridContext.columnsOffset || []

const { key, fixedInfo, appendCellNode, additionalCellProps } = getCellProps(
const { key, fixedInfo, appendCellNode, additionalCellProps, hoverRowSpan } = getCellProps(
rowInfo,
record,
column,
Expand Down Expand Up @@ -132,6 +132,7 @@ const VirtualCell = defineComponent<VirtualCellProps<any>>({
shouldCellUpdate={column.shouldCellUpdate}
{...fixedInfo}
appendNode={appendCellNode}
hoverRowSpan={hoverRowSpan}
additionalProps={{
...additionalCellProps,
style: mergedStyle,
Expand Down
99 changes: 99 additions & 0 deletions packages/table/tests/hover-expand-offset.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// @vitest-environment jsdom

import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { h, nextTick } from 'vue'
import Table from '../src'

describe('table hover with expandedRowOffset', () => {
it('does not include expanded rows in rowSpan hover range', async () => {
const columns = [
{
title: 'Team',
dataIndex: 'team',
key: 'team',
onCell: (_record: any, index = 0) => index % 2 === 0 ? { rowSpan: 2 } : { rowSpan: 0 },
},
Table.EXPAND_COLUMN,
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Age', dataIndex: 'age', key: 'age' },
]
const data = [
{ key: '1', team: 'Team A', name: 'John', age: 32, description: 'John details' },
{ key: '2', team: 'Team A', name: 'Jim', age: 42, description: 'Jim details' },
{ key: '3', team: 'Team B', name: 'Joe', age: 22, description: 'Joe details' },
]

const wrapper = mount(Table, {
props: {
columns,
data,
expandable: { defaultExpandedRowKeys: ['1'], expandedRowOffset: 3 },
},
slots: {
expandedRowRender: ({ record }: any) => h('div', { class: 'expanded-content' }, record.description),
},
})

const firstRow = wrapper.find('tbody tr[data-row-key="1"]')
const thirdRow = wrapper.find('tbody tr[data-row-key="3"]')

await firstRow.find('td').trigger('mouseenter')
await nextTick()

expect(firstRow.findAll('td').some(cell => cell.classes().includes('vc-table-cell-row-hover'))).toBe(true)
expect(thirdRow.findAll('td').some(cell => cell.classes().includes('vc-table-cell-row-hover'))).toBe(false)

wrapper.unmount()
})

it('does not hover previous offset cells when moving into the next grouped row', async () => {
const columns = [
{
title: 'Team',
dataIndex: 'team',
key: 'team',
onCell: (_record: any, index = 0) => index % 2 === 0 ? { rowSpan: 2 } : { rowSpan: 0 },
},
Table.EXPAND_COLUMN,
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Age', dataIndex: 'age', key: 'age' },
{ title: 'Address', dataIndex: 'address', key: 'address' },
]
const data = [
{ key: '1', team: 'Team A', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park', description: 'John details' },
{ key: '2', team: 'Team A', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park', description: 'Jim details' },
{ key: '3', team: 'Team B', name: 'Not Expandable', age: 29, address: 'Jiangsu No. 1 Lake Park', description: 'This not expandable' },
{ key: '4', team: 'Team B', name: 'Joe Black', age: 32, address: 'Sydney No. 1 Lake Park', description: 'Joe details' },
]

const wrapper = mount(Table, {
props: {
columns,
data,
expandable: { defaultExpandedRowKeys: ['1', '2', '3', '4'], expandedRowOffset: 3 },
},
slots: {
expandedRowRender: ({ record }: any) => h('div', { class: 'expanded-content' }, record.description),
},
})

const allBodyCells = wrapper.findAll('tbody td')
const teamACell = allBodyCells.find(cell => cell.text() === 'Team A')
const jimNameCell = allBodyCells.find(cell => cell.text() === 'Jim Green')
const notExpandableAgeCell = allBodyCells.find(cell => cell.text() === '29')

expect(teamACell).toBeTruthy()
expect(jimNameCell).toBeTruthy()
expect(notExpandableAgeCell).toBeTruthy()

await notExpandableAgeCell!.trigger('mouseenter')
await nextTick()

expect(notExpandableAgeCell!.classes()).toContain('vc-table-cell-row-hover')
expect(teamACell!.classes()).not.toContain('vc-table-cell-row-hover')
expect(jimNameCell!.classes()).not.toContain('vc-table-cell-row-hover')

wrapper.unmount()
})
})