veo-sdk 0.3.14 → 0.3.16
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-EQYOMQFY.mjs +5 -0
- package/dist/{builder-4YBB3RSZ.mjs.map → builder-EQYOMQFY.mjs.map} +1 -1
- package/dist/builder.cjs +113 -7
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.mjs +4 -4
- package/dist/{chunk-MPZVVZDL.mjs → chunk-IEHGG5NL.mjs} +4 -4
- package/dist/chunk-IEHGG5NL.mjs.map +1 -0
- package/dist/{chunk-B6S4V5Q5.mjs → chunk-QCIT7CGE.mjs} +4 -4
- package/dist/{chunk-B6S4V5Q5.mjs.map → chunk-QCIT7CGE.mjs.map} +1 -1
- package/dist/{chunk-3WJDFE7Q.mjs → chunk-YHUPUTWH.mjs} +114 -8
- package/dist/chunk-YHUPUTWH.mjs.map +1 -0
- package/dist/index.cjs +114 -8
- 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/index.mjs.map +1 -1
- package/dist/veo-builder.js +23 -5
- package/dist/veo-builder.js.map +1 -1
- package/dist/veo-guides.js +22 -4
- package/dist/veo-guides.js.map +1 -1
- package/dist/veo.js.map +1 -1
- package/package.json +1 -1
- package/dist/builder-4YBB3RSZ.mjs +0 -5
- package/dist/chunk-3WJDFE7Q.mjs.map +0 -1
- package/dist/chunk-MPZVVZDL.mjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -944,6 +944,24 @@ var init_styles = __esm({
|
|
|
944
944
|
cursor: pointer; color: #9ca3af; padding: 0;
|
|
945
945
|
}
|
|
946
946
|
.veo-guide-close:hover { color: var(--veo-text); }
|
|
947
|
+
/*
|
|
948
|
+
* Si el PRIMER bloque es una imagen, la \u2715 quedar\xEDa sobre la esquina de la foto
|
|
949
|
+
* (invisible seg\xFAn el color). En ese caso pasa a ser una pastilla flotante con
|
|
950
|
+
* fondo propio, legible sobre cualquier imagen. (Sin soporte de :has() queda el
|
|
951
|
+
* estilo base \u2014 mismo comportamiento de antes, sin regresi\xF3n.)
|
|
952
|
+
*/
|
|
953
|
+
.veo-guide-content:has(> .veo-guide-image:first-child) > .veo-guide-close {
|
|
954
|
+
top: 2px; right: 2px;
|
|
955
|
+
display: flex; align-items: center; justify-content: center;
|
|
956
|
+
font-size: 16px; color: #374151;
|
|
957
|
+
background: rgba(255, 255, 255, 0.92);
|
|
958
|
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
959
|
+
border-radius: 50%;
|
|
960
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
|
|
961
|
+
}
|
|
962
|
+
.veo-guide-content:has(> .veo-guide-image:first-child) > .veo-guide-close:hover {
|
|
963
|
+
color: #111827;
|
|
964
|
+
}
|
|
947
965
|
|
|
948
966
|
.veo-form { display: flex; flex-direction: column; gap: 14px; margin-bottom: 16px; }
|
|
949
967
|
.veo-form-field { display: flex; flex-direction: column; gap: 6px; }
|
|
@@ -1096,6 +1114,37 @@ var init_base_renderer = __esm({
|
|
|
1096
1114
|
this.host = null;
|
|
1097
1115
|
this.shadow = null;
|
|
1098
1116
|
this.cleanups = [];
|
|
1117
|
+
// ── Update in-place (preview en vivo del editor) ──
|
|
1118
|
+
// La subclase setea estas piezas en render() para habilitarlo: el contenedor
|
|
1119
|
+
// del contenido, el nodo de contenido actual y cómo reconstruirlo.
|
|
1120
|
+
this.liveContainer = null;
|
|
1121
|
+
this.liveContent = null;
|
|
1122
|
+
this.liveBuild = null;
|
|
1123
|
+
/** Clave de anclaje/estructura fijada en render(); si cambia → remontar. */
|
|
1124
|
+
this.liveKey = "";
|
|
1125
|
+
}
|
|
1126
|
+
/** Clave de anclaje derivada del step (override por subclase). */
|
|
1127
|
+
liveKeyOf(_step) {
|
|
1128
|
+
return "";
|
|
1129
|
+
}
|
|
1130
|
+
/** Hook post-swap (reposicionar tooltip, actualizar clase del banner…). */
|
|
1131
|
+
onLiveUpdate(_step) {
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Actualiza el contenido del step SIN remontar el host — así el preview del
|
|
1135
|
+
* editor no parpadea en cada tecla. Devuelve `false` cuando el renderer no
|
|
1136
|
+
* lo soporta o el cambio requiere remontar (cambió el ancla/estructura);
|
|
1137
|
+
* en ese caso el caller hace el re-render completo.
|
|
1138
|
+
*/
|
|
1139
|
+
updateStep(step) {
|
|
1140
|
+
if (!this.host || !this.liveContainer || !this.liveContent || !this.liveBuild) return false;
|
|
1141
|
+
if (this.liveKeyOf(step) !== this.liveKey) return false;
|
|
1142
|
+
const next = this.liveBuild(step);
|
|
1143
|
+
this.liveContainer.replaceChild(next, this.liveContent);
|
|
1144
|
+
this.liveContent = next;
|
|
1145
|
+
this.applyDesign(step.style);
|
|
1146
|
+
this.onLiveUpdate(step);
|
|
1147
|
+
return true;
|
|
1099
1148
|
}
|
|
1100
1149
|
/**
|
|
1101
1150
|
* Crea un `<div data-veo-guide>` adjunto a `document.body`, le adjunta
|
|
@@ -1186,9 +1235,21 @@ var init_banner_renderer = __esm({
|
|
|
1186
1235
|
banner.appendChild(content);
|
|
1187
1236
|
root.appendChild(banner);
|
|
1188
1237
|
if (!context.nav) {
|
|
1238
|
+
this.liveContainer = banner;
|
|
1239
|
+
this.liveContent = content;
|
|
1240
|
+
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
1241
|
+
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
1242
|
+
onDismiss: () => dismiss("dismissed")
|
|
1243
|
+
});
|
|
1189
1244
|
context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
|
|
1190
1245
|
}
|
|
1191
1246
|
}
|
|
1247
|
+
onLiveUpdate(step) {
|
|
1248
|
+
if (this.liveContainer) {
|
|
1249
|
+
const position = step.style?.position === "bottom" ? "bottom" : "top";
|
|
1250
|
+
this.liveContainer.className = `veo-banner veo-banner-${position}`;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1192
1253
|
};
|
|
1193
1254
|
}
|
|
1194
1255
|
});
|
|
@@ -1508,7 +1569,7 @@ function mountFormContent(card, context, doc) {
|
|
|
1508
1569
|
const empty = value === void 0 || value === null || value === "";
|
|
1509
1570
|
if (empty) {
|
|
1510
1571
|
if (field.required) {
|
|
1511
|
-
error.textContent = `
|
|
1572
|
+
error.textContent = `Completa "${field.label}"`;
|
|
1512
1573
|
error.style.display = "block";
|
|
1513
1574
|
return;
|
|
1514
1575
|
}
|
|
@@ -1517,7 +1578,7 @@ function mountFormContent(card, context, doc) {
|
|
|
1517
1578
|
answers[field.key] = value;
|
|
1518
1579
|
}
|
|
1519
1580
|
if (Object.keys(answers).length === 0) {
|
|
1520
|
-
error.textContent = "
|
|
1581
|
+
error.textContent = "Responde al menos un campo";
|
|
1521
1582
|
error.style.display = "block";
|
|
1522
1583
|
return;
|
|
1523
1584
|
}
|
|
@@ -1526,7 +1587,7 @@ function mountFormContent(card, context, doc) {
|
|
|
1526
1587
|
void submitFn(answers).then((ok) => {
|
|
1527
1588
|
if (!ok) {
|
|
1528
1589
|
submit.disabled = false;
|
|
1529
|
-
error.textContent = "No se pudo enviar.
|
|
1590
|
+
error.textContent = "No se pudo enviar. Prueba de nuevo.";
|
|
1530
1591
|
error.style.display = "block";
|
|
1531
1592
|
return;
|
|
1532
1593
|
}
|
|
@@ -1585,7 +1646,7 @@ function buildField(field, doc) {
|
|
|
1585
1646
|
select.className = "veo-form-input";
|
|
1586
1647
|
const blank = doc.createElement("option");
|
|
1587
1648
|
blank.value = "";
|
|
1588
|
-
blank.textContent = field.placeholder || "
|
|
1649
|
+
blank.textContent = field.placeholder || "Elige una opci\xF3n\u2026";
|
|
1589
1650
|
select.appendChild(blank);
|
|
1590
1651
|
for (const opt of field.options ?? []) {
|
|
1591
1652
|
const option = doc.createElement("option");
|
|
@@ -1900,8 +1961,18 @@ var init_inline_renderer = __esm({
|
|
|
1900
1961
|
});
|
|
1901
1962
|
card.appendChild(content);
|
|
1902
1963
|
root.appendChild(card);
|
|
1964
|
+
this.liveContainer = card;
|
|
1965
|
+
this.liveContent = content;
|
|
1966
|
+
this.liveKey = `${selector}|${position}`;
|
|
1967
|
+
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
1968
|
+
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
1969
|
+
onDismiss: () => dismiss("dismissed")
|
|
1970
|
+
});
|
|
1903
1971
|
context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
|
|
1904
1972
|
}
|
|
1973
|
+
liveKeyOf(step) {
|
|
1974
|
+
return `${step.selector ?? ""}|${readInlinePosition(step.style)}`;
|
|
1975
|
+
}
|
|
1905
1976
|
};
|
|
1906
1977
|
}
|
|
1907
1978
|
});
|
|
@@ -1947,6 +2018,14 @@ var init_modal_renderer = __esm({
|
|
|
1947
2018
|
card.appendChild(content);
|
|
1948
2019
|
overlay.appendChild(card);
|
|
1949
2020
|
root.appendChild(overlay);
|
|
2021
|
+
if (!context.nav) {
|
|
2022
|
+
this.liveContainer = card;
|
|
2023
|
+
this.liveContent = content;
|
|
2024
|
+
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
2025
|
+
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
2026
|
+
onDismiss: () => dismiss("dismissed")
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
1950
2029
|
overlay.addEventListener("click", (e) => {
|
|
1951
2030
|
if (e.target === overlay) onBackdropOrEsc();
|
|
1952
2031
|
});
|
|
@@ -1992,6 +2071,12 @@ var init_tooltip_renderer = __esm({
|
|
|
1992
2071
|
init_base_renderer();
|
|
1993
2072
|
init_floating_arrow();
|
|
1994
2073
|
TooltipRenderer = class extends BaseRenderer {
|
|
2074
|
+
constructor() {
|
|
2075
|
+
super(...arguments);
|
|
2076
|
+
/** Lado preferido (mutable: el update in-place puede cambiarlo). */
|
|
2077
|
+
this.side = "bottom";
|
|
2078
|
+
this.reposition = null;
|
|
2079
|
+
}
|
|
1995
2080
|
async render(context) {
|
|
1996
2081
|
const step = context.guide.guideSteps[0];
|
|
1997
2082
|
if (!step) return;
|
|
@@ -2000,7 +2085,7 @@ var init_tooltip_renderer = __esm({
|
|
|
2000
2085
|
const anchor = await waitForElement(selector);
|
|
2001
2086
|
if (!anchor) return;
|
|
2002
2087
|
const rawSide = step.style?.tooltipPlacement;
|
|
2003
|
-
|
|
2088
|
+
this.side = rawSide === "top" || rawSide === "left" || rawSide === "right" ? rawSide : "bottom";
|
|
2004
2089
|
const { root } = this.createHost();
|
|
2005
2090
|
this.applyDesign(step.style);
|
|
2006
2091
|
const ownerDocument = root.ownerDocument ?? document;
|
|
@@ -2028,7 +2113,7 @@ var init_tooltip_renderer = __esm({
|
|
|
2028
2113
|
root.appendChild(tooltip);
|
|
2029
2114
|
const updatePosition = async () => {
|
|
2030
2115
|
const { x, y, placement, middlewareData } = await dom.computePosition(anchor, tooltip, {
|
|
2031
|
-
placement: side,
|
|
2116
|
+
placement: this.side,
|
|
2032
2117
|
middleware: [dom.offset(10), dom.flip(), dom.shift({ padding: 8 }), dom.arrow({ element: arrowEl })]
|
|
2033
2118
|
});
|
|
2034
2119
|
tooltip.style.left = `${x}px`;
|
|
@@ -2039,18 +2124,34 @@ var init_tooltip_renderer = __esm({
|
|
|
2039
2124
|
const reposition = () => {
|
|
2040
2125
|
void updatePosition();
|
|
2041
2126
|
};
|
|
2127
|
+
this.reposition = reposition;
|
|
2042
2128
|
window.addEventListener("scroll", reposition, true);
|
|
2043
2129
|
window.addEventListener("resize", reposition);
|
|
2044
2130
|
this.registerCleanup(() => {
|
|
2045
2131
|
window.removeEventListener("scroll", reposition, true);
|
|
2046
2132
|
window.removeEventListener("resize", reposition);
|
|
2047
2133
|
});
|
|
2134
|
+
this.liveContainer = tooltip;
|
|
2135
|
+
this.liveContent = content;
|
|
2136
|
+
this.liveKey = selector;
|
|
2137
|
+
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
2138
|
+
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
2139
|
+
onDismiss: () => dismiss("dismissed")
|
|
2140
|
+
});
|
|
2048
2141
|
context.onInteraction({
|
|
2049
2142
|
guideId: context.guide.guideId,
|
|
2050
2143
|
stepIndex: 0,
|
|
2051
2144
|
action: "shown"
|
|
2052
2145
|
});
|
|
2053
2146
|
}
|
|
2147
|
+
liveKeyOf(step) {
|
|
2148
|
+
return step.selector ?? "";
|
|
2149
|
+
}
|
|
2150
|
+
onLiveUpdate(step) {
|
|
2151
|
+
const raw = step.style?.tooltipPlacement;
|
|
2152
|
+
this.side = raw === "top" || raw === "left" || raw === "right" ? raw : "bottom";
|
|
2153
|
+
this.reposition?.();
|
|
2154
|
+
}
|
|
2054
2155
|
};
|
|
2055
2156
|
}
|
|
2056
2157
|
});
|
|
@@ -2196,6 +2297,11 @@ var init_guide_preview = __esm({
|
|
|
2196
2297
|
this.input = null;
|
|
2197
2298
|
}
|
|
2198
2299
|
preview(input) {
|
|
2300
|
+
const nextStep = input.guideSteps[0];
|
|
2301
|
+
if (this.singleStep && this.input && input.guideType === this.input.guideType && input.guideType !== "walkthrough" && nextStep && this.singleStep.updateStep(nextStep)) {
|
|
2302
|
+
this.input = input;
|
|
2303
|
+
return { close: () => this.close(), ready: Promise.resolve({ rendered: true }) };
|
|
2304
|
+
}
|
|
2199
2305
|
this.close();
|
|
2200
2306
|
this.input = input;
|
|
2201
2307
|
const guide = normalize(input);
|
|
@@ -2646,7 +2752,7 @@ var init_element_picker = __esm({
|
|
|
2646
2752
|
this.label.style.display = "none";
|
|
2647
2753
|
const hint = document.createElement("div");
|
|
2648
2754
|
hint.className = "veo-pick-hint";
|
|
2649
|
-
hint.textContent = options.hint ?? "
|
|
2755
|
+
hint.textContent = options.hint ?? "Selecciona un elemento \xB7 Esc para cancelar";
|
|
2650
2756
|
shadow.append(style, this.box, this.label, hint);
|
|
2651
2757
|
document.body.appendChild(host);
|
|
2652
2758
|
this.host = host;
|
|
@@ -4021,7 +4127,7 @@ var GuideResolverClient = class {
|
|
|
4021
4127
|
* matchea, pero el walkthrough activo debe poder consultarla igual.
|
|
4022
4128
|
*
|
|
4023
4129
|
* El endpoint backend (`GET /v1/guides/:guideId`) devuelve `GuideResponse`,
|
|
4024
|
-
* un superset de `ResolvedGuide` con campos de audit.
|
|
4130
|
+
* un superset de `ResolvedGuide` con campos de audit. Aquí descartamos los
|
|
4025
4131
|
* extra y nos quedamos con el shape que el resto del SDK ya consume.
|
|
4026
4132
|
*
|
|
4027
4133
|
* Devuelve `null` en cualquier error (404, red, parse) — el caller debe
|