Skip to content

Commit fe45eb5

Browse files
committed
feat: Add ssr support
1 parent 694fd7a commit fe45eb5

File tree

4 files changed

+92
-8
lines changed

4 files changed

+92
-8
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"devDependencies": {
5252
"@types/classnames": "^2.2.9",
5353
"@types/enzyme": "^3.10.8",
54-
"@types/jest": "^26.0.18",
54+
"@types/jest": "^26.0.23",
5555
"@types/react": "^16.14.2",
5656
"@types/react-dom": "^16.9.10",
5757
"@umijs/fabric": "^2.0.8",

src/Overflow.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ export interface OverflowProps<ItemType> extends React.HTMLAttributes<any> {
5555

5656
/** @private This API may be refactor since not well design */
5757
onVisibleChange?: (visibleCount: number) => void;
58+
59+
/** When set to `full`, ssr will render full items by default and remove at client side */
60+
ssr?: 'full';
5861
}
5962

6063
function defaultRenderRest<ItemType>(omittedItems: ItemType[]) {
@@ -72,6 +75,7 @@ function Overflow<ItemType = any>(
7275
renderRawItem,
7376
itemKey,
7477
itemWidth = 10,
78+
ssr,
7579
style,
7680
className,
7781
maxCount,
@@ -86,7 +90,9 @@ function Overflow<ItemType = any>(
8690

8791
const createUseState = useBatchFrameState();
8892

89-
const [containerWidth, setContainerWidth] = createUseState(0);
93+
const [containerWidth, setContainerWidth] = createUseState<number>(null);
94+
const mergedContainerWidth = containerWidth || 0;
95+
9096
const [itemWidths, setItemWidths] = createUseState(
9197
new Map<React.Key, number>(),
9298
);
@@ -119,7 +125,14 @@ function Overflow<ItemType = any>(
119125
let items = data;
120126

121127
if (isResponsive) {
122-
items = data.slice(0, Math.min(data.length, containerWidth / itemWidth));
128+
if (containerWidth === null && ssr === 'full') {
129+
items = data;
130+
} else {
131+
items = data.slice(
132+
0,
133+
Math.min(data.length, mergedContainerWidth / itemWidth),
134+
);
135+
}
123136
} else if (typeof maxCount === 'number') {
124137
items = data.slice(0, maxCount);
125138
}
@@ -192,7 +205,7 @@ function Overflow<ItemType = any>(
192205
}
193206

194207
React.useLayoutEffect(() => {
195-
if (containerWidth && mergedRestWidth && mergedData) {
208+
if (mergedContainerWidth && mergedRestWidth && mergedData) {
196209
let totalWidth = suffixWidth;
197210

198211
const len = mergedData.length;
@@ -219,13 +232,13 @@ function Overflow<ItemType = any>(
219232

220233
if (
221234
i === lastIndex - 1 &&
222-
totalWidth + getItemWidth(lastIndex)! <= containerWidth
235+
totalWidth + getItemWidth(lastIndex)! <= mergedContainerWidth
223236
) {
224237
// Additional check if match the end
225238
updateDisplayCount(lastIndex);
226239
setSuffixFixedStart(null);
227240
break;
228-
} else if (totalWidth + mergedRestWidth > containerWidth) {
241+
} else if (totalWidth + mergedRestWidth > mergedContainerWidth) {
229242
// Can not hold all the content to show rest
230243
updateDisplayCount(i - 1);
231244
setSuffixFixedStart(
@@ -240,11 +253,18 @@ function Overflow<ItemType = any>(
240253
}
241254
}
242255

243-
if (suffix && getItemWidth(0) + suffixWidth > containerWidth) {
256+
if (suffix && getItemWidth(0) + suffixWidth > mergedContainerWidth) {
244257
setSuffixFixedStart(null);
245258
}
246259
}
247-
}, [containerWidth, itemWidths, restWidth, suffixWidth, getKey, mergedData]);
260+
}, [
261+
mergedContainerWidth,
262+
itemWidths,
263+
restWidth,
264+
suffixWidth,
265+
getKey,
266+
mergedData,
267+
]);
248268

249269
// ================================ Render ================================
250270
const displayRest = restReady && !!omittedItems.length;

tests/__snapshots__/ssr.spec.tsx.snap

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Overflow.SSR basic 1`] = `
4+
<div
5+
class="rc-overflow"
6+
>
7+
<div
8+
class="rc-overflow-item"
9+
style="opacity:1;order:0"
10+
>
11+
Label 0
12+
</div>
13+
<div
14+
aria-hidden="true"
15+
class="rc-overflow-item rc-overflow-item-rest"
16+
style="opacity:0;height:0;overflow-y:hidden;order:9007199254740991;pointer-events:none"
17+
>
18+
+ 0 ...
19+
</div>
20+
</div>
21+
`;

tests/ssr.spec.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import { render } from 'enzyme';
3+
import { act } from 'react-dom/test-utils';
4+
import Overflow from '../src';
5+
6+
interface ItemType {
7+
label: React.ReactNode;
8+
key: React.Key;
9+
}
10+
11+
function renderItem(item: ItemType) {
12+
return item.label;
13+
}
14+
15+
describe('Overflow.SSR', () => {
16+
function getData(count: number) {
17+
return new Array(count).fill(undefined).map((_, index) => ({
18+
label: `Label ${index}`,
19+
key: `k-${index}`,
20+
}));
21+
}
22+
23+
beforeEach(() => {
24+
jest.useFakeTimers();
25+
});
26+
27+
afterEach(() => {
28+
jest.useRealTimers();
29+
});
30+
31+
it('basic', () => {
32+
const wrapper = render(
33+
<Overflow<ItemType>
34+
data={getData(1)}
35+
renderItem={renderItem}
36+
maxCount="responsive"
37+
ssr="full"
38+
/>,
39+
);
40+
41+
expect(wrapper).toMatchSnapshot();
42+
});
43+
});

0 commit comments

Comments
 (0)