Now use Tippy for Tooltips

This commit is contained in:
DrMint 2022-03-13 14:54:56 +01:00
parent 3873ef44f9
commit d2294393b5
11 changed files with 238 additions and 196 deletions

52
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@fontsource/opendyslexic": "^4.5.2", "@fontsource/opendyslexic": "^4.5.2",
"@fontsource/vollkorn": "^4.5.4", "@fontsource/vollkorn": "^4.5.4",
"@fontsource/zen-maru-gothic": "^4.5.5", "@fontsource/zen-maru-gothic": "^4.5.5",
"@tippyjs/react": "^4.2.6",
"markdown-to-jsx": "^7.1.7", "markdown-to-jsx": "^7.1.7",
"next": "^12.1.0", "next": "^12.1.0",
"react": "17.0.2", "react": "17.0.2",
@ -447,12 +448,34 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@popperjs/core": {
"version": "2.11.3",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.3.tgz",
"integrity": "sha512-8U7hIl7+30XbIrJ0deQMXpXESM1L4yrt6BHok5hzcR0LivivuNkk+tHU1iRVScOwCmQcrOr6kvtIr29MNbQHqQ==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rushstack/eslint-patch": { "node_modules/@rushstack/eslint-patch": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
"integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==", "integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==",
"dev": true "dev": true
}, },
"node_modules/@tippyjs/react": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
"dependencies": {
"tippy.js": "^6.3.1"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/@types/json5": { "node_modules/@types/json5": {
"version": "0.0.29", "version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -3409,6 +3432,14 @@
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true "dev": true
}, },
"node_modules/tippy.js": {
"version": "6.3.7",
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
"dependencies": {
"@popperjs/core": "^2.9.0"
}
},
"node_modules/to-regex-range": { "node_modules/to-regex-range": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -3894,12 +3925,25 @@
"fastq": "^1.6.0" "fastq": "^1.6.0"
} }
}, },
"@popperjs/core": {
"version": "2.11.3",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.3.tgz",
"integrity": "sha512-8U7hIl7+30XbIrJ0deQMXpXESM1L4yrt6BHok5hzcR0LivivuNkk+tHU1iRVScOwCmQcrOr6kvtIr29MNbQHqQ=="
},
"@rushstack/eslint-patch": { "@rushstack/eslint-patch": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
"integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==", "integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==",
"dev": true "dev": true
}, },
"@tippyjs/react": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
"requires": {
"tippy.js": "^6.3.1"
}
},
"@types/json5": { "@types/json5": {
"version": "0.0.29", "version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -6013,6 +6057,14 @@
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true "dev": true
}, },
"tippy.js": {
"version": "6.3.7",
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
"requires": {
"@popperjs/core": "^2.9.0"
}
},
"to-regex-range": { "to-regex-range": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",

View File

@ -13,6 +13,7 @@
"@fontsource/opendyslexic": "^4.5.2", "@fontsource/opendyslexic": "^4.5.2",
"@fontsource/vollkorn": "^4.5.4", "@fontsource/vollkorn": "^4.5.4",
"@fontsource/zen-maru-gothic": "^4.5.5", "@fontsource/zen-maru-gothic": "^4.5.5",
"@tippyjs/react": "^4.2.6",
"markdown-to-jsx": "^7.1.7", "markdown-to-jsx": "^7.1.7",
"next": "^12.1.0", "next": "^12.1.0",
"react": "17.0.2", "react": "17.0.2",

View File

@ -3,16 +3,12 @@ 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] hover:opacity-100 ${props.className} `} className={`grid relative 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>

View File

