ContentWithTooltip.tsx
1 import { Box, ClickAwayListener, Popper, styled, Tooltip } from '@mui/material'; 2 import { JSXElementConstructor, ReactElement, ReactNode, useState } from 'react'; 3 4 interface ContentWithTooltipProps { 5 children: ReactNode; 6 // eslint-disable-next-line 7 tooltipContent: ReactElement<any, string | JSXElementConstructor<any>>; 8 placement?: 'top' | 'bottom'; 9 withoutHover?: boolean; 10 open?: boolean; 11 setOpen?: (value: boolean) => void; 12 offset?: [number, number]; 13 } 14 15 export const PopperComponent = styled(Popper)(({ theme }) => 16 theme.unstable_sx({ 17 '.MuiTooltip-tooltip': { 18 color: 'text.primary', 19 backgroundColor: 'background.paper', 20 p: 0, 21 borderRadius: '6px', 22 boxShadow: '0px 0px 2px rgba(0, 0, 0, 0.2), 0px 2px 10px rgba(0, 0, 0, 0.1)', 23 maxWidth: '280px', 24 }, 25 '.MuiTooltip-arrow': { 26 color: 'background.paper', 27 '&:before': { 28 boxShadow: '0px 0px 2px rgba(0, 0, 0, 0.2), 0px 2px 10px rgba(0, 0, 0, 0.1)', 29 }, 30 }, 31 }) 32 ); 33 34 export const ContentWithTooltip = ({ 35 children, 36 tooltipContent, 37 placement = 'top', 38 withoutHover, 39 open, 40 setOpen, 41 offset, 42 }: ContentWithTooltipProps) => { 43 const [openTooltip, setOpenTooltip] = useState(false); 44 45 const formattedOpen = typeof open !== 'undefined' ? open : openTooltip; 46 const toggleOpen = () => 47 typeof setOpen !== 'undefined' ? setOpen(!formattedOpen) : setOpenTooltip(!formattedOpen); 48 const handleClose = () => 49 typeof setOpen !== 'undefined' ? setOpen(false) : setOpenTooltip(false); 50 51 return ( 52 <Tooltip 53 open={formattedOpen} 54 onClose={handleClose} 55 disableFocusListener 56 disableHoverListener 57 disableTouchListener 58 placement={placement} 59 PopperComponent={PopperComponent} 60 componentsProps={{ 61 popper: { 62 modifiers: [ 63 { 64 name: 'offset', 65 options: { 66 offset: offset ?? [], 67 }, 68 }, 69 ], 70 onClick: (e) => { 71 e.stopPropagation(); 72 }, 73 }, 74 }} 75 title={ 76 <ClickAwayListener 77 mouseEvent="onMouseDown" 78 touchEvent="onTouchStart" 79 onClickAway={handleClose} 80 > 81 <Box 82 sx={{ 83 py: 4, 84 px: 6, 85 fontSize: '12px', 86 lineHeight: '16px', 87 a: { 88 fontSize: '12px', 89 lineHeight: '16px', 90 fontWeight: 500, 91 '&:hover': { textDecoration: 'underline' }, 92 }, 93 }} 94 > 95 {tooltipContent} 96 </Box> 97 </ClickAwayListener> 98 } 99 arrow 100 > 101 <Box 102 sx={{ 103 display: 'inline-flex', 104 cursor: 'pointer', 105 transition: 'all 0.2s ease', 106 '&:hover': { opacity: withoutHover ? 1 : formattedOpen ? 1 : 0.5 }, 107 }} 108 onClick={(e) => { 109 e.preventDefault(); 110 e.stopPropagation(); 111 toggleOpen(); 112 }} 113 > 114 {children} 115 </Box> 116 </Tooltip> 117 ); 118 };