mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add tabs controlls
Signed-off-by: DmitriyNoa <dmytro.zharkov@gmail.com>
This commit is contained in:
parent
f74d78566a
commit
5f192f6712
@ -28,10 +28,6 @@
|
|||||||
padding-right: $padding;
|
padding-right: $padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
padding-right: $padding;
|
padding-right: $padding;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,7 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* 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 { Icon } from "../icon";
|
||||||
import { Tabs } from "../tabs/tabs";
|
import { Tabs } from "../tabs/tabs";
|
||||||
import { DockTab } from "./dock-tab";
|
import { DockTab } from "./dock-tab";
|
||||||
@ -20,6 +19,43 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: 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) => {
|
const renderTab = (tab?: DockTabModel) => {
|
||||||
if (!tab) {
|
if (!tab) {
|
||||||
return null;
|
return null;
|
||||||
@ -39,14 +75,46 @@ export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
elem.current.addEventListener("scroll", ( evt: UIEvent<HTMLDivElement>) => {
|
||||||
|
const position = evt.currentTarget.scrollLeft;
|
||||||
|
|
||||||
|
if (position!== undefined) {
|
||||||
|
setScrollPosition(position);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<div style={{ overflow: "hidden" }} className={"flex gaps align-center"}>
|
||||||
className="DockTabs"
|
{isScrollableLeft() && (
|
||||||
autoFocus={autoFocus}
|
<Icon
|
||||||
value={selectedTab}
|
material="keyboard_arrow_left"
|
||||||
onChange={onChangeTab}
|
tooltip="Show tabs to the left"
|
||||||
>
|
onClick={scrollToLeft}
|
||||||
{tabs.map(tab => <Fragment key={tab.id}>{renderTab(tab)}</Fragment>)}
|
className={"tab-control scroll-left"}
|
||||||
</Tabs>
|
/>
|
||||||
|
)}
|
||||||
|
<div ref={elem} className={"tabs-control flex gaps align-center"}>
|
||||||
|
<div ref={contentElem} className={"scrollable"}>
|
||||||
|
<Tabs
|
||||||
|
className="DockTabs"
|
||||||
|
autoFocus={autoFocus}
|
||||||
|
value={selectedTab}
|
||||||
|
onChange={onChangeTab}
|
||||||
|
>
|
||||||
|
{tabs.map(tab => <Fragment key={tab.id}>{renderTab(tab)}</Fragment>)}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{isScrollableRight() && (
|
||||||
|
<Icon
|
||||||
|
material="keyboard_arrow_right"
|
||||||
|
tooltip="Show tabs to the right"
|
||||||
|
onClick={scrollToRight}
|
||||||
|
className={"tab-control scroll-right"}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -76,4 +76,47 @@
|
|||||||
bottom: 0;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import "./dock.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
import { cssNames, prevDefault } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { MenuItem } from "../menu";
|
import { MenuItem } from "../menu";
|
||||||
import { MenuActions } from "../menu/menu-actions";
|
import { MenuActions } from "../menu/menu-actions";
|
||||||
@ -91,20 +91,6 @@ class NonInjectedDock extends React.Component<Props & Dependencies> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
renderTabContent() {
|
||||||
const { isOpen, height, selectedTab } = this.props.dockStore;
|
const { isOpen, height, selectedTab } = this.props.dockStore;
|
||||||
|
|
||||||
@ -138,7 +124,7 @@ class NonInjectedDock extends React.Component<Props & Dependencies> {
|
|||||||
onMinExtentExceed={dockStore.open}
|
onMinExtentExceed={dockStore.open}
|
||||||
onDrag={extent => dockStore.height = extent}
|
onDrag={extent => dockStore.height = extent}
|
||||||
/>
|
/>
|
||||||
<div className="tabs-container flex align-center" onDoubleClick={prevDefault(toggle)}>
|
<div className="tabs-container flex align-center">
|
||||||
<DockTabs
|
<DockTabs
|
||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
selectedTab={selectedTab}
|
selectedTab={selectedTab}
|
||||||
@ -146,11 +132,6 @@ class NonInjectedDock extends React.Component<Props & Dependencies> {
|
|||||||
onChangeTab={this.onChangeTab}
|
onChangeTab={this.onChangeTab}
|
||||||
/>
|
/>
|
||||||
<div className="toolbar flex gaps align-center box grow">
|
<div className="toolbar flex gaps align-center box grow">
|
||||||
<Icon
|
|
||||||
material="keyboard_arrow_right"
|
|
||||||
tooltip="Show tabs to the right"
|
|
||||||
onClick={this.scrollToRight}
|
|
||||||
/>
|
|
||||||
<div className="dock-menu box grow">
|
<div className="dock-menu box grow">
|
||||||
<MenuActions usePortal triggerIcon={{ material: "add", className: "new-dock-tab", tooltip: "New tab" }} closeOnScroll={false}>
|
<MenuActions usePortal triggerIcon={{ material: "add", className: "new-dock-tab", tooltip: "New tab" }} closeOnScroll={false}>
|
||||||
<MenuItem className="create-terminal-tab" onClick={() => this.props.createTerminalTab()}>
|
<MenuItem className="create-terminal-tab" onClick={() => this.props.createTerminalTab()}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user