@@ -20,6 +20,7 @@ export interface OverflowProps<ItemType> {
2020 renderRest ?:
2121 | React . ReactNode
2222 | ( ( omittedItems : ItemType [ ] ) => React . ReactNode ) ;
23+ suffix ?: React . ReactNode ;
2324}
2425
2526function defaultRenderRest < ItemType > ( omittedItems : ItemType [ ] ) {
@@ -40,6 +41,7 @@ function Overflow<ItemType = any>(
4041 className,
4142 maxCount,
4243 renderRest = defaultRenderRest ,
44+ suffix,
4345 } = props ;
4446
4547 const createUseState = useBatchFrameState ( ) ;
@@ -51,14 +53,18 @@ function Overflow<ItemType = any>(
5153
5254 const [ prevRestWidth , setPrevRestWidth ] = createUseState ( 0 ) ;
5355 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 ) ;
5659
5760 const [ displayCount , setDisplayCount ] = useState ( 0 ) ;
5861 const [ restReady , setRestReady ] = useState ( false ) ;
5962
6063 const itemPrefixCls = `${ prefixCls } -item` ;
6164
65+ // Always use the max width to avoid blink
66+ const mergedRestWidth = Math . max ( prevRestWidth , restWidth ) ;
67+
6268 // ================================= Data =================================
6369 const isResponsive = maxCount === RESPONSIVE ;
6470
@@ -132,14 +138,18 @@ function Overflow<ItemType = any>(
132138 setPrevRestWidth ( restWidth ) ;
133139 }
134140
141+ function registerSuffixSize ( _ : React . Key , width : number | null ) {
142+ setSuffixWidth ( width ! ) ;
143+ }
144+
135145 // ================================ Effect ================================
136146 function getItemWidth ( index : number ) {
137147 return itemWidths . get ( getKey ( mergedData [ index ] , index ) ) ;
138148 }
139149
140150 React . useLayoutEffect ( ( ) => {
141151 if ( containerWidth && mergedRestWidth && mergedData ) {
142- let totalWidth = 0 ;
152+ let totalWidth = suffixWidth ;
143153
144154 const len = mergedData . length ;
145155 const lastIndex = len - 1 ;
@@ -162,21 +172,48 @@ function Overflow<ItemType = any>(
162172 ) {
163173 // Additional check if match the end
164174 updateDisplayCount ( lastIndex ) ;
175+ setSuffixFixedStart ( null ) ;
165176 break ;
166177 } else if ( totalWidth + mergedRestWidth > containerWidth ) {
167178 // Can not hold all the content to show rest
168179 updateDisplayCount ( i - 1 ) ;
180+ setSuffixFixedStart (
181+ totalWidth - currentItemWidth - suffixWidth + mergedRestWidth ,
182+ ) ;
169183 break ;
170184 } else if ( i === lastIndex ) {
171185 // Reach the end
172186 updateDisplayCount ( lastIndex ) ;
187+ setSuffixFixedStart ( totalWidth - suffixWidth ) ;
173188 break ;
174189 }
175190 }
191+
192+ if ( suffix && getItemWidth ( 0 ) + suffixWidth > containerWidth ) {
193+ setSuffixFixedStart ( null ) ;
194+ }
176195 }
177- } , [ containerWidth , itemWidths , mergedRestWidth , getKey , mergedData ] ) ;
196+ } , [
197+ containerWidth ,
198+ itemWidths ,
199+ mergedRestWidth ,
200+ suffixWidth ,
201+ getKey ,
202+ mergedData ,
203+ ] ) ;
178204
179205 // ================================ 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+
180217 let overflowNode = (
181218 < div className = { classNames ( prefixCls , className ) } style = { style } ref = { ref } >
182219 { mergedData . map ( ( item , index ) => {
@@ -200,18 +237,33 @@ function Overflow<ItemType = any>(
200237 { /* Rest Count Item */ }
201238 { showRest ? (
202239 < Item
203- order = { displayCount }
240+ order = { displayRest ? displayCount : mergedData . length }
204241 prefixCls = { itemPrefixCls }
205242 className = { `${ itemPrefixCls } -rest` }
206243 responsive = { isResponsive }
207244 registerSize = { registerOverflowSize }
208- display = { restReady && ! ! omittedItems . length }
245+ display = { displayRest }
209246 >
210247 { typeof renderRest === 'function'
211248 ? renderRest ( omittedItems )
212249 : renderRest }
213250 </ Item >
214251 ) : 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+ ) }
215267 </ div >
216268 ) ;
217269
0 commit comments