@ulu/frontend-vue 0.6.34 → 0.6.36
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/dist/mcp-data.json +1003 -929
- package/dist/plugins/tour/UluTourContent.vue.d.ts.map +1 -1
- package/dist/plugins/tour/UluTourContent.vue.js +22 -14
- package/dist/plugins/tour/UluTourDisplay.vue.js +83 -69
- package/dist/plugins/tour/api.d.ts +18 -2
- package/dist/plugins/tour/api.d.ts.map +1 -1
- package/dist/plugins/tour/api.js +32 -16
- package/lib/plugins/tour/UluTourContent.vue +32 -2
- package/lib/plugins/tour/UluTourDisplay.vue +41 -13
- package/lib/plugins/tour/api.js +41 -7
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UluTourContent.vue.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/UluTourContent.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UluTourContent.vue.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/UluTourContent.vue"],"names":[],"mappings":"AA2BA;"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { computed as
|
|
2
|
-
import
|
|
3
|
-
import { useTour as
|
|
4
|
-
const
|
|
1
|
+
import { computed as r, createElementBlock as a, openBlock as o, createBlock as f, createCommentVNode as l, createVNode as h, resolveDynamicComponent as C, normalizeClass as c, withCtx as _, createElementVNode as u, toDisplayString as n } from "vue";
|
|
2
|
+
import y from "../../components/elements/UluRule.vue.js";
|
|
3
|
+
import { useTour as P } from "./useTour.js";
|
|
4
|
+
const k = { class: "tour-content crop-margins" }, x = { class: "tour-content__title-text" }, T = {
|
|
5
|
+
key: 1,
|
|
6
|
+
class: "tour-content__body"
|
|
7
|
+
}, V = {
|
|
5
8
|
__name: "UluTourContent",
|
|
6
9
|
props: {
|
|
7
10
|
/**
|
|
@@ -19,23 +22,28 @@ const v = { class: "tour-content crop-margins" }, y = { key: 1 }, M = {
|
|
|
19
22
|
default: !1
|
|
20
23
|
}
|
|
21
24
|
},
|
|
22
|
-
setup(
|
|
23
|
-
const { state:
|
|
24
|
-
return (
|
|
25
|
-
|
|
25
|
+
setup(t) {
|
|
26
|
+
const { state: e } = P(), s = t, d = r(() => s.step.titleClass ? s.step.titleClass : s.isModal ? e.active?.modalTitleClass || ["h3", "no-margin"] : e.active?.popoverTitleClass || ["h4", "display-block", "no-margin"]), p = r(() => s.step.progressClass || e.active?.progressClass || "headline-label"), m = r(() => e.stepIndex + 1), g = r(() => e.active?.steps?.length || 0), v = r(() => s.step.hideProgress !== void 0 ? !s.step.hideProgress : e.active?.hideProgress !== void 0 ? !e.active.hideProgress : !0);
|
|
27
|
+
return (b, i) => (o(), a("div", k, [
|
|
28
|
+
t.step?.title ? (o(), f(C(t.isModal ? "h2" : "strong"), {
|
|
26
29
|
key: 0,
|
|
27
|
-
class: d
|
|
30
|
+
class: c(["tour-content__title", d.value])
|
|
28
31
|
}, {
|
|
29
|
-
default:
|
|
30
|
-
|
|
32
|
+
default: _(() => [
|
|
33
|
+
v.value ? (o(), a("span", {
|
|
34
|
+
key: 0,
|
|
35
|
+
class: c(["tour-content__title-progress", p.value])
|
|
36
|
+
}, " Part " + n(m.value) + " / " + n(g.value), 3)) : l("", !0),
|
|
37
|
+
i[0] || (i[0] = u("span", { class: "hidden-visually" }, ":", -1)),
|
|
38
|
+
u("span", x, n(t.step.title), 1)
|
|
31
39
|
]),
|
|
32
40
|
_: 1
|
|
33
41
|
}, 8, ["class"])) : l("", !0),
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
h(y),
|
|
43
|
+
t.step?.content ? (o(), a("p", T, n(t.step.content), 1)) : l("", !0)
|
|
36
44
|
]));
|
|
37
45
|
}
|
|
38
46
|
};
|
|
39
47
|
export {
|
|
40
|
-
|
|
48
|
+
V as default
|
|
41
49
|
};
|
|
@@ -1,37 +1,44 @@
|
|
|
1
|
-
import { computed as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { useTour as
|
|
7
|
-
const
|
|
1
|
+
import { computed as r, ref as h, unref as n, watch as M, nextTick as $, onMounted as R, onUnmounted as q, createBlock as a, openBlock as u, Teleport as U, createElementBlock as P, createCommentVNode as S, Fragment as V, resolveDynamicComponent as i, mergeProps as d, createSlots as _, withCtx as y, normalizeStyle as H } from "vue";
|
|
2
|
+
import N from "../../components/collapsible/UluModal.vue.js";
|
|
3
|
+
import O from "../popovers/UluPopoverBase.vue.js";
|
|
4
|
+
import j from "./UluTourPager.vue.js";
|
|
5
|
+
import E from "./UluTourContent.vue.js";
|
|
6
|
+
import { useTour as A } from "./useTour.js";
|
|
7
|
+
const Z = {
|
|
8
8
|
__name: "UluTourDisplay",
|
|
9
|
-
setup(
|
|
10
|
-
const { api:
|
|
9
|
+
setup(G) {
|
|
10
|
+
const { api: s, state: l } = A(), t = r(() => l.active?.steps[l.stepIndex]), w = r(() => t.value?.component || l.active?.component), f = r(() => t.value?.contentComponent || l.active?.contentComponent), x = r(() => t.value?.pagerComponent || l.active?.pagerComponent || j), T = r(() => t.value?.modalComponent || l.active?.modalComponent || N), B = r(() => t.value?.popoverComponent || l.active?.popoverComponent || O), v = h(null), g = h(null), C = h(null), k = r(() => {
|
|
11
|
+
const e = n(t.value?.target);
|
|
12
|
+
return typeof e == "function" ? n(e()) : e;
|
|
13
|
+
}), b = r(() => {
|
|
14
|
+
const e = n(t.value?.highlightElement);
|
|
15
|
+
return typeof e == "function" ? n(e()) : e;
|
|
16
|
+
}), z = r(() => ({
|
|
11
17
|
placement: t.value?.placement || "bottom",
|
|
12
18
|
arrow: !0,
|
|
13
19
|
offset: 8
|
|
14
|
-
})),
|
|
15
|
-
...
|
|
20
|
+
})), L = r(() => ({
|
|
21
|
+
...l.active?.modalProps || {},
|
|
16
22
|
...t.value?.modalProps || {}
|
|
17
|
-
})),
|
|
23
|
+
})), F = r(() => ({
|
|
18
24
|
modifiers: "large",
|
|
19
|
-
...
|
|
25
|
+
...l.active?.popoverProps || {},
|
|
20
26
|
...t.value?.popoverProps || {}
|
|
21
|
-
})),
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
})), m = h(null), c = () => {
|
|
28
|
+
const e = g.value || v.value;
|
|
29
|
+
if (e) {
|
|
30
|
+
const o = e.getBoundingClientRect();
|
|
31
|
+
m.value = {
|
|
32
|
+
top: o.top,
|
|
33
|
+
left: o.left,
|
|
34
|
+
width: o.width,
|
|
35
|
+
height: o.height
|
|
29
36
|
};
|
|
30
37
|
} else
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
if (!
|
|
34
|
-
const e =
|
|
38
|
+
m.value = null;
|
|
39
|
+
}, I = r(() => {
|
|
40
|
+
if (!m.value) return {};
|
|
41
|
+
const e = m.value;
|
|
35
42
|
return {
|
|
36
43
|
position: "fixed",
|
|
37
44
|
top: 0,
|
|
@@ -56,44 +63,51 @@ const Q = {
|
|
|
56
63
|
)`
|
|
57
64
|
};
|
|
58
65
|
});
|
|
59
|
-
return
|
|
60
|
-
if (e
|
|
61
|
-
await
|
|
62
|
-
const
|
|
63
|
-
|
|
66
|
+
return M([k, b], async ([e, o]) => {
|
|
67
|
+
if (e) {
|
|
68
|
+
await $();
|
|
69
|
+
const p = typeof e == "string" ? document.querySelector(e) : n(e);
|
|
70
|
+
p ? (v.value = p, C.value && C.value.update()) : (console.warn("Tour target not found:", e), v.value = null);
|
|
64
71
|
} else
|
|
65
|
-
v.value = null
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
v.value = null;
|
|
73
|
+
if (o) {
|
|
74
|
+
await $();
|
|
75
|
+
const p = typeof o == "string" ? document.querySelector(o) : n(o);
|
|
76
|
+
p ? g.value = p : (console.warn("Tour highlight element not found:", o), g.value = null);
|
|
77
|
+
} else
|
|
78
|
+
g.value = null;
|
|
79
|
+
t.value?.highlight && c();
|
|
80
|
+
}, { immediate: !0 }), R(() => {
|
|
81
|
+
window.addEventListener("resize", c), window.addEventListener("scroll", c);
|
|
82
|
+
}), q(() => {
|
|
83
|
+
window.removeEventListener("resize", c), window.removeEventListener("scroll", c);
|
|
84
|
+
}), (e, o) => (u(), a(U, { to: "body" }, [
|
|
85
|
+
n(l).active ? (u(), P(V, { key: 0 }, [
|
|
86
|
+
w.value ? (u(), a(i(w.value), d({
|
|
73
87
|
key: 0,
|
|
74
88
|
"data-ulu-tour-ui": "true",
|
|
75
89
|
step: t.value,
|
|
76
|
-
tourState:
|
|
77
|
-
api:
|
|
78
|
-
}, t.value.componentProps), null, 16, ["step", "tourState", "api"])) :
|
|
90
|
+
tourState: n(l),
|
|
91
|
+
api: n(s)
|
|
92
|
+
}, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : k.value ? (u(), a(i(B.value), d({
|
|
79
93
|
key: 2,
|
|
80
94
|
ref_key: "popoverBase",
|
|
81
|
-
ref:
|
|
95
|
+
ref: C,
|
|
82
96
|
trigger: v.value,
|
|
83
|
-
config:
|
|
97
|
+
config: z.value,
|
|
84
98
|
style: { zIndex: 9999 },
|
|
85
99
|
isOpen: !0,
|
|
86
100
|
"data-ulu-tour-ui": "true",
|
|
87
|
-
onClose:
|
|
88
|
-
},
|
|
89
|
-
default:
|
|
90
|
-
|
|
101
|
+
onClose: o[1] || (o[1] = (p) => n(s).stop())
|
|
102
|
+
}, F.value), _({
|
|
103
|
+
default: y(() => [
|
|
104
|
+
f.value ? (u(), a(i(f.value), d({
|
|
91
105
|
key: 0,
|
|
92
106
|
step: t.value,
|
|
93
|
-
tourState:
|
|
94
|
-
api:
|
|
107
|
+
tourState: n(l),
|
|
108
|
+
api: n(s),
|
|
95
109
|
"is-modal": !1
|
|
96
|
-
}, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : (
|
|
110
|
+
}, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : (u(), a(E, {
|
|
97
111
|
key: 1,
|
|
98
112
|
step: t.value,
|
|
99
113
|
"is-modal": !1
|
|
@@ -103,26 +117,26 @@ const Q = {
|
|
|
103
117
|
}, [
|
|
104
118
|
t.value?.hideFooter ? void 0 : {
|
|
105
119
|
name: "footer",
|
|
106
|
-
fn:
|
|
107
|
-
(
|
|
120
|
+
fn: y(() => [
|
|
121
|
+
(u(), a(i(x.value)))
|
|
108
122
|
]),
|
|
109
123
|
key: "0"
|
|
110
124
|
}
|
|
111
|
-
]), 1040, ["trigger", "config"])) : (
|
|
125
|
+
]), 1040, ["trigger", "config"])) : (u(), a(i(T.value), d({
|
|
112
126
|
key: 1,
|
|
113
127
|
modelValue: !0,
|
|
114
128
|
"data-ulu-tour-ui": "true"
|
|
115
|
-
},
|
|
116
|
-
onClose:
|
|
117
|
-
}),
|
|
118
|
-
default:
|
|
119
|
-
|
|
129
|
+
}, L.value, {
|
|
130
|
+
onClose: o[0] || (o[0] = (p) => n(s).stop())
|
|
131
|
+
}), _({
|
|
132
|
+
default: y(() => [
|
|
133
|
+
f.value ? (u(), a(i(f.value), d({
|
|
120
134
|
key: 0,
|
|
121
135
|
step: t.value,
|
|
122
|
-
tourState:
|
|
123
|
-
api:
|
|
136
|
+
tourState: n(l),
|
|
137
|
+
api: n(s),
|
|
124
138
|
"is-modal": !0
|
|
125
|
-
}, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : (
|
|
139
|
+
}, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : (u(), a(E, {
|
|
126
140
|
key: 1,
|
|
127
141
|
step: t.value,
|
|
128
142
|
"is-modal": !0
|
|
@@ -132,23 +146,23 @@ const Q = {
|
|
|
132
146
|
}, [
|
|
133
147
|
t.value?.hideFooter ? void 0 : {
|
|
134
148
|
name: "footer",
|
|
135
|
-
fn:
|
|
136
|
-
(
|
|
149
|
+
fn: y(() => [
|
|
150
|
+
(u(), a(i(x.value)))
|
|
137
151
|
]),
|
|
138
152
|
key: "0"
|
|
139
153
|
}
|
|
140
154
|
]), 1040)),
|
|
141
|
-
t.value?.target && t.value?.highlight &&
|
|
155
|
+
t.value?.target && t.value?.highlight && m.value ? (u(), P("div", {
|
|
142
156
|
key: 3,
|
|
143
157
|
class: "tour-highlight-backdrop",
|
|
144
|
-
style:
|
|
158
|
+
style: H(I.value),
|
|
145
159
|
"data-ulu-tour-ui": "true",
|
|
146
|
-
onClick:
|
|
147
|
-
}, null, 4)) :
|
|
148
|
-
], 64)) :
|
|
160
|
+
onClick: o[2] || (o[2] = (p) => n(s).stop())
|
|
161
|
+
}, null, 4)) : S("", !0)
|
|
162
|
+
], 64)) : S("", !0)
|
|
149
163
|
]));
|
|
150
164
|
}
|
|
151
165
|
};
|
|
152
166
|
export {
|
|
153
|
-
|
|
167
|
+
Z as default
|
|
154
168
|
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export function createApi(state: Object): Object;
|
|
2
2
|
export type TourStep = {
|
|
3
3
|
/**
|
|
4
|
-
* - The CSS selector for the target element. If omitted, step renders as a modal.
|
|
4
|
+
* - The CSS selector, DOM element, or function returning either, for the target element. If omitted or resolves to falsy, step renders as a modal.
|
|
5
5
|
*/
|
|
6
|
-
target?: string | undefined;
|
|
6
|
+
target?: string | Function | HTMLElement | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* - Element to highlight if different from target. Falls back to target if not provided.
|
|
9
|
+
*/
|
|
10
|
+
highlightElement?: string | Function | HTMLElement | undefined;
|
|
7
11
|
/**
|
|
8
12
|
* - The title text for the step.
|
|
9
13
|
*/
|
|
@@ -16,6 +20,10 @@ export type TourStep = {
|
|
|
16
20
|
* - Class to apply to the pager footer.
|
|
17
21
|
*/
|
|
18
22
|
pagerClass?: string | Object | any[] | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* - Class to apply to the progress indicator.
|
|
25
|
+
*/
|
|
26
|
+
progressClass?: string | Object | any[] | undefined;
|
|
19
27
|
/**
|
|
20
28
|
* - The content text for the step.
|
|
21
29
|
*/
|
|
@@ -36,6 +44,10 @@ export type TourStep = {
|
|
|
36
44
|
* - If true, hides the default tour footer (Next/Back buttons).
|
|
37
45
|
*/
|
|
38
46
|
hideFooter?: boolean | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* - If true, hides the "Part X / Y" progress indicator for this step.
|
|
49
|
+
*/
|
|
50
|
+
hideProgress?: boolean | undefined;
|
|
39
51
|
/**
|
|
40
52
|
* - Floating UI placement string (e.g. 'bottom', 'right').
|
|
41
53
|
*/
|
|
@@ -44,6 +56,10 @@ export type TourStep = {
|
|
|
44
56
|
* - If true, darkens the backdrop around the target element.
|
|
45
57
|
*/
|
|
46
58
|
highlight?: boolean | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* - If true or returns true, this step will be skipped when navigating the tour.
|
|
61
|
+
*/
|
|
62
|
+
skip?: boolean | Function | undefined;
|
|
47
63
|
/**
|
|
48
64
|
* - Props to pass to the modal (if target is omitted).
|
|
49
65
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/api.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/api.js"],"names":[],"mappings":"AA8BO,iCAHI,MAAM,GACJ,MAAM,CAgJjB"}
|
package/dist/plugins/tour/api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { markRaw as
|
|
2
|
-
const
|
|
1
|
+
import { markRaw as o } from "vue";
|
|
2
|
+
const a = (n) => ({
|
|
3
3
|
/**
|
|
4
4
|
* Starts a new tour
|
|
5
5
|
* @param {Object} tour - The tour configuration object
|
|
@@ -10,6 +10,8 @@ const r = (n) => ({
|
|
|
10
10
|
* @param {String|Array|Object} [tour.modalTitleClass] - Global class applied to the title of modal steps.
|
|
11
11
|
* @param {String|Array|Object} [tour.popoverTitleClass] - Global class applied to the title of popover steps.
|
|
12
12
|
* @param {String|Array|Object} [tour.pagerClass] - Global class applied to the pager.
|
|
13
|
+
* @param {String|Array|Object} [tour.progressClass] - Global class applied to the progress indicator.
|
|
14
|
+
* @param {Boolean} [tour.hideProgress] - Globally hides the progress indicator for all steps unless overridden.
|
|
13
15
|
* @param {Function} [tour.onStart] - Async hook called before the tour starts.
|
|
14
16
|
* @param {Function} [tour.onStop] - Async hook called when the tour is closed/finished.
|
|
15
17
|
*/
|
|
@@ -18,7 +20,18 @@ const r = (n) => ({
|
|
|
18
20
|
n.isTransitioning = !0;
|
|
19
21
|
try {
|
|
20
22
|
if (!i?.steps?.length) return;
|
|
21
|
-
typeof i.onStart == "function" && await i.onStart()
|
|
23
|
+
typeof i.onStart == "function" && await i.onStart();
|
|
24
|
+
let s = 0;
|
|
25
|
+
for (; s < i.steps.length; ) {
|
|
26
|
+
const e = i.steps[s];
|
|
27
|
+
if (!(typeof e.skip == "function" ? await e.skip() : e.skip)) break;
|
|
28
|
+
s++;
|
|
29
|
+
}
|
|
30
|
+
if (s >= i.steps.length) {
|
|
31
|
+
typeof i.onStop == "function" && await i.onStop();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
await this._runHooks(i.steps[s]), n.active = o(i), n.stepIndex = s;
|
|
22
35
|
} finally {
|
|
23
36
|
n.isTransitioning = !1;
|
|
24
37
|
}
|
|
@@ -33,12 +46,13 @@ const r = (n) => ({
|
|
|
33
46
|
if (i) {
|
|
34
47
|
n.isTransitioning = !0;
|
|
35
48
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const e =
|
|
39
|
-
await
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
let s = n.stepIndex + 1;
|
|
50
|
+
for (; s < i.steps.length; ) {
|
|
51
|
+
const e = i.steps[s];
|
|
52
|
+
if (!(typeof e.skip == "function" ? await e.skip() : e.skip)) break;
|
|
53
|
+
s++;
|
|
54
|
+
}
|
|
55
|
+
s < i.steps.length ? (await this._runLeaveHook(i.steps[n.stepIndex]), await this._runHooks(i.steps[s]), n.stepIndex = s) : await this.stop(!0);
|
|
42
56
|
} finally {
|
|
43
57
|
n.isTransitioning = !1;
|
|
44
58
|
}
|
|
@@ -53,11 +67,13 @@ const r = (n) => ({
|
|
|
53
67
|
if (i) {
|
|
54
68
|
n.isTransitioning = !0;
|
|
55
69
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const e =
|
|
59
|
-
await
|
|
70
|
+
let s = n.stepIndex - 1;
|
|
71
|
+
for (; s >= 0; ) {
|
|
72
|
+
const e = i.steps[s];
|
|
73
|
+
if (!(typeof e.skip == "function" ? await e.skip() : e.skip)) break;
|
|
74
|
+
s--;
|
|
60
75
|
}
|
|
76
|
+
s >= 0 && (await this._runLeaveHook(i.steps[n.stepIndex]), await this._runHooks(i.steps[s]), n.stepIndex = s);
|
|
61
77
|
} finally {
|
|
62
78
|
n.isTransitioning = !1;
|
|
63
79
|
}
|
|
@@ -71,8 +87,8 @@ const r = (n) => ({
|
|
|
71
87
|
if (!(!i && n.isTransitioning)) {
|
|
72
88
|
n.isTransitioning = !0;
|
|
73
89
|
try {
|
|
74
|
-
const
|
|
75
|
-
|
|
90
|
+
const s = n.active;
|
|
91
|
+
s && (s.steps[n.stepIndex] && await this._runLeaveHook(s.steps[n.stepIndex]), typeof s.onStop == "function" && await s.onStop()), n.active = null, n.stepIndex = 0;
|
|
76
92
|
} finally {
|
|
77
93
|
n.isTransitioning = !1;
|
|
78
94
|
}
|
|
@@ -94,5 +110,5 @@ const r = (n) => ({
|
|
|
94
110
|
}
|
|
95
111
|
});
|
|
96
112
|
export {
|
|
97
|
-
|
|
113
|
+
a as createApi
|
|
98
114
|
};
|
|
@@ -2,13 +2,25 @@
|
|
|
2
2
|
<div class="tour-content crop-margins">
|
|
3
3
|
<component
|
|
4
4
|
v-if="step?.title"
|
|
5
|
+
class="tour-content__title"
|
|
5
6
|
:is="isModal ? 'h2' : 'strong'"
|
|
6
7
|
:class="resolvedTitleClass"
|
|
7
8
|
>
|
|
8
|
-
|
|
9
|
+
<span
|
|
10
|
+
v-if="showProgress"
|
|
11
|
+
class="tour-content__title-progress"
|
|
12
|
+
:class="resolvedProgressClass"
|
|
13
|
+
>
|
|
14
|
+
Part {{ currentProgress }} / {{ totalProgress }}
|
|
15
|
+
</span>
|
|
16
|
+
<span class="hidden-visually">:</span>
|
|
17
|
+
<span class="tour-content__title-text">{{ step.title }}</span>
|
|
9
18
|
</component>
|
|
10
19
|
<UluRule />
|
|
11
|
-
<p
|
|
20
|
+
<p
|
|
21
|
+
class="tour-content__body"
|
|
22
|
+
v-if="step?.content"
|
|
23
|
+
>
|
|
12
24
|
{{ step.content }}
|
|
13
25
|
</p>
|
|
14
26
|
</div>
|
|
@@ -47,4 +59,22 @@
|
|
|
47
59
|
return tourState.active?.popoverTitleClass || ['h4', 'display-block', 'no-margin'];
|
|
48
60
|
}
|
|
49
61
|
});
|
|
62
|
+
|
|
63
|
+
const resolvedProgressClass = computed(() => {
|
|
64
|
+
return props.step.progressClass || tourState.active?.progressClass || 'headline-label';
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const currentProgress = computed(() => tourState.stepIndex + 1);
|
|
68
|
+
|
|
69
|
+
const totalProgress = computed(() => tourState.active?.steps?.length || 0);
|
|
70
|
+
|
|
71
|
+
const showProgress = computed(() => {
|
|
72
|
+
if (props.step.hideProgress !== undefined) {
|
|
73
|
+
return !props.step.hideProgress;
|
|
74
|
+
}
|
|
75
|
+
if (tourState.active?.hideProgress !== undefined) {
|
|
76
|
+
return !tourState.active.hideProgress;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
});
|
|
50
80
|
</script>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
<!-- 2. RENDER MODAL STEP -->
|
|
17
17
|
<component
|
|
18
|
-
v-else-if="!
|
|
18
|
+
v-else-if="!resolvedTargetDescriptor"
|
|
19
19
|
:is="resolvedModalComponent"
|
|
20
20
|
:modelValue="true"
|
|
21
21
|
data-ulu-tour-ui="true"
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
</template>
|
|
81
81
|
|
|
82
82
|
<script setup>
|
|
83
|
-
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue';
|
|
83
|
+
import { ref, computed, watch, nextTick, onMounted, onUnmounted, unref } from 'vue';
|
|
84
84
|
import UluModal from '../../components/collapsible/UluModal.vue';
|
|
85
85
|
import UluPopoverBase from '../popovers/UluPopoverBase.vue';
|
|
86
86
|
import UluTourPager from './UluTourPager.vue';
|
|
@@ -100,8 +100,21 @@
|
|
|
100
100
|
|
|
101
101
|
// Floating UI Setup for Popovers
|
|
102
102
|
const targetEl = ref(null);
|
|
103
|
+
const highlightEl = ref(null);
|
|
103
104
|
const popoverBase = ref(null);
|
|
104
105
|
|
|
106
|
+
const resolvedTargetDescriptor = computed(() => {
|
|
107
|
+
const t = unref(currentStep.value?.target);
|
|
108
|
+
if (typeof t === 'function') return unref(t());
|
|
109
|
+
return t;
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const resolvedHighlightDescriptor = computed(() => {
|
|
113
|
+
const h = unref(currentStep.value?.highlightElement);
|
|
114
|
+
if (typeof h === 'function') return unref(h());
|
|
115
|
+
return h;
|
|
116
|
+
});
|
|
117
|
+
|
|
105
118
|
const resolvedConfig = computed(() => ({
|
|
106
119
|
placement: currentStep.value?.placement || 'bottom',
|
|
107
120
|
arrow: true,
|
|
@@ -128,8 +141,9 @@
|
|
|
128
141
|
const targetRect = ref(null);
|
|
129
142
|
|
|
130
143
|
const updateTargetRect = () => {
|
|
131
|
-
|
|
132
|
-
|
|
144
|
+
const el = highlightEl.value || targetEl.value;
|
|
145
|
+
if (el) {
|
|
146
|
+
const rect = el.getBoundingClientRect();
|
|
133
147
|
targetRect.value = {
|
|
134
148
|
top: rect.top,
|
|
135
149
|
left: rect.left,
|
|
@@ -169,11 +183,11 @@
|
|
|
169
183
|
};
|
|
170
184
|
});
|
|
171
185
|
|
|
172
|
-
// Watch for step changes to update floating UI target
|
|
173
|
-
watch(
|
|
174
|
-
if (
|
|
186
|
+
// Watch for step changes to update floating UI target and highlight target
|
|
187
|
+
watch([resolvedTargetDescriptor, resolvedHighlightDescriptor], async ([targetDesc, highlightDesc]) => {
|
|
188
|
+
if (targetDesc) {
|
|
175
189
|
await nextTick();
|
|
176
|
-
const el = document.querySelector(
|
|
190
|
+
const el = typeof targetDesc === 'string' ? document.querySelector(targetDesc) : unref(targetDesc);
|
|
177
191
|
if (el) {
|
|
178
192
|
targetEl.value = el;
|
|
179
193
|
// UluPopoverBase's isOpen watcher automatically calls update(),
|
|
@@ -182,15 +196,29 @@
|
|
|
182
196
|
if (popoverBase.value) {
|
|
183
197
|
popoverBase.value.update();
|
|
184
198
|
}
|
|
185
|
-
if (step.highlight) {
|
|
186
|
-
updateTargetRect();
|
|
187
|
-
}
|
|
188
199
|
} else {
|
|
189
|
-
console.warn(`Tour target not found
|
|
200
|
+
console.warn(`Tour target not found:`, targetDesc);
|
|
201
|
+
targetEl.value = null;
|
|
190
202
|
}
|
|
191
203
|
} else {
|
|
192
204
|
targetEl.value = null;
|
|
193
|
-
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (highlightDesc) {
|
|
208
|
+
await nextTick();
|
|
209
|
+
const hEl = typeof highlightDesc === 'string' ? document.querySelector(highlightDesc) : unref(highlightDesc);
|
|
210
|
+
if (hEl) {
|
|
211
|
+
highlightEl.value = hEl;
|
|
212
|
+
} else {
|
|
213
|
+
console.warn(`Tour highlight element not found:`, highlightDesc);
|
|
214
|
+
highlightEl.value = null;
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
highlightEl.value = null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (currentStep.value?.highlight) {
|
|
221
|
+
updateTargetRect();
|
|
194
222
|
}
|
|
195
223
|
}, { immediate: true });
|
|
196
224
|
|