99 />
1010 <span class =" comparison-title" @click =" toggleExpanded" >{{ title }}</span >
1111 </div >
12- <div
13- ref =" contentContainer"
14- class =" comparison-content-container"
15- :style =" { 'max-height': maxHeight }"
12+ <Transition
13+ name =" expand"
14+ @before-enter =" beforeEnter"
15+ @enter =" enter"
16+ @after-enter =" afterEnter"
17+ @before-leave =" beforeLeave"
18+ @leave =" leave"
1619 >
17- <div class =" form-row align-items-center mb-2" >
18- <FileMultiSelectDropdown
19- v-model =" internalFileModel"
20- :item_id =" item_id"
21- :block_id =" block_id"
22- :extensions =" extensions"
23- :update-block-on-change =" false"
24- :exclude-file-ids =" excludeFileIds"
25- />
20+ <div v-if =" isExpanded" ref =" contentContainer" class =" comparison-content-container" >
21+ <div class =" form-row align-items-center mb-2" >
22+ <FileMultiSelectDropdown
23+ v-model =" internalFileModel"
24+ :item_id =" item_id"
25+ :block_id =" block_id"
26+ :extensions =" extensions"
27+ :update-block-on-change =" false"
28+ :exclude-file-ids =" excludeFileIds"
29+ />
30+ </div >
31+ <div class =" form-row mt-2 mb-3" >
32+ <button class =" btn btn-primary btn-sm" @click =" applySelection" >
33+ {{ applyButtonText }}
34+ </button >
35+ </div >
2636 </div >
27- <div class =" form-row mt-2 mb-3" >
28- <button class =" btn btn-primary btn-sm" @click =" applySelection" >
29- {{ applyButtonText }}
30- </button >
31- </div >
32- </div >
37+ </Transition >
3338 </div >
3439</template >
3540
3641<script >
3742import FileMultiSelectDropdown from " @/components/FileMultiSelectDropdown" ;
3843
44+ // Padding added to content height for smooth collapse animation
45+ const CONTENT_PADDING_HEIGHT = 18 ;
46+
3947export default {
4048 components: {
4149 FileMultiSelectDropdown,
@@ -78,8 +86,6 @@ export default {
7886 data () {
7987 return {
8088 internalFileModel: [],
81- maxHeight: " 0px" ,
82- paddingHeight: 18 ,
8389 isExpanded: false ,
8490 };
8591 },
@@ -94,42 +100,42 @@ export default {
94100
95101 // Set initial expanded state
96102 this .isExpanded = this .initiallyExpanded ;
97-
98- // Initialize collapse state
99- var contentContainer = this .$refs .contentContainer ;
100- if (contentContainer) {
101- if (this .isExpanded ) {
102- this .maxHeight = " none" ;
103- contentContainer .style .overflow = " visible" ;
104- } else {
105- this .maxHeight = " 0px" ;
106- }
107-
108- contentContainer .addEventListener (" transitionend" , () => {
109- if (this .isExpanded ) {
110- this .maxHeight = " none" ;
111- }
112- });
113- }
114103 },
115104 methods: {
116105 toggleExpanded () {
117- var content = this .$refs .contentContainer ;
118- if (! this .isExpanded ) {
119- this .maxHeight = content .scrollHeight + 2 * this .paddingHeight + " px" ;
120- this .isExpanded = true ;
121- content .style .overflow = " visible" ;
122- } else {
123- content .style .overflow = " hidden" ;
124- requestAnimationFrame (() => {
125- this .maxHeight = content .scrollHeight + " px" ;
126- requestAnimationFrame (() => {
127- this .maxHeight = " 0px" ;
128- this .isExpanded = false ;
129- });
130- });
131- }
106+ this .isExpanded = ! this .isExpanded ;
132107 },
108+
109+ // Transition hooks for dynamic height animation
110+ beforeEnter (el ) {
111+ el .style .height = " 0" ;
112+ el .style .overflow = " hidden" ;
113+ },
114+
115+ enter (el ) {
116+ // Get actual content height including padding
117+ const height = el .scrollHeight + 2 * CONTENT_PADDING_HEIGHT ;
118+ el .style .height = height + " px" ;
119+ },
120+
121+ afterEnter (el ) {
122+ // Allow content to grow/shrink naturally after animation
123+ el .style .height = " auto" ;
124+ el .style .overflow = " visible" ;
125+ },
126+
127+ beforeLeave (el ) {
128+ // Set current height before collapsing
129+ el .style .height = el .scrollHeight + " px" ;
130+ el .style .overflow = " hidden" ;
131+ },
132+
133+ leave (el ) {
134+ // Force reflow to ensure the height is set before animating
135+ el .offsetHeight ;
136+ el .style .height = " 0" ;
137+ },
138+
133139 applySelection () {
134140 this .$emit (" update:modelValue" , this .internalFileModel .slice ());
135141 this .$emit (" apply" , this .internalFileModel .slice ());
@@ -170,9 +176,15 @@ export default {
170176 transform : rotate (90deg );
171177}
172178
173- .comparison-content-container {
179+ /* Transition styles for expand/collapse */
180+ .expand-enter-active ,
181+ .expand-leave-active {
182+ transition : height 0.4s ease-in-out ;
174183 overflow : hidden ;
175- max-height : none ;
176- transition : max-height 0.4s ease-in-out ;
184+ }
185+
186+ .expand-enter-from ,
187+ .expand-leave-to {
188+ height : 0 ;
177189}
178190 </style >
0 commit comments