1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Fix flickering and arrows position

Signed-off-by: DmitriyNoa <dmytro.zharkov@gmail.com>
This commit is contained in:
DmitriyNoa 2022-01-28 15:03:57 +01:00
parent 411c28d969
commit 1d79392668
5 changed files with 62 additions and 30 deletions

View File

@ -49,6 +49,7 @@ const getComponent = (dockStore: DockStore) => (
selectedTab={dockStore.selectedTab} selectedTab={dockStore.selectedTab}
autoFocus={true} autoFocus={true}
onChangeTab={noop} onChangeTab={noop}
dockStore={dockStore}
/> />
); );

View File

@ -97,6 +97,11 @@ export interface DockTabCloseEvent {
tabId: TabId; // closed tab id tabId: TabId; // closed tab id
} }
export interface DockTabsNumberEvent {
currentTabsNumber: number; // number of open tabs
previousTabsNumber: number;
}
interface Dependencies { interface Dependencies {
storage: StorageHelper<DockStorageState> storage: StorageHelper<DockStorageState>
} }
@ -160,6 +165,10 @@ export class DockStore implements DockStorageState {
this.dependencies.storage.merge({ selectedTabId: tabId }); this.dependencies.storage.merge({ selectedTabId: tabId });
} }
@computed get tabsNumber() : number {
return this.tabs.length;
}
@computed get selectedTab() { @computed get selectedTab() {
return this.tabs.find(tab => tab.id === this.selectedTabId); return this.tabs.find(tab => tab.id === this.selectedTabId);
} }
@ -224,6 +233,15 @@ export class DockStore implements DockStorageState {
}), reactionOpts); }), reactionOpts);
} }
onTabsNumberChange(callback: (evt: DockTabsNumberEvent) => void) {
return reaction(() => this.tabsNumber, ((currentTabsNumber, previousTabsNumber) => {
callback({
currentTabsNumber,
previousTabsNumber,
});
}));
}
hasTabs() { hasTabs() {
return this.tabs.length > 0; return this.tabs.length > 0;
} }

View File

@ -8,17 +8,18 @@ import { Icon } from "../icon";
import { Tabs } from "../tabs/tabs"; import { Tabs } from "../tabs/tabs";
import { DockTab } from "./dock-tab"; import { DockTab } from "./dock-tab";
import type { DockTab as DockTabModel } from "./dock-store/dock.store"; 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"; import { TerminalTab } from "./terminal-tab";
interface Props { interface Props {
tabs: DockTabModel[] tabs: DockTabModel[]
dockStore: DockStore;
autoFocus: boolean autoFocus: boolean
selectedTab: DockTabModel selectedTab: DockTabModel
onChangeTab: (tab: DockTabModel) => void 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 elem = useRef(null);
const contentElem = useRef(null); const contentElem = useRef(null);
const [contentWidth, setContentWidth] = useState(0); const [contentWidth, setContentWidth] = useState(0);
@ -27,7 +28,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) =
const scrollStep = 200; const scrollStep = 200;
const scrollToRight = (): void => { const scrollToRight = (): void => {
if(!elem || scrollPosition + scrollStep > contentWidth) return; if(!elem || scrollPosition === contentWidth) return;
const scroll = scrollPosition + scrollStep; const scroll = scrollPosition + scrollStep;
setScrollPosition(scroll); setScrollPosition(scroll);
@ -35,6 +36,14 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) =
elem.current.scrollLeft = scroll; 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 => { const scrollToLeft = (): void => {
if(!elem) return; if(!elem) return;
const scroll = scrollPosition - scrollStep; const scroll = scrollPosition - scrollStep;
@ -47,13 +56,15 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) =
const isScrollableRight = (): boolean => { const isScrollableRight = (): boolean => {
if(!elem || !contentElem) return false; 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 => { const isScrollableLeft = (): boolean => {
if(!elem || !contentElem) return false; if(!elem || !contentElem) return false;
return scrollPosition > scrollStep; return scrollPosition > 0;
}; };
const updateScrollPosition = ( evt: UIEvent<HTMLDivElement>): void => { const updateScrollPosition = ( evt: UIEvent<HTMLDivElement>): void => {
@ -65,11 +76,7 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) =
}; };
const onWindowResize = (): void => { const onWindowResize = (): void => {
if(!elem || !contentElem) return; updateStateValues();
setContentWidth(contentElem.current.clientWidth);
setContainerWidth(elem.current.clientWidth);
setScrollPosition(elem.current.scrollLeft);
}; };
const renderTab = (tab?: DockTabModel) => { const renderTab = (tab?: DockTabModel) => {
@ -93,17 +100,18 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) =
useEffect(() => { useEffect(() => {
if(!elem || !contentElem) return; updateStateValues();
setContentWidth(contentElem.current.clientWidth);
setContainerWidth(elem.current.clientWidth);
setScrollPosition(elem.current.scrollLeft);
// update values in store on scroll // update values in store on scroll
elem.current.addEventListener("scroll", updateScrollPosition); elem.current.addEventListener("scroll", updateScrollPosition);
// update current values on resize to show/hide scroll // update current values on resize to show/hide scroll
window.addEventListener("resize", onWindowResize); window.addEventListener("resize", onWindowResize);
// update scroll state if tabs numbers has changed
dockStore.onTabsNumberChange(() => {
updateStateValues();
});
}, []); }, []);
return ( return (

View File

@ -60,6 +60,10 @@
.tabs-wrapper { .tabs-wrapper {
overflow: hidden; overflow: hidden;
width: 100%;
box-sizing: border-box;
position: relative;
padding: 0 $padding*2.5;
} }
.tab-content { .tab-content {
@ -83,7 +87,7 @@
.tabs-control { .tabs-control {
overflow: auto; overflow: auto;
position: relative; width: 100%;
&::-webkit-scrollbar { &::-webkit-scrollbar {
visibility: hidden; visibility: hidden;
@ -100,20 +104,6 @@
&:hover::-webkit-scrollbar-thumb { &:hover::-webkit-scrollbar-thumb {
background: var(--scrollBarColor); background: var(--scrollBarColor);
} }
.tab-control {
position: absolute;
z-index: 9999;
}
.scroll-left {
left: 0;
}
.right {
right: 0;
}
} }
.DockTab.active { .DockTab.active {
@ -123,4 +113,18 @@
color: var(--terminalWhite); color: var(--terminalWhite);
} }
} }
.tab-control {
position: absolute;
z-index: 9999;
}
.scroll-left {
left: 0;
}
.scroll-right {
right: 0;
}
} }

View File

@ -157,6 +157,7 @@ class NonInjectedDock extends React.Component<Props & Dependencies> {
selectedTab={selectedTab} selectedTab={selectedTab}
autoFocus={isOpen} autoFocus={isOpen}
onChangeTab={this.onChangeTab} onChangeTab={this.onChangeTab}
dockStore={dockStore}
/> />
<div className="toolbar flex gaps align-center box grow"> <div className="toolbar flex gaps align-center box grow">
<div className="dock-menu box grow"> <div className="dock-menu box grow">