fix: Added callback to close all tooltips on click

This commit is contained in:
Davide Passoni 2025-03-31 11:29:00 +02:00
parent 1bca2e5c26
commit 266326c40c
8 changed files with 144 additions and 87 deletions

View File

@ -1,6 +1,6 @@
import { IconProp } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { OlTooltip } from "./oltooltip";
export function OlButtonGroup(props: {
@ -12,6 +12,13 @@ export function OlButtonGroup(props: {
const [hover, setHover] = useState(false);
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
return (
<>
<div

View File

@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { Coalition } from "../../types/types";
import { OlTooltip } from "./oltooltip";
@ -15,69 +15,74 @@ export function OlCoalitionToggle(props: {
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
return (
<>
<div
className="inline-flex cursor-pointer items-center"
onClick={(e) => {
e.stopPropagation();
props.onClick();
props.onClick ?? setHover(false);
}}
onMouseEnter={() => {
setHoverTimeout(
window.setTimeout(() => {
setHover(true);
setHoverTimeout(null);
}, 400)
);
}}
onMouseLeave={() => {
setHover(false);
if (hoverTimeout) {
window.clearTimeout(hoverTimeout);
setHoverTimeout(null);
}
}}
ref={buttonRef}
>
<button className="peer sr-only" />
<div
data-flash={props.coalition === undefined}
data-coalition={props.coalition ?? "blue"}
className={`
${props.className ?? ""}
peer relative h-7 w-14 rounded-full bg-gray-200
after:absolute after:start-[4px] after:top-0.5 after:h-6 after:w-6
after:rounded-full after:border after:border-gray-300 after:bg-white
after:transition-all after:content-['']
dark:border-gray-600 dark:peer-focus:ring-blue-800
data-[coalition='blue']:bg-blue-600
data-[coalition='neutral']:bg-gray-400
data-[coalition='neutral']:after:translate-x-[50%]
data-[coalition='neutral']:after:border-white
data-[coalition='red']:bg-red-500
data-[coalition='red']:after:translate-x-full
data-[coalition='red']:after:border-white
peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-300
rtl:data-[coalition='neutral']:after:-translate-x-[50%]
rtl:data-[coalition='red']:after:-translate-x-full
`}
></div>
{props.showLabel && (
<span
className="inline-flex cursor-pointer items-center"
onClick={(e) => {
e.stopPropagation();
props.onClick();
props.onClick ?? setHover(false);
}}
onMouseEnter={() => {
setHoverTimeout(
window.setTimeout(() => {
setHover(true);
setHoverTimeout(null);
}, 400)
);
}}
onMouseLeave={() => {
setHover(false);
if (hoverTimeout) {
window.clearTimeout(hoverTimeout);
setHoverTimeout(null);
}
}}
ref={buttonRef}
>
<button className="peer sr-only" />
<div
data-flash={props.coalition === undefined}
data-coalition={props.coalition ?? "blue"}
className={`
ms-3 overflow-hidden text-ellipsis text-nowrap text-gray-900
dark:text-white
data-[flash='true']:after:animate-pulse
${props.className ?? ""}
peer relative h-7 w-14 rounded-full bg-gray-200
after:absolute after:start-[4px] after:top-0.5 after:h-6 after:w-6
after:rounded-full after:border after:border-gray-300 after:bg-white
after:transition-all after:content-['']
dark:border-gray-600 dark:peer-focus:ring-blue-800
data-[coalition='blue']:bg-blue-600
data-[coalition='neutral']:bg-gray-400
data-[coalition='neutral']:after:translate-x-[50%]
data-[coalition='neutral']:after:border-white
data-[coalition='red']:bg-red-500
data-[coalition='red']:after:translate-x-full
data-[coalition='red']:after:border-white
peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-300
rtl:data-[coalition='neutral']:after:-translate-x-[50%]
rtl:data-[coalition='red']:after:-translate-x-full
`}
>
{props.coalition ? `${props.coalition[0].toLocaleUpperCase() + props.coalition.substring(1)}` : "Diff. values"}
</span>
)}
</div>
{hover && props.tooltip && (
></div>
{props.showLabel && (
<span
className={`
ms-3 overflow-hidden text-ellipsis text-nowrap text-gray-900
dark:text-white
data-[flash='true']:after:animate-pulse
`}
>
{props.coalition ? `${props.coalition[0].toLocaleUpperCase() + props.coalition.substring(1)}` : "Diff. values"}
</span>
)}
</div>
{hover && props.tooltip && (
<OlTooltip
buttonRef={buttonRef}
content={typeof props.tooltip === "string" ? props.tooltip : props.tooltip()}

View File

@ -22,6 +22,12 @@ export function OlDropdown(props: {
var contentRef = useRef(null);
var buttonRef = props.buttonRef !== undefined ? props.buttonRef : useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
function setPosition(content: HTMLDivElement, button: HTMLButtonElement) {
/* Reset the position of the content */
content.style.left = "0px";
@ -126,12 +132,9 @@ export function OlDropdown(props: {
}
}}
>
{props.leftIcon && (
<FontAwesomeIcon
icon={props.leftIcon}
className={`mr-3`}
/>
)}
{props.leftIcon && <FontAwesomeIcon icon={props.leftIcon} className={`
mr-3
`} />}
<span className="overflow-hidden text-ellipsis text-nowrap">{props.label ?? ""}</span>
<svg
className={`

View File

@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { OlTooltip } from "./oltooltip";
export function OlLabelToggle(props: {
@ -14,6 +14,12 @@ export function OlLabelToggle(props: {
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
return (
<>
<button

View File

@ -1,4 +1,4 @@
import React, { ChangeEvent, useRef, useState } from "react";
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
import { zeroAppend } from "../../other/utils";
import { OlTooltip } from "./oltooltip";
@ -20,6 +20,12 @@ export function OlNumberInput(props: {
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
return (
<div
className={`

View File

@ -1,7 +1,7 @@
import { IconProp } from "@fortawesome/fontawesome-svg-core";
import { faLock, faUnlockAlt } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { OlTooltip } from "./oltooltip";
import { computeBrightness, setOpacity } from "../../other/utils";
import { colors } from "../../constants/constants";
@ -24,6 +24,12 @@ export function OlStateButton(props: {
const [isMouseHovering, setIsMouseHovering] = useState(false);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
const className =
(props.className ?? "") +
`
@ -109,6 +115,12 @@ export function OlRoundStateButton(props: {
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
const className =
(props.className ?? "") +
`
@ -169,6 +181,12 @@ export function OlLockStateButton(props: {
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
const className =
(props.className ?? "") +
`

View File

@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { OlTooltip } from "./oltooltip";
export function OlToggle(props: {
@ -12,6 +12,12 @@ export function OlToggle(props: {
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
return (
<>
<div

View File

@ -1,9 +1,7 @@
import React, { useEffect, useState } from "react";
import { UnitBlueprint } from "../../interfaces";
import { Coalition } from "../../types/types";
import { getWikipediaImage, getWikipediaSummary } from "../../other/utils";
import { OlStateButton } from "./olstatebutton";
import { faImage } from "@fortawesome/free-solid-svg-icons";
import { getWikipediaImage } from "../../other/utils";
import { FaQuestionCircle } from "react-icons/fa";
export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coalition }) {
@ -12,6 +10,12 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
const [hover, setHover] = useState(false);
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
useEffect(() => {
window.addEventListener("click", (e) => {
setHover(false);
});
}, []);
useEffect(() => {
getWikipediaImage(props.blueprint.label).then((url) => {
setImageUrl(url);
@ -63,9 +67,7 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
</div>
{imageUrl && (
<div className="flex w-full min-w-0 gap-1 text-sm text-gray-500">
<FaQuestionCircle
className={`my-auto min-w-4`}
/>
<FaQuestionCircle className={`my-auto min-w-4`} />
<div className={`my-auto max-w-full truncate`}>Hover to show image</div>
</div>
)}
@ -82,17 +84,21 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
</div>
<div className="flex flex-row gap-1 px-2">
{props.blueprint.abilities?.split(" ").map((ability) => {
return <>{ ability.replaceAll(" ", "") !== "" &&
<div
key={ability}
className={`
rounded-full bg-olympus-800 px-2 py-0.5 text-xs font-bold
dark:text-olympus-50
`}
>
{ability}
</div>
}</>
return (
<>
{ability.replaceAll(" ", "") !== "" && (
<div
key={ability}
className={`
rounded-full bg-olympus-800 px-2 py-0.5 text-xs font-bold
dark:text-olympus-50
`}
>
{ability}
</div>
)}
</>
);
})}
<div