diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aed010214..a1fb4fe48c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Feat: マウスでもタイムラインを引っ張って更新できるように - アクセシビリティ設定からオフにすることもできます - Enhance: タイムラインのパフォーマンスを向上 +- Fix: 一部のブラウザでアコーディオンメニューのアニメーションが動作しない問題を修正 ### Server - Enhance: 凍結されたユーザのノートが各種タイムラインで表示されないように `#15775` diff --git a/packages/frontend/src/components/MkFolder.vue b/packages/frontend/src/components/MkFolder.vue index 1236b843f2..e86861c874 100644 --- a/packages/frontend/src/components/MkFolder.vue +++ b/packages/frontend/src/components/MkFolder.vue @@ -31,6 +31,10 @@ SPDX-License-Identifier: AGPL-3.0-only :leaveActiveClass="prefer.s.animation ? $style.transition_toggle_leaveActive : ''" :enterFromClass="prefer.s.animation ? $style.transition_toggle_enterFrom : ''" :leaveToClass="prefer.s.animation ? $style.transition_toggle_leaveTo : ''" + @enter="enter" + @afterEnter="afterEnter" + @leave="leave" + @afterLeave="afterLeave" >
@@ -86,6 +90,42 @@ const bgSame = ref(false); const opened = ref(props.defaultOpen); const openedAtLeastOnce = ref(props.defaultOpen); +//#region interpolate-sizeに対応していないブラウザ向け(TODO: 主要ブラウザが対応したら消す) +function enter(el: Element) { + if (CSS.supports('interpolate-size', 'allow-keywords')) return; + if (!(el instanceof HTMLElement)) return; + + const elementHeight = el.getBoundingClientRect().height; + el.style.height = '0'; + el.offsetHeight; // reflow + el.style.height = `${Math.min(elementHeight, props.maxHeight ?? Infinity)}px`; +} + +function afterEnter(el: Element) { + if (CSS.supports('interpolate-size', 'allow-keywords')) return; + if (!(el instanceof HTMLElement)) return; + + el.style.height = ''; +} + +function leave(el: Element) { + if (CSS.supports('interpolate-size', 'allow-keywords')) return; + if (!(el instanceof HTMLElement)) return; + + const elementHeight = el.getBoundingClientRect().height; + el.style.height = `${elementHeight}px`; + el.offsetHeight; // reflow + el.style.height = '0'; +} + +function afterLeave(el: Element) { + if (CSS.supports('interpolate-size', 'allow-keywords')) return; + if (!(el instanceof HTMLElement)) return; + + el.style.height = ''; +} +//#endregion + function toggle() { if (!opened.value) { openedAtLeastOnce.value = true; @@ -108,17 +148,27 @@ onMounted(() => { .transition_toggle_enterActive, .transition_toggle_leaveActive { overflow-y: hidden; // 子要素のmarginが突き出るため clip を使ってはいけない - transition: opacity 0.3s, height 0.3s !important; + transition: opacity 0.3s, height 0.3s; } + +@supports (interpolate-size: allow-keywords) { + .transition_toggle_enterFrom, + .transition_toggle_leaveTo { + height: 0; + } + + .root { + interpolate-size: allow-keywords; // heightのtransitionを動作させるために必要 + } +} + .transition_toggle_enterFrom, .transition_toggle_leaveTo { opacity: 0; - height: 0; } .root { display: block; - interpolate-size: allow-keywords; // heightのtransitionを動作させるために必要 } .header {