working on a hover state for the headers

This commit is contained in:
sawka 2024-06-14 10:46:03 -07:00
parent ab785aa992
commit 29c2b6bc7f
3 changed files with 84 additions and 2 deletions

View file

@ -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;

View file

@ -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>

View file

@ -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;
} }