@ulu/frontend-vue 0.6.32 → 0.6.34

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,100 +1,5 @@
1
- import { nextTick } from 'vue';
2
1
  declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
3
- popoverBase: ({
4
- $: import('vue').ComponentInternalInstance;
5
- $data: {};
6
- $props: Partial<{}> & Omit<{} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>;
7
- $attrs: {
8
- [x: string]: unknown;
9
- };
10
- $refs: {
11
- [x: string]: unknown;
12
- } & {
13
- contentEl: HTMLSpanElement;
14
- contentArrow: HTMLSpanElement;
15
- };
16
- $slots: Readonly<{
17
- [name: string]: import('vue').Slot<any> | undefined;
18
- }>;
19
- $root: import('vue').ComponentPublicInstance | null;
20
- $parent: import('vue').ComponentPublicInstance | null;
21
- $host: Element | null;
22
- $emit: (event: string, ...args: any[]) => void;
23
- $el: HTMLSpanElement;
24
- $options: import('vue').ComponentOptionsBase<Readonly<{}> & Readonly<{}>, {
25
- close: () => void;
26
- update: Function;
27
- content: import('vue').Ref<null, null>;
28
- $emit: (event: "close" | "update:isOpen", ...args: any[]) => void;
29
- isOpen: boolean;
30
- clickOutsideCloses: boolean;
31
- escapeCloses: boolean;
32
- directFocus: Function;
33
- trigger: Record<string, any>;
34
- config: Record<string, any>;
35
- modifiers?: string | Record<string, any> | unknown[] | undefined;
36
- $props: {
37
- readonly isOpen?: boolean | undefined;
38
- readonly clickOutsideCloses?: boolean | undefined;
39
- readonly escapeCloses?: boolean | undefined;
40
- readonly directFocus?: Function | undefined;
41
- readonly trigger?: Record<string, any> | undefined;
42
- readonly config?: Record<string, any> | undefined;
43
- readonly modifiers?: string | Record<string, any> | unknown[] | undefined;
44
- };
45
- }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, {}, {}, string, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, import('vue').ComponentProvideOptions> & {
46
- beforeCreate?: (() => void) | (() => void)[];
47
- created?: (() => void) | (() => void)[];
48
- beforeMount?: (() => void) | (() => void)[];
49
- mounted?: (() => void) | (() => void)[];
50
- beforeUpdate?: (() => void) | (() => void)[];
51
- updated?: (() => void) | (() => void)[];
52
- activated?: (() => void) | (() => void)[];
53
- deactivated?: (() => void) | (() => void)[];
54
- beforeDestroy?: (() => void) | (() => void)[];
55
- beforeUnmount?: (() => void) | (() => void)[];
56
- destroyed?: (() => void) | (() => void)[];
57
- unmounted?: (() => void) | (() => void)[];
58
- renderTracked?: ((e: import('vue').DebuggerEvent) => void) | ((e: import('vue').DebuggerEvent) => void)[];
59
- renderTriggered?: ((e: import('vue').DebuggerEvent) => void) | ((e: import('vue').DebuggerEvent) => void)[];
60
- errorCaptured?: ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void)[];
61
- };
62
- $forceUpdate: () => void;
63
- $nextTick: typeof nextTick;
64
- $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, import('@vue/reactivity').OnCleanup]) => any : (...args: [any, any, import('@vue/reactivity').OnCleanup]) => any, options?: import('vue').WatchOptions): import('vue').WatchStopHandle;
65
- } & Readonly<{}> & Omit<Readonly<{}> & Readonly<{}>, "$props" | "$emit" | "isOpen" | "clickOutsideCloses" | "escapeCloses" | "directFocus" | "trigger" | "config" | "modifiers" | "content" | "close" | "update"> & import('vue').ShallowUnwrapRef<{
66
- close: () => void;
67
- update: Function;
68
- content: import('vue').Ref<null, null>;
69
- $emit: (event: "close" | "update:isOpen", ...args: any[]) => void;
70
- isOpen: boolean;
71
- clickOutsideCloses: boolean;
72
- escapeCloses: boolean;
73
- directFocus: Function;
74
- trigger: Record<string, any>;
75
- config: Record<string, any>;
76
- modifiers?: string | Record<string, any> | unknown[] | undefined;
77
- $props: {
78
- readonly isOpen?: boolean | undefined;
79
- readonly clickOutsideCloses?: boolean | undefined;
80
- readonly escapeCloses?: boolean | undefined;
81
- readonly directFocus?: Function | undefined;
82
- readonly trigger?: Record<string, any> | undefined;
83
- readonly config?: Record<string, any> | undefined;
84
- readonly modifiers?: string | Record<string, any> | unknown[] | undefined;
85
- };
86
- }> & {} & import('vue').ComponentCustomProperties & {} & {
87
- $slots: {
88
- default?(_: {
89
- isOpen: boolean;
90
- close: () => void;
91
- }): any;
92
- footer?(_: {
93
- isOpen: boolean;
94
- close: () => void;
95
- }): any;
96
- };
97
- }) | null;
2
+ popoverBase: any;
98
3
  }, any>;
