@vue-interface/tooltip 1.0.0-beta.12 → 1.0.0-beta.14

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.
@@ -1,82 +1,104 @@
1
- declare const _sfc_main: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").DefineComponent<{
1
+ import { Instance } from '@popperjs/core';
2
+ declare const _sfc_main: import("vue").DefineComponent<{
2
3
  offset: {
3
- type: ArrayConstructor;
4
- default: undefined;
4
+ type: ObjectConstructor;
5
+ required: false;
5
6
  };
6
7
  popper: {
7
8
  type: ObjectConstructor;
8
- default: undefined;
9
+ required: false;
9
10
  };
10
11
  placement: {
11
12
  type: StringConstructor;
12
- default: undefined;
13
+ required: false;
13
14
  };
14
15
  target: {
15
- type: {
16
- new (): Element;
17
- prototype: Element;
18
- };
16
+ type: null;
19
17
  required: true;
20
18
  };
21
19
  title: {
22
20
  type: StringConstructor;
23
- default: undefined;
24
- };
25
- show: BooleanConstructor;
26
- top: BooleanConstructor;
27
- bottom: BooleanConstructor;
28
- left: BooleanConstructor;
29
- right: BooleanConstructor;
30
- }, unknown, {
31
- currentShow: boolean;
32
- popperInstance: null;
33
- }, {
34
- computedPlacement(): any;
35
- tooltipClasses(): {
36
- [x: string]: any;
37
- show: any;
21
+ required: false;
22
+ };
23
+ show: {
24
+ type: BooleanConstructor;
25
+ required: false;
26
+ };
27
+ top: {
28
+ type: BooleanConstructor;
29
+ required: false;
30
+ };
31
+ bottom: {
32
+ type: BooleanConstructor;
33
+ required: false;
34
+ };
35
+ left: {
36
+ type: BooleanConstructor;
37
+ required: false;
38
+ };
39
+ right: {
40
+ type: BooleanConstructor;
41
+ required: false;
38
42
  };
39
43
  }, {
40
- open(): void;
41
- close(): void;
42
- }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
44
+ props: any;
45
+ el: import("vue").Ref<HTMLElement | undefined>;
46
+ arrow: import("vue").Ref<HTMLElement | undefined>;
47
+ currentShow: import("vue").Ref<boolean>;
48
+ popperInstance: import("vue").Ref<Instance | undefined>;
49
+ placement: import("vue").ComputedRef<any>;
50
+ tooltipClasses: import("vue").ComputedRef<{
51
+ [x: string]: boolean | import("vue").Ref<boolean>;
52
+ show: import("vue").Ref<boolean>;
53
+ }>;
54
+ open: () => void;
55
+ close: () => void;
56
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
43
57
  offset: {
44
- type: ArrayConstructor;
45
- default: undefined;
58
+ type: ObjectConstructor;
59
+ required: false;
46
60
  };
47
61
  popper: {
48
62
  type: ObjectConstructor;
49
- default: undefined;
63
+ required: false;
50
64
  };
51
65
  placement: {
52
66
  type: StringConstructor;
53
- default: undefined;
67
+ required: false;
54
68
  };
55
69
  target: {
56
- type: {
57
- new (): Element;
58
- prototype: Element;
59
- };
70
+ type: null;
60
71
  required: true;
61
72
  };
62
73
  title: {
63
74
  type: StringConstructor;
64
- default: undefined;
75
+ required: false;
76
+ };
77
+ show: {
78
+ type: BooleanConstructor;
79
+ required: false;
80
+ };
81
+ top: {
82
+ type: BooleanConstructor;
83
+ required: false;
84
+ };
85
+ bottom: {
86
+ type: BooleanConstructor;
87
+ required: false;
88
+ };
89
+ left: {
90
+ type: BooleanConstructor;
91
+ required: false;
92
+ };
93
+ right: {
94
+ type: BooleanConstructor;
95
+ required: false;
65
96
  };
66
- show: BooleanConstructor;
67
- top: BooleanConstructor;
68
- bottom: BooleanConstructor;
69
- left: BooleanConstructor;
70
- right: BooleanConstructor;
71
97
  }>>, {
72
- offset: unknown[];
73
- popper: Record<string, any>;
74
- placement: string;
75
- title: string;
76
98
  show: boolean;
77
99
  top: boolean;
78
100
  bottom: boolean;
79
101
  left: boolean;
80
102
  right: boolean;
81
- }>, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
103
+ }, {}>;
82
104
  export default _sfc_main;
