mirror of
https://github.com/wavetermdev/waveterm
synced 2026-05-24 09:18:27 +00:00
working on a hover state for the headers
This commit is contained in:
parent
ab785aa992
commit
29c2b6bc7f
3 changed files with 84 additions and 2 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.block-content {
|
.block-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -19,6 +20,23 @@
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.block-header-animation-wrap {
|
||||||
|
max-height: 0;
|
||||||
|
transition:
|
||||||
|
max-height 0.3s ease-out,
|
||||||
|
opacity 0.3s ease-out;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
z-index: var(--zindex-header-hover);
|
||||||
|
|
||||||
|
&.is-showing {
|
||||||
|
max-height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-header {
|
.block-header {
|
||||||
|
|
@ -34,6 +52,11 @@
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
|
||||||
|
.block-header-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.block-header-text {
|
.block-header-text {
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,14 @@ import { TerminalView } from "@/app/view/term";
|
||||||
import { ErrorBoundary } from "@/element/errorboundary";
|
import { ErrorBoundary } from "@/element/errorboundary";
|
||||||
import { CenteredDiv } from "@/element/quickelems";
|
import { CenteredDiv } from "@/element/quickelems";
|
||||||
import * as WOS from "@/store/wos";
|
import * as WOS from "@/store/wos";
|
||||||
|
import clsx from "clsx";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import "./block.less";
|
import "./block.less";
|
||||||
|
|
||||||
|
const HoverPixels = 15;
|
||||||
|
const HoverTimeoutMs = 100;
|
||||||
|
|
||||||
interface BlockProps {
|
interface BlockProps {
|
||||||
blockId: string;
|
blockId: string;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
|
|
@ -34,8 +38,45 @@ const BlockHeader = ({ blockId, onClose }: BlockProps) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hoverStateOff = "off";
|
||||||
|
const hoverStatePending = "pending";
|
||||||
|
const hoverStateOn = "on";
|
||||||
|
|
||||||
const Block = ({ blockId, onClose }: BlockProps) => {
|
const Block = ({ blockId, onClose }: BlockProps) => {
|
||||||
const blockRef = React.useRef<HTMLDivElement>(null);
|
const blockRef = React.useRef<HTMLDivElement>(null);
|
||||||
|
const hoverState = React.useRef(hoverStateOff);
|
||||||
|
const [showHeader, setShowHeader] = React.useState(false);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const block = blockRef.current;
|
||||||
|
let hoverTimeout: NodeJS.Timeout = null;
|
||||||
|
const handleMouseMove = (event) => {
|
||||||
|
const rect = block.getBoundingClientRect();
|
||||||
|
if (event.clientY - rect.top <= HoverPixels) {
|
||||||
|
if (hoverState.current == hoverStateOff) {
|
||||||
|
hoverTimeout = setTimeout(() => {
|
||||||
|
if (hoverState.current == hoverStatePending) {
|
||||||
|
hoverState.current = hoverStateOn;
|
||||||
|
setShowHeader(true);
|
||||||
|
}
|
||||||
|
}, HoverTimeoutMs);
|
||||||
|
hoverState.current = hoverStatePending;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hoverTimeout) {
|
||||||
|
if (hoverState.current == hoverStatePending) {
|
||||||
|
hoverState.current = hoverStateOff;
|
||||||
|
}
|
||||||
|
clearTimeout(hoverTimeout);
|
||||||
|
hoverTimeout = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
block.addEventListener("mousemove", handleMouseMove);
|
||||||
|
return () => {
|
||||||
|
block.removeEventListener("mousemove", handleMouseMove);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
let blockElem: JSX.Element = null;
|
let blockElem: JSX.Element = null;
|
||||||
const [blockData, blockDataLoading] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
|
const [blockData, blockDataLoading] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
|
||||||
|
|
@ -52,8 +93,23 @@ const Block = ({ blockId, onClose }: BlockProps) => {
|
||||||
blockElem = <CodeEdit text={null} filename={null} />;
|
blockElem = <CodeEdit text={null} filename={null} />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="block" ref={blockRef}>
|
<div
|
||||||
<BlockHeader blockId={blockId} onClose={onClose} />
|
className="block"
|
||||||
|
ref={blockRef}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
setShowHeader(false);
|
||||||
|
hoverState.current = hoverStateOff;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={clsx("block-header-animation-wrap", showHeader ? "is-showing" : null)}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
setShowHeader(false);
|
||||||
|
hoverState.current = hoverStateOff;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BlockHeader blockId={blockId} onClose={onClose} />
|
||||||
|
</div>
|
||||||
<div key="content" className="block-content">
|
<div key="content" className="block-content">
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<React.Suspense fallback={<CenteredDiv>Loading...</CenteredDiv>}>{blockElem}</React.Suspense>
|
<React.Suspense fallback={<CenteredDiv>Loading...</CenteredDiv>}>{blockElem}</React.Suspense>
|
||||||
|
|
|
||||||
|
|
@ -22,4 +22,7 @@
|
||||||
--scrollbar-background-color: var(--main-bg-color);
|
--scrollbar-background-color: var(--main-bg-color);
|
||||||
--scrollbar-thumb-color: rgba(255, 255, 255, 0.3);
|
--scrollbar-thumb-color: rgba(255, 255, 255, 0.3);
|
||||||
--scrollbar-thumb-hover-color: rgba(255, 255, 255, 0.5);
|
--scrollbar-thumb-hover-color: rgba(255, 255, 255, 0.5);
|
||||||
|
|
||||||
|
/* z-index values */
|
||||||
|
--zindex-header-hover: 100;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue