@@ -20,6 +20,7 @@ export interface OverflowProps<ItemType> {
20
20
renderRest ?:
21
21
| React . ReactNode
22
22
| ( ( omittedItems : ItemType [ ] ) => React . ReactNode ) ;
23
+ suffix ?: React . ReactNode ;
23
24
}
24
25
25
26
function defaultRenderRest < ItemType > ( omittedItems : ItemType [ ] ) {
@@ -40,6 +41,7 @@ function Overflow<ItemType = any>(
40
41
className,
41
42
maxCount,
42
43
renderRest = defaultRenderRest ,
44
+ suffix,
43
45
} = props ;
44
46
45
47
const createUseState = useBatchFrameState ( ) ;
@@ -51,14 +53,18 @@ function Overflow<ItemType = any>(
51
53
52
54
const [ prevRestWidth , setPrevRestWidth ] = createUseState ( 0 ) ;
53
55
const [ restWidth , setRestWidth ] = createUseState ( 0 ) ;
54
- // Always use the max width to avoid blink
55
- const mergedRestWidth = Math . max ( prevRestWidth , restWidth ) ;
56
+
57
+ const [ suffixWidth , setSuffixWidth ] = createUseState ( 0 ) ;
58
+ const [ suffixFixedStart , setSuffixFixedStart ] = useState < number > ( null ) ;
56
59
57
60
const [ displayCount , setDisplayCount ] = useState ( 0 ) ;
58
61
const [ restReady , setRestReady ] = useState ( false ) ;
59
62
60
63
const itemPrefixCls = `${ prefixCls } -item` ;
61
64
65
+ // Always use the max width to avoid blink
66
+ const mergedRestWidth = Math . max ( prevRestWidth , restWidth ) ;
67
+
62
68
// ================================= Data =================================
63
69
const isResponsive = maxCount === RESPONSIVE ;
64
70
@@ -132,14 +138,18 @@ function Overflow<ItemType = any>(
132
138
setPrevRestWidth ( restWidth ) ;
133
139
}
134
140
141
+ function registerSuffixSize ( _ : React . Key , width : number | null ) {
142
+ setSuffixWidth ( width ! ) ;
143
+ }
144
+
135
145
// ================================ Effect ================================
136
146
function getItemWidth ( index : number ) {
137
147
return itemWidths . get ( getKey ( mergedData [ index ] , index ) ) ;
138
148
}
139
149
140
150
React . useLayoutEffect ( ( ) => {
141
151
if ( containerWidth && mergedRestWidth && mergedData ) {
142
- let totalWidth = 0 ;
152
+ let totalWidth = suffixWidth ;
143
153
144
154
const len = mergedData . length ;
145
155
const lastIndex = len - 1 ;
@@ -162,21 +172,48 @@ function Overflow<ItemType = any>(
162
172
) {
163
173
// Additional check if match the end
164
174
updateDisplayCount ( lastIndex ) ;
175
+ setSuffixFixedStart ( null ) ;
165
176
break ;
166
177
} else if ( totalWidth + mergedRestWidth > containerWidth ) {
167
178
// Can not hold all the content to show rest
168
179
updateDisplayCount ( i - 1 ) ;
180
+ setSuffixFixedStart (
181
+ totalWidth - currentItemWidth - suffixWidth + mergedRestWidth ,
182
+ ) ;
169
183
break ;
170
184
} else if ( i === lastIndex ) {
171
185
// Reach the end
172
186
updateDisplayCount ( lastIndex ) ;
187
+ setSuffixFixedStart ( totalWidth - suffixWidth ) ;
173
188
break ;
174
189
}
175
190
}
191
+
192
+ if ( suffix && getItemWidth ( 0 ) + suffixWidth > containerWidth ) {
193
+ setSuffixFixedStart ( null ) ;
194
+ }
176
195
}
177
- } , [ containerWidth , itemWidths , mergedRestWidth , getKey , mergedData ] ) ;
196
+ } , [
197
+ containerWidth ,
198
+ itemWidths ,
199
+ mergedRestWidth ,
200
+ suffixWidth ,
201
+ getKey ,
202
+ mergedData ,
203
+ ] ) ;
178
204
179
205
// ================================ Render ================================
206
+ const displayRest = restReady && ! ! omittedItems . length ;
207
+
208
+ let suffixStyle : React . CSSProperties = { } ;
209
+ if ( suffixFixedStart !== null && isResponsive ) {
210
+ suffixStyle = {
211
+ position : 'absolute' ,
212
+ left : suffixFixedStart ,
213
+ top : 0 ,
214
+ } ;
215
+ }
216
+
180
217
let overflowNode = (
181
218
< div className = { classNames ( prefixCls , className ) } style = { style } ref = { ref } >
182
219
{ mergedData . map ( ( item , index ) => {
@@ -200,18 +237,33 @@ function Overflow<ItemType = any>(
200
237
{ /* Rest Count Item */ }
201
238
{ showRest ? (
202
239
< Item
203
- order = { displayCount }
240
+ order = { displayRest ? displayCount : mergedData . length }
204
241
prefixCls = { itemPrefixCls }
205
242
className = { `${ itemPrefixCls } -rest` }
206
243
responsive = { isResponsive }
207
244
registerSize = { registerOverflowSize }
208
- display = { restReady && ! ! omittedItems . length }
245
+ display = { displayRest }
209
246
>
210
247
{ typeof renderRest === 'function'
211
248
? renderRest ( omittedItems )
212
249
: renderRest }
213
250
</ Item >
214
251
) : null }
252
+
253
+ { /* Suffix Node */ }
254
+ { suffix && (
255
+ < Item
256
+ order = { displayCount }
257
+ prefixCls = { itemPrefixCls }
258
+ className = { `${ itemPrefixCls } -suffix` }
259
+ responsive = { isResponsive }
260
+ registerSize = { registerSuffixSize }
261
+ display
262
+ style = { suffixStyle }
263
+ >
264
+ { suffix }
265
+ </ Item >
266
+ ) }
215
267
</ div >
216
268
) ;
217
269
0 commit comments