Skip to content

Commit

Permalink
utils: implement ClickAway listener on mobile TooltipButton (#562)
Browse files Browse the repository at this point in the history
  • Loading branch information
zbycz authored Sep 19, 2024
1 parent 70e2c2f commit 67c9b3d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
3 changes: 1 addition & 2 deletions src/components/FeaturePanel/Coordinates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ const StyledMenuItem = styled(MenuItem)`
` as unknown as any; // <Menu> expects "li", but it as "a"

const StyledToggleButton = styled(IconButton)`
position: absolute !important;
margin: -5px 0 0 0 !important;
margin: -10px 0 -5px 0 !important;
svg {
font-size: 17px;
Expand Down
42 changes: 33 additions & 9 deletions src/components/utils/TooltipButton.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import { IconButton, Tooltip } from '@mui/material';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import CloseIcon from '@mui/icons-material/Close';
import { SvgIconOwnProps } from '@mui/material/SvgIcon/SvgIcon';
import { isMobileDevice, useToggleState } from '../helpers';
import { isMobileDevice, useBoolState } from '../helpers';
import styled from '@emotion/styled';

type Props = {
Expand All @@ -12,34 +11,59 @@ type Props = {
color?: SvgIconOwnProps['color'];
};

const useClickAwayListener = (
tooltipRef: React.MutableRefObject<HTMLDivElement>,
hide: () => void,
isMobile: boolean,
) => {
useEffect(() => {
const clickAway = (e: MouseEvent) => {
if (e.target instanceof Node && !tooltipRef.current.contains(e.target)) {
hide();
}
};

if (isMobile) {
window.addEventListener('click', clickAway);
}

return () => {
if (isMobile) {
window.removeEventListener('click', clickAway);
}
};
}, [hide, isMobile, tooltipRef]);
};

const StyledIconButton = styled(IconButton)`
font-size: inherit;
`;

export const TooltipButton = ({ tooltip, onClick, color }: Props) => {
const isMobile = isMobileDevice();
const [mobileTooltipShown, toggleMobileTooltip] = useToggleState(false);
const tooltipRef = useRef<HTMLDivElement>(null);
const [mobileTooltipShown, show, hide] = useBoolState(false);

const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
onClick?.(e);
if (isMobile) {
toggleMobileTooltip();
show();
}
e.stopPropagation();
};

useClickAwayListener(tooltipRef, hide, isMobile);

return (
<Tooltip
arrow
title={tooltip}
placement="top"
open={isMobile ? mobileTooltipShown : undefined}
ref={tooltipRef}
>
<StyledIconButton onClick={handleClick}>
{!mobileTooltipShown && (
<InfoOutlinedIcon fontSize="inherit" color={color} />
)}
{mobileTooltipShown && <CloseIcon fontSize="inherit" color={color} />}
<InfoOutlinedIcon fontSize="small" color={color} />
</StyledIconButton>
</Tooltip>
);
Expand Down

0 comments on commit 67c9b3d

Please sign in to comment.