fix: slide the side panel tabs in their own direction

This commit is contained in:
DiheChen committed 2026-11-05 12:46:00 +08:00
1 parent 4737bb9ddf
commit 7168a97afa
3 files changed
+10 -6

No files matched your search

+3 -1
View File
@@ -218,8 +218,10 @@ export function App() {
// 加入房间前不显示面板:底部的切换按钮此时不可用,而聊天视图的关闭按钮在 RoomGate 内,打开的聊天面板会无法关闭。
const shownPanel = joined && panel !== page ? panel : null
const switchPanel = (next: Panel | null) => {
// 侧栏 tab 里播放历史排在播放列表右边,切回播放列表时内容要从左边进来。
const direction = shownPanel === 'history' && next === 'queue' ? 'backward' : 'forward'
if (shownPanel && next && next !== shownPanel && next !== page)
withViewTransition(() => navigationStore.setPanel(next))
withViewTransition(() => navigationStore.setPanel(next), direction)
else
navigationStore.setPanel(next)
}
+5 -4
View File
@@ -76,7 +76,8 @@
from { opacity: 0; }
to { opacity: 1; }
}
:root { --detail-panel-width: 480px; }
:root { --detail-panel-width: 480px; --view-direction: 1; }
:root[data-view-direction='backward'] { --view-direction: -1; }
.detail-panel { width: var(--detail-panel-width); flex-shrink: 0; position: relative; min-height: 0; display: flex; flex-direction: column; border: 0; border-radius: 12px; background: var(--color-panel); overflow: hidden; animation: detail-panel-open 240ms cubic-bezier(.2, .8, .2, 1) both; }
.detail-panel-content { view-transition-name: detail-panel-content; width: var(--detail-panel-width); flex: 1; min-height: 0; display: flex; flex-direction: column; }
.detail-panel-closing { pointer-events: none; animation-name: detail-panel-close; }
@@ -99,15 +100,15 @@
::view-transition-new(detail-panel-content) { animation: view-push-in 300ms cubic-bezier(.2, .8, .2, 1) both; }
@keyframes view-recede {
from { transform: translateX(0); }
to { transform: translateX(-14%); }
to { transform: translateX(calc(var(--view-direction) * -14%)); }
}
@keyframes view-push-in {
from { transform: translateX(100%); }
from { transform: translateX(calc(var(--view-direction) * 100%)); }
to { transform: translateX(0); }
}
.detail-panel-swap { animation: detail-panel-swap-in 180ms cubic-bezier(.2, .8, .2, 1) both; }
@keyframes detail-panel-swap-in {
from { opacity: 0; transform: translateX(10px); }
from { opacity: 0; transform: translateX(calc(var(--view-direction) * 10px)); }
to { opacity: 1; transform: translateX(0); }
}
:root[data-performance='low'] .header-menu[open] .main-nav { animation: fade-in 160ms ease both; }
+2 -1
View File
@@ -5,7 +5,8 @@ export function canPushViews(): boolean {
return 'startViewTransition' in document && performanceStore.smoothMotion()
}
export function withViewTransition(update: () => void): void {
export function withViewTransition(update: () => void, direction: 'forward' | 'backward'): void {
document.documentElement.dataset.viewDirection = direction
if (!canPushViews()) {
update()
return