@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/README.md
CHANGED
|
@@ -128,6 +128,11 @@ Config fields:
|
|
|
128
128
|
- `platform?: 'web' | 'android' | 'ios'` — defaults to `'web'`
|
|
129
129
|
- `device?: DeviceInfo` — device context override, for hosts where the SDK cannot detect it
|
|
130
130
|
- `contactAttributes?: Record<string, string | number | boolean>`
|
|
131
|
+
- `renderChrome?: boolean` — React Native only. Defaults to `true`. When `false`, the survey
|
|
132
|
+
WebView HTML is delivered transparent and edge-to-edge, without the SDK's own card, backdrop,
|
|
133
|
+
or positioning, so the host mounts its own `Modal`/container and controls the styling. This
|
|
134
|
+
avoids a "double modal" when the host already wraps the WebView. The survey stays fully
|
|
135
|
+
functional (message bridge, form, nav buttons, close). No effect on the web DOM popup.
|
|
131
136
|
- `language?: string` — BCP-47 tag (`'en'`, `'en-US'`, …) used for popup language
|
|
132
137
|
segmentation (`segments.lang`) and for the analytics context. If omitted it is
|
|
133
138
|
auto-detected from `navigator.language`, falling back to the `Intl` locale (which is
|
|
@@ -196,6 +201,7 @@ session start/end and unhandled errors are automatic. The rest is instrumented b
|
|
|
196
201
|
| `trackSearch(query, resultsCount, params?)` | Searches, with `has_results` derived |
|
|
197
202
|
| `trackFunnelStep(funnel, step, taskId, params?)` | A funnel step, correlated by `taskId` |
|
|
198
203
|
| `trackFindabilityFriction(topic, params?)` | Friction signal |
|
|
204
|
+
| `trackMeaningfulInteraction(interactionType, params?)` | A meaningful interaction, grouped by `interaction_type` |
|
|
199
205
|
| `enterMiniService(name, entryPointType?)` / `exitMiniService(name)` | Mini-service, with duration |
|
|
200
206
|
| `setUserAttributes(map)` / `setMetric(key, value)` | Breakdown dimensions / measurable values |
|
|
201
207
|
| `setUserId(userId?)` | Login, logout or account switch |
|
package/dist/index.d.mts
CHANGED
|
@@ -256,6 +256,15 @@ interface DeepdotsInitParams {
|
|
|
256
256
|
* `setContactAttributes` after init (sends only when values changed from the last sync).
|
|
257
257
|
*/
|
|
258
258
|
contactAttributes?: Record<string, string | number | boolean>;
|
|
259
|
+
/**
|
|
260
|
+
* Whether the SDK renders the popup "modal" (card + backdrop + positioning) around the survey.
|
|
261
|
+
* Default `true`. Only affects React Native (the survey WebView HTML); the web DOM popup is
|
|
262
|
+
* unaffected. With `false` the survey is delivered transparent and edge-to-edge so the host
|
|
263
|
+
* mounts its own Modal/container and controls the styling — avoids the "double modal" when the
|
|
264
|
+
* host already wraps the WebView. The survey stays fully functional (bridge, form, nav buttons,
|
|
265
|
+
* close). Ver `ReactNativePopupRenderer`.
|
|
266
|
+
*/
|
|
267
|
+
renderChrome?: boolean;
|
|
259
268
|
}
|
|
260
269
|
interface DeepdotsConfig {
|
|
261
270
|
/** API key for authentication */
|
|
@@ -388,7 +397,7 @@ interface PopupRenderer {
|
|
|
388
397
|
/** Preparar recursos si aplica */
|
|
389
398
|
init?(): void;
|
|
390
399
|
/** Mostrar popup */
|
|
391
|
-
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string): void;
|
|
400
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean): void;
|
|
392
401
|
/** Ocultar popup */
|
|
393
402
|
hide(): void;
|
|
394
403
|
}
|
|
@@ -402,7 +411,7 @@ declare class BrowserPopupRenderer implements PopupRenderer {
|
|
|
402
411
|
private container;
|
|
403
412
|
private visible;
|
|
404
413
|
init(): void;
|
|
405
|
-
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string): void;
|
|
414
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, _renderChrome?: boolean): void;
|
|
406
415
|
hide(): void;
|
|
407
416
|
}
|
|
408
417
|
/** Factoría para obtener renderer por defecto */
|
|
@@ -602,6 +611,8 @@ declare class DeepdotsPopups {
|
|
|
602
611
|
private deferredExitTimers;
|
|
603
612
|
private baseUrl;
|
|
604
613
|
private env;
|
|
614
|
+
/** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
|
|
615
|
+
private renderChrome;
|
|
605
616
|
/** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
|
|
606
617
|
private tracking;
|
|
607
618
|
/** Capa de analytics (canal separado del feedback). Null hasta init(). */
|
|
@@ -673,6 +684,15 @@ declare class DeepdotsPopups {
|
|
|
673
684
|
trackFindabilityFriction(frictionTopic: string, params?: Record<string, unknown>): void;
|
|
674
685
|
/** Funnel: un paso del embudo, correlacionado por `taskId`. El backend reconstruye conversión/drop-off/tiempo. */
|
|
675
686
|
trackFunnelStep(funnel: string, step: string, taskId: string, params?: Record<string, unknown>): void;
|
|
687
|
+
/**
|
|
688
|
+
* Product Effectiveness: una interacción significativa del usuario (`interaction_type` es la
|
|
689
|
+
* dimensión de agrupación, p. ej. `get_help`, `homepage`, `contact_support`).
|
|
690
|
+
*
|
|
691
|
+
* Existe como evento RESERVADO para que la convención no la invente cada host: un `track()`
|
|
692
|
+
* custom acaba como `deepdots_event_…` y no lo cuenta la analítica de effectiveness.
|
|
693
|
+
* Un `interactionType` vacío se descarta con warning (no aporta dato agrupable).
|
|
694
|
+
*/
|
|
695
|
+
trackMeaningfulInteraction(interactionType: string, params?: Record<string, unknown>): void;
|
|
676
696
|
/**
|
|
677
697
|
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
678
698
|
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
@@ -847,7 +867,7 @@ declare class ReactNativePopupRenderer implements PopupRenderer {
|
|
|
847
867
|
private partialEmitted;
|
|
848
868
|
constructor(options?: ReactNativeRendererOptions);
|
|
849
869
|
init(): void;
|
|
850
|
-
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: EmitFn, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string): void;
|
|
870
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: EmitFn, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean): void;
|
|
851
871
|
hide(): void;
|
|
852
872
|
/**
|
|
853
873
|
* El host la conecta al `onMessage` del WebView. Traduce los mensajes del survey a
|
|
@@ -880,6 +900,13 @@ interface BuildSurveyHtmlOptions {
|
|
|
880
900
|
theme?: 'light' | 'dark';
|
|
881
901
|
position?: 'bottom' | 'bottom-right' | 'bottom-left' | 'top' | 'top-right' | 'top-left' | 'center';
|
|
882
902
|
actions?: PopupActions;
|
|
903
|
+
/**
|
|
904
|
+
* Renderiza el "modal" del popup (tarjeta con fondo/sombra/bordes + overlay + posicionamiento).
|
|
905
|
+
* Default `true`. Con `false` el HTML es transparente y llena el contenedor: el host monta su
|
|
906
|
+
* propio Modal/tarjeta y controla el estilo. El survey sigue siendo funcional (bridge, form,
|
|
907
|
+
* botones y botón de cerrar). Pensado para React Native cuando el host gestiona el contenedor.
|
|
908
|
+
*/
|
|
909
|
+
chrome?: boolean;
|
|
883
910
|
}
|
|
884
911
|
declare function buildSurveyHtml(opts: BuildSurveyHtmlOptions): string;
|
|
885
912
|
|
package/dist/index.d.ts
CHANGED
|
@@ -256,6 +256,15 @@ interface DeepdotsInitParams {
|
|
|
256
256
|
* `setContactAttributes` after init (sends only when values changed from the last sync).
|
|
257
257
|
*/
|
|
258
258
|
contactAttributes?: Record<string, string | number | boolean>;
|
|
259
|
+
/**
|
|
260
|
+
* Whether the SDK renders the popup "modal" (card + backdrop + positioning) around the survey.
|
|
261
|
+
* Default `true`. Only affects React Native (the survey WebView HTML); the web DOM popup is
|
|
262
|
+
* unaffected. With `false` the survey is delivered transparent and edge-to-edge so the host
|
|
263
|
+
* mounts its own Modal/container and controls the styling — avoids the "double modal" when the
|
|
264
|
+
* host already wraps the WebView. The survey stays fully functional (bridge, form, nav buttons,
|
|
265
|
+
* close). Ver `ReactNativePopupRenderer`.
|
|
266
|
+
*/
|
|
267
|
+
renderChrome?: boolean;
|
|
259
268
|
}
|
|
260
269
|
interface DeepdotsConfig {
|
|
261
270
|
/** API key for authentication */
|
|
@@ -388,7 +397,7 @@ interface PopupRenderer {
|
|
|
388
397
|
/** Preparar recursos si aplica */
|
|
389
398
|
init?(): void;
|
|
390
399
|
/** Mostrar popup */
|
|
391
|
-
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string): void;
|
|
400
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean): void;
|
|
392
401
|
/** Ocultar popup */
|
|
393
402
|
hide(): void;
|
|
394
403
|
}
|
|
@@ -402,7 +411,7 @@ declare class BrowserPopupRenderer implements PopupRenderer {
|
|
|
402
411
|
private container;
|
|
403
412
|
private visible;
|
|
404
413
|
init(): void;
|
|
405
|
-
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string): void;
|
|
414
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, _renderChrome?: boolean): void;
|
|
406
415
|
hide(): void;
|
|
407
416
|
}
|
|
408
417
|
/** Factoría para obtener renderer por defecto */
|
|
@@ -602,6 +611,8 @@ declare class DeepdotsPopups {
|
|
|
602
611
|
private deferredExitTimers;
|
|
603
612
|
private baseUrl;
|
|
604
613
|
private env;
|
|
614
|
+
/** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
|
|
615
|
+
private renderChrome;
|
|
605
616
|
/** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
|
|
606
617
|
private tracking;
|
|
607
618
|
/** Capa de analytics (canal separado del feedback). Null hasta init(). */
|
|
@@ -673,6 +684,15 @@ declare class DeepdotsPopups {
|
|
|
673
684
|
trackFindabilityFriction(frictionTopic: string, params?: Record<string, unknown>): void;
|
|
674
685
|
/** Funnel: un paso del embudo, correlacionado por `taskId`. El backend reconstruye conversión/drop-off/tiempo. */
|
|
675
686
|
trackFunnelStep(funnel: string, step: string, taskId: string, params?: Record<string, unknown>): void;
|
|
687
|
+
/**
|
|
688
|
+
* Product Effectiveness: una interacción significativa del usuario (`interaction_type` es la
|
|
689
|
+
* dimensión de agrupación, p. ej. `get_help`, `homepage`, `contact_support`).
|
|
690
|
+
*
|
|
691
|
+
* Existe como evento RESERVADO para que la convención no la invente cada host: un `track()`
|
|
692
|
+
* custom acaba como `deepdots_event_…` y no lo cuenta la analítica de effectiveness.
|
|
693
|
+
* Un `interactionType` vacío se descarta con warning (no aporta dato agrupable).
|
|
694
|
+
*/
|
|
695
|
+
trackMeaningfulInteraction(interactionType: string, params?: Record<string, unknown>): void;
|
|
676
696
|
/**
|
|
677
697
|
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
678
698
|
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
@@ -847,7 +867,7 @@ declare class ReactNativePopupRenderer implements PopupRenderer {
|
|
|
847
867
|
private partialEmitted;
|
|
848
868
|
constructor(options?: ReactNativeRendererOptions);
|
|
849
869
|
init(): void;
|
|
850
|
-
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: EmitFn, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string): void;
|
|
870
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: EmitFn, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean): void;
|
|
851
871
|
hide(): void;
|
|
852
872
|
/**
|
|
853
873
|
* El host la conecta al `onMessage` del WebView. Traduce los mensajes del survey a
|
|
@@ -880,6 +900,13 @@ interface BuildSurveyHtmlOptions {
|
|
|
880
900
|
theme?: 'light' | 'dark';
|
|
881
901
|
position?: 'bottom' | 'bottom-right' | 'bottom-left' | 'top' | 'top-right' | 'top-left' | 'center';
|
|
882
902
|
actions?: PopupActions;
|
|
903
|
+
/**
|
|
904
|
+
* Renderiza el "modal" del popup (tarjeta con fondo/sombra/bordes + overlay + posicionamiento).
|
|
905
|
+
* Default `true`. Con `false` el HTML es transparente y llena el contenedor: el host monta su
|
|
906
|
+
* propio Modal/tarjeta y controla el estilo. El survey sigue siendo funcional (bridge, form,
|
|
907
|
+
* botones y botón de cerrar). Pensado para React Native cuando el host gestiona el contenedor.
|
|
908
|
+
*/
|
|
909
|
+
chrome?: boolean;
|
|
883
910
|
}
|
|
884
911
|
declare function buildSurveyHtml(opts: BuildSurveyHtmlOptions): string;
|
|
885
912
|
|
package/dist/index.js
CHANGED
|
@@ -2542,7 +2542,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2542
2542
|
};
|
|
2543
2543
|
generateOptions.onLoadedEvent = ({ formData }) => {
|
|
2544
2544
|
try {
|
|
2545
|
-
} catch
|
|
2545
|
+
} catch {
|
|
2546
2546
|
}
|
|
2547
2547
|
const s = formData?.style;
|
|
2548
2548
|
if (s && !stylesInjected) {
|
|
@@ -2720,6 +2720,10 @@ var POPUP_TRIGGER_CONDITION_STATUSES = [
|
|
|
2720
2720
|
];
|
|
2721
2721
|
|
|
2722
2722
|
// src/triggers/index.ts
|
|
2723
|
+
function toNumericValue(value, fallback) {
|
|
2724
|
+
const n = Number(value);
|
|
2725
|
+
return Number.isFinite(n) ? n : fallback;
|
|
2726
|
+
}
|
|
2723
2727
|
function setupTrigger(popups, trigger) {
|
|
2724
2728
|
switch (trigger.type) {
|
|
2725
2729
|
case "time":
|
|
@@ -2740,14 +2744,14 @@ function setupTrigger(popups, trigger) {
|
|
|
2740
2744
|
}
|
|
2741
2745
|
}
|
|
2742
2746
|
function setupTimeTrigger(popups, trigger) {
|
|
2743
|
-
const delay = trigger.value
|
|
2747
|
+
const delay = toNumericValue(trigger.value, 5e3);
|
|
2744
2748
|
setTimeout(() => {
|
|
2745
2749
|
popups.triggerSurvey(trigger.surveyId, trigger.popupId);
|
|
2746
2750
|
}, delay);
|
|
2747
2751
|
popups.debug(`Time trigger set for ${delay}ms`);
|
|
2748
2752
|
}
|
|
2749
2753
|
function setupScrollTrigger(popups, trigger) {
|
|
2750
|
-
const threshold = trigger.value
|
|
2754
|
+
const threshold = toNumericValue(trigger.value, 50);
|
|
2751
2755
|
const handler = () => {
|
|
2752
2756
|
const scrollPercentage = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) * 100;
|
|
2753
2757
|
if (scrollPercentage >= threshold) {
|
|
@@ -2927,6 +2931,16 @@ function buildSurveyHtml(opts) {
|
|
|
2927
2931
|
const colorScheme = isDark ? "dark" : "light";
|
|
2928
2932
|
const textPrimary = isDark ? "#f0f0f0" : "#111";
|
|
2929
2933
|
const pos = POSITION_MAP[opts.position ?? "center"] ?? POSITION_MAP.center;
|
|
2934
|
+
const chrome = opts.chrome !== false;
|
|
2935
|
+
const bodyBg = chrome ? pos.background : "transparent";
|
|
2936
|
+
const bodyPadding = chrome ? pos.padding : "0";
|
|
2937
|
+
const bodyDisplay = chrome ? "flex" : "block";
|
|
2938
|
+
const cardBg = chrome ? popupBg : "transparent";
|
|
2939
|
+
const cardShadow = chrome ? "0 4px 6px rgba(0,0,0,0.1)" : "none";
|
|
2940
|
+
const cardRadius = chrome ? "8px" : "0";
|
|
2941
|
+
const cardMaxWidth = chrome ? "600px" : "none";
|
|
2942
|
+
const cardWidth = chrome ? "90%" : "100%";
|
|
2943
|
+
const cardMinHeight = chrome ? "200px" : "0";
|
|
2930
2944
|
const backLabel = JSON.stringify(opts.actions?.back?.label ?? "Back");
|
|
2931
2945
|
const startLabel = JSON.stringify(opts.actions?.start?.label ?? "Start survey");
|
|
2932
2946
|
const completeLabel = JSON.stringify(opts.actions?.complete?.label ?? "Complete survey");
|
|
@@ -2938,8 +2952,8 @@ function buildSurveyHtml(opts) {
|
|
|
2938
2952
|
${style_default}
|
|
2939
2953
|
${fontFaceCss}
|
|
2940
2954
|
html,body{margin:0;padding:0;height:100%;font-family:${fontFamilyValue}}
|
|
2941
|
-
body{display
|
|
2942
|
-
.deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${
|
|
2955
|
+
body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${pos.alignItems};background:${bodyBg};padding:${bodyPadding};box-sizing:border-box}
|
|
2956
|
+
.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}
|
|
2943
2957
|
.deepdots-popup-header{display:flex;justify-content:flex-end;align-items:center;width:100%}
|
|
2944
2958
|
#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}
|
|
2945
2959
|
.deepdots-popup-container-content{display:flex;flex-direction:column;padding:0 20px 12px 20px;max-height:80vh;overflow:hidden;box-sizing:border-box}
|
|
@@ -2997,6 +3011,7 @@ body{display:flex;justify-content:${pos.justifyContent};align-items:${pos.alignI
|
|
|
2997
3011
|
function emit(s){ try{ if(window.ReactNativeWebView){ window.ReactNativeWebView.postMessage(s); } }catch(e){} }
|
|
2998
3012
|
function emitJSON(n,p){ try{ emit(JSON.stringify({name:n,payload:p||{}})); }catch(e){} }
|
|
2999
3013
|
window.DeepdotsClose = function(){ emitJSON('popup_close'); };
|
|
3014
|
+
var chromeOn=${chrome ? "true" : "false"};
|
|
3000
3015
|
|
|
3001
3016
|
var popup=document.getElementById('dd-popup');
|
|
3002
3017
|
var main=document.getElementById('dd-main');
|
|
@@ -3072,7 +3087,7 @@ body{display:flex;justify-content:${pos.justifyContent};align-items:${pos.alignI
|
|
|
3072
3087
|
var s=args && args.formData ? args.formData.style : null;
|
|
3073
3088
|
if(s && !stylesInjected){
|
|
3074
3089
|
stylesInjected=true;
|
|
3075
|
-
if(s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
3090
|
+
if(chromeOn && s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
3076
3091
|
if(s.contentAlign){ main.style.justifyContent = s.contentAlign==='center' ? 'center' : 'flex-start'; }
|
|
3077
3092
|
if(s.buttonPrimaryColor){
|
|
3078
3093
|
submitBtn.style.background=s.buttonPrimaryColor; submitBtn.style.border='none'; submitBtn.style.color='#fff';
|
|
@@ -3162,7 +3177,7 @@ var ReactNativePopupRenderer = class {
|
|
|
3162
3177
|
}
|
|
3163
3178
|
init() {
|
|
3164
3179
|
}
|
|
3165
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
3180
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome) {
|
|
3166
3181
|
this.emitFn = emit;
|
|
3167
3182
|
this.onCloseFn = onClose;
|
|
3168
3183
|
this.currentSurveyId = surveyId;
|
|
@@ -3177,7 +3192,9 @@ var ReactNativePopupRenderer = class {
|
|
|
3177
3192
|
font: style?.font,
|
|
3178
3193
|
theme: style?.theme,
|
|
3179
3194
|
position: style?.position,
|
|
3180
|
-
actions
|
|
3195
|
+
actions,
|
|
3196
|
+
// renderChrome:false (init) → HTML sin tarjeta/overlay: el host lo envuelve en su Modal.
|
|
3197
|
+
chrome: renderChrome
|
|
3181
3198
|
});
|
|
3182
3199
|
if (this.options.onShow) {
|
|
3183
3200
|
this.options.onShow({ surveyId, productId, html });
|
|
@@ -3268,7 +3285,7 @@ var BrowserPopupRenderer = class {
|
|
|
3268
3285
|
document.body.appendChild(this.container);
|
|
3269
3286
|
}
|
|
3270
3287
|
}
|
|
3271
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
3288
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome) {
|
|
3272
3289
|
if (this.visible) return;
|
|
3273
3290
|
if (!this.container || !document.body.contains(this.container)) this.init();
|
|
3274
3291
|
if (!this.container) return;
|
|
@@ -4129,6 +4146,8 @@ var DeepdotsPopups = class {
|
|
|
4129
4146
|
this.deferredExitTimers = [];
|
|
4130
4147
|
this.baseUrl = "";
|
|
4131
4148
|
this.env = "production";
|
|
4149
|
+
/** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
|
|
4150
|
+
this.renderChrome = true;
|
|
4132
4151
|
/** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
|
|
4133
4152
|
this.tracking = null;
|
|
4134
4153
|
/** Capa de analytics (canal separado del feedback). Null hasta init(). */
|
|
@@ -4179,6 +4198,7 @@ var DeepdotsPopups = class {
|
|
|
4179
4198
|
const env = resolveEnvironment(config.nodeEnv);
|
|
4180
4199
|
this.baseUrl = env.apiBaseUrl;
|
|
4181
4200
|
this.env = config.nodeEnv || "production";
|
|
4201
|
+
this.renderChrome = config.renderChrome ?? true;
|
|
4182
4202
|
this.config = {
|
|
4183
4203
|
apiKey: config.apiKey || void 0,
|
|
4184
4204
|
debug: config.debug || false,
|
|
@@ -4364,6 +4384,22 @@ var DeepdotsPopups = class {
|
|
|
4364
4384
|
trackFunnelStep(funnel, step, taskId, params) {
|
|
4365
4385
|
this.track("deepdots_funnel_step", { funnel, step, task_id: taskId, ...params ?? {} });
|
|
4366
4386
|
}
|
|
4387
|
+
/**
|
|
4388
|
+
* Product Effectiveness: una interacción significativa del usuario (`interaction_type` es la
|
|
4389
|
+
* dimensión de agrupación, p. ej. `get_help`, `homepage`, `contact_support`).
|
|
4390
|
+
*
|
|
4391
|
+
* Existe como evento RESERVADO para que la convención no la invente cada host: un `track()`
|
|
4392
|
+
* custom acaba como `deepdots_event_…` y no lo cuenta la analítica de effectiveness.
|
|
4393
|
+
* Un `interactionType` vacío se descarta con warning (no aporta dato agrupable).
|
|
4394
|
+
*/
|
|
4395
|
+
trackMeaningfulInteraction(interactionType, params) {
|
|
4396
|
+
const type = typeof interactionType === "string" ? interactionType.trim() : "";
|
|
4397
|
+
if (!type) {
|
|
4398
|
+
console.warn("[DeepdotsPopups] trackMeaningfulInteraction discarded: empty interaction_type");
|
|
4399
|
+
return;
|
|
4400
|
+
}
|
|
4401
|
+
this.track("deepdots_meaningful_interaction", { interaction_type: type, ...params ?? {} });
|
|
4402
|
+
}
|
|
4367
4403
|
/**
|
|
4368
4404
|
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
4369
4405
|
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
@@ -4964,7 +5000,8 @@ var DeepdotsPopups = class {
|
|
|
4964
5000
|
style,
|
|
4965
5001
|
sessionId,
|
|
4966
5002
|
miniService,
|
|
4967
|
-
analyticsFeedbackSessionId
|
|
5003
|
+
analyticsFeedbackSessionId,
|
|
5004
|
+
this.renderChrome
|
|
4968
5005
|
);
|
|
4969
5006
|
return;
|
|
4970
5007
|
}
|