singleton component
This commit is contained in:
@@ -41,6 +41,7 @@ app.use(
|
||||
{
|
||||
directive: 'tippy', // => v-tippy
|
||||
component: 'tippy', // => <tippy/>
|
||||
componentSingleton: 'tippy-singleton', // => <tippy-singleton/>
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
+37
-16
@@ -17,16 +17,22 @@
|
||||
<div class="mt-6">
|
||||
<span class="font-semibold mr-4">Tippy Component:</span>
|
||||
|
||||
<tippy content="test">
|
||||
<button class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg">Hi</button>
|
||||
<tippy
|
||||
content="test"
|
||||
class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg"
|
||||
>
|
||||
Hi
|
||||
</tippy>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<span class="font-semibold mr-4">Tippy Component with content slot:</span>
|
||||
|
||||
<tippy interactive>
|
||||
<button class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg">Hi</button>
|
||||
<tippy
|
||||
interactive
|
||||
class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg"
|
||||
>
|
||||
Hi
|
||||
|
||||
<template #content>
|
||||
<button
|
||||
@@ -39,28 +45,43 @@
|
||||
</tippy>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<div class="mt-6">
|
||||
<span class="font-semibold mr-4">Tippy Component with component content slot:</span>
|
||||
|
||||
<tippy interactive>
|
||||
<button class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg">Hi</button>
|
||||
<tippy
|
||||
interactive
|
||||
class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg"
|
||||
>
|
||||
Hi
|
||||
|
||||
<template #content>
|
||||
<counter/>
|
||||
<counter />
|
||||
</template>
|
||||
</tippy>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mt-6">
|
||||
<span class="font-semibold mr-4">Tippy component + content slot data</span>
|
||||
<tippy interactive :hideOnClick="false" trigger="manual">
|
||||
<div class="mt-6">
|
||||
<span class="font-semibold mr-4">Tippy component + content slot data</span>
|
||||
<tippy
|
||||
interactive
|
||||
:hideOnClick="false"
|
||||
trigger="manual"
|
||||
>
|
||||
<template #default="{ show }">
|
||||
<button @click="show" class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg">Hi</button>
|
||||
<button
|
||||
@click="show"
|
||||
class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg"
|
||||
>Hi</button>
|
||||
</template>
|
||||
<template #content="{ tippy, hide }" class="relative">
|
||||
<button class="absolute top-0 right-0 m-2 w-6 h-6 bg-white text-black rounded" @click="hide()">×</button>
|
||||
<pre class="p-4">{{ tippy && tippy.state }}</pre>
|
||||
<template
|
||||
#content="{ tippy, hide }"
|
||||
class="relative"
|
||||
>
|
||||
<button
|
||||
class="absolute top-0 right-0 m-2 w-6 h-6 bg-white text-black rounded"
|
||||
@click="hide()"
|
||||
>×</button>
|
||||
<pre class="p-4">{{ tippy && tippy.state }}</pre>
|
||||
</template>
|
||||
</tippy>
|
||||
</div>
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
<template>
|
||||
<div>
|
||||
<tippy :ref="(v) => instances.push(v.tippy)" v-for="i in 10" :key="i">
|
||||
<template #content>
|
||||
<div>Working tooltip</div>
|
||||
</template>
|
||||
<button>Button {{ i }}</button>
|
||||
</tippy>
|
||||
<div class="grid grid-cols-4 gap-4 ">
|
||||
<tippy-singleton move-transition="transform 0.2s ease-out" placement="top">
|
||||
<tippy
|
||||
v-for="i in 10"
|
||||
:key="i"
|
||||
class="text-sm py-2 px-3 bg-gray-900 text-white rounded-lg"
|
||||
>
|
||||
<template #content>
|
||||
<div>Working tooltip</div>
|
||||
</template>
|
||||
Button {{ i }}
|
||||
</tippy>
|
||||
</tippy-singleton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from "vue";
|
||||
import { useSingleton } from '../../src';
|
||||
export default {
|
||||
name: "App",
|
||||
setup() {
|
||||
const instances = ref([]);
|
||||
|
||||
useSingleton(() => instances.value.map((i) => i.tippy), {
|
||||
moveTransition: "transform 0.2s ease-out",
|
||||
});
|
||||
|
||||
return {
|
||||
instances,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -52,7 +52,7 @@ Object.keys(tippy.defaultProps).forEach((prop: string) => {
|
||||
props['to'] = {}
|
||||
|
||||
props['tag'] = {
|
||||
default : 'span'
|
||||
default : 'button'
|
||||
}
|
||||
|
||||
props['contentTag'] = {
|
||||
@@ -97,7 +97,7 @@ const TippyComponent = defineComponent({
|
||||
},
|
||||
render() {
|
||||
let slot = this.$slots.default ? this.$slots.default(this) : []
|
||||
return h(this.tag, { ref: 'elem' }, this.$slots.content ?[
|
||||
return h(this.tag, { ref: 'elem' , 'data-v-tippy' : '' }, this.$slots.content ?[
|
||||
slot,
|
||||
h(this.contentTag, { ref : 'contentElem', class : this.contentClass }, this.$slots.content(this))
|
||||
] : slot)
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Instance } from 'tippy.js'
|
||||
import { ComponentObjectPropsOptions, defineComponent, h, ref } from 'vue'
|
||||
import { useSingleton } from '../composables'
|
||||
import { TippyOptions } from '../types'
|
||||
import tippy, { DefaultProps } from 'tippy.js'
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
interface ComponentCustomProps extends TippyOptions {}
|
||||
}
|
||||
|
||||
const booleanProps = [
|
||||
'a11y',
|
||||
'allowHTML',
|
||||
'arrow',
|
||||
'flip',
|
||||
'flipOnUpdate',
|
||||
'hideOnClick',
|
||||
'ignoreAttributes',
|
||||
'inertia',
|
||||
'interactive',
|
||||
'lazy',
|
||||
'multiple',
|
||||
'showOnInit',
|
||||
'touch',
|
||||
'touchHold',
|
||||
]
|
||||
|
||||
let props: ComponentObjectPropsOptions = {}
|
||||
|
||||
Object.keys(tippy.defaultProps).forEach((prop: string) => {
|
||||
if (booleanProps.includes(prop)) {
|
||||
props[prop] = {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return tippy.defaultProps[prop as keyof DefaultProps] as Boolean
|
||||
},
|
||||
}
|
||||
} else {
|
||||
props[prop] = {
|
||||
default: function () {
|
||||
return tippy.defaultProps[prop as keyof DefaultProps]
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const TippySingleton = defineComponent({
|
||||
props,
|
||||
setup(props) {
|
||||
const instances = ref<Instance<any>[]>([])
|
||||
|
||||
const { singleton } = useSingleton(instances, props)
|
||||
|
||||
return { instances, singleton }
|
||||
},
|
||||
mounted() {
|
||||
const parent = this.$el.parentElement
|
||||
const elements = parent.querySelectorAll('[data-v-tippy]')
|
||||
|
||||
this.instances = Array.from(elements)
|
||||
.map((el: any) => el._tippy)
|
||||
.filter(Boolean)
|
||||
|
||||
this.singleton?.setInstances(this.instances)
|
||||
},
|
||||
render() {
|
||||
let slot = this.$slots.default ? this.$slots.default() : []
|
||||
|
||||
return h(() => slot)
|
||||
},
|
||||
})
|
||||
|
||||
export default TippySingleton
|
||||
@@ -1 +1,2 @@
|
||||
export { useTippy } from './useTippy'
|
||||
export { useSingleton } from './useSingleton'
|
||||
|
||||
@@ -7,6 +7,7 @@ import tippy, {
|
||||
} from 'tippy.js'
|
||||
|
||||
import Tippy from './components/Tippy'
|
||||
import TippySingleton from './components/TippySingleton'
|
||||
import directive from './directive'
|
||||
import plugin from './plugin'
|
||||
|
||||
@@ -27,6 +28,7 @@ export {
|
||||
useSingleton,
|
||||
setDefaultProps,
|
||||
Tippy,
|
||||
TippySingleton,
|
||||
directive,
|
||||
plugin,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import TippyComponent from '../components/Tippy'
|
||||
import TippySingletonComponent from '../components/TippySingleton'
|
||||
import directive from '../directive'
|
||||
import { Plugin } from 'vue'
|
||||
import tippy from 'tippy.js'
|
||||
@@ -10,6 +11,7 @@ const plugin: Plugin = {
|
||||
|
||||
app.directive(options.directive || 'tippy', directive)
|
||||
app.component(options.component || 'tippy', TippyComponent)
|
||||
app.component(options.componentSingleton || 'tippy-singleton', TippySingletonComponent)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ export declare type TippyComponent = InstanceType<typeof Tippy>
|
||||
export interface TippyPluginOptions {
|
||||
directive?: string
|
||||
component?: string
|
||||
componentSingleton?: string
|
||||
defaultProps?: Partial<DefaultProps>
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user