@@ -13,11 +13,10 @@ import {
13
13
collapseExtraClassName ,
14
14
collapseContentClassName ,
15
15
} from './base' ;
16
- import { Scrollable } from '../scrollable' ;
17
16
import { select } from 'mo/common/dom' ;
18
17
19
18
type RenderFunctionProps = ( data : DataBaseProps ) => React . ReactNode ;
20
- interface DataBaseProps {
19
+ export interface DataBaseProps {
21
20
id : React . Key ;
22
21
name : string ;
23
22
className ?: string ;
@@ -50,15 +49,16 @@ export interface ICollapseProps {
50
49
}
51
50
52
51
// default collapse height, only contains header
53
- const HEADER_HEIGTH = 26 ;
52
+ export const HEADER_HEIGTH = 26 ;
54
53
/**
55
54
* It's the max height for the item which set the grow to 0
56
55
*/
57
- const MAX_GROW_HEIGHT = 220 ;
56
+ export const MAX_GROW_HEIGHT = 220 ;
58
57
59
58
export function Collapse ( props : ICollapseProps ) {
60
59
const [ activePanelKeys , setActivePanelKeys ] = useState < React . Key [ ] > ( [ ] ) ;
61
60
const wrapper = React . useRef < HTMLDivElement > ( null ) ;
61
+ const requestAF = React . useRef < number > ( ) ;
62
62
63
63
const {
64
64
className,
@@ -98,9 +98,14 @@ export function Collapse(props: ICollapseProps) {
98
98
const isActive = activePanelKeys . includes ( panel . id ) ;
99
99
let isEmpty = true ;
100
100
if ( isActive ) {
101
- const contentDom = select (
102
- `.${ collapseContentClassName } [data-content='${ panel . id } ']`
103
- ) ;
101
+ const contentDom =
102
+ select (
103
+ `.${ collapseContentClassName } [data-content='${ panel . id } ']`
104
+ ) ?. querySelector ( `[data-content='${ panel . id } ']` ) ||
105
+ select (
106
+ `.${ collapseContentClassName } [data-content='${ panel . id } ']`
107
+ ) ;
108
+
104
109
isEmpty = ! contentDom ?. hasChildNodes ( ) ;
105
110
}
106
111
panel . _isEmpty = isEmpty ;
@@ -117,21 +122,20 @@ export function Collapse(props: ICollapseProps) {
117
122
`.${ collapseItemClassName } [data-content='${ panel . id } ']`
118
123
) ;
119
124
120
- // Only set content height for non-grow-zero panel
121
- // 'Cause when you set height for grow-zero panel, you'll get wrong height next render time
122
- if ( panel . config ?. grow !== 0 ) {
123
- const contentDom = select < HTMLElement > (
124
- `.${ collapseContentClassName } [data-content='${ panel . id } ']`
125
- ) ;
126
- if ( contentDom ) {
127
- contentDom . style . height = `${ height - HEADER_HEIGTH - 2 } px` ;
128
- }
129
- }
130
125
if ( dom ) {
131
- dom . style . height = `${ height } px` ;
132
- dom . style . top = `${ top } px` ;
126
+ requestAF . current = requestAnimationFrame ( ( ) => {
127
+ dom . style . height = `${ height } px` ;
128
+ dom . style . top = `${ top } px` ;
129
+ } ) ;
133
130
}
134
131
} ) ;
132
+
133
+ return ( ) => {
134
+ if ( requestAF . current ) {
135
+ cancelAnimationFrame ( requestAF . current ) ;
136
+ requestAF . current = undefined ;
137
+ }
138
+ } ;
135
139
} , [ filterData ] ) ;
136
140
137
141
const handleChangeCallback = ( key : React . Key ) => {
@@ -199,15 +203,22 @@ export function Collapse(props: ICollapseProps) {
199
203
const contentDom = select (
200
204
`.${ collapseContentClassName } [data-content='${ key } ']`
201
205
) ;
202
- if ( contentDom ) {
203
- // border-top-width + border-bottom-width = 2
204
- const basisHeight =
205
- contentDom . getBoundingClientRect ( ) . height -
206
- 2 +
207
- HEADER_HEIGTH ;
208
- return basisHeight > 220 ? 220 : basisHeight ;
206
+
207
+ const childrenDom = contentDom ?. querySelector (
208
+ `[data-content='${ key } ']`
209
+ ) ;
210
+
211
+ let contentHeight = contentDom ?. getBoundingClientRect ( ) . height || 0 ;
212
+
213
+ if ( childrenDom ) {
214
+ contentHeight = childrenDom . getBoundingClientRect ( ) . height ;
209
215
}
210
- return 0 ;
216
+
217
+ // border-top-width + border-bottom-width = 2
218
+ const height =
219
+ parseInt ( contentHeight . toFixed ( 0 ) ) - 2 + HEADER_HEIGTH ;
220
+
221
+ return height > MAX_GROW_HEIGHT ? MAX_GROW_HEIGHT : height ;
211
222
} ) ;
212
223
} ;
213
224
@@ -235,10 +246,12 @@ export function Collapse(props: ICollapseProps) {
235
246
// to get current panel content
236
247
const contentDom = select (
237
248
`.${ collapseContentClassName } [data-content='${ panel . id } ']`
238
- ) ;
249
+ ) ?. querySelector ( `[data-content='${ panel . id } ']` ) ;
250
+
239
251
if ( contentDom ) {
240
252
const height =
241
253
contentDom . getBoundingClientRect ( ) . height +
254
+ 2 +
242
255
HEADER_HEIGTH ;
243
256
res [ 0 ] =
244
257
height > MAX_GROW_HEIGHT ? MAX_GROW_HEIGHT : height ;
@@ -282,7 +295,7 @@ export function Collapse(props: ICollapseProps) {
282
295
// In general, the following code will not be excuted
283
296
const contentDom = select (
284
297
`.${ collapseContentClassName } [data-content='${ panel . id } ']`
285
- ) ;
298
+ ) ?. querySelector ( `[data-content=' ${ panel . id } ']` ) ;
286
299
return contentDom ?. hasChildNodes ( ) ;
287
300
}
288
301
return false ;
@@ -375,15 +388,13 @@ export function Collapse(props: ICollapseProps) {
375
388
) }
376
389
</ div >
377
390
</ div >
378
- < Scrollable noScrollX isShowShadow >
379
- < div
380
- className = { collapseContentClassName }
381
- data-content = { panel . id }
382
- tabIndex = { 0 }
383
- >
384
- { renderPanels ( panel , panel . renderPanel ) }
385
- </ div >
386
- </ Scrollable >
391
+ < div
392
+ className = { collapseContentClassName }
393
+ data-content = { panel . id }
394
+ tabIndex = { 0 }
395
+ >
396
+ { renderPanels ( panel , panel . renderPanel ) }
397
+ </ div >
387
398
</ div >
388
399
) ;
389
400
} ) }
0 commit comments