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:
parent
4eac1b180b
commit
948b278360
@ -49,6 +49,7 @@ const getComponent = (dockStore: DockStore) => (
|
||||
selectedTab={dockStore.selectedTab}
|
||||
autoFocus={true}
|
||||
onChangeTab={noop}
|
||||
dockStore={dockStore}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
@ -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<DockStorageState>
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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<HTMLDivElement>): 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 (
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -157,6 +157,7 @@ class NonInjectedDock extends React.Component<Props & Dependencies> {
|
||||
selectedTab={selectedTab}
|
||||
autoFocus={isOpen}
|
||||
onChangeTab={this.onChangeTab}
|
||||
dockStore={dockStore}
|
||||
/>
|
||||
<div className="toolbar flex gaps align-center box grow">
|
||||
<div className="dock-menu box grow">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user