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:
martylukyy 2024-02-27 12:24:17 +01:00 committed by GitHub
parent fdea29103d
commit 35566039d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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"