import React, { useEffect, useRef, useState } from 'react'; import styled from 'styled-components'; import v from '../../styles/Variables'; import UnderlineButton from '../Common/UnderlineButton'; interface Props { callback: () => void; focusCb?: () => void; blurCb?: () => void; content: React.ReactNode; id: string; position: string; showQuestion?: boolean; theme: string; themeTooltip: string; themeWrapper?: string; title: string; width: number; showOnHover?: boolean; buttonComponent?: React.ReactNode; } interface Styles { elementWidth: number; width: number; position: string; left: string; } //automatically activated tooltip const Tooltip = ({ callback, focusCb = () => null, blurCb = () => null, content, id = 'tooltip', position, showQuestion = false, showOnHover = true, theme, themeTooltip, themeWrapper, title, width, buttonComponent, }: Props) => { const [show, showSetter] = useState(false); const [focus, focusSetter] = useState(false); const [elementWidth, elementWidthSetter] = useState(0); const wrapperRef = useRef(null); let left = '0'; if (position === 'left') { left = `-${width + 8}px`; } else if (position === 'right') { left = '105%'; } else if (position === 'square') { left = '0'; } else { left = `${elementWidth / 2 - width / 2}px`; } useEffect(() => { document.addEventListener('click', handleClickOutside, false); return () => { document.removeEventListener('click', handleClickOutside, false); }; }, []); const handleClickOutside = (event: { target: any }) => { if (wrapperRef && wrapperRef.current && !wrapperRef.current.contains(event.target)) { showSetter(false); } }; return ( { blurCb(); elementWidthSetter(e.currentTarget.offsetWidth); setTimeout(() => { showSetter(false); }, 200); focusSetter(false); }} onFocus={(e) => { focusCb(); elementWidthSetter(e.currentTarget.offsetWidth); showSetter(true); focusSetter(true); }} onClick={() => { callback(); showSetter(true); }} onMouseEnter={() => { showOnHover && showSetter(true); }} onMouseLeave={() => { !focus && showOnHover && showSetter(false); }} aria-expanded={show === true ? 'true' : 'false'} aria-controls={`tooltip--${title.replace(/\s/g, '')}`} tabIndex={0} > {buttonComponent ? buttonComponent : }{' '} {showQuestion === true ? ( ) : ( {title} )} {content} ); }; export default Tooltip; /* styles */ const Wrapper = styled.span` display: inline-block; position: relative; text-align: center; `; const Trigger = styled.div` background: none; border: none; padding: 0; cursor: help; &:focus { outline: 2px dotted black; outline-offset: 2px; } `; const Background = styled.div` position: absolute; background: ${v.colors.dark222}; color: ${v.colors.light}; text-align: center; width: ${({ width }) => `${width}px`}; z-index: 9999; font-size: 14px; padding: 8px; top: ${({ position }) => (position === 'top' ? null : null)}; bottom: ${({ position }) => (position === 'top' ? '100%' : null)}; left: ${({ left }) => left}; margin-top: ${({ position }) => (position === 'left' || position === 'right' ? '-30%' : 0)}; `;