TooltipContent.vue 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. <script setup lang="ts">
  2. import type { TooltipContentEmits, TooltipContentProps } from 'reka-ui'
  3. import type { HTMLAttributes } from 'vue'
  4. import { reactiveOmit } from '@vueuse/core'
  5. import { TooltipArrow, TooltipContent, TooltipPortal, useForwardPropsEmits } from 'reka-ui'
  6. import { cn } from '@/lib/utils'
  7. defineOptions({
  8. inheritAttrs: false,
  9. })
  10. const props = withDefaults(
  11. defineProps<TooltipContentProps & { class?: HTMLAttributes['class']; arrowClass?: string }>(),
  12. {
  13. sideOffset: 4,
  14. },
  15. )
  16. const emits = defineEmits<TooltipContentEmits>()
  17. const delegatedProps = reactiveOmit(props, 'class')
  18. const forwarded = useForwardPropsEmits(delegatedProps, emits)
  19. </script>
  20. <template>
  21. <TooltipPortal>
  22. <TooltipContent
  23. data-slot="tooltip-content"
  24. v-bind="{ ...forwarded, ...$attrs }"
  25. :class="
  26. cn(
  27. 'bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance',
  28. props.class,
  29. )
  30. "
  31. >
  32. <slot />
  33. <TooltipArrow
  34. :class="
  35. cn(
  36. `bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]`,
  37. props.arrowClass,
  38. )
  39. "
  40. />
  41. </TooltipContent>
  42. </TooltipPortal>
  43. </template>