Skip to content

Commit

Permalink
fix(data-table): fixed column with multiple level header
Browse files Browse the repository at this point in the history
  • Loading branch information
07akioni committed Oct 13, 2021
1 parent 31caf74 commit 37d7fc9
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 43 deletions.
128 changes: 128 additions & 0 deletions src/data-table/demos/zhCN/fixed-column-debug.demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Fixed Column Debug

```html
<n-data-table
bordered
:scroll-x="2000"
:max-height="200"
:data="data"
:columns="columns"
:single-line="false"
:pagination="pagination"
/>
```

```js
import { defineComponent, ref } from 'vue'

function createCols () {
return [
{
title: 'Name',
key: 'name',
fixed: 'left',
children: [
{
title: '1',
key: '1',
fixed: 'left',
width: 100
},
{
title: '2',
key: '2',
fixed: 'left',
width: 100
},
{
title: '3',
key: '3',
fixed: 'left',
width: 100
},
{
title: '4',
key: '4',
fixed: 'left',
width: 100
},
{
title: '5',
key: '5',
fixed: 'left',
width: 100
},
{
title: '6',
key: '6',
fixed: 'left',
width: 100
}
]
},
{ title: 'Name2', key: 'name1', fixed: 'left', width: 100 },
{ title: 'Name3', key: 'name2', fixed: 'left', width: 100 },
{
title: 'Attrs',
key: 'attrs',
children: [
{
title: 'Attack',
key: 'attack',
children: [
{
title: 'Physics Attack',
key: 'physicsAttack'
},
{
title: 'Magic Attack',
key: 'magicAttack'
}
]
},
{
title: 'Defend',
key: 'defend'
},
{
title: 'Speed',
key: 'speed'
},
{
title: 'Defend1',
key: 'defend1'
},
{
title: 'Speed2',
key: 'speed2'
}
]
}
]
}

function createData () {
return Array.apply(null, { length: 50 }).map((_, i) => {
return {
key: i,
name: `name_${i}`,
physicsAttack: `physicsAttack_${i}`,
magicAttack: `magicAttack_${i}`,
defend: `defend_${i}`,
speed: `speed_${i}`
}
})
}

export default defineComponent({
setup () {
return {
data: ref(createData()),
columns: ref(createCols()),
pagination: ref({
pageSize: 10
})
}
}
})
```
1 change: 1 addition & 0 deletions src/data-table/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ virtual
custom-filter-menu
tree
flex-height
fixed-column-debug
scroll-debug
```

Expand Down
4 changes: 2 additions & 2 deletions src/data-table/src/TableParts/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,8 @@ export default defineComponent({
key={colKey}
style={{
textAlign: column.align || undefined,
left: pxfy(fixedColumnLeftMap[colKey]),
right: pxfy(fixedColumnRightMap[colKey])
left: pxfy(fixedColumnLeftMap[colKey]?.start),
right: pxfy(fixedColumnRightMap[colKey]?.start)
}}
colspan={mergedColSpan}
rowspan={mergedRowSpan}
Expand Down
12 changes: 8 additions & 4 deletions src/data-table/src/TableParts/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,25 @@ export default defineComponent({
const key = getColKey(column)
const { ellipsis } = column
if (!hasEllipsis && ellipsis) hasEllipsis = true
const leftFixed = key in fixedColumnLeftMap
const rightFixed = key in fixedColumnRightMap
return (
<th
key={key}
style={{
textAlign: column.align,
left: pxfy(fixedColumnLeftMap[key]),
right: pxfy(fixedColumnRightMap[key])
left: pxfy(fixedColumnLeftMap[key]?.start),
right: pxfy(fixedColumnRightMap[key]?.start)
}}
colspan={colSpan}
rowspan={rowSpan}
data-col-key={key}
class={[
`${mergedClsPrefix}-data-table-th`,
column.fixed &&
`${mergedClsPrefix}-data-table-th--fixed-${column.fixed}`,
(leftFixed || rightFixed) &&
`${mergedClsPrefix}-data-table-th--fixed-${
leftFixed ? 'left' : 'right'
}`,
{
[`${mergedClsPrefix}-data-table-th--hover`]:
isColumnSorting(column, mergedSortState),
Expand Down
8 changes: 6 additions & 2 deletions src/data-table/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,12 @@ export interface DataTableInjection {
rightFixedColumnsRef: Ref<TableColumns>
leftActiveFixedColKeyRef: Ref<ColumnKey | null>
rightActiveFixedColKeyRef: Ref<ColumnKey | null>
fixedColumnLeftMapRef: Ref<Record<ColumnKey, number | undefined>>
fixedColumnRightMapRef: Ref<Record<ColumnKey, number | undefined>>
fixedColumnLeftMapRef: Ref<
Record<ColumnKey, { start: number, end: number } | undefined>
>
fixedColumnRightMapRef: Ref<
Record<ColumnKey, { start: number, end: number } | undefined>
>
mergedCurrentPageRef: Ref<number>
someRowsCheckedRef: Ref<boolean>
allRowsCheckedRef: Ref<boolean>
Expand Down
75 changes: 44 additions & 31 deletions src/data-table/src/use-scroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { beforeNextFrameOnce } from 'seemly'
import { computed, ComputedRef, watch, Ref, ref } from 'vue'
import { formatLength } from '../../_utils'
import { DataTableSetupProps } from './DataTable'
import type { ColumnKey, MainTableRef, TableColumns } from './interface'
import type { ColumnKey, MainTableRef, TableColumn } from './interface'
import { getColWidth, getColKey } from './utils'

// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
Expand All @@ -27,43 +27,53 @@ export function useScroll (
return formatLength(props.scrollX)
})
const leftFixedColumnsRef = computed(() => {
const tableColumns: TableColumns = []
getFixedColumn(tableColumns, props.columns, 'left')
return tableColumns
return props.columns.filter((column) => column.fixed === 'left')
})
const rightFixedColumnsRef = computed(() => {
const tableColumns: TableColumns = []
getFixedColumn(tableColumns, props.columns, 'right')
return tableColumns
return props.columns.filter((column) => column.fixed === 'right')
})
const getFixedColumn = (
tableColumns: TableColumns,
columns: TableColumns,
direction: 'left' | 'right'
): void => {
columns.forEach((column) => {
column.fixed === direction && tableColumns.push(column)
if ('children' in column) {
getFixedColumn(tableColumns, column.children, direction)
}
})
}
const fixedColumnLeftMapRef = computed(() => {
const columns: Record<ColumnKey, number | undefined> = {}
const columns: Record<
ColumnKey,
{ start: number, end: number } | undefined
> = {}
let left = 0
for (const column of leftFixedColumnsRef.value) {
columns[getColKey(column)] = left
left += getColWidth(column) || 0
function traverse (cols: TableColumn[]): void {
cols.forEach((col) => {
const positionInfo = { start: left, end: 0 }
columns[getColKey(col)] = positionInfo
if ('children' in col) {
traverse(col.children)
positionInfo.end = left
} else {
left += getColWidth(col) || 0
positionInfo.end = left
}
})
}
traverse(leftFixedColumnsRef.value)
return columns
})
const fixedColumnRightMapRef = computed(() => {
const columns: Record<ColumnKey, number | undefined> = {}
const columns: Record<
ColumnKey,
{ start: number, end: number } | undefined
> = {}
let right = 0
for (const column of rightFixedColumnsRef.value.reverse()) {
columns[getColKey(column)] = right
right += column.width || 0
function traverse (cols: TableColumn[]): void {
cols.forEach((col) => {
const positionInfo = { start: right, end: 0 }
columns[getColKey(col)] = positionInfo
if ('children' in col) {
traverse(col.children)
positionInfo.end = right
} else {
right += getColWidth(col) || 0
positionInfo.end = right
}
})
}
traverse(rightFixedColumnsRef.value.reverse())
return columns
})
function deriveActiveLeftFixedColumn (): void {
Expand All @@ -74,9 +84,9 @@ export function useScroll (
let leftActiveFixedColKey = null
for (let i = 0; i < leftFixedColumns.length; ++i) {
const key = getColKey(leftFixedColumns[i])
if (scrollLeft > (fixedColumnLeftMap[key] || 0) - leftWidth) {
if (scrollLeft > (fixedColumnLeftMap[key]?.start || 0) - leftWidth) {
leftActiveFixedColKey = key
leftWidth += getColWidth(leftFixedColumns[i]) || 0
leftWidth = fixedColumnLeftMap[key]?.end || 0
} else {
break
}
Expand All @@ -96,11 +106,14 @@ export function useScroll (
const key = getColKey(rightFixedColumns[i])
if (
Math.round(
scrollLeft + (fixedColumnRightMap[key] || 0) + tableWidth - rightWidth
scrollLeft +
(fixedColumnRightMap[key]?.start || 0) +
tableWidth -
rightWidth
) < scrollWidth
) {
rightActiveFixedColKey = key
rightWidth += getColWidth(rightFixedColumns[i]) || 0
rightWidth = fixedColumnRightMap[key]?.end || 0
} else {
break
}
Expand Down
5 changes: 1 addition & 4 deletions src/table/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ const tableProps = {
type: Boolean,
default: true
},
singleColumn: {
type: Boolean,
default: false
},
singleColumn: Boolean,
size: {
type: String as PropType<'small' | 'medium' | 'large'>,
default: 'medium'
Expand Down

0 comments on commit 37d7fc9

Please sign in to comment.