86 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import React from 'react'
 | 
						|
import { styled, keyframes } from '../stitches.config'
 | 
						|
import * as TooltipPrimitive from '@radix-ui/react-tooltip'
 | 
						|
 | 
						|
const slideUpAndFade = keyframes({
 | 
						|
  '0%': { opacity: 0, transform: 'translateY(2px)' },
 | 
						|
  '100%': { opacity: 1, transform: 'translateY(0)' }
 | 
						|
})
 | 
						|
 | 
						|
const slideRightAndFade = keyframes({
 | 
						|
  '0%': { opacity: 0, transform: 'translateX(-2px)' },
 | 
						|
  '100%': { opacity: 1, transform: 'translateX(0)' }
 | 
						|
})
 | 
						|
 | 
						|
const slideDownAndFade = keyframes({
 | 
						|
  '0%': { opacity: 0, transform: 'translateY(-2px)' },
 | 
						|
  '100%': { opacity: 1, transform: 'translateY(0)' }
 | 
						|
})
 | 
						|
 | 
						|
const slideLeftAndFade = keyframes({
 | 
						|
  '0%': { opacity: 0, transform: 'translateX(2px)' },
 | 
						|
  '100%': { opacity: 1, transform: 'translateX(0)' }
 | 
						|
})
 | 
						|
 | 
						|
const StyledContent = styled(TooltipPrimitive.Content, {
 | 
						|
  borderRadius: 4,
 | 
						|
  padding: '$2 $3',
 | 
						|
  fontSize: 12,
 | 
						|
  lineHeight: 1,
 | 
						|
  color: '$text',
 | 
						|
  backgroundColor: '$background',
 | 
						|
  boxShadow: 'hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px',
 | 
						|
  '@media (prefers-reduced-motion: no-preference)': {
 | 
						|
    animationDuration: '400ms',
 | 
						|
    animationTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)',
 | 
						|
    animationFillMode: 'forwards',
 | 
						|
    willChange: 'transform, opacity',
 | 
						|
    '&[data-state="delayed-open"]': {
 | 
						|
      '&[data-side="top"]': { animationName: slideDownAndFade },
 | 
						|
      '&[data-side="right"]': { animationName: slideLeftAndFade },
 | 
						|
      '&[data-side="bottom"]': { animationName: slideUpAndFade },
 | 
						|
      '&[data-side="left"]': { animationName: slideRightAndFade }
 | 
						|
    }
 | 
						|
  },
 | 
						|
  '.dark &': {
 | 
						|
    boxShadow:
 | 
						|
      '0px 0px 10px 2px rgba(0,0,0,.45), hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px'
 | 
						|
  },
 | 
						|
  '.light &': {
 | 
						|
    boxShadow:
 | 
						|
      '0px 0px 10px 2px rgba(0,0,0,.25), hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px'
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
const StyledArrow = styled(TooltipPrimitive.Arrow, {
 | 
						|
  fill: '$background'
 | 
						|
})
 | 
						|
 | 
						|
interface ITooltip {
 | 
						|
  content: string
 | 
						|
  open?: boolean
 | 
						|
  defaultOpen?: boolean
 | 
						|
  onOpenChange?: (open: boolean) => void
 | 
						|
}
 | 
						|
 | 
						|
const Tooltip: React.FC<React.ComponentProps<typeof StyledContent> & ITooltip> = ({
 | 
						|
  children,
 | 
						|
  content,
 | 
						|
  open,
 | 
						|
  defaultOpen = false,
 | 
						|
  onOpenChange,
 | 
						|
  ...rest
 | 
						|
}) => {
 | 
						|
  return (
 | 
						|
    <TooltipPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>
 | 
						|
      <TooltipPrimitive.Trigger asChild>{children}</TooltipPrimitive.Trigger>
 | 
						|
      <StyledContent side="bottom" align="center" {...rest}>
 | 
						|
        <div dangerouslySetInnerHTML={{ __html: content }} />
 | 
						|
        <StyledArrow offset={5} width={11} height={5} />
 | 
						|
      </StyledContent>
 | 
						|
    </TooltipPrimitive.Root>
 | 
						|
  )
 | 
						|
}
 | 
						|
 | 
						|
export default Tooltip
 |