Skip to content

Commit c9bbdcf

Browse files
authored
fix: Do not add sticky style on IE (#668)
* fix: IE will not append additional sticky props * test: Add test case * chore: Use sticky context * chore: adjust logic
1 parent d63bc29 commit c9bbdcf

File tree

7 files changed

+97
-20
lines changed

7 files changed

+97
-20
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"@babel/runtime": "^7.10.1",
5757
"classnames": "^2.2.5",
5858
"rc-resize-observer": "^1.0.0",
59-
"rc-util": "^5.13.0",
59+
"rc-util": "^5.14.0",
6060
"shallowequal": "^1.1.0"
6161
},
6262
"devDependencies": {

src/Cell/index.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
CellEllipsisType,
1313
} from '../interface';
1414
import { getPathValue, validateValue } from '../utils/valueUtil';
15+
import StickyContext from '../context/StickyContext';
1516

1617
function isRenderCell<RecordType>(
1718
data: React.ReactNode | RenderedCell<RecordType>,
@@ -93,6 +94,8 @@ function Cell<RecordType extends DefaultRecordType>(
9394
): React.ReactElement {
9495
const cellPrefixCls = `${prefixCls}-cell`;
9596

97+
const supportSticky = React.useContext(StickyContext);
98+
9699
// ==================== Child Node ====================
97100
let cellProps: CellType<RecordType>;
98101
let childNode: React.ReactNode;
@@ -145,8 +148,8 @@ function Cell<RecordType extends DefaultRecordType>(
145148

146149
// ====================== Fixed =======================
147150
const fixedStyle: React.CSSProperties = {};
148-
const isFixLeft = typeof fixLeft === 'number';
149-
const isFixRight = typeof fixRight === 'number';
151+
const isFixLeft = typeof fixLeft === 'number' && supportSticky;
152+
const isFixRight = typeof fixRight === 'number' && supportSticky;
150153

151154
if (isFixLeft) {
152155
fixedStyle.position = 'sticky';
@@ -185,15 +188,15 @@ function Cell<RecordType extends DefaultRecordType>(
185188
cellPrefixCls,
186189
className,
187190
{
188-
[`${cellPrefixCls}-fix-left`]: isFixLeft,
189-
[`${cellPrefixCls}-fix-left-first`]: firstFixLeft,
190-
[`${cellPrefixCls}-fix-left-last`]: lastFixLeft,
191-
[`${cellPrefixCls}-fix-right`]: isFixRight,
192-
[`${cellPrefixCls}-fix-right-first`]: firstFixRight,
193-
[`${cellPrefixCls}-fix-right-last`]: lastFixRight,
191+
[`${cellPrefixCls}-fix-left`]: isFixLeft && supportSticky,
192+
[`${cellPrefixCls}-fix-left-first`]: firstFixLeft && supportSticky,
193+
[`${cellPrefixCls}-fix-left-last`]: lastFixLeft && supportSticky,
194+
[`${cellPrefixCls}-fix-right`]: isFixRight && supportSticky,
195+
[`${cellPrefixCls}-fix-right-first`]: firstFixRight && supportSticky,
196+
[`${cellPrefixCls}-fix-right-last`]: lastFixRight && supportSticky,
194197
[`${cellPrefixCls}-ellipsis`]: ellipsis,
195198
[`${cellPrefixCls}-with-append`]: appendNode,
196-
[`${cellPrefixCls}-fix-sticky`]: (isFixLeft || isFixRight) && isSticky,
199+
[`${cellPrefixCls}-fix-sticky`]: (isFixLeft || isFixRight) && isSticky && supportSticky,
197200
},
198201
additionalProps.className,
199202
cellClassName,

src/Table.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import * as React from 'react';
2828
import isVisible from 'rc-util/lib/Dom/isVisible';
29+
import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker';
2930
import classNames from 'classnames';
3031
import shallowEqual from 'shallowequal';
3132
import warning from 'rc-util/lib/warning';
@@ -73,6 +74,7 @@ import useSticky from './hooks/useSticky';
7374
import FixedHolder from './FixedHolder';
7475
import type { SummaryProps } from './Footer/Summary';
7576
import Summary from './Footer/Summary';
77+
import StickyContext from './context/StickyContext';
7678

7779
// Used for conditions cache
7880
const EMPTY_DATA = [];
@@ -502,9 +504,11 @@ function Table<RecordType extends DefaultRecordType>(props: TableProps<RecordTyp
502504

503505
// ===================== Effects ======================
504506
const [scrollbarSize, setScrollbarSize] = React.useState(0);
507+
const [supportSticky, setSupportSticky] = React.useState(true); // Only IE not support, we mark as support first
505508

506509
React.useEffect(() => {
507510
setScrollbarSize(getTargetScrollBarSize(scrollBodyRef.current).width);
511+
setSupportSticky(isStyleSupport('position', 'sticky'));
508512
}, []);
509513

510514
// ================== INTERNAL HOOKS ==================
@@ -823,11 +827,13 @@ function Table<RecordType extends DefaultRecordType>(props: TableProps<RecordTyp
823827
const ResizeContextValue = React.useMemo(() => ({ onColumnResize }), [onColumnResize]);
824828

825829
return (
826-
<TableContext.Provider value={TableContextValue}>
827-
<BodyContext.Provider value={BodyContextValue}>
828-
<ResizeContext.Provider value={ResizeContextValue}>{fullTable}</ResizeContext.Provider>
829-
</BodyContext.Provider>
830-
</TableContext.Provider>
830+
<StickyContext.Provider value={supportSticky}>
831+
<TableContext.Provider value={TableContextValue}>
832+
<BodyContext.Provider value={BodyContextValue}>
833+
<ResizeContext.Provider value={ResizeContextValue}>{fullTable}</ResizeContext.Provider>
834+
</BodyContext.Provider>
835+
</TableContext.Provider>
836+
</StickyContext.Provider>
831837
);
832838
}
833839

src/context/StickyContext.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as React from 'react';
2+
3+
// Tell cell that browser support sticky
4+
const StickyContext = React.createContext<boolean>(false);
5+
6+
export default StickyContext;

src/context/TableContext.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
2-
import { GetComponent } from '../interface';
3-
import { FixedInfo } from '../utils/fixUtil';
2+
import type { GetComponent } from '../interface';
3+
import type { FixedInfo } from '../utils/fixUtil';
44

55
export interface TableContextProps {
66
// Table context

tests/Cell.spec.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Table from '../src';
44

55
describe('Table.Cell', () => {
66
it('shouldCellUpdate', () => {
7-
let renderTime = 0;
7+
let reRenderTime = 0;
88

99
const Demo = () => {
1010
const [, forceUpdate] = React.useState({});
@@ -18,7 +18,7 @@ describe('Table.Cell', () => {
1818
shouldCellUpdate: (record, prevRecord) => prevRecord.key !== record.key,
1919
dataIndex: 'key',
2020
render: value => {
21-
renderTime += 1;
21+
reRenderTime += 1;
2222
return value;
2323
},
2424
},
@@ -35,10 +35,11 @@ describe('Table.Cell', () => {
3535
};
3636

3737
const wrapper = mount(<Demo />);
38+
reRenderTime = 0;
3839

3940
for (let i = 0; i < 100; i += 1) {
4041
wrapper.find('button').simulate('click');
41-
expect(renderTime).toEqual(1);
42+
expect(reRenderTime).toEqual(0);
4243
}
4344
});
4445
});

tests/FixedColumn-IE.spec.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
import { act } from 'react-dom/test-utils';
4+
import { spyElementPrototype } from 'rc-util/lib/test/domHook';
5+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
6+
import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker';
7+
import Table from '../src';
8+
9+
jest.mock('rc-util/lib/Dom/styleChecker', () => {
10+
return {
11+
isStyleSupport: (name, val) => val !== 'sticky',
12+
};
13+
});
14+
15+
describe('Table.FixedColumn', () => {
16+
let domSpy;
17+
18+
beforeAll(() => {
19+
domSpy = spyElementPrototype(HTMLElement, 'offsetParent', {
20+
get: () => ({}),
21+
});
22+
});
23+
24+
afterAll(() => {
25+
domSpy.mockRestore();
26+
});
27+
28+
const columns = [
29+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' },
30+
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' },
31+
{ title: 'title3', dataIndex: 'c', key: 'c' },
32+
{ title: 'title4', dataIndex: 'b', key: 'd' },
33+
{ title: 'title5', dataIndex: 'b', key: 'e' },
34+
{ title: 'title6', dataIndex: 'b', key: 'f' },
35+
{ title: 'title7', dataIndex: 'b', key: 'g' },
36+
{ title: 'title8', dataIndex: 'b', key: 'h' },
37+
{ title: 'title9', dataIndex: 'b', key: 'i' },
38+
{ title: 'title10', dataIndex: 'b', key: 'j' },
39+
{ title: 'title11', dataIndex: 'b', key: 'k' },
40+
{ title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' },
41+
];
42+
const data = [{ a: '123', b: 'xxxxxxxx', d: 3, key: '1' }];
43+
44+
it('not sticky', async () => {
45+
jest.useFakeTimers();
46+
const wrapper = mount(<Table columns={columns} data={data} scroll={{ x: 1200 }} />);
47+
48+
act(() => {
49+
wrapper.find('table ResizeObserver').first().props().onResize({ width: 93, offsetWidth: 93 });
50+
});
51+
52+
await act(async () => {
53+
jest.runAllTimers();
54+
await Promise.resolve();
55+
wrapper.update();
56+
});
57+
58+
expect(wrapper.exists('.rc-table-cell-fix-left')).toBeFalsy();
59+
expect(wrapper.exists('.rc-table-cell-fix-right')).toBeFalsy();
60+
});
61+
});

0 commit comments

Comments
 (0)