From ef938c4e993b7571553dcdfef62d9cc180d43cb8 Mon Sep 17 00:00:00 2001 From: zombiej Date: Tue, 14 Sep 2021 18:41:45 +0800 Subject: [PATCH 1/4] fix: IE will not append additional sticky props --- package.json | 2 +- src/Cell/index.tsx | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 82909b63e..b38ee118d 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", "rc-resize-observer": "^1.0.0", - "rc-util": "^5.13.0", + "rc-util": "^5.14.0", "shallowequal": "^1.1.0" }, "devDependencies": { diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index 9492ccc32..6487360f2 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import classNames from 'classnames'; import { supportRef } from 'rc-util/lib/ref'; +import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker'; import type { DataIndex, ColumnType, @@ -13,6 +14,8 @@ import type { } from '../interface'; import { getPathValue, validateValue } from '../utils/valueUtil'; +const supportSticky = isStyleSupport('position', 'sticky'); + function isRenderCell( data: React.ReactNode | RenderedCell, ): data is RenderedCell { @@ -145,8 +148,8 @@ function Cell( // ====================== Fixed ======================= const fixedStyle: React.CSSProperties = {}; - const isFixLeft = typeof fixLeft === 'number'; - const isFixRight = typeof fixRight === 'number'; + const isFixLeft = typeof fixLeft === 'number' && supportSticky; + const isFixRight = typeof fixRight === 'number' && supportSticky; if (isFixLeft) { fixedStyle.position = 'sticky'; @@ -185,15 +188,15 @@ function Cell( cellPrefixCls, className, { - [`${cellPrefixCls}-fix-left`]: isFixLeft, - [`${cellPrefixCls}-fix-left-first`]: firstFixLeft, - [`${cellPrefixCls}-fix-left-last`]: lastFixLeft, - [`${cellPrefixCls}-fix-right`]: isFixRight, - [`${cellPrefixCls}-fix-right-first`]: firstFixRight, - [`${cellPrefixCls}-fix-right-last`]: lastFixRight, + [`${cellPrefixCls}-fix-left`]: isFixLeft && supportSticky, + [`${cellPrefixCls}-fix-left-first`]: firstFixLeft && supportSticky, + [`${cellPrefixCls}-fix-left-last`]: lastFixLeft && supportSticky, + [`${cellPrefixCls}-fix-right`]: isFixRight && supportSticky, + [`${cellPrefixCls}-fix-right-first`]: firstFixRight && supportSticky, + [`${cellPrefixCls}-fix-right-last`]: lastFixRight && supportSticky, [`${cellPrefixCls}-ellipsis`]: ellipsis, [`${cellPrefixCls}-with-append`]: appendNode, - [`${cellPrefixCls}-fix-sticky`]: (isFixLeft || isFixRight) && isSticky, + [`${cellPrefixCls}-fix-sticky`]: (isFixLeft || isFixRight) && isSticky && supportSticky, }, additionalProps.className, cellClassName, From b14ed6152f1b720e182429e75e3ff5c231212468 Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 15 Sep 2021 11:29:02 +0800 Subject: [PATCH 2/4] test: Add test case --- tests/FixedColumn-IE.spec.js | 61 ++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/FixedColumn-IE.spec.js diff --git a/tests/FixedColumn-IE.spec.js b/tests/FixedColumn-IE.spec.js new file mode 100644 index 000000000..90b9bb653 --- /dev/null +++ b/tests/FixedColumn-IE.spec.js @@ -0,0 +1,61 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { spyElementPrototype } from 'rc-util/lib/test/domHook'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker'; +import Table from '../src'; + +jest.mock('rc-util/lib/Dom/styleChecker', () => { + return { + isStyleSupport: (name, val) => val !== 'sticky', + }; +}); + +describe('Table.FixedColumn', () => { + let domSpy; + + beforeAll(() => { + domSpy = spyElementPrototype(HTMLElement, 'offsetParent', { + get: () => ({}), + }); + }); + + afterAll(() => { + domSpy.mockRestore(); + }); + + const columns = [ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, + { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, + { title: 'title3', dataIndex: 'c', key: 'c' }, + { title: 'title4', dataIndex: 'b', key: 'd' }, + { title: 'title5', dataIndex: 'b', key: 'e' }, + { title: 'title6', dataIndex: 'b', key: 'f' }, + { title: 'title7', dataIndex: 'b', key: 'g' }, + { title: 'title8', dataIndex: 'b', key: 'h' }, + { title: 'title9', dataIndex: 'b', key: 'i' }, + { title: 'title10', dataIndex: 'b', key: 'j' }, + { title: 'title11', dataIndex: 'b', key: 'k' }, + { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, + ]; + const data = [{ a: '123', b: 'xxxxxxxx', d: 3, key: '1' }]; + + it('not sticky', async () => { + jest.useFakeTimers(); + const wrapper = mount(); + + act(() => { + wrapper.find('table ResizeObserver').first().props().onResize({ width: 93, offsetWidth: 93 }); + }); + + await act(async () => { + jest.runAllTimers(); + await Promise.resolve(); + wrapper.update(); + }); + + expect(wrapper.exists('.rc-table-cell-fix-left')).toBeFalsy(); + expect(wrapper.exists('.rc-table-cell-fix-right')).toBeFalsy(); + }); +}); From f94173d1cc6f63e125d8b28d032f83efaebd6ecf Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 15 Sep 2021 11:40:26 +0800 Subject: [PATCH 3/4] chore: Use sticky context --- src/Cell/index.tsx | 6 +++--- src/Table.tsx | 16 +++++++++++----- src/context/StickyContext.tsx | 6 ++++++ src/context/TableContext.tsx | 4 ++-- tests/Cell.spec.tsx | 7 ++++--- 5 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 src/context/StickyContext.tsx diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index 6487360f2..dab5296b2 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import classNames from 'classnames'; import { supportRef } from 'rc-util/lib/ref'; -import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker'; import type { DataIndex, ColumnType, @@ -13,8 +12,7 @@ import type { CellEllipsisType, } from '../interface'; import { getPathValue, validateValue } from '../utils/valueUtil'; - -const supportSticky = isStyleSupport('position', 'sticky'); +import StickyContext from '../context/StickyContext'; function isRenderCell( data: React.ReactNode | RenderedCell, @@ -96,6 +94,8 @@ function Cell( ): React.ReactElement { const cellPrefixCls = `${prefixCls}-cell`; + const supportSticky = React.useContext(StickyContext); + // ==================== Child Node ==================== let cellProps: CellType; let childNode: React.ReactNode; diff --git a/src/Table.tsx b/src/Table.tsx index 7d78b5b22..b42e1650f 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -26,6 +26,7 @@ import * as React from 'react'; import isVisible from 'rc-util/lib/Dom/isVisible'; +import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker'; import classNames from 'classnames'; import shallowEqual from 'shallowequal'; import warning from 'rc-util/lib/warning'; @@ -73,6 +74,7 @@ import useSticky from './hooks/useSticky'; import FixedHolder from './FixedHolder'; import type { SummaryProps } from './Footer/Summary'; import Summary from './Footer/Summary'; +import StickyContext from './context/StickyContext'; // Used for conditions cache const EMPTY_DATA = []; @@ -502,9 +504,11 @@ function Table(props: TableProps { setScrollbarSize(getTargetScrollBarSize(scrollBodyRef.current).width); + setSupportSticky(isStyleSupport('position', 'sticky')); }, []); // ================== INTERNAL HOOKS ================== @@ -823,11 +827,13 @@ function Table(props: TableProps ({ onColumnResize }), [onColumnResize]); return ( - - - {fullTable} - - + + + + {fullTable} + + + ); } diff --git a/src/context/StickyContext.tsx b/src/context/StickyContext.tsx new file mode 100644 index 000000000..420e8cc79 --- /dev/null +++ b/src/context/StickyContext.tsx @@ -0,0 +1,6 @@ +import * as React from 'react'; + +// Tell cell that browser support sticky +const StickyContext = React.createContext(false); + +export default StickyContext; diff --git a/src/context/TableContext.tsx b/src/context/TableContext.tsx index 51957cfe5..5570ac44c 100644 --- a/src/context/TableContext.tsx +++ b/src/context/TableContext.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { GetComponent } from '../interface'; -import { FixedInfo } from '../utils/fixUtil'; +import type { GetComponent } from '../interface'; +import type { FixedInfo } from '../utils/fixUtil'; export interface TableContextProps { // Table context diff --git a/tests/Cell.spec.tsx b/tests/Cell.spec.tsx index 5bab299c1..e37b9334a 100644 --- a/tests/Cell.spec.tsx +++ b/tests/Cell.spec.tsx @@ -4,7 +4,7 @@ import Table from '../src'; describe('Table.Cell', () => { it('shouldCellUpdate', () => { - let renderTime = 0; + let reRenderTime = 0; const Demo = () => { const [, forceUpdate] = React.useState({}); @@ -18,7 +18,7 @@ describe('Table.Cell', () => { shouldCellUpdate: (record, prevRecord) => prevRecord.key !== record.key, dataIndex: 'key', render: value => { - renderTime += 1; + reRenderTime += 1; return value; }, }, @@ -35,10 +35,11 @@ describe('Table.Cell', () => { }; const wrapper = mount(); + reRenderTime = 0; for (let i = 0; i < 100; i += 1) { wrapper.find('button').simulate('click'); - expect(renderTime).toEqual(1); + expect(reRenderTime).toEqual(0); } }); }); From 695b4266799c7b8c35d5ccda079506334bb8478b Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 15 Sep 2021 11:46:40 +0800 Subject: [PATCH 4/4] chore: adjust logic --- src/Table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Table.tsx b/src/Table.tsx index b42e1650f..f00db3363 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -504,7 +504,7 @@ function Table(props: TableProps { setScrollbarSize(getTargetScrollBarSize(scrollBodyRef.current).width);