From fa576abbe37a80c73b683db5d1f844bf277cbd16 Mon Sep 17 00:00:00 2001
From: Terry Truong <terry06890@gmail.com>
Date: Tue, 5 Jul 2022 13:20:32 +1000
Subject: Fix SCollapsible sometimes not fully expanding

---
 src/components/SCollapsible.vue | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

(limited to 'src/components/SCollapsible.vue')

diff --git a/src/components/SCollapsible.vue b/src/components/SCollapsible.vue
index 4b414fc..4570ee0 100644
--- a/src/components/SCollapsible.vue
+++ b/src/components/SCollapsible.vue
@@ -3,9 +3,11 @@
 	<div class="hover:cursor-pointer" @click="collapsed = !collapsed">
 		<slot name="summary" :collapsed="collapsed">(Summary)</slot>
 	</div>
-	<div :style="contentStyles" ref="content">
-		<slot name="content">(Content)</slot>
-	</div>
+	<transition @enter="onEnter" @after-enter="onAfterEnter" @leave="onLeave" @before-leave="onBeforeLeave">
+		<div v-show="!collapsed" :style="contentStyles" class="max-h-0" ref="content">
+			<slot name="content">(Content)</slot>
+		</div>
+	</transition>
 </div>
 </template>
 
@@ -27,7 +29,6 @@ export default defineComponent({
 		contentStyles(): Record<string,string> {
 			return {
 				overflow: 'hidden',
-				maxHeight: this.collapsed ? '0' : (this.$refs.content as HTMLDivElement).scrollHeight + 'px',
 				opacity: this.collapsed ? '0' : '1',
 				transitionProperty: 'max-height, opacity',
 				transitionDuration: '300ms',
@@ -35,5 +36,21 @@ export default defineComponent({
 			};
 		},
 	},
+	methods: {
+		onEnter(el: HTMLDivElement){
+			el.style.maxHeight = el.scrollHeight + 'px';
+		},
+		onAfterEnter(el: HTMLDivElement){
+			el.style.maxHeight = 'none';
+				// Allows the content to grow after the transition ends, as the scrollHeight sometimes is too short
+		},
+		onBeforeLeave(el: HTMLDivElement){
+			el.style.maxHeight = el.scrollHeight + 'px';
+			el.offsetWidth; // Triggers reflow
+		},
+		onLeave(el: HTMLDivElement){
+			el.style.maxHeight = '0';
+		},
+	},
 });
 </script>
-- 
cgit v1.2.3

