mirror of
https://github.com/nocodb/nocodb.git
synced 2026-05-03 16:07:05 +00:00
123 lines
2.9 KiB
TypeScript
123 lines
2.9 KiB
TypeScript
import { isBoxHovered } from '../../components/smartsheet/grid/canvas/utils/canvas'
|
|
import type { RenderRectangleProps } from '../../components/smartsheet/grid/canvas/utils/types'
|
|
|
|
export interface TooltipPosition {
|
|
x: number
|
|
y: number
|
|
}
|
|
|
|
export interface TooltipInfo {
|
|
text: string
|
|
position: TooltipPosition
|
|
theme?: 'light' | 'dark'
|
|
}
|
|
|
|
export type TooltipTextType = string | VNode
|
|
|
|
export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right'
|
|
|
|
export const useTooltipStore = defineStore('tooltip', () => {
|
|
const placement = ref<TooltipPlacement>('top')
|
|
const tooltipText = ref<TooltipTextType>('')
|
|
|
|
const targetRect = ref<Omit<DOMRect, 'toJSON'>>({ x: 0, y: 0, top: 0, left: 0, bottom: 0, right: 0, width: 0, height: 0 })
|
|
|
|
const hideTooltip = () => {
|
|
tooltipText.value = ''
|
|
}
|
|
|
|
const targetReference = computed(() => {
|
|
const rect = targetRect.value
|
|
return {
|
|
getBoundingClientRect() {
|
|
return rect
|
|
},
|
|
}
|
|
})
|
|
|
|
function showTooltip({
|
|
text,
|
|
rect,
|
|
placement: _placement = 'top',
|
|
}: {
|
|
text: TooltipTextType
|
|
/**
|
|
* Todo: Show tooltip at mouse position if showAtMousePosition is true & targetWidth is provided
|
|
*/
|
|
rect: RenderRectangleProps & { showAtMousePosition?: boolean }
|
|
mousePosition: {
|
|
x: number
|
|
y: number
|
|
}
|
|
placement?: TooltipPlacement
|
|
}) {
|
|
if (!text) return
|
|
|
|
let canvasX = 0
|
|
let canvasY = 0
|
|
const canvasRect = document.querySelector('canvas')?.getBoundingClientRect()
|
|
|
|
if (canvasRect) {
|
|
canvasX = canvasRect.x
|
|
canvasY = canvasRect.y
|
|
}
|
|
rect.x += canvasX
|
|
rect.y += canvasY
|
|
tooltipText.value = text
|
|
placement.value = _placement
|
|
targetRect.value = {
|
|
x: rect.x,
|
|
y: rect.y,
|
|
left: rect.x,
|
|
top: rect.y,
|
|
right: rect.x + (rect.targetWidth || rect.width),
|
|
bottom: rect.y + rect.height,
|
|
width: rect.targetWidth || rect.width,
|
|
height: rect.height,
|
|
}
|
|
}
|
|
|
|
function tryShowTooltip({
|
|
text,
|
|
description,
|
|
rect,
|
|
mousePosition,
|
|
placement,
|
|
}: {
|
|
text: TooltipTextType
|
|
description?: string
|
|
rect?: RenderRectangleProps & { showAtMousePosition?: boolean }
|
|
mousePosition: {
|
|
x: number
|
|
y: number
|
|
}
|
|
placement?: TooltipPlacement
|
|
}) {
|
|
if (!rect || !isBoxHovered(rect, mousePosition) || !text) return false
|
|
|
|
const tooltipWithDescription =
|
|
ncIsString(text) && description
|
|
? h('div', { class: 'flex flex-col gap-1' }, [
|
|
h('div', { class: 'text-captionBold' }, text),
|
|
h('div', { class: 'text-captionSm' }, description),
|
|
])
|
|
: text
|
|
|
|
showTooltip({ text: tooltipWithDescription, rect, mousePosition, placement })
|
|
return true
|
|
}
|
|
|
|
return {
|
|
targetReference,
|
|
tooltipText,
|
|
placement,
|
|
tryShowTooltip,
|
|
showTooltip,
|
|
hideTooltip,
|
|
}
|
|
})
|
|
|
|
if (import.meta.hot) {
|
|
import.meta.hot.accept(acceptHMRUpdate(useTooltipStore as any, import.meta.hot))
|
|
}
|