package/dist/tooltip.js CHANGED
@@ -1,115 +1,80 @@
1
- import { defineComponent as $, openBlock as A, createElementBlock as S, normalizeClass as N, createElementVNode as _, renderSlot as O, createTextVNode as L, toDisplayString as j, h as B, render as C } from "vue";
2
- import { createPopper as P } from "@popperjs/core";
3
- const I = $({
1
+ import { defineComponent as B, ref as b, computed as w, onMounted as L, nextTick as O, onBeforeUnmount as S, openBlock as j, createElementBlock as k, normalizeClass as C, createElementVNode as x, renderSlot as F, createTextVNode as M, toDisplayString as R, h as I, render as P } from "vue";
2
+ import { createPopper as H } from "@popperjs/core";
3
+ const U = {
4
+ ref: "inner",
5
+ class: "tooltip-inner"
6
+ }, V = /* @__PURE__ */ B({
7
+ __name: "Tooltip",
4
8
  props: {
5
- offset: {
6
- type: Array,
7
- default: void 0
8
- },
9
- popper: {
10
- type: Object,
11
- default: void 0
12
- },
13
- placement: {
14
- type: String,
15
- default: void 0
16
- },
17
- target: {
18
- type: Element,
19
- required: !0
20
- },
21
- title: {
22
- type: String,
23
- default: void 0
24
- },
25
- show: Boolean,
26
- top: Boolean,
27
- bottom: Boolean,
28
- left: Boolean,
29
- right: Boolean
30
- },
31
- data() {
32
- return {
33
- currentShow: !1,
34
- popperInstance: null
35
- };
9
+ offset: {},
10
+ popper: {},
11
+ placement: {},
12
+ target: {},
13
+ title: {},
14
+ show: { type: Boolean },
15
+ top: { type: Boolean },
16
+ bottom: { type: Boolean },
17
+ left: { type: Boolean },
18
+ right: { type: Boolean }
36
19
  },
37
- computed: {
38
- computedPlacement() {
39
- return this.placement ? this.placement : this.bottom ? "bottom" : this.left ? "left" : this.right ? "right" : "top";
40
- },
41
- tooltipClasses() {
42
- return {
43
- show: this.currentShow,
44
- [`bs-tooltip-${this.computedPlacement}`]: !0
45
- };
20
+ setup(d, { expose: h }) {
21
+ const n = d, u = b(), r = b(), a = b(!1), p = b(), v = w(() => n.placement ? n.placement : n.bottom ? "bottom" : n.left ? "left" : n.right ? "right" : "top"), T = w(() => ({
22
+ show: a,
23
+ [`bs-tooltip-${v.value}`]: !0
24
+ }));
25
+ function f() {
26
+ a.value = !0;
46
27
  }
47
- },
48
- mounted() {
49
- this.popperInstance = P(this.target, this.$el, Object.assign({
50
- placement: this.computedPlacement,
51
- modifiers: [
52
- {
53
- name: "offset",
54
- options: {
55
- offset: [0, 6]
56
- }
57
- },
58
- {
59
- name: "arrow",
60
- options: {
61
- element: this.$refs.arrow
62
- }
63
- }
64
- ]
65
- }, this.popper)), this.$nextTick(() => {
66
- this.currentShow = this.show;
67
- });
68
- },
69
- beforeUnmount() {
70
- this.popperInstance && this.popperInstance.destroy();
71
- },
72
- methods: {
73
- open() {
74
- this.currentShow = !0;
75
- },
76
- close() {
77
- this.currentShow = !1;
28
+ function e() {
29
+ a.value = !1;
78
30
  }
31
+ return h({
32
+ open: f,
33
+ close: e
34
+ }), L(() => {
35
+ var t, o;
36
+ u.value && (p.value = H(n.target, u.value, Object.assign({
37
+ placement: v.value,
38
+ modifiers: [
39
+ {
40
+ name: "offset",
41
+ options: {
42
+ offset: [((t = n.offset) == null ? void 0 : t.x) ?? 0, ((o = n.offset) == null ? void 0 : o.y) ?? 6]
43
+ }
44
+ },
45
+ {
46
+ name: "arrow",
47
+ options: {
48
+ element: r.value
49
+ }
50
+ }
51
+ ]
52
+ }, n.popper)), O(() => {
53
+ a.value = n.show;
54
+ }));
55
+ }), S(() => {
56
+ p.value && p.value.destroy();
57
+ }), (t, o) => (j(), k("div", {
58
+ ref_key: "el",
59
+ ref: u,
60
+ class: C(["tooltip", T.value]),
61
+ role: "tooltip"
62
+ }, [
63
+ x("div", {
64
+ ref_key: "arrow",
65
+ ref: r,
66
+ class: "tooltip-arrow"
67
+ }, null, 512),
68
+ x("div", U, [
69
+ F(t.$slots, "default", {}, () => [
70
+ M(R(t.title), 1)
71
+ ])
72
+ ], 512)
73
+ ], 2));
79
74
  }
80
- }), R = $({
81
- mixins: [
82
- I
83
- ]
84
75
  });
85
- const k = (l, d) => {
86
- const p = l.__vccOpts || l;
87
- for (const [a, n] of d)
88
- p[a] = n;
89
- return p;
90
- }, F = {
91
- ref: "arrow",
92
- class: "tooltip-arrow"
93
- }, M = {
94
- ref: "inner",
95
- class: "tooltip-inner"
96
- };
97
- function q(l, d, p, a, n, m) {
98
- return A(), S("div", {
99
- class: N(["tooltip", l.tooltipClasses]),
100
- role: "tooltip"
101
- }, [
102
- _("div", F, null, 512),
103
- _("div", M, [
104
- O(l.$slots, "default", {}, () => [
105
- L(j(l.title), 1)
106
- ])
107
- ], 512)
108
- ], 2);
109
- }
110
- const H = /* @__PURE__ */ k(R, [["render", q]]);
111
- function W(l, d = {}) {
112
- const p = /* @__PURE__ */ new Map(), a = Object.assign({
76
+ function z(d, h = {}) {
77
+ const n = /* @__PURE__ */ new Map(), u = Object.assign({
113
78
  delay: void 0,
114
79
  prefix: "data-tooltip",
115
80
  progressiveEnhancement: !0,
@@ -117,85 +82,94 @@ function W(l, d = {}) {
117
82
  open: ["mouseover:350"],
118
83
  close: ["mouseout:100"]
119
84
  }
120
- }, d), n = a.prefix.replace(/[-]+$/, ""), m = new RegExp(`^${n}-`);
121
- function E(e) {
122
- return Array.from(e.attributes).map((t) => [t.name, t.value]).filter(([t]) => t === "title" || t.match(m)).map(([t, o]) => [t.replace(new RegExp(m), ""), o]).reduce((t, o) => Object.assign(t, { [o[0]]: o[1] }), {});
85
+ }, h), r = u.prefix.replace(/[-]+$/, ""), a = new RegExp(`^${r}-`);
86
+ function p(e) {
87
+ return Array.from(e.attributes).map((t) => [t.name, t.value]).filter(([t]) => t === "title" || t.match(a)).map(([t, o]) => [t.replace(new RegExp(a), ""), o]).reduce((t, o) => Object.assign(t, { [o[0]]: o[1] }), {});
123
88
  }
124
- function w(e, t = {}, o) {
125
- const i = document.createElement("template"), r = B(H, Object.assign({
89
+ function v(e, t = {}, o) {
90
+ const l = document.createElement("template"), i = I(V, Object.assign({
126
91
  target: e,
127
92
  show: !0
128
93
  }, t));
129
- C(r, i);
130
- const [s] = [...i.children];
94
+ P(i, l);
95
+ const [s] = [...l.children];
131
96
  return document.body.append(s), () => {
132
- var u;
133
- p.delete(o), (u = r.component) == null || u.ctx.close(), setTimeout(() => s.remove(), 150);
97
+ n.delete(o), setTimeout(() => s.remove(), 150);
134
98
  };
135
99
  }
136
- function h(e, t = {}) {
137
- var b, v;
100
+ function T(e) {
101
+ const t = e.getAttribute(`${r}-id`);
102
+ if (t) {
103
+ const o = n.get(t);
104
+ o == null || o();
105
+ }
106
+ }
107
+ function f(e, t = {}) {
108
+ var _, y;
138
109
  const o = Object.assign({
139
- title: e.getAttribute(n) || e.getAttribute("title")
140
- }, t, E(e));
141
- if (!o.title || e.hasAttribute(`${n}-id`))
110
+ title: e.getAttribute(r) || e.getAttribute("title")
111
+ }, t, p(e));
112
+ if (!o.title || e.hasAttribute(`${r}-id`))
142
113
  return;
143
- const i = Math.random().toString(36).slice(2, 7);
144
- let r, s;
145
- e.setAttribute(`${n}-id`, i), e.removeAttribute("title");
146
- function u(c = 0) {
147
- clearTimeout(s), r || (s = setTimeout(() => {
148
- document.contains(e) && (r = w(e, o, i), p.set(i, r));
114
+ const l = Math.random().toString(36).slice(2, 7);
115
+ let i, s;
116
+ e.setAttribute(`${r}-id`, l), e.removeAttribute("title");
117
+ function g(c = 0) {
118
+ clearTimeout(s), i || (s = setTimeout(() => {
119
+ document.contains(e) && (i = v(e, o, l), n.set(l, i));
149
120
  }, c));
150
121
  }
151
- function f(c = 0) {
152
- clearTimeout(s), r && (s = setTimeout(() => {
153
- r && r(), r = null;
122
+ function E(c = 0) {
123
+ clearTimeout(s), i && (s = setTimeout(() => {
124
+ i && i(), i = null;
154
125
  }, c));
155
126
  }
156
- function g(c, T) {
157
- const [x, y] = c.split(":");
158
- e.addEventListener(x, () => T(Number(y || 0)));
127
+ function m(c, A) {
128
+ const [$, N] = c.split(":");
129
+ e.addEventListener($, () => A(Number(N || 0)));
159
130
  }
160
- (((b = e.getAttribute(`${n}-trigger-open`)) == null ? void 0 : b.split(",")) || a.triggers.open).map((c) => g(c, u)), (((v = e.getAttribute(`${n}-trigger-close`)) == null ? void 0 : v.split(",")) || a.triggers.close).map((c) => g(c, f));
131
+ (((_ = e.getAttribute(`${r}-trigger-open`)) == null ? void 0 : _.split(",")) || u.triggers.open).map((c) => m(c, g)), (((y = e.getAttribute(`${r}-trigger-close`)) == null ? void 0 : y.split(",")) || u.triggers.close).map((c) => m(c, E));
161
132
  }
162
- l.mixin({
133
+ d.mixin({
163
134
  mounted() {
164
- if (!a.progressiveEnhancement)
135
+ if (!u.progressiveEnhancement)
165
136
  return;
166
137
  let e = this.$el;
167
- this.$el instanceof Text && (e = this.$el.parentNode), e instanceof HTMLElement && h(e);
138
+ this.$el instanceof Text && (e = this.$el.parentNode), e instanceof HTMLElement && f(e);
168
139
  const t = document.createTreeWalker(
169
140
  e,
170
141
  NodeFilter.SHOW_ALL,
171
- (i) => i instanceof Element ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
142
+ (l) => l instanceof Element ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
172
143
  );
173
144
  for (; t.nextNode(); )
174
- t.currentNode instanceof Element && h(t.currentNode);
175
- new MutationObserver((i) => {
176
- for (const { removedNodes: r } of i)
177
- for (const s of r)
178
- if (s instanceof Element)
179
- for (const u of s.querySelectorAll(`[${n}-id]`)) {
180
- const f = p.get(
181
- u.getAttribute(`${n}-id`)
145
+ t.currentNode instanceof Element && f(t.currentNode);
146
+ new MutationObserver((l) => {
147
+ let i = !1;
148
+ for (const { removedNodes: s } of l)
149
+ for (const g of s)
150
+ if (g instanceof Element)
151
+ for (const E of g.querySelectorAll(`[${r}-id]`)) {
152
+ const m = n.get(
153
+ E.getAttribute(`${r}-id`)
182
154
  );
183
- f && f();
155
+ m && (i = !0, m());
184
156
  }
157
+ if (!i)
158
+ for (const s of n.values())
159
+ s();
185
160
  }).observe(e, { childList: !0 });
186
161
  }
187
- }), l.directive("tooltip", {
162
+ }), d.directive("tooltip", {
188
163
  beforeMount(e, t) {
189
- h(e, Object.assign({}, t.modifiers, t.value));
164
+ f(e, Object.assign({}, t.modifiers, t.value));
190
165
  },
191
166
  beforeUnmount(e) {
192
- const t = e.getAttribute(`${n}-id`), o = p.get(t);
193
- o && o();
167
+ T(e);
194
168
  }
195
169
  });
196
170
  }
197
171
  export {
198
- H as Tooltip,
199
- W as TooltipPlugin
172
+ V as Tooltip,
173
+ z as TooltipPlugin
200
174
  };
201
175
  //# sourceMappingURL=tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","sources":["../src/Popper.ts","../src/Tooltip.vue","../src/TooltipPlugin.ts"],"sourcesContent":["import { createPopper } from '@popperjs/core';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n\n props: {\n offset: {\n type: Array,\n default: undefined\n },\n\n popper: {\n type: Object,\n default: undefined\n },\n\n placement: {\n type: String,\n default: undefined\n },\n\n target: {\n type: Element,\n required: true\n },\n\n title: {\n type: String,\n default: undefined\n },\n \n show: Boolean,\n \n top: Boolean,\n\n bottom: Boolean,\n\n left: Boolean,\n\n right: Boolean,\n },\n\n data() {\n return {\n currentShow: false,\n popperInstance: null\n };\n },\n\n computed: {\n computedPlacement() {\n if(this.placement) {\n return this.placement;\n }\n\n if(this.bottom) {\n return 'bottom';\n }\n\n if(this.left) {\n return 'left';\n }\n\n if(this.right) {\n return 'right';\n }\n\n return 'top';\n },\n tooltipClasses() {\n return {\n show: this.currentShow,\n [`bs-tooltip-${this.computedPlacement}`]: true\n };\n }\n },\n\n mounted() {\n this.popperInstance = createPopper(this.target, this.$el, Object.assign({\n placement: this.computedPlacement,\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [0, 6]\n },\n },\n {\n name: 'arrow',\n options: {\n element: this.$refs.arrow,\n },\n },\n ],\n }, this.popper));\n\n this.$nextTick(() => {\n this.currentShow = this.show;\n });\n },\n\n beforeUnmount() {\n this.popperInstance && this.popperInstance.destroy();\n },\n\n methods: {\n\n open() {\n this.currentShow = true;\n },\n\n close() {\n this.currentShow = false;\n }\n\n }\n\n});","<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport Popper from './Popper';\n\nexport default defineComponent({\n mixins: [\n Popper\n ]\n});\n</script>\n\n<template>\n <div\n class=\"tooltip\"\n :class=\"tooltipClasses\"\n role=\"tooltip\">\n <div\n ref=\"arrow\"\n class=\"tooltip-arrow\" />\n <div\n ref=\"inner\"\n class=\"tooltip-inner\">\n <slot>{{ title }}</slot>\n </div>\n </div>\n</template>\n\n<style>\n.tooltip:not(.show) {\n z-index: -1;\n}\n</style>","import type { App } from 'vue';\nimport { h, render } from 'vue';\nimport Tooltip from './Tooltip.vue';\n\ntype TooltipPluginOptions = {\n delay?: number,\n prefix: string,\n progressiveEnhancement: boolean,\n triggers: {\n open: string[],\n close: string[],\n }\n}\n\nexport default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {\n const tooltips: Map<string,Function> = new Map;\n\n const options: TooltipPluginOptions = Object.assign({\n delay: undefined,\n prefix: 'data-tooltip',\n progressiveEnhancement: true,\n triggers: {\n open: ['mouseover:350'],\n close: ['mouseout:100'],\n }\n }, opts);\n \n const prefix = options.prefix.replace(/[-]+$/, '');\n const prefixRegExp = new RegExp(`^${prefix}\\-`);\n\n function getAttributes(el: Element): Record<string,any> {\n return Array.from(el.attributes)\n .map(a => [a.name, a.value])\n .filter(([key]) => key === 'title' || key.match(prefixRegExp))\n .map(([key, value]) => [key.replace(new RegExp(prefixRegExp), ''), value])\n .reduce((carry, attr) => Object.assign(carry, { [attr[0]]: attr[1] }), {});\n }\n\n function createTooltip(target: Element, props: Record<string,any> = {}, hash: string): Function {\n const container = document.createElement('template');\n \n const vnode = h(Tooltip, Object.assign({\n target,\n show: true\n }, props));\n \n render(vnode, container);\n \n const [el] = [...container.children];\n \n document.body.append(el);\n \n return () => {\n tooltips.delete(hash);\n\n // @ts-ignore\n vnode.component?.ctx.close();\n \n // @todo: Make the animation rate (150) dynamic. Should get value \n // from the CSS transition duration.\n setTimeout(() => el.remove(), 150);\n };\n }\n\n function init(target: Element, props = {}) {\n const properties: Record<string,any> = Object.assign({\n title: target.getAttribute(prefix) || target.getAttribute('title')\n }, props, getAttributes(target));\n\n // If the properties don't have a title, ignore this target.\n if(!properties.title || target.hasAttribute(`${prefix}-id`)) {\n return;\n }\n\n // Create a unique \"hash\" to show the node has been initialized.\n // This prevents double initializing on the same element.\n const hash = Math.random().toString(36).slice(2, 7);\n \n // Create the instance vars.\n let tooltip: Function|null, timer: number;\n\n //target.setAttribute(prefix, properties.title);\n target.setAttribute(`${prefix}-id`, hash);\n target.removeAttribute('title');\n\n function open(delay = 0) {\n clearTimeout(timer);\n\n if(!tooltip) {\n timer = setTimeout(() => {\n // Do a check before creating the tooltip to ensure the dom\n // element still exists. Its possible for the element to\n // be removed after the timeout delay runs.\n if(document.contains(target)) {\n tooltip = createTooltip(target, properties, hash);\n tooltips.set(hash, tooltip);\n }\n }, delay);\n }\n }\n\n function close(delay = 0) {\n clearTimeout(timer);\n\n if(tooltip) {\n timer = setTimeout(() => {\n tooltip && tooltip();\n tooltip = null;\n }, delay);\n } \n }\n\n function addEventListener(trigger: string, fn: Function) {\n const [ event, delayString ] = trigger.split(':');\n\n target.addEventListener(event, () => fn(Number(delayString || 0)));\n }\n\n (target.getAttribute(`${prefix}-trigger-open`)?.split(',') || options.triggers.open)\n .map(trigger => addEventListener(trigger, open));\n \n (target.getAttribute(`${prefix}-trigger-close`)?.split(',') || options.triggers.close)\n .map(trigger => addEventListener(trigger, close));\n }\n \n app.mixin({\n mounted() {\n if(!options.progressiveEnhancement) {\n return;\n }\n \n let el = this.$el;\n\n if(this.$el instanceof Text) {\n el = this.$el.parentNode;\n }\n\n if(el instanceof HTMLElement) {\n init(el);\n }\n\n // Create the tree walker.\n const walker = document.createTreeWalker(\n el,\n NodeFilter.SHOW_ALL,\n (node: Node) => {\n if(!(node instanceof Element)) {\n return NodeFilter.FILTER_REJECT;\n }\n \n return NodeFilter.FILTER_ACCEPT;\n }\n );\n\n // Step through and alert all child nodes\n while(walker.nextNode()) {\n if(walker.currentNode instanceof Element) {\n init(<Element> walker.currentNode);\n }\n }\n\n const observer = new MutationObserver((changes) => {\n for(const { removedNodes } of changes) {\n for(const node of removedNodes) {\n if(!(node instanceof Element)) {\n continue;\n }\n \n for(const el of node.querySelectorAll(`[${prefix}-id]`)) {\n const tooltip = tooltips.get(\n el.getAttribute(`${prefix}-id`) as string\n );\n\n tooltip && tooltip();\n }\n } \n }\n });\n\n observer.observe(el, { childList: true });\n }\n });\n\n app.directive('tooltip', {\n beforeMount(target, binding) {\n init(target, Object.assign({}, binding.modifiers, binding.value));\n },\n beforeUnmount(target) {\n const id = target.getAttribute(`${prefix}-id`);\n const tooltip = tooltips.get(id);\n\n tooltip && tooltip();\n }\n });\n}"],"names":["Popper","defineComponent","createPopper","_sfc_main","_hoisted_1","_hoisted_2","_sfc_render","_ctx","_cache","$props","$setup","$data","$options","_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_renderSlot","TooltipPlugin","app","opts","tooltips","options","prefix","prefixRegExp","getAttributes","el","a","key","value","carry","attr","createTooltip","target","props","hash","container","vnode","h","Tooltip","render","_a","init","properties","tooltip","timer","open","delay","close","addEventListener","trigger","fn","event","delayString","_b","walker","node","changes","removedNodes","binding","id"],"mappings":"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"}
1
+ {"version":3,"file":"tooltip.js","sources":["../src/Tooltip.vue","../src/TooltipPlugin.ts"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { Instance, Offsets, OptionsGeneric, createPopper } from '@popperjs/core';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';\n\nconst props = defineProps<{\n offset?: Offsets,\n popper?: OptionsGeneric<unknown>,\n placement?: string,\n target: Element,\n title?: string,\n show?: boolean,\n top?: boolean,\n bottom?: boolean,\n left?: boolean,\n right?: boolean\n}>();\n\nconst el = ref<HTMLElement>();\nconst arrow = ref<HTMLElement>();\nconst currentShow = ref(false);\nconst popperInstance = ref<Instance>();\n\nconst placement = computed(() => {\n if(props.placement) {\n return props.placement;\n }\n\n if(props.bottom) {\n return 'bottom';\n }\n\n if(props.left) {\n return 'left';\n }\n\n if(props.right) {\n return 'right';\n }\n\n return 'top';\n});\n\nconst tooltipClasses = computed(() => {\n return {\n show: currentShow,\n [`bs-tooltip-${placement.value}`]: true\n };\n});\n\nfunction open() {\n currentShow.value = true;\n}\n\nfunction close() {\n currentShow.value = false;\n}\n\ndefineExpose({\n open, close\n});\n\nonMounted(() => {\n if(!el.value) {\n return;\n }\n\n popperInstance.value = createPopper(props.target, el.value, Object.assign({\n placement: placement.value,\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [props.offset?.x ?? 0, props.offset?.y ?? 6]\n },\n },\n {\n name: 'arrow',\n options: {\n element: arrow.value,\n },\n },\n ],\n }, props.popper));\n\n nextTick(() => {\n currentShow.value = props.show;\n });\n});\n\nonBeforeUnmount(()=> {\n popperInstance.value && popperInstance.value.destroy();\n});\n</script>\n\n<template>\n <div\n ref=\"el\"\n class=\"tooltip\"\n :class=\"tooltipClasses\"\n role=\"tooltip\">\n <div\n ref=\"arrow\"\n class=\"tooltip-arrow\" />\n <div\n ref=\"inner\"\n class=\"tooltip-inner\">\n <slot>{{ title }}</slot>\n </div>\n </div>\n</template>\n\n<style>\n.tooltip:not(.show) {\n z-index: -1;\n}\n</style>","import type { App } from 'vue';\nimport { h, render } from 'vue';\nimport Tooltip from './Tooltip.vue';\n\ntype TooltipPluginOptions = {\n delay?: number,\n prefix: string,\n progressiveEnhancement: boolean,\n triggers: {\n open: string[],\n close: string[],\n }\n}\n\nexport default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {\n const tooltips: Map<string,Function> = new Map;\n\n const options: TooltipPluginOptions = Object.assign({\n delay: undefined,\n prefix: 'data-tooltip',\n progressiveEnhancement: true,\n triggers: {\n open: ['mouseover:350'],\n close: ['mouseout:100'],\n }\n }, opts);\n \n const prefix = options.prefix.replace(/[-]+$/, '');\n const prefixRegExp = new RegExp(`^${prefix}\\-`);\n\n function getAttributes(el: Element): Record<string,string> {\n return Array.from(el.attributes)\n .map(a => [a.name, a.value])\n .filter(([key]) => key === 'title' || key.match(prefixRegExp))\n .map(([key, value]) => [key.replace(new RegExp(prefixRegExp), ''), value])\n .reduce((carry, attr) => Object.assign(carry, { [attr[0]]: attr[1] }), {});\n }\n\n function createTooltip(target: Element, props: Record<string,string> = {}, hash: string): Function {\n const container = document.createElement('template');\n \n const vnode = h(Tooltip, Object.assign({\n target,\n show: true\n }, props));\n \n render(vnode, container);\n \n const [el] = [...container.children];\n \n document.body.append(el);\n \n return () => {\n tooltips.delete(hash);\n\n // vnode.component?.close();\n \n // @todo: Make the animation rate (150) dynamic. Should get value \n // from the CSS transition duration.\n setTimeout(() => el.remove(), 150);\n };\n }\n\n function destroyTooltip(target: Element) {\n const id = target.getAttribute(`${prefix}-id`);\n if(id) {\n const tooltip = tooltips.get(id);\n tooltip?.();\n }\n }\n\n function init(target: Element, props = {}) {\n const properties: Record<string,string> = Object.assign({\n title: target.getAttribute(prefix) || target.getAttribute('title')\n }, props, getAttributes(target));\n\n // If the properties don't have a title, ignore this target.\n if(!properties.title || target.hasAttribute(`${prefix}-id`)) {\n return;\n }\n\n // Create a unique \"hash\" to show the node has been initialized.\n // This prevents double initializing on the same element.\n const hash = Math.random().toString(36).slice(2, 7);\n \n // Create the instance vars.\n let tooltip: Function|null, timer: number;\n\n //target.setAttribute(prefix, properties.title);\n target.setAttribute(`${prefix}-id`, hash);\n target.removeAttribute('title');\n\n function open(delay = 0) {\n clearTimeout(timer);\n\n if(!tooltip) {\n timer = setTimeout(() => {\n // Do a check before creating the tooltip to ensure the dom\n // element still exists. Its possible for the element to\n // be removed after the timeout delay runs.\n if(document.contains(target)) {\n tooltip = createTooltip(target, properties, hash);\n tooltips.set(hash, tooltip);\n }\n }, delay);\n }\n }\n\n function close(delay = 0) {\n clearTimeout(timer);\n\n if(tooltip) {\n timer = setTimeout(() => {\n tooltip && tooltip();\n tooltip = null;\n }, delay);\n }\n }\n\n function addEventListener(trigger: string, fn: Function) {\n const [ event, delayString ] = trigger.split(':');\n\n target.addEventListener(event, () => fn(Number(delayString || 0)));\n }\n\n (target.getAttribute(`${prefix}-trigger-open`)?.split(',') || options.triggers.open)\n .map(trigger => addEventListener(trigger, open));\n \n (target.getAttribute(`${prefix}-trigger-close`)?.split(',') || options.triggers.close)\n .map(trigger => addEventListener(trigger, close));\n }\n \n app.mixin({\n mounted() {\n if(!options.progressiveEnhancement) {\n return;\n }\n \n let el = this.$el;\n\n if(this.$el instanceof Text) {\n el = this.$el.parentNode;\n }\n\n if(el instanceof HTMLElement) {\n init(el);\n }\n\n // Create the tree walker.\n const walker = document.createTreeWalker(\n el,\n NodeFilter.SHOW_ALL,\n (node: Node) => {\n if(!(node instanceof Element)) {\n return NodeFilter.FILTER_REJECT;\n }\n \n return NodeFilter.FILTER_ACCEPT;\n }\n );\n\n // Step through and alert all child nodes\n while(walker.nextNode()) {\n if(walker.currentNode instanceof Element) {\n init(<Element> walker.currentNode);\n }\n }\n\n const observer = new MutationObserver((changes) => {\n\n let tooltipFound = false;\n for(const { removedNodes } of changes) {\n for(const node of removedNodes) {\n if(!(node instanceof Element)) {\n continue;\n }\n for(const el of node.querySelectorAll(`[${prefix}-id]`)) {\n const tooltip = tooltips.get(\n el.getAttribute(`${prefix}-id`) as string\n );\n if(tooltip) {\n tooltipFound = true;\n tooltip();\n }\n }\n } \n }\n\n // @experimental\n // In some cases in Inertia.js, not all tooltips are removed on certain actions.\n // remove all tooltips if no tooltip was found.\n if(!tooltipFound) {\n for(const tooltip of tooltips.values()) {\n tooltip();\n }\n }\n });\n\n observer.observe(el, { childList: true });\n },\n });\n\n app.directive('tooltip', {\n beforeMount(target, binding) {\n init(target, Object.assign({}, binding.modifiers, binding.value));\n },\n beforeUnmount(target) {\n destroyTooltip(target);\n }\n });\n}"],"names":["el","ref","arrow","currentShow","popperInstance","placement","computed","props","tooltipClasses","open","close","__expose","onMounted","createPopper","_a","_b","nextTick","onBeforeUnmount","TooltipPlugin","app","opts","tooltips","options","prefix","prefixRegExp","getAttributes","a","key","value","carry","attr","createTooltip","target","hash","container","vnode","h","Tooltip","render","destroyTooltip","id","tooltip","init","properties","timer","delay","addEventListener","trigger","fn","event","delayString","walker","node","changes","tooltipFound","removedNodes","binding"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- (function(c,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("vue"),require("@popperjs/core")):typeof define=="function"&&define.amd?define(["exports","vue","@popperjs/core"],o):(c=typeof globalThis<"u"?globalThis:c||self,o(c.Tooltip={},c.Vue,c.PopperjsCore))})(this,function(c,o,$){"use strict";const w=o.defineComponent({props:{offset:{type:Array,default:void 0},popper:{type:Object,default:void 0},placement:{type:String,default:void 0},target:{type:Element,required:!0},title:{type:String,default:void 0},show:Boolean,top:Boolean,bottom:Boolean,left:Boolean,right:Boolean},data(){return{currentShow:!1,popperInstance:null}},computed:{computedPlacement(){return this.placement?this.placement:this.bottom?"bottom":this.left?"left":this.right?"right":"top"},tooltipClasses(){return{show:this.currentShow,[`bs-tooltip-${this.computedPlacement}`]:!0}}},mounted(){this.popperInstance=$.createPopper(this.target,this.$el,Object.assign({placement:this.computedPlacement,modifiers:[{name:"offset",options:{offset:[0,6]}},{name:"arrow",options:{element:this.$refs.arrow}}]},this.popper)),this.$nextTick(()=>{this.currentShow=this.show})},beforeUnmount(){this.popperInstance&&this.popperInstance.destroy()},methods:{open(){this.currentShow=!0},close(){this.currentShow=!1}}}),y=o.defineComponent({mixins:[w]}),M="",x=(p,m)=>{const a=p.__vccOpts||p;for(const[d,i]of m)a[d]=i;return a},A={ref:"arrow",class:"tooltip-arrow"},S={ref:"inner",class:"tooltip-inner"};function j(p,m,a,d,i,g){return o.openBlock(),o.createElementBlock("div",{class:o.normalizeClass(["tooltip",p.tooltipClasses]),role:"tooltip"},[o.createElementVNode("div",A,null,512),o.createElementVNode("div",S,[o.renderSlot(p.$slots,"default",{},()=>[o.createTextVNode(o.toDisplayString(p.title),1)])],512)],2)}const T=x(y,[["render",j]]);function N(p,m={}){const a=new Map,d=Object.assign({delay:void 0,prefix:"data-tooltip",progressiveEnhancement:!0,triggers:{open:["mouseover:350"],close:["mouseout:100"]}},m),i=d.prefix.replace(/[-]+$/,""),g=new RegExp(`^${i}-`);function O(e){return Array.from(e.attributes).map(t=>[t.name,t.value]).filter(([t])=>t==="title"||t.match(g)).map(([t,n])=>[t.replace(new RegExp(g),""),n]).reduce((t,n)=>Object.assign(t,{[n[0]]:n[1]}),{})}function P(e,t={},n){const s=document.createElement("template"),r=o.h(T,Object.assign({target:e,show:!0},t));o.render(r,s);const[l]=[...s.children];return document.body.append(l),()=>{var f;a.delete(n),(f=r.component)==null||f.ctx.close(),setTimeout(()=>l.remove(),150)}}function b(e,t={}){var v,E;const n=Object.assign({title:e.getAttribute(i)||e.getAttribute("title")},t,O(e));if(!n.title||e.hasAttribute(`${i}-id`))return;const s=Math.random().toString(36).slice(2,7);let r,l;e.setAttribute(`${i}-id`,s),e.removeAttribute("title");function f(u=0){clearTimeout(l),r||(l=setTimeout(()=>{document.contains(e)&&(r=P(e,n,s),a.set(s,r))},u))}function h(u=0){clearTimeout(l),r&&(l=setTimeout(()=>{r&&r(),r=null},u))}function _(u,C){const[L,B]=u.split(":");e.addEventListener(L,()=>C(Number(B||0)))}(((v=e.getAttribute(`${i}-trigger-open`))==null?void 0:v.split(","))||d.triggers.open).map(u=>_(u,f)),(((E=e.getAttribute(`${i}-trigger-close`))==null?void 0:E.split(","))||d.triggers.close).map(u=>_(u,h))}p.mixin({mounted(){if(!d.progressiveEnhancement)return;let e=this.$el;this.$el instanceof Text&&(e=this.$el.parentNode),e instanceof HTMLElement&&b(e);const t=document.createTreeWalker(e,NodeFilter.SHOW_ALL,s=>s instanceof Element?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT);for(;t.nextNode();)t.currentNode instanceof Element&&b(t.currentNode);new MutationObserver(s=>{for(const{removedNodes:r}of s)for(const l of r)if(l instanceof Element)for(const f of l.querySelectorAll(`[${i}-id]`)){const h=a.get(f.getAttribute(`${i}-id`));h&&h()}}).observe(e,{childList:!0})}}),p.directive("tooltip",{beforeMount(e,t){b(e,Object.assign({},t.modifiers,t.value))},beforeUnmount(e){const t=e.getAttribute(`${i}-id`),n=a.get(t);n&&n()}})}c.Tooltip=T,c.TooltipPlugin=N,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ (function(p,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("vue"),require("@popperjs/core")):typeof define=="function"&&define.amd?define(["exports","vue","@popperjs/core"],o):(p=typeof globalThis<"u"?globalThis:p||self,o(p.Tooltip={},p.Vue,p.PopperjsCore))})(this,function(p,o,A){"use strict";const $={ref:"inner",class:"tooltip-inner"},_=o.defineComponent({__name:"Tooltip",props:{offset:{},popper:{},placement:{},target:{},title:{},show:{type:Boolean},top:{type:Boolean},bottom:{type:Boolean},left:{type:Boolean},right:{type:Boolean}},setup(b,{expose:y}){const i=b,u=o.ref(),r=o.ref(),a=o.ref(!1),d=o.ref(),h=o.computed(()=>i.placement?i.placement:i.bottom?"bottom":i.left?"left":i.right?"right":"top"),v=o.computed(()=>({show:a,[`bs-tooltip-${h.value}`]:!0}));function m(){a.value=!0}function e(){a.value=!1}return y({open:m,close:e}),o.onMounted(()=>{var t,n;u.value&&(d.value=A.createPopper(i.target,u.value,Object.assign({placement:h.value,modifiers:[{name:"offset",options:{offset:[((t=i.offset)==null?void 0:t.x)??0,((n=i.offset)==null?void 0:n.y)??6]}},{name:"arrow",options:{element:r.value}}]},i.popper)),o.nextTick(()=>{a.value=i.show}))}),o.onBeforeUnmount(()=>{d.value&&d.value.destroy()}),(t,n)=>(o.openBlock(),o.createElementBlock("div",{ref_key:"el",ref:u,class:o.normalizeClass(["tooltip",v.value]),role:"tooltip"},[o.createElementVNode("div",{ref_key:"arrow",ref:r,class:"tooltip-arrow"},null,512),o.createElementVNode("div",$,[o.renderSlot(t.$slots,"default",{},()=>[o.createTextVNode(o.toDisplayString(t.title),1)])],512)],2))}}),B="";function N(b,y={}){const i=new Map,u=Object.assign({delay:void 0,prefix:"data-tooltip",progressiveEnhancement:!0,triggers:{open:["mouseover:350"],close:["mouseout:100"]}},y),r=u.prefix.replace(/[-]+$/,""),a=new RegExp(`^${r}-`);function d(e){return Array.from(e.attributes).map(t=>[t.name,t.value]).filter(([t])=>t==="title"||t.match(a)).map(([t,n])=>[t.replace(new RegExp(a),""),n]).reduce((t,n)=>Object.assign(t,{[n[0]]:n[1]}),{})}function h(e,t={},n){const c=document.createElement("template"),s=o.h(_,Object.assign({target:e,show:!0},t));o.render(s,c);const[l]=[...c.children];return document.body.append(l),()=>{i.delete(n),setTimeout(()=>l.remove(),150)}}function v(e){const t=e.getAttribute(`${r}-id`);if(t){const n=i.get(t);n==null||n()}}function m(e,t={}){var w,x;const n=Object.assign({title:e.getAttribute(r)||e.getAttribute("title")},t,d(e));if(!n.title||e.hasAttribute(`${r}-id`))return;const c=Math.random().toString(36).slice(2,7);let s,l;e.setAttribute(`${r}-id`,c),e.removeAttribute("title");function T(f=0){clearTimeout(l),s||(l=setTimeout(()=>{document.contains(e)&&(s=h(e,n,c),i.set(c,s))},f))}function E(f=0){clearTimeout(l),s&&(l=setTimeout(()=>{s&&s(),s=null},f))}function g(f,j){const[O,S]=f.split(":");e.addEventListener(O,()=>j(Number(S||0)))}(((w=e.getAttribute(`${r}-trigger-open`))==null?void 0:w.split(","))||u.triggers.open).map(f=>g(f,T)),(((x=e.getAttribute(`${r}-trigger-close`))==null?void 0:x.split(","))||u.triggers.close).map(f=>g(f,E))}b.mixin({mounted(){if(!u.progressiveEnhancement)return;let e=this.$el;this.$el instanceof Text&&(e=this.$el.parentNode),e instanceof HTMLElement&&m(e);const t=document.createTreeWalker(e,NodeFilter.SHOW_ALL,c=>c instanceof Element?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT);for(;t.nextNode();)t.currentNode instanceof Element&&m(t.currentNode);new MutationObserver(c=>{let s=!1;for(const{removedNodes:l}of c)for(const T of l)if(T instanceof Element)for(const E of T.querySelectorAll(`[${r}-id]`)){const g=i.get(E.getAttribute(`${r}-id`));g&&(s=!0,g())}if(!s)for(const l of i.values())l()}).observe(e,{childList:!0})}}),b.directive("tooltip",{beforeMount(e,t){m(e,Object.assign({},t.modifiers,t.value))},beforeUnmount(e){v(e)}})}p.Tooltip=_,p.TooltipPlugin=N,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=tooltip.umd.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.umd.cjs","sources":["../src/Popper.ts","../src/Tooltip.vue","../src/TooltipPlugin.ts"],"sourcesContent":["import { createPopper } from '@popperjs/core';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n\n props: {\n offset: {\n type: Array,\n default: undefined\n },\n\n popper: {\n type: Object,\n default: undefined\n },\n\n placement: {\n type: String,\n default: undefined\n },\n\n target: {\n type: Element,\n required: true\n },\n\n title: {\n type: String,\n default: undefined\n },\n \n show: Boolean,\n \n top: Boolean,\n\n bottom: Boolean,\n\n left: Boolean,\n\n right: Boolean,\n },\n\n data() {\n return {\n currentShow: false,\n popperInstance: null\n };\n },\n\n computed: {\n computedPlacement() {\n if(this.placement) {\n return this.placement;\n }\n\n if(this.bottom) {\n return 'bottom';\n }\n\n if(this.left) {\n return 'left';\n }\n\n if(this.right) {\n return 'right';\n }\n\n return 'top';\n },\n tooltipClasses() {\n return {\n show: this.currentShow,\n [`bs-tooltip-${this.computedPlacement}`]: true\n };\n }\n },\n\n mounted() {\n this.popperInstance = createPopper(this.target, this.$el, Object.assign({\n placement: this.computedPlacement,\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [0, 6]\n },\n },\n {\n name: 'arrow',\n options: {\n element: this.$refs.arrow,\n },\n },\n ],\n }, this.popper));\n\n this.$nextTick(() => {\n this.currentShow = this.show;\n });\n },\n\n beforeUnmount() {\n this.popperInstance && this.popperInstance.destroy();\n },\n\n methods: {\n\n open() {\n this.currentShow = true;\n },\n\n close() {\n this.currentShow = false;\n }\n\n }\n\n});","<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport Popper from './Popper';\n\nexport default defineComponent({\n mixins: [\n Popper\n ]\n});\n</script>\n\n<template>\n <div\n class=\"tooltip\"\n :class=\"tooltipClasses\"\n role=\"tooltip\">\n <div\n ref=\"arrow\"\n class=\"tooltip-arrow\" />\n <div\n ref=\"inner\"\n class=\"tooltip-inner\">\n <slot>{{ title }}</slot>\n </div>\n </div>\n</template>\n\n<style>\n.tooltip:not(.show) {\n z-index: -1;\n}\n</style>","import type { App } from 'vue';\nimport { h, render } from 'vue';\nimport Tooltip from './Tooltip.vue';\n\ntype TooltipPluginOptions = {\n delay?: number,\n prefix: string,\n progressiveEnhancement: boolean,\n triggers: {\n open: string[],\n close: string[],\n }\n}\n\nexport default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {\n const tooltips: Map<string,Function> = new Map;\n\n const options: TooltipPluginOptions = Object.assign({\n delay: undefined,\n prefix: 'data-tooltip',\n progressiveEnhancement: true,\n triggers: {\n open: ['mouseover:350'],\n close: ['mouseout:100'],\n }\n }, opts);\n \n const prefix = options.prefix.replace(/[-]+$/, '');\n const prefixRegExp = new RegExp(`^${prefix}\\-`);\n\n function getAttributes(el: Element): Record<string,any> {\n return Array.from(el.attributes)\n .map(a => [a.name, a.value])\n .filter(([key]) => key === 'title' || key.match(prefixRegExp))\n .map(([key, value]) => [key.replace(new RegExp(prefixRegExp), ''), value])\n .reduce((carry, attr) => Object.assign(carry, { [attr[0]]: attr[1] }), {});\n }\n\n function createTooltip(target: Element, props: Record<string,any> = {}, hash: string): Function {\n const container = document.createElement('template');\n \n const vnode = h(Tooltip, Object.assign({\n target,\n show: true\n }, props));\n \n render(vnode, container);\n \n const [el] = [...container.children];\n \n document.body.append(el);\n \n return () => {\n tooltips.delete(hash);\n\n // @ts-ignore\n vnode.component?.ctx.close();\n \n // @todo: Make the animation rate (150) dynamic. Should get value \n // from the CSS transition duration.\n setTimeout(() => el.remove(), 150);\n };\n }\n\n function init(target: Element, props = {}) {\n const properties: Record<string,any> = Object.assign({\n title: target.getAttribute(prefix) || target.getAttribute('title')\n }, props, getAttributes(target));\n\n // If the properties don't have a title, ignore this target.\n if(!properties.title || target.hasAttribute(`${prefix}-id`)) {\n return;\n }\n\n // Create a unique \"hash\" to show the node has been initialized.\n // This prevents double initializing on the same element.\n const hash = Math.random().toString(36).slice(2, 7);\n \n // Create the instance vars.\n let tooltip: Function|null, timer: number;\n\n //target.setAttribute(prefix, properties.title);\n target.setAttribute(`${prefix}-id`, hash);\n target.removeAttribute('title');\n\n function open(delay = 0) {\n clearTimeout(timer);\n\n if(!tooltip) {\n timer = setTimeout(() => {\n // Do a check before creating the tooltip to ensure the dom\n // element still exists. Its possible for the element to\n // be removed after the timeout delay runs.\n if(document.contains(target)) {\n tooltip = createTooltip(target, properties, hash);\n tooltips.set(hash, tooltip);\n }\n }, delay);\n }\n }\n\n function close(delay = 0) {\n clearTimeout(timer);\n\n if(tooltip) {\n timer = setTimeout(() => {\n tooltip && tooltip();\n tooltip = null;\n }, delay);\n } \n }\n\n function addEventListener(trigger: string, fn: Function) {\n const [ event, delayString ] = trigger.split(':');\n\n target.addEventListener(event, () => fn(Number(delayString || 0)));\n }\n\n (target.getAttribute(`${prefix}-trigger-open`)?.split(',') || options.triggers.open)\n .map(trigger => addEventListener(trigger, open));\n \n (target.getAttribute(`${prefix}-trigger-close`)?.split(',') || options.triggers.close)\n .map(trigger => addEventListener(trigger, close));\n }\n \n app.mixin({\n mounted() {\n if(!options.progressiveEnhancement) {\n return;\n }\n \n let el = this.$el;\n\n if(this.$el instanceof Text) {\n el = this.$el.parentNode;\n }\n\n if(el instanceof HTMLElement) {\n init(el);\n }\n\n // Create the tree walker.\n const walker = document.createTreeWalker(\n el,\n NodeFilter.SHOW_ALL,\n (node: Node) => {\n if(!(node instanceof Element)) {\n return NodeFilter.FILTER_REJECT;\n }\n \n return NodeFilter.FILTER_ACCEPT;\n }\n );\n\n // Step through and alert all child nodes\n while(walker.nextNode()) {\n if(walker.currentNode instanceof Element) {\n init(<Element> walker.currentNode);\n }\n }\n\n const observer = new MutationObserver((changes) => {\n for(const { removedNodes } of changes) {\n for(const node of removedNodes) {\n if(!(node instanceof Element)) {\n continue;\n }\n \n for(const el of node.querySelectorAll(`[${prefix}-id]`)) {\n const tooltip = tooltips.get(\n el.getAttribute(`${prefix}-id`) as string\n );\n\n tooltip && tooltip();\n }\n } \n }\n });\n\n observer.observe(el, { childList: true });\n }\n });\n\n app.directive('tooltip', {\n beforeMount(target, binding) {\n init(target, Object.assign({}, binding.modifiers, binding.value));\n },\n beforeUnmount(target) {\n const id = target.getAttribute(`${prefix}-id`);\n const tooltip = tooltips.get(id);\n\n tooltip && tooltip();\n }\n });\n}"],"names":["Popper","defineComponent","createPopper","_sfc_main","_hoisted_1","_hoisted_2","_sfc_render","_ctx","_cache","$props","$setup","$data","$options","_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_renderSlot","TooltipPlugin","app","opts","tooltips","options","prefix","prefixRegExp","getAttributes","el","a","key","value","carry","attr","createTooltip","target","props","hash","container","vnode","h","Tooltip","render","_a","init","properties","tooltip","timer","open","delay","close","addEventListener","trigger","fn","event","delayString","_b","walker","node","changes","removedNodes","binding","id"],"mappings":"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"}
1
+ {"version":3,"file":"tooltip.umd.cjs","sources":["../src/Tooltip.vue","../src/TooltipPlugin.ts"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { Instance, Offsets, OptionsGeneric, createPopper } from '@popperjs/core';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';\n\nconst props = defineProps<{\n offset?: Offsets,\n popper?: OptionsGeneric<unknown>,\n placement?: string,\n target: Element,\n title?: string,\n show?: boolean,\n top?: boolean,\n bottom?: boolean,\n left?: boolean,\n right?: boolean\n}>();\n\nconst el = ref<HTMLElement>();\nconst arrow = ref<HTMLElement>();\nconst currentShow = ref(false);\nconst popperInstance = ref<Instance>();\n\nconst placement = computed(() => {\n if(props.placement) {\n return props.placement;\n }\n\n if(props.bottom) {\n return 'bottom';\n }\n\n if(props.left) {\n return 'left';\n }\n\n if(props.right) {\n return 'right';\n }\n\n return 'top';\n});\n\nconst tooltipClasses = computed(() => {\n return {\n show: currentShow,\n [`bs-tooltip-${placement.value}`]: true\n };\n});\n\nfunction open() {\n currentShow.value = true;\n}\n\nfunction close() {\n currentShow.value = false;\n}\n\ndefineExpose({\n open, close\n});\n\nonMounted(() => {\n if(!el.value) {\n return;\n }\n\n popperInstance.value = createPopper(props.target, el.value, Object.assign({\n placement: placement.value,\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [props.offset?.x ?? 0, props.offset?.y ?? 6]\n },\n },\n {\n name: 'arrow',\n options: {\n element: arrow.value,\n },\n },\n ],\n }, props.popper));\n\n nextTick(() => {\n currentShow.value = props.show;\n });\n});\n\nonBeforeUnmount(()=> {\n popperInstance.value && popperInstance.value.destroy();\n});\n</script>\n\n<template>\n <div\n ref=\"el\"\n class=\"tooltip\"\n :class=\"tooltipClasses\"\n role=\"tooltip\">\n <div\n ref=\"arrow\"\n class=\"tooltip-arrow\" />\n <div\n ref=\"inner\"\n class=\"tooltip-inner\">\n <slot>{{ title }}</slot>\n </div>\n </div>\n</template>\n\n<style>\n.tooltip:not(.show) {\n z-index: -1;\n}\n</style>","import type { App } from 'vue';\nimport { h, render } from 'vue';\nimport Tooltip from './Tooltip.vue';\n\ntype TooltipPluginOptions = {\n delay?: number,\n prefix: string,\n progressiveEnhancement: boolean,\n triggers: {\n open: string[],\n close: string[],\n }\n}\n\nexport default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {\n const tooltips: Map<string,Function> = new Map;\n\n const options: TooltipPluginOptions = Object.assign({\n delay: undefined,\n prefix: 'data-tooltip',\n progressiveEnhancement: true,\n triggers: {\n open: ['mouseover:350'],\n close: ['mouseout:100'],\n }\n }, opts);\n \n const prefix = options.prefix.replace(/[-]+$/, '');\n const prefixRegExp = new RegExp(`^${prefix}\\-`);\n\n function getAttributes(el: Element): Record<string,string> {\n return Array.from(el.attributes)\n .map(a => [a.name, a.value])\n .filter(([key]) => key === 'title' || key.match(prefixRegExp))\n .map(([key, value]) => [key.replace(new RegExp(prefixRegExp), ''), value])\n .reduce((carry, attr) => Object.assign(carry, { [attr[0]]: attr[1] }), {});\n }\n\n function createTooltip(target: Element, props: Record<string,string> = {}, hash: string): Function {\n const container = document.createElement('template');\n \n const vnode = h(Tooltip, Object.assign({\n target,\n show: true\n }, props));\n \n render(vnode, container);\n \n const [el] = [...container.children];\n \n document.body.append(el);\n \n return () => {\n tooltips.delete(hash);\n\n // vnode.component?.close();\n \n // @todo: Make the animation rate (150) dynamic. Should get value \n // from the CSS transition duration.\n setTimeout(() => el.remove(), 150);\n };\n }\n\n function destroyTooltip(target: Element) {\n const id = target.getAttribute(`${prefix}-id`);\n if(id) {\n const tooltip = tooltips.get(id);\n tooltip?.();\n }\n }\n\n function init(target: Element, props = {}) {\n const properties: Record<string,string> = Object.assign({\n title: target.getAttribute(prefix) || target.getAttribute('title')\n }, props, getAttributes(target));\n\n // If the properties don't have a title, ignore this target.\n if(!properties.title || target.hasAttribute(`${prefix}-id`)) {\n return;\n }\n\n // Create a unique \"hash\" to show the node has been initialized.\n // This prevents double initializing on the same element.\n const hash = Math.random().toString(36).slice(2, 7);\n \n // Create the instance vars.\n let tooltip: Function|null, timer: number;\n\n //target.setAttribute(prefix, properties.title);\n target.setAttribute(`${prefix}-id`, hash);\n target.removeAttribute('title');\n\n function open(delay = 0) {\n clearTimeout(timer);\n\n if(!tooltip) {\n timer = setTimeout(() => {\n // Do a check before creating the tooltip to ensure the dom\n // element still exists. Its possible for the element to\n // be removed after the timeout delay runs.\n if(document.contains(target)) {\n tooltip = createTooltip(target, properties, hash);\n tooltips.set(hash, tooltip);\n }\n }, delay);\n }\n }\n\n function close(delay = 0) {\n clearTimeout(timer);\n\n if(tooltip) {\n timer = setTimeout(() => {\n tooltip && tooltip();\n tooltip = null;\n }, delay);\n }\n }\n\n function addEventListener(trigger: string, fn: Function) {\n const [ event, delayString ] = trigger.split(':');\n\n target.addEventListener(event, () => fn(Number(delayString || 0)));\n }\n\n (target.getAttribute(`${prefix}-trigger-open`)?.split(',') || options.triggers.open)\n .map(trigger => addEventListener(trigger, open));\n \n (target.getAttribute(`${prefix}-trigger-close`)?.split(',') || options.triggers.close)\n .map(trigger => addEventListener(trigger, close));\n }\n \n app.mixin({\n mounted() {\n if(!options.progressiveEnhancement) {\n return;\n }\n \n let el = this.$el;\n\n if(this.$el instanceof Text) {\n el = this.$el.parentNode;\n }\n\n if(el instanceof HTMLElement) {\n init(el);\n }\n\n // Create the tree walker.\n const walker = document.createTreeWalker(\n el,\n NodeFilter.SHOW_ALL,\n (node: Node) => {\n if(!(node instanceof Element)) {\n return NodeFilter.FILTER_REJECT;\n }\n \n return NodeFilter.FILTER_ACCEPT;\n }\n );\n\n // Step through and alert all child nodes\n while(walker.nextNode()) {\n if(walker.currentNode instanceof Element) {\n init(<Element> walker.currentNode);\n }\n }\n\n const observer = new MutationObserver((changes) => {\n\n let tooltipFound = false;\n for(const { removedNodes } of changes) {\n for(const node of removedNodes) {\n if(!(node instanceof Element)) {\n continue;\n }\n for(const el of node.querySelectorAll(`[${prefix}-id]`)) {\n const tooltip = tooltips.get(\n el.getAttribute(`${prefix}-id`) as string\n );\n if(tooltip) {\n tooltipFound = true;\n tooltip();\n }\n }\n } \n }\n\n // @experimental\n // In some cases in Inertia.js, not all tooltips are removed on certain actions.\n // remove all tooltips if no tooltip was found.\n if(!tooltipFound) {\n for(const tooltip of tooltips.values()) {\n tooltip();\n }\n }\n });\n\n observer.observe(el, { childList: true });\n },\n });\n\n app.directive('tooltip', {\n beforeMount(target, binding) {\n init(target, Object.assign({}, binding.modifiers, binding.value));\n },\n beforeUnmount(target) {\n destroyTooltip(target);\n }\n });\n}"],"names":["el","ref","arrow","currentShow","popperInstance","placement","computed","props","tooltipClasses","open","close","__expose","onMounted","createPopper","_a","_b","nextTick","onBeforeUnmount","TooltipPlugin","app","opts","tooltips","options","prefix","prefixRegExp","getAttributes","a","key","value","carry","attr","createTooltip","target","hash","container","vnode","h","Tooltip","render","destroyTooltip","id","tooltip","init","properties","timer","delay","addEventListener","trigger","fn","event","delayString","walker","node","changes","tooltipFound","removedNodes","binding"],"mappings":"0kBAiBMA,EAAKC,EAAAA,MACLC,EAAQD,EAAAA,MACRE,EAAcF,MAAI,EAAK,EACvBG,EAAiBH,EAAAA,MAEjBI,EAAYC,EAAAA,SAAS,IACpBC,EAAM,UACEA,EAAM,UAGdA,EAAM,OACE,SAGRA,EAAM,KACE,OAGRA,EAAM,MACE,QAGJ,KACV,EAEKC,EAAiBF,EAAAA,SAAS,KACrB,CACH,KAAMH,EACN,CAAC,cAAcE,EAAU,KAAK,EAAE,EAAG,EAAA,EAE1C,EAED,SAASI,GAAO,CACZN,EAAY,MAAQ,EACxB,CAEA,SAASO,GAAQ,CACbP,EAAY,MAAQ,EACxB,CAEa,OAAAQ,EAAA,CACT,KAAAF,EAAM,MAAAC,CAAA,CACT,EAEDE,EAAAA,UAAU,IAAM,SACRZ,EAAG,QAIPI,EAAe,MAAQS,EAAAA,aAAaN,EAAM,OAAQP,EAAG,MAAO,OAAO,OAAO,CACtE,UAAWK,EAAU,MACrB,UAAW,CACP,CACI,KAAM,SACN,QAAS,CACL,OAAQ,GAACS,EAAAP,EAAM,SAAN,YAAAO,EAAc,IAAK,IAAGC,EAAAR,EAAM,SAAN,YAAAQ,EAAc,IAAK,CAAC,CACvD,CACJ,EACA,CACI,KAAM,QACN,QAAS,CACL,QAASb,EAAM,KACnB,CACJ,CACJ,CAAA,EACDK,EAAM,MAAM,CAAC,EAEhBS,EAAAA,SAAS,IAAM,CACXb,EAAY,MAAQI,EAAM,IAAA,CAC7B,EAAA,CACJ,EAEDU,EAAAA,gBAAgB,IAAK,CACFb,EAAA,OAASA,EAAe,MAAM,QAAQ,CAAA,CACxD,kWC7EwB,SAAAc,EAAAC,EAAUC,EAAsC,GAAI,CACzE,MAAMC,EAAqC,IAAA,IAErCC,EAAgC,OAAO,OAAO,CAChD,MAAO,OACP,OAAQ,eACR,uBAAwB,GACxB,SAAU,CACN,KAAM,CAAC,eAAe,EACtB,MAAO,CAAC,cAAc,CAC1B,GACDF,CAAI,EAEDG,EAASD,EAAQ,OAAO,QAAQ,QAAS,EAAE,EAC3CE,EAAe,IAAI,OAAO,IAAID,CAAM,GAAI,EAE9C,SAASE,EAAczB,EAAoC,CACvD,OAAO,MAAM,KAAKA,EAAG,UAAU,EAC1B,IAAS0B,GAAA,CAACA,EAAE,KAAMA,EAAE,KAAK,CAAC,EAC1B,OAAO,CAAC,CAACC,CAAG,IAAMA,IAAQ,SAAWA,EAAI,MAAMH,CAAY,CAAC,EAC5D,IAAI,CAAC,CAACG,EAAKC,CAAK,IAAM,CAACD,EAAI,QAAQ,IAAI,OAAOH,CAAY,EAAG,EAAE,EAAGI,CAAK,CAAC,EACxE,OAAO,CAACC,EAAOC,IAAS,OAAO,OAAOD,EAAO,CAAE,CAACC,EAAK,CAAC,CAAC,EAAGA,EAAK,CAAC,EAAG,EAAG,CAAE,CAAA,CACjF,CAEA,SAASC,EAAcC,EAAiBzB,EAA+B,CAAA,EAAI0B,EAAwB,CACzF,MAAAC,EAAY,SAAS,cAAc,UAAU,EAE7CC,EAAQC,EAAA,EAAEC,EAAS,OAAO,OAAO,CACnC,OAAAL,EACA,KAAM,EAAA,EACPzB,CAAK,CAAC,EAET+B,SAAOH,EAAOD,CAAS,EAEvB,KAAM,CAAClC,CAAE,EAAI,CAAC,GAAGkC,EAAU,QAAQ,EAE1B,gBAAA,KAAK,OAAOlC,CAAE,EAEhB,IAAM,CACTqB,EAAS,OAAOY,CAAI,EAMpB,WAAW,IAAMjC,EAAG,OAAO,EAAG,GAAG,CAAA,CAEzC,CAEA,SAASuC,EAAeP,EAAiB,CACrC,MAAMQ,EAAKR,EAAO,aAAa,GAAGT,CAAM,KAAK,EAC7C,GAAGiB,EAAI,CACG,MAAAC,EAAUpB,EAAS,IAAImB,CAAE,EACrBC,GAAA,MAAAA,GACd,CACJ,CAEA,SAASC,EAAKV,EAAiBzB,EAAQ,GAAI,SACjC,MAAAoC,EAAoC,OAAO,OAAO,CACpD,MAAOX,EAAO,aAAaT,CAAM,GAAKS,EAAO,aAAa,OAAO,CAClE,EAAAzB,EAAOkB,EAAcO,CAAM,CAAC,EAG5B,GAAA,CAACW,EAAW,OAASX,EAAO,aAAa,GAAGT,CAAM,KAAK,EACtD,OAKE,MAAAU,EAAO,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,EAGlD,IAAIQ,EAAwBG,EAG5BZ,EAAO,aAAa,GAAGT,CAAM,MAAOU,CAAI,EACxCD,EAAO,gBAAgB,OAAO,EAErB,SAAAvB,EAAKoC,EAAQ,EAAG,CACrB,aAAaD,CAAK,EAEdH,IACAG,EAAQ,WAAW,IAAM,CAIlB,SAAS,SAASZ,CAAM,IACbS,EAAAV,EAAcC,EAAQW,EAAYV,CAAI,EACvCZ,EAAA,IAAIY,EAAMQ,CAAO,IAE/BI,CAAK,EAEhB,CAES,SAAAnC,EAAMmC,EAAQ,EAAG,CACtB,aAAaD,CAAK,EAEfH,IACCG,EAAQ,WAAW,IAAM,CACrBH,GAAWA,EAAQ,EACTA,EAAA,MACXI,CAAK,EAEhB,CAES,SAAAC,EAAiBC,EAAiBC,EAAc,CACrD,KAAM,CAAEC,EAAOC,CAAY,EAAIH,EAAQ,MAAM,GAAG,EAEzCf,EAAA,iBAAiBiB,EAAO,IAAMD,EAAG,OAAOE,GAAe,CAAC,CAAC,CAAC,CACrE,IAECpC,EAAAkB,EAAO,aAAa,GAAGT,CAAM,eAAe,IAA5C,YAAAT,EAA+C,MAAM,OAAQQ,EAAQ,SAAS,MAC1E,OAAewB,EAAiBC,EAAStC,CAAI,CAAC,KAElDM,EAAAiB,EAAO,aAAa,GAAGT,CAAM,gBAAgB,IAA7C,YAAAR,EAAgD,MAAM,OAAQO,EAAQ,SAAS,OAC3E,OAAewB,EAAiBC,EAASrC,CAAK,CAAC,CACxD,CAEAS,EAAI,MAAM,CACN,SAAU,CACH,GAAA,CAACG,EAAQ,uBACR,OAGJ,IAAItB,EAAK,KAAK,IAEX,KAAK,eAAe,OACnBA,EAAK,KAAK,IAAI,YAGfA,aAAc,aACb0C,EAAK1C,CAAE,EAIX,MAAMmD,EAAS,SAAS,iBACpBnD,EACA,WAAW,SACVoD,GACQA,aAAgB,QAId,WAAW,cAHP,WAAW,aAI1B,EAIE,KAAAD,EAAO,YACNA,EAAO,uBAAuB,SAC7BT,EAAeS,EAAO,WAAW,EAIxB,IAAI,iBAAkBE,GAAY,CAE/C,IAAIC,EAAe,GACT,SAAA,CAAE,aAAAC,CAAa,IAAKF,EAC1B,UAAUD,KAAQG,EACX,GAAEH,aAAgB,QAGrB,UAAUpD,KAAMoD,EAAK,iBAAiB,IAAI7B,CAAM,MAAM,EAAG,CACrD,MAAMkB,EAAUpB,EAAS,IACrBrB,EAAG,aAAa,GAAGuB,CAAM,KAAK,CAAA,EAE/BkB,IACgBa,EAAA,GACPb,IAEhB,CAOR,GAAG,CAACa,EACU,UAAAb,KAAWpB,EAAS,SAClBoB,GAEhB,CACH,EAEQ,QAAQzC,EAAI,CAAE,UAAW,EAAM,CAAA,CAC5C,CAAA,CACH,EAEDmB,EAAI,UAAU,UAAW,CACrB,YAAYa,EAAQwB,EAAS,CACpBd,EAAAV,EAAQ,OAAO,OAAO,CAAA,EAAIwB,EAAQ,UAAWA,EAAQ,KAAK,CAAC,CACpE,EACA,cAAcxB,EAAQ,CAClBO,EAAeP,CAAM,CACzB,CAAA,CACH,CACL"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-interface/tooltip",
3
- "version": "1.0.0-beta.12",
3
+ "version": "1.0.0-beta.14",
4
4
  "description": "A Vue tooltip component.",
5
5
  "files": [
6
6
  "index.ts",
@@ -50,17 +50,26 @@
50
50
  "vue": "^3.0.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@vitejs/plugin-vue": "^3.0.1",
54
- "@vue-interface/eslint-config": "^1.0.0-beta.0",
55
- "autoprefixer": "^10.4.2",
53
+ "@commitlint/config-conventional": "^17.7.0",
54
+ "@semantic-release/changelog": "^6.0.3",
55
+ "@semantic-release/git": "^10.0.1",
56
+ "@semantic-release/npm": "^10.0.4",
57
+ "@vitejs/plugin-vue": "^4.2.3",
58
+ "@vue-interface/eslint-config": "1.0.0-beta.4",
59
+ "autoprefixer": "^10.4.15",
56
60
  "change-case": "^4.1.2",
57
- "eslint": "^8.27.0",
61
+ "commitlint": "^17.7.1",
62
+ "dotenv": "^16.3.1",
63
+ "eslint": "^8.47.0",
64
+ "husky": "^8.0.3",
58
65
  "pascalcase": "^2.0.0",
59
- "postcss": "^8.4.6",
60
- "tailwindcss": "^3.0.18",
61
- "typescript": "^5.0.2",
62
- "vite": "^3.0.0",
63
- "vite-plugin-dts": "^1.7.1",
64
- "vue": "^3.2.37"
66
+ "postcss": "^8.4.28",
67
+ "semantic-release": "^21.0.7",
68
+ "tailwindcss": "^3.3.3",
69
+ "typescript": "^4.9.5",
70
+ "vite": "^4.4.9",
71
+ "vite-plugin-dts": "^1.7.3",
72
+ "vue": "^3.3.4",
73
+ "vue-router": "^4.2"
65
74
  }
66
75
  }
package/src/Tooltip.vue CHANGED
@@ -1,16 +1,100 @@
1
- <script lang="ts">
2
- import { defineComponent } from 'vue';
3
- import Popper from './Popper';
4
-
5
- export default defineComponent({
6
- mixins: [
7
- Popper
8
- ]
1
+ <script lang="ts" setup>
2
+ import { Instance, Offsets, OptionsGeneric, createPopper } from '@popperjs/core';
3
+ import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
4
+
5
+ const props = defineProps<{
6
+ offset?: Offsets,
7
+ popper?: OptionsGeneric<unknown>,
8
+ placement?: string,
9
+ target: Element,
10
+ title?: string,
11
+ show?: boolean,
12
+ top?: boolean,
13
+ bottom?: boolean,
14
+ left?: boolean,
15
+ right?: boolean
16
+ }>();
17
+
18
+ const el = ref<HTMLElement>();
19
+ const arrow = ref<HTMLElement>();
20
+ const currentShow = ref(false);
21
+ const popperInstance = ref<Instance>();
22
+
23
+ const placement = computed(() => {
24
+ if(props.placement) {
25
+ return props.placement;
26
+ }
27
+
28
+ if(props.bottom) {
29
+ return 'bottom';
30
+ }
31
+
32
+ if(props.left) {
33
+ return 'left';
34
+ }
35
+
36
+ if(props.right) {
37
+ return 'right';
38
+ }
39
+
40
+ return 'top';
41
+ });
42
+
43
+ const tooltipClasses = computed(() => {
44
+ return {
45
+ show: currentShow,
46
+ [`bs-tooltip-${placement.value}`]: true
47
+ };
48
+ });
49
+
50
+ function open() {
51
+ currentShow.value = true;
52
+ }
53
+
54
+ function close() {
55
+ currentShow.value = false;
56
+ }
57
+
58
+ defineExpose({
59
+ open, close
60
+ });
61
+
62
+ onMounted(() => {
63
+ if(!el.value) {
64
+ return;
65
+ }
66
+
67
+ popperInstance.value = createPopper(props.target, el.value, Object.assign({
68
+ placement: placement.value,
69
+ modifiers: [
70
+ {
71
+ name: 'offset',
72
+ options: {
73
+ offset: [props.offset?.x ?? 0, props.offset?.y ?? 6]
74
+ },
75
+ },
76
+ {
77
+ name: 'arrow',
78
+ options: {
79
+ element: arrow.value,
80
+ },
81
+ },
82
+ ],
83
+ }, props.popper));
84
+
85
+ nextTick(() => {
86
+ currentShow.value = props.show;
87
+ });
88
+ });
89
+
90
+ onBeforeUnmount(()=> {
91
+ popperInstance.value && popperInstance.value.destroy();
9
92
  });
10
93
  </script>
11
94
 
12
95
  <template>
13
96
  <div
97
+ ref="el"
14
98
  class="tooltip"
15
99
  :class="tooltipClasses"
16
100
  role="tooltip">
@@ -28,7 +28,7 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
28
28
  const prefix = options.prefix.replace(/[-]+$/, '');
29
29
  const prefixRegExp = new RegExp(`^${prefix}\-`);
30
30
 
31
- function getAttributes(el: Element): Record<string,any> {
31
+ function getAttributes(el: Element): Record<string,string> {
32
32
  return Array.from(el.attributes)
33
33
  .map(a => [a.name, a.value])
34
34
  .filter(([key]) => key === 'title' || key.match(prefixRegExp))
@@ -36,7 +36,7 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
36
36
  .reduce((carry, attr) => Object.assign(carry, { [attr[0]]: attr[1] }), {});
37
37
  }
38
38
 
39
- function createTooltip(target: Element, props: Record<string,any> = {}, hash: string): Function {
39
+ function createTooltip(target: Element, props: Record<string,string> = {}, hash: string): Function {
40
40
  const container = document.createElement('template');
41
41
 
42
42
  const vnode = h(Tooltip, Object.assign({
@@ -53,8 +53,7 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
53
53
  return () => {
54
54
  tooltips.delete(hash);
55
55
 
56
- // @ts-ignore
57
- vnode.component?.ctx.close();
56
+ // vnode.component?.close();
58
57
 
59
58
  // @todo: Make the animation rate (150) dynamic. Should get value
60
59
  // from the CSS transition duration.
@@ -62,8 +61,16 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
62
61
  };
63
62
  }
64
63
 
64
+ function destroyTooltip(target: Element) {
65
+ const id = target.getAttribute(`${prefix}-id`);
66
+ if(id) {
67
+ const tooltip = tooltips.get(id);
68
+ tooltip?.();
69
+ }
70
+ }
71
+
65
72
  function init(target: Element, props = {}) {
66
- const properties: Record<string,any> = Object.assign({
73
+ const properties: Record<string,string> = Object.assign({
67
74
  title: target.getAttribute(prefix) || target.getAttribute('title')
68
75
  }, props, getAttributes(target));
69
76
 
@@ -107,7 +114,7 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
107
114
  tooltip && tooltip();
108
115
  tooltip = null;
109
116
  }, delay);
110
- }
117
+ }
111
118
  }
112
119
 
113
120
  function addEventListener(trigger: string, fn: Function) {
@@ -160,25 +167,37 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
160
167
  }
161
168
 
162
169
  const observer = new MutationObserver((changes) => {
170
+
171
+ let tooltipFound = false;
163
172
  for(const { removedNodes } of changes) {
164
173
  for(const node of removedNodes) {
165
174
  if(!(node instanceof Element)) {
166
175
  continue;
167
176
  }
168
-
169
177
  for(const el of node.querySelectorAll(`[${prefix}-id]`)) {
170
178
  const tooltip = tooltips.get(
171
179
  el.getAttribute(`${prefix}-id`) as string
172
180
  );
173
-
174
- tooltip && tooltip();
181
+ if(tooltip) {
182
+ tooltipFound = true;
183
+ tooltip();
184
+ }
175
185
  }
176
186
  }
177
187
  }
188
+
189
+ // @experimental
190
+ // In some cases in Inertia.js, not all tooltips are removed on certain actions.
191
+ // remove all tooltips if no tooltip was found.
192
+ if(!tooltipFound) {
193
+ for(const tooltip of tooltips.values()) {
194
+ tooltip();
195
+ }
196
+ }
178
197
  });
179
198
 
180
199
  observer.observe(el, { childList: true });
181
- }
200
+ },
182
201
  });
183
202
 
184
203
  app.directive('tooltip', {
@@ -186,10 +205,7 @@ export default function (app: App, opts: Partial<TooltipPluginOptions> = {}) {
186
205
  init(target, Object.assign({}, binding.modifiers, binding.value));
187
206
  },
188
207
  beforeUnmount(target) {
189
- const id = target.getAttribute(`${prefix}-id`);
190
- const tooltip = tooltips.get(id);
191
-
192
- tooltip && tooltip();
208
+ destroyTooltip(target);
193
209
  }
194
210
  });
195
211
  }
@@ -1,82 +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
- placement: {
11
- type: StringConstructor;
12
- default: undefined;
13
- };
14
- target: {
15
- type: {
16
- new (): Element;
17
- prototype: Element;
18
- };
19
- required: true;
20
- };
21
- title: {
22
- type: StringConstructor;
23
- default: undefined;
24
- };
25
- show: BooleanConstructor;
26
- top: BooleanConstructor;
27
- bottom: BooleanConstructor;
28
- left: BooleanConstructor;
29
- right: BooleanConstructor;
30
- }, unknown, {
31
- currentShow: boolean;
32
- popperInstance: null;
33
- }, {
34
- computedPlacement(): any;
35
- tooltipClasses(): {
36
- [x: string]: any;
37
- show: any;
38
- };
39
- }, {
40
- open(): void;
41
- close(): void;
42
- }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
43
- offset: {
44
- type: ArrayConstructor;
45
- default: undefined;
46
- };
47
- popper: {
48
- type: ObjectConstructor;
49
- default: undefined;
50
- };
51
- placement: {
52
- type: StringConstructor;
53
- default: undefined;
54
- };
55
- target: {
56
- type: {
57
- new (): Element;
58
- prototype: Element;
59
- };
60
- required: true;
61
- };
62
- title: {
63
- type: StringConstructor;
64
- default: undefined;
65
- };
66
- show: BooleanConstructor;
67
- top: BooleanConstructor;
68
- bottom: BooleanConstructor;
69
- left: BooleanConstructor;
70
- right: BooleanConstructor;
71
- }>>, {
72
- offset: unknown[];
73
- popper: Record<string, any>;
74
- placement: string;
75
- title: string;
76
- show: boolean;
77
- top: boolean;
78
- bottom: boolean;
79
- left: boolean;
80
- right: boolean;
81
- }>;
82
- export default _default;
package/src/Popper.ts DELETED
@@ -1,118 +0,0 @@
1
- import { createPopper } from '@popperjs/core';
2
- import { defineComponent } from 'vue';
3
-
4
- export default defineComponent({
5
-
6
- props: {
7
- offset: {
8
- type: Array,
9
- default: undefined
10
- },
11
-
12
- popper: {
13
- type: Object,
14
- default: undefined
15
- },
16
-
17
- placement: {
18
- type: String,
19
- default: undefined
20
- },
21
-
22
- target: {
23
- type: Element,
24
- required: true
25
- },
26
-
27
- title: {
28
- type: String,
29
- default: undefined
30
- },
31
-
32
- show: Boolean,
33
-
34
- top: Boolean,
35
-
36
- bottom: Boolean,
37
-
38
- left: Boolean,
39
-
40
- right: Boolean,
41
- },
42
-
43
- data() {
44
- return {
45
- currentShow: false,
46
- popperInstance: null
47
- };
48
- },
49
-
50
- computed: {
51
- computedPlacement() {
52
- if(this.placement) {
53
- return this.placement;
54
- }
55
-
56
- if(this.bottom) {
57
- return 'bottom';
58
- }
59
-
60
- if(this.left) {
61
- return 'left';
62
- }
63
-
64
- if(this.right) {
65
- return 'right';
66
- }
67
-
68
- return 'top';
69
- },
70
- tooltipClasses() {
71
- return {
72
- show: this.currentShow,
73
- [`bs-tooltip-${this.computedPlacement}`]: true
74
- };
75
- }
76
- },
77
-
78
- mounted() {
79
- this.popperInstance = createPopper(this.target, this.$el, Object.assign({
80
- placement: this.computedPlacement,
81
- modifiers: [
82
- {
83
- name: 'offset',
84
- options: {
85
- offset: [0, 6]
86
- },
87
- },
88
- {
89
- name: 'arrow',
90
- options: {
91
- element: this.$refs.arrow,
92
- },
93
- },
94
- ],
95
- }, this.popper));
96
-
97
- this.$nextTick(() => {
98
- this.currentShow = this.show;
99
- });
100
- },
101
-
102
- beforeUnmount() {
103
- this.popperInstance && this.popperInstance.destroy();
104
- },
105
-
106
- methods: {
107
-
108
- open() {
109
- this.currentShow = true;
110
- },
111
-
112
- close() {
113
- this.currentShow = false;
114
- }
115
-
116
- }
117
-
118
- });