Changed Applayout from fixed to grid + using custom tooltip
This commit is contained in:
parent
f4217a597c
commit
4b30dac878
|
@ -54,27 +54,6 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mainPanelClass = `fixed desktop:left-0 desktop:top-0 desktop:bottom-0 ${
|
|
||||||
appLayout.mainPanelReduced ? "desktop:w-[6rem]" : "desktop:w-[20rem]"
|
|
||||||
}`;
|
|
||||||
const subPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:w-[20rem] ${
|
|
||||||
appLayout.mainPanelReduced ? " desktop:left-[6rem]" : "desktop:left-[20rem]"
|
|
||||||
}`;
|
|
||||||
let contentPanelClass = "";
|
|
||||||
if (subPanel) {
|
|
||||||
contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 ${
|
|
||||||
appLayout.mainPanelReduced
|
|
||||||
? "desktop:left-[26rem]"
|
|
||||||
: "desktop:left-[40rem]"
|
|
||||||
}`;
|
|
||||||
} else if (contentPanel) {
|
|
||||||
contentPanelClass = `fixed desktop:top-0 desktop:bottom-0 desktop:right-0 ${
|
|
||||||
appLayout.mainPanelReduced
|
|
||||||
? "desktop:left-[6rem]"
|
|
||||||
: "desktop:left-[20rem]"
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const turnSubIntoContent = subPanel && !contentPanel;
|
const turnSubIntoContent = subPanel && !contentPanel;
|
||||||
|
|
||||||
const titlePrefix = "Accord’s Library";
|
const titlePrefix = "Accord’s Library";
|
||||||
|
@ -115,6 +94,21 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [currencySelect]);
|
}, [currencySelect]);
|
||||||
|
|
||||||
|
let gridCol = "";
|
||||||
|
if (props.subPanel) {
|
||||||
|
if (appLayout.mainPanelReduced) {
|
||||||
|
gridCol = "grid-cols-[6rem_20rem_1fr]";
|
||||||
|
} else {
|
||||||
|
gridCol = "grid-cols-[20rem_20rem_1fr]";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (appLayout.mainPanelReduced) {
|
||||||
|
gridCol = "grid-cols-[6rem_0px_1fr]";
|
||||||
|
} else {
|
||||||
|
gridCol = "grid-cols-[20rem_0px_1fr]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
|
@ -127,7 +121,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
{...handlers}
|
{...handlers}
|
||||||
className="fixed inset-0 touch-pan-y p-0 m-0 bg-light text-black"
|
className={`fixed inset-0 touch-pan-y p-0 m-0 bg-light text-black grid [grid-template-areas:'main_sub_content'] ${gridCol} mobile:grid-cols-[1fr] mobile:grid-rows-[1fr_5rem] mobile:[grid-template-areas:'content''navbar']`}
|
||||||
>
|
>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{`${titlePrefix} - ${ogTitle}`}</title>
|
<title>{`${titlePrefix} - ${ogTitle}`}</title>
|
||||||
|
@ -157,9 +151,32 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
<meta name="twitter:image" content={metaImage.image}></meta>
|
<meta name="twitter:image" content={metaImage.image}></meta>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
|
{/* Background when navbar is opened */}
|
||||||
|
<div
|
||||||
|
className={`[grid-area:content] mobile:z-10 absolute inset-0 transition-[backdrop-filter] duration-500 ${
|
||||||
|
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
||||||
|
? "[backdrop-filter:blur(2px)]"
|
||||||
|
: "pointer-events-none touch-none "
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`absolute bg-shade inset-0 transition-opacity duration-500
|
||||||
|
${turnSubIntoContent ? "" : ""}
|
||||||
|
${
|
||||||
|
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
||||||
|
? "opacity-60"
|
||||||
|
: "opacity-0"
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
appLayout.setMainPanelOpen(false);
|
||||||
|
appLayout.setSubPanelOpen(false);
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Content panel */}
|
{/* Content panel */}
|
||||||
<div
|
<div
|
||||||
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light texture-paper-dots ${contentPanelClass}`}
|
className={`[grid-area:content] overflow-y-scroll bg-light texture-paper-dots`}
|
||||||
>
|
>
|
||||||
{contentPanel ? (
|
{contentPanel ? (
|
||||||
contentPanel
|
contentPanel
|
||||||
|
@ -173,38 +190,15 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Background when navbar is opened */}
|
|
||||||
<div
|
|
||||||
className={`fixed inset-0 transition-[backdrop-filter] duration-500 ${
|
|
||||||
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
|
||||||
? "[backdrop-filter:blur(2px)]"
|
|
||||||
: "pointer-events-none touch-none "
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`fixed bg-shade inset-0 transition-opacity duration-500
|
|
||||||
${turnSubIntoContent ? "z-10" : ""}
|
|
||||||
${
|
|
||||||
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
|
|
||||||
? "opacity-60"
|
|
||||||
: "opacity-0"
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
appLayout.setMainPanelOpen(false);
|
|
||||||
appLayout.setSubPanelOpen(false);
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Sub panel */}
|
{/* Sub panel */}
|
||||||
{subPanel && (
|
{subPanel && (
|
||||||
<div
|
<div
|
||||||
className={`${subPanelClass} border-r-[1px] mobile:bottom-20 mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
className={`[grid-area:sub] mobile:[grid-area:content] mobile:z-10 mobile:w-[90%] mobile:justify-self-end border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
||||||
${
|
${
|
||||||
turnSubIntoContent
|
turnSubIntoContent
|
||||||
? "mobile:translate-x-0 mobile:left-0 mobile:border-l-0"
|
? "mobile:border-l-0 mobile:w-full"
|
||||||
: !appLayout.subPanelOpen
|
: !appLayout.subPanelOpen
|
||||||
? "mobile:translate-x-full"
|
? "mobile:translate-x-[100vw]"
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
@ -214,28 +208,14 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
|
|
||||||
{/* Main panel */}
|
{/* Main panel */}
|
||||||
<div
|
<div
|
||||||
className={`${mainPanelClass} border-r-[1px] mobile:bottom-20 border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light texture-paper-dots
|
className={`[grid-area:main] mobile:[grid-area:content] mobile:z-10 mobile:w-[90%] mobile:justify-self-start border-r-[1px] border-black border-dotted overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
||||||
${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
||||||
>
|
>
|
||||||
<MainPanel langui={langui} />
|
<MainPanel langui={langui} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main panel minimize button*/}
|
|
||||||
<div
|
|
||||||
className={`mobile:hidden translate-x-0 fixed top-1/2 z-20 ${
|
|
||||||
appLayout.mainPanelReduced ? "left-[4.65rem]" : "left-[18.65rem]"
|
|
||||||
}`}
|
|
||||||
onClick={() =>
|
|
||||||
appLayout.setMainPanelReduced(!appLayout.mainPanelReduced)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button className="material-icons bg-light !px-2">
|
|
||||||
{appLayout.mainPanelReduced ? "chevron_right" : "chevron_left"}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Navbar */}
|
{/* Navbar */}
|
||||||
<div className="fixed inset-0 z-30 top-auto h-20 border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots">
|
<div className="[grid-area:navbar] border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots">
|
||||||
<span
|
<span
|
||||||
className="material-icons mt-[.1em] cursor-pointer"
|
className="material-icons mt-[.1em] cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
|
import { MouseEventHandler } from "react";
|
||||||
|
|
||||||
type ChipProps = {
|
type ChipProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
onMouseEnter?: MouseEventHandler<HTMLDivElement>;
|
||||||
|
onMouseLeave?: MouseEventHandler<HTMLDivElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Chip(props: ChipProps): JSX.Element {
|
export default function Chip(props: ChipProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`grid place-content-center place-items-center text-xs pb-[0.14rem] px-1.5 border-[1px] rounded-full opacity-70 transition-[color,_opacity,border-color] ${props.className} `}
|
className={`grid place-content-center place-items-center text-xs pb-[0.14rem] px-1.5 border-[1px] rounded-full opacity-70 transition-[color,_opacity,_border-color] hover:opacity-100 ${props.className} `}
|
||||||
|
onMouseEnter={props.onMouseEnter}
|
||||||
|
onMouseLeave={props.onMouseLeave}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default function LibraryItemsPreview(
|
||||||
<h3 className="mobile:text-xs leading-3">{item.subtitle}</h3>
|
<h3 className="mobile:text-xs leading-3">{item.subtitle}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full grid grid-flow-col gap-1 overflow-x-scroll webkit-scrollbar:w-0 [scrollbar-width:none] place-content-start">
|
<div className="w-full grid grid-flow-col gap-1 overflow-x-scroll webkit-scrollbar:h-0 [scrollbar-width:none] place-content-start">
|
||||||
{item.categories.data.map((category) => (
|
{item.categories.data.map((category) => (
|
||||||
<Chip key={category.id} className="text-sm">
|
<Chip key={category.id} className="text-sm">
|
||||||
{category.attributes.short}
|
{category.attributes.short}
|
||||||
|
|
|
@ -22,10 +22,18 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
||||||
slugify: slugify,
|
slugify: slugify,
|
||||||
overrides: {
|
overrides: {
|
||||||
h2: {
|
h2: {
|
||||||
component: (props: { id: string; children: React.ReactNode }) => {
|
component: (props: {
|
||||||
|
id: string;
|
||||||
|
style: React.CSSProperties;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row place-items-center place-content-center gap-3 hover:[--anchor-opacity:100] [--anchor-opacity:0]">
|
<h2
|
||||||
<h2 id={props.id}>{props.children}</h2>
|
id={props.id}
|
||||||
|
className="flex flex-row place-items-center place-content-center gap-3 hover:[--anchor-opacity:100] [--anchor-opacity:0]"
|
||||||
|
style={props.style}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
<abbr title="Copy anchor link">
|
<abbr title="Copy anchor link">
|
||||||
<span
|
<span
|
||||||
className="material-icons opacity-[var(--anchor-opacity)] transition-all hover:text-dark cursor-pointer"
|
className="material-icons opacity-[var(--anchor-opacity)] transition-all hover:text-dark cursor-pointer"
|
||||||
|
@ -41,7 +49,7 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
||||||
link
|
link
|
||||||
</span>
|
</span>
|
||||||
</abbr>
|
</abbr>
|
||||||
</div>
|
</h2>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { MouseEventHandler } from "react";
|
import { MouseEventHandler, useState } from "react";
|
||||||
|
import ToolTip from "components/ToolTip";
|
||||||
|
|
||||||
type NavOptionProps = {
|
type NavOptionProps = {
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -22,11 +23,15 @@ export default function NavOption(props: NavOptionProps): JSX.Element {
|
||||||
props.border ? border : ""
|
props.border ? border : ""
|
||||||
} ${isActive ? divActive : ""}`;
|
} ${isActive ? divActive : ""}`;
|
||||||
|
|
||||||
|
const [hovered, setHovered] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={props.url} passHref>
|
<Link href={props.url} passHref>
|
||||||
<div
|
<div
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
className={`grid grid-flow-col grid-cols-[auto] auto-cols-fr justify-center ${
|
onMouseEnter={() => props.reduced && setHovered(true)}
|
||||||
|
onMouseLeave={() => setHovered(false)}
|
||||||
|
className={`relative grid grid-flow-col grid-cols-[auto] auto-cols-fr justify-center ${
|
||||||
props.icon ? "text-left" : "text-center"
|
props.icon ? "text-left" : "text-center"
|
||||||
} ${divCommon}`}
|
} ${divCommon}`}
|
||||||
>
|
>
|
||||||
|
@ -40,6 +45,11 @@ export default function NavOption(props: NavOptionProps): JSX.Element {
|
||||||
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
|
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<ToolTip hovered={hovered} direction="right" offset="3.5rem">
|
||||||
|
<h3 className="text-2xl">{props.title}</h3>
|
||||||
|
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
|
||||||
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|
|
@ -24,6 +24,20 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
||||||
appLayout.mainPanelReduced && isDesktop && "px-4"
|
appLayout.mainPanelReduced && isDesktop && "px-4"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
{/* Reduce/expand main menu */}
|
||||||
|
<div
|
||||||
|
className={`mobile:hidden top-1/2 fixed ${
|
||||||
|
appLayout.mainPanelReduced ? "left-[4.65rem]" : "left-[18.65rem]"
|
||||||
|
}`}
|
||||||
|
onClick={() =>
|
||||||
|
appLayout.setMainPanelReduced(!appLayout.mainPanelReduced)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button className="material-icons bg-light !px-2">
|
||||||
|
{appLayout.mainPanelReduced ? "chevron_right" : "chevron_left"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div className="grid place-items-center">
|
<div className="grid place-items-center">
|
||||||
<Link href="/" passHref>
|
<Link href="/" passHref>
|
||||||
|
|
|
@ -4,7 +4,7 @@ type SubPanelProps = {
|
||||||
|
|
||||||
export default function SubPanel(props: SubPanelProps): JSX.Element {
|
export default function SubPanel(props: SubPanelProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col p-8 gap-y-2 justify-items-center text-center mobile:h-full">
|
<div className="grid pt-10 pb-20 px-6 desktop:py-8 desktop:px-10 gap-y-2 justify-items-center text-center">
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,6 +3,9 @@ import {
|
||||||
GetContentTextQuery,
|
GetContentTextQuery,
|
||||||
GetWebsiteInterfaceQuery,
|
GetWebsiteInterfaceQuery,
|
||||||
} from "graphql/operations-types";
|
} from "graphql/operations-types";
|
||||||
|
import { useState } from "react";
|
||||||
|
import Img, { ImageQuality } from "./Img";
|
||||||
|
import ToolTip from "./ToolTip";
|
||||||
|
|
||||||
type RecorderChipProps = {
|
type RecorderChipProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
@ -13,11 +16,59 @@ type RecorderChipProps = {
|
||||||
export default function RecorderChip(props: RecorderChipProps): JSX.Element {
|
export default function RecorderChip(props: RecorderChipProps): JSX.Element {
|
||||||
const recorder = props.recorder;
|
const recorder = props.recorder;
|
||||||
const langui = props.langui;
|
const langui = props.langui;
|
||||||
|
|
||||||
|
const [hovered, setHovered] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Chip key={recorder.id}>
|
<Chip
|
||||||
|
key={recorder.id}
|
||||||
|
onMouseEnter={() => setHovered(true)}
|
||||||
|
onMouseLeave={() => setHovered(false)}
|
||||||
|
>
|
||||||
{recorder.attributes.anonymize
|
{recorder.attributes.anonymize
|
||||||
? `Recorder#${recorder.attributes.anonymous_code}`
|
? `Recorder#${recorder.attributes.anonymous_code}`
|
||||||
: recorder.attributes.username}
|
: recorder.attributes.username}
|
||||||
|
|
||||||
|
<ToolTip
|
||||||
|
hovered={hovered}
|
||||||
|
direction="top"
|
||||||
|
offset="1.5rem"
|
||||||
|
delayShow={150}
|
||||||
|
>
|
||||||
|
<div className="p-2 py-5 grid gap-2">
|
||||||
|
<div className="grid grid-flow-col gap-2 place-items-center place-content-start">
|
||||||
|
{recorder.attributes.avatar.data && (
|
||||||
|
<Img
|
||||||
|
className="w-8 rounded-full"
|
||||||
|
image={recorder.attributes.avatar.data.attributes}
|
||||||
|
quality={ImageQuality.Small}
|
||||||
|
rawImg
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<h3 className="text-xl">{recorder.attributes.username}</h3>
|
||||||
|
</div>
|
||||||
|
{recorder.attributes.languages.data.length > 0 && (
|
||||||
|
<div className="flex flex-row flex-wrap gap-1">
|
||||||
|
<p>{langui.languages}:</p>
|
||||||
|
{recorder.attributes.languages.data.map((language) => (
|
||||||
|
<Chip key={language.attributes.code}>
|
||||||
|
{language.attributes.code.toUpperCase()}
|
||||||
|
</Chip>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{recorder.attributes.pronouns && (
|
||||||
|
<div className="flex flex-row flex-wrap gap-1">
|
||||||
|
<p>{langui.pronouns}:</p>
|
||||||
|
<Chip>{recorder.attributes.pronouns}</Chip>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<p>
|
||||||
|
{recorder.attributes.bio.length > 0 &&
|
||||||
|
recorder.attributes.bio[0].bio}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</ToolTip>
|
||||||
</Chip>
|
</Chip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
type ToolTipProps = {
|
||||||
|
hovered: boolean;
|
||||||
|
children: React.ReactNode;
|
||||||
|
delayShow?: number;
|
||||||
|
direction: "right" | "bottom" | "top" | "left";
|
||||||
|
offset: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ToolTip(props: ToolTipProps): JSX.Element {
|
||||||
|
const { children, hovered, direction, offset } = props;
|
||||||
|
let { delayShow } = props;
|
||||||
|
if (delayShow === undefined) delayShow = 500;
|
||||||
|
|
||||||
|
const [show, setShow] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let timeout = setTimeout(() => {});
|
||||||
|
if (hovered) {
|
||||||
|
timeout = setTimeout(() => hovered && setShow(true), delayShow);
|
||||||
|
} else {
|
||||||
|
setShow(false);
|
||||||
|
}
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}, [delayShow, hovered]);
|
||||||
|
|
||||||
|
let tooltipCSS = "";
|
||||||
|
let transformCSS = "";
|
||||||
|
let arrowParentCSS = "";
|
||||||
|
let arrowCSS = "";
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case "left":
|
||||||
|
tooltipCSS = "[justify-self:end] [align-self:center]";
|
||||||
|
transformCSS = `translateX(-${offset})`;
|
||||||
|
arrowParentCSS = "w-4 -right-4 top-0 bottom-0";
|
||||||
|
arrowCSS = "border-l-light";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "right":
|
||||||
|
tooltipCSS = "[justify-self:start] [align-self:center]";
|
||||||
|
transformCSS = `translateX(${offset})`;
|
||||||
|
arrowParentCSS = "w-4 -left-4 top-0 bottom-0";
|
||||||
|
arrowCSS = "border-r-light";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "top":
|
||||||
|
tooltipCSS = "[align-self:end]";
|
||||||
|
transformCSS = `translateY(-${offset})`;
|
||||||
|
arrowParentCSS = "h-4 -bottom-4 left-0 right-0";
|
||||||
|
arrowCSS = "border-t-light";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "bottom":
|
||||||
|
tooltipCSS = "[align-self:start]";
|
||||||
|
transformCSS = `translateY(${offset})`;
|
||||||
|
arrowParentCSS = "h-4 -top-4 left-0 right-0";
|
||||||
|
arrowCSS = "border-b-light";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`fixed z-[100] drop-shadow-shade-xl transition-opacity max-w-sm ${
|
||||||
|
show
|
||||||
|
? "opacity-100 pointer-events-auto"
|
||||||
|
: "opacity-0 pointer-events-none"
|
||||||
|
} ${tooltipCSS}`}
|
||||||
|
style={{ transform: transformCSS }}
|
||||||
|
>
|
||||||
|
<div className={`absolute grid ${arrowParentCSS}`}>
|
||||||
|
<div
|
||||||
|
className={`w-0 h-0 border-8 border-[transparent] place-self-center ${arrowCSS}`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="p-2 px-4 bg-light rounded-md">{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -15,6 +15,11 @@ export default function Home(props: HomeProps): JSX.Element {
|
||||||
const { post } = props;
|
const { post } = props;
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
|
<div className="grid place-items-center place-content-center w-full gap-5 text-center">
|
||||||
|
<div className="[mask:url('/icons/accords.svg')] [mask-size:contain] [mask-repeat:no-repeat] [mask-position:center] w-32 aspect-square mobile:w-[50vw] bg-black" />
|
||||||
|
<h1 className="text-5xl mb-0">Accord’s Library</h1>
|
||||||
|
<h2 className="text-xl -mt-5">Discover • Analyse • Translate • Archive</h2>
|
||||||
|
</div>
|
||||||
{post.translations.length > 0 && (
|
{post.translations.length > 0 && (
|
||||||
<Markdawn text={post.translations[0].body} />
|
<Markdawn text={post.translations[0].body} />
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Reference in New Issue