Skip to content

Commit

Permalink
refactor: tooltip on focus for mobile mode
Browse files Browse the repository at this point in the history
  • Loading branch information
yvesfracari committed Nov 26, 2024
1 parent 2c58c01 commit 4a3d68d
Showing 1 changed file with 49 additions and 26 deletions.
75 changes: 49 additions & 26 deletions packages/cow-hooks-ui/src/ui/TooltipBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
InfoCircledIcon,
QuestionMarkCircledIcon,
} from "@radix-ui/react-icons";
import { useState } from "react";
import { useEffect, useRef, useState } from "react";

export const InfoTooltip = ({
text,
Expand All @@ -22,6 +22,35 @@ export const InfoTooltip = ({
className?: string;
}) => {
const [isOpen, setIsOpen] = useState(false);
const tooltipRef = useRef<HTMLButtonElement | null>(null);
const preventClose = useRef(false);

useEffect(() => {
const handleClickOutside = (event: MouseEvent | TouchEvent) => {
if (preventClose.current) {
preventClose.current = false;
return;
}

const target = event.target as Node;
if (tooltipRef.current?.contains(target)) {
return;
}

setIsOpen(false);
};

// Handle both mouse and touch events
document.addEventListener("mousedown", handleClickOutside, true);
document.addEventListener("touchstart", handleClickOutside, true);
document.addEventListener("click", handleClickOutside, true);

return () => {
document.removeEventListener("mousedown", handleClickOutside, true);
document.removeEventListener("touchstart", handleClickOutside, true);
document.removeEventListener("click", handleClickOutside, true);
};
}, []);

if (!text) return null;

Expand All @@ -36,30 +65,13 @@ export const InfoTooltip = ({
}
}

const handleTouch = (e: React.TouchEvent) => {
const handleClick = (e: React.MouseEvent | React.TouchEvent) => {
e.preventDefault();
setIsOpen(true);
// Auto-hide tooltip after 1.5 seconds on mobile
setTimeout(() => setIsOpen(false), 1500);
};

const handleClick = (e: React.MouseEvent) => {
// For desktop clicks, toggle the tooltip
setIsOpen(!isOpen);
// Prevent click from bubbling up
e.stopPropagation();
preventClose.current = true;
setIsOpen(true);
};

// Close tooltip when clicking outside
const handleOutsideClick = () => {
setIsOpen(false);
};

// Add event listener for outside clicks
if (typeof window !== "undefined") {
window.addEventListener("click", handleOutsideClick);
}

return (
<Tooltip
side={side}
Expand All @@ -69,14 +81,17 @@ export const InfoTooltip = ({
className="bg-color-paper-darker text-color-text touch-none rounded-xl"
>
<TooltipTrigger
onFocusCapture={(e) => {
ref={tooltipRef}
type="button"
onMouseDownCapture={handleClick}
onTouchStartCapture={handleClick}
onClickCapture={(e) => {
e.preventDefault();
e.stopPropagation();
}}
onTouchStart={handleTouch}
onClick={handleClick}
type="button"
className={cn(
"cursor-pointer hover:text-primary touch-manipulation",
"cursor-pointer hover:text-primary",
isOpen ? "text-primary" : "",
className,
)}
>
Expand All @@ -85,6 +100,14 @@ export const InfoTooltip = ({
href={link}
target="_blank"
rel="noreferrer"
onMouseDownCapture={(e) => {
e.stopPropagation();
preventClose.current = true;
}}
onTouchStartCapture={(e) => {
e.stopPropagation();
preventClose.current = true;
}}
onClick={(e) => e.stopPropagation()}
>
<Icon />
Expand Down

0 comments on commit 4a3d68d

Please sign in to comment.