Skip to content

Commit b4bc3f7

Browse files
author
刘欢
committed
feat: scrollTo add align
1 parent 45f97df commit b4bc3f7

9 files changed

Lines changed: 234 additions & 97 deletions

File tree

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,25 @@ React.render(<Table columns={columns} data={data} />, mountNode);
119119
| summary | (data: readonly RecordType[]) => React.ReactNode | - | `summary` attribute in `table` component is used to define the summary row. |
120120
| rowHoverable | boolean | true | Table hover interaction |
121121

122+
### Methods
123+
124+
#### scrollTo
125+
126+
Table 组件暴露 `scrollTo` 方法用于滚动到指定位置:
127+
128+
```js
129+
const tblRef = useRef();
130+
tblRef.current?.scrollTo({ key: 'rowKey', align: 'start' });
131+
```
132+
133+
| Name | Type | Default | Description |
134+
| --- | --- | --- | --- |
135+
| index | number | - | Row index to scroll to |
136+
| top | number | - | Scroll to specific top position (in px) |
137+
| key | string | - | Scroll to row by row key |
138+
| offset | number | - | Additional offset from target position |
139+
| align | `start` \| `center` \| `end` \| `nearest` | `nearest` | Alignment of the target element within the scroll container. `start` aligns to top, `center` to middle, `end` to bottom, `nearest` automatically chooses the closest alignment |
140+
122141
## Column Props
123142
124143
| Name | Type | Default | Description |

