index.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useState } from 'react'
  4. import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
  5. export type TooltipProps = {
  6. position?: 'top' | 'right' | 'bottom' | 'left'
  7. triggerMethod?: 'hover' | 'click'
  8. popupContent: React.ReactNode
  9. children: React.ReactNode
  10. }
  11. const arrow = (
  12. <svg className="absolute text-white h-2 w-full left-0 top-full" x="0px" y="0px" viewBox="0 0 255 255"><polygon className="fill-current" points="0,0 127.5,127.5 255,0"></polygon></svg>
  13. )
  14. const Tooltip: FC<TooltipProps> = ({
  15. position = 'top',
  16. triggerMethod = 'hover',
  17. popupContent,
  18. children,
  19. }) => {
  20. const [open, setOpen] = useState(false)
  21. return (
  22. <PortalToFollowElem
  23. open={open}
  24. onOpenChange={setOpen}
  25. placement={position}
  26. offset={10}
  27. >
  28. <PortalToFollowElemTrigger
  29. onClick={() => triggerMethod === 'click' && setOpen(v => !v)}
  30. onMouseEnter={() => triggerMethod === 'hover' && setOpen(true)}
  31. onMouseLeave={() => triggerMethod === 'hover' && setOpen(false)}
  32. >
  33. {children}
  34. </PortalToFollowElemTrigger>
  35. <PortalToFollowElemContent
  36. className="z-[9999]"
  37. >
  38. <div className='relative px-3 py-2 text-xs font-normal text-gray-700 bg-white rounded-md shadow-lg'>
  39. {popupContent}
  40. {arrow}
  41. </div>
  42. </PortalToFollowElemContent>
  43. </PortalToFollowElem>
  44. )
  45. }
  46. export default React.memo(Tooltip)