From 2a0014fb94daf56424fc1698519717771beca358 Mon Sep 17 00:00:00 2001 From: DmitriyNoa Date: Mon, 24 Jan 2022 17:23:40 +0100 Subject: [PATCH 1/8] Add separators and scroll button Signed-off-by: DmitriyNoa --- src/renderer/components/dock/dock-tab.scss | 5 ++++- src/renderer/components/dock/dock.tsx | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/renderer/components/dock/dock-tab.scss b/src/renderer/components/dock/dock-tab.scss index 845a66c794..a90bd9e594 100644 --- a/src/renderer/components/dock/dock-tab.scss +++ b/src/renderer/components/dock/dock-tab.scss @@ -5,7 +5,6 @@ .DockTab { padding: $padding; - padding-right: 0; .Icon { &.material { @@ -36,4 +35,8 @@ &:last-child { padding-right: $padding; } + + border-right-width: 2px; + border-right-color: var(--dockInfoBackground); + border-right-style: solid; } diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx index 5a9f1b26e1..ace893b34f 100644 --- a/src/renderer/components/dock/dock.tsx +++ b/src/renderer/components/dock/dock.tsx @@ -91,6 +91,20 @@ class NonInjectedDock extends React.Component { } } + isScrollableRight = (): boolean => { + if(!this.element) return false; + const child = document.querySelector(".DockTabs"); + + const parentWidth = this.element.current.clientWidth; + const childWidth = child && child.clientWidth || 0; + + return childWidth > parentWidth; + }; + + scrollToRight = (): void => { + console.log("Current", this.element?.current); + }; + renderTabContent() { const { isOpen, height, selectedTab } = this.props.dockStore; @@ -132,6 +146,11 @@ class NonInjectedDock extends React.Component { onChangeTab={this.onChangeTab} />
+
this.props.createTerminalTab()}> From 130618c8f4fad842e79e02303ad1370bcf9099b1 Mon Sep 17 00:00:00 2001 From: DmitriyNoa Date: Tue, 25 Jan 2022 15:11:39 +0100 Subject: [PATCH 2/8] Add tabs controlls Signed-off-by: DmitriyNoa --- src/renderer/components/dock/dock-tab.scss | 4 - src/renderer/components/dock/dock-tabs.tsx | 88 +++++++++++++++++++--- src/renderer/components/dock/dock.scss | 43 +++++++++++ src/renderer/components/dock/dock.tsx | 23 +----- 4 files changed, 123 insertions(+), 35 deletions(-) diff --git a/src/renderer/components/dock/dock-tab.scss b/src/renderer/components/dock/dock-tab.scss index a90bd9e594..881c35cf62 100644 --- a/src/renderer/components/dock/dock-tab.scss +++ b/src/renderer/components/dock/dock-tab.scss @@ -28,10 +28,6 @@ padding-right: $padding; } - &:first-child { - padding-left: 0; - } - &:last-child { padding-right: $padding; } diff --git a/src/renderer/components/dock/dock-tabs.tsx b/src/renderer/components/dock/dock-tabs.tsx index 8902fe439a..e7699229f1 100644 --- a/src/renderer/components/dock/dock-tabs.tsx +++ b/src/renderer/components/dock/dock-tabs.tsx @@ -3,8 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import React, { Fragment } from "react"; - +import React, { Fragment, useRef, useEffect, useState, UIEvent } from "react"; import { Icon } from "../icon"; import { Tabs } from "../tabs/tabs"; import { DockTab } from "./dock-tab"; @@ -20,6 +19,43 @@ interface Props { } export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) => { + const elem = useRef(null); + const contentElem = useRef(null); + const [scrollPosition, setScrollPosition] = useState(0); + const scrollStep = 200; + + const scrollToRight = (): void => { + if(!elem) return; + + setScrollPosition(scrollPosition + scrollStep); + + elem.current.scrollLeft = scrollPosition; + }; + + + const scrollToLeft = (): void => { + if(!elem) return; + + setScrollPosition(scrollPosition - scrollStep); + + elem.current.scrollLeft = scrollPosition; + }; + + const isScrollableRight = (): boolean => { + if(!elem || !contentElem) return false; + + const containerWidth = elem.current?.clientWidth; + const contentWidth = contentElem.current?.clientWidth; + + return contentWidth > containerWidth && scrollPosition < contentWidth - scrollStep; + }; + + const isScrollableLeft = (): boolean => { + if(!elem || !contentElem) return false; + + return scrollPosition > scrollStep; + }; + const renderTab = (tab?: DockTabModel) => { if (!tab) { return null; @@ -39,14 +75,46 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = } }; + useEffect(() => { + elem.current.addEventListener("scroll", ( evt: UIEvent) => { + const position = evt.currentTarget.scrollLeft; + + if (position!== undefined) { + setScrollPosition(position); + } + }); + }, []); + return ( - - {tabs.map(tab => {renderTab(tab)})} - +
+ {isScrollableLeft() && ( + + )} +
+
+ + {tabs.map(tab => {renderTab(tab)})} + +
+
+ {isScrollableRight() && ( + + )} +
); }; diff --git a/src/renderer/components/dock/dock.scss b/src/renderer/components/dock/dock.scss index 7a543ce934..255ff2fcfc 100644 --- a/src/renderer/components/dock/dock.scss +++ b/src/renderer/components/dock/dock.scss @@ -76,4 +76,47 @@ bottom: 0; } } + + .tabs-control { + overflow: auto; + position: relative; + + &::-webkit-scrollbar { + visibility: hidden; + height: 4px; + background:transparent; + position: absolute; + bottom: 0; + } + + &:hover::-webkit-scrollbar { + visibility: visible; + } + + &:hover::-webkit-scrollbar-thumb { + background: var(--scrollBarColor); + } + + .tab-control { + position: absolute; + z-index: 9999; + } + + .scroll-left { + left: 0; + } + + .right { + right: 0; + } + + } + + .DockTab.active { + background-color: var(--menuActiveBackground); + + &::after { + color: var(--terminalWhite); + } + } } diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx index ace893b34f..f44d7d00e5 100644 --- a/src/renderer/components/dock/dock.tsx +++ b/src/renderer/components/dock/dock.tsx @@ -8,7 +8,7 @@ import "./dock.scss"; import React from "react"; import { observer } from "mobx-react"; -import { cssNames, prevDefault } from "../../utils"; +import { cssNames } from "../../utils"; import { Icon } from "../icon"; import { MenuItem } from "../menu"; import { MenuActions } from "../menu/menu-actions"; @@ -91,20 +91,6 @@ class NonInjectedDock extends React.Component { } } - isScrollableRight = (): boolean => { - if(!this.element) return false; - const child = document.querySelector(".DockTabs"); - - const parentWidth = this.element.current.clientWidth; - const childWidth = child && child.clientWidth || 0; - - return childWidth > parentWidth; - }; - - scrollToRight = (): void => { - console.log("Current", this.element?.current); - }; - renderTabContent() { const { isOpen, height, selectedTab } = this.props.dockStore; @@ -138,7 +124,7 @@ class NonInjectedDock extends React.Component { onMinExtentExceed={dockStore.open} onDrag={extent => dockStore.height = extent} /> -
+
{ onChangeTab={this.onChangeTab} />
-
this.props.createTerminalTab()}> From f484620ebbb863870659307ea1b318703154d9ba Mon Sep 17 00:00:00 2001 From: DmitriyNoa Date: Tue, 25 Jan 2022 15:52:36 +0100 Subject: [PATCH 3/8] Update values on resize Signed-off-by: DmitriyNoa --- src/renderer/components/dock/dock-tabs.tsx | 52 +++++++++++++++------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/renderer/components/dock/dock-tabs.tsx b/src/renderer/components/dock/dock-tabs.tsx index e7699229f1..70568da0f7 100644 --- a/src/renderer/components/dock/dock-tabs.tsx +++ b/src/renderer/components/dock/dock-tabs.tsx @@ -21,33 +21,34 @@ interface Props { export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) => { const elem = useRef(null); const contentElem = useRef(null); + const [contentWidth, setContentWidth] = useState(0); + const [containerWidth, setContainerWidth] = useState(0); const [scrollPosition, setScrollPosition] = useState(0); const scrollStep = 200; const scrollToRight = (): void => { if(!elem) return; + const scroll = scrollPosition + scrollStep; - setScrollPosition(scrollPosition + scrollStep); + setScrollPosition(scroll); - elem.current.scrollLeft = scrollPosition; + elem.current.scrollLeft = scroll; }; const scrollToLeft = (): void => { if(!elem) return; + const scroll = scrollPosition - scrollStep; - setScrollPosition(scrollPosition - scrollStep); + setScrollPosition(scroll); - elem.current.scrollLeft = scrollPosition; + elem.current.scrollLeft = scroll; }; const isScrollableRight = (): boolean => { if(!elem || !contentElem) return false; - const containerWidth = elem.current?.clientWidth; - const contentWidth = contentElem.current?.clientWidth; - - return contentWidth > containerWidth && scrollPosition < contentWidth - scrollStep; + return contentWidth > containerWidth && scrollPosition < contentWidth - containerWidth; }; const isScrollableLeft = (): boolean => { @@ -56,6 +57,22 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = return scrollPosition > scrollStep; }; + const updateScrollPosition = ( evt: UIEvent) => { + const position = evt.currentTarget.scrollLeft; + + if (position!== undefined) { + setScrollPosition(position); + } + }; + + const onWindowResize = () => { + if(!elem || !contentElem) return; + + setContentWidth(contentElem.current.clientWidth); + setContainerWidth(elem.current.clientWidth); + setScrollPosition(elem.current.scrollLeft); + }; + const renderTab = (tab?: DockTabModel) => { if (!tab) { return null; @@ -75,14 +92,19 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = } }; - useEffect(() => { - elem.current.addEventListener("scroll", ( evt: UIEvent) => { - const position = evt.currentTarget.scrollLeft; - if (position!== undefined) { - setScrollPosition(position); - } - }); + useEffect(() => { + if(!elem || !contentElem) return; + + setContentWidth(contentElem.current.clientWidth); + setContainerWidth(elem.current.clientWidth); + setScrollPosition(elem.current.scrollLeft); + + // update values in store on scroll + elem.current.addEventListener("scroll", updateScrollPosition); + + // update current values on resize to show/hide scroll + window.addEventListener("resize", onWindowResize); }, []); return ( From 61345aaf722ea3a322831c8d8be0ab4e6651fb05 Mon Sep 17 00:00:00 2001 From: DmitriyNoa Date: Tue, 25 Jan 2022 16:25:44 +0100 Subject: [PATCH 4/8] Fix right button Signed-off-by: DmitriyNoa --- src/renderer/components/dock/dock-tabs.tsx | 9 ++++----- src/renderer/components/dock/dock.scss | 4 ++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/renderer/components/dock/dock-tabs.tsx b/src/renderer/components/dock/dock-tabs.tsx index 70568da0f7..1b90766489 100644 --- a/src/renderer/components/dock/dock-tabs.tsx +++ b/src/renderer/components/dock/dock-tabs.tsx @@ -27,7 +27,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = const scrollStep = 200; const scrollToRight = (): void => { - if(!elem) return; + if(!elem || scrollPosition + scrollStep > contentWidth) return; const scroll = scrollPosition + scrollStep; setScrollPosition(scroll); @@ -35,7 +35,6 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = elem.current.scrollLeft = scroll; }; - const scrollToLeft = (): void => { if(!elem) return; const scroll = scrollPosition - scrollStep; @@ -57,7 +56,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = return scrollPosition > scrollStep; }; - const updateScrollPosition = ( evt: UIEvent) => { + const updateScrollPosition = ( evt: UIEvent): void => { const position = evt.currentTarget.scrollLeft; if (position!== undefined) { @@ -65,7 +64,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = } }; - const onWindowResize = () => { + const onWindowResize = (): void => { if(!elem || !contentElem) return; setContentWidth(contentElem.current.clientWidth); @@ -108,7 +107,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = }, []); return ( -
+
{isScrollableLeft() && ( Date: Tue, 25 Jan 2022 17:31:12 +0100 Subject: [PATCH 5/8] Add change tab on keydown Signed-off-by: DmitriyNoa --- src/renderer/components/dock/dock.tsx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx index f44d7d00e5..e24be02b2a 100644 --- a/src/renderer/components/dock/dock.tsx +++ b/src/renderer/components/dock/dock.tsx @@ -36,6 +36,11 @@ interface Dependencies { dockStore: DockStore } +enum Direction { + next = "next", + prev = "prev", +} + @observer class NonInjectedDock extends React.Component { private element = React.createRef(); @@ -51,6 +56,7 @@ class NonInjectedDock extends React.Component { onKeyDown = (evt: KeyboardEvent) => { const { close, selectedTab, closeTab } = this.props.dockStore; const { code, ctrlKey, metaKey, shiftKey } = evt; + // Determine if user working inside or using any other areas in app const dockIsFocused = this.element?.current.contains(document.activeElement); @@ -64,6 +70,14 @@ class NonInjectedDock extends React.Component { closeTab(selectedTab.id); this.element?.current.focus(); // Avoid loosing focus when closing tab } + + if(ctrlKey && code === "Period") { + this.nextTab(Direction.next); + } + + if(ctrlKey && code === "Comma") { + this.nextTab(Direction.prev); + } }; onChangeTab = (tab: DockTab) => { @@ -74,6 +88,19 @@ class NonInjectedDock extends React.Component { this.element?.current.focus(); }; + nextTab = (direction: Direction) => { + const { tabs, selectedTab } = this.props.dockStore; + const currentIndex = tabs.indexOf(selectedTab); + const nextIndex = direction === Direction.next ? currentIndex + 1 : currentIndex - 1; + + if (direction === Direction.next && currentIndex!== -1 && nextIndex >= tabs.length) return; + if (direction === Direction.prev && currentIndex!== -1 && nextIndex < 0) return; + + const nextElement = tabs[nextIndex]; + + this.onChangeTab(nextElement); + }; + renderTab(tab: DockTab) { switch (tab.kind) { case TabKind.CREATE_RESOURCE: From 948b2783606e92a4e262ae2c4985ad5c8cc024a6 Mon Sep 17 00:00:00 2001 From: DmitriyNoa Date: Fri, 28 Jan 2022 15:03:57 +0100 Subject: [PATCH 6/8] Fix flickering and arrows position Signed-off-by: DmitriyNoa --- .../dock/__test__/dock-tabs.test.tsx | 1 + .../components/dock/dock-store/dock.store.ts | 18 +++++++++ src/renderer/components/dock/dock-tabs.tsx | 38 +++++++++++-------- src/renderer/components/dock/dock.scss | 34 +++++++++-------- src/renderer/components/dock/dock.tsx | 1 + 5 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/renderer/components/dock/__test__/dock-tabs.test.tsx b/src/renderer/components/dock/__test__/dock-tabs.test.tsx index 705680317f..47e9689fa3 100644 --- a/src/renderer/components/dock/__test__/dock-tabs.test.tsx +++ b/src/renderer/components/dock/__test__/dock-tabs.test.tsx @@ -49,6 +49,7 @@ const getComponent = (dockStore: DockStore) => ( selectedTab={dockStore.selectedTab} autoFocus={true} onChangeTab={noop} + dockStore={dockStore} /> ); diff --git a/src/renderer/components/dock/dock-store/dock.store.ts b/src/renderer/components/dock/dock-store/dock.store.ts index b551496e7e..9de5b2d092 100644 --- a/src/renderer/components/dock/dock-store/dock.store.ts +++ b/src/renderer/components/dock/dock-store/dock.store.ts @@ -97,6 +97,11 @@ export interface DockTabCloseEvent { tabId: TabId; // closed tab id } +export interface DockTabsNumberEvent { + currentTabsNumber: number; // number of open tabs + previousTabsNumber: number; +} + interface Dependencies { storage: StorageHelper } @@ -160,6 +165,10 @@ export class DockStore implements DockStorageState { this.dependencies.storage.merge({ selectedTabId: tabId }); } + @computed get tabsNumber() : number { + return this.tabs.length; + } + @computed get selectedTab() { return this.tabs.find(tab => tab.id === this.selectedTabId); } @@ -224,6 +233,15 @@ export class DockStore implements DockStorageState { }), reactionOpts); } + onTabsNumberChange(callback: (evt: DockTabsNumberEvent) => void) { + return reaction(() => this.tabsNumber, ((currentTabsNumber, previousTabsNumber) => { + callback({ + currentTabsNumber, + previousTabsNumber, + }); + })); + } + hasTabs() { return this.tabs.length > 0; } diff --git a/src/renderer/components/dock/dock-tabs.tsx b/src/renderer/components/dock/dock-tabs.tsx index 1b90766489..482f114e8c 100644 --- a/src/renderer/components/dock/dock-tabs.tsx +++ b/src/renderer/components/dock/dock-tabs.tsx @@ -8,17 +8,18 @@ import { Icon } from "../icon"; import { Tabs } from "../tabs/tabs"; import { DockTab } from "./dock-tab"; import type { DockTab as DockTabModel } from "./dock-store/dock.store"; -import { TabKind } from "./dock-store/dock.store"; +import { TabKind, DockStore } from "./dock-store/dock.store"; import { TerminalTab } from "./terminal-tab"; interface Props { tabs: DockTabModel[] + dockStore: DockStore; autoFocus: boolean selectedTab: DockTabModel onChangeTab: (tab: DockTabModel) => void } -export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) => { +export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab, dockStore }: Props) => { const elem = useRef(null); const contentElem = useRef(null); const [contentWidth, setContentWidth] = useState(0); @@ -27,7 +28,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = const scrollStep = 200; const scrollToRight = (): void => { - if(!elem || scrollPosition + scrollStep > contentWidth) return; + if(!elem || scrollPosition === contentWidth) return; const scroll = scrollPosition + scrollStep; setScrollPosition(scroll); @@ -35,6 +36,14 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = elem.current.scrollLeft = scroll; }; + const updateStateValues = () => { + if(!elem || !contentElem) return; + + setContentWidth(contentElem.current.clientWidth); + setContainerWidth(elem.current.clientWidth); + setScrollPosition(elem.current.scrollLeft); + }; + const scrollToLeft = (): void => { if(!elem) return; const scroll = scrollPosition - scrollStep; @@ -47,13 +56,15 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = const isScrollableRight = (): boolean => { if(!elem || !contentElem) return false; - return contentWidth > containerWidth && scrollPosition < contentWidth - containerWidth; + // check if element with tabs is wider than the parent element + // check if scroll at the end of scrollable area. + return contentElem.current?.clientWidth > containerWidth && scrollPosition < contentElem.current?.clientWidth - elem.current?.clientWidth; }; const isScrollableLeft = (): boolean => { if(!elem || !contentElem) return false; - return scrollPosition > scrollStep; + return scrollPosition > 0; }; const updateScrollPosition = ( evt: UIEvent): void => { @@ -65,11 +76,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = }; const onWindowResize = (): void => { - if(!elem || !contentElem) return; - - setContentWidth(contentElem.current.clientWidth); - setContainerWidth(elem.current.clientWidth); - setScrollPosition(elem.current.scrollLeft); + updateStateValues(); }; const renderTab = (tab?: DockTabModel) => { @@ -93,17 +100,18 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) = useEffect(() => { - if(!elem || !contentElem) return; - - setContentWidth(contentElem.current.clientWidth); - setContainerWidth(elem.current.clientWidth); - setScrollPosition(elem.current.scrollLeft); + updateStateValues(); // update values in store on scroll elem.current.addEventListener("scroll", updateScrollPosition); // update current values on resize to show/hide scroll window.addEventListener("resize", onWindowResize); + + // update scroll state if tabs numbers has changed + dockStore.onTabsNumberChange(() => { + updateStateValues(); + }); }, []); return ( diff --git a/src/renderer/components/dock/dock.scss b/src/renderer/components/dock/dock.scss index ba9be598a0..c3919fc78e 100644 --- a/src/renderer/components/dock/dock.scss +++ b/src/renderer/components/dock/dock.scss @@ -60,6 +60,10 @@ .tabs-wrapper { overflow: hidden; + width: 100%; + box-sizing: border-box; + position: relative; + padding: 0 $padding*2.5; } .tab-content { @@ -83,7 +87,7 @@ .tabs-control { overflow: auto; - position: relative; + width: 100%; &::-webkit-scrollbar { visibility: hidden; @@ -100,20 +104,6 @@ &:hover::-webkit-scrollbar-thumb { background: var(--scrollBarColor); } - - .tab-control { - position: absolute; - z-index: 9999; - } - - .scroll-left { - left: 0; - } - - .right { - right: 0; - } - } .DockTab.active { @@ -123,4 +113,18 @@ color: var(--terminalWhite); } } + + .tab-control { + position: absolute; + z-index: 9999; + } + + .scroll-left { + left: 0; + } + + .scroll-right { + right: 0; + } + } diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx index e24be02b2a..60c5cd7c0a 100644 --- a/src/renderer/components/dock/dock.tsx +++ b/src/renderer/components/dock/dock.tsx @@ -157,6 +157,7 @@ class NonInjectedDock extends React.Component { selectedTab={selectedTab} autoFocus={isOpen} onChangeTab={this.onChangeTab} + dockStore={dockStore} />
From 8674f3ecf1a44261b786712ec4aba689283df2bf Mon Sep 17 00:00:00 2001 From: DmitriyNoa Date: Fri, 28 Jan 2022 16:28:17 +0100 Subject: [PATCH 7/8] Fix pr comments. Cleanup function. Simplify reaction Signed-off-by: DmitriyNoa --- src/renderer/components/dock/dock-store/dock.store.ts | 9 --------- src/renderer/components/dock/dock-tabs.tsx | 10 +++++++--- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/renderer/components/dock/dock-store/dock.store.ts b/src/renderer/components/dock/dock-store/dock.store.ts index 9de5b2d092..4c06de01dd 100644 --- a/src/renderer/components/dock/dock-store/dock.store.ts +++ b/src/renderer/components/dock/dock-store/dock.store.ts @@ -233,15 +233,6 @@ export class DockStore implements DockStorageState { }), reactionOpts); } - onTabsNumberChange(callback: (evt: DockTabsNumberEvent) => void) { - return reaction(() => this.tabsNumber, ((currentTabsNumber, previousTabsNumber) => { - callback({ - currentTabsNumber, - previousTabsNumber, - }); - })); - } - hasTabs() { return this.tabs.length > 0; } diff --git a/src/renderer/components/dock/dock-tabs.tsx b/src/renderer/components/dock/dock-tabs.tsx index 482f114e8c..c83c7094c6 100644 --- a/src/renderer/components/dock/dock-tabs.tsx +++ b/src/renderer/components/dock/dock-tabs.tsx @@ -4,6 +4,7 @@ */ import React, { Fragment, useRef, useEffect, useState, UIEvent } from "react"; +import { reaction } from "mobx"; import { Icon } from "../icon"; import { Tabs } from "../tabs/tabs"; import { DockTab } from "./dock-tab"; @@ -109,9 +110,12 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab, dockStore window.addEventListener("resize", onWindowResize); // update scroll state if tabs numbers has changed - dockStore.onTabsNumberChange(() => { - updateStateValues(); - }); + reaction(() => dockStore.tabsNumber, updateStateValues); + + return () => { + window.removeEventListener("resize", onWindowResize); + elem.current.removeEventListener("scroll", updateScrollPosition); + }; }, []); return ( From 70c3d03f21a822804e3fd70e623c79003079e469 Mon Sep 17 00:00:00 2001 From: DmitriyNoa Date: Mon, 31 Jan 2022 09:49:04 +0100 Subject: [PATCH 8/8] Add disposer cleanup Signed-off-by: DmitriyNoa --- src/renderer/components/dock/dock-tabs.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/renderer/components/dock/dock-tabs.tsx b/src/renderer/components/dock/dock-tabs.tsx index c83c7094c6..ac6da79f0b 100644 --- a/src/renderer/components/dock/dock-tabs.tsx +++ b/src/renderer/components/dock/dock-tabs.tsx @@ -110,11 +110,12 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab, dockStore window.addEventListener("resize", onWindowResize); // update scroll state if tabs numbers has changed - reaction(() => dockStore.tabsNumber, updateStateValues); + const onTabsNumberChangedDisposer = reaction(() => dockStore.tabsNumber, updateStateValues); return () => { window.removeEventListener("resize", onWindowResize); elem.current.removeEventListener("scroll", updateScrollPosition); + onTabsNumberChangedDisposer(); }; }, []);