mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
fix(web): make tooltips clickable if touchscreen is present (#1427)
* fix(web): make tooltips clickable if touchscreen is present * fix(web): handle visibility for click and touch * fix(chore): add removed license header again
This commit is contained in:
parent
fdea29103d
commit
35566039d5
1 changed files with 15 additions and 18 deletions
|
@ -14,7 +14,6 @@ import { classNames } from "@utils";
|
||||||
|
|
||||||
interface TooltipProps {
|
interface TooltipProps {
|
||||||
label: ReactNode;
|
label: ReactNode;
|
||||||
onLabelClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
||||||
title?: ReactNode;
|
title?: ReactNode;
|
||||||
maxWidth?: string;
|
maxWidth?: string;
|
||||||
requiresClick?: boolean;
|
requiresClick?: boolean;
|
||||||
|
@ -27,7 +26,6 @@ interface TooltipProps {
|
||||||
|
|
||||||
export const Tooltip = ({
|
export const Tooltip = ({
|
||||||
label,
|
label,
|
||||||
onLabelClick,
|
|
||||||
title,
|
title,
|
||||||
children,
|
children,
|
||||||
requiresClick,
|
requiresClick,
|
||||||
|
@ -36,9 +34,6 @@ export const Tooltip = ({
|
||||||
const [isTooltipVisible, setIsTooltipVisible] = useState(false);
|
const [isTooltipVisible, setIsTooltipVisible] = useState(false);
|
||||||
const [tooltipNode, setTooltipNode] = useState<HTMLDivElement | null>(null);
|
const [tooltipNode, setTooltipNode] = useState<HTMLDivElement | null>(null);
|
||||||
const [triggerNode, setTriggerNode] = useState<HTMLDivElement | null>(null);
|
const [triggerNode, setTriggerNode] = useState<HTMLDivElement | null>(null);
|
||||||
const isTouchDevice = () => {
|
|
||||||
return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// default tooltip placement to right
|
// default tooltip placement to right
|
||||||
const [placement, setPlacement] = useState<Placement>('right');
|
const [placement, setPlacement] = useState<Placement>('right');
|
||||||
|
@ -62,19 +57,23 @@ export const Tooltip = ({
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getTooltipProps,
|
getTooltipProps,
|
||||||
setTooltipRef: popperSetTooltipRef,
|
setTooltipRef: popperSetTooltipRef,
|
||||||
setTriggerRef: popperSetTriggerRef,
|
setTriggerRef: popperSetTriggerRef,
|
||||||
visible
|
visible
|
||||||
} = usePopperTooltip({
|
} = usePopperTooltip({
|
||||||
trigger: isTouchDevice() ? [] : (requiresClick ? 'click' : ['click', 'hover']),
|
trigger: requiresClick ? 'click' : ['click', 'hover'],
|
||||||
interactive: true,
|
interactive: true,
|
||||||
delayHide: 200,
|
delayHide: 200,
|
||||||
placement,
|
placement,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsTooltipVisible(!isTooltipVisible);
|
||||||
|
};
|
||||||
|
|
||||||
const handleTouch = (e: React.TouchEvent<HTMLDivElement>) => {
|
const handleTouch = (e: React.TouchEvent<HTMLDivElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsTooltipVisible(!isTooltipVisible);
|
setIsTooltipVisible(!isTooltipVisible);
|
||||||
|
@ -90,35 +89,33 @@ export const Tooltip = ({
|
||||||
setTriggerNode(node);
|
setTriggerNode(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClickOutside = useCallback((event: TouchEvent) => {
|
const handleClickOutside = useCallback((event: MouseEvent | TouchEvent) => {
|
||||||
if (tooltipNode && !tooltipNode.contains(event.target as Node) && triggerNode && !triggerNode.contains(event.target as Node)) {
|
if (tooltipNode && !tooltipNode.contains(event.target as Node) && triggerNode && !triggerNode.contains(event.target as Node)) {
|
||||||
setIsTooltipVisible(false);
|
setIsTooltipVisible(false);
|
||||||
}
|
}
|
||||||
}, [tooltipNode, triggerNode]);
|
}, [tooltipNode, triggerNode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.addEventListener('touchstart', handleClickOutside, true);
|
document.addEventListener('touchstart', handleClickOutside as EventListener, true);
|
||||||
|
document.addEventListener('mousedown', handleClickOutside as EventListener, true);
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener('touchstart', handleClickOutside, true);
|
document.removeEventListener('touchstart', handleClickOutside as EventListener, true);
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside as EventListener, true);
|
||||||
};
|
};
|
||||||
}, [handleClickOutside, tooltipNode, triggerNode]);
|
}, [handleClickOutside]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
ref={setTriggerRef}
|
ref={setTriggerRef}
|
||||||
className="truncate"
|
className="truncate"
|
||||||
onClick={(e) => {
|
onClick={handleClick}
|
||||||
if (!isTouchDevice() && !visible) {
|
onTouchStart={handleTouch}
|
||||||
onLabelClick?.(e);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onTouchStart={isTouchDevice() ? handleTouch : undefined}
|
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</div>
|
</div>
|
||||||
<Transition
|
<Transition
|
||||||
show={isTouchDevice() ? isTooltipVisible : visible}
|
show={isTooltipVisible || visible}
|
||||||
className="z-10"
|
className="z-10"
|
||||||
enter="transition duration-200 ease-out"
|
enter="transition duration-200 ease-out"
|
||||||
enterFrom="opacity-0"
|
enterFrom="opacity-0"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue