fix: fix sidebar animation weirdness in sidebar folders

This commit is contained in:
2026-08-24 14:04:08 +09:30
parent a411d646ae
commit dde5096d1c
5 changed files with 155 additions and 78 deletions
+4 -1
View File
@@ -195,6 +195,8 @@
class="logo-link bsplus-sidebar-list"
class:noscroll={sidebarState.isDrilling}
class:drilling={sidebarState.isDrilling}
class:drill-entering={sidebarState.enterFrameKey != null}
class:drill-returning={sidebarState.drillReturning}
class:compact={sidebarState.compact}
class:edit-mode={sidebarState.editMode}
class:is-sorting={dragging}
@@ -283,7 +285,8 @@
class="sub"
class:bsplus-sub-enter={sidebarState.enterFrameKey === current.frame.key}
onanimationend={(e) => {
if (e.target === e.currentTarget) {
if (e.target !== e.currentTarget) return;
if (sidebarState.enterFrameKey === current.frame.key) {
sidebarState.clearEnterFrame(current.frame.key);
}
}}
+1 -1
View File
@@ -101,7 +101,7 @@ function scheduleSync() {
* never see them. Opening Goals/Folios via SEQTA + our drill UI freezes the tab.
*/
function onCustomSidebarCaptureClick(event: MouseEvent) {
if (!menuEl || sidebarState.editMode) return;
if (!menuEl || sidebarState.editMode || sidebarState.drillReturning) return;
const root = document.getElementById(ROOT_ID);
const target = event.target;
+23 -5
View File
@@ -184,8 +184,9 @@ class SidebarState {
activePath = $state("");
editMode = $state(false);
iconOnly = $state(false);
/** Frame key whose `.sub` should play the one-shot enter animation. */
/** Folder key playing the one-shot panel enter animation. */
enterFrameKey = $state<string | null>(null);
drillReturning = $state(false);
visibleRootItems = $derived(
filterVisible(orderItems(this.items, settingsState.menuorder ?? [])),
@@ -262,10 +263,11 @@ class SidebarState {
}
openFolder(item: SidebarItem, menu?: HTMLElement) {
if (!item.hasChildren) return;
// Ignore duplicate opens (double-firing click / label + li).
if (!item.hasChildren || this.drillReturning) return;
if (this.drillStack.at(-1)?.key === item.key) return;
this.drillReturning = false;
const frame: SidebarDrillFrame = {
key: item.key,
label: item.label,
@@ -293,14 +295,23 @@ class SidebarState {
}
goBack() {
if (!this.drillStack.length) return;
if (!this.drillStack.length || this.drillReturning) return;
this.enterFrameKey = null;
this.drillStack = this.drillStack.slice(0, -1);
resetSidebarScroll();
if (settingsState.animations !== true) return;
this.drillReturning = true;
window.setTimeout(() => {
this.drillReturning = false;
}, 360);
}
resetDrill() {
this.enterFrameKey = null;
this.drillReturning = false;
this.drillStack = [];
resetSidebarScroll();
}
@@ -350,7 +361,7 @@ class SidebarState {
}
activateItem(item: SidebarItem, menu: HTMLElement) {
if (this.editMode) return;
if (this.editMode || this.drillReturning) return;
if (item.hasChildren) {
this.openFolder(item, menu);
@@ -360,6 +371,13 @@ class SidebarState {
this.activeKey = item.key;
if (item.path) this.activePath = item.path;
// Already inside this folder — never replay the one-shot enter animation when
// SEQTA rewrites `.active` on the route change.
if (this.isDrilling) {
this.enterFrameKey = null;
restoreCustomMenuActive();
}
const native = findNativeMenuEntry(menu, item);
if (native) {
// Clear native drill once only — repeating clearNativeDrillActive fights