@magicfeedback/popup-sdk 1.4.0 → 1.6.0
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/assets/assets/style.css +1496 -595
- package/dist/chunk-AN7JIVWB.mjs +1965 -0
- package/dist/chunk-AN7JIVWB.mjs.map +1 -0
- package/dist/chunk-Z3LLJMSH.mjs +1944 -0
- package/dist/chunk-Z3LLJMSH.mjs.map +1 -0
- package/dist/index.d.mts +55 -3
- package/dist/index.d.ts +55 -3
- package/dist/index.js +3418 -617
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +226 -53
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +35 -2
- package/dist/react-native.d.ts +35 -2
- package/dist/react-native.js +2229 -140
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +226 -53
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-TCKR5Z3P.mjs → renderPopup-M6MKTDEH.mjs} +1423 -570
- package/dist/renderPopup-M6MKTDEH.mjs.map +1 -0
- package/dist/{renderPopup-UYMGEBSI.mjs → renderPopup-SELXQ3UE.mjs} +232 -91
- package/dist/renderPopup-SELXQ3UE.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-R4B3K2ZW.mjs +0 -176
- package/dist/chunk-R4B3K2ZW.mjs.map +0 -1
- package/dist/chunk-XFA2Y6CK.mjs +0 -197
- package/dist/chunk-XFA2Y6CK.mjs.map +0 -1
- package/dist/renderPopup-TCKR5Z3P.mjs.map +0 -1
- package/dist/renderPopup-UYMGEBSI.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
sdkWarn,
|
|
10
10
|
setLogger,
|
|
11
11
|
style_default
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-AN7JIVWB.mjs";
|
|
13
13
|
|
|
14
14
|
// src/types/index.ts
|
|
15
15
|
var POPUP_TRIGGER_CONDITION_STATUSES = [
|
|
@@ -209,14 +209,17 @@ var POSITION_MAP = {
|
|
|
209
209
|
"top-right": { justifyContent: "flex-end", alignItems: "flex-start", padding: "16px", background: "transparent" },
|
|
210
210
|
"top-left": { justifyContent: "flex-start", alignItems: "flex-start", padding: "16px", background: "transparent" }
|
|
211
211
|
};
|
|
212
|
+
function jsonForScript(value) {
|
|
213
|
+
return JSON.stringify(value ?? null).replace(/</g, "\\u003C").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
214
|
+
}
|
|
212
215
|
function buildSurveyHtml(opts) {
|
|
213
216
|
const env = opts.env === "development" ? "dev" : "prod";
|
|
214
|
-
const version = opts.version ?? "2.2.
|
|
217
|
+
const version = opts.version ?? "2.2.8";
|
|
215
218
|
const cdn = `https://cdn.jsdelivr.net/npm/@magicfeedback/native@${version}/dist/magicfeedback-sdk.browser.js`;
|
|
216
|
-
const sid =
|
|
217
|
-
const pid =
|
|
218
|
-
const profileJson =
|
|
219
|
-
const metaJson =
|
|
219
|
+
const sid = jsonForScript(opts.surveyId);
|
|
220
|
+
const pid = jsonForScript(opts.productId);
|
|
221
|
+
const profileJson = jsonForScript(opts.profile ?? []);
|
|
222
|
+
const metaJson = jsonForScript(opts.metadata ?? []);
|
|
220
223
|
const fontFaceCss = opts.font ? buildFontFaceCss(opts.font.family, opts.font.url) : "";
|
|
221
224
|
const fontFamilyValue = opts.font ? buildFontFamilyValue(opts.font.family) : "-apple-system,system-ui,sans-serif";
|
|
222
225
|
const popupClass = opts.font?.family ? "deepdots-popup deepdots-has-font" : "deepdots-popup";
|
|
@@ -224,6 +227,8 @@ function buildSurveyHtml(opts) {
|
|
|
224
227
|
const popupBg = isDark ? "#1e1e1e" : "#fff";
|
|
225
228
|
const colorScheme = isDark ? "dark" : "light";
|
|
226
229
|
const textPrimary = isDark ? "#f0f0f0" : "#111";
|
|
230
|
+
const textMuted = isDark ? "#9ca3af" : "#6b7280";
|
|
231
|
+
const trackBg = isDark ? "#3f3f46" : "#e5e7eb";
|
|
227
232
|
const pos = POSITION_MAP[opts.position ?? "center"] ?? POSITION_MAP.center;
|
|
228
233
|
const chrome = opts.chrome !== false;
|
|
229
234
|
const bodyBg = chrome ? pos.background : "transparent";
|
|
@@ -235,10 +240,16 @@ function buildSurveyHtml(opts) {
|
|
|
235
240
|
const cardMaxWidth = chrome ? "600px" : "none";
|
|
236
241
|
const cardWidth = chrome ? "90%" : "100%";
|
|
237
242
|
const cardMinHeight = chrome ? "200px" : "0";
|
|
238
|
-
const
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
const
|
|
243
|
+
const cardHeight = chrome ? "auto" : "100%";
|
|
244
|
+
const cardMaxHeight = chrome ? "90vh" : "100%";
|
|
245
|
+
const mobileCard = chrome ? `.deepdots-popup{width:calc(100% - 24px);max-width:calc(100% - 24px);border-radius:12px;padding:calc(16px + env(safe-area-inset-top)) 16px calc(16px + env(safe-area-inset-bottom)) 16px}` : `.deepdots-popup{width:100%;max-width:100%;border-radius:0;padding:16px}`;
|
|
246
|
+
const titleJson = jsonForScript(opts.title ?? "");
|
|
247
|
+
const customCss = (opts.surveyCss ?? "").replace(/<\/\s*style/gi, "<\\/style");
|
|
248
|
+
const progressPref = opts.showProgressBar === void 0 ? "null" : String(opts.showProgressBar);
|
|
249
|
+
const backLabel = jsonForScript(opts.actions?.back?.label ?? "Back");
|
|
250
|
+
const startLabel = jsonForScript(opts.actions?.start?.label ?? "Start survey");
|
|
251
|
+
const completeLabel = jsonForScript(opts.actions?.complete?.label ?? "Complete survey");
|
|
252
|
+
const submitLabel = jsonForScript(opts.actions?.accept?.label ?? "Send");
|
|
242
253
|
return `<!DOCTYPE html><html><head>
|
|
243
254
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
244
255
|
<meta name="color-scheme" content="${colorScheme}"/>
|
|
@@ -247,56 +258,97 @@ ${style_default}
|
|
|
247
258
|
${fontFaceCss}
|
|
248
259
|
html,body{margin:0;padding:0;height:100%;font-family:${fontFamilyValue}}
|
|
249
260
|
body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${pos.alignItems};background:${bodyBg};padding:${bodyPadding};box-sizing:border-box}
|
|
250
|
-
.deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${cardBg};color-scheme:${colorScheme};border-radius:${cardRadius};padding:24px;box-shadow:${cardShadow};max-width:${cardMaxWidth};width:${cardWidth};min-height:${cardMinHeight};box-sizing:border-box}
|
|
251
|
-
.deepdots-popup-header{display:flex;justify-content:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
261
|
+
.deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${cardBg};color-scheme:${colorScheme};border-radius:${cardRadius};padding:24px;box-shadow:${cardShadow};max-width:${cardMaxWidth};width:${cardWidth};min-height:${cardMinHeight};height:${cardHeight};max-height:${cardMaxHeight};box-sizing:border-box}
|
|
262
|
+
.deepdots-popup-header{display:flex;justify-content:space-between;align-items:center;gap:12px;width:100%;flex:0 0 auto}
|
|
263
|
+
/* Neutraliza la regla \`.deepdots-popup h2\` del CSS del survey (uppercase, centrado y
|
|
264
|
+
margin-bottom 40px), pensada para los enunciados y no para el t\xEDtulo de la cabecera. */
|
|
265
|
+
#dd-title{margin:0;font-family:var(--deepdots-font,'Montserrat',inherit);font-size:17px;font-weight:600;line-height:1.3;color:${textPrimary};text-transform:none;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
266
|
+
#dd-close{background:transparent;border:none;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:8px;cursor:pointer;color:${textPrimary};padding:4px;flex:0 0 auto;margin-left:auto}
|
|
267
|
+
/* Progreso alineado con la cabecera: sin padding horizontal propio, lo marca la tarjeta.
|
|
268
|
+
El vertical es el mismo arriba y abajo, y del mismo valor que el padding de la tarjeta. */
|
|
269
|
+
.deepdots-progress{display:none;flex-direction:column;gap:8px;width:100%;flex:0 0 auto;padding:16px 0;box-sizing:border-box}
|
|
270
|
+
.deepdots-progress-head{display:flex;flex-direction:row;justify-content:space-between;align-items:center;width:100%;gap:8px}
|
|
271
|
+
#dd-progress-label{font-size:13px;line-height:1.2}
|
|
272
|
+
/* "Question 1" en negrita y "of 3" en regular gris, como el mockup. */
|
|
273
|
+
#dd-progress-current{font-weight:700;color:${textPrimary}}
|
|
274
|
+
#dd-progress-total{font-weight:400;color:${textMuted}}
|
|
275
|
+
#dd-progress-followup{display:none;font-size:12px;font-weight:600;color:#fff;background:rgba(59,130,246,0.44);border-radius:999px;padding:2px 10px}
|
|
276
|
+
.deepdots-progress-track{width:100%;height:4px;border-radius:999px;background:${trackBg};overflow:hidden}
|
|
277
|
+
#dd-progress-bar{height:100%;width:0%;background:#22C55E;border-radius:999px;transition:width 450ms ease}
|
|
278
|
+
/* El popup es una columna: solo el bloque de preguntas hace scroll, para que el footer
|
|
279
|
+
con las acciones quede siempre visible en el borde inferior (antes viv\xEDa dentro del
|
|
280
|
+
\xE1rea scrollable y hab\xEDa que bajar hasta el final para ver "Send"). */
|
|
281
|
+
/* Sin sangrado extra: el contenido se alinea con el t\xEDtulo y con la barra de progreso (antes
|
|
282
|
+
sumaba 20px a los lados sobre el padding de la tarjeta y quedaba m\xE1s adentro que la cabecera). */
|
|
283
|
+
/* Sin barra de progreso, este padding-top es el que separa la cabecera de la pregunta. Con
|
|
284
|
+
barra, el JS lo pone a 0 y el hueco lo aporta el padding inferior del bloque de progreso,
|
|
285
|
+
de modo que el espacio por arriba y por abajo de la barra es id\xE9ntico. */
|
|
286
|
+
.deepdots-popup-container-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:16px 0 0 0;overflow:hidden;box-sizing:border-box}
|
|
287
|
+
/* El enunciado trae margin-top:20px del CSS de surveys, que sumaba al hueco de la barra y
|
|
288
|
+
descompensaba la simetr\xEDa. Solo se anula en el primero: entre preguntas sigue separando. */
|
|
289
|
+
.deepdots-popup .magicfeedback-questions .magicfeedback-div:first-child .magicfeedback-label{margin-top:0}
|
|
290
|
+
.deepdots-popup-main{display:flex;flex-direction:column;width:100%;flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;position:relative}
|
|
255
291
|
#dd-form-wrapper{width:100%;flex:1 1 auto}
|
|
256
292
|
#mf{width:100%;box-sizing:border-box;visibility:hidden}
|
|
257
293
|
.deepdots-popup-main *{max-width:100%;box-sizing:border-box}
|
|
258
|
-
#dd-logo{max-height:40px;max-width:100%;object-fit:contain}
|
|
294
|
+
#dd-logo{max-height:40px;max-width:100%;object-fit:contain;display:block;margin:12px 0 0 0}
|
|
259
295
|
.deepdots-error-hint{display:none;margin:12px 0 0 0;padding:10px 12px;border-radius:6px;background:#FEF3C7;color:#92400E;border:1px solid #FCD34D;font-size:13px}
|
|
260
|
-
.
|
|
261
|
-
.
|
|
262
|
-
|
|
296
|
+
/* Pantalla final: el HTML del editor de la plataforma (imagen + texto), centrado. */
|
|
297
|
+
.deepdots-success{display:none;width:100%;text-align:center;padding:24px 0;color:${textPrimary}}
|
|
298
|
+
.deepdots-success img{max-width:100%;height:auto;margin:0 auto 16px auto;display:block}
|
|
299
|
+
.deepdots-success p{margin:0;font-size:16px;font-weight:600;line-height:1.4}
|
|
300
|
+
.deepdots-popup-footer{display:flex;flex-direction:row-reverse;justify-content:space-between;align-items:center;gap:4px;margin-top:auto;width:100%;padding-top:12px}
|
|
301
|
+
.dd-nav-btn{display:none;border:none;min-height:44px;padding:12px 24px;border-radius:6px;cursor:pointer;font-size:15px;font-weight:600;align-items:center;justify-content:center;text-align:center}
|
|
302
|
+
/* Secundario como bot\xF3n de texto: sin borde ni fondo, para que el primario sea la \xFAnica CTA. */
|
|
303
|
+
#dd-back{background:transparent;color:${textMuted};border:none}
|
|
263
304
|
#dd-start,#dd-complete,#dd-submit{background:#1E293B;color:#fff;border:none}
|
|
264
305
|
#dd-submit:disabled,#dd-start:disabled,#dd-back:disabled,#dd-complete:disabled{opacity:0.6;cursor:not-allowed}
|
|
265
306
|
.mf-spinner{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}
|
|
266
307
|
.mf-spinner-circle{width:28px;height:28px;border:3px solid #e0e6ed;border-top-color:#1E293B;border-radius:50%;animation:ddspin 0.9s linear infinite}
|
|
267
308
|
@keyframes ddspin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
|
|
268
309
|
@media (max-width:640px){
|
|
269
|
-
|
|
270
|
-
.
|
|
310
|
+
${mobileCard}
|
|
311
|
+
/* Apilados: la acci\xF3n principal (Send/Start/Complete) arriba y Back debajo. El orden del
|
|
312
|
+
DOM ya es ese, as\xED que \`column\` (no \`column-reverse\`) es lo que lo respeta. */
|
|
313
|
+
.deepdots-popup-footer{flex-direction:column;gap:4px}
|
|
271
314
|
.dd-nav-btn{width:100%}
|
|
272
315
|
.magicfeedback-checkbox-container,.magicfeedback-radio-container{margin:4px 0;padding:4px 8px}
|
|
273
316
|
.magicfeedback-checkbox label,.magicfeedback-radio-container label{font-size:15px}
|
|
274
317
|
.deepdots-popup input[type="radio"]{margin:6px 0 6px 8px}
|
|
275
318
|
.deepdots-popup input[type="checkbox"]{width:16px;height:16px}
|
|
276
319
|
}
|
|
320
|
+
${customCss}
|
|
277
321
|
</style>
|
|
278
322
|
</head><body>
|
|
279
323
|
<div class="${popupClass}" id="dd-popup">
|
|
280
324
|
<div class="deepdots-popup-header">
|
|
325
|
+
<h2 id="dd-title" class="deepdots-popup-title" hidden></h2>
|
|
281
326
|
<button type="button" id="dd-close" aria-label="Close popup">
|
|
282
|
-
<svg width="
|
|
283
|
-
<path d="
|
|
327
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
328
|
+
<path d="M5 5L19 19M5 19L19 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="butt"/>
|
|
284
329
|
</svg>
|
|
285
330
|
</button>
|
|
286
331
|
</div>
|
|
287
|
-
<div class="deepdots-
|
|
332
|
+
<div class="deepdots-progress" id="dd-progress">
|
|
333
|
+
<div class="deepdots-progress-head">
|
|
334
|
+
<span id="dd-progress-label"><span id="dd-progress-current"></span><span id="dd-progress-total"></span></span>
|
|
335
|
+
<span id="dd-progress-followup">Follow-up</span>
|
|
336
|
+
</div>
|
|
337
|
+
<div class="deepdots-progress-track"><div id="dd-progress-bar"></div></div>
|
|
338
|
+
</div>
|
|
339
|
+
<div class="deepdots-popup-container-content" id="dd-content">
|
|
288
340
|
<div class="deepdots-popup-main" id="dd-main">
|
|
289
341
|
<div id="dd-form-wrapper">
|
|
290
342
|
<div class="mf-spinner" id="dd-spinner" role="status" aria-label="Loading survey"><div class="mf-spinner-circle"></div></div>
|
|
291
343
|
<div id="mf"></div>
|
|
292
344
|
</div>
|
|
293
345
|
<div class="deepdots-error-hint" id="dd-error" role="alert" aria-live="polite"></div>
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
</
|
|
346
|
+
</div>
|
|
347
|
+
<div class="deepdots-popup-footer" id="dd-footer">
|
|
348
|
+
<button type="button" class="dd-nav-btn" id="dd-submit">Send</button>
|
|
349
|
+
<button type="button" class="dd-nav-btn" id="dd-back">Back</button>
|
|
350
|
+
<button type="button" class="dd-nav-btn" id="dd-complete">Complete survey</button>
|
|
351
|
+
<button type="button" class="dd-nav-btn" id="dd-start">Start survey</button>
|
|
300
352
|
</div>
|
|
301
353
|
</div>
|
|
302
354
|
</div>
|
|
@@ -309,6 +361,7 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
309
361
|
|
|
310
362
|
var popup=document.getElementById('dd-popup');
|
|
311
363
|
var main=document.getElementById('dd-main');
|
|
364
|
+
var content=document.getElementById('dd-content');
|
|
312
365
|
var footer=document.getElementById('dd-footer');
|
|
313
366
|
var spinner=document.getElementById('dd-spinner');
|
|
314
367
|
var formHost=document.getElementById('mf');
|
|
@@ -317,6 +370,58 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
317
370
|
var startBtn=document.getElementById('dd-start');
|
|
318
371
|
var completeBtn=document.getElementById('dd-complete');
|
|
319
372
|
var submitBtn=document.getElementById('dd-submit');
|
|
373
|
+
var titleEl=document.getElementById('dd-title');
|
|
374
|
+
var progressEl=document.getElementById('dd-progress');
|
|
375
|
+
var progressLabel=document.getElementById('dd-progress-label');
|
|
376
|
+
var progressCurrent=document.getElementById('dd-progress-current');
|
|
377
|
+
var progressTotal=document.getElementById('dd-progress-total');
|
|
378
|
+
var progressFollowUp=document.getElementById('dd-progress-followup');
|
|
379
|
+
var progressBar=document.getElementById('dd-progress-bar');
|
|
380
|
+
|
|
381
|
+
function setTitle(t){
|
|
382
|
+
if(!t) return;
|
|
383
|
+
titleEl.textContent=t;
|
|
384
|
+
titleEl.hidden=false;
|
|
385
|
+
}
|
|
386
|
+
setTitle(${titleJson});
|
|
387
|
+
|
|
388
|
+
// Estado de la barra de progreso. \`progressPref\` null = manda la plataforma (style).
|
|
389
|
+
var progressPref=${progressPref};
|
|
390
|
+
var progressEnabled=progressPref===true;
|
|
391
|
+
var progressShowUnit=true;
|
|
392
|
+
var progressUnit='fraction';
|
|
393
|
+
var onStartPage=false;
|
|
394
|
+
|
|
395
|
+
function updateProgress(p){
|
|
396
|
+
var total=p&&typeof p.total==='number'?p.total:0;
|
|
397
|
+
var progress=p&&typeof p.progress==='number'?p.progress:0;
|
|
398
|
+
// Solo tiene sentido con m\xE1s de una p\xE1gina, fuera de la pantalla de inicio y sin completar.
|
|
399
|
+
if(!progressEnabled||onStartPage||p&&p.completed||total<=1){
|
|
400
|
+
progressEl.style.display='none';
|
|
401
|
+
// Sin barra, el hueco cabecera\u2192pregunta lo pone el contenido.
|
|
402
|
+
content.style.paddingTop='16px';
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
progressEl.style.display='flex';
|
|
406
|
+
// Con barra, el hueco inferior ya lo pone el bloque de progreso: no duplicarlo.
|
|
407
|
+
content.style.paddingTop='0';
|
|
408
|
+
// Espejo de LineProgressQuestion (MagicSurvey): la barra usa el valor real (las follow-up
|
|
409
|
+
// suman +0.5 y avanzan media casilla) y la etiqueta redondea hacia abajo, porque una
|
|
410
|
+
// follow-up es un paso DENTRO de la misma pregunta, no la siguiente.
|
|
411
|
+
var current=Math.min(total,Math.max(1,progress+1));
|
|
412
|
+
var pct=Math.min(100,Math.max(0,(current/total)*100));
|
|
413
|
+
progressBar.style.width=pct+'%';
|
|
414
|
+
var label=Math.min(total,Math.max(1,Math.floor(progress)+1));
|
|
415
|
+
progressLabel.style.display=progressShowUnit?'block':'none';
|
|
416
|
+
if(progressUnit==='percentage'){
|
|
417
|
+
progressCurrent.textContent=Math.round(pct)+'%';
|
|
418
|
+
progressTotal.textContent='';
|
|
419
|
+
} else {
|
|
420
|
+
progressCurrent.textContent='Question '+label;
|
|
421
|
+
progressTotal.textContent=' of '+total;
|
|
422
|
+
}
|
|
423
|
+
progressFollowUp.style.display=p&&p.followup?'inline-block':'none';
|
|
424
|
+
}
|
|
320
425
|
|
|
321
426
|
backBtn.textContent=${backLabel};
|
|
322
427
|
startBtn.textContent=${startLabel};
|
|
@@ -325,7 +430,13 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
325
430
|
|
|
326
431
|
document.getElementById('dd-close').onclick=function(){ emitJSON('popup_close'); };
|
|
327
432
|
backBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.back){ window.DeepdotsForm.back(); } };
|
|
328
|
-
startBtn.onclick=function(){
|
|
433
|
+
startBtn.onclick=function(){
|
|
434
|
+
if(window.DeepdotsForm && window.DeepdotsForm.startForm){
|
|
435
|
+
window.DeepdotsForm.startForm();
|
|
436
|
+
onStartPage=false;
|
|
437
|
+
updateProgress({ progress:window.DeepdotsForm.progress, total:window.DeepdotsForm.total, completed:false, followup:false });
|
|
438
|
+
}
|
|
439
|
+
};
|
|
329
440
|
completeBtn.onclick=function(){ emitJSON('popup_close'); };
|
|
330
441
|
var surveyCompletedEmitted=false;
|
|
331
442
|
submitBtn.onclick=function(){
|
|
@@ -333,6 +444,36 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
333
444
|
if(window.DeepdotsForm && window.DeepdotsForm.send){ window.DeepdotsForm.send(); }
|
|
334
445
|
};
|
|
335
446
|
|
|
447
|
+
// Mensaje final configurado en la plataforma (\`style.successMessage\`). Se guarda al cargar
|
|
448
|
+
// y se pinta al completar. Va por innerHTML porque es HTML del editor de la plataforma
|
|
449
|
+
// (imagen + texto), igual que ya hace \`renderStartMessage\` con el mensaje de inicio.
|
|
450
|
+
var successMessageHtml='';
|
|
451
|
+
function showSuccessScreen(){
|
|
452
|
+
progressEl.style.display='none';
|
|
453
|
+
var wrapper=document.getElementById('dd-form-wrapper');
|
|
454
|
+
if(wrapper){ wrapper.style.display='none'; }
|
|
455
|
+
var done=document.getElementById('dd-success');
|
|
456
|
+
if(!done){
|
|
457
|
+
done=document.createElement('div');
|
|
458
|
+
done.id='dd-success';
|
|
459
|
+
done.className='deepdots-success';
|
|
460
|
+
main.insertBefore(done, errorHint);
|
|
461
|
+
}
|
|
462
|
+
done.innerHTML=successMessageHtml || '<p>Thank you for your feedback!</p>';
|
|
463
|
+
done.style.display='block';
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Profundidad de navegaci\xF3n DENTRO del survey: +1 por p\xE1gina avanzada, -1 al volver.
|
|
467
|
+
// Sustituye a la condici\xF3n \`total>1 && progress>0 && progress<total\`, que escond\xEDa el
|
|
468
|
+
// Back siempre que la siguiente pantalla era una follow-up din\xE1mica: las follow-up no
|
|
469
|
+
// entran en el grafo (suman +0.5 al progress y no tocan el total), as\xED que un survey de
|
|
470
|
+
// una pregunta con follow-up tiene total=1 y nunca cumpl\xEDa \`total>1\`.
|
|
471
|
+
var pageDepth=0;
|
|
472
|
+
|
|
473
|
+
function updateNavButtons(){
|
|
474
|
+
updateButtons(pageDepth>0?'in_progress_next':'in_progress_first');
|
|
475
|
+
}
|
|
476
|
+
|
|
336
477
|
function updateButtons(state){
|
|
337
478
|
backBtn.style.display='none';
|
|
338
479
|
startBtn.style.display='none';
|
|
@@ -377,10 +518,20 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
377
518
|
form.generate('mf', {
|
|
378
519
|
addButton:false,
|
|
379
520
|
getMetaData:true,
|
|
521
|
+
// La pantalla final la pinta el popup: renderSuccess de @magicfeedback/native usa
|
|
522
|
+
// textContent, as\xED que el mensaje de la plataforma (HTML con imagen) no se ver\xEDa, y su
|
|
523
|
+
// fallback es un literal gen\xE9rico que ignora style.successMessage.
|
|
524
|
+
addSuccessScreen:false,
|
|
380
525
|
onLoadedEvent:function(args){
|
|
381
526
|
var s=args && args.formData ? args.formData.style : null;
|
|
382
527
|
if(s && !stylesInjected){
|
|
383
528
|
stylesInjected=true;
|
|
529
|
+
if(s.successMessage){ successMessageHtml=s.successMessage; }
|
|
530
|
+
// La barra de progreso la decide el host (init) y, si no se pronuncia, la plataforma.
|
|
531
|
+
if(progressPref===null){ progressEnabled=s.showProgressBar===true; }
|
|
532
|
+
if(s.showProgressUnit!==undefined){ progressShowUnit=s.showProgressUnit!==false; }
|
|
533
|
+
if(s.progressUnit){ progressUnit=s.progressUnit; }
|
|
534
|
+
if(s.loadingBarColor){ progressBar.style.background=s.loadingBarColor; progressFollowUp.style.background=s.loadingBarColor; }
|
|
384
535
|
if(chromeOn && s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
385
536
|
if(s.contentAlign){ main.style.justifyContent = s.contentAlign==='center' ? 'center' : 'flex-start'; }
|
|
386
537
|
if(s.buttonPrimaryColor){
|
|
@@ -389,7 +540,8 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
389
540
|
completeBtn.style.background=s.buttonPrimaryColor; completeBtn.style.border='none'; completeBtn.style.color='#fff';
|
|
390
541
|
}
|
|
391
542
|
if(s.buttonSecondaryColor){
|
|
392
|
-
|
|
543
|
+
// Bot\xF3n de texto: solo ti\xF1e la etiqueta, sin recuperar fondo ni borde.
|
|
544
|
+
backBtn.style.background='transparent'; backBtn.style.color=s.buttonSecondaryColor; backBtn.style.border='none';
|
|
393
545
|
}
|
|
394
546
|
if(s.logo && !document.getElementById('dd-logo')){
|
|
395
547
|
var logoImg=document.createElement('img');
|
|
@@ -397,16 +549,20 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
397
549
|
if(s.logoSize==='small'){ logoImg.style.maxHeight='30px'; }
|
|
398
550
|
else if(s.logoSize==='medium'){ logoImg.style.maxHeight='50px'; }
|
|
399
551
|
else if(s.logoSize==='large'){ logoImg.style.maxHeight='70px'; }
|
|
400
|
-
if(s.logoPosition==='left'){ logoImg.style.margin='
|
|
401
|
-
else if(s.logoPosition==='right'){ logoImg.style.margin='0 0
|
|
402
|
-
else if(s.logoPosition==='center'){ logoImg.style.margin='
|
|
403
|
-
|
|
552
|
+
if(s.logoPosition==='left'){ logoImg.style.margin='12px 16px 0 0'; logoImg.style.marginLeft='0'; }
|
|
553
|
+
else if(s.logoPosition==='right'){ logoImg.style.margin='12px 0 0 16px'; logoImg.style.marginLeft='auto'; }
|
|
554
|
+
else if(s.logoPosition==='center'){ logoImg.style.margin='12px auto 0 auto'; }
|
|
555
|
+
// Encima de la barra de progreso, como hermano del header (espejo de ui/logo.ts en
|
|
556
|
+
// web). Fuera de #dd-main, as\xED el logo no se va con el scroll del formulario.
|
|
557
|
+
popup.insertBefore(logoImg, progressEl);
|
|
404
558
|
}
|
|
405
|
-
if(s.startMessage && s.startMessage!==''){ updateButtons('start'); }
|
|
559
|
+
if(s.startMessage && s.startMessage!==''){ onStartPage=true; updateButtons('start'); }
|
|
406
560
|
else { updateButtons('in_progress_first'); }
|
|
407
561
|
} else {
|
|
408
562
|
updateButtons('in_progress_first');
|
|
409
563
|
}
|
|
564
|
+
// El total solo se conoce una vez montado el form; sin \xE9l no hay barra que pintar.
|
|
565
|
+
updateProgress({ progress:form.progress, total:form.total, completed:false, followup:false });
|
|
410
566
|
emitJSON('loaded');
|
|
411
567
|
setLoading(false);
|
|
412
568
|
},
|
|
@@ -419,9 +575,10 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
419
575
|
if(error){
|
|
420
576
|
setLoading(false);
|
|
421
577
|
if(error.toLowerCase().indexOf('no response')!==-1){
|
|
578
|
+
// La p\xE1gina no ha cambiado: el estado de navegaci\xF3n se queda como estaba.
|
|
422
579
|
errorHint.textContent='Please answer the required question to continue.';
|
|
423
580
|
errorHint.style.display='block';
|
|
424
|
-
|
|
581
|
+
updateNavButtons();
|
|
425
582
|
return;
|
|
426
583
|
}
|
|
427
584
|
errorHint.textContent='An error occurred while submitting. Please try again or close the popup.';
|
|
@@ -432,17 +589,23 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
432
589
|
setLoading(false);
|
|
433
590
|
if(p && p.completed){
|
|
434
591
|
surveyCompletedEmitted=true;
|
|
592
|
+
showSuccessScreen();
|
|
435
593
|
updateButtons('completed');
|
|
594
|
+
updateProgress(p);
|
|
436
595
|
emitJSON('survey_completed', p);
|
|
437
596
|
return;
|
|
438
597
|
}
|
|
439
|
-
|
|
440
|
-
|
|
598
|
+
pageDepth++;
|
|
599
|
+
updateNavButtons();
|
|
600
|
+
updateProgress(p);
|
|
441
601
|
emitJSON('after_submit', p);
|
|
442
602
|
},
|
|
443
603
|
onBackEvent:function(p){
|
|
444
|
-
|
|
445
|
-
|
|
604
|
+
// Con error ("No page found") no hubo navegaci\xF3n: la profundidad no se toca.
|
|
605
|
+
if(!(p&&p.error)){ pageDepth=Math.max(0,pageDepth-1); }
|
|
606
|
+
updateNavButtons();
|
|
607
|
+
// onBackEvent no trae \`total\`: se lee del form, que es su due\xF1o.
|
|
608
|
+
updateProgress({ progress:p&&p.progress, total:form.total, completed:false, followup:p&&p.followup });
|
|
446
609
|
emitJSON('back', p);
|
|
447
610
|
}
|
|
448
611
|
}).catch(function(e){ setLoading(false); emit('error:init'); });
|
|
@@ -470,7 +633,7 @@ var ReactNativePopupRenderer = class {
|
|
|
470
633
|
}
|
|
471
634
|
init() {
|
|
472
635
|
}
|
|
473
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome) {
|
|
636
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome, options) {
|
|
474
637
|
this.emitFn = emit;
|
|
475
638
|
this.onCloseFn = onClose;
|
|
476
639
|
this.currentSurveyId = surveyId;
|
|
@@ -487,7 +650,10 @@ var ReactNativePopupRenderer = class {
|
|
|
487
650
|
position: style?.position,
|
|
488
651
|
actions,
|
|
489
652
|
// renderChrome:false (init) → HTML sin tarjeta/overlay: el host lo envuelve en su Modal.
|
|
490
|
-
chrome: renderChrome
|
|
653
|
+
chrome: renderChrome,
|
|
654
|
+
title: options?.title,
|
|
655
|
+
showProgressBar: options?.showProgressBar,
|
|
656
|
+
surveyCss: options?.surveyCss
|
|
491
657
|
});
|
|
492
658
|
if (this.options.onShow) {
|
|
493
659
|
this.options.onShow({ surveyId, productId, html });
|
|
@@ -527,7 +693,6 @@ var ReactNativePopupRenderer = class {
|
|
|
527
693
|
break;
|
|
528
694
|
case "survey_completed":
|
|
529
695
|
this.emitFn("survey_completed", surveyId);
|
|
530
|
-
this.onCloseFn?.();
|
|
531
696
|
break;
|
|
532
697
|
case "popup_close":
|
|
533
698
|
this.onCloseFn?.();
|
|
@@ -578,14 +743,14 @@ var BrowserPopupRenderer = class {
|
|
|
578
743
|
document.body.appendChild(this.container);
|
|
579
744
|
}
|
|
580
745
|
}
|
|
581
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome) {
|
|
746
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome, options) {
|
|
582
747
|
if (this.visible) return;
|
|
583
748
|
if (!this.container || !document.body.contains(this.container)) this.init();
|
|
584
749
|
if (!this.container) return;
|
|
585
750
|
this.visible = true;
|
|
586
751
|
const container = this.container;
|
|
587
|
-
void import("./renderPopup-
|
|
588
|
-
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId);
|
|
752
|
+
void import("./renderPopup-M6MKTDEH.mjs").then(({ renderPopup }) => {
|
|
753
|
+
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId, options);
|
|
589
754
|
});
|
|
590
755
|
}
|
|
591
756
|
hide() {
|
|
@@ -1434,6 +1599,10 @@ var DeepdotsPopups = class {
|
|
|
1434
1599
|
this.env = "production";
|
|
1435
1600
|
/** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
|
|
1436
1601
|
this.renderChrome = true;
|
|
1602
|
+
/** Barra de progreso. undefined = la decide la plataforma (style.showProgressBar). */
|
|
1603
|
+
this.showProgressBar = void 0;
|
|
1604
|
+
/** CSS del host inyectado al final de los estilos del popup. */
|
|
1605
|
+
this.surveyCss = void 0;
|
|
1437
1606
|
/** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
|
|
1438
1607
|
this.tracking = null;
|
|
1439
1608
|
/** Capa de analytics (canal separado del feedback). Null hasta init(). */
|
|
@@ -1485,6 +1654,8 @@ var DeepdotsPopups = class {
|
|
|
1485
1654
|
this.baseUrl = env.apiBaseUrl;
|
|
1486
1655
|
this.env = config.nodeEnv || "production";
|
|
1487
1656
|
this.renderChrome = config.renderChrome ?? true;
|
|
1657
|
+
this.showProgressBar = config.showProgressBar;
|
|
1658
|
+
this.surveyCss = config.surveyCss;
|
|
1488
1659
|
this.config = {
|
|
1489
1660
|
apiKey: config.apiKey || void 0,
|
|
1490
1661
|
debug: config.debug || false,
|
|
@@ -1930,7 +2101,7 @@ var DeepdotsPopups = class {
|
|
|
1930
2101
|
this.log("Showing popup (definition)", def);
|
|
1931
2102
|
this.surveyToPopupId.set(def.surveyId, def.id);
|
|
1932
2103
|
this.lastShown.set(def.id, Date.now());
|
|
1933
|
-
this.renderPopup(def.surveyId, def.productId, def.actions, def.style);
|
|
2104
|
+
this.renderPopup(def.surveyId, def.productId, def.actions, def.style, def.title);
|
|
1934
2105
|
this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
|
|
1935
2106
|
}
|
|
1936
2107
|
shouldShow(def, pathUrl, skipPathCheck = false) {
|
|
@@ -2268,7 +2439,7 @@ var DeepdotsPopups = class {
|
|
|
2268
2439
|
document.body.appendChild(this.popupContainer);
|
|
2269
2440
|
}
|
|
2270
2441
|
/** Render the popup UI */
|
|
2271
|
-
renderPopup(surveyId, productId, actions, style) {
|
|
2442
|
+
renderPopup(surveyId, productId, actions, style, title) {
|
|
2272
2443
|
const userId = this.tracking?.getUserId() ?? this.config?.userId;
|
|
2273
2444
|
const sessionId = this.tracking?.getSessionId() ?? void 0;
|
|
2274
2445
|
const miniService = this.analytics?.getMiniService() ?? void 0;
|
|
@@ -2287,13 +2458,14 @@ var DeepdotsPopups = class {
|
|
|
2287
2458
|
sessionId,
|
|
2288
2459
|
miniService,
|
|
2289
2460
|
analyticsFeedbackSessionId,
|
|
2290
|
-
this.renderChrome
|
|
2461
|
+
this.renderChrome,
|
|
2462
|
+
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
|
|
2291
2463
|
);
|
|
2292
2464
|
return;
|
|
2293
2465
|
}
|
|
2294
2466
|
if (!this.popupContainer) return;
|
|
2295
2467
|
const container = this.popupContainer;
|
|
2296
|
-
void import("./renderPopup-
|
|
2468
|
+
void import("./renderPopup-M6MKTDEH.mjs").then(({ renderPopup }) => {
|
|
2297
2469
|
renderPopup(
|
|
2298
2470
|
container,
|
|
2299
2471
|
surveyId,
|
|
@@ -2306,7 +2478,8 @@ var DeepdotsPopups = class {
|
|
|
2306
2478
|
style,
|
|
2307
2479
|
sessionId,
|
|
2308
2480
|
miniService,
|
|
2309
|
-
analyticsFeedbackSessionId
|
|
2481
|
+
analyticsFeedbackSessionId,
|
|
2482
|
+
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
|
|
2310
2483
|
);
|
|
2311
2484
|
});
|
|
2312
2485
|
}
|