99
4
  export default _default;
100
5
  //# sourceMappingURL=UluTourDisplay.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UluTourDisplay.vue.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/UluTourDisplay.vue"],"names":[],"mappings":"AA2EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAqjBs3Q,GAAG,8CAA8C,GAAG,yBAAyB,GAAG,6DAAmC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAjXn6Q,KAAK"}
1
+ {"version":3,"file":"UluTourDisplay.vue.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/UluTourDisplay.vue"],"names":[],"mappings":"AAgFA;"}
@@ -1,37 +1,37 @@
1
- import { computed as s, ref as f, watch as B, nextTick as T, onMounted as b, onUnmounted as z, createBlock as r, openBlock as o, Teleport as L, createElementBlock as y, createCommentVNode as x, unref as u, Fragment as F, resolveDynamicComponent as g, mergeProps as v, createSlots as $, withCtx as d, createVNode as k, normalizeStyle as I } from "vue";
2
- import R from "../../components/collapsible/UluModal.vue.js";
1
+ import { computed as l, ref as h, watch as z, nextTick as L, onMounted as F, onUnmounted as I, createBlock as a, openBlock as n, Teleport as M, createElementBlock as $, createCommentVNode as k, unref as r, Fragment as R, resolveDynamicComponent as p, mergeProps as d, createSlots as w, withCtx as f, normalizeStyle as D } from "vue";
2
+ import U from "../../components/collapsible/UluModal.vue.js";
3
3
  import V from "../popovers/UluPopoverBase.vue.js";
