@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/index.mjs
CHANGED
|
@@ -19,6 +19,10 @@ var POPUP_TRIGGER_CONDITION_STATUSES = [
|
|
|
19
19
|
];
|
|
20
20
|
|
|
21
21
|
// src/triggers/index.ts
|
|
22
|
+
function toNumericValue(value, fallback) {
|
|
23
|
+
const n = Number(value);
|
|
24
|
+
return Number.isFinite(n) ? n : fallback;
|
|
25
|
+
}
|
|
22
26
|
function setupTrigger(popups, trigger) {
|
|
23
27
|
switch (trigger.type) {
|
|
24
28
|
case "time":
|
|
@@ -39,14 +43,14 @@ function setupTrigger(popups, trigger) {
|
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
function setupTimeTrigger(popups, trigger) {
|
|
42
|
-
const delay = trigger.value
|
|
46
|
+
const delay = toNumericValue(trigger.value, 5e3);
|
|
43
47
|
setTimeout(() => {
|
|
44
48
|
popups.triggerSurvey(trigger.surveyId, trigger.popupId);
|
|
45
49
|
}, delay);
|
|
46
50
|
popups.debug(`Time trigger set for ${delay}ms`);
|
|
47
51
|
}
|
|
48
52
|
function setupScrollTrigger(popups, trigger) {
|
|
49
|
-
const threshold = trigger.value
|
|
53
|
+
const threshold = toNumericValue(trigger.value, 50);
|
|
50
54
|
const handler = () => {
|
|
51
55
|
const scrollPercentage = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) * 100;
|
|
52
56
|
if (scrollPercentage >= threshold) {
|
|
@@ -221,6 +225,16 @@ function buildSurveyHtml(opts) {
|
|
|
221
225
|
const colorScheme = isDark ? "dark" : "light";
|
|
222
226
|
const textPrimary = isDark ? "#f0f0f0" : "#111";
|
|
223
227
|
const pos = POSITION_MAP[opts.position ?? "center"] ?? POSITION_MAP.center;
|
|
228
|
+
const chrome = opts.chrome !== false;
|
|
229
|
+
const bodyBg = chrome ? pos.background : "transparent";
|
|
230
|
+
const bodyPadding = chrome ? pos.padding : "0";
|
|
231
|
+
const bodyDisplay = chrome ? "flex" : "block";
|
|
232
|
+
const cardBg = chrome ? popupBg : "transparent";
|
|
233
|
+
const cardShadow = chrome ? "0 4px 6px rgba(0,0,0,0.1)" : "none";
|
|
234
|
+
const cardRadius = chrome ? "8px" : "0";
|
|
235
|
+
const cardMaxWidth = chrome ? "600px" : "none";
|
|
236
|
+
const cardWidth = chrome ? "90%" : "100%";
|
|
237
|
+
const cardMinHeight = chrome ? "200px" : "0";
|
|
224
238
|
const backLabel = JSON.stringify(opts.actions?.back?.label ?? "Back");
|
|
225
239
|
const startLabel = JSON.stringify(opts.actions?.start?.label ?? "Start survey");
|
|
226
240
|
const completeLabel = JSON.stringify(opts.actions?.complete?.label ?? "Complete survey");
|
|
@@ -232,8 +246,8 @@ function buildSurveyHtml(opts) {
|
|
|
232
246
|
${style_default}
|
|
233
247
|
${fontFaceCss}
|
|
234
248
|
html,body{margin:0;padding:0;height:100%;font-family:${fontFamilyValue}}
|
|
235
|
-
body{display
|
|
236
|
-
.deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${
|
|
249
|
+
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}
|
|
237
251
|
.deepdots-popup-header{display:flex;justify-content:flex-end;align-items:center;width:100%}
|
|
238
252
|
#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}
|
|
239
253
|
.deepdots-popup-container-content{display:flex;flex-direction:column;padding:0 20px 12px 20px;max-height:80vh;overflow:hidden;box-sizing:border-box}
|
|
@@ -291,6 +305,7 @@ body{display:flex;justify-content:${pos.justifyContent};align-items:${pos.alignI
|
|
|
291
305
|
function emit(s){ try{ if(window.ReactNativeWebView){ window.ReactNativeWebView.postMessage(s); } }catch(e){} }
|
|
292
306
|
function emitJSON(n,p){ try{ emit(JSON.stringify({name:n,payload:p||{}})); }catch(e){} }
|
|
293
307
|
window.DeepdotsClose = function(){ emitJSON('popup_close'); };
|
|
308
|
+
var chromeOn=${chrome ? "true" : "false"};
|
|
294
309
|
|
|
295
310
|
var popup=document.getElementById('dd-popup');
|
|
296
311
|
var main=document.getElementById('dd-main');
|
|
@@ -366,7 +381,7 @@ body{display:flex;justify-content:${pos.justifyContent};align-items:${pos.alignI
|
|
|
366
381
|
var s=args && args.formData ? args.formData.style : null;
|
|
367
382
|
if(s && !stylesInjected){
|
|
368
383
|
stylesInjected=true;
|
|
369
|
-
if(s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
384
|
+
if(chromeOn && s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
370
385
|
if(s.contentAlign){ main.style.justifyContent = s.contentAlign==='center' ? 'center' : 'flex-start'; }
|
|
371
386
|
if(s.buttonPrimaryColor){
|
|
372
387
|
submitBtn.style.background=s.buttonPrimaryColor; submitBtn.style.border='none'; submitBtn.style.color='#fff';
|
|
@@ -455,7 +470,7 @@ var ReactNativePopupRenderer = class {
|
|
|
455
470
|
}
|
|
456
471
|
init() {
|
|
457
472
|
}
|
|
458
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
473
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome) {
|
|
459
474
|
this.emitFn = emit;
|
|
460
475
|
this.onCloseFn = onClose;
|
|
461
476
|
this.currentSurveyId = surveyId;
|
|
@@ -470,7 +485,9 @@ var ReactNativePopupRenderer = class {
|
|
|
470
485
|
font: style?.font,
|
|
471
486
|
theme: style?.theme,
|
|
472
487
|
position: style?.position,
|
|
473
|
-
actions
|
|
488
|
+
actions,
|
|
489
|
+
// renderChrome:false (init) → HTML sin tarjeta/overlay: el host lo envuelve en su Modal.
|
|
490
|
+
chrome: renderChrome
|
|
474
491
|
});
|
|
475
492
|
if (this.options.onShow) {
|
|
476
493
|
this.options.onShow({ surveyId, productId, html });
|
|
@@ -561,13 +578,13 @@ var BrowserPopupRenderer = class {
|
|
|
561
578
|
document.body.appendChild(this.container);
|
|
562
579
|
}
|
|
563
580
|
}
|
|
564
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
581
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome) {
|
|
565
582
|
if (this.visible) return;
|
|
566
583
|
if (!this.container || !document.body.contains(this.container)) this.init();
|
|
567
584
|
if (!this.container) return;
|
|
568
585
|
this.visible = true;
|
|
569
586
|
const container = this.container;
|
|
570
|
-
void import("./renderPopup-
|
|
587
|
+
void import("./renderPopup-TCKR5Z3P.mjs").then(({ renderPopup }) => {
|
|
571
588
|
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId);
|
|
572
589
|
});
|
|
573
590
|
}
|
|
@@ -1415,6 +1432,8 @@ var DeepdotsPopups = class {
|
|
|
1415
1432
|
this.deferredExitTimers = [];
|
|
1416
1433
|
this.baseUrl = "";
|
|
1417
1434
|
this.env = "production";
|
|
1435
|
+
/** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
|
|
1436
|
+
this.renderChrome = true;
|
|
1418
1437
|
/** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
|
|
1419
1438
|
this.tracking = null;
|
|
1420
1439
|
/** Capa de analytics (canal separado del feedback). Null hasta init(). */
|
|
@@ -1465,6 +1484,7 @@ var DeepdotsPopups = class {
|
|
|
1465
1484
|
const env = resolveEnvironment(config.nodeEnv);
|
|
1466
1485
|
this.baseUrl = env.apiBaseUrl;
|
|
1467
1486
|
this.env = config.nodeEnv || "production";
|
|
1487
|
+
this.renderChrome = config.renderChrome ?? true;
|
|
1468
1488
|
this.config = {
|
|
1469
1489
|
apiKey: config.apiKey || void 0,
|
|
1470
1490
|
debug: config.debug || false,
|
|
@@ -1650,6 +1670,22 @@ var DeepdotsPopups = class {
|
|
|
1650
1670
|
trackFunnelStep(funnel, step, taskId, params) {
|
|
1651
1671
|
this.track("deepdots_funnel_step", { funnel, step, task_id: taskId, ...params ?? {} });
|
|
1652
1672
|
}
|
|
1673
|
+
/**
|
|
1674
|
+
* Product Effectiveness: una interacción significativa del usuario (`interaction_type` es la
|
|
1675
|
+
* dimensión de agrupación, p. ej. `get_help`, `homepage`, `contact_support`).
|
|
1676
|
+
*
|
|
1677
|
+
* Existe como evento RESERVADO para que la convención no la invente cada host: un `track()`
|
|
1678
|
+
* custom acaba como `deepdots_event_…` y no lo cuenta la analítica de effectiveness.
|
|
1679
|
+
* Un `interactionType` vacío se descarta con warning (no aporta dato agrupable).
|
|
1680
|
+
*/
|
|
1681
|
+
trackMeaningfulInteraction(interactionType, params) {
|
|
1682
|
+
const type = typeof interactionType === "string" ? interactionType.trim() : "";
|
|
1683
|
+
if (!type) {
|
|
1684
|
+
console.warn("[DeepdotsPopups] trackMeaningfulInteraction discarded: empty interaction_type");
|
|
1685
|
+
return;
|
|
1686
|
+
}
|
|
1687
|
+
this.track("deepdots_meaningful_interaction", { interaction_type: type, ...params ?? {} });
|
|
1688
|
+
}
|
|
1653
1689
|
/**
|
|
1654
1690
|
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
1655
1691
|
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
@@ -2250,13 +2286,14 @@ var DeepdotsPopups = class {
|
|
|
2250
2286
|
style,
|
|
2251
2287
|
sessionId,
|
|
2252
2288
|
miniService,
|
|
2253
|
-
analyticsFeedbackSessionId
|
|
2289
|
+
analyticsFeedbackSessionId,
|
|
2290
|
+
this.renderChrome
|
|
2254
2291
|
);
|
|
2255
2292
|
return;
|
|
2256
2293
|
}
|
|
2257
2294
|
if (!this.popupContainer) return;
|
|
2258
2295
|
const container = this.popupContainer;
|
|
2259
|
-
void import("./renderPopup-
|
|
2296
|
+
void import("./renderPopup-TCKR5Z3P.mjs").then(({ renderPopup }) => {
|
|
2260
2297
|
renderPopup(
|
|
2261
2298
|
container,
|
|
2262
2299
|
surveyId,
|