mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
fix: Added callback to close all tooltips on click
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { OlTooltip } from "./oltooltip";
|
import { OlTooltip } from "./oltooltip";
|
||||||
|
|
||||||
export function OlButtonGroup(props: {
|
export function OlButtonGroup(props: {
|
||||||
@@ -12,6 +12,13 @@ export function OlButtonGroup(props: {
|
|||||||
const [hover, setHover] = useState(false);
|
const [hover, setHover] = useState(false);
|
||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { Coalition } from "../../types/types";
|
import { Coalition } from "../../types/types";
|
||||||
import { OlTooltip } from "./oltooltip";
|
import { OlTooltip } from "./oltooltip";
|
||||||
|
|
||||||
@@ -15,69 +15,74 @@ export function OlCoalitionToggle(props: {
|
|||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
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
|
<div
|
||||||
data-flash={props.coalition === undefined}
|
className="inline-flex cursor-pointer items-center"
|
||||||
data-coalition={props.coalition ?? "blue"}
|
onClick={(e) => {
|
||||||
className={`
|
e.stopPropagation();
|
||||||
${props.className ?? ""}
|
props.onClick();
|
||||||
peer relative h-7 w-14 rounded-full bg-gray-200
|
props.onClick ?? setHover(false);
|
||||||
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
|
onMouseEnter={() => {
|
||||||
after:transition-all after:content-['']
|
setHoverTimeout(
|
||||||
dark:border-gray-600 dark:peer-focus:ring-blue-800
|
window.setTimeout(() => {
|
||||||
data-[coalition='blue']:bg-blue-600
|
setHover(true);
|
||||||
data-[coalition='neutral']:bg-gray-400
|
setHoverTimeout(null);
|
||||||
data-[coalition='neutral']:after:translate-x-[50%]
|
}, 400)
|
||||||
data-[coalition='neutral']:after:border-white
|
);
|
||||||
data-[coalition='red']:bg-red-500
|
}}
|
||||||
data-[coalition='red']:after:translate-x-full
|
onMouseLeave={() => {
|
||||||
data-[coalition='red']:after:border-white
|
setHover(false);
|
||||||
peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-300
|
if (hoverTimeout) {
|
||||||
rtl:data-[coalition='neutral']:after:-translate-x-[50%]
|
window.clearTimeout(hoverTimeout);
|
||||||
rtl:data-[coalition='red']:after:-translate-x-full
|
setHoverTimeout(null);
|
||||||
`}
|
}
|
||||||
></div>
|
}}
|
||||||
{props.showLabel && (
|
ref={buttonRef}
|
||||||
<span
|
>
|
||||||
|
<button className="peer sr-only" />
|
||||||
|
<div
|
||||||
|
data-flash={props.coalition === undefined}
|
||||||
|
data-coalition={props.coalition ?? "blue"}
|
||||||
className={`
|
className={`
|
||||||
ms-3 overflow-hidden text-ellipsis text-nowrap text-gray-900
|
${props.className ?? ""}
|
||||||
dark:text-white
|
peer relative h-7 w-14 rounded-full bg-gray-200
|
||||||
data-[flash='true']:after:animate-pulse
|
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.coalition ? `${props.coalition[0].toLocaleUpperCase() + props.coalition.substring(1)}` : "Diff. values"}
|
{props.showLabel && (
|
||||||
</span>
|
<span
|
||||||
)}
|
className={`
|
||||||
|
ms-3 overflow-hidden text-ellipsis text-nowrap text-gray-900
|
||||||
</div>
|
dark:text-white
|
||||||
{hover && props.tooltip && (
|
data-[flash='true']:after:animate-pulse
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{props.coalition ? `${props.coalition[0].toLocaleUpperCase() + props.coalition.substring(1)}` : "Diff. values"}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{hover && props.tooltip && (
|
||||||
<OlTooltip
|
<OlTooltip
|
||||||
buttonRef={buttonRef}
|
buttonRef={buttonRef}
|
||||||
content={typeof props.tooltip === "string" ? props.tooltip : props.tooltip()}
|
content={typeof props.tooltip === "string" ? props.tooltip : props.tooltip()}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ export function OlDropdown(props: {
|
|||||||
var contentRef = useRef(null);
|
var contentRef = useRef(null);
|
||||||
var buttonRef = props.buttonRef !== undefined ? props.buttonRef : useRef(null);
|
var buttonRef = props.buttonRef !== undefined ? props.buttonRef : useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
function setPosition(content: HTMLDivElement, button: HTMLButtonElement) {
|
function setPosition(content: HTMLDivElement, button: HTMLButtonElement) {
|
||||||
/* Reset the position of the content */
|
/* Reset the position of the content */
|
||||||
content.style.left = "0px";
|
content.style.left = "0px";
|
||||||
@@ -126,12 +132,9 @@ export function OlDropdown(props: {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.leftIcon && (
|
{props.leftIcon && <FontAwesomeIcon icon={props.leftIcon} className={`
|
||||||
<FontAwesomeIcon
|
mr-3
|
||||||
icon={props.leftIcon}
|
`} />}
|
||||||
className={`mr-3`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<span className="overflow-hidden text-ellipsis text-nowrap">{props.label ?? ""}</span>
|
<span className="overflow-hidden text-ellipsis text-nowrap">{props.label ?? ""}</span>
|
||||||
<svg
|
<svg
|
||||||
className={`
|
className={`
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { OlTooltip } from "./oltooltip";
|
import { OlTooltip } from "./oltooltip";
|
||||||
|
|
||||||
export function OlLabelToggle(props: {
|
export function OlLabelToggle(props: {
|
||||||
@@ -14,6 +14,12 @@ export function OlLabelToggle(props: {
|
|||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -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 { zeroAppend } from "../../other/utils";
|
||||||
import { OlTooltip } from "./oltooltip";
|
import { OlTooltip } from "./oltooltip";
|
||||||
|
|
||||||
@@ -20,6 +20,12 @@ export function OlNumberInput(props: {
|
|||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
||||||
import { faLock, faUnlockAlt } from "@fortawesome/free-solid-svg-icons";
|
import { faLock, faUnlockAlt } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { OlTooltip } from "./oltooltip";
|
import { OlTooltip } from "./oltooltip";
|
||||||
import { computeBrightness, setOpacity } from "../../other/utils";
|
import { computeBrightness, setOpacity } from "../../other/utils";
|
||||||
import { colors } from "../../constants/constants";
|
import { colors } from "../../constants/constants";
|
||||||
@@ -24,6 +24,12 @@ export function OlStateButton(props: {
|
|||||||
const [isMouseHovering, setIsMouseHovering] = useState(false);
|
const [isMouseHovering, setIsMouseHovering] = useState(false);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const className =
|
const className =
|
||||||
(props.className ?? "") +
|
(props.className ?? "") +
|
||||||
`
|
`
|
||||||
@@ -109,6 +115,12 @@ export function OlRoundStateButton(props: {
|
|||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const className =
|
const className =
|
||||||
(props.className ?? "") +
|
(props.className ?? "") +
|
||||||
`
|
`
|
||||||
@@ -169,6 +181,12 @@ export function OlLockStateButton(props: {
|
|||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const className =
|
const className =
|
||||||
(props.className ?? "") +
|
(props.className ?? "") +
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { OlTooltip } from "./oltooltip";
|
import { OlTooltip } from "./oltooltip";
|
||||||
|
|
||||||
export function OlToggle(props: {
|
export function OlToggle(props: {
|
||||||
@@ -12,6 +12,12 @@ export function OlToggle(props: {
|
|||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
var buttonRef = useRef(null);
|
var buttonRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { UnitBlueprint } from "../../interfaces";
|
import { UnitBlueprint } from "../../interfaces";
|
||||||
import { Coalition } from "../../types/types";
|
import { Coalition } from "../../types/types";
|
||||||
import { getWikipediaImage, getWikipediaSummary } from "../../other/utils";
|
import { getWikipediaImage } from "../../other/utils";
|
||||||
import { OlStateButton } from "./olstatebutton";
|
|
||||||
import { faImage } from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import { FaQuestionCircle } from "react-icons/fa";
|
import { FaQuestionCircle } from "react-icons/fa";
|
||||||
|
|
||||||
export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coalition }) {
|
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 [hover, setHover] = useState(false);
|
||||||
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
setHover(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getWikipediaImage(props.blueprint.label).then((url) => {
|
getWikipediaImage(props.blueprint.label).then((url) => {
|
||||||
setImageUrl(url);
|
setImageUrl(url);
|
||||||
@@ -63,9 +67,7 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
|
|||||||
</div>
|
</div>
|
||||||
{imageUrl && (
|
{imageUrl && (
|
||||||
<div className="flex w-full min-w-0 gap-1 text-sm text-gray-500">
|
<div className="flex w-full min-w-0 gap-1 text-sm text-gray-500">
|
||||||
<FaQuestionCircle
|
<FaQuestionCircle className={`my-auto min-w-4`} />
|
||||||
className={`my-auto min-w-4`}
|
|
||||||
/>
|
|
||||||
<div className={`my-auto max-w-full truncate`}>Hover to show image</div>
|
<div className={`my-auto max-w-full truncate`}>Hover to show image</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -82,17 +84,21 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row gap-1 px-2">
|
<div className="flex flex-row gap-1 px-2">
|
||||||
{props.blueprint.abilities?.split(" ").map((ability) => {
|
{props.blueprint.abilities?.split(" ").map((ability) => {
|
||||||
return <>{ ability.replaceAll(" ", "") !== "" &&
|
return (
|
||||||
<div
|
<>
|
||||||
key={ability}
|
{ability.replaceAll(" ", "") !== "" && (
|
||||||
className={`
|
<div
|
||||||
rounded-full bg-olympus-800 px-2 py-0.5 text-xs font-bold
|
key={ability}
|
||||||
dark:text-olympus-50
|
className={`
|
||||||
`}
|
rounded-full bg-olympus-800 px-2 py-0.5 text-xs font-bold
|
||||||
>
|
dark:text-olympus-50
|
||||||
{ability}
|
`}
|
||||||
</div>
|
>
|
||||||
}</>
|
{ability}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user