@vue-interface/tooltip 1.0.0-beta.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/docs/tooltip.md +156 -0
- package/index.css +71 -0
- package/index.html +140 -0
- package/index.ts +2 -1
- package/package.json +18 -32
- package/src/Tooltip.vue +167 -25
- package/src/TooltipPlugin.ts +91 -141
- package/tsconfig.json +27 -0
- package/vite.config.js +47 -0
- package/dist/index.d.ts +0 -3
- package/dist/src/Popper.d.ts +0 -73
- package/dist/src/Tooltip.vue.d.ts +0 -73
- package/dist/src/TooltipPlugin.d.ts +0 -11
- package/dist/style.css +0 -1
- package/dist/tooltip.js +0 -193
- package/dist/tooltip.js.map +0 -1
- package/dist/tooltip.umd.cjs +0 -2
- package/dist/tooltip.umd.cjs.map +0 -1
- package/dist/vite.d.ts +0 -5
- package/src/Popper.ts +0 -150
- package/tailwindcss/index.cjs +0 -162
- package/tailwindcss/safelist.cjs +0 -12
package/src/TooltipPlugin.ts
CHANGED
|
@@ -1,127 +1,111 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { h, render, type App, type Directive } from 'vue';
|
|
2
|
+
import Tooltip, { type TooltipProps } from './Tooltip.vue';
|
|
3
|
+
|
|
4
|
+
const prefix = 'data-tooltip';
|
|
5
|
+
const prefixRegExp = new RegExp(`^${prefix}\-`);
|
|
6
|
+
|
|
7
|
+
function getAttributes(el: Element): Record<string,string> {
|
|
8
|
+
return Array.from(el.attributes)
|
|
9
|
+
.map(a => [a.name, a.value])
|
|
10
|
+
.filter(([key]) => key === 'title' || key.match(prefixRegExp))
|
|
11
|
+
.map(([key, value]) => [key.replace(new RegExp(prefixRegExp), ''), value])
|
|
12
|
+
.reduce((carry, attr) => Object.assign(carry, { [attr[0]]: attr[1] }), {});
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
const
|
|
15
|
+
function createTooltip(target: Element, props?: TooltipProps) {
|
|
16
|
+
const container = document.createElement('template');
|
|
17
|
+
|
|
18
|
+
const vnode = h(Tooltip, Object.assign({
|
|
19
|
+
target
|
|
20
|
+
}, getAttributes(target), props));
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
delay: undefined,
|
|
19
|
-
prefix: 'data-tooltip',
|
|
20
|
-
triggers: {
|
|
21
|
-
open: ['mouseover:350'],
|
|
22
|
-
close: ['mouseout:100'],
|
|
23
|
-
}
|
|
24
|
-
}, opts);
|
|
22
|
+
render(vnode, container);
|
|
25
23
|
|
|
26
|
-
const
|
|
27
|
-
const prefixRegExp = new RegExp(`^${prefix}\-`);
|
|
24
|
+
const title = target.getAttribute('title');
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
.filter(([key]) => key === 'title' || key.match(prefixRegExp))
|
|
33
|
-
.map(([key, value]) => [key.replace(new RegExp(prefixRegExp), ''), value])
|
|
34
|
-
.reduce((carry, attr) => Object.assign(carry, { [attr[0]]: attr[1] }), {});
|
|
26
|
+
if(title) {
|
|
27
|
+
target.setAttribute(`${prefix}-og-title`, title);
|
|
28
|
+
target.removeAttribute('title');
|
|
35
29
|
}
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}, props));
|
|
44
|
-
|
|
45
|
-
render(vnode, container);
|
|
46
|
-
|
|
47
|
-
const [el] = [...container.children];
|
|
48
|
-
|
|
49
|
-
document.body.append(el);
|
|
50
|
-
|
|
51
|
-
return () => {
|
|
52
|
-
tooltips.delete(hash);
|
|
31
|
+
return () => {
|
|
32
|
+
if(vnode.component) {
|
|
33
|
+
vnode.component.exposed?.tooltipEl.value?.remove();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
53
37
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// from the CSS transition duration.
|
|
59
|
-
setTimeout(() => el.remove(), 150);
|
|
60
|
-
};
|
|
61
|
-
}
|
|
38
|
+
function destroyTooltip(target: Element) {
|
|
39
|
+
const tooltips = document.querySelectorAll(
|
|
40
|
+
`[${prefix}-id="${target.getAttribute(`${prefix}-id`)}"]`
|
|
41
|
+
);
|
|
62
42
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}, props, getAttributes(target));
|
|
43
|
+
for(const tooltip of tooltips) {
|
|
44
|
+
tooltip.remove();
|
|
45
|
+
}
|
|
67
46
|
|
|
68
|
-
|
|
69
|
-
if(!properties.title || target.hasAttribute(`${prefix}-id`)) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
47
|
+
target.removeAttribute(`${prefix}-id`);
|
|
72
48
|
|
|
73
|
-
|
|
74
|
-
// This prevents double initializing on the same element.
|
|
75
|
-
const hash = Math.random().toString(36).slice(2, 7);
|
|
76
|
-
|
|
77
|
-
// Create the instance vars.
|
|
78
|
-
let tooltip: Function|null, timer: number;
|
|
49
|
+
const title = target.getAttribute(`${prefix}-og-title`);
|
|
79
50
|
|
|
80
|
-
|
|
81
|
-
target.setAttribute(
|
|
82
|
-
|
|
51
|
+
if(title) {
|
|
52
|
+
target.setAttribute('title', title);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
83
55
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
timer = setTimeout(() => {
|
|
89
|
-
// Do a check before creating the tooltip to ensure the dom
|
|
90
|
-
// element still exists. Its possible for the element to
|
|
91
|
-
// be removed after the timeout delay runs.
|
|
92
|
-
if(document.contains(target)) {
|
|
93
|
-
tooltip = createTooltip(target, properties, hash);
|
|
94
|
-
tooltips.set(hash, tooltip);
|
|
95
|
-
}
|
|
96
|
-
}, delay);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
56
|
+
function shouldCreateTooltip(target: Node): target is Element {
|
|
57
|
+
if(!(target instanceof Element)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
99
60
|
|
|
100
|
-
|
|
101
|
-
clearTimeout(timer);
|
|
61
|
+
const attrs = getAttributes(target);
|
|
102
62
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
tooltip && tooltip();
|
|
106
|
-
tooltip = null;
|
|
107
|
-
}, delay);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
63
|
+
return !attrs.id && !!attrs.title;
|
|
64
|
+
}
|
|
110
65
|
|
|
111
|
-
|
|
112
|
-
|
|
66
|
+
function shouldRemoveTooltip(target: Node): target is Element {
|
|
67
|
+
if(!(target instanceof Element)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
113
70
|
|
|
114
|
-
|
|
115
|
-
|
|
71
|
+
return target.hasAttribute(`${prefix}-id`);
|
|
72
|
+
}
|
|
116
73
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
74
|
+
export const TooltipDirective: Directive<Element, string|TooltipProps> = {
|
|
75
|
+
beforeMount(target, binding) {
|
|
76
|
+
createTooltip(target, typeof binding.value === 'string' ? {
|
|
77
|
+
title: binding.value
|
|
78
|
+
}: binding.value);
|
|
79
|
+
},
|
|
80
|
+
beforeUnmount(target) {
|
|
81
|
+
destroyTooltip(target);
|
|
122
82
|
}
|
|
123
|
-
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export function TooltipPlugin(app: App<Element>) {
|
|
124
86
|
app.mixin({
|
|
87
|
+
beforeMount() {
|
|
88
|
+
const observer = new MutationObserver((mutations) => {
|
|
89
|
+
for(const { addedNodes, removedNodes } of mutations) {
|
|
90
|
+
addedNodes.forEach((node) => {
|
|
91
|
+
if(shouldCreateTooltip(node)) {
|
|
92
|
+
createTooltip(node);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
removedNodes.forEach((node) => {
|
|
97
|
+
if(shouldRemoveTooltip(node)) {
|
|
98
|
+
destroyTooltip(node);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
observer.observe(document.body, {
|
|
105
|
+
childList: true,
|
|
106
|
+
subtree: true
|
|
107
|
+
});
|
|
108
|
+
},
|
|
125
109
|
mounted() {
|
|
126
110
|
let el = this.$el;
|
|
127
111
|
|
|
@@ -129,11 +113,6 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
|
|
|
129
113
|
el = this.$el.parentNode;
|
|
130
114
|
}
|
|
131
115
|
|
|
132
|
-
if(el instanceof HTMLElement) {
|
|
133
|
-
init(el);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Create the tree walker.
|
|
137
116
|
const walker = document.createTreeWalker(
|
|
138
117
|
el,
|
|
139
118
|
NodeFilter.SHOW_ALL,
|
|
@@ -146,42 +125,13 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
|
|
|
146
125
|
}
|
|
147
126
|
);
|
|
148
127
|
|
|
149
|
-
// Step through and alert all child nodes
|
|
150
128
|
while(walker.nextNode()) {
|
|
151
|
-
if(walker.currentNode
|
|
152
|
-
|
|
129
|
+
if(shouldCreateTooltip(walker.currentNode)) {
|
|
130
|
+
createTooltip(walker.currentNode);
|
|
153
131
|
}
|
|
154
132
|
}
|
|
155
|
-
|
|
156
|
-
const observer = new MutationObserver((changes) => {
|
|
157
|
-
for(const { removedNodes } of changes) {
|
|
158
|
-
for(const node of removedNodes) {
|
|
159
|
-
for(const el of (node as Element).querySelectorAll(`[${prefix}-id]`)) {
|
|
160
|
-
const tooltip = tooltips.get(
|
|
161
|
-
el.getAttribute(`${prefix}-id`) as string
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
tooltip && tooltip();
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
observer.observe(el, { childList: true });
|
|
171
133
|
}
|
|
172
134
|
});
|
|
173
135
|
|
|
174
|
-
app.directive('tooltip',
|
|
175
|
-
created(target, binding) {
|
|
176
|
-
init(target, Object.assign({}, binding.modifiers, binding.value));
|
|
177
|
-
},
|
|
178
|
-
beforeUnmount(target) {
|
|
179
|
-
const id = target.getAttribute(`${prefix}-id`);
|
|
180
|
-
const tooltip = tooltips.get(id);
|
|
181
|
-
|
|
182
|
-
console.log('beforeUnmount');
|
|
183
|
-
|
|
184
|
-
tooltip && tooltip();
|
|
185
|
-
}
|
|
186
|
-
});
|
|
136
|
+
app.directive<Element, string|TooltipProps>('tooltip', TooltipDirective);
|
|
187
137
|
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"customConditions": ["source"],
|
|
10
|
+
"allowImportingTsExtensions": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUnusedLocals": true,
|
|
16
|
+
"noUnusedParameters": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"jsx": "preserve",
|
|
19
|
+
"jsxImportSource": "vue"
|
|
20
|
+
},
|
|
21
|
+
"include": [
|
|
22
|
+
"**/*.ts",
|
|
23
|
+
"**/*.tsx",
|
|
24
|
+
"**/*.vue",
|
|
25
|
+
],
|
|
26
|
+
"exclude": ["node_modules"]
|
|
27
|
+
}
|
package/vite.config.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
2
|
+
import vue from '@vitejs/plugin-vue';
|
|
3
|
+
import { pascalCase } from 'change-case';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { defineConfig } from 'vite';
|
|
6
|
+
import dts from 'vite-plugin-dts';
|
|
7
|
+
import pkg from './package.json';
|
|
8
|
+
|
|
9
|
+
const fileName = pkg.name.split('/')[1];
|
|
10
|
+
|
|
11
|
+
const external = [
|
|
12
|
+
...(pkg.dependencies ? Object.keys(pkg.dependencies) : []),
|
|
13
|
+
...(pkg.peerDependencies ? Object.keys(pkg.peerDependencies) : [])
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export default ({ command }) => defineConfig({
|
|
17
|
+
build: {
|
|
18
|
+
sourcemap: command === 'build',
|
|
19
|
+
lib: {
|
|
20
|
+
entry: path.resolve(__dirname, 'index.ts'),
|
|
21
|
+
name: pascalCase(fileName),
|
|
22
|
+
fileName,
|
|
23
|
+
},
|
|
24
|
+
rollupOptions: {
|
|
25
|
+
external,
|
|
26
|
+
output: {
|
|
27
|
+
globals: external.reduce((carry, dep) => {
|
|
28
|
+
return Object.assign(carry, {
|
|
29
|
+
[dep]: pascalCase(dep)
|
|
30
|
+
});
|
|
31
|
+
}, {}),
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
watch: !process.env.NODE_ENV && {
|
|
35
|
+
include: [
|
|
36
|
+
'./tailwindcss/**/*.js'
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
plugins: [
|
|
41
|
+
vue(),
|
|
42
|
+
dts({
|
|
43
|
+
entryRoot: path.resolve(__dirname, './'),
|
|
44
|
+
}),
|
|
45
|
+
tailwindcss()
|
|
46
|
+
],
|
|
47
|
+
});
|
package/dist/index.d.ts
DELETED
package/dist/src/Popper.d.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
declare const _default: import("vue").DefineComponent<{
|
|
2
|
-
offset: {
|
|
3
|
-
type: ArrayConstructor;
|
|
4
|
-
default: undefined;
|
|
5
|
-
};
|
|
6
|
-
popper: {
|
|
7
|
-
type: ObjectConstructor;
|
|
8
|
-
default: undefined;
|
|
9
|
-
};
|
|
10
|
-
target: {
|
|
11
|
-
type: {
|
|
12
|
-
new (): Element;
|
|
13
|
-
prototype: Element;
|
|
14
|
-
};
|
|
15
|
-
required: true;
|
|
16
|
-
};
|
|
17
|
-
title: {
|
|
18
|
-
type: StringConstructor;
|
|
19
|
-
default: undefined;
|
|
20
|
-
};
|
|
21
|
-
show: BooleanConstructor;
|
|
22
|
-
top: BooleanConstructor;
|
|
23
|
-
bottom: BooleanConstructor;
|
|
24
|
-
left: BooleanConstructor;
|
|
25
|
-
right: BooleanConstructor;
|
|
26
|
-
}, unknown, {
|
|
27
|
-
currentShow: boolean;
|
|
28
|
-
popperInstance: null;
|
|
29
|
-
}, {
|
|
30
|
-
computedPlacement(): any;
|
|
31
|
-
tooltipClasses(): {
|
|
32
|
-
[x: string]: any;
|
|
33
|
-
show: any;
|
|
34
|
-
};
|
|
35
|
-
}, {
|
|
36
|
-
open(): void;
|
|
37
|
-
close(): void;
|
|
38
|
-
}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
|
39
|
-
offset: {
|
|
40
|
-
type: ArrayConstructor;
|
|
41
|
-
default: undefined;
|
|
42
|
-
};
|
|
43
|
-
popper: {
|
|
44
|
-
type: ObjectConstructor;
|
|
45
|
-
default: undefined;
|
|
46
|
-
};
|
|
47
|
-
target: {
|
|
48
|
-
type: {
|
|
49
|
-
new (): Element;
|
|
50
|
-
prototype: Element;
|
|
51
|
-
};
|
|
52
|
-
required: true;
|
|
53
|
-
};
|
|
54
|
-
title: {
|
|
55
|
-
type: StringConstructor;
|
|
56
|
-
default: undefined;
|
|
57
|
-
};
|
|
58
|
-
show: BooleanConstructor;
|
|
59
|
-
top: BooleanConstructor;
|
|
60
|
-
bottom: BooleanConstructor;
|
|
61
|
-
left: BooleanConstructor;
|
|
62
|
-
right: BooleanConstructor;
|
|
63
|
-
}>>, {
|
|
64
|
-
offset: unknown[];
|
|
65
|
-
popper: Record<string, any>;
|
|
66
|
-
title: string;
|
|
67
|
-
show: boolean;
|
|
68
|
-
top: boolean;
|
|
69
|
-
bottom: boolean;
|
|
70
|
-
left: boolean;
|
|
71
|
-
right: boolean;
|
|
72
|
-
}>;
|
|
73
|
-
export default _default;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
declare const _sfc_main: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").DefineComponent<{
|
|
2
|
-
offset: {
|
|
3
|
-
type: ArrayConstructor;
|
|
4
|
-
default: undefined;
|
|
5
|
-
};
|
|
6
|
-
popper: {
|
|
7
|
-
type: ObjectConstructor;
|
|
8
|
-
default: undefined;
|
|
9
|
-
};
|
|
10
|
-
target: {
|
|
11
|
-
type: {
|
|
12
|
-
new (): Element;
|
|
13
|
-
prototype: Element;
|
|
14
|
-
};
|
|
15
|
-
required: true;
|
|
16
|
-
};
|
|
17
|
-
title: {
|
|
18
|
-
type: StringConstructor;
|
|
19
|
-
default: undefined;
|
|
20
|
-
};
|
|
21
|
-
show: BooleanConstructor;
|
|
22
|
-
top: BooleanConstructor;
|
|
23
|
-
bottom: BooleanConstructor;
|
|
24
|
-
left: BooleanConstructor;
|
|
25
|
-
right: BooleanConstructor;
|
|
26
|
-
}, unknown, {
|
|
27
|
-
currentShow: boolean;
|
|
28
|
-
popperInstance: null;
|
|
29
|
-
}, {
|
|
30
|
-
computedPlacement(): any;
|
|
31
|
-
tooltipClasses(): {
|
|
32
|
-
[x: string]: any;
|
|
33
|
-
show: any;
|
|
34
|
-
};
|
|
35
|
-
}, {
|
|
36
|
-
open(): void;
|
|
37
|
-
close(): void;
|
|
38
|
-
}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
|
39
|
-
offset: {
|
|
40
|
-
type: ArrayConstructor;
|
|
41
|
-
default: undefined;
|
|
42
|
-
};
|
|
43
|
-
popper: {
|
|
44
|
-
type: ObjectConstructor;
|
|
45
|
-
default: undefined;
|
|
46
|
-
};
|
|
47
|
-
target: {
|
|
48
|
-
type: {
|
|
49
|
-
new (): Element;
|
|
50
|
-
prototype: Element;
|
|
51
|
-
};
|
|
52
|
-
required: true;
|
|
53
|
-
};
|
|
54
|
-
title: {
|
|
55
|
-
type: StringConstructor;
|
|
56
|
-
default: undefined;
|
|
57
|
-
};
|
|
58
|
-
show: BooleanConstructor;
|
|
59
|
-
top: BooleanConstructor;
|
|
60
|
-
bottom: BooleanConstructor;
|
|
61
|
-
left: BooleanConstructor;
|
|
62
|
-
right: BooleanConstructor;
|
|
63
|
-
}>>, {
|
|
64
|
-
offset: unknown[];
|
|
65
|
-
popper: Record<string, any>;
|
|
66
|
-
title: string;
|
|
67
|
-
show: boolean;
|
|
68
|
-
top: boolean;
|
|
69
|
-
bottom: boolean;
|
|
70
|
-
left: boolean;
|
|
71
|
-
right: boolean;
|
|
72
|
-
}>, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
|
|
73
|
-
export default _sfc_main;
|
package/dist/style.css
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.tooltip:not(.show){z-index:-1}
|