index.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import React from "react";
  2. import styled from "styled-components";
  3. interface TooltipProps extends React.ComponentPropsWithoutRef<"div"> {
  4. title?: string;
  5. }
  6. const StyledTooltipWrapper = styled.div`
  7. position: relative;
  8. width: fit-content;
  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), 25%);
  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. @media only screen and (max-width: 768px) {
  41. display: none;
  42. }
  43. `;
  44. const StyledChildren = styled.div``;
  45. export const Tooltip: React.FC<React.PropsWithChildren<TooltipProps>> = ({
  46. children,
  47. title,
  48. ...props
  49. }) => {
  50. const [visible, setVisible] = React.useState(false);
  51. return (
  52. <StyledTooltipWrapper {...props}>
  53. {title && <StyledTooltip visible={visible}>{title}</StyledTooltip>}
  54. <StyledChildren
  55. onMouseEnter={() => setVisible(true)}
  56. onMouseLeave={() => setVisible(false)}
  57. >
  58. {children}
  59. </StyledChildren>
  60. </StyledTooltipWrapper>
  61. );
  62. };