fix(web): tooltips (#1154)

* fix broken tooltips, replace react-tooltip with react-popper-tooltip

* make tooltips use ExternalLink component

* fix import

* get rid of unused import

* fix(tooltip): set delayHide

* removed unecessary comment

* fix tooltip on mobile

* stop tooltip label propagation (mainly for mobile devices)

* added onClick convenience prop for label component wrapper (since onClick isn't propagated down)

---------

Co-authored-by: soup <soup@r4tio.dev>
This commit is contained in:
stacksmash76 2023-10-01 13:16:05 +00:00 committed by GitHub
parent 98df0c9040
commit 3e3454724b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 1171 additions and 396 deletions

View file

@ -1,16 +0,0 @@
/*
* Copyright (c) 2021 - 2023, Ludvig Lundgren and the autobrr contributors.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.react-tooltip code {
background-color: rgb(63, 71, 94);
padding-left: 4px;
padding-right: 4px;
padding-top: 2px;
padding-bottom: 2px;
}
.react-tooltip a:hover {
text-decoration-line: underline;
}

View file

@ -1,40 +0,0 @@
/*
* Copyright (c) 2021 - 2023, Ludvig Lundgren and the autobrr contributors.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import { PlacesType, Tooltip } from "react-tooltip";
import "./CustomTooltip.css";
interface CustomTooltipProps {
anchorId: string;
children?: React.ReactNode;
clickable?: boolean;
place?: PlacesType;
}
export const CustomTooltip = ({
anchorId,
children,
clickable = true,
place = "top"
}: CustomTooltipProps) => {
const id = `${anchorId}-tooltip`;
return (
<div className="flex items-center">
<svg id={id} className="ml-1 w-4 h-4 text-gray-500 dark:text-gray-400 fill-current" viewBox="0 0 72 72"><path d="M32 2C15.432 2 2 15.432 2 32s13.432 30 30 30s30-13.432 30-30S48.568 2 32 2m5 49.75H27v-24h10v24m-5-29.5a5 5 0 1 1 0-10a5 5 0 0 1 0 10"/></svg>
<Tooltip
style={{ maxWidth: "350px", fontSize: "12px", textTransform: "none", fontWeight: "normal", borderRadius: "0.375rem", backgroundColor: "#34343A", color: "#fff" }}
delayShow={100}
delayHide={150}
place={place}
anchorSelect={id}
data-html={true}
clickable={clickable}
>
{children}
</Tooltip>
</div>
);
};

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2021 - 2023, Ludvig Lundgren and the autobrr contributors.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import { Tooltip } from "./Tooltip";
interface DocsTooltipProps {
label?: React.ReactNode;
children?: React.ReactNode;
}
export const DocsTooltip = ({ label, children }: DocsTooltipProps) => (
<Tooltip
label={
<div className="flex flex-row items-center">
{label ?? null}
<svg className="ml-1 w-4 h-4 text-gray-500 dark:text-gray-400 fill-current" viewBox="0 0 72 72"><path d="M32 2C15.432 2 2 15.432 2 32s13.432 30 30 30s30-13.432 30-30S48.568 2 32 2m5 49.75H27v-24h10v24m-5-29.5a5 5 0 1 1 0-10a5 5 0 0 1 0 10" /></svg>
</div>
}
>
{children}
</Tooltip>
);

View file

@ -3,22 +3,30 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import * as React from "react";
import type { ReactNode } from "react";
import { Transition } from "@headlessui/react";
import { usePopperTooltip } from "react-popper-tooltip";
import { classNames } from "@utils";
interface TooltipProps {
label: ReactNode;
onLabelClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
title?: ReactNode;
maxWidth?: string;
requiresClick?: boolean;
children: ReactNode;
}
// NOTE(stacksmash76): onClick is not propagated
// to the label (always-visible) component, so you will have
// to use the `onLabelClick` prop in this case.
export const Tooltip = ({
label,
onLabelClick,
title,
children,
requiresClick,
maxWidth = "max-w-sm"
}: TooltipProps) => {
const {
@ -28,22 +36,46 @@ export const Tooltip = ({
setTriggerRef,
visible
} = usePopperTooltip({
trigger: ["click"],
interactive: false
trigger: requiresClick ? ["click"] : ["click", "hover"],
interactive: !requiresClick,
delayHide: 200
});
if (!children || Array.isArray(children) && !children.length) {
return null;
}
return (
<>
<div ref={setTriggerRef} className="truncate">
<div
ref={setTriggerRef}
className="truncate"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
onLabelClick?.(e);
}}
>
{label}
</div>
{visible && (
<Transition
show={visible}
className="z-10"
enter="transition duration-200 ease-out"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition duration-200 ease-in"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div
ref={setTooltipRef}
{...getTooltipProps({
className: classNames(
maxWidth,
"rounded-md border border-gray-300 text-black text-xs shadow-lg dark:text-white dark:border-gray-700 dark:shadow-2xl"
"rounded-md border border-gray-300 text-black text-xs normal-case tracking-normal font-normal shadow-lg dark:text-white dark:border-gray-700 dark:shadow-2xl"
)
})}
>
@ -55,13 +87,13 @@ export const Tooltip = ({
<div
className={classNames(
title ? "" : "rounded-t-md",
"py-1 px-2 rounded-b-md bg-white dark:bg-gray-900"
"whitespace-normal break-words py-1 px-2 rounded-b-md bg-white dark:bg-gray-900"
)}
>
{children}
</div>
</div>
)}
</Transition>
</>
);
};
};