summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/MkFolder.vue
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2025-05-04 14:06:43 +0900
committerGitHub <noreply@github.com>2025-05-04 14:06:43 +0900
commit0884605b62761c0b8aa5365d74d8778562ddbea6 (patch)
treeefc4f6ce2c5cf1900991ab6381690f5194a3ded7 /packages/frontend/src/components/MkFolder.vue
parentenhance(frontend): タイムラインpush時のアニメーションを調整... (diff)
downloadmisskey-0884605b62761c0b8aa5365d74d8778562ddbea6.tar.gz
misskey-0884605b62761c0b8aa5365d74d8778562ddbea6.tar.bz2
misskey-0884605b62761c0b8aa5365d74d8778562ddbea6.zip
fix(frontend): MkFolderのアニメーションにフォールバックを追加 (#15937)
* fix(frontend): Chrome系以外のブラウザでMkFolderがアニメーションしない問題を修正 * fix * Update Changelog * fix
Diffstat (limited to 'packages/frontend/src/components/MkFolder.vue')
-rw-r--r--packages/frontend/src/components/MkFolder.vue56
1 files changed, 53 insertions, 3 deletions
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"
>
<KeepAlive>
<div v-show="opened">
@@ -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 {