@magicfeedback/popup-sdk 1.3.0 → 1.4.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/README.md +6 -0
- package/dist/index.d.mts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +47 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +48 -11
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +22 -2
- package/dist/react-native.d.ts +22 -2
- package/dist/react-native.js +47 -10
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +48 -11
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-NJK7Z46E.mjs → renderPopup-TCKR5Z3P.mjs} +2 -2
- package/dist/{renderPopup-NJK7Z46E.mjs.map → renderPopup-TCKR5Z3P.mjs.map} +1 -1
- package/dist/{renderPopup-ZYXOUBCP.mjs → renderPopup-UYMGEBSI.mjs} +2 -2
- package/dist/{renderPopup-ZYXOUBCP.mjs.map → renderPopup-UYMGEBSI.mjs.map} +1 -1
- package/package.json +5 -10
package/dist/react-native.mjs
CHANGED
|
@@ -24,6 +24,10 @@ var POPUP_TRIGGER_CONDITION_STATUSES = [
|
|
|
24
24
|
];
|
|
25
25
|
|
|
26
26
|
// src/triggers/index.ts
|
|
27
|
+
function toNumericValue(value, fallback) {
|
|
28
|
+
const n = Number(value);
|
|
29
|
+
return Number.isFinite(n) ? n : fallback;
|
|
30
|
+
}
|
|
27
31
|
function setupTrigger(popups, trigger) {
|
|
28
32
|
switch (trigger.type) {
|
|
29
33
|
case "time":
|
|
@@ -44,14 +48,14 @@ function setupTrigger(popups, trigger) {
|
|
|
44
48
|
}
|
|
45
49
|
}
|
|
46
50
|
function setupTimeTrigger(popups, trigger) {
|
|
47
|
-
const delay = trigger.value
|
|
51
|
+
const delay = toNumericValue(trigger.value, 5e3);
|
|
48
52
|
setTimeout(() => {
|
|
49
53
|
popups.triggerSurvey(trigger.surveyId, trigger.popupId);
|
|
50
54
|
}, delay);
|
|
51
55
|
popups.debug(`Time trigger set for ${delay}ms`);
|
|
52
56
|
}
|
|
53
57
|
function setupScrollTrigger(popups, trigger) {
|
|
54
|
-
const threshold = trigger.value
|
|
58
|
+
const threshold = toNumericValue(trigger.value, 50);
|
|
55
59
|
const handler = () => {
|
|
56
60
|
const scrollPercentage = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) * 100;
|
|
57
61
|
if (scrollPercentage >= threshold) {
|
|
@@ -226,6 +230,16 @@ function buildSurveyHtml(opts) {
|
|
|
226
230
|
const colorScheme = isDark ? "dark" : "light";
|
|
227
231
|
const textPrimary = isDark ? "#f0f0f0" : "#111";
|
|
228
232
|
const pos = POSITION_MAP[opts.position ?? "center"] ?? POSITION_MAP.center;
|
|
233
|
+
const chrome = opts.chrome !== false;
|
|
234
|
+
const bodyBg = chrome ? pos.background : "transparent";
|
|
235
|
+
const bodyPadding = chrome ? pos.padding : "0";
|
|
236
|
+
const bodyDisplay = chrome ? "flex" : "block";
|
|
237
|
+
const cardBg = chrome ? popupBg : "transparent";
|
|
238
|
+
const cardShadow = chrome ? "0 4px 6px rgba(0,0,0,0.1)" : "none";
|
|
239
|
+
const cardRadius = chrome ? "8px" : "0";
|
|
240
|
+
const cardMaxWidth = chrome ? "600px" : "none";
|
|
241
|
+
const cardWidth = chrome ? "90%" : "100%";
|
|
242
|
+
const cardMinHeight = chrome ? "200px" : "0";
|
|
229
243
|
const backLabel = JSON.stringify(opts.actions?.back?.label ?? "Back");
|
|
230
244
|
const startLabel = JSON.stringify(opts.actions?.start?.label ?? "Start survey");
|
|
231
245
|
const completeLabel = JSON.stringify(opts.actions?.complete?.label ?? "Complete survey");
|
|
@@ -237,8 +251,8 @@ function buildSurveyHtml(opts) {
|
|
|
237
251
|
${style_default}
|
|
238
252
|
${fontFaceCss}
|
|
239
253
|
html,body{margin:0;padding:0;height:100%;font-family:${fontFamilyValue}}
|
|
240
|
-
body{display
|
|
241
|
-
.deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${
|
|
254
|
+
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}
|
|
242
256
|
.deepdots-popup-header{display:flex;justify-content:flex-end;align-items:center;width:100%}
|
|
243
257
|
#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}
|
|
244
258
|
.deepdots-popup-container-content{display:flex;flex-direction:column;padding:0 20px 12px 20px;max-height:80vh;overflow:hidden;box-sizing:border-box}
|
|
@@ -296,6 +310,7 @@ body{display:flex;justify-content:${pos.justifyContent};align-items:${pos.alignI
|
|
|
296
310
|
function emit(s){ try{ if(window.ReactNativeWebView){ window.ReactNativeWebView.postMessage(s); } }catch(e){} }
|
|
297
311
|
function emitJSON(n,p){ try{ emit(JSON.stringify({name:n,payload:p||{}})); }catch(e){} }
|
|
298
312
|
window.DeepdotsClose = function(){ emitJSON('popup_close'); };
|
|
313
|
+
var chromeOn=${chrome ? "true" : "false"};
|
|
299
314
|
|
|
300
315
|
var popup=document.getElementById('dd-popup');
|
|
301
316
|
var main=document.getElementById('dd-main');
|
|
@@ -371,7 +386,7 @@ body{display:flex;justify-content:${pos.justifyContent};align-items:${pos.alignI
|
|
|
371
386
|
var s=args && args.formData ? args.formData.style : null;
|
|
372
387
|
if(s && !stylesInjected){
|
|
373
388
|
stylesInjected=true;
|
|
374
|
-
if(s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
389
|
+
if(chromeOn && s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
375
390
|
if(s.contentAlign){ main.style.justifyContent = s.contentAlign==='center' ? 'center' : 'flex-start'; }
|
|
376
391
|
if(s.buttonPrimaryColor){
|
|
377
392
|
submitBtn.style.background=s.buttonPrimaryColor; submitBtn.style.border='none'; submitBtn.style.color='#fff';
|
|
@@ -460,7 +475,7 @@ var ReactNativePopupRenderer = class {
|
|
|
460
475
|
}
|
|
461
476
|
init() {
|
|
462
477
|
}
|
|
463
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
478
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome) {
|
|
464
479
|
this.emitFn = emit;
|
|
465
480
|
this.onCloseFn = onClose;
|
|
466
481
|
this.currentSurveyId = surveyId;
|
|
@@ -475,7 +490,9 @@ var ReactNativePopupRenderer = class {
|
|
|
475
490
|
font: style?.font,
|
|
476
491
|
theme: style?.theme,
|
|
477
492
|
position: style?.position,
|
|
478
|
-
actions
|
|
493
|
+
actions,
|
|
494
|
+
// renderChrome:false (init) → HTML sin tarjeta/overlay: el host lo envuelve en su Modal.
|
|
495
|
+
chrome: renderChrome
|
|
479
496
|
});
|
|
480
497
|
if (this.options.onShow) {
|
|
481
498
|
this.options.onShow({ surveyId, productId, html });
|
|
@@ -566,13 +583,13 @@ var BrowserPopupRenderer = class {
|
|
|
566
583
|
document.body.appendChild(this.container);
|
|
567
584
|
}
|
|
568
585
|
}
|
|
569
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
586
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome) {
|
|
570
587
|
if (this.visible) return;
|
|
571
588
|
if (!this.container || !document.body.contains(this.container)) this.init();
|
|
572
589
|
if (!this.container) return;
|
|
573
590
|
this.visible = true;
|
|
574
591
|
const container = this.container;
|
|
575
|
-
void import("./renderPopup-
|
|
592
|
+
void import("./renderPopup-UYMGEBSI.mjs").then(({ renderPopup }) => {
|
|
576
593
|
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId);
|
|
577
594
|
});
|
|
578
595
|
}
|
|
@@ -1420,6 +1437,8 @@ var DeepdotsPopups = class {
|
|
|
1420
1437
|
this.deferredExitTimers = [];
|
|
1421
1438
|
this.baseUrl = "";
|
|
1422
1439
|
this.env = "production";
|
|
1440
|
+
/** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
|
|
1441
|
+
this.renderChrome = true;
|
|
1423
1442
|
/** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
|
|
1424
1443
|
this.tracking = null;
|
|
1425
1444
|
/** Capa de analytics (canal separado del feedback). Null hasta init(). */
|
|
@@ -1470,6 +1489,7 @@ var DeepdotsPopups = class {
|
|
|
1470
1489
|
const env = resolveEnvironment(config.nodeEnv);
|
|
1471
1490
|
this.baseUrl = env.apiBaseUrl;
|
|
1472
1491
|
this.env = config.nodeEnv || "production";
|
|
1492
|
+
this.renderChrome = config.renderChrome ?? true;
|
|
1473
1493
|
this.config = {
|
|
1474
1494
|
apiKey: config.apiKey || void 0,
|
|
1475
1495
|
debug: config.debug || false,
|
|
@@ -1655,6 +1675,22 @@ var DeepdotsPopups = class {
|
|
|
1655
1675
|
trackFunnelStep(funnel, step, taskId, params) {
|
|
1656
1676
|
this.track("deepdots_funnel_step", { funnel, step, task_id: taskId, ...params ?? {} });
|
|
1657
1677
|
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Product Effectiveness: una interacción significativa del usuario (`interaction_type` es la
|
|
1680
|
+
* dimensión de agrupación, p. ej. `get_help`, `homepage`, `contact_support`).
|
|
1681
|
+
*
|
|
1682
|
+
* Existe como evento RESERVADO para que la convención no la invente cada host: un `track()`
|
|
1683
|
+
* custom acaba como `deepdots_event_…` y no lo cuenta la analítica de effectiveness.
|
|
1684
|
+
* Un `interactionType` vacío se descarta con warning (no aporta dato agrupable).
|
|
1685
|
+
*/
|
|
1686
|
+
trackMeaningfulInteraction(interactionType, params) {
|
|
1687
|
+
const type = typeof interactionType === "string" ? interactionType.trim() : "";
|
|
1688
|
+
if (!type) {
|
|
1689
|
+
console.warn("[DeepdotsPopups] trackMeaningfulInteraction discarded: empty interaction_type");
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
this.track("deepdots_meaningful_interaction", { interaction_type: type, ...params ?? {} });
|
|
1693
|
+
}
|
|
1658
1694
|
/**
|
|
1659
1695
|
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
1660
1696
|
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
@@ -2255,13 +2291,14 @@ var DeepdotsPopups = class {
|
|
|
2255
2291
|
style,
|
|
2256
2292
|
sessionId,
|
|
2257
2293
|
miniService,
|
|
2258
|
-
analyticsFeedbackSessionId
|
|
2294
|
+
analyticsFeedbackSessionId,
|
|
2295
|
+
this.renderChrome
|
|
2259
2296
|
);
|
|
2260
2297
|
return;
|
|
2261
2298
|
}
|
|
2262
2299
|
if (!this.popupContainer) return;
|
|
2263
2300
|
const container = this.popupContainer;
|
|
2264
|
-
void import("./renderPopup-
|
|
2301
|
+
void import("./renderPopup-UYMGEBSI.mjs").then(({ renderPopup }) => {
|
|
2265
2302
|
renderPopup(
|
|
2266
2303
|
container,
|
|
2267
2304
|
surveyId,
|