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