index.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useState } from 'react'
  4. import cn from 'classnames'
  5. import type { OffsetOptions, Placement } from '@floating-ui/react'
  6. import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
  7. export type TooltipProps = {
  8. position?: Placement
  9. triggerMethod?: 'hover' | 'click'
  10. popupContent: React.ReactNode
  11. children: React.ReactNode
  12. hideArrow?: boolean
  13. popupClassName?: string
  14. offset?: OffsetOptions
  15. }
  16. const arrow = (
  17. <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>
  18. )
  19. const Tooltip: FC<TooltipProps> = ({
  20. position = 'top',
  21. triggerMethod = 'hover',
  22. popupContent,
  23. children,
  24. hideArrow,
  25. popupClassName,
  26. offset,
  27. }) => {
  28. const [open, setOpen] = useState(false)
  29. return (
  30. <PortalToFollowElem
  31. open={open}
  32. onOpenChange={setOpen}
  33. placement={position}
  34. offset={offset ?? 10}
  35. >
  36. <PortalToFollowElemTrigger
  37. onClick={() => triggerMethod === 'click' && setOpen(v => !v)}
  38. onMouseEnter={() => triggerMethod === 'hover' && setOpen(true)}
  39. onMouseLeave={() => triggerMethod === 'hover' && setOpen(false)}
  40. >
  41. {children}
  42. </PortalToFollowElemTrigger>
  43. <PortalToFollowElemContent
  44. className="z-[9999]"
  45. >
  46. <div className={cn(
  47. 'relative px-3 py-2 text-xs font-normal text-gray-700 bg-white rounded-md shadow-lg',
  48. popupClassName,
  49. )}>
  50. {popupContent}
  51. {!hideArrow && arrow}
  52. </div>
  53. </PortalToFollowElemContent>
  54. </PortalToFollowElem>
  55. )
  56. }
  57. export default React.memo(Tooltip)