diff --git a/.changeset/moody-bikes-raise.md b/.changeset/moody-bikes-raise.md new file mode 100644 index 000000000..2669a64c1 --- /dev/null +++ b/.changeset/moody-bikes-raise.md @@ -0,0 +1,6 @@ +--- +"@hi-ui/table": minor +"@hi-ui/hiui": minor +--- + +feat(table): 虚拟列表下,支持设置滚动位置(#3044) diff --git a/packages/ui/table/src/TableBody.tsx b/packages/ui/table/src/TableBody.tsx index 962d493c8..fb8058f13 100644 --- a/packages/ui/table/src/TableBody.tsx +++ b/packages/ui/table/src/TableBody.tsx @@ -1,5 +1,5 @@ -import React, { forwardRef, useMemo, useRef } from 'react' -import VirtualList from 'rc-virtual-list' +import React, { forwardRef, useMemo, useRef, useImperativeHandle } from 'react' +import VirtualList, { ListRef } from 'rc-virtual-list' import { cx, getPrefixCls } from '@hi-ui/classname' import { __DEV__ } from '@hi-ui/env' import { useLatestCallback } from '@hi-ui/use-latest' @@ -32,8 +32,11 @@ export const TableBody = forwardRef( measureRowElementRef, scrollbar, scrollLeft, + innerRef, } = useTableContext() const virtualListRef = useRef(null) + const listRef = useRef(null) + const cls = cx(`${prefixCls}-body`) const getRequiredProps = useLatestCallback( @@ -56,6 +59,10 @@ export const TableBody = forwardRef( return tmpWidth }, [colWidths]) + useImperativeHandle(innerRef, () => ({ + scrollTo: listRef.current?.scrollTo, + })) + if (virtual) { // TODO: avg和summay row的逻辑 const realHeight = (virtualListRef.current as HTMLTableElement | null)?.getBoundingClientRect() @@ -92,6 +99,7 @@ export const TableBody = forwardRef( style={{ width: '100%', position: 'sticky', left: 0, maxHeight }} > + +export type ScrollAlign = 'top' | 'bottom' | 'auto' + +export type ScrollConfig = + | { + index: number + align?: ScrollAlign + offset?: number + } + | { + key: React.Key + align?: ScrollAlign + offset?: number + } + +export interface TableHelper { + scrollTo?: (arg: number | ScrollConfig) => void +} diff --git a/packages/ui/table/src/use-table.ts b/packages/ui/table/src/use-table.ts index 805e1dd07..94ab60914 100644 --- a/packages/ui/table/src/use-table.ts +++ b/packages/ui/table/src/use-table.ts @@ -32,6 +32,7 @@ import { TableRowSelection, FlattedTableColumnItemData, FlattedTableRowData, + TableHelper, } from './types' import { SELECTION_DATA_KEY } from './Table' @@ -87,6 +88,7 @@ export const useTable = ({ cellClassName, onChange, onHighlightedCol, + innerRef, ...rootProps }: UseTableProps) => { /** @@ -687,6 +689,7 @@ export const useTable = ({ rowClassName, cellClassName, onHighlightedCol, + innerRef, } } @@ -904,6 +907,10 @@ export interface UseTableProps { }, highlightedColKeys: string[] ) => void + /** + * 提供辅助方法的内部引用 + */ + innerRef?: React.Ref } export type UseTableReturn = ReturnType diff --git a/packages/ui/table/stories/virtual.stories.tsx b/packages/ui/table/stories/virtual.stories.tsx index e20a662a0..092f3cd50 100644 --- a/packages/ui/table/stories/virtual.stories.tsx +++ b/packages/ui/table/stories/virtual.stories.tsx @@ -1,6 +1,6 @@ import React from 'react' -import Table from '../src' - +import Table, { TableHelper } from '../src' +import Button from '@hi-ui/button' /** * @title 虚拟列表 */ @@ -45,16 +45,28 @@ export const Virtual = () => { }, ]) const [data] = React.useState(MockData) + const tableRef = React.useRef(null) return ( <>

Virtual for Table

+
+ +