@@ -11,13 +11,7 @@ import {
1111} from ' vue'
1212
1313import { SAFE_STYLES , VISUALLY_HIDDEN , AUTO_DUR_VAR , FALLBACK_DURATION } from ' ./constants'
14- import {
15- getTransitionProp ,
16- getComputedHeight ,
17- getHeightProp ,
18- getAutoDuration ,
19- isReducedOrDisabled ,
20- } from ' ./utils'
14+ import { getTransitionProp , getComputedHeight , getAutoDuration , isReducedOrDisabled } from ' ./utils'
2115
2216export type TransitionState = ' expanding' | ' expanded' | ' collapsing' | ' collapsed'
2317
@@ -104,6 +98,15 @@ const setAutoDuration = (newDuration: number) => (autoDuration.value = newDurati
10498
10599const autoDurationVar = computed (() => ({ [AUTO_DUR_VAR ]: ` ${autoDuration .value }ms ` }))
106100
101+ /**
102+ * In some edge cases, Collapse may have children elements that also expand
103+ * their height while expanding.
104+ *
105+ * When this occurs, the 'scrollHeight' obtained on transition start will be lower than
106+ * the same 'scrollHeight' obtained on transition end.
107+ */
108+ let transitionStartScrollHeight = NaN
109+
107110function onExpanded() {
108111 replaceStyles (SAFE_STYLES )
109112 setState (' expanded' )
@@ -139,6 +142,8 @@ onMounted(() => {
139142watch (isExpanded , (isExpanding ) => {
140143 if (! collapseRef .value ) return
141144
145+ transitionStartScrollHeight = NaN
146+
142147 if (isExpanding ) {
143148 if (isReducedOrDisabled (collapseRef )) return onExpanded ()
144149
@@ -168,9 +173,11 @@ watch(isExpanded, (isExpanding) => {
168173
169174 /** Set height to scrollHeight and trigger the transition. */
170175
176+ transitionStartScrollHeight = collapseRef .value ! .scrollHeight
177+
171178 addStyles ({
172- ... getHeightProp (collapseRef ),
173179 ... getTransitionProp (collapseRef ),
180+ height: ` ${transitionStartScrollHeight }px ` ,
174181 willChange: ' height' ,
175182 })
176183 })
@@ -189,7 +196,7 @@ watch(isExpanded, (isExpanding) => {
189196
190197 addStyles ({
191198 ... autoDurationVar .value ,
192- ... getHeightProp ( collapseRef ) ,
199+ height: ` ${ collapseRef . value ! . scrollHeight }px ` ,
193200 })
194201
195202 /** Same as for expand, abort transition and force collapse */
@@ -230,6 +237,15 @@ function onTransitionEnd(e: TransitionEvent) {
230237 if (isExpanded .value ) {
231238 if (Math .abs (collapseRef .value .scrollHeight - getComputedHeight (collapseRef )) < 1 ) {
232239 onExpanded ()
240+ } else if (transitionStartScrollHeight < collapseRef .value .scrollHeight ) {
241+ /**
242+ * A child element expanded its height while Collapse
243+ * is transitioning, update the height and trigger
244+ * the transition again.
245+ */
246+ addStyles ({
247+ height: ` ${collapseRef .value .scrollHeight }px ` ,
248+ })
233249 }
234250 } else {
235251 if (Math .abs (baseHeight .value - getComputedHeight (collapseRef )) < 1 ) {
0 commit comments