Skip to content

Commit 66db52a

Browse files
committed
feat: support renderRest
1 parent 202ee82 commit 66db52a

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

examples/basic.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,20 @@ function renderItem(item: ItemType) {
3131
);
3232
}
3333

34+
function renderRest(items: ItemType[]) {
35+
return (
36+
<div
37+
style={{
38+
margin: '0 16px 0 8px',
39+
padding: '4px 8px',
40+
background: 'rgba(255, 0, 0, 0.2)',
41+
}}
42+
>
43+
+{items.length}...
44+
</div>
45+
);
46+
}
47+
3448
const Demo = () => {
3549
const [responsive, setResponsive] = React.useState(false);
3650
const [data, setData] = React.useState(createData(5));
@@ -72,6 +86,7 @@ const Demo = () => {
7286
<Overflow<ItemType>
7387
data={data}
7488
renderItem={renderItem}
89+
renderRest={renderRest}
7590
maxCount={responsive ? 'responsive' : 6}
7691
/>
7792
</div>

src/Overflow.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ export interface OverflowProps<ItemType> {
1616
itemWidth?: number;
1717
renderItem?: (item: ItemType) => React.ReactNode;
1818
maxCount?: number | typeof RESPONSIVE;
19+
renderRest?:
20+
| React.ReactNode
21+
| ((omittedItems: ItemType[]) => React.ReactNode);
22+
}
23+
24+
function defaultRenderRest<ItemType>(omittedItems: ItemType[]) {
25+
return `+ ${omittedItems.length} ...`;
1926
}
2027

2128
function Overflow<ItemType = any>(
@@ -31,6 +38,7 @@ function Overflow<ItemType = any>(
3138
style,
3239
className,
3340
maxCount,
41+
renderRest = defaultRenderRest,
3442
} = props;
3543

3644
const createUseState = useBatchFrameState();
@@ -50,11 +58,17 @@ function Overflow<ItemType = any>(
5058
// ================================= Data =================================
5159
const isResponsive = maxCount === RESPONSIVE;
5260

53-
const mergedData = React.useMemo(() => {
61+
const [visibleItems, omittedItems] = React.useMemo(() => {
62+
const len = data.length;
63+
let items = data;
64+
5465
if (isResponsive) {
55-
return data.slice(0, Math.min(data.length, containerWidth / itemWidth));
66+
items = data.slice(0, Math.min(len, containerWidth / itemWidth));
67+
} else if (typeof maxCount === 'number') {
68+
items = data.slice(0, maxCount);
5669
}
57-
return typeof maxCount === 'number' ? data.slice(0, maxCount) : data;
70+
71+
return [items, data.slice(items.length, len)];
5872
}, [data, itemWidth, containerWidth, maxCount]);
5973

6074
// When is `responsive`, we will always render rest node to get the real width of it for calculation
@@ -107,13 +121,13 @@ function Overflow<ItemType = any>(
107121

108122
// ================================ Effect ================================
109123
React.useLayoutEffect(() => {
110-
if (containerWidth && restWidth && mergedData) {
124+
if (containerWidth && restWidth && visibleItems) {
111125
let totalWidth = 0;
112126

113-
const len = mergedData.length;
127+
const len = visibleItems.length;
114128

115129
for (let i = 0; i < len; i += 1) {
116-
const currentItemWidth = itemWidths.get(getKey(mergedData[i], i));
130+
const currentItemWidth = itemWidths.get(getKey(visibleItems[i], i));
117131

118132
// Break since data not ready
119133
if (currentItemWidth === undefined) {
@@ -133,12 +147,12 @@ function Overflow<ItemType = any>(
133147
}
134148
}
135149
}
136-
}, [containerWidth, itemWidths, restWidth, getKey, mergedData]);
150+
}, [containerWidth, itemWidths, restWidth, getKey, visibleItems]);
137151

138152
// ================================ Render ================================
139153
let overflowNode = (
140154
<div className={classNames(prefixCls, className)} style={style} ref={ref}>
141-
{mergedData.map((item, index) => {
155+
{visibleItems.map((item, index) => {
142156
const key = getKey(item, index);
143157

144158
return (
@@ -166,7 +180,9 @@ function Overflow<ItemType = any>(
166180
registerSize={registerOverflowSize}
167181
display={restReady && displayCount < data.length}
168182
>
169-
Overflow
183+
{typeof renderRest === 'function'
184+
? renderRest(omittedItems)
185+
: renderRest}
170186
</Item>
171187
) : null}
172188
</div>

0 commit comments

Comments
 (0)