Files
speckle-server/packages/frontend-2/composables/tooltips.ts
T
2025-08-04 21:45:37 +02:00

81 lines
1.9 KiB
TypeScript

import type { MaybeNullOrUndefined } from '@speckle/shared'
/**
* Smart tooltip delay composable
*
* Provides sophisticated tooltip behavior where:
* - First tooltip shows after a configurable delay (default 1 second)
* - Subsequent tooltips show instantly once user has shown intent
* - State resets after a period of inactivity (default 3 seconds)
*/
export function useSmartTooltipDelay() {
const initialDelay = 350
const resetAfter = 2000
const hasShownAny = ref(false)
const resetTimer = ref<NodeJS.Timeout | null>(null)
const getTooltipProps = (
content?: MaybeNullOrUndefined<
string | { content: string; allowHTML?: boolean; theme?: string }
>,
additionalProps: Record<string, unknown> = {}
) => {
// If content is already a tooltip configuration object, merge it with our base props
if (typeof content === 'object' && content !== null) {
return {
...content,
delay: hasShownAny.value ? 0 : initialDelay,
onShow: () => {
hasShownAny.value = true
if (resetTimer.value) {
clearTimeout(resetTimer.value)
}
resetTimer.value = setTimeout(() => {
hasShownAny.value = false
}, resetAfter)
},
...additionalProps
}
}
// Handle string content
return {
content,
delay: hasShownAny.value ? 0 : initialDelay,
onShow: () => {
hasShownAny.value = true
if (resetTimer.value) {
clearTimeout(resetTimer.value)
}
resetTimer.value = setTimeout(() => {
hasShownAny.value = false
}, resetAfter)
},
...additionalProps
}
}
const cleanup = () => {
if (resetTimer.value) {
clearTimeout(resetTimer.value)
resetTimer.value = null
}
}
const reset = () => {
cleanup()
hasShownAny.value = false
}
onUnmounted(() => {
cleanup()
})
return {
getTooltipProps,
reset
}
}