@@ -4,16 +4,18 @@ import ResizeObserver from 'rc-resize-observer';
44import Item from './Item' ;
55import { useBatchFrameState } from './hooks/useBatchFrameState' ;
66
7+ const RESPONSIVE = 'responsive' as const ;
8+
79export interface OverflowProps < ItemType > {
810 prefixCls ?: string ;
911 className ?: string ;
1012 style ?: React . CSSProperties ;
1113 data ?: ItemType [ ] ;
1214 itemKey ?: React . Key | ( ( item : ItemType ) => React . Key ) ;
15+ /** Used for `responsive`. It will limit render node to avoid perf issue */
1316 itemWidth ?: number ;
1417 renderItem ?: ( item : ItemType ) => React . ReactNode ;
15- disabled ?: boolean ;
16- maxCount ?: number | 'responsive' ;
18+ maxCount ?: number | typeof RESPONSIVE ;
1719}
1820
1921function Overflow < ItemType = any > (
@@ -25,14 +27,14 @@ function Overflow<ItemType = any>(
2527 data = [ ] ,
2628 renderItem,
2729 itemKey,
28- itemWidth,
30+ itemWidth = 10 ,
2931 style,
3032 className,
31- disabled,
32- maxCount = 'responsive' ,
33+ maxCount = RESPONSIVE ,
3334 } = props ;
3435
3536 const createUseState = useBatchFrameState ( ) ;
37+ const disabled = maxCount !== RESPONSIVE ;
3638
3739 const [ containerWidth , setContainerWidth ] = createUseState ( 0 ) ;
3840 const [ itemWidths , setItemWidths ] = createUseState (
@@ -90,24 +92,30 @@ function Overflow<ItemType = any>(
9092 setOverflowWidth ( width ) ;
9193 }
9294
95+ // ================================= Data =================================
96+ const mergedData = React . useMemo (
97+ ( ) => data . slice ( 0 , Math . min ( data . length , containerWidth / itemWidth ) ) ,
98+ [ data , itemWidth , containerWidth ] ,
99+ ) ;
100+
93101 // ================================ Effect ================================
94102 React . useLayoutEffect ( ( ) => {
95- if ( containerWidth && overflowWidth && data ) {
103+ if ( containerWidth && overflowWidth && mergedData ) {
96104 let totalWidth = 0 ;
97105
98- const len = data . length ;
106+ const len = mergedData . length ;
99107
100108 for ( let i = 0 ; i < len ; i += 1 ) {
101- const itemWidth = itemWidths . get ( getKey ( data [ i ] , i ) ) ;
109+ const currentItemWidth = itemWidths . get ( getKey ( mergedData [ i ] , i ) ) ;
102110
103111 // Break since data not ready
104- if ( itemWidth === undefined ) {
112+ if ( currentItemWidth === undefined ) {
105113 updateDisplayCount ( i - 1 , true ) ;
106114 break ;
107115 }
108116
109117 // Find best match
110- totalWidth += itemWidth ;
118+ totalWidth += currentItemWidth ;
111119
112120 if ( totalWidth + overflowWidth > containerWidth ) {
113121 updateDisplayCount ( i - 1 ) ;
@@ -118,12 +126,12 @@ function Overflow<ItemType = any>(
118126 }
119127 }
120128 }
121- } , [ containerWidth , itemWidths , overflowWidth , getKey , data ] ) ;
129+ } , [ containerWidth , itemWidths , overflowWidth , getKey , mergedData ] ) ;
122130
123131 // ================================ Render ================================
124132 let overflowNode = (
125133 < div className = { classNames ( prefixCls , className ) } style = { style } ref = { ref } >
126- { data . map ( ( item , index ) => {
134+ { mergedData . map ( ( item , index ) => {
127135 const key = getKey ( item , index ) ;
128136
129137 return (
0 commit comments