Skip to content

Commit

Permalink
feat(comp:table): add scrollToTopOnChange support (#1169)
Browse files Browse the repository at this point in the history
  • Loading branch information
sallerli1 authored Sep 28, 2022
1 parent 43b0802 commit 464bf40
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/components/config/src/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ export const defaultConfig: GlobalConfig = {
childrenKey: 'children',
getKey: 'key',
size: 'md',
scrollToTopOnChange: true,
pagination: {
position: 'bottomEnd',
},
Expand Down
1 change: 1 addition & 0 deletions packages/components/config/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ export interface TableConfig {
*/
rowKey?: string
size: TableSize
scrollToTopOnChange?: boolean

emptyCell?: string | ((options: TableEmptyCellOptions) => VNodeChild)

Expand Down
1 change: 1 addition & 0 deletions packages/components/table/docs/Api.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
| `headless` | 是否隐藏表头 | `boolean` | `false` | - |- |
| `pagination` | 配置分页器, 参见[TablePagination](#TablePagination) | `boolean \| TablePagination` | - || 设置 `false` 时表示不显示分页 |
| `scroll` | 表格滚动配置项,可以指定滚动区域的宽、高, 参见[TableScroll](#TableScroll) | `TableScroll` | - | - | - |
| `scrollToTopOnChange` | 是否在表格的分页、筛选、排序信息改变后滚动到顶部 | `boolean` | `true` || - |
| `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` |
Expand Down
13 changes: 10 additions & 3 deletions packages/components/table/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useFilterable } from './composables/useFilterable'
import { useGetRowKey } from './composables/useGetRowKey'
import { usePagination } from './composables/usePagination'
import { useScroll } from './composables/useScroll'
import { useScrollOnChange } from './composables/useScrollOnChange'
import { useSelectable } from './composables/useSelectable'
import { useSortable } from './composables/useSortable'
import { useSticky } from './composables/useSticky'
Expand All @@ -46,26 +47,32 @@ export default defineComponent({
const mergedGetKey = useGetRowKey(props, config)
const mergedEmptyCell = computed(() => props.emptyCell ?? config.emptyCell)
const mergedSize = computed(() => props.size ?? config.size)
const { mergedPagination } = usePagination(props, config, mergedSize)

const stickyContext = useSticky(props)
const scrollContext = useScroll(props, mergedAutoHeight, stickyContext)
const columnsContext = useColumns(props, slots, config, scrollContext.scrollBarSizeOnFixedHolder)
const sortableContext = useSortable(columnsContext.flattedColumns)
const filterableContext = useFilterable(columnsContext.flattedColumns)
const expandableContext = useExpandable(props, columnsContext.flattedColumns)
const tableLayout = useTableLayout(props, columnsContext, scrollContext, stickyContext.isSticky)
const { mergedPagination } = usePagination(props, config, mergedSize)

const { activeSorters } = sortableContext
const { activeFilters } = filterableContext

const dataContext = useDataSource(
props,
mergedChildrenKey,
mergedGetKey,
sortableContext.activeSorters,
filterableContext.activeFilters,
activeSorters,
activeFilters,
expandableContext.expandedRowKeys,
mergedPagination,
)
const selectableContext = useSelectable(props, locale, columnsContext.flattedColumns, dataContext)

useScrollOnChange(props, config, scrollContext.scrollBodyRef, mergedPagination, activeSorters, activeFilters)

const context = {
props,
slots,
Expand Down
59 changes: 59 additions & 0 deletions packages/components/table/src/composables/useScrollOnChange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @license
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { TablePagination, TableProps } from '../types'
import type { ActiveFilter } from './useFilterable'
import type { ActiveSorter } from './useSortable'
import type { TableConfig } from '@idux/components/config'

import { type ComputedRef, type Ref, type WatchStopHandle, computed, watch } from 'vue'

import { type VirtualScrollInstance, scrollToTop } from '@idux/cdk/scroll'

export function useScrollOnChange(
props: TableProps,
config: TableConfig,
scrollBodyRef: Ref<HTMLElement | VirtualScrollInstance | undefined>,
mergedPagination: ComputedRef<TablePagination | null>,
activeSorters: ComputedRef<ActiveSorter[]>,
activeFilters: ComputedRef<ActiveFilter[]>,
): void {
const mergedScrollToTopOnChange = computed(() => props.scrollToTopOnChange ?? config.scrollToTopOnChange)

let stopOnChangeWatch: WatchStopHandle | undefined
const startOnChangeWatch = () => {
stopOnChangeWatch = watch(
[() => mergedPagination.value?.pageIndex, () => mergedPagination.value?.pageSize, activeSorters, activeFilters],
() => {
if (!scrollBodyRef.value) {
return
}

if (props.virtual) {
;(scrollBodyRef.value as VirtualScrollInstance).scrollTo(0)
} else {
scrollToTop({
target: scrollBodyRef.value as HTMLElement,
top: 0,
})
}
},
)
}

watch(
mergedScrollToTopOnChange,
scrollToTopOnChange => {
stopOnChangeWatch?.()

if (scrollToTopOnChange) {
startOnChangeWatch()
}
},
{ immediate: true },
)
}
1 change: 1 addition & 0 deletions packages/components/table/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const tableProps = {
size: { type: String as PropType<TableSize>, default: undefined },
spin: { type: [Boolean, Object] as PropType<boolean | SpinProps>, default: undefined },
sticky: { type: [Boolean, Object] as PropType<boolean | TableSticky>, default: undefined },
scrollToTopOnChange: { type: Boolean, default: undefined },
tableLayout: { type: String as PropType<'auto' | 'fixed'>, default: undefined },
virtual: { type: Boolean, default: false },

Expand Down
1 change: 1 addition & 0 deletions packages/pro/table/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const proTableProps = {
layoutTool: { type: [Boolean, Object] as PropType<boolean | ProTableLayoutToolPublicProps>, default: true },
pagination: { type: [Boolean, Object] as PropType<boolean | TablePagination>, default: undefined },
scroll: { type: Object as PropType<TableScroll>, default: undefined },
scrollToTopOnChange: { type: Boolean, default: undefined },
size: { type: String as PropType<TableSize>, default: undefined },
spin: { type: [Boolean, Object] as PropType<boolean | SpinProps>, default: undefined },
sticky: { type: [Boolean, Object] as PropType<boolean | TableSticky>, default: undefined },
Expand Down

0 comments on commit 464bf40

Please sign in to comment.