@ -6,7 +6,6 @@ import {
GetWebsiteInterfaceQuery, GetWebsiteInterfaceQuery,
} from "graphql/operations-types"; } from "graphql/operations-types";
import { getStatusDescription } from "queries/helpers"; import { getStatusDescription } from "queries/helpers";
import { useState } from "react";
export type ChronologyItemComponentProps = { export type ChronologyItemComponentProps = {
item: GetChronologyItemsQuery["chronologyItems"]["data"][number]; item: GetChronologyItemsQuery["chronologyItems"]["data"][number];
@ -18,7 +17,6 @@ export default function ChronologyItemComponent(
props: ChronologyItemComponentProps props: ChronologyItemComponentProps
): JSX.Element { ): JSX.Element {
const { langui } = props; const { langui } = props;
const [statusHovered, setStatusHovered] = useState(false);
function generateAnchor(year: number, month: number, day: number): string { function generateAnchor(year: number, month: number, day: number): string {
let result: string = ""; let result: string = "";
@ -93,23 +91,12 @@ export default function ChronologyItemComponent(
<div className="place-items-start place-content-start grid grid-flow-col gap-2"> <div className="place-items-start place-content-start grid grid-flow-col gap-2">
{translation.status !== {translation.status !==
Enum_Componenttranslationschronologyitem_Status.Done && ( Enum_Componenttranslationschronologyitem_Status.Done && (
<Chip <ToolTip
onMouseEnter={() => setStatusHovered(true)} content={getStatusDescription(translation.status, langui)}
onMouseLeave={() => setStatusHovered(false)} maxWidth={"20rem"}
> >
{translation.status} <Chip>{translation.status}</Chip>
<ToolTip </ToolTip>
direction="top"
hovered={statusHovered}
offset={"1.5rem"}
maxWidth="max-w-[10rem]"
delayShow={100}
>
<p>
{getStatusDescription(translation.status, langui)}
</p>
</ToolTip>
</Chip>
)} )}
{translation.title ? <h3>{translation.title}</h3> : ""} {translation.title ? <h3>{translation.title}</h3> : ""}
</div> </div>

View File

@ -1,6 +1,6 @@
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import Link from "next/link"; import Link from "next/link";
import { MouseEventHandler, useState } from "react"; import { MouseEventHandler } from "react";
import ToolTip from "components/ToolTip"; import ToolTip from "components/ToolTip";
type NavOptionProps = { type NavOptionProps = {
@ -23,34 +23,39 @@ 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> <ToolTip
<div content={
onClick={props.onClick} <div>
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"
} ${divCommon}`}
>
{props.icon && (
<span className="material-icons mt-[.1em]">{props.icon}</span>
)}
{!props.reduced && (
<div>
<h3 className="text-2xl">{props.title}</h3>
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
</div>
)}
<ToolTip hovered={hovered} direction="right" offset="3.5rem">
<h3 className="text-2xl">{props.title}</h3> <h3 className="text-2xl">{props.title}</h3>
{props.subtitle && <p className="col-start-2">{props.subtitle}</p>} {props.subtitle && <p className="col-start-2">{props.subtitle}</p>}
</ToolTip> </div>
</div> }
</Link> placement="right"
className="text-left"
disabled={!props.reduced}
>
<Link href={props.url} passHref>
<div
onClick={props.onClick}
className={`relative grid grid-flow-col grid-cols-[auto] auto-cols-fr justify-center ${
props.icon ? "text-left" : "text-center"
} ${divCommon}`}
>
{props.icon && (
<span className="material-icons mt-[.1em]">{props.icon}</span>
)}
{!props.reduced && (
<div>
<h3 className="text-2xl">{props.title}</h3>
{props.subtitle && (
<p className="col-start-2">{props.subtitle}</p>
)}
</div>
)}
</div>
</Link>
</ToolTip>
); );
} }

View File

@ -7,6 +7,7 @@ import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
import Markdown from "markdown-to-jsx"; import Markdown from "markdown-to-jsx";
import { useMediaDesktop } from "hooks/useMediaQuery"; import { useMediaDesktop } from "hooks/useMediaQuery";
import { useAppLayout } from "contexts/AppLayoutContext"; import { useAppLayout } from "contexts/AppLayoutContext";
import ToolTip from "components/ToolTip";
type MainPanelProps = { type MainPanelProps = {
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]; langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
@ -62,49 +63,74 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
: "flex-row" : "flex-row"
} flex-wrap gap-2`} } flex-wrap gap-2`}
> >
<Button <ToolTip
className={ content={<h3 className="text-2xl">{"Open settings"}</h3>}
appLayout.mainPanelReduced && isDesktop ? "" : "!py-0.5 !px-2.5" placement="right"
} className="text-left"
onClick={() => { disabled={!appLayout.mainPanelReduced}
appLayout.setConfigPanelOpen(true);
}}
> >
<span
className={`material-icons ${
!(appLayout.mainPanelReduced && isDesktop) && "!text-sm"
} `}
>
settings
</span>
</Button>
{router.locale && (
<Button <Button
onClick={() => appLayout.setLanguagePanelOpen(true)}
className={ className={
appLayout.mainPanelReduced && isDesktop appLayout.mainPanelReduced && isDesktop
? "" ? ""
: "!py-0.5 !px-2.5 !text-sm" : "!py-0.5 !px-2.5"
} }
onClick={() => {
appLayout.setConfigPanelOpen(true);
}}
> >
{router.locale.toUpperCase()} <span
className={`material-icons ${
!(appLayout.mainPanelReduced && isDesktop) && "!text-sm"
} `}
>
settings
</span>
</Button> </Button>
</ToolTip>
{router.locale && (
<ToolTip
content={<h3 className="text-2xl">{"Change language"}</h3>}
placement="right"
className="text-left"
disabled={!appLayout.mainPanelReduced}
>
<Button
onClick={() => appLayout.setLanguagePanelOpen(true)}
className={
appLayout.mainPanelReduced && isDesktop
? ""
: "!py-0.5 !px-2.5 !text-sm"
}
>
{router.locale.toUpperCase()}
</Button>
</ToolTip>
)} )}
<Button <ToolTip
className={ content={<h3 className="text-2xl">{"Open search"}</h3>}
appLayout.mainPanelReduced && isDesktop ? "" : "!py-0.5 !px-2.5" placement="right"
} className="text-left"
disabled={!appLayout.mainPanelReduced}
> >
<span <Button
className={`material-icons ${ className={
!(appLayout.mainPanelReduced && isDesktop) && "!text-sm" appLayout.mainPanelReduced && isDesktop
} `} ? ""
: "!py-0.5 !px-2.5"
}
> >
search <span
</span> className={`material-icons ${
</Button> !(appLayout.mainPanelReduced && isDesktop) && "!text-sm"
} `}
>
search
</span>
</Button>
</ToolTip>
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,7 +3,6 @@ import {
GetContentTextQuery, GetContentTextQuery,
GetWebsiteInterfaceQuery, GetWebsiteInterfaceQuery,
} from "graphql/operations-types"; } from "graphql/operations-types";
import { useState } from "react";
import Img, { ImageQuality } from "./Img"; import Img, { ImageQuality } from "./Img";
import ToolTip from "./ToolTip"; import ToolTip from "./ToolTip";
@ -17,24 +16,9 @@ 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 <ToolTip
key={recorder.id} content={
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{recorder.attributes.anonymize
? `Recorder#${recorder.attributes.anonymous_code}`
: recorder.attributes.username}
<ToolTip
hovered={hovered}
direction="top"
offset="1.5rem"
delayShow={150}
>
<div className="p-2 py-5 grid gap-2"> <div className="p-2 py-5 grid gap-2">
<div className="grid grid-flow-col gap-2 place-items-center place-content-start"> <div className="grid grid-flow-col gap-2 place-items-center place-content-start">
{recorder.attributes.avatar.data && ( {recorder.attributes.avatar.data && (
@ -68,7 +52,14 @@ export default function RecorderChip(props: RecorderChipProps): JSX.Element {
recorder.attributes.bio[0].bio} recorder.attributes.bio[0].bio}
</p> </p>
</div> </div>
</ToolTip> }
</Chip> placement="top"
>
<Chip key={recorder.id}>
{recorder.attributes.anonymize
? `Recorder#${recorder.attributes.anonymous_code}`
: recorder.attributes.username}
</Chip>
</ToolTip>
); );
} }

View File

@ -1,82 +1,17 @@
import { useEffect, useState } from "react"; import Tippy, { TippyProps } from "@tippyjs/react";
type ToolTipProps = { interface ToolTipProps extends TippyProps {}
hovered: boolean;
children: React.ReactNode;
direction: "right" | "bottom" | "top" | "left";
offset: string;
delayShow?: number;
maxWidth?: "max-w-[10rem]" | "max-w-xs" | "max-w-sm" | "max-w-md";
};
export default function ToolTip(props: ToolTipProps): JSX.Element { export default function ToolTip(props: ToolTipProps): JSX.Element {
const { children, hovered, direction, offset } = props; let newProps = { ...props };
let { delayShow, maxWidth } = props;
if (delayShow === undefined) delayShow = 300;
if (maxWidth === undefined) maxWidth = "max-w-sm";
const [show, setShow] = useState(false); // Set defaults
if (newProps.delay === undefined) newProps.delay = [150, 0];
useEffect(() => { if (newProps.interactive === undefined) newProps.interactive = true;
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 ( return (
<div <Tippy {...newProps}>
className={`fixed z-[100] drop-shadow-shade-xl transition-opacity ${maxWidth} ${ <div>{props.children}</div>
show </Tippy>
? "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-4 px-6 bg-light rounded-md">{children}</div>
</div>
); );
} }

View File

@ -2,7 +2,7 @@ import type { AppProps } from "next/app";
import "tailwind.css"; import "tailwind.css";
import "@fontsource/zen-maru-gothic/500.css"; import "@fontsource/zen-maru-gothic/500.css";
import "@fontsource/vollkorn/700.css"; import "@fontsource/vollkorn/700.css";
import "@fontsource/opendyslexic/400.css" import "@fontsource/opendyslexic/400.css";
import "@fontsource/material-icons"; import "@fontsource/material-icons";
import { AppContextProvider } from "contexts/AppLayoutContext"; import { AppContextProvider } from "contexts/AppLayoutContext";

View File

@ -28,7 +28,6 @@ import RecorderChip from "components/RecorderChip";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import TOC from "components/Markdown/TOC"; import TOC from "components/Markdown/TOC";
import ToolTip from "components/ToolTip"; import ToolTip from "components/ToolTip";
import { useState } from "react";
interface ContentReadProps extends AppStaticProps { interface ContentReadProps extends AppStaticProps {
content: GetContentTextQuery["contents"]["data"][number]["attributes"]; content: GetContentTextQuery["contents"]["data"][number]["attributes"];
@ -40,8 +39,6 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
const { langui, content, languages } = props; const { langui, content, languages } = props;
const router = useRouter(); const router = useRouter();
const [statusHovered, setStatusHovered] = useState(false);
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<ReturnButton <ReturnButton
@ -82,23 +79,12 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
<div className="grid grid-flow-col place-items-center place-content-center gap-2"> <div className="grid grid-flow-col place-items-center place-content-center gap-2">
<p className="font-headers">{langui.status}:</p> <p className="font-headers">{langui.status}:</p>
<Chip <ToolTip
onMouseEnter={() => setStatusHovered(true)} content={getStatusDescription(content.text_set[0].status, langui)}
onMouseLeave={() => setStatusHovered(false)} maxWidth={"20rem"}
> >
{content.text_set[0].status} <Chip>{content.text_set[0].status}</Chip>
<ToolTip </ToolTip>
direction="top"
hovered={statusHovered}
offset={"1.5rem"}
maxWidth="max-w-[10rem]"
delayShow={100}
>
<p>
{getStatusDescription(content.text_set[0].status, langui)}
</p>
</ToolTip>
</Chip>
</div> </div>
{content.text_set[0].transcribers.data.length > 0 && ( {content.text_set[0].transcribers.data.length > 0 && (

View File

@ -25,7 +25,7 @@
} }
mark { mark {
@apply bg-mid px-2 @apply bg-mid px-2;
} }
/* SCROLLBARS STYLING */ /* SCROLLBARS STYLING */
@ -142,3 +142,66 @@
@apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm]; @apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm];
} }
} }
.tippy-box[data-animation="fade"][data-state="hidden"] {
@apply opacity-0;
}
[data-tippy-root] {
max-width: calc(100vw - 10px);
}
.tippy-box {
@apply relative bg-light drop-shadow-shade-xl rounded-lg transition-[transform,_visibility,_opacity];
}
.tippy-box[data-placement^="top"] > .tippy-arrow {
@apply bottom-0;
}
.tippy-box[data-placement^="top"] > .tippy-arrow:before {
bottom: -7px;
left: 0;
border-width: 8px 8px 0;
border-top-color: initial;
transform-origin: center top;
}
.tippy-box[data-placement^="bottom"] > .tippy-arrow {
top: 0;
}
.tippy-box[data-placement^="bottom"] > .tippy-arrow:before {
top: -7px;
left: 0;
border-width: 0 8px 8px;
border-bottom-color: initial;
transform-origin: center bottom;
}
.tippy-box[data-placement^="left"] > .tippy-arrow {
right: 0;
}
.tippy-box[data-placement^="left"] > .tippy-arrow:before {
border-width: 8px 0 8px 8px;
border-left-color: initial;
right: -7px;
transform-origin: center left;
}
.tippy-box[data-placement^="right"] > .tippy-arrow {
left: 0;
}
.tippy-box[data-placement^="right"] > .tippy-arrow:before {
left: -7px;
border-width: 8px 8px 8px 0;
border-right-color: initial;
transform-origin: center right;
}
.tippy-box[data-inertia][data-state="visible"] {
transition-timing-function: cubic-bezier(0.54, 1.5, 0.38, 1.11);
}
.tippy-arrow {
@apply h-4 w-4 text-light;
}
.tippy-arrow:before {
content: "";
position: absolute;
border-color: transparent;
border-style: solid;
}
.tippy-content {
@apply relative px-6 py-4 z-10;
}