diff --git a/playground/pages/Index.vue b/playground/pages/Index.vue
index 5588c20..05409e7 100644
--- a/playground/pages/Index.vue
+++ b/playground/pages/Index.vue
@@ -195,6 +195,26 @@
+
+ useTippy + plain string:
+
+
+
+
+ useTippy + computed string:
+
+
+
Tippy component + change content and props realtime using component
@@ -413,6 +433,15 @@ export default defineComponent({
content: 'Test Vue component',
})
+ const buttonText = ref()
+
+ useTippy(buttonText, 'String content')
+
+ const buttonTextComputed = ref()
+ const computedText = computed(() => `Counter: ${counter.value}`)
+
+ useTippy(buttonTextComputed, computedText);
+
const { x, y } = useMousePosition()
const { tippy } = useTippy(() => document.body, {
@@ -494,6 +523,8 @@ export default defineComponent({
button7,
target7,
vueComponentButton,
+ buttonText,
+ buttonTextComputed,
tippyComponent1,
log: console.log,
}
diff --git a/src/composables/useTippy.ts b/src/composables/useTippy.ts
index 4e67263..5f72f8a 100644
--- a/src/composables/useTippy.ts
+++ b/src/composables/useTippy.ts
@@ -2,7 +2,6 @@ import tippy, { Instance, Props, Content } from 'tippy.js'
import {
ref,
onMounted,
- Ref,
isRef,
isReactive,
isVNode,
@@ -15,7 +14,8 @@ import {
shallowRef,
App,
} from 'vue'
-import { TippyOptions, TippyContent } from '../types'
+import { TippyOptions, TippyContent, MaybeRef, MaybeRefOrGetter } from '../types'
+import { isObject, isString, toValue, isComponentInstance } from '../utils'
tippy.setDefaultProps({
//@ts-ignore
@@ -24,15 +24,11 @@ tippy.setDefaultProps({
},
})
-const isComponentInstance = (value: any): value is { $el: any } => {
- return value instanceof Object && '$' in value && '$el' in value
-}
-
type TippyElement = Element | any // TODO: use ComponentPublicInstance
export function useTippy(
- el: TippyElement | (() => TippyElement) | Ref | Ref,
- opts: TippyOptions = {},
+ el: MaybeRefOrGetter,
+ opts: TippyOptions | MaybeRef = {},
settings: {
mount: boolean,
appName: string,
@@ -109,15 +105,15 @@ export function useTippy(
return newContent!
}
- const getProps = (opts: TippyOptions): Partial => {
+ const getProps = (opts: TippyOptions | MaybeRef): Partial => {
+ const value = toValue(opts);
+
let options: any = {}
- if (isRef(opts)) {
- options = opts.value || {}
- } else if (isReactive(opts)) {
- options = { ...opts }
+ if (isString(value)) {
+ options = { content: value }
} else {
- options = { ...opts }
+ options = { ...value }
}
if (options.content) {
@@ -173,23 +169,41 @@ export function useTippy(
return options as Props
}
+ const getOptsContent = () => {
+ const value = toValue(opts)
+
+ if (isString(value)) {
+ return value
+ }
+
+ return value?.content
+ }
+
const refresh = () => {
if (!instance.value) return
- instance.value.setProps(getProps(opts))
+ if (isObject(toValue(opts))) {
+ instance.value.setProps(getProps(opts))
+ } else {
+ refreshContent()
+ }
}
const refreshContent = () => {
- if (!instance.value || !opts.content) return
+ if (!instance.value) return
+
+ const content = getOptsContent()
+
+ if (!content) return
- instance.value.setContent(getContent(opts.content))
+ instance.value.setContent(getContent(content))
}
const setContent = (value: TippyContent) => {
instance.value?.setContent(getContent(value))
}
- const setProps = (value: TippyOptions) => {
+ const setProps = (value: TippyOptions | MaybeRef) => {
instance.value?.setProps(getProps(value))
}
@@ -283,9 +297,9 @@ export function useTippy(
})
}
- if (isRef(opts) || isReactive(opts)) {
+ if ((isRef(opts) || isReactive(opts)) && !isString(opts)) {
watch(opts, refresh, { immediate: false })
- } else if (isRef(opts.content)) {
+ } else if (isObject(opts) && isRef(opts.content)) {
watch(opts.content, refreshContent, { immediate: false })
}
diff --git a/src/types/index.ts b/src/types/index.ts
index 48b62e5..99bacde 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -1,7 +1,7 @@
import Tippy from '../components/Tippy'
import { useTippy } from '../composables'
import { Props, Content, DefaultProps, Instance } from 'tippy.js'
-import { VNode, Ref, Component, UnwrapNestedRefs } from 'vue'
+import { VNode, Ref, Component, UnwrapNestedRefs, ShallowRef, WritableComputedRef, ComputedRef } from 'vue'
export declare type TippyContent = Content | VNode | Component | Ref
export declare type TippyTarget =
@@ -35,3 +35,11 @@ export interface TippyPluginOptions {
export type TippyInstance = Instance | Element | undefined
export type TippyInstances = Ref[] | Ref | (() => TippyInstance[])
+
+export type MaybeRef =
+ | T
+ | Ref
+ | ShallowRef
+ | WritableComputedRef
+
+export type MaybeRefOrGetter = MaybeRef | ComputedRef | (() => T)
\ No newline at end of file
diff --git a/src/utils/index.ts b/src/utils/index.ts
new file mode 100644
index 0000000..a7e8047
--- /dev/null
+++ b/src/utils/index.ts
@@ -0,0 +1,27 @@
+import { isRef, unref } from 'vue'
+import { MaybeRefOrGetter } from '../types'
+
+export const isComponentInstance = (value: any): value is { $el: any } => {
+ return value instanceof Object && '$' in value && '$el' in value
+}
+
+export const isString = (val: unknown): val is string => typeof val === 'string'
+
+export const isFunction = (val: unknown): val is Function =>
+ typeof val === 'function'
+
+export const isObject = (val: unknown): val is Record =>
+ val !== null && typeof val === 'object'
+
+
+export function toValue(source: MaybeRefOrGetter): T {
+ if (isRef(source)) {
+ return unref(source)
+ }
+
+ if (isFunction(source)) {
+ return source()
+ }
+
+ return source;
+}
\ No newline at end of file