docs/examples/scrollY.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,36 @@ const Test = () => {
8888
>
8989
Scroll To Key 6 + Offset -10
9090
</button>
91+
<button
92+
onClick={() => {
93+
tblRef.current?.scrollTo({
94+
key: 9,
95+
align: 'start',
96+
});
97+
}}
98+
>
99+
Scroll To key 9 (align: start)
100+
</button>
101+
<button
102+
onClick={() => {
103+
tblRef.current?.scrollTo({
104+
key: 9,
105+
align: 'center',
106+
});
107+
}}
108+
>
109+
Scroll To key 9 (align: center)
110+
</button>
111+
<button
112+
onClick={() => {
113+
tblRef.current?.scrollTo({
114+
key: 9,
115+
align: 'end',
116+
});
117+
}}
118+
>
119+
Scroll To key 9 (align: end)
120+
</button>
91121
<Table
92122
ref={tblRef}
93123
columns={columns}

src/Table.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ const EMPTY_SCROLL_TARGET = {};
8888
export type SemanticName = 'section' | 'title' | 'footer' | 'content';
8989
export type ComponentsSemantic = 'wrapper' | 'cell' | 'row';
9090

91-
export interface TableProps<RecordType = any>
92-
extends Omit<LegacyExpandableProps<RecordType>, 'showExpandColumn'> {
91+
export interface TableProps<RecordType = any> extends Omit<
92+
LegacyExpandableProps<RecordType>,
93+
'showExpandColumn'
94+
> {
9395
prefixCls?: string;
9496
className?: string;
9597
style?: React.CSSProperties;
@@ -349,7 +351,7 @@ const Table = <RecordType extends DefaultRecordType>(
349351
scrollTo: config => {
350352
if (scrollBodyRef.current instanceof HTMLElement) {
351353
// Native scroll
352-
const { index, top, key, offset } = config;
354+
const { index, top, key, offset, align = 'nearest' } = config;
353355

354356
if (validNumberValue(top)) {
355357
// In top mode, offset is ignored
@@ -361,12 +363,21 @@ const Table = <RecordType extends DefaultRecordType>(
361363
);
362364
if (targetElement) {
363365
if (!offset) {
364-
// No offset, use scrollIntoView for default behavior
365-
targetElement.scrollIntoView();
366+
targetElement.scrollIntoView({ block: align });
366367
} else {
367-
// With offset, use element's offsetTop + offset
368+
const container = scrollBodyRef.current;
368369
const elementTop = (targetElement as HTMLElement).offsetTop;
369-
scrollBodyRef.current.scrollTo({ top: elementTop + offset });
370+
const elementHeight = (targetElement as HTMLElement).offsetHeight;
371+
const containerHeight = container.clientHeight;
372+
373+
const alignMap: Record<string, number> = {
374+
start: elementTop,
375+
end: elementTop + elementHeight - containerHeight,
376+
center: elementTop + (elementHeight - containerHeight) / 2,
377+
nearest: elementTop,
378+
};
379+
const targetTop = alignMap[align] ?? elementTop;
380+
container.scrollTo({ top: targetTop + offset });
370381
}
371382
}
372383
}

src/interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ export type ScrollConfig = {
4343
* When offset is set, the target element will always be aligned to the top of the container.
4444
*/
4545
offset?: number;
46+
47+
align?: ScrollLogicalPosition;
4648
};
4749

4850
export type Reference = {

tests/__snapshots__/ExpandRow.spec.jsx.snap

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ exports[`Table.Expand > does not crash if scroll is not set 1`] = `
129129
<tr>
130130
<th
131131
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
132-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
132+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
133133
/>
134134
<th
135135
class="rc-table-cell"
@@ -202,7 +202,7 @@ exports[`Table.Expand > does not crash if scroll is not set 1`] = `
202202
>
203203
<td
204204
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
205-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
205+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
206206
>
207207
<span
208208
class="rc-table-row-expand-icon rc-table-row-collapsed"
@@ -230,7 +230,7 @@ exports[`Table.Expand > does not crash if scroll is not set 1`] = `
230230
>
231231
<td
232232
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
233-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
233+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
234234
>
235235
<span
236236
class="rc-table-row-expand-icon rc-table-row-collapsed"
@@ -284,7 +284,7 @@ exports[`Table.Expand > does not crash if scroll is not set 2`] = `
284284
<tr>
285285
<th
286286
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
287-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
287+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
288288
/>
289289
<th
290290
class="rc-table-cell"
@@ -357,7 +357,7 @@ exports[`Table.Expand > does not crash if scroll is not set 2`] = `
357357
>
358358
<td
359359
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
360-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
360+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
361361
>
362362
<span
363363
class="rc-table-row-expand-icon rc-table-row-collapsed"
@@ -385,7 +385,7 @@ exports[`Table.Expand > does not crash if scroll is not set 2`] = `
385385
>
386386
<td
387387
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
388-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
388+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
389389
>
390390
<span
391391
class="rc-table-row-expand-icon rc-table-row-collapsed"
@@ -525,12 +525,12 @@ exports[`Table.Expand > renders fixed column correctly > work 1`] = `
525525
<tr>
526526
<th
527527
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start"
528-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
528+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
529529
/>
530530
<th
531531
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
532532
scope="col"
533-
style="inset-inline-start: 0; --z-offset: 7; --z-offset-reverse: 5;"
533+
style="inset-inline-start: 0px; --z-offset: 7; --z-offset-reverse: 5;"
534534
>
535535
Name
536536
</th>
@@ -543,7 +543,7 @@ exports[`Table.Expand > renders fixed column correctly > work 1`] = `
543543
<th
544544
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-end rc-table-cell-fix-end-shadow"
545545
scope="col"
546-
style="inset-inline-end: 0; --z-offset: 3; --z-offset-reverse: 1;"
546+
style="inset-inline-end: 0px; --z-offset: 3; --z-offset-reverse: 1;"
547547
>
548548
Gender
549549
</th>
@@ -600,15 +600,15 @@ exports[`Table.Expand > renders fixed column correctly > work 1`] = `
600600
>
601601
<td
602602
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start"
603-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
603+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
604604
>
605605
<span
606606
class="rc-table-row-expand-icon rc-table-row-expanded"
607607
/>
608608
</td>
609609
<td
610610
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
611-
style="inset-inline-start: 0; --z-offset: 7; --z-offset-reverse: 5;"
611+
style="inset-inline-start: 0px; --z-offset: 7; --z-offset-reverse: 5;"
612612
>
613613
Lucy
614614
</td>
@@ -619,7 +619,7 @@ exports[`Table.Expand > renders fixed column correctly > work 1`] = `
619619
</td>
620620
<td
621621
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-end rc-table-cell-fix-end-shadow"
622-
style="inset-inline-end: 0; --z-offset: 3; --z-offset-reverse: 1;"
622+
style="inset-inline-end: 0px; --z-offset: 3; --z-offset-reverse: 1;"
623623
>
624624
F
625625
</td>
@@ -647,15 +647,15 @@ exports[`Table.Expand > renders fixed column correctly > work 1`] = `
647647
>
648648
<td
649649
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start"
650-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
650+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
651651
>
652652
<span
653653
class="rc-table-row-expand-icon rc-table-row-expanded"
654654
/>
655655
</td>
656656
<td
657657
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
658-
style="inset-inline-start: 0; --z-offset: 7; --z-offset-reverse: 5;"
658+
style="inset-inline-start: 0px; --z-offset: 7; --z-offset-reverse: 5;"
659659
>
660660
Jack
661661
</td>
@@ -666,7 +666,7 @@ exports[`Table.Expand > renders fixed column correctly > work 1`] = `
666666
</td>
667667
<td
668668
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-end rc-table-cell-fix-end-shadow"
669-
style="inset-inline-end: 0; --z-offset: 3; --z-offset-reverse: 1;"
669+
style="inset-inline-end: 0px; --z-offset: 3; --z-offset-reverse: 1;"
670670
>
671671
M
672672
</td>
@@ -991,7 +991,7 @@ exports[`Table.Expand > work in expandable fix 1`] = `
991991
<tr>
992992
<th
993993
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
994-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
994+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
995995
/>
996996
<th
997997
class="rc-table-cell"
@@ -1064,7 +1064,7 @@ exports[`Table.Expand > work in expandable fix 1`] = `
10641064
>
10651065
<td
10661066
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
1067-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
1067+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
10681068
>
10691069
<span
10701070
class="rc-table-row-expand-icon rc-table-row-collapsed"
@@ -1092,7 +1092,7 @@ exports[`Table.Expand > work in expandable fix 1`] = `
10921092
>
10931093
<td
10941094
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
1095-
style="inset-inline-start: 0; --z-offset: 8; --z-offset-reverse: 4;"
1095+
style="inset-inline-start: 0px; --z-offset: 8; --z-offset-reverse: 4;"
10961096
>
10971097
<span
10981098
class="rc-table-row-expand-icon rc-table-row-collapsed"
@@ -1167,7 +1167,7 @@ exports[`Table.Expand > work in expandable fix 2`] = `
11671167
</th>
11681168
<th
11691169
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
1170-
style="inset-inline-start: 0; --z-offset: 5; --z-offset-reverse: 7;"
1170+
style="inset-inline-start: 0px; --z-offset: 5; --z-offset-reverse: 7;"
11711171
/>
11721172
</tr>
11731173
</thead>
@@ -1237,7 +1237,7 @@ exports[`Table.Expand > work in expandable fix 2`] = `
12371237
</td>
12381238
<td
12391239
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
1240-
style="inset-inline-start: 0; --z-offset: 5; --z-offset-reverse: 7;"
1240+
style="inset-inline-start: 0px; --z-offset: 5; --z-offset-reverse: 7;"
12411241
>
12421242
<span
12431243
class="rc-table-row-expand-icon rc-table-row-collapsed"
@@ -1265,7 +1265,7 @@ exports[`Table.Expand > work in expandable fix 2`] = `
12651265
</td>
12661266
<td
12671267
class="rc-table-cell rc-table-row-expand-icon-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow"
1268-
style="inset-inline-start: 0; --z-offset: 5; --z-offset-reverse: 7;"
1268+
style="inset-inline-start: 0px; --z-offset: 5; --z-offset-reverse: 7;"
12691269
>
12701270
<span
12711271
class="rc-table-row-expand-icon rc-table-row-collapsed"

0 commit comments

Comments
 (0)