Files
dmz/src/directives/tooltip.ts
2025-05-24 01:47:40 +09:00

95 lines
1.9 KiB
TypeScript

import type { Directive, DirectiveHook } from 'vue'
const updateVTooltip: DirectiveHook = (el: HTMLElement, bindings) => {
const value = bindings.value
let placement = 'top'
let color = ''
let shape = ''
if (bindings.modifiers.bottom) {
placement = 'bottom'
}
if (bindings.modifiers.left) {
placement += '-left'
}
else if (bindings.modifiers.right) {
placement += '-right'
}
if (bindings.modifiers.light) {
color = 'hint--light'
}
else if (bindings.modifiers.primary) {
color = 'hint--primary'
}
else if (bindings.modifiers.info) {
color = 'hint--info'
}
else if (bindings.modifiers.success) {
color = 'hint--success'
}
else if (bindings.modifiers.warning) {
color = 'hint--warning'
}
else if (bindings.modifiers.error) {
color = 'hint--error'
}
if (bindings.modifiers.rounded) {
shape = 'hint--rounded'
}
else if (bindings.modifiers.bubble) {
shape = 'hint--bubble'
}
const previousClasses: string[] = []
const nextClasses: string[] = []
el.classList.forEach((className) => {
if (className.startsWith('hint--')) {
previousClasses.push(className)
}
})
if (typeof value === 'string') {
el.dataset.hint = value
el.ariaLabel = value
el.tabIndex ??= 0
nextClasses.push(`hint--${placement}`)
if (color) {
nextClasses.push(color)
}
if (shape) {
nextClasses.push(shape)
}
}
else {
el.dataset.hint = undefined
}
// add new classes
nextClasses.forEach((className) => {
if (!previousClasses.includes(className)) {
el.classList.add(className)
}
})
// remove old classes
previousClasses.forEach((className) => {
if (!nextClasses.includes(className)) {
el.classList.remove(className)
}
})
}
export const vTooltip = {
getSSRProps() {
return {}
},
updated: updateVTooltip,
mounted: updateVTooltip,
} satisfies Directive