diff --git a/docs/content/en/flavor/directive.md b/docs/content/en/flavor/directive.md index 00307ed..191cb17 100644 --- a/docs/content/en/flavor/directive.md +++ b/docs/content/en/flavor/directive.md @@ -26,3 +26,15 @@ Click [here](/props) to see full documentation on props. Tippy! ``` + +For dynamically setting if tooltip is enabled: + +```js +const isTippyEnabled = ref(true); +``` + +```html + +``` \ No newline at end of file diff --git a/docs/content/en/props.md b/docs/content/en/props.md index cf8c59c..49fec95 100644 --- a/docs/content/en/props.md +++ b/docs/content/en/props.md @@ -195,7 +195,7 @@ useTippy(target, { delay: [100, 200], // show delay is 100ms, hide delay is the default delay: [100, null], -} +}) ``` ## duration @@ -212,7 +212,19 @@ useTippy(target, { duration: [100, 200], // show duration is 100ms, hide duration is the default duration: [100, null], -} +}) +``` + +## enabled + +Controls if tooltip is enabled. + +```js +useTippy(target, { + // default + enabled: true, + enabled: false +}) ``` ## followCursor diff --git a/src/components/Tippy.ts b/src/components/Tippy.ts index 9b37f5d..ee7a7bd 100644 --- a/src/components/Tippy.ts +++ b/src/components/Tippy.ts @@ -9,6 +9,7 @@ declare module 'vue' { tag: string contentTag: string contentClass: string + enabled: boolean } interface ComponentCustomProperties extends UnwrapNestedRefs> { } } @@ -84,9 +85,10 @@ const TippyComponent = defineComponent({ maxWidth: { default: () => tippy.defaultProps['maxWidth'] }, role: { default: () => tippy.defaultProps['role'] }, theme: { default: () => tippy.defaultProps['theme'] }, - zIndex: { default: () => tippy.defaultProps['zIndex'] } + zIndex: { default: () => tippy.defaultProps['zIndex'] }, + enabled: { type: Boolean, default: true }, }, - emits: ['state'], + emits: ['state', 'update:enabled'], setup(props, { slots, emit, expose }) { const elem = ref() const findParentHelper = ref() @@ -138,8 +140,22 @@ const TippyComponent = defineComponent({ }) }) - watch(tippy.state, () => { + watch(() => props.enabled, (newValue) => { + const isTippyEnabled = tippy.state.value.isEnabled; + + if (newValue && !isTippyEnabled) { + tippy.enable(); + } else if (!newValue && isTippyEnabled) { + tippy.disable(); + } + }); + + watch(tippy.state, (newValue, oldValue) => { emit('state', unref(tippy.state)) + + if (newValue.isEnabled !== oldValue?.isEnabled && props.enabled !== newValue.isEnabled) + emit('update:enabled', newValue.isEnabled) + }, { immediate: true, deep: true }) watch(() => props, () => { diff --git a/src/composables/useTippy.ts b/src/composables/useTippy.ts index 4e67263..ea283c2 100644 --- a/src/composables/useTippy.ts +++ b/src/composables/useTippy.ts @@ -17,6 +17,14 @@ import { } from 'vue' import { TippyOptions, TippyContent } from '../types' +interface TippyState { + isEnabled: boolean + isVisible: boolean + isDestroyed: boolean + isMounted: boolean + isShown: boolean +} + tippy.setDefaultProps({ //@ts-ignore onShow: instance => { @@ -37,12 +45,26 @@ export function useTippy( mount: boolean, appName: string, } = { mount: true, appName: 'Tippy' } -) { +) : { + tippy: Ref + refresh: () => void + refreshContent: () => void + setContent: (value: TippyContent) => void + setProps: (value: TippyOptions) => void + destroy: () => void + hide: () => void + show: () => void + disable: () => void + enable: () => void + unmount: () => void + mount: () => void + state: Ref +} { settings = Object.assign({ mount: true, appName: 'Tippy' }, settings); const vm = getCurrentInstance() const instance = ref() - const state = ref({ + const state = ref({ isEnabled: false, isVisible: false, isDestroyed: false, diff --git a/src/directive/index.ts b/src/directive/index.ts index 72af1a3..97e020d 100644 --- a/src/directive/index.ts +++ b/src/directive/index.ts @@ -8,6 +8,7 @@ const directive: Directive = { const modifiers = Object.keys(binding.modifiers || {}) const placement = modifiers.find(modifier => modifier !== 'arrow') const withArrow = modifiers.findIndex(modifier => modifier === 'arrow') !== -1 + const enabled = opts.enabled ?? true; if (placement) { opts.placement = opts.placement || placement @@ -56,7 +57,11 @@ const directive: Directive = { opts.content = el.getAttribute('content') } - useTippy(el, opts) + const { disable } = useTippy(el, opts) + + if (!enabled) { + disable(); + } }, unmounted(el) { if (el.$tippy) { @@ -68,6 +73,7 @@ const directive: Directive = { updated(el, binding) { const opts = typeof binding.value === "string" ? { content: binding.value } : binding.value || {} + const enabled = opts.enabled ?? true; if (el.getAttribute('title') && !opts.content) { opts.content = el.getAttribute('title') @@ -83,6 +89,14 @@ const directive: Directive = { } else if (el._tippy) { el._tippy.setProps(opts || {}) } + + const isTippyEnabled = el.$tippy?.state.value.isEnabled; + + if (enabled && !isTippyEnabled) { + el.$tippy.enable(); + } else if (!enabled && isTippyEnabled) { + el.$tippy.disable(); + } }, }