Skip to content

Commit 10a5ee6

Browse files
committed
feat(data-table): enhance fixed column rendering and add container scroll handling
1 parent fc7a989 commit 10a5ee6

12 files changed

Lines changed: 438 additions & 72 deletions

File tree

packages/varlet-ui/src/data-table/DataTable.vue

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@
1414
"
1515
>
1616
<var-loading :loading="loading">
17-
<div :class="classes(n('container'), n('$--scrollbar'))" :style="containerStyle">
17+
<div
18+
ref="container"
19+
:class="classes(n('container'), n('$--scrollbar'))"
20+
:style="containerStyle"
21+
@scroll="handleContainerScroll"
22+
>
1823
<table v-if="columns.length" :class="n('table')" :style="tableStyle">
1924
<colgroup>
2025
<col
@@ -42,8 +47,8 @@
4247
:get-column-sorter-order="getColumnSorterOrder"
4348
:is-column-resizable="isColumnResizable"
4449
:is-last-header-column="isLastHeaderColumn"
45-
:is-last-left-fixed-column="isLastLeftFixedColumn"
46-
:is-first-right-fixed-column="isFirstRightFixedColumn"
50+
:should-render-left-fixed-shadow="shouldRenderLeftFixedShadow"
51+
:should-render-right-fixed-shadow="shouldRenderRightFixedShadow"
4752
:toggle-column-sorter="toggleColumnSorter"
4853
:toggle-current-selectable-rows="toggleCurrentSelectableRows"
4954
:start-column-resize="startColumnResize"
@@ -69,8 +74,8 @@
6974
:is-row-key-selected="isRowKeySelected"
7075
:is-row-key-indeterminate="isRowKeyIndeterminate"
7176
:is-row-expandable="isRowExpandable"
72-
:is-last-left-fixed-column="isLastLeftFixedColumn"
73-
:is-first-right-fixed-column="isFirstRightFixedColumn"
77+
:should-render-left-fixed-shadow="shouldRenderLeftFixedShadow"
78+
:should-render-right-fixed-shadow="shouldRenderRightFixedShadow"
7479
:toggle-row-selection="toggleRowSelection"
7580
:toggle-row-expanded="toggleRowExpanded"
7681
:toggle-tree-row-expanded="toggleTreeRowExpanded"
@@ -99,8 +104,8 @@
99104
n('cell'),
100105
n('summary-cell'),
101106
[cell.column.fixed, n('fixed-cell')],
102-
[isLastLeftFixedColumn(cell.columnIndex), n('fixed-cell--shadow-right')],
103-
[isFirstRightFixedColumn(cell.columnIndex), n('fixed-cell--shadow-left')],
107+
[shouldRenderLeftFixedShadow(cell.columnIndex), n('fixed-cell--shadow-right')],
108+
[shouldRenderRightFixedShadow(cell.columnIndex), n('fixed-cell--shadow-left')],
104109
)
105110
"
106111
:style="getBodyCellStyle(cell)"
@@ -168,6 +173,7 @@ import {
168173
import { type DataTableBodyCell, type DataTableBodyRow, useBodyRows } from './useBodyRows'
169174
import { useColumnsFixedOffsets } from './useColumnsFixedOffsets'
170175
import { useColumnSizes } from './useColumnSizes'
176+
import { useContainerScroll } from './useContainerScroll'
171177
import { useExpandRow } from './useExpandRow'
172178
import { useFootRows } from './useFootRows'
173179
import { type DataTableHeaderCell, useHeaderRows } from './useHeaderRows'
@@ -195,6 +201,35 @@ export default defineComponent({
195201
const expandedTreeRowKeys = useVModel(props, 'expandedTreeRowKeys')
196202
const page = useVModel(props, 'page')
197203
const pageSize = useVModel(props, 'pageSize')
204+
205+
const { collapsedTreeRowKeys, toggleTreeRowExpanded } = useTreeExpand({
206+
tree: () => props.tree,
207+
data: () => props.data,
208+
expandedTreeRowKeys,
209+
getRowKey,
210+
getTreeChildren,
211+
})
212+
213+
const { normalizedColumns: columns, headerRows } = useHeaderRows({
214+
columns: () => props.columns,
215+
})
216+
217+
console.log(columns)
218+
console.log(headerRows)
219+
220+
const {
221+
allColumnsHaveResolvedWidth,
222+
hasResolvedColumnWidth,
223+
resolvedColumnWidths,
224+
totalResolvedColumnWidth,
225+
getColStyle,
226+
isColumnResizable,
227+
startColumnResize,
228+
} = useColumnSizes({
229+
columns: () => columns.value,
230+
isSelectionColumn,
231+
isExpandColumn,
232+
})
198233
const containerStyle = computed<CSSProperties>(() => {
199234
const style: CSSProperties = {}
200235
@@ -203,46 +238,36 @@ export default defineComponent({
203238
style.overflow = 'auto'
204239
}
205240
206-
if (props.scrollX != null) {
207-
style.overflowX = 'auto'
208-
}
241+
style.overflowX = 'auto'
209242
210243
return style
211244
})
212245
const tableStyle = computed<CSSProperties>(() => {
213246
const style: CSSProperties = {
214-
tableLayout: props.tableLayout,
215-
minWidth: '100%',
247+
tableLayout: hasResolvedColumnWidth.value ? 'fixed' : props.tableLayout,
216248
}
217249
218-
if (props.scrollX != null) {
219-
style.width = toSizeUnit(props.scrollX)
250+
if (allColumnsHaveResolvedWidth.value) {
251+
style.width = '100%'
252+
style.minWidth = toSizeUnit(totalResolvedColumnWidth.value)
253+
return style
220254
}
221255
222-
return style
223-
})
224-
225-
const { collapsedTreeRowKeys, toggleTreeRowExpanded } = useTreeExpand({
226-
tree: () => props.tree,
227-
data: () => props.data,
228-
expandedTreeRowKeys,
229-
getRowKey,
230-
getTreeChildren,
231-
})
256+
if (props.scrollX != null) {
257+
const width = toSizeUnit(props.scrollX)
258+
style.width = width
259+
style.minWidth = width
260+
return style
261+
}
232262
233-
const { normalizedColumns: columns, headerRows } = useHeaderRows({
234-
columns: () => props.columns,
235-
})
263+
style.minWidth = '100%'
236264
237-
const { columnWidths, getColStyle, isColumnResizable, startColumnResize } = useColumnSizes({
238-
columns: () => columns.value,
239-
isSelectionColumn,
240-
isExpandColumn,
265+
return style
241266
})
242267
243268
const { getFixedStyle, isFirstRightFixedColumn, isLastLeftFixedColumn } = useColumnsFixedOffsets({
244269
columns: () => columns.value,
245-
columnWidths: () => columnWidths.value,
270+
resolvedColumnWidths: () => resolvedColumnWidths.value,
246271
})
247272
248273
const { getColumnSorterOrder, isColumnSortable, toggleColumnSorter } = useSorter({
@@ -291,6 +316,14 @@ export default defineComponent({
291316
summary: () => props.summary,
292317
})
293318
319+
const { container, scrollLeft, maxScrollDistance, handleContainerScroll } = useContainerScroll([
320+
columns,
321+
bodyRows,
322+
footRows,
323+
totalResolvedColumnWidth,
324+
() => props.scrollX,
325+
])
326+
294327
const {
295328
currentSelectableRows,
296329
allCurrentRowsSelected,
@@ -392,6 +425,14 @@ export default defineComponent({
392425
return columnIndex === columns.value.length - 1
393426
}
394427
428+
function shouldRenderLeftFixedShadow(columnIndex: number) {
429+
return scrollLeft.value > 1 && isLastLeftFixedColumn(columnIndex)
430+
}
431+
432+
function shouldRenderRightFixedShadow(columnIndex: number) {
433+
return scrollLeft.value < maxScrollDistance.value - 1 && isFirstRightFixedColumn(columnIndex)
434+
}
435+
395436
function getHeaderCellStyle(cell: DataTableHeaderCell): CSSProperties {
396437
return {
397438
textAlign: getAlign(cell.column.titleAlign ?? cell.column.align),
@@ -416,6 +457,7 @@ export default defineComponent({
416457
return {
417458
pt,
418459
t,
460+
container,
419461
expandedRowKeys,
420462
containerStyle,
421463
paginationProps,
@@ -445,6 +487,8 @@ export default defineComponent({
445487
isRowKeyIndeterminate,
446488
isRowKeySelected,
447489
isRowSelectable,
490+
shouldRenderLeftFixedShadow,
491+
shouldRenderRightFixedShadow,
448492
toggleColumnSorter,
449493
toggleCurrentSelectableRows,
450494
toggleRowExpanded,
@@ -456,9 +500,8 @@ export default defineComponent({
456500
getHeaderCellStyle,
457501
getBodyCellStyle,
458502
handlePaginationChange,
503+
handleContainerScroll,
459504
isLastHeaderColumn,
460-
isFirstRightFixedColumn,
461-
isLastLeftFixedColumn,
462505
startColumnResize,
463506
n,
464507
classes,

packages/varlet-ui/src/data-table/DataTableBodyCell.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
[isSelectionColumn(cell.column), n('selection-cell')],
88
[isExpandColumn(cell.column), n('expand-cell')],
99
[cell.column.fixed, n('fixed-cell')],
10-
[isLastLeftFixedColumn(cell.columnIndex), n('fixed-cell--shadow-right')],
11-
[isFirstRightFixedColumn(cell.columnIndex), n('fixed-cell--shadow-left')],
10+
[shouldRenderLeftFixedShadow(cell.columnIndex), n('fixed-cell--shadow-right')],
11+
[shouldRenderRightFixedShadow(cell.columnIndex), n('fixed-cell--shadow-left')],
1212
)
1313
"
1414
:style="style"
@@ -134,11 +134,11 @@ export default defineComponent({
134134
type: Function as PropType<(bodyRow: DataTableBodyRow, column?: DataTableExpandColumn) => boolean>,
135135
required: true,
136136
},
137-
isLastLeftFixedColumn: {
137+
shouldRenderLeftFixedShadow: {
138138
type: Function as PropType<(columnIndex: number) => boolean>,
139139
required: true,
140140
},
141-
isFirstRightFixedColumn: {
141+
shouldRenderRightFixedShadow: {
142142
type: Function as PropType<(columnIndex: number) => boolean>,
143143
required: true,
144144
},

packages/varlet-ui/src/data-table/DataTableHeaderCell.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
[isSelectionColumn(headerCell.column), n('selection-cell')],
88
[isExpandColumn(headerCell.column), n('expand-cell')],
99
[headerCell.fixed, n('fixed-cell')],
10-
[isLastLeftFixedColumn(headerCell.endLeafColumnIndex), n('fixed-cell--shadow-right')],
11-
[isFirstRightFixedColumn(headerCell.startLeafColumnIndex), n('fixed-cell--shadow-left')],
10+
[shouldRenderLeftFixedShadow(headerCell.endLeafColumnIndex), n('fixed-cell--shadow-right')],
11+
[shouldRenderRightFixedShadow(headerCell.startLeafColumnIndex), n('fixed-cell--shadow-left')],
1212
)
1313
"
1414
:style="style"
@@ -151,11 +151,11 @@ export default defineComponent({
151151
type: Function as PropType<(columnIndex: number) => boolean>,
152152
required: true,
153153
},
154-
isLastLeftFixedColumn: {
154+
shouldRenderLeftFixedShadow: {
155155
type: Function as PropType<(columnIndex: number) => boolean>,
156156
required: true,
157157
},
158-
isFirstRightFixedColumn: {
158+
shouldRenderRightFixedShadow: {
159159
type: Function as PropType<(columnIndex: number) => boolean>,
160160
required: true,
161161
},

0 commit comments

Comments
 (0)