React | 호버시 나타나는 tooltip

샘샘·2024년 6월 27일
0

React

목록 보기
27/31

디자인 기획
느낌표 아이콘에 마우스 호버 시, 물량 추출 실패 툴팁 보이게 하기

<Tooltip
            componentsProps={{
              tooltip: {
                sx: {
                  padding: "0px",
                  backgroundColor: "#191919cc",
                  opacity: "0.8",
                  borderRadius: "6px",
                },
              },
              popper: {
                sx: {
                  marginLeft: "92px !important",
                  marginTop: "-49px !important",
                },
              },
            }}
            title={<FailedTooltip />}
          >
            <CalculateButton
              sx={{ position: "relative" }}
              disabled={loading}
              onClick={handleClick}
            >
              <Box
                sx={{
                  position: "absolute",
                  width: "16px",
                  top: "-4px",
                  right: "0px",
                }}
              >
                <ExclamIcon />
              </Box>
              <CalculatorIcon />
              계산하기
            </CalculateButton>
          </Tooltip>
// 수정 전 FailedTooltip.tsx
import Box from "@mui/material/Box";
import { ExclamIcon } from "components";

const FailedTooltip = () => {
return (
    <Box
      sx={{
        padding: "4px 8px",
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        gap: "6px",
      }}
    >
      <ExclamIcon />
      물량 추출 실패
    </Box>
  );
};

export default FailedTooltip;

처음엔 muiTooltip을 사용했다
계산하기 버튼 전체에 position: relative를 주고
Tooltip으로 감싼 후에 아이콘에 position: absolute를 주어서 띄웠다

호버 전 느낌표 위에 tooltip 자체가 겹쳐지게 구현했다
그랬더니 반응형으로 화면폭이 변할 때마다 툴팁이 느낌표를 따라가지 못하고 위치를 못 잡는 것이었다..! 😰

어떡하나 고민하다가 책임님께 질문!

const [showTooltip, setShowTooltip] = React.useState(false);

const hoverIcon = () => {
    setShowTooltip(true);
  };

const leaveIcon = () => {
    setShowTooltip(false);
  };

const failedTooltipProps = { showTooltip, hoverIcon, leaveIcon };

<CalculateButton
            sx={{ position: "relative" }}
            disabled={loading}
            onClick={handleClick}
          >
            <FailedTooltip {...failedTooltipProps} />
            <CalculatorIcon />
            계산하기
          </CalculateButton>

계산하기 버튼 전체에 position: relative를 준건 그대로 두고
boolean 타입의 state를 만들어서 호버를 하면 true, 안하면 false의 핸들러를 만들어서
FailedTooltip이라는 컴포넌트에 props를 줬다

// 수정 후 FailedTooltip.tsx
import { ExclamIcon } from "components";
import { FailedBox, FailedTypo } from "./style";

interface PropType {
  showTooltip: boolean;
  hoverIcon: () => void;
  leaveIcon: () => void;
}

const FailedTooltip = (props: PropType) => {
const { showTooltip, hoverIcon, leaveIcon } = props;
return (
    <FailedBox show={showTooltip.toString()}>
      <ExclamIcon onMouseEnter={hoverIcon} onMouseLeave={leaveIcon} />
      <FailedTypo show={showTooltip.toString()}>물량 추출 실패</FailedTypo>
    </FailedBox>
  );
};

export default FailedTooltip;

이렇게 생긴 Box를 일단 만들기!
그리고 역시 내 생각은 좁았다고 생각했던 부분👇👇

// style.ts
export const FailedBox = styled(Box)((props: { visible: string }) => ({
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  gap: 6,
  minHeight: 28,
  background: props.visible === "true" ? "rgba(25, 25, 25, 0.80)" : "none",
  borderRadius: 6,
  padding: "4px 8px",
  position: "absolute",
  right: "-80px",
  top: "-3px",
  svg: {
    width: 16,
    height: 16,
    ":hover": {
      cursor: "pointer",
    },
  },
}));

export const FailedTypo = styled(Box)((props: { visible: string }) => ({
  color: colors.white,
  fontSize: 12,
  fontWeight: 500,
  letterSpacing: -0.3,
  lineHeight: "20px",
  opacity: props.visible === "true" ? 1 : 0,
}));

각 스타일에 show라는 props를 줘서 아까 만들어준 호버의 상태값인
showTooltip을 넘겨줬다

그렇게 해서 true라면 배경색과 글자가 보이게 하고 아니면 none,,, 🤯
나는 정말 상상도 못 해본 방법이다

이렇게 하니까 화면폭이 어떻든지 툴팁이 제 위치에 잘 보이게 되었고
아이콘을 하나로 사용해서 겹치게 구현할 일도 없게 됐다!!

profile
회계팀 출신 FE개발자 👉콘테크 회사에서 웹개발을 하고 있습니다

0개의 댓글