TextWithTooltip.tsx
1 import { InformationCircleIcon } from '@heroicons/react/outline'; 2 import { Box, BoxProps, IconButton, SvgIcon, Typography } from '@mui/material'; 3 import { TypographyProps } from '@mui/material/Typography'; 4 import { JSXElementConstructor, ReactElement, ReactNode, useState } from 'react'; 5 import { TrackEventProps } from 'src/store/analyticsSlice'; 6 import { useRootStore } from 'src/store/root'; 7 8 import { ContentWithTooltip } from './ContentWithTooltip'; 9 10 export interface TextWithTooltipProps extends TypographyProps { 11 text?: ReactNode; 12 icon?: ReactNode; 13 iconSize?: number; 14 iconColor?: string; 15 iconMargin?: number; 16 textColor?: string; 17 // eslint-disable-next-line 18 children?: ReactElement<any, string | JSXElementConstructor<any>>; 19 wrapperProps?: BoxProps; 20 event?: TrackEventProps; 21 open?: boolean; 22 setOpen?: (open: boolean) => void; 23 } 24 25 export const TextWithTooltip = ({ 26 text, 27 icon, 28 iconSize = 14, 29 iconColor, 30 iconMargin, 31 children, 32 textColor, 33 wrapperProps: { sx: boxSx, ...boxRest } = {}, 34 event, 35 open: openProp = false, 36 setOpen: setOpenProp, 37 ...rest 38 }: TextWithTooltipProps) => { 39 const [open, setOpen] = useState(openProp); 40 const trackEvent = useRootStore((store) => store.trackEvent); 41 42 const toggleOpen = () => { 43 if (setOpenProp) setOpenProp(!open); 44 setOpen(!open); 45 }; 46 47 return ( 48 <Box sx={{ display: 'flex', alignItems: 'center', ...boxSx }} {...boxRest}> 49 {text && ( 50 <Typography {...rest} color={textColor}> 51 {text} 52 </Typography> 53 )} 54 55 <ContentWithTooltip tooltipContent={<>{children}</>} open={open} setOpen={toggleOpen}> 56 <IconButton 57 sx={{ 58 display: 'flex', 59 alignItems: 'center', 60 justifyContent: 'center', 61 width: iconSize, 62 height: iconSize, 63 borderRadius: '50%', 64 p: 0, 65 minWidth: 0, 66 ml: iconMargin || 0.5, 67 }} 68 onClick={() => { 69 if (event) { 70 trackEvent(event.eventName, { ...event.eventParams }); 71 } 72 }} 73 > 74 <SvgIcon 75 sx={{ 76 fontSize: iconSize, 77 color: iconColor ? iconColor : open ? 'info.main' : 'text.muted', 78 borderRadius: '50%', 79 '&:hover': { color: iconColor || 'info.main' }, 80 }} 81 > 82 {icon || <InformationCircleIcon />} 83 </SvgIcon> 84 </IconButton> 85 </ContentWithTooltip> 86 </Box> 87 ); 88 };