From c2d04c952c638a0b1a6c3addce839db350f6422c Mon Sep 17 00:00:00 2001 From: linxianxi <904492381@qq.com> Date: Fri, 22 Sep 2023 17:12:27 +0800 Subject: [PATCH] fix: support sticky when virtual --- package.json | 2 +- src/Table.tsx | 2 +- src/VirtualTable/BodyGrid.tsx | 13 ++++++++++++- src/VirtualTable/context.ts | 2 ++ src/VirtualTable/index.tsx | 7 +++++-- tests/Virtual.spec.tsx | 27 +++++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1fd58d934..365cfe8e9 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "classnames": "^2.2.5", "rc-resize-observer": "^1.1.0", "rc-util": "^5.36.0", - "rc-virtual-list": "^3.10.7" + "rc-virtual-list": "^3.11.1" }, "devDependencies": { "@rc-component/father-plugin": "^1.0.2", diff --git a/src/Table.tsx b/src/Table.tsx index 3562516ab..28f3b86d2 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -669,7 +669,7 @@ function Table(tableProps: TableProps )} - {isSticky && ( + {isSticky && scrollBodyRef.current instanceof Element && ( ((props, ref) => { 'emptyNode', 'scrollX', ]); - const { scrollY, listItemHeight } = useContext(StaticContext); + const { sticky, scrollY, listItemHeight } = useContext(StaticContext); // =========================== Ref ============================ const listRef = React.useRef(); @@ -195,10 +195,21 @@ const Grid = React.forwardRef((props, ref) => { let bodyContent: React.ReactNode; if (flattenData.length) { + // ========================== Sticky Scroll Bar ========================== + const horizontalScrollBarStyle: React.CSSProperties = {}; + if (sticky) { + horizontalScrollBarStyle.position = 'sticky'; + horizontalScrollBarStyle.bottom = 0; + if (typeof sticky === 'object' && sticky.offsetScroll) { + horizontalScrollBarStyle.bottom = sticky.offsetScroll; + } + } + bodyContent = ( > fullHeight={false} ref={listRef} + styles={{ horizontalScrollBar: horizontalScrollBarStyle }} className={classNames(tblPrefixCls, `${tblPrefixCls}-virtual`)} height={scrollY} itemHeight={listItemHeight || 24} diff --git a/src/VirtualTable/context.ts b/src/VirtualTable/context.ts index 5e6786737..097658a90 100644 --- a/src/VirtualTable/context.ts +++ b/src/VirtualTable/context.ts @@ -1,8 +1,10 @@ import { createContext } from '@rc-component/context'; +import type { TableSticky } from '../interface'; export interface StaticContextProps { scrollY: number; listItemHeight: number; + sticky: boolean | TableSticky; } export const StaticContext = createContext(null); diff --git a/src/VirtualTable/index.tsx b/src/VirtualTable/index.tsx index 57d6d68c7..89703e203 100644 --- a/src/VirtualTable/index.tsx +++ b/src/VirtualTable/index.tsx @@ -24,7 +24,7 @@ export interface VirtualTableProps extends Omit(props: VirtualTableProps) { - const { columns, scroll, prefixCls = DEFAULT_PREFIX, className, listItemHeight } = props; + const { columns, scroll, sticky, prefixCls = DEFAULT_PREFIX, className, listItemHeight } = props; let { x: scrollX, y: scrollY } = scroll || {}; @@ -47,7 +47,10 @@ function VirtualTable(props: VirtualTableProps) { } // ========================= Context ========================== - const context = React.useMemo(() => ({ scrollY, listItemHeight }), [scrollY, listItemHeight]); + const context = React.useMemo( + () => ({ sticky, scrollY, listItemHeight }), + [sticky, scrollY, listItemHeight], + ); // ========================== Render ========================== return ( diff --git a/tests/Virtual.spec.tsx b/tests/Virtual.spec.tsx index 637a41f87..129a745c4 100644 --- a/tests/Virtual.spec.tsx +++ b/tests/Virtual.spec.tsx @@ -268,4 +268,31 @@ describe('Table.Virtual', () => { '1128', ); }); + + it('sticky header with virtual should work', async () => { + const { container } = getTable({ sticky: { offsetHeader: 10 } }); + + await waitFakeTimer(); + + expect(container.querySelector('.rc-table-header')).toHaveStyle({ + overflow: 'hidden', + top: '10px', + }); + + expect(container.querySelector('.rc-table-header')).toHaveClass( + 'rc-table-header', + 'rc-table-sticky-holder', + ); + }); + + it('sticky scrollbar with virtual should work', async () => { + const { container } = getTable({ sticky: { offsetScroll: 10 } }); + + await waitFakeTimer(); + + expect(container.querySelector('.rc-virtual-list-scrollbar-horizontal')).toHaveStyle({ + position: 'sticky', + bottom: '10px', + }); + }); });