preview-slice.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { useState } from 'react'
  2. import type { FC, ReactNode } from 'react'
  3. import { autoUpdate, flip, inline, shift, useDismiss, useFloating, useHover, useInteractions, useRole } from '@floating-ui/react'
  4. import type { SliceProps } from './type'
  5. import { SliceContainer, SliceContent, SliceDivider, SliceLabel } from './shared'
  6. type PreviewSliceProps = SliceProps<{
  7. label: ReactNode
  8. tooltip: ReactNode
  9. labelInnerClassName?: string
  10. dividerClassName?: string
  11. }>
  12. export const PreviewSlice: FC<PreviewSliceProps> = (props) => {
  13. const { label, className, text, tooltip, labelInnerClassName, dividerClassName, ...rest } = props
  14. const [tooltipOpen, setTooltipOpen] = useState(false)
  15. const { refs, floatingStyles, context } = useFloating({
  16. open: tooltipOpen,
  17. onOpenChange: setTooltipOpen,
  18. whileElementsMounted: autoUpdate,
  19. placement: 'top',
  20. middleware: [
  21. inline(),
  22. flip(),
  23. shift(),
  24. ],
  25. })
  26. const hover = useHover(context, {
  27. delay: { open: 500 },
  28. move: true,
  29. })
  30. const dismiss = useDismiss(context)
  31. const role = useRole(context, { role: 'tooltip' })
  32. const { getReferenceProps, getFloatingProps } = useInteractions([hover, dismiss, role])
  33. return (
  34. <>
  35. <SliceContainer {...rest}
  36. className={className}
  37. ref={refs.setReference}
  38. {...getReferenceProps()}
  39. >
  40. <SliceLabel labelInnerClassName={labelInnerClassName}>{label}</SliceLabel>
  41. <SliceContent>{text}</SliceContent>
  42. <SliceDivider className={dividerClassName} />
  43. </SliceContainer>
  44. {tooltipOpen && <span
  45. ref={refs.setFloating}
  46. style={floatingStyles}
  47. {...getFloatingProps()}
  48. className='p-2 rounded-md bg-components-tooltip-bg shadow shadow-shadow-shadow-5 backdrop-blur-[5px] text-text-secondary leading-4 border-[0.5px] border-components-panel-border text-xs'
  49. >
  50. {tooltip}
  51. </span>}
  52. </>
  53. )
  54. }