index.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import React from "react";
  2. import styled from "styled-components";
  3. interface TooltipProps {
  4. title?: string;
  5. }
  6. const StyledTooltipWrapper = styled.div`
  7. position: relative;
  8. width: 100%;
  9. height: 100%;
  10. `;
  11. const StyledTooltip = styled.div<{ visible: boolean }>`
  12. position: absolute;
  13. top: 0;
  14. right: 0;
  15. transform: translate(calc(100% + 15px), 10%);
  16. z-index: 5;
  17. background: ${({ theme }) => theme.BACKGROUND_PRIMARY};
  18. color: ${({ theme }) => theme.TEXT_NORMAL};
  19. border-radius: 5px;
  20. padding: 4px 8px;
  21. display: ${({ visible }) => (visible ? "initial" : "none")};
  22. white-space: nowrap;
  23. font-size: 16px;
  24. user-select: none;
  25. font-weight: 500;
  26. box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.07),
  27. 0 4px 8px rgba(0, 0, 0, 0.07), 0 8px 16px rgba(0, 0, 0, 0.07),
  28. 0 16px 32px rgba(0, 0, 0, 0.07), 0 32px 64px rgba(0, 0, 0, 0.07);
  29. &::after {
  30. content: "";
  31. position: absolute;
  32. top: 0;
  33. left: 0;
  34. transform: translate(-90%, 50%);
  35. border-width: 8px;
  36. border-style: solid;
  37. border-color: transparent ${({ theme }) => theme.BACKGROUND_PRIMARY}
  38. transparent transparent;
  39. }
  40. `;
  41. const StyledChildren = styled.div``;
  42. export const Tooltip: React.FC<React.PropsWithChildren<TooltipProps>> = ({
  43. children,
  44. title,
  45. }) => {
  46. const [visible, setVisible] = React.useState(false);
  47. return (
  48. <StyledTooltipWrapper>
  49. { title && <StyledTooltip visible={visible}>{title}</StyledTooltip>}
  50. <StyledChildren
  51. onMouseEnter={() => setVisible(true)}
  52. onMouseLeave={() => setVisible(false)}
  53. >
  54. {children}
  55. </StyledChildren>
  56. </StyledTooltipWrapper>
  57. );
  58. };