4
- import w from "./UluTourPager.vue.js";
5
- import _ from "./UluTourContent.vue.js";
6
- import { useTour as D } from "./useTour.js";
7
- const G = {
4
+ import q from "./UluTourPager.vue.js";
5
+ import P from "./UluTourContent.vue.js";
6
+ import { useTour as N } from "./useTour.js";
7
+ const Q = {
8
8
  __name: "UluTourDisplay",
9
- setup(M) {
10
- const { api: c, state: n } = D(), t = s(() => n.active?.steps[n.stepIndex]), p = f(null), m = f(null), C = s(() => ({
9
+ setup(O) {
10
+ const { api: i, state: o } = N(), t = l(() => o.active?.steps[o.stepIndex]), y = l(() => t.value?.component || o.active?.component), c = l(() => t.value?.contentComponent || o.active?.contentComponent), C = l(() => t.value?.pagerComponent || o.active?.pagerComponent || q), _ = l(() => t.value?.modalComponent || o.active?.modalComponent || U), S = l(() => t.value?.popoverComponent || o.active?.popoverComponent || V), v = h(null), g = h(null), E = l(() => ({
11
11
  placement: t.value?.placement || "bottom",
12
12
  arrow: !0,
13
13
  offset: 8
14
- })), P = s(() => ({
15
- ...n.active?.modalProps || {},
14
+ })), B = l(() => ({
15
+ ...o.active?.modalProps || {},
16
16
  ...t.value?.modalProps || {}
17
- })), S = s(() => ({
17
+ })), T = l(() => ({
18
18
  modifiers: "large",
19
- ...n.active?.popoverProps || {},
19
+ ...o.active?.popoverProps || {},
20
20
  ...t.value?.popoverProps || {}
21
- })), a = f(null), i = () => {
22
- if (p.value) {
23
- const e = p.value.getBoundingClientRect();
24
- a.value = {
21
+ })), s = h(null), m = () => {
22
+ if (v.value) {
23
+ const e = v.value.getBoundingClientRect();
24
+ s.value = {
25
25
  top: e.top,
26
26
  left: e.left,
27
27
  width: e.width,
28
28
  height: e.height
29
29
  };
30
30
  } else
31
- a.value = null;
32
- }, E = s(() => {
33
- if (!a.value) return {};
34
- const e = a.value;
31
+ s.value = null;
32
+ }, b = l(() => {
33
+ if (!s.value) return {};
34
+ const e = s.value;
35
35
  return {
36
36
  position: "fixed",
37
37
  top: 0,
@@ -56,42 +56,44 @@ const G = {
56
56
  )`
57
57
  };
58
58
  });
59
- return B(t, async (e) => {
59
+ return z(t, async (e) => {
60
60
  if (e?.target) {
61
- await T();
62
- const l = document.querySelector(e.target);
63
- l ? (p.value = l, m.value && m.value.update(), e.highlight && i()) : console.warn(`Tour target not found: ${e.target}`);
61
+ await L();
62
+ const u = document.querySelector(e.target);
63
+ u ? (v.value = u, g.value && g.value.update(), e.highlight && m()) : console.warn(`Tour target not found: ${e.target}`);
64
64
  } else
65
- p.value = null, a.value = null;
66
- }, { immediate: !0 }), b(() => {
67
- window.addEventListener("resize", i), window.addEventListener("scroll", i);
68
- }), z(() => {
69
- window.removeEventListener("resize", i), window.removeEventListener("scroll", i);
70
- }), (e, l) => (o(), r(L, { to: "body" }, [
71
- u(n).active ? (o(), y(F, { key: 0 }, [
72
- t.value?.component ? (o(), r(g(t.value.component), v({
65
+ v.value = null, s.value = null;
66
+ }, { immediate: !0 }), F(() => {
67
+ window.addEventListener("resize", m), window.addEventListener("scroll", m);
68
+ }), I(() => {
69
+ window.removeEventListener("resize", m), window.removeEventListener("scroll", m);
70
+ }), (e, u) => (n(), a(M, { to: "body" }, [
71
+ r(o).active ? (n(), $(R, { key: 0 }, [
72
+ y.value ? (n(), a(p(y.value), d({
73
73
  key: 0,
74
74
  "data-ulu-tour-ui": "true",
75
75
  step: t.value,
76
- tourState: u(n)
77
- }, t.value.componentProps), null, 16, ["step", "tourState"])) : t.value?.target ? (o(), r(V, v({
76
+ tourState: r(o),
77
+ api: r(i)
78
+ }, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : t.value?.target ? (n(), a(p(S.value), d({
78
79
  key: 2,
79
80
  ref_key: "popoverBase",
80
- ref: m,
81
- trigger: p.value,
82
- config: C.value,
81
+ ref: g,
82
+ trigger: v.value,
83
+ config: E.value,
83
84
  style: { zIndex: 9999 },
84
85
  isOpen: !0,
85
86
  "data-ulu-tour-ui": "true",
86
- onClose: l[1] || (l[1] = (h) => u(c).stop())
87
- }, S.value), $({
88
- default: d(() => [
89
- t.value?.contentComponent ? (o(), r(g(t.value.contentComponent), v({
87
+ onClose: u[1] || (u[1] = (x) => r(i).stop())
88
+ }, T.value), w({
89
+ default: f(() => [
90
+ c.value ? (n(), a(p(c.value), d({
90
91
  key: 0,
91
92
  step: t.value,
92
- tourState: u(n),
93
+ tourState: r(o),
94
+ api: r(i),
93
95
  "is-modal": !1
94
- }, t.value.componentProps), null, 16, ["step", "tourState"])) : (o(), r(_, {
96
+ }, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : (n(), a(P, {
95
97
  key: 1,
96
98
  step: t.value,
97
99
  "is-modal": !1
@@ -101,25 +103,26 @@ const G = {
101
103
  }, [
102
104
  t.value?.hideFooter ? void 0 : {
103
105
  name: "footer",
104
- fn: d(() => [
105
- k(w)
106
+ fn: f(() => [
107
+ (n(), a(p(C.value)))
106
108
  ]),
107
109
  key: "0"
108
110
  }
109
- ]), 1040, ["trigger", "config"])) : (o(), r(R, v({
111
+ ]), 1040, ["trigger", "config"])) : (n(), a(p(_.value), d({
110
112
  key: 1,
111
113
  modelValue: !0,
112
114
  "data-ulu-tour-ui": "true"
113
- }, P.value, {
114
- onClose: l[0] || (l[0] = (h) => u(c).stop())
115
- }), $({
116
- default: d(() => [
117
- t.value?.contentComponent ? (o(), r(g(t.value.contentComponent), v({
115
+ }, B.value, {
116
+ onClose: u[0] || (u[0] = (x) => r(i).stop())
117
+ }), w({
118
+ default: f(() => [
119
+ c.value ? (n(), a(p(c.value), d({
118
120
  key: 0,
119
121
  step: t.value,
120
- tourState: u(n),
122
+ tourState: r(o),
123
+ api: r(i),
121
124
  "is-modal": !0
122
- }, t.value.componentProps), null, 16, ["step", "tourState"])) : (o(), r(_, {
125
+ }, t.value.componentProps), null, 16, ["step", "tourState", "api"])) : (n(), a(P, {
123
126
  key: 1,
124
127
  step: t.value,
125
128
  "is-modal": !0
@@ -129,23 +132,23 @@ const G = {
129
132
  }, [
130
133
  t.value?.hideFooter ? void 0 : {
131
134
  name: "footer",
132
- fn: d(() => [
133
- k(w)
135
+ fn: f(() => [
136
+ (n(), a(p(C.value)))
134
137
  ]),
135
138
  key: "0"
136
139
  }
137
140
  ]), 1040)),
138
- t.value?.target && t.value?.highlight && a.value ? (o(), y("div", {
141
+ t.value?.target && t.value?.highlight && s.value ? (n(), $("div", {
139
142
  key: 3,
140
143
  class: "tour-highlight-backdrop",
141
- style: I(E.value),
144
+ style: D(b.value),
142
145
  "data-ulu-tour-ui": "true",
143
- onClick: l[2] || (l[2] = (h) => u(c).stop())
144
- }, null, 4)) : x("", !0)
145
- ], 64)) : x("", !0)
146
+ onClick: u[2] || (u[2] = (x) => r(i).stop())
147
+ }, null, 4)) : k("", !0)
148
+ ], 64)) : k("", !0)
146
149
  ]));
147
150
  }
148
151
  };
149
152
  export {
150
- G as default
153
+ Q as default
151
154
  };
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/api.js"],"names":[],"mappings":"AA0BO,iCAHI,MAAM,GACJ,MAAM,CAqFjB"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/api.js"],"names":[],"mappings":"AA0BO,iCAHI,MAAM,GACJ,MAAM,CAkHjB"}
@@ -1,5 +1,5 @@
1
- import { markRaw as o } from "vue";
2
- const s = (e) => ({
1
+ import { markRaw as s } from "vue";
2
+ const r = (n) => ({
3
3
  /**
4
4
  * Starts a new tour
5
5
  * @param {Object} tour - The tour configuration object
@@ -10,57 +10,89 @@ const s = (e) => ({
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 {Function} [tour.onStart] - Async hook called before the tour starts.
13
14
  * @param {Function} [tour.onStop] - Async hook called when the tour is closed/finished.
14
15
  */
15
- async start(n) {
16
- n?.steps?.length && (await this._runHooks(n.steps[0]), e.active = o(n), e.stepIndex = 0);
16
+ async start(i) {
17
+ if (!n.isTransitioning) {
18
+ n.isTransitioning = !0;
19
+ try {
20
+ if (!i?.steps?.length) return;
21
+ typeof i.onStart == "function" && await i.onStart(), await this._runHooks(i.steps[0]), n.active = s(i), n.stepIndex = 0;
22
+ } finally {
23
+ n.isTransitioning = !1;
24
+ }
25
+ }
17
26
  },
18
27
  /**
19
28
  * Advances the tour to the next step, or stops if it is the last step
20
29
  */
21
30
  async next() {
22
- const n = e.active;
23
- if (n)
24
- if (e.stepIndex < n.steps.length - 1) {
25
- await this._runLeaveHook(n.steps[e.stepIndex]);
26
- const i = e.stepIndex + 1;
27
- await this._runHooks(n.steps[i]), e.stepIndex = i;
28
- } else
29
- await this.stop();
31
+ if (n.isTransitioning) return;
32
+ const i = n.active;
33
+ if (i) {
34
+ n.isTransitioning = !0;
35
+ try {
36
+ if (n.stepIndex < i.steps.length - 1) {
37
+ await this._runLeaveHook(i.steps[n.stepIndex]);
38
+ const e = n.stepIndex + 1;
39
+ await this._runHooks(i.steps[e]), n.stepIndex = e;
40
+ } else
41
+ await this.stop(!0);
42
+ } finally {
43
+ n.isTransitioning = !1;
44
+ }
45
+ }
30
46
  },
31
47
  /**
32
48
  * Returns the tour to the previous step
33
49
  */
34
50
  async prev() {
35
- const n = e.active;
36
- if (n && e.stepIndex > 0) {
37
- await this._runLeaveHook(n.steps[e.stepIndex]);
38
- const i = e.stepIndex - 1;
39
- await this._runHooks(n.steps[i]), e.stepIndex = i;
51
+ if (n.isTransitioning) return;
52
+ const i = n.active;
53
+ if (i) {
54
+ n.isTransitioning = !0;
55
+ try {
56
+ if (n.stepIndex > 0) {
57
+ await this._runLeaveHook(i.steps[n.stepIndex]);
58
+ const e = n.stepIndex - 1;
59
+ await this._runHooks(i.steps[e]), n.stepIndex = e;
60
+ }
61
+ } finally {
62
+ n.isTransitioning = !1;
63
+ }
40
64
  }
41
65
  },
42
66
  /**
43
67
  * Stops and closes the current tour
68
+ * @param {Boolean} [internalBypass=false] - Used internally to bypass transition check
44
69
  */
45
- async stop() {
46
- const n = e.active;
47
- n && (n.steps[e.stepIndex] && await this._runLeaveHook(n.steps[e.stepIndex]), typeof n.onStop == "function" && await n.onStop()), e.active = null, e.stepIndex = 0;
70
+ async stop(i = !1) {
71
+ if (!(!i && n.isTransitioning)) {
72
+ n.isTransitioning = !0;
73
+ try {
74
+ const e = n.active;
75
+ e && (e.steps[n.stepIndex] && await this._runLeaveHook(e.steps[n.stepIndex]), typeof e.onStop == "function" && await e.onStop()), n.active = null, n.stepIndex = 0;
76
+ } finally {
77
+ n.isTransitioning = !1;
78
+ }
79
+ }
48
80
  },
49
81
  /**
50
82
  * Internal method to run asynchronous enter hooks on a step
51
83
  * @param {Object} step - The tour step configuration
52
84
  */
53
- async _runHooks(n) {
54
- n && typeof n.onEnter == "function" && await n.onEnter();
85
+ async _runHooks(i) {
86
+ i && typeof i.onEnter == "function" && await i.onEnter();
55
87
  },
56
88
  /**
57
89
  * Internal method to run asynchronous leave hooks on a step
58
90
  * @param {Object} step - The tour step configuration
59
91
  */
60
- async _runLeaveHook(n) {
61
- n && typeof n.onLeave == "function" && await n.onLeave();
92
+ async _runLeaveHook(i) {
93
+ i && typeof i.onLeave == "function" && await i.onLeave();
62
94
  }
63
95
  });
64
96
  export {
65
- s as createApi
97
+ r as createApi
66
98
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/index.js"],"names":[],"mappings":"AAQA,gDAeC;;;;;wBAjBuB,cAAc"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/plugins/tour/index.js"],"names":[],"mappings":"AAQA,gDAgBC;;;;;wBAlBuB,cAAc"}
@@ -1,14 +1,15 @@
1
- import { reactive as e } from "vue";
2
- import u from "./UluTourDisplay.vue.js";
3
- import { createApi as i } from "./api.js";
4
- function s(o) {
5
- const t = e({
1
+ import { reactive as r } from "vue";
2
+ import e from "./UluTourDisplay.vue.js";
3
+ import { createApi as u } from "./api.js";
4
+ function a(o) {
5
+ const t = r({
6
6
  active: null,
7
- stepIndex: 0
8
- }), r = i(t);
9
- o.component("UluTourDisplay", u), o.config.globalProperties.$uluTour = r, o.config.globalProperties.$uluTourState = t, o.provide("uluTour", r), o.provide("uluTourState", t);
7
+ stepIndex: 0,
8
+ isTransitioning: !1
9
+ }), i = u(t);
10
+ o.component("UluTourDisplay", e), o.config.globalProperties.$uluTour = i, o.config.globalProperties.$uluTourState = t, o.provide("uluTour", i), o.provide("uluTourState", t);
10
11
  }
11
12
  export {
12
- u as UluTourDisplay,
13
- s as default
13
+ e as UluTourDisplay,
14
+ a as default
14
15
  };
@@ -4,40 +4,44 @@
4
4
 
5
5
  <!-- 1. FULL COMPONENT TAKEOVER -->
6
6
  <component
7
- v-if="currentStep?.component"
8
- :is="currentStep.component"
7
+ v-if="resolvedComponent"
8
+ :is="resolvedComponent"
9
9
  data-ulu-tour-ui="true"
10
10
  :step="currentStep"
11
11
  :tourState="tourState"
12
+ :api="api"
12
13
  v-bind="currentStep.componentProps"
13
14
  />
14
15
 
15
16
  <!-- 2. RENDER MODAL STEP -->
16
- <UluModal
17
+ <component
17
18
  v-else-if="!currentStep?.target"
19
+ :is="resolvedModalComponent"
18
20
  :modelValue="true"
19
21
  data-ulu-tour-ui="true"
20
22
  v-bind="resolvedModalProps"
21
23
  @close="api.stop()"
22
24
  >
23
25
  <component
24
- v-if="currentStep?.contentComponent"
25
- :is="currentStep.contentComponent"
26
+ v-if="resolvedContentComponent"
27
+ :is="resolvedContentComponent"
26
28
  :step="currentStep"
27
29
  :tourState="tourState"
30
+ :api="api"
28
31
  :is-modal="true"
29
32
  v-bind="currentStep.componentProps"
30
33
  />
31
34
  <UluTourContent v-else :step="currentStep" :is-modal="true" />
32
35
 
33
36
  <template #footer v-if="!currentStep?.hideFooter">
34
- <UluTourPager />
37
+ <component :is="resolvedPagerComponent" />
35
38
  </template>
36
- </UluModal>
39
+ </component>
37
40
 
38
41
  <!-- 3. RENDER POPOVER STEP -->
39
- <UluPopoverBase
42
+ <component
40
43
  v-else
44
+ :is="resolvedPopoverComponent"
41
45
  ref="popoverBase"
42
46
  :trigger="targetEl"
43
47
  :config="resolvedConfig"
@@ -48,19 +52,20 @@
48
52
  v-bind="resolvedPopoverProps"
49
53
  >
50
54
  <component
51
- v-if="currentStep?.contentComponent"
52
- :is="currentStep.contentComponent"
55
+ v-if="resolvedContentComponent"
56
+ :is="resolvedContentComponent"
53
57
  :step="currentStep"
54
58
  :tourState="tourState"
59
+ :api="api"
55
60
  :is-modal="false"
56
61
  v-bind="currentStep.componentProps"
57
62
  />
58
63
  <UluTourContent v-else :step="currentStep" :is-modal="false" />
59
64
 
60
65
  <template #footer v-if="!currentStep?.hideFooter">
61
- <UluTourPager />
66
+ <component :is="resolvedPagerComponent" />
62
67
  </template>
63
- </UluPopoverBase>
68
+ </component>
64
69
 
65
70
  <!-- OPTIONAL HIGHLIGHT BACKDROP -->
66
71
  <div
@@ -86,6 +91,13 @@
86
91
 
87
92
  const currentStep = computed(() => tourState.active?.steps[tourState.stepIndex]);
88
93
 
94
+ // Component Resolution
95
+ const resolvedComponent = computed(() => currentStep.value?.component || tourState.active?.component);
96
+ const resolvedContentComponent = computed(() => currentStep.value?.contentComponent || tourState.active?.contentComponent);
97
+ const resolvedPagerComponent = computed(() => currentStep.value?.pagerComponent || tourState.active?.pagerComponent || UluTourPager);
98
+ const resolvedModalComponent = computed(() => currentStep.value?.modalComponent || tourState.active?.modalComponent || UluModal);
99
+ const resolvedPopoverComponent = computed(() => currentStep.value?.popoverComponent || tourState.active?.popoverComponent || UluPopoverBase);
100
+
89
101
  // Floating UI Setup for Popovers
90
102
  const targetEl = ref(null);
91
103
  const popoverBase = ref(null);