Files
router-lists-ui/frontend/src/components/Tooltip.jsx
T

136 lines
3.8 KiB
React

import { useState, useRef, useEffect } from 'react'
/**
* Tooltip компонент в стиле Tabler UI
* Использует position: absolute относительно trigger элемента
*/
function Tooltip({
children,
content,
position = 'top', // top, bottom, left, right
shortcut, // keyboard shortcut to display
delay = 200,
className = ''
}) {
const [isVisible, setIsVisible] = useState(false)
const timeoutRef = useRef(null)
const triggerRef = useRef(null)
const showTooltip = () => {
if (timeoutRef.current) clearTimeout(timeoutRef.current)
timeoutRef.current = setTimeout(() => {
setIsVisible(true)
}, delay)
}
const hideTooltip = () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
setIsVisible(false)
}
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
}
}, [])
return (
<span
ref={triggerRef}
onMouseEnter={showTooltip}
onMouseLeave={hideTooltip}
onFocus={showTooltip}
onBlur={hideTooltip}
className={`tooltip-trigger ${className}`}
style={{ position: 'relative', display: 'inline-block' }}
>
{children}
{isVisible && (
<div
className={`tooltip bs-tooltip-${position} show`}
role="tooltip"
style={{
position: 'absolute',
zIndex: 1070,
display: 'block',
margin: 0,
pointerEvents: 'none',
...(position === 'top' && {
bottom: '100%',
left: '50%',
transform: 'translateX(-50%)',
marginBottom: '8px'
}),
...(position === 'bottom' && {
top: '100%',
left: '50%',
transform: 'translateX(-50%)',
marginTop: '8px'
}),
...(position === 'left' && {
right: '100%',
top: '50%',
transform: 'translateY(-50%)',
marginRight: '8px'
}),
...(position === 'right' && {
left: '100%',
top: '50%',
transform: 'translateY(-50%)',
marginLeft: '8px'
})
}}
>
<div className="tooltip-arrow" style={(() => {
const styles = {
position: 'absolute',
width: '8px',
height: '8px',
background: 'inherit'
}
if (position === 'top') {
styles.bottom = '0'
styles.left = '50%'
styles.transform = 'translateX(-50%) translateY(50%) rotate(45deg)'
} else if (position === 'bottom') {
styles.top = '0'
styles.left = '50%'
styles.transform = 'translateX(-50%) translateY(-50%) rotate(45deg)'
} else if (position === 'left') {
styles.right = '0'
styles.top = '50%'
styles.transform = 'translateX(50%) translateY(-50%) rotate(45deg)'
} else if (position === 'right') {
styles.left = '0'
styles.top = '50%'
styles.transform = 'translateX(-50%) translateY(-50%) rotate(45deg)'
}
return styles
})()}></div>
<div className="tooltip-inner">
{content}
{shortcut && (
<kbd className="ms-2" style={{
background: 'rgba(255, 255, 255, 0.2)',
padding: '0.125rem 0.375rem',
borderRadius: '0.25rem',
fontSize: '0.75rem',
fontFamily: 'monospace'
}}>{shortcut}</kbd>
)}
</div>
</div>
)}
</span>
)
}
export default Tooltip