veo-sdk 0.3.6 → 0.3.7
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/builder-7MBMYL26.mjs +5 -0
- package/dist/{builder-MIPJRGOD.mjs.map → builder-7MBMYL26.mjs.map} +1 -1
- package/dist/builder.cjs +249 -110
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.d.cts +2 -2
- package/dist/builder.d.ts +2 -2
- package/dist/builder.mjs +4 -4
- package/dist/{chunk-FUMGOQJR.mjs → chunk-4VJIILXF.mjs} +251 -112
- package/dist/chunk-4VJIILXF.mjs.map +1 -0
- package/dist/{chunk-A73VSAZP.mjs → chunk-734ORVMM.mjs} +3 -3
- package/dist/{chunk-A73VSAZP.mjs.map → chunk-734ORVMM.mjs.map} +1 -1
- package/dist/{chunk-B5GO6PTO.mjs → chunk-RNHOBE2D.mjs} +34 -4
- package/dist/chunk-RNHOBE2D.mjs.map +1 -0
- package/dist/{guide-preview-CO5ShtNf.d.cts → guide-preview-DewCTa-B.d.cts} +26 -1
- package/dist/{guide-preview-CO5ShtNf.d.ts → guide-preview-DewCTa-B.d.ts} +26 -1
- package/dist/index.cjs +288 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +5 -5
- package/dist/veo-builder.js +9 -9
- package/dist/veo-builder.js.map +1 -1
- package/dist/veo-guides.js +4 -4
- package/dist/veo-guides.js.map +1 -1
- package/package.json +1 -1
- package/dist/builder-MIPJRGOD.mjs +0 -5
- package/dist/chunk-B5GO6PTO.mjs.map +0 -1
- package/dist/chunk-FUMGOQJR.mjs.map +0 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createBuilderSession, initBuilderMode, startElementPicker, stopElementPicker } from './chunk-734ORVMM.mjs';
|
|
2
|
+
import './chunk-4VJIILXF.mjs';
|
|
3
|
+
import './chunk-PTG3BTJE.mjs';
|
|
4
|
+
//# sourceMappingURL=builder-7MBMYL26.mjs.map
|
|
5
|
+
//# sourceMappingURL=builder-7MBMYL26.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"builder-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"builder-7MBMYL26.mjs"}
|
package/dist/builder.cjs
CHANGED
|
@@ -146,6 +146,16 @@ var WALKTHROUGH_STEP_SELECTOR_TIMEOUT_MS = 5e3;
|
|
|
146
146
|
function buildStepContent(step, doc, callbacks) {
|
|
147
147
|
const container = doc.createElement("div");
|
|
148
148
|
container.className = "veo-guide-content";
|
|
149
|
+
const blocks = normalizeBlocks(step);
|
|
150
|
+
if (blocks) {
|
|
151
|
+
renderBlocks(container, blocks, doc, callbacks);
|
|
152
|
+
} else {
|
|
153
|
+
renderLegacyStep(container, step, doc, callbacks);
|
|
154
|
+
}
|
|
155
|
+
container.appendChild(createCloseButton(doc, () => callbacks.onDismiss()));
|
|
156
|
+
return container;
|
|
157
|
+
}
|
|
158
|
+
function renderLegacyStep(container, step, doc, callbacks) {
|
|
149
159
|
if (typeof step.imageUrl === "string" && step.imageUrl && isSafeUrl(step.imageUrl)) {
|
|
150
160
|
const img = doc.createElement("img");
|
|
151
161
|
img.className = "veo-guide-image";
|
|
@@ -180,8 +190,110 @@ function buildStepContent(step, doc, callbacks) {
|
|
|
180
190
|
actions.appendChild(cta);
|
|
181
191
|
}
|
|
182
192
|
container.appendChild(actions);
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
}
|
|
194
|
+
function normalizeBlocks(step) {
|
|
195
|
+
if (!Array.isArray(step.blocks) || step.blocks.length === 0) return null;
|
|
196
|
+
const valid = step.blocks.filter((b) => {
|
|
197
|
+
if (!b || typeof b !== "object") return false;
|
|
198
|
+
if (b.type === "image") return typeof b.url === "string" && isSafeUrl(b.url);
|
|
199
|
+
return b.type === "title" || b.type === "text" || b.type === "button";
|
|
200
|
+
});
|
|
201
|
+
return valid.length > 0 ? valid : null;
|
|
202
|
+
}
|
|
203
|
+
function renderBlocks(container, blocks, doc, callbacks) {
|
|
204
|
+
let i = 0;
|
|
205
|
+
while (i < blocks.length) {
|
|
206
|
+
const block = blocks[i];
|
|
207
|
+
if (block?.type === "button") {
|
|
208
|
+
const actions = doc.createElement("div");
|
|
209
|
+
actions.className = "veo-guide-actions";
|
|
210
|
+
while (i < blocks.length && blocks[i]?.type === "button") {
|
|
211
|
+
const btnBlock = blocks[i];
|
|
212
|
+
actions.appendChild(buildButtonBlock(btnBlock, doc, callbacks));
|
|
213
|
+
i++;
|
|
214
|
+
}
|
|
215
|
+
container.appendChild(actions);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const node = buildContentBlock(block, doc);
|
|
219
|
+
if (node) container.appendChild(node);
|
|
220
|
+
i++;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function buildContentBlock(block, doc) {
|
|
224
|
+
switch (block.type) {
|
|
225
|
+
case "title": {
|
|
226
|
+
const el = doc.createElement("h2");
|
|
227
|
+
el.className = "veo-guide-title";
|
|
228
|
+
el.textContent = typeof block.text === "string" ? block.text : "";
|
|
229
|
+
applyBlockStyle(el, block.style, "text");
|
|
230
|
+
return el;
|
|
231
|
+
}
|
|
232
|
+
case "text": {
|
|
233
|
+
const el = doc.createElement("p");
|
|
234
|
+
el.className = "veo-guide-text";
|
|
235
|
+
el.textContent = typeof block.text === "string" ? block.text : "";
|
|
236
|
+
applyBlockStyle(el, block.style, "text");
|
|
237
|
+
return el;
|
|
238
|
+
}
|
|
239
|
+
case "image": {
|
|
240
|
+
if (typeof block.url !== "string" || !isSafeUrl(block.url)) return null;
|
|
241
|
+
const el = doc.createElement("img");
|
|
242
|
+
el.className = "veo-guide-image";
|
|
243
|
+
el.src = block.url;
|
|
244
|
+
el.alt = "";
|
|
245
|
+
applyBlockStyle(el, block.style, "image");
|
|
246
|
+
return el;
|
|
247
|
+
}
|
|
248
|
+
default:
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function buildButtonBlock(block, doc, callbacks) {
|
|
253
|
+
const btn = doc.createElement("button");
|
|
254
|
+
btn.type = "button";
|
|
255
|
+
btn.className = "veo-guide-cta";
|
|
256
|
+
btn.textContent = typeof block.text === "string" && block.text ? block.text : "OK";
|
|
257
|
+
applyBlockStyle(btn, block.style, "button");
|
|
258
|
+
btn.addEventListener("click", () => {
|
|
259
|
+
const action = block.action ?? "dismiss";
|
|
260
|
+
const url = action === "url" && typeof block.url === "string" && isSafeUrl(block.url) ? block.url : void 0;
|
|
261
|
+
callbacks.onCtaClick(action, url);
|
|
262
|
+
});
|
|
263
|
+
return btn;
|
|
264
|
+
}
|
|
265
|
+
var BLOCK_ALIGN_SELF = {
|
|
266
|
+
left: "flex-start",
|
|
267
|
+
center: "center",
|
|
268
|
+
right: "flex-end"
|
|
269
|
+
};
|
|
270
|
+
function clampNum(n, min, max) {
|
|
271
|
+
return Math.min(max, Math.max(min, n));
|
|
272
|
+
}
|
|
273
|
+
function applyBlockStyle(el, style, kind) {
|
|
274
|
+
if (!style || typeof style !== "object") return;
|
|
275
|
+
const s = style;
|
|
276
|
+
const align = typeof s.align === "string" ? s.align : null;
|
|
277
|
+
if (align && (align === "left" || align === "center" || align === "right")) {
|
|
278
|
+
if (kind === "text") el.style.textAlign = align;
|
|
279
|
+
else el.style.alignSelf = BLOCK_ALIGN_SELF[align];
|
|
280
|
+
}
|
|
281
|
+
if (kind !== "image" && typeof s.color === "string") el.style.color = s.color;
|
|
282
|
+
if (kind === "text" && typeof s.fontSize === "number" && Number.isFinite(s.fontSize)) {
|
|
283
|
+
el.style.fontSize = `${clampNum(s.fontSize, 8, 72)}px`;
|
|
284
|
+
}
|
|
285
|
+
if (kind === "image" && typeof s.width === "number" && Number.isFinite(s.width)) {
|
|
286
|
+
el.style.width = `${clampNum(s.width, 10, 100)}%`;
|
|
287
|
+
}
|
|
288
|
+
if (kind === "image" && typeof s.radius === "number" && Number.isFinite(s.radius)) {
|
|
289
|
+
el.style.borderRadius = `${clampNum(s.radius, 0, 48)}px`;
|
|
290
|
+
}
|
|
291
|
+
if (typeof s.marginTop === "number" && Number.isFinite(s.marginTop)) {
|
|
292
|
+
el.style.marginTop = `${clampNum(s.marginTop, 0, 64)}px`;
|
|
293
|
+
}
|
|
294
|
+
if (typeof s.marginBottom === "number" && Number.isFinite(s.marginBottom)) {
|
|
295
|
+
el.style.marginBottom = `${clampNum(s.marginBottom, 0, 64)}px`;
|
|
296
|
+
}
|
|
185
297
|
}
|
|
186
298
|
function createCloseButton(doc, onClose, className = "veo-guide-close") {
|
|
187
299
|
const closeBtn = doc.createElement("button");
|
|
@@ -208,6 +320,78 @@ function readCtaUrl(step) {
|
|
|
208
320
|
return isSafeUrl(candidate) ? candidate : void 0;
|
|
209
321
|
}
|
|
210
322
|
|
|
323
|
+
// src/plugins/guides/walkthrough-block-builder.ts
|
|
324
|
+
function buildWalkthroughStepContent(step, stepIndex, totalSteps, doc, callbacks) {
|
|
325
|
+
const container = doc.createElement("div");
|
|
326
|
+
container.className = "veo-guide-content";
|
|
327
|
+
const counter = doc.createElement("div");
|
|
328
|
+
counter.className = "veo-walkthrough-counter";
|
|
329
|
+
counter.textContent = `Paso ${stepIndex + 1} de ${totalSteps}`;
|
|
330
|
+
container.appendChild(counter);
|
|
331
|
+
const progress = doc.createElement("div");
|
|
332
|
+
progress.className = "veo-walkthrough-progress";
|
|
333
|
+
for (let i = 0; i < totalSteps; i++) {
|
|
334
|
+
const dot = doc.createElement("span");
|
|
335
|
+
dot.className = "veo-walkthrough-progress-dot";
|
|
336
|
+
if (i < stepIndex) dot.classList.add("completed");
|
|
337
|
+
if (i === stepIndex) dot.classList.add("active");
|
|
338
|
+
progress.appendChild(dot);
|
|
339
|
+
}
|
|
340
|
+
container.appendChild(progress);
|
|
341
|
+
if (typeof step.imageUrl === "string" && step.imageUrl && isSafeUrl(step.imageUrl)) {
|
|
342
|
+
const img = doc.createElement("img");
|
|
343
|
+
img.className = "veo-guide-image";
|
|
344
|
+
img.src = step.imageUrl;
|
|
345
|
+
img.alt = typeof step.title === "string" ? step.title : "";
|
|
346
|
+
container.appendChild(img);
|
|
347
|
+
}
|
|
348
|
+
if (typeof step.title === "string" && step.title) {
|
|
349
|
+
const heading = doc.createElement("h2");
|
|
350
|
+
heading.className = "veo-guide-title";
|
|
351
|
+
heading.textContent = step.title;
|
|
352
|
+
container.appendChild(heading);
|
|
353
|
+
}
|
|
354
|
+
if (typeof step.content === "string" && step.content) {
|
|
355
|
+
const paragraph = doc.createElement("p");
|
|
356
|
+
paragraph.className = "veo-guide-text";
|
|
357
|
+
paragraph.textContent = step.content;
|
|
358
|
+
container.appendChild(paragraph);
|
|
359
|
+
}
|
|
360
|
+
const actions = doc.createElement("div");
|
|
361
|
+
actions.className = "veo-walkthrough-actions";
|
|
362
|
+
const skipBtn = doc.createElement("button");
|
|
363
|
+
skipBtn.type = "button";
|
|
364
|
+
skipBtn.className = "veo-walkthrough-skip";
|
|
365
|
+
skipBtn.textContent = "Omitir";
|
|
366
|
+
skipBtn.addEventListener("click", () => callbacks.onSkip());
|
|
367
|
+
actions.appendChild(skipBtn);
|
|
368
|
+
const rightGroup = doc.createElement("div");
|
|
369
|
+
rightGroup.className = "veo-walkthrough-actions-right";
|
|
370
|
+
if (stepIndex > 0) {
|
|
371
|
+
const backBtn = doc.createElement("button");
|
|
372
|
+
backBtn.type = "button";
|
|
373
|
+
backBtn.className = "veo-walkthrough-btn-secondary";
|
|
374
|
+
backBtn.textContent = "Atr\xE1s";
|
|
375
|
+
backBtn.addEventListener("click", () => callbacks.onBack());
|
|
376
|
+
rightGroup.appendChild(backBtn);
|
|
377
|
+
}
|
|
378
|
+
const isLastStep = stepIndex === totalSteps - 1;
|
|
379
|
+
const primaryBtn = doc.createElement("button");
|
|
380
|
+
primaryBtn.type = "button";
|
|
381
|
+
primaryBtn.className = "veo-guide-cta";
|
|
382
|
+
const defaultLabel = isLastStep ? "Finalizar" : "Siguiente";
|
|
383
|
+
primaryBtn.textContent = typeof step.ctaText === "string" && step.ctaText ? step.ctaText : defaultLabel;
|
|
384
|
+
primaryBtn.addEventListener("click", () => {
|
|
385
|
+
if (isLastStep) callbacks.onComplete();
|
|
386
|
+
else callbacks.onNext();
|
|
387
|
+
});
|
|
388
|
+
rightGroup.appendChild(primaryBtn);
|
|
389
|
+
actions.appendChild(rightGroup);
|
|
390
|
+
container.appendChild(actions);
|
|
391
|
+
container.appendChild(createCloseButton(doc, () => callbacks.onSkip()));
|
|
392
|
+
return container;
|
|
393
|
+
}
|
|
394
|
+
|
|
211
395
|
// src/plugins/guides/guide-design.ts
|
|
212
396
|
var DARK_THEME = {
|
|
213
397
|
"--veo-bg": "#1f2937",
|
|
@@ -257,6 +441,9 @@ function applyDesignVars(host, style) {
|
|
|
257
441
|
if (typeof s.accentColor === "string" && COLOR_RE.test(s.accentColor.trim())) {
|
|
258
442
|
host.style.setProperty("--veo-primary", s.accentColor.trim());
|
|
259
443
|
}
|
|
444
|
+
if (typeof s.fontFamily === "string" && s.fontFamily.length <= 200 && !/[<>{}]/.test(s.fontFamily)) {
|
|
445
|
+
host.style.setProperty("--veo-font", s.fontFamily.trim());
|
|
446
|
+
}
|
|
260
447
|
if (s.theme === "dark") {
|
|
261
448
|
for (const [key, value] of Object.entries(DARK_THEME)) {
|
|
262
449
|
host.style.setProperty(key, value);
|
|
@@ -350,7 +537,7 @@ var GUIDE_STYLES = `
|
|
|
350
537
|
--veo-actions-justify: flex-end;
|
|
351
538
|
all: initial;
|
|
352
539
|
}
|
|
353
|
-
* { box-sizing: border-box; font-family: -apple-system, system-ui, "Segoe UI", Roboto, sans-serif; }
|
|
540
|
+
* { box-sizing: border-box; font-family: var(--veo-font, -apple-system, system-ui, "Segoe UI", Roboto, sans-serif); }
|
|
354
541
|
|
|
355
542
|
.veo-modal-overlay {
|
|
356
543
|
position: fixed; inset: 0;
|
|
@@ -681,7 +868,8 @@ var BaseRenderer = class {
|
|
|
681
868
|
// src/plugins/guides/renderers/banner-renderer.ts
|
|
682
869
|
var BannerRenderer = class extends BaseRenderer {
|
|
683
870
|
render(context) {
|
|
684
|
-
const
|
|
871
|
+
const idx = context.nav?.stepIndex ?? 0;
|
|
872
|
+
const step = context.guide.guideSteps[idx];
|
|
685
873
|
if (!step) return;
|
|
686
874
|
const { root } = this.createHost();
|
|
687
875
|
this.applyDesign(step.style);
|
|
@@ -690,27 +878,25 @@ var BannerRenderer = class extends BaseRenderer {
|
|
|
690
878
|
const banner = ownerDocument.createElement("div");
|
|
691
879
|
banner.className = `veo-banner veo-banner-${position}`;
|
|
692
880
|
const dismiss = (action, ctaUrl) => {
|
|
693
|
-
context.onInteraction({
|
|
694
|
-
guideId: context.guide.guideId,
|
|
695
|
-
stepIndex: 0,
|
|
696
|
-
action
|
|
697
|
-
});
|
|
881
|
+
context.onInteraction({ guideId: context.guide.guideId, stepIndex: idx, action });
|
|
698
882
|
if (ctaUrl) window.open(ctaUrl, "_blank", "noopener,noreferrer");
|
|
699
883
|
context.onClose();
|
|
700
884
|
};
|
|
701
|
-
const content =
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
885
|
+
const content = context.nav ? buildWalkthroughStepContent(
|
|
886
|
+
step,
|
|
887
|
+
context.nav.stepIndex,
|
|
888
|
+
context.nav.totalSteps,
|
|
889
|
+
ownerDocument,
|
|
890
|
+
context.nav.callbacks
|
|
891
|
+
) : buildStepContent(step, ownerDocument, {
|
|
892
|
+
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
705
893
|
onDismiss: () => dismiss("dismissed")
|
|
706
894
|
});
|
|
707
895
|
banner.appendChild(content);
|
|
708
896
|
root.appendChild(banner);
|
|
709
|
-
context.
|
|
710
|
-
guideId: context.guide.guideId,
|
|
711
|
-
|
|
712
|
-
action: "shown"
|
|
713
|
-
});
|
|
897
|
+
if (!context.nav) {
|
|
898
|
+
context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
|
|
899
|
+
}
|
|
714
900
|
}
|
|
715
901
|
};
|
|
716
902
|
|
|
@@ -1390,7 +1576,8 @@ var InlineRenderer = class extends BaseRenderer {
|
|
|
1390
1576
|
// src/plugins/guides/renderers/modal-renderer.ts
|
|
1391
1577
|
var ModalRenderer = class extends BaseRenderer {
|
|
1392
1578
|
render(context) {
|
|
1393
|
-
const
|
|
1579
|
+
const idx = context.nav?.stepIndex ?? 0;
|
|
1580
|
+
const step = context.guide.guideSteps[idx];
|
|
1394
1581
|
if (!step) return;
|
|
1395
1582
|
const { root } = this.createHost();
|
|
1396
1583
|
this.applyDesign(step.style);
|
|
@@ -1400,36 +1587,38 @@ var ModalRenderer = class extends BaseRenderer {
|
|
|
1400
1587
|
const card = ownerDocument.createElement("div");
|
|
1401
1588
|
card.className = "veo-modal-card";
|
|
1402
1589
|
const dismiss = (action, ctaUrl) => {
|
|
1403
|
-
context.onInteraction({
|
|
1404
|
-
guideId: context.guide.guideId,
|
|
1405
|
-
stepIndex: 0,
|
|
1406
|
-
action
|
|
1407
|
-
});
|
|
1590
|
+
context.onInteraction({ guideId: context.guide.guideId, stepIndex: idx, action });
|
|
1408
1591
|
if (ctaUrl) window.open(ctaUrl, "_blank", "noopener,noreferrer");
|
|
1409
1592
|
context.onClose();
|
|
1410
1593
|
};
|
|
1411
|
-
const
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1594
|
+
const onBackdropOrEsc = () => {
|
|
1595
|
+
if (context.nav) context.nav.callbacks.onSkip();
|
|
1596
|
+
else dismiss("dismissed");
|
|
1597
|
+
};
|
|
1598
|
+
const content = context.nav ? buildWalkthroughStepContent(
|
|
1599
|
+
step,
|
|
1600
|
+
context.nav.stepIndex,
|
|
1601
|
+
context.nav.totalSteps,
|
|
1602
|
+
ownerDocument,
|
|
1603
|
+
context.nav.callbacks
|
|
1604
|
+
) : buildStepContent(step, ownerDocument, {
|
|
1605
|
+
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
1415
1606
|
onDismiss: () => dismiss("dismissed")
|
|
1416
1607
|
});
|
|
1417
1608
|
card.appendChild(content);
|
|
1418
1609
|
overlay.appendChild(card);
|
|
1419
1610
|
root.appendChild(overlay);
|
|
1420
1611
|
overlay.addEventListener("click", (e) => {
|
|
1421
|
-
if (e.target === overlay)
|
|
1612
|
+
if (e.target === overlay) onBackdropOrEsc();
|
|
1422
1613
|
});
|
|
1423
1614
|
const onKey = (e) => {
|
|
1424
|
-
if (e.key === "Escape")
|
|
1615
|
+
if (e.key === "Escape") onBackdropOrEsc();
|
|
1425
1616
|
};
|
|
1426
1617
|
document.addEventListener("keydown", onKey);
|
|
1427
1618
|
this.registerCleanup(() => document.removeEventListener("keydown", onKey));
|
|
1428
|
-
context.
|
|
1429
|
-
guideId: context.guide.guideId,
|
|
1430
|
-
|
|
1431
|
-
action: "shown"
|
|
1432
|
-
});
|
|
1619
|
+
if (!context.nav) {
|
|
1620
|
+
context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
|
|
1621
|
+
}
|
|
1433
1622
|
}
|
|
1434
1623
|
};
|
|
1435
1624
|
|
|
@@ -1510,80 +1699,6 @@ var TooltipRenderer = class extends BaseRenderer {
|
|
|
1510
1699
|
});
|
|
1511
1700
|
}
|
|
1512
1701
|
};
|
|
1513
|
-
|
|
1514
|
-
// src/plugins/guides/walkthrough-block-builder.ts
|
|
1515
|
-
function buildWalkthroughStepContent(step, stepIndex, totalSteps, doc, callbacks) {
|
|
1516
|
-
const container = doc.createElement("div");
|
|
1517
|
-
container.className = "veo-guide-content";
|
|
1518
|
-
const counter = doc.createElement("div");
|
|
1519
|
-
counter.className = "veo-walkthrough-counter";
|
|
1520
|
-
counter.textContent = `Paso ${stepIndex + 1} de ${totalSteps}`;
|
|
1521
|
-
container.appendChild(counter);
|
|
1522
|
-
const progress = doc.createElement("div");
|
|
1523
|
-
progress.className = "veo-walkthrough-progress";
|
|
1524
|
-
for (let i = 0; i < totalSteps; i++) {
|
|
1525
|
-
const dot = doc.createElement("span");
|
|
1526
|
-
dot.className = "veo-walkthrough-progress-dot";
|
|
1527
|
-
if (i < stepIndex) dot.classList.add("completed");
|
|
1528
|
-
if (i === stepIndex) dot.classList.add("active");
|
|
1529
|
-
progress.appendChild(dot);
|
|
1530
|
-
}
|
|
1531
|
-
container.appendChild(progress);
|
|
1532
|
-
if (typeof step.imageUrl === "string" && step.imageUrl && isSafeUrl(step.imageUrl)) {
|
|
1533
|
-
const img = doc.createElement("img");
|
|
1534
|
-
img.className = "veo-guide-image";
|
|
1535
|
-
img.src = step.imageUrl;
|
|
1536
|
-
img.alt = typeof step.title === "string" ? step.title : "";
|
|
1537
|
-
container.appendChild(img);
|
|
1538
|
-
}
|
|
1539
|
-
if (typeof step.title === "string" && step.title) {
|
|
1540
|
-
const heading = doc.createElement("h2");
|
|
1541
|
-
heading.className = "veo-guide-title";
|
|
1542
|
-
heading.textContent = step.title;
|
|
1543
|
-
container.appendChild(heading);
|
|
1544
|
-
}
|
|
1545
|
-
if (typeof step.content === "string" && step.content) {
|
|
1546
|
-
const paragraph = doc.createElement("p");
|
|
1547
|
-
paragraph.className = "veo-guide-text";
|
|
1548
|
-
paragraph.textContent = step.content;
|
|
1549
|
-
container.appendChild(paragraph);
|
|
1550
|
-
}
|
|
1551
|
-
const actions = doc.createElement("div");
|
|
1552
|
-
actions.className = "veo-walkthrough-actions";
|
|
1553
|
-
const skipBtn = doc.createElement("button");
|
|
1554
|
-
skipBtn.type = "button";
|
|
1555
|
-
skipBtn.className = "veo-walkthrough-skip";
|
|
1556
|
-
skipBtn.textContent = "Omitir";
|
|
1557
|
-
skipBtn.addEventListener("click", () => callbacks.onSkip());
|
|
1558
|
-
actions.appendChild(skipBtn);
|
|
1559
|
-
const rightGroup = doc.createElement("div");
|
|
1560
|
-
rightGroup.className = "veo-walkthrough-actions-right";
|
|
1561
|
-
if (stepIndex > 0) {
|
|
1562
|
-
const backBtn = doc.createElement("button");
|
|
1563
|
-
backBtn.type = "button";
|
|
1564
|
-
backBtn.className = "veo-walkthrough-btn-secondary";
|
|
1565
|
-
backBtn.textContent = "Atr\xE1s";
|
|
1566
|
-
backBtn.addEventListener("click", () => callbacks.onBack());
|
|
1567
|
-
rightGroup.appendChild(backBtn);
|
|
1568
|
-
}
|
|
1569
|
-
const isLastStep = stepIndex === totalSteps - 1;
|
|
1570
|
-
const primaryBtn = doc.createElement("button");
|
|
1571
|
-
primaryBtn.type = "button";
|
|
1572
|
-
primaryBtn.className = "veo-guide-cta";
|
|
1573
|
-
const defaultLabel = isLastStep ? "Finalizar" : "Siguiente";
|
|
1574
|
-
primaryBtn.textContent = typeof step.ctaText === "string" && step.ctaText ? step.ctaText : defaultLabel;
|
|
1575
|
-
primaryBtn.addEventListener("click", () => {
|
|
1576
|
-
if (isLastStep) callbacks.onComplete();
|
|
1577
|
-
else callbacks.onNext();
|
|
1578
|
-
});
|
|
1579
|
-
rightGroup.appendChild(primaryBtn);
|
|
1580
|
-
actions.appendChild(rightGroup);
|
|
1581
|
-
container.appendChild(actions);
|
|
1582
|
-
container.appendChild(createCloseButton(doc, () => callbacks.onSkip()));
|
|
1583
|
-
return container;
|
|
1584
|
-
}
|
|
1585
|
-
|
|
1586
|
-
// src/plugins/guides/renderers/walkthrough-renderer.ts
|
|
1587
1702
|
var WalkthroughRenderer = class extends BaseRenderer {
|
|
1588
1703
|
async render(context) {
|
|
1589
1704
|
const step = context.guide.guideSteps[context.currentStepIndex];
|
|
@@ -1637,6 +1752,7 @@ var PREVIEW_GUIDE_ID = "__veo_preview__";
|
|
|
1637
1752
|
var GuidePreviewController = class {
|
|
1638
1753
|
constructor() {
|
|
1639
1754
|
this.singleStep = null;
|
|
1755
|
+
/** Renderer del paso de walkthrough activo (walkthrough tooltip o modal/banner). */
|
|
1640
1756
|
this.walkthrough = null;
|
|
1641
1757
|
this.walkthroughGuide = null;
|
|
1642
1758
|
this.walkthroughIndex = 0;
|
|
@@ -1709,7 +1825,6 @@ var GuidePreviewController = class {
|
|
|
1709
1825
|
safeDestroy(this.walkthrough);
|
|
1710
1826
|
this.walkthrough = null;
|
|
1711
1827
|
}
|
|
1712
|
-
const renderer = new WalkthroughRenderer();
|
|
1713
1828
|
const callbacks = {
|
|
1714
1829
|
onNext: () => {
|
|
1715
1830
|
const next = this.walkthroughIndex + 1;
|
|
@@ -1729,6 +1844,30 @@ var GuidePreviewController = class {
|
|
|
1729
1844
|
onSkip: () => this.close(),
|
|
1730
1845
|
onComplete: () => this.close()
|
|
1731
1846
|
};
|
|
1847
|
+
const step = guide.guideSteps[index];
|
|
1848
|
+
const render = step?.style?.render;
|
|
1849
|
+
if (render === "modal" || render === "banner") {
|
|
1850
|
+
const renderer2 = render === "modal" ? new ModalRenderer() : new BannerRenderer();
|
|
1851
|
+
try {
|
|
1852
|
+
renderer2.render({
|
|
1853
|
+
guide,
|
|
1854
|
+
onInteraction: () => {
|
|
1855
|
+
},
|
|
1856
|
+
onClose: () => this.close(),
|
|
1857
|
+
nav: { stepIndex: index, totalSteps: guide.guideSteps.length, callbacks }
|
|
1858
|
+
});
|
|
1859
|
+
} catch {
|
|
1860
|
+
safeDestroy(renderer2);
|
|
1861
|
+
return false;
|
|
1862
|
+
}
|
|
1863
|
+
if (this.walkthroughGuide !== guide) {
|
|
1864
|
+
safeDestroy(renderer2);
|
|
1865
|
+
return false;
|
|
1866
|
+
}
|
|
1867
|
+
this.walkthrough = renderer2;
|
|
1868
|
+
return true;
|
|
1869
|
+
}
|
|
1870
|
+
const renderer = new WalkthroughRenderer();
|
|
1732
1871
|
let success = false;
|
|
1733
1872
|
try {
|
|
1734
1873
|
success = await renderer.render({ guide, currentStepIndex: index, callbacks });
|