Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(comp:table): add virtualHorizontal support #1776

Merged
merged 1 commit into from
Dec 27, 2023
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
2 changes: 1 addition & 1 deletion packages/components/table/demo/AutoHeightVirtual.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
title:
zh: 自动高度 + 虚拟滚动
en: Auto height + Virtual
order: 91
order: 93
hidden: true
---
6 changes: 6 additions & 0 deletions packages/components/table/demo/VirtualBoth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title:
zh: 横向&竖向虚拟滚动
en: Virtual horizontal and vertical
order: 92
---
57 changes: 57 additions & 0 deletions packages/components/table/demo/VirtualBoth.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<IxTable
:columns="columns"
:dataSource="data"
:pagination="false"
virtual
virtualHorizontal
:scroll="scroll"
:virtualColWidth="150"
>
</IxTable>
</template>

<script lang="ts" setup>
import { h } from 'vue'

import { TableColumn } from '@idux/components/table'
import { IxText } from '@idux/components/text'

interface Data {
key: number
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[name: string]: any
}

const columns: TableColumn<Data>[] = []

const columnCount = 1000
const rowCount = 1000

const customCell = ({ value }: { value: string }) => {
return h(IxText, { ellipsis: true, tooltip: 'native' }, () => value)
}
for (let index = 0; index < columnCount; index++) {
const key = `column${index}`
columns.push({
title: key,
dataKey: key,
width: index % 2 === 1 ? 150 : 170,
fixed: index === 0 ? 'start' : index === columnCount - 1 ? 'end' : undefined,
customCell,
})
}

const data: Data[] = []
for (let index = 0; index < rowCount; index++) {
const item: Data = { key: index }

for (let colIndex = 0; colIndex < columnCount; colIndex++) {
item[`column${colIndex}`] = `row-${index} col-${colIndex} hahahahahahahahahahah`
}

data.push(item)
}

const scroll = { height: 800 }
</script>
14 changes: 14 additions & 0 deletions packages/components/table/demo/VirtualHorizontal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title:
zh: 横向虚拟滚动
en: Virtual horizontal
order: 91
---

## zh

通过 `virtualHorizontal` 开启横向虚拟滚动,横向虚拟滚动必须指定列宽

## en

Enable horizontal virtual scroll via `virtualHorizontal`, column width must be provided.
38 changes: 38 additions & 0 deletions packages/components/table/demo/VirtualHorizontal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<IxTable :columns="columns" :dataSource="data" :pagination="false" virtualHorizontal :virtualColWidth="150">
</IxTable>
</template>

<script lang="ts" setup>
import { TableColumn } from '@idux/components/table'

interface Data {
key: number
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[name: string]: any
}

const columns: TableColumn<Data>[] = []

const columnCount = 100

for (let index = 0; index < columnCount; index++) {
const key = `column${index}`
columns.push({
title: key,
dataKey: key,
width: index % 2 === 1 ? 150 : 170,
})
}

const data: Data[] = []
for (let index = 0; index < 8; index++) {
const item: Data = { key: index }

for (let colIndex = 0; colIndex < columnCount; colIndex++) {
item[`column${colIndex}`] = `row-${index} col-${colIndex}`
}

data.push(item)
}
</script>
6 changes: 5 additions & 1 deletion packages/components/table/docs/Api.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@
| `size` | 表格大小 | `'lg' \| 'md' \| 'sm'` | `md` | ✅ |- |
| `spin` | 表格是否加载中 | `boolean \| SpinProps` | - | - | - |
| `tableLayout` | 表格元素的 [table-layout](https://developer.mozilla.org/zh-CN/docs/Web/CSS/table-layout) 属性 | `'auto' \| 'fixed'` | - | - | 固定表头/列或设置了 `column.ellipsis` 时,默认值为 `fixed` |
| `virtual` | 是否开启虚拟滚动 | `boolean` | `false` | - | 需要设置 `scroll.height` |
| `virtual` | 是否开启纵向虚拟滚动 | `boolean` | `false` | - | 需要设置 `scroll.height` |
| `virtualHorizontal` | 是否开启横向虚拟滚动 | `boolean` | `false` | - | 不可以设置 `scroll.width`,并且每列的宽度必须配置 |
| `virtualItemHeight` | 虚拟滚动每一行的高度 | `number` | - | - | 标准大小的表格不需要设置,会自动设置。如果有非标准大小的表格,可以设置一个准确的值来提高性能。 |
| `virtualColWidth` | 虚拟滚动每一列的宽度 | `number` | - | - | 需要设置一个默认的值。 |
| `virtualBufferSize` | 虚拟滚动的buffer大小 | `number` | - | - | - |
| `virtualBufferOffset` | 虚拟滚动的buffer边界offset | `number` | - | - | - |
| `onScroll` | 滚动事件 | `(evt: Event) => void` | - | - | - |
| `onScrolledChange` | 滚动的位置发生变化 | `(startIndex: number, endIndex: number, visibleNodes: TreeNode[]) => void` | - | - | 仅 `virtual` 模式下可用 |
| `onScrolledBottom` | 滚动到底部时触发 | `() => void` | - | - | 仅 `virtual` 模式下可用 |
Expand Down
21 changes: 20 additions & 1 deletion packages/components/table/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { VirtualScrollEnabled } from '@idux/cdk/scroll'

import { type VNode, computed, defineComponent, normalizeClass, provide } from 'vue'

import { isBoolean } from 'lodash-es'
Expand Down Expand Up @@ -34,6 +36,7 @@ import { tableProps } from './types'
import { getThemeTokens } from '../theme'

const virtualItemHeight = { sm: 32, md: 40, lg: 56 } as const
const virtualColWidth = 150

export default defineComponent({
name: 'IxTable',
Expand All @@ -53,7 +56,14 @@ export default defineComponent({
const mergedEmptyCell = computed(() => props.emptyCell ?? config.emptyCell)
const mergedInsetShadow = computed(() => props.insetShadow ?? config.insetShadow)
const mergedSize = computed(() => props.size ?? config.size)
const mergedVirtual = computed<VirtualScrollEnabled>(() => {
return {
horizontal: props.virtualHorizontal,
vertical: props.virtual,
}
})
const mergedVirtualItemHeight = computed(() => props.virtualItemHeight ?? virtualItemHeight[mergedSize.value])
const mergedVirtualColWidth = computed(() => props.virtualColWidth ?? virtualColWidth)
const { mergedPagination } = usePagination(props, config, mergedSize)

const stickyContext = useSticky(props)
Expand All @@ -62,7 +72,14 @@ export default defineComponent({
const sortableContext = useSortable(columnsContext.flattedColumns)
const filterableContext = useFilterable(columnsContext.flattedColumns)
const expandableContext = useExpandable(props, columnsContext.flattedColumns)
const tableLayout = useTableLayout(props, columnsContext, scrollContext, stickyContext.isSticky, mergedAutoHeight)
const tableLayout = useTableLayout(
props,
columnsContext,
scrollContext,
stickyContext.isSticky,
mergedVirtual,
mergedAutoHeight,
)

const { activeSorters } = sortableContext
const { activeFilters } = filterableContext
Expand All @@ -88,7 +105,9 @@ export default defineComponent({
mergedPrefixCls,
mergedEmptyCell,
mergedInsetShadow,
mergedVirtual,
mergedVirtualItemHeight,
mergedVirtualColWidth,
mergedAutoHeight,
...columnsContext,
...scrollContext,
Expand Down
Loading