From dd4cb7de7da14d4d0c34b2375628a89c9e7fb960 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Fri, 30 May 2025 20:28:17 +0800 Subject: [PATCH 1/2] feat(tab-row): Added smooth decay logic to ensure responsive and fluid animation --- apps/client/src/widgets/tab_row.ts | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/apps/client/src/widgets/tab_row.ts b/apps/client/src/widgets/tab_row.ts index 92b81f6dd..f1ba461f3 100644 --- a/apps/client/src/widgets/tab_row.ts +++ b/apps/client/src/widgets/tab_row.ts @@ -378,16 +378,37 @@ export default class TabRowWidget extends BasicWidget { } scrollTabContainer(direction: number, behavior: ScrollBehavior = "smooth") { - const currentScrollLeft = this.$tabScrollingContainer[0]?.scrollLeft; - this.$tabScrollingContainer[0].scrollTo({ - left: currentScrollLeft + direction, + this.$tabScrollingContainer[0].scrollBy({ + left: direction, behavior }); }; setupScrollEvents() { + let deltaX = 0; + let isScrolling = false; + const stepScroll = () => { + if (Math.abs(deltaX) > 5) { + const step = Math.round(deltaX * 0.2); + deltaX -= step; + this.scrollTabContainer(step, "instant"); + requestAnimationFrame(stepScroll); + } else { + this.scrollTabContainer(deltaX, "instant"); + deltaX = 0; + isScrolling = false; + } + }; this.$tabScrollingContainer[0].addEventListener('wheel', (event) => { - this.scrollTabContainer(event.deltaY * 1.5); + if (!event.shiftKey || event.deltaX === 0) { + event.preventDefault(); + // Clamp deltaX between TAB_CONTAINER_MIN_WIDTH and TAB_CONTAINER_MIN_WIDTH * 3 + deltaX += Math.sign(event.deltaY) * Math.max(Math.min(Math.abs(event.deltaY), TAB_CONTAINER_MIN_WIDTH * 3), TAB_CONTAINER_MIN_WIDTH); + if (!isScrolling) { + isScrolling = true; + stepScroll(); + } + } }); this.$scrollButtonLeft[0].addEventListener('click', () => this.scrollTabContainer(-200)); From 7010472bea4aae6f10c634757ee41b9186176993 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Fri, 30 May 2025 20:40:33 +0800 Subject: [PATCH 2/2] feat(tab): enable Shift + Wheel to switch tabs --- apps/client/src/widgets/tab_row.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/client/src/widgets/tab_row.ts b/apps/client/src/widgets/tab_row.ts index f1ba461f3..6d0fc2fba 100644 --- a/apps/client/src/widgets/tab_row.ts +++ b/apps/client/src/widgets/tab_row.ts @@ -399,8 +399,8 @@ export default class TabRowWidget extends BasicWidget { isScrolling = false; } }; - this.$tabScrollingContainer[0].addEventListener('wheel', (event) => { - if (!event.shiftKey || event.deltaX === 0) { + this.$tabScrollingContainer[0].addEventListener('wheel', async (event) => { + if (!event.shiftKey && event.deltaX === 0) { event.preventDefault(); // Clamp deltaX between TAB_CONTAINER_MIN_WIDTH and TAB_CONTAINER_MIN_WIDTH * 3 deltaX += Math.sign(event.deltaY) * Math.max(Math.min(Math.abs(event.deltaY), TAB_CONTAINER_MIN_WIDTH * 3), TAB_CONTAINER_MIN_WIDTH); @@ -408,6 +408,14 @@ export default class TabRowWidget extends BasicWidget { isScrolling = true; stepScroll(); } + } else if (event.shiftKey) { + event.preventDefault(); + if (event.deltaY > 0) { + await appContext.tabManager.activateNextTabCommand(); + } else { + await appContext.tabManager.activatePreviousTabCommand(); + } + this.activeTabEl.scrollIntoView(); } });