singleton component

This commit is contained in:
Georges KABBOUCHI
2021-03-09 13:12:57 +02:00
parent c887644e62
commit bd39c6cd54
9 changed files with 133 additions and 37 deletions
+1
View File
@@ -41,6 +41,7 @@ app.use(
{
directive: 'tippy', // => v-tippy
component: 'tippy', // => <tippy/>
componentSingleton: 'tippy-singleton', // => <tippy-singleton/>
}
)
+37 -16
View File
@@ -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()">&times;</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()"
>&times;</button>
<pre class="p-4">{{ tippy && tippy.state }}</pre>
</template>
</tippy>
</div>
+13 -19
View File
@@ -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>
+2 -2
View File
@@ -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)
+74
View File
@@ -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
View File
@@ -1 +1,2 @@
export { useTippy } from './useTippy'
export { useSingleton } from './useSingleton'
+2
View File
@@ -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,
}
+2
View File
@@ -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)
},
}
+1
View File
@@ -22,6 +22,7 @@ export declare type TippyComponent = InstanceType<typeof Tippy>
export interface TippyPluginOptions {
directive?: string
component?: string
componentSingleton?: string
defaultProps?: Partial<DefaultProps>
}