214 lines
6.4 KiB
TypeScript

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 { OlTooltip } from "./oltooltip";
import { computeBrightness, setOpacity } from "../../other/utils";
import { colors } from "../../constants/constants";
export function OlStateButton(props: {
className?: string;
buttonColor?: string;
checked: boolean;
icon?: IconProp;
tooltip?: string | (() => JSX.Element | JSX.Element[]);
tooltipPosition?: string;
tooltipRelativeToParent?: boolean;
onClick: () => void;
onMouseUp?: () => void;
onMouseDown?: () => void;
children?: JSX.Element | JSX.Element[];
}) {
const [hover, setHover] = useState(false);
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
const className =
(props.className ?? "") +
`
pointer-events-auto h-[40px] w-[40px] flex-none rounded-md text-lg
font-medium
dark:bg-olympus-600 dark:text-gray-300
`;
return (
<>
<button
ref={buttonRef}
onClick={(e) => {
e.stopPropagation();
props.onClick();
props.onClick ?? setHover(false);
}}
onMouseUp={props.onMouseUp ?? (() => {})}
onMouseDown={props.onMouseDown ?? (() => {})}
data-checked={props.checked}
type="button"
className={className}
style={{
border: props.buttonColor ? "2px solid " + props.buttonColor : "0px solid transparent",
background: setOpacity(
props.checked || hover ? (props.buttonColor ? props.buttonColor : colors.OLYMPUS_LIGHT_BLUE) : colors.OLYMPUS_BLUE,
!props.checked && hover ? 0.3 : 1
),
}}
onMouseEnter={() => {
setHoverTimeout(
window.setTimeout(() => {
setHover(true);
setHoverTimeout(null);
}, 400)
);
}}
onMouseLeave={() => {
setHover(false);
if (hoverTimeout) {
window.clearTimeout(hoverTimeout);
setHoverTimeout(null);
}
}}
>
<div className={`m-auto flex w-fit content-center justify-center gap-2`}>
{props.icon && (
<FontAwesomeIcon
icon={props.icon}
data-bright={props.buttonColor && props.checked && computeBrightness(props.buttonColor) > 200}
className={`
m-auto text-gray-200
data-[bright='true']:text-gray-800
`}
/>
)}
{props.children}
</div>
</button>
{hover && props.tooltip && (
<OlTooltip
buttonRef={buttonRef}
content={typeof props.tooltip === "string" ? props.tooltip : props.tooltip()}
position={props.tooltipPosition}
relativeToParent={props.tooltipRelativeToParent}
/>
)}
</>
);
}
export function OlRoundStateButton(props: {
className?: string;
checked: boolean;
icon: IconProp;
tooltip?: string | (() => JSX.Element | JSX.Element[]);
tooltipPosition?: string;
onClick: () => void;
}) {
const [hover, setHover] = useState(false);
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
const className =
(props.className ?? "") +
`
m-auto h-8 w-8 flex-none rounded-full border-2 border-gray-900 text-sm
font-medium
dark:border-gray-400 dark:bg-[transparent] dark:text-gray-400
dark:hover:bg-gray-800 dark:data-[checked='true']:border-white
dark:data-[checked='true']:bg-white
dark:data-[checked='true']:text-gray-900
dark:data-[checked='true']:hover:border-gray-200
dark:data-[checked='true']:hover:bg-gray-200
`;
return (
<>
<button
ref={buttonRef}
onClick={() => {
props.onClick();
setHover(false);
}}
data-checked={props.checked}
type="button"
className={className}
onMouseEnter={() => {
setHoverTimeout(
window.setTimeout(() => {
setHover(true);
setHoverTimeout(null);
}, 400)
);
}}
onMouseLeave={() => {
setHover(false);
if (hoverTimeout) {
window.clearTimeout(hoverTimeout);
setHoverTimeout(null);
}
}}
>
<FontAwesomeIcon className="pt-[3px]" icon={props.icon} />
</button>
{hover && props.tooltip && (
<OlTooltip buttonRef={buttonRef} content={typeof props.tooltip === "string" ? props.tooltip : props.tooltip()} position={props.tooltipPosition} />
)}
</>
);
}
export function OlLockStateButton(props: {
className?: string;
checked: boolean;
tooltip?: string | (() => JSX.Element | JSX.Element[]);
tooltipPosition?: string;
onClick: () => void;
}) {
const [hover, setHover] = useState(false);
const [hoverTimeout, setHoverTimeout] = useState(null as number | null);
var buttonRef = useRef(null);
const className =
(props.className ?? "") +
`
m-auto h-8 w-8 flex-none rounded-full border-gray-900 text-sm font-medium
dark:bg-red-500 dark:text-olympus-900 dark:hover:bg-red-400
dark:data-[checked='true']:bg-green-500
dark:data-[checked='true']:text-green-900
dark:data-[checked='true']:hover:bg-green-400
`;
return (
<>
<button
ref={buttonRef}
onClick={() => {
props.onClick();
setHover(false);
}}
data-checked={props.checked}
type="button"
className={className}
onMouseEnter={() => {
setHoverTimeout(
window.setTimeout(() => {
setHover(true);
setHoverTimeout(null);
}, 400)
);
}}
onMouseLeave={() => {
setHover(false);
if (hoverTimeout) {
window.clearTimeout(hoverTimeout);
setHoverTimeout(null);
}
}}
>
<FontAwesomeIcon className="pt-[3px]" icon={props.checked == true ? faUnlockAlt : faLock} />
</button>
{hover && props.tooltip && (
<OlTooltip buttonRef={buttonRef} content={typeof props.tooltip === "string" ? props.tooltip : props.tooltip()} position={props.tooltipPosition} />
)}
</>
);
}