Skip to content

Commit 357e5f3

Browse files
authored
refactor: move hover & expand into hooks (#921)
* chore: hover with hooks * chore: useExpand
1 parent 0cd01d3 commit 357e5f3

File tree

5 files changed

+364
-284
lines changed

5 files changed

+364
-284
lines changed

src/FixedHolder/index.tsx

Lines changed: 128 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import { useContext } from '@rc-component/context';
12
import classNames from 'classnames';
23
import { fillRef } from 'rc-util/lib/ref';
34
import * as React from 'react';
45
import { useMemo } from 'react';
56
import ColGroup from '../ColGroup';
67
import TableContext from '../context/TableContext';
7-
import { useContext } from '@rc-component/context';
88
import type { HeaderProps } from '../Header/Header';
9+
import useRenderTimes from '../hooks/useRenderTimes';
910
import type { ColumnsType, ColumnType } from '../interface';
1011

1112
function useColumnWidth(colWidths: readonly number[], columCount: number) {
@@ -38,138 +39,137 @@ export interface FixedHeaderProps<RecordType> extends HeaderProps<RecordType> {
3839
children: (info: HeaderProps<RecordType>) => React.ReactNode;
3940
}
4041

41-
const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<unknown>>(
42-
(
43-
{
44-
className,
45-
noData,
46-
columns,
47-
flattenColumns,
48-
colWidths,
49-
columCount,
50-
stickyOffsets,
51-
direction,
52-
fixHeader,
53-
stickyTopOffset,
54-
stickyBottomOffset,
55-
stickyClassName,
56-
onScroll,
57-
maxContentScroll,
58-
children,
59-
...props
60-
},
61-
ref,
62-
) => {
63-
const { prefixCls, scrollbarSize, isSticky } = useContext(TableContext, [
64-
'prefixCls',
65-
'scrollbarSize',
66-
'isSticky',
67-
]);
68-
69-
const combinationScrollBarSize = isSticky && !fixHeader ? 0 : scrollbarSize;
70-
71-
// Pass wheel to scroll event
72-
const scrollRef = React.useRef<HTMLDivElement>(null);
73-
74-
const setScrollRef = React.useCallback((element: HTMLElement) => {
75-
fillRef(ref, element);
76-
fillRef(scrollRef, element);
77-
}, []);
78-
79-
React.useEffect(() => {
80-
function onWheel(e: WheelEvent) {
81-
const { currentTarget, deltaX } = e as unknown as React.WheelEvent<HTMLDivElement>;
82-
if (deltaX) {
83-
onScroll({ currentTarget, scrollLeft: currentTarget.scrollLeft + deltaX });
84-
e.preventDefault();
85-
}
42+
const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<unknown>>((props, ref) => {
43+
useRenderTimes(props);
44+
45+
const {
46+
className,
47+
noData,
48+
columns,
49+
flattenColumns,
50+
colWidths,
51+
columCount,
52+
stickyOffsets,
53+
direction,
54+
fixHeader,
55+
stickyTopOffset,
56+
stickyBottomOffset,
57+
stickyClassName,
58+
onScroll,
59+
maxContentScroll,
60+
children,
61+
...restProps
62+
} = props;
63+
64+
const { prefixCls, scrollbarSize, isSticky } = useContext(TableContext, [
65+
'prefixCls',
66+
'scrollbarSize',
67+
'isSticky',
68+
]);
69+
70+
const combinationScrollBarSize = isSticky && !fixHeader ? 0 : scrollbarSize;
71+
72+
// Pass wheel to scroll event
73+
const scrollRef = React.useRef<HTMLDivElement>(null);
74+
75+
const setScrollRef = React.useCallback((element: HTMLElement) => {
76+
fillRef(ref, element);
77+
fillRef(scrollRef, element);
78+
}, []);
79+
80+
React.useEffect(() => {
81+
function onWheel(e: WheelEvent) {
82+
const { currentTarget, deltaX } = e as unknown as React.WheelEvent<HTMLDivElement>;
83+
if (deltaX) {
84+
onScroll({ currentTarget, scrollLeft: currentTarget.scrollLeft + deltaX });
85+
e.preventDefault();
8686
}
87-
scrollRef.current?.addEventListener('wheel', onWheel);
88-
89-
return () => {
90-
scrollRef.current?.removeEventListener('wheel', onWheel);
91-
};
92-
}, []);
93-
94-
// Check if all flattenColumns has width
95-
const allFlattenColumnsWithWidth = React.useMemo(
96-
() => flattenColumns.every(column => column.width >= 0),
97-
[flattenColumns],
98-
);
99-
100-
// Add scrollbar column
101-
const lastColumn = flattenColumns[flattenColumns.length - 1];
102-
const ScrollBarColumn: ColumnType<unknown> & { scrollbar: true } = {
103-
fixed: lastColumn ? lastColumn.fixed : null,
104-
scrollbar: true,
105-
onHeaderCell: () => ({
106-
className: `${prefixCls}-cell-scrollbar`,
107-
}),
108-
};
87+
}
88+
scrollRef.current?.addEventListener('wheel', onWheel);
10989

110-
const columnsWithScrollbar = useMemo<ColumnsType<unknown>>(
111-
() => (combinationScrollBarSize ? [...columns, ScrollBarColumn] : columns),
112-
[combinationScrollBarSize, columns],
113-
);
114-
115-
const flattenColumnsWithScrollbar = useMemo(
116-
() => (combinationScrollBarSize ? [...flattenColumns, ScrollBarColumn] : flattenColumns),
117-
[combinationScrollBarSize, flattenColumns],
118-
);
119-
120-
// Calculate the sticky offsets
121-
const headerStickyOffsets = useMemo(() => {
122-
const { right, left } = stickyOffsets;
123-
return {
124-
...stickyOffsets,
125-
left:
126-
direction === 'rtl' ? [...left.map(width => width + combinationScrollBarSize), 0] : left,
127-
right:
128-
direction === 'rtl'
129-
? right
130-
: [...right.map(width => width + combinationScrollBarSize), 0],
131-
isSticky,
132-
};
133-
}, [combinationScrollBarSize, stickyOffsets, isSticky]);
134-
135-
const mergedColumnWidth = useColumnWidth(colWidths, columCount);
136-
137-
return (
138-
<div
90+
return () => {
91+
scrollRef.current?.removeEventListener('wheel', onWheel);
92+
};
93+
}, []);
94+
95+
// Check if all flattenColumns has width
96+
const allFlattenColumnsWithWidth = React.useMemo(
97+
() => flattenColumns.every(column => column.width >= 0),
98+
[flattenColumns],
99+
);
100+
101+
// Add scrollbar column
102+
const lastColumn = flattenColumns[flattenColumns.length - 1];
103+
const ScrollBarColumn: ColumnType<unknown> & { scrollbar: true } = {
104+
fixed: lastColumn ? lastColumn.fixed : null,
105+
scrollbar: true,
106+
onHeaderCell: () => ({
107+
className: `${prefixCls}-cell-scrollbar`,
108+
}),
109+
};
110+
111+
const columnsWithScrollbar = useMemo<ColumnsType<unknown>>(
112+
() => (combinationScrollBarSize ? [...columns, ScrollBarColumn] : columns),
113+
[combinationScrollBarSize, columns],
114+
);
115+
116+
const flattenColumnsWithScrollbar = useMemo(
117+
() => (combinationScrollBarSize ? [...flattenColumns, ScrollBarColumn] : flattenColumns),
118+
[combinationScrollBarSize, flattenColumns],
119+
);
120+
121+
// Calculate the sticky offsets
122+
const headerStickyOffsets = useMemo(() => {
123+
const { right, left } = stickyOffsets;
124+
return {
125+
...stickyOffsets,
126+
left:
127+
direction === 'rtl' ? [...left.map(width => width + combinationScrollBarSize), 0] : left,
128+
right:
129+
direction === 'rtl' ? right : [...right.map(width => width + combinationScrollBarSize), 0],
130+
isSticky,
131+
};
132+
}, [combinationScrollBarSize, stickyOffsets, isSticky]);
133+
134+
const mergedColumnWidth = useColumnWidth(colWidths, columCount);
135+
136+
return (
137+
<div
138+
style={{
139+
overflow: 'hidden',
140+
...(isSticky ? { top: stickyTopOffset, bottom: stickyBottomOffset } : {}),
141+
}}
142+
ref={setScrollRef}
143+
className={classNames(className, {
144+
[stickyClassName]: !!stickyClassName,
145+
})}
146+
>
147+
<table
139148
style={{
140-
overflow: 'hidden',
141-
...(isSticky ? { top: stickyTopOffset, bottom: stickyBottomOffset } : {}),
149+
tableLayout: 'fixed',
150+
visibility: noData || mergedColumnWidth ? null : 'hidden',
142151
}}
143-
ref={setScrollRef}
144-
className={classNames(className, {
145-
[stickyClassName]: !!stickyClassName,
146-
})}
147152
>
148-
<table
149-
style={{
150-
tableLayout: 'fixed',
151-
visibility: noData || mergedColumnWidth ? null : 'hidden',
152-
}}
153-
>
154-
{(!noData || !maxContentScroll || allFlattenColumnsWithWidth) && (
155-
<ColGroup
156-
colWidths={mergedColumnWidth ? [...mergedColumnWidth, combinationScrollBarSize] : []}
157-
columCount={columCount + 1}
158-
columns={flattenColumnsWithScrollbar}
159-
/>
160-
)}
161-
{children({
162-
...props,
163-
stickyOffsets: headerStickyOffsets,
164-
columns: columnsWithScrollbar,
165-
flattenColumns: flattenColumnsWithScrollbar,
166-
})}
167-
</table>
168-
</div>
169-
);
170-
},
171-
);
153+
{(!noData || !maxContentScroll || allFlattenColumnsWithWidth) && (
154+
<ColGroup
155+
colWidths={mergedColumnWidth ? [...mergedColumnWidth, combinationScrollBarSize] : []}
156+
columCount={columCount + 1}
157+
columns={flattenColumnsWithScrollbar}
158+
/>
159+
)}
160+
{children({
161+
...restProps,
162+
stickyOffsets: headerStickyOffsets,
163+
columns: columnsWithScrollbar,
164+
flattenColumns: flattenColumnsWithScrollbar,
165+
})}
166+
</table>
167+
</div>
168+
);
169+
});
172170

173171
FixedHolder.displayName = 'FixedHolder';
174172

175-
export default FixedHolder;
173+
/** Return a table in div as fixed element which contains sticky info */
174+
// export default responseImmutable(FixedHolder);
175+
export default React.memo(FixedHolder);

0 commit comments

Comments
 (0)