@magicfeedback/popup-sdk 1.0.0 → 1.0.2
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 +170 -238
- package/dist/index.d.mts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +3554 -1680
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3553 -1679
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,169 +1,155 @@
|
|
|
1
|
-
#
|
|
1
|
+
# MagicFeedback Popup SDK
|
|
2
2
|
|
|
3
3
|
TypeScript SDK to render and manage survey popups for MagicFeedback.
|
|
4
4
|
|
|
5
|
+
> Current package name: `@magicfeedback/popup-sdk`
|
|
6
|
+
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
|
-
npm install
|
|
10
|
+
npm install @magicfeedback/popup-sdk
|
|
9
11
|
```
|
|
10
12
|
|
|
11
13
|
## Quick Start
|
|
12
14
|
|
|
13
15
|
```typescript
|
|
14
|
-
import {
|
|
16
|
+
import {DeepdotsPopups} from '@magicfeedback/popup-sdk';
|
|
15
17
|
|
|
16
|
-
//
|
|
18
|
+
// Basic initialization
|
|
17
19
|
const popups = new DeepdotsPopups();
|
|
18
20
|
popups.init({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
debug: true, // enable verbose logging
|
|
22
|
+
mode: 'client', // 'client' (preloaded definitions) | 'server' (fake async load for now)
|
|
23
|
+
popups: [ // optional in client mode
|
|
24
|
+
{
|
|
25
|
+
id: 'popup-123',
|
|
26
|
+
title: 'Help us improve?',
|
|
27
|
+
message: '<p>Take a quick survey and share your thoughts.</p>',
|
|
28
|
+
trigger: {type: 'time_on_page', value: 5, condition: [{answered: false, cooldownDays: 7}]},
|
|
29
|
+
actions: {
|
|
30
|
+
accept: {label: 'Take Survey', surveyId: 'survey-abc'},
|
|
31
|
+
decline: {label: 'Not Now', cooldownDays: 7}
|
|
32
|
+
},
|
|
33
|
+
surveyId: 'survey-abc',
|
|
34
|
+
productId: 'product-xyz',
|
|
35
|
+
style: {theme: 'light', position: 'bottom-right', imageUrl: null},
|
|
36
|
+
segments: {lang: ['en'], path: ['/checkout']}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
21
39
|
});
|
|
22
40
|
|
|
23
|
-
// Show a popup immediately
|
|
41
|
+
// Show a popup immediately
|
|
24
42
|
popups.show({
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
surveyId: 'survey-abc',
|
|
44
|
+
productId: 'product-xyz',
|
|
45
|
+
data: {source: 'homepage'}
|
|
27
46
|
});
|
|
28
47
|
|
|
29
48
|
// Listen to events
|
|
30
|
-
popups.on('popup_shown', (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
popups.on('survey_completed', (event) => {
|
|
35
|
-
console.log('Survey completed:', event);
|
|
36
|
-
});
|
|
49
|
+
popups.on('popup_shown', (ev) => console.log('Shown:', ev));
|
|
50
|
+
popups.on('popup_clicked', (ev) => console.log('Clicked:', ev));
|
|
51
|
+
popups.on('survey_completed', (ev) => console.log('Completed:', ev));
|
|
37
52
|
```
|
|
38
53
|
|
|
39
54
|
## Features
|
|
40
55
|
|
|
41
|
-
- ✅ Simple API:
|
|
42
|
-
- ✅ Auto-launch
|
|
43
|
-
- ✅ Automatic trigger derivation from
|
|
44
|
-
- ✅ Conditions &
|
|
45
|
-
- ✅ Event
|
|
46
|
-
- ✅
|
|
47
|
-
- ✅
|
|
48
|
-
- ✅
|
|
56
|
+
- ✅ Simple API: initialize and show popups with minimal code
|
|
57
|
+
- ✅ Auto-launch triggers: time, scroll, exit intent
|
|
58
|
+
- ✅ Automatic trigger derivation from popup definitions (`time_on_page` → internal `time` in ms)
|
|
59
|
+
- ✅ Conditions & cooldowns: prevent display if already answered or within cooldown window
|
|
60
|
+
- ✅ Event system: `popup_shown`, `popup_clicked`, `survey_completed`
|
|
61
|
+
- ✅ Renderer abstraction: browser, React Native stub, SSR-friendly no-op
|
|
62
|
+
- ✅ TypeScript: full type definitions
|
|
63
|
+
- ✅ Lightweight: zero runtime dependencies for core logic
|
|
64
|
+
- ✅ Framework agnostic: works in vanilla JS or any framework
|
|
49
65
|
|
|
50
66
|
## API Reference
|
|
51
67
|
|
|
52
|
-
### `DeepdotsPopups`
|
|
53
|
-
|
|
54
|
-
Main class for managing survey popups.
|
|
68
|
+
### Class: `DeepdotsPopups`
|
|
69
|
+
Main class for configuring and displaying survey popups.
|
|
55
70
|
|
|
56
|
-
####
|
|
57
|
-
|
|
58
|
-
##### `init(config: DeepdotsInitParams): void`
|
|
59
|
-
|
|
60
|
-
Initialize the SDK with configuration.
|
|
71
|
+
#### `init(config: DeepdotsInitParams): void`
|
|
72
|
+
Initializes the SDK. Must be called before other methods.
|
|
61
73
|
|
|
62
74
|
```typescript
|
|
63
75
|
popups.init({
|
|
64
|
-
apiKey: 'your-
|
|
65
|
-
nodeEnv: 'production',
|
|
66
|
-
mode: 'client',
|
|
67
|
-
debug: false,
|
|
68
|
-
popups: [
|
|
69
|
-
{
|
|
70
|
-
id: 'popup-123',
|
|
71
|
-
title: 'Would you like to help us improve?',
|
|
72
|
-
message: '<p>Take a quick survey and share your thoughts.</p>',
|
|
73
|
-
trigger: { type: 'time_on_page', value: 5, condition: [{ answered: false, cooldownDays: 7 }] },
|
|
74
|
-
actions: {
|
|
75
|
-
accept: { label: 'Take Survey', surveyId: 'survey-abc' },
|
|
76
|
-
decline: { label: 'Not Now', cooldownDays: 7 }
|
|
77
|
-
},
|
|
78
|
-
surveyId: 'survey-abc',
|
|
79
|
-
productId: 'product-xyz',
|
|
80
|
-
style: { theme: 'light', position: 'bottom-right', imageUrl: null },
|
|
81
|
-
segments: { lang: ['en'], path: ['/checkout'] }
|
|
82
|
-
}
|
|
83
|
-
]
|
|
76
|
+
apiKey: 'your-key', // optional
|
|
77
|
+
nodeEnv: 'production', // optional: influences internal baseUrl
|
|
78
|
+
mode: 'client', // 'client' or 'server'
|
|
79
|
+
debug: false, // verbose logging
|
|
80
|
+
popups: [ /* PopupDefinition[] (client mode only) */ ]
|
|
84
81
|
});
|
|
85
82
|
```
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
##### `show(options: ShowOptions): void`
|
|
84
|
+
In `server` mode popups are (currently) loaded via a simulated async fetch; triggers derived after load will start when `autoLaunch()` runs or once loading completes.
|
|
90
85
|
|
|
91
|
-
|
|
86
|
+
#### `show(options: ShowOptions): void`
|
|
87
|
+
Displays a popup for a survey immediately. `productId` is required.
|
|
92
88
|
|
|
93
89
|
```typescript
|
|
94
|
-
popups.show({
|
|
95
|
-
surveyId: 'survey-123',
|
|
96
|
-
productId: 'product-xyz', // REQUIRED now
|
|
97
|
-
data: { // Optional custom data passed to events
|
|
98
|
-
userId: 'user-456',
|
|
99
|
-
source: 'homepage'
|
|
100
|
-
}
|
|
101
|
-
});
|
|
90
|
+
popups.show({ surveyId: 'survey-xyz', productId: 'product-123', data: { plan: 'pro' } });
|
|
102
91
|
```
|
|
103
92
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Show a popup using its definition `id` (will internally map to `surveyId`).
|
|
93
|
+
#### `showByPopupId(popupId: string): void`
|
|
94
|
+
Displays a popup using its definition `id` (internally maps to `surveyId` + `productId`).
|
|
107
95
|
|
|
108
96
|
```typescript
|
|
109
97
|
popups.showByPopupId('popup-123');
|
|
110
98
|
```
|
|
111
99
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Manually configure triggers for auto-launching popups.
|
|
100
|
+
#### `configureTriggers(triggers: TriggerConfig[]): void`
|
|
101
|
+
Registers manual triggers.
|
|
115
102
|
|
|
116
103
|
```typescript
|
|
117
104
|
popups.configureTriggers([
|
|
118
|
-
{ type: 'time', value: 5000, surveyId: 'survey-
|
|
119
|
-
{ type: 'scroll', value:
|
|
120
|
-
{ type: 'exit', surveyId: 'survey-
|
|
105
|
+
{ type: 'time', value: 5000, surveyId: 'survey-1' },
|
|
106
|
+
{ type: 'scroll', value: 60, surveyId: 'survey-2' },
|
|
107
|
+
{ type: 'exit', surveyId: 'survey-3' }
|
|
121
108
|
]);
|
|
122
109
|
```
|
|
123
110
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Enable auto-launch functionality with previously configured triggers OR triggers derived automatically from popup definitions.
|
|
111
|
+
#### `autoLaunch(): void`
|
|
112
|
+
Starts automatic trigger evaluation. If popups are not yet loaded (server mode) call is deferred until load completes.
|
|
127
113
|
|
|
128
114
|
```typescript
|
|
129
115
|
popups.autoLaunch();
|
|
130
116
|
```
|
|
131
117
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Internal trigger evaluation + display (used by trigger system). You normally don't call this directly; use `configureTriggers` + `autoLaunch`.
|
|
118
|
+
#### `triggerSurvey(surveyId: string): void`
|
|
119
|
+
Evaluates conditions and, if allowed, shows a popup for the specified survey. Used internally by trigger handlers; you normally don’t call this directly.
|
|
135
120
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Manually mark a survey as answered (affects future conditions like `answered: false`).
|
|
121
|
+
#### `markSurveyAnswered(surveyId: string): void`
|
|
122
|
+
Marks a survey as answered to satisfy conditions like `{ answered: false }`.
|
|
139
123
|
|
|
140
124
|
```typescript
|
|
141
|
-
popups.markSurveyAnswered('survey-
|
|
125
|
+
popups.markSurveyAnswered('survey-xyz');
|
|
142
126
|
```
|
|
143
127
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
Add an event listener.
|
|
128
|
+
#### `on(type, listener)` / `off(type, listener)`
|
|
129
|
+
Add or remove event listeners.
|
|
147
130
|
|
|
148
131
|
```typescript
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
132
|
+
const handler = (ev) => console.log(ev);
|
|
133
|
+
popups.on('popup_shown', handler);
|
|
134
|
+
popups.off('popup_shown', handler);
|
|
152
135
|
```
|
|
153
136
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Remove an event listener.
|
|
137
|
+
#### `setRenderer(renderer: PopupRenderer): void`
|
|
138
|
+
Inject a custom renderer (e.g. native mobile). If called after `init` and the renderer has `init()`, it's invoked automatically.
|
|
157
139
|
|
|
158
140
|
```typescript
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
141
|
+
import { ReactNativePopupRenderer } from './my-native-renderer';
|
|
142
|
+
const sdk = new DeepdotsPopups();
|
|
143
|
+
sdk.setRenderer(new ReactNativePopupRenderer());
|
|
144
|
+
sdk.init({ mode: 'client', popups: [...] });
|
|
162
145
|
```
|
|
163
146
|
|
|
164
|
-
|
|
147
|
+
## Popup Definitions
|
|
165
148
|
|
|
166
|
-
When
|
|
149
|
+
When using `client` mode you can preload definitions. In `server` mode a fake fetch creates sample definitions. Trigger types in definitions:
|
|
150
|
+
- `time_on_page` (seconds) → mapped automatically to internal `time` trigger (milliseconds)
|
|
151
|
+
- `scroll` (percentage scrolled)
|
|
152
|
+
- `exit` (exit intent)
|
|
167
153
|
|
|
168
154
|
Structure:
|
|
169
155
|
|
|
@@ -174,8 +160,8 @@ interface PopupDefinition {
|
|
|
174
160
|
message: string; // HTML string
|
|
175
161
|
trigger: {
|
|
176
162
|
type: 'time_on_page' | 'scroll' | 'exit';
|
|
177
|
-
value: number; // seconds
|
|
178
|
-
condition?: { answered: boolean; cooldownDays: number
|
|
163
|
+
value: number; // seconds (time_on_page) or percentage (scroll)
|
|
164
|
+
condition?: { answered: boolean; cooldownDays: number }[];
|
|
179
165
|
};
|
|
180
166
|
actions: {
|
|
181
167
|
accept: { label: string; surveyId: string };
|
|
@@ -183,108 +169,94 @@ interface PopupDefinition {
|
|
|
183
169
|
};
|
|
184
170
|
surveyId: string;
|
|
185
171
|
productId: string;
|
|
186
|
-
style: {
|
|
172
|
+
style: {
|
|
173
|
+
theme: 'light' | 'dark';
|
|
174
|
+
position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'center';
|
|
175
|
+
imageUrl: string | null;
|
|
176
|
+
};
|
|
187
177
|
segments?: { lang?: string[]; path?: string[]; [key: string]: unknown };
|
|
188
178
|
}
|
|
189
179
|
```
|
|
190
180
|
|
|
191
|
-
Conditions
|
|
181
|
+
### Conditions
|
|
182
|
+
- `answered: false` → show only if survey not yet completed
|
|
183
|
+
- `cooldownDays: N` → do not show again until N days have passed since last display (per popup definition `id`)
|
|
192
184
|
|
|
193
|
-
|
|
194
|
-
- `cooldownDays: X` → don't show again until X days have passed since last display
|
|
185
|
+
## Events
|
|
195
186
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
- `popup_shown`: Fired when a popup is displayed
|
|
201
|
-
- `popup_clicked`: Fired on the first interaction (form load or manual click)
|
|
202
|
-
- `survey_completed`: Fired when a user completes the survey
|
|
203
|
-
|
|
204
|
-
Each event includes:
|
|
187
|
+
Emitted events:
|
|
188
|
+
- `popup_shown`
|
|
189
|
+
- `popup_clicked` (first interaction / initial rendering)
|
|
190
|
+
- `survey_completed`
|
|
205
191
|
|
|
192
|
+
Payload:
|
|
206
193
|
```typescript
|
|
207
|
-
{
|
|
208
|
-
type: 'popup_shown' | 'popup_clicked' | 'survey_completed'
|
|
209
|
-
surveyId: string
|
|
210
|
-
timestamp: number
|
|
211
|
-
data?: Record<string, unknown
|
|
194
|
+
interface DeepdotsEvent {
|
|
195
|
+
type: 'popup_shown' | 'popup_clicked' | 'survey_completed';
|
|
196
|
+
surveyId: string;
|
|
197
|
+
timestamp: number;
|
|
198
|
+
data?: Record<string, unknown>;
|
|
212
199
|
}
|
|
213
200
|
```
|
|
214
201
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
#### Time Trigger (`type: 'time'`)
|
|
218
|
-
Show popup after a specified delay in milliseconds.
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
{ type: 'time', value: 5000, surveyId: 'survey-123' }
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
#### Scroll Trigger (`type: 'scroll'`)
|
|
225
|
-
Show popup when user scrolls to a certain percentage of the page.
|
|
202
|
+
## Trigger Types (Manual Mode)
|
|
226
203
|
|
|
227
204
|
```typescript
|
|
228
|
-
{ type: '
|
|
205
|
+
{ type: 'time', value: 5000, surveyId: 'survey-1' } // after 5s
|
|
206
|
+
{ type: 'scroll', value: 50, surveyId: 'survey-2' } // at 50% scroll
|
|
207
|
+
{ type: 'exit', surveyId: 'survey-3' } // exit intent
|
|
229
208
|
```
|
|
230
209
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
{ type: 'exit', surveyId: 'survey-123' }
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Automatic Trigger Derivation
|
|
239
|
-
When using popup definitions, remote trigger types like `time_on_page` are mapped to internal `time` triggers (seconds → milliseconds) and started automatically after `autoLaunch()`.
|
|
210
|
+
## Automatic Trigger Derivation
|
|
211
|
+
When definitions are loaded, each `time_on_page` trigger is converted to `{ type: 'time', value: seconds * 1000 }`. You just call `autoLaunch()` and derived triggers start.
|
|
240
212
|
|
|
241
213
|
## Styling & Container
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
## Examples
|
|
245
|
-
|
|
246
|
-
See the [examples](./examples) directory for a complete demo.
|
|
247
|
-
|
|
248
|
-
To run the demo:
|
|
249
|
-
|
|
250
|
-
1. Open `examples/demo.html` in your browser
|
|
251
|
-
2. Try different triggers and see events in the console
|
|
252
|
-
|
|
253
|
-
## Development
|
|
214
|
+
Browser renderer creates a container `#deepdots-popup-container` with an overlay. Override styles via global CSS (e.g. `.deepdots-popup`, `#deepdots-popup-container`). The layout is intentionally minimal.
|
|
254
215
|
|
|
255
|
-
|
|
216
|
+
## Renderer Architecture
|
|
256
217
|
|
|
257
|
-
|
|
258
|
-
npm install
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### Build
|
|
262
|
-
|
|
263
|
-
```bash
|
|
264
|
-
npm run build
|
|
265
|
-
```
|
|
218
|
+
The SDK decouples core logic (triggers, conditions, events) from UI rendering.
|
|
266
219
|
|
|
267
|
-
|
|
220
|
+
- `BrowserPopupRenderer`: default when DOM is available.
|
|
221
|
+
- `ReactNativePopupRenderer` (stub): demonstrates how to bridge events in RN (does not render real UI here).
|
|
222
|
+
- `NoopPopupRenderer`: used in SSR / test environments without a DOM.
|
|
268
223
|
|
|
269
|
-
|
|
270
|
-
npm run lint
|
|
271
|
-
```
|
|
224
|
+
Detection for React Native uses `navigator.product === 'ReactNative'`.
|
|
272
225
|
|
|
273
|
-
###
|
|
226
|
+
### Creating a Native Renderer
|
|
227
|
+
```typescript
|
|
228
|
+
class MyNativeRenderer implements PopupRenderer {
|
|
229
|
+
init() { /* prepare modal/store */ }
|
|
230
|
+
show(surveyId, productId, data, emit, onClose) {
|
|
231
|
+
// 1. Display native modal
|
|
232
|
+
// 2. Render equivalent UI
|
|
233
|
+
// 3. Call emit('popup_clicked', surveyId, data) on first interaction
|
|
234
|
+
}
|
|
235
|
+
hide() { /* close modal */ }
|
|
236
|
+
}
|
|
274
237
|
|
|
275
|
-
|
|
276
|
-
|
|
238
|
+
const sdk = new DeepdotsPopups();
|
|
239
|
+
sdk.setRenderer(new MyNativeRenderer());
|
|
240
|
+
sdk.init({ mode: 'client', popups: [...] });
|
|
277
241
|
```
|
|
278
242
|
|
|
279
|
-
###
|
|
243
|
+
### WebView (Cordova / Capacitor / RN / Flutter)
|
|
244
|
+
1. Build the bundle: `npm run build`.
|
|
245
|
+
2. Load `dist/` in a WebView.
|
|
246
|
+
3. Bridge events: `window.ReactNativeWebView.postMessage(JSON.stringify(ev))`.
|
|
247
|
+
4. Initialize: `popups.init({...}); popups.autoLaunch();`.
|
|
280
248
|
|
|
281
|
-
|
|
282
|
-
|
|
249
|
+
Example event forwarding:
|
|
250
|
+
```javascript
|
|
251
|
+
function forward(ev) {
|
|
252
|
+
window.ReactNativeWebView?.postMessage(JSON.stringify(ev));
|
|
253
|
+
}
|
|
254
|
+
popups.on('popup_shown', forward);
|
|
255
|
+
popups.on('survey_completed', forward);
|
|
283
256
|
```
|
|
284
257
|
|
|
285
|
-
##
|
|
286
|
-
|
|
287
|
-
The package includes full TypeScript type definitions. Import types as needed:
|
|
258
|
+
## Types
|
|
259
|
+
Import types directly:
|
|
288
260
|
|
|
289
261
|
```typescript
|
|
290
262
|
import type {
|
|
@@ -293,80 +265,40 @@ import type {
|
|
|
293
265
|
ShowOptions,
|
|
294
266
|
DeepdotsEvent,
|
|
295
267
|
DeepdotsEventType,
|
|
296
|
-
EventListener
|
|
297
|
-
} from '
|
|
268
|
+
EventListener,
|
|
269
|
+
} from '@magicfeedback/popup-sdk';
|
|
298
270
|
```
|
|
299
271
|
|
|
300
|
-
##
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
- Core (triggers, condiciones, eventos, definiciones) es independiente del DOM.
|
|
306
|
-
- `BrowserPopupRenderer` implementa la UI sobre el DOM (usa `renderPopup`).
|
|
307
|
-
- `NoopPopupRenderer` evita errores en SSR / pruebas sin DOM.
|
|
308
|
-
|
|
309
|
-
### Cómo usar en Android / iOS (WebView)
|
|
310
|
-
Caso rápido (Cordova / Capacitor / React Native WebView / Flutter WebView):
|
|
311
|
-
1. Construye el bundle (`npm run build`).
|
|
312
|
-
2. Sirve o empaqueta los archivos de `dist/` dentro de un WebView.
|
|
313
|
-
3. Expone una API puente (bridge) para recibir eventos (`popup_shown`, `survey_completed`) usando `window.ReactNativeWebView.postMessage` (RN) o `webView.evaluateJavascript` (Android nativo).
|
|
314
|
-
4. Inyecta script de inicialización: `popups.init({...}); popups.autoLaunch();`.
|
|
272
|
+
## Example Demo
|
|
273
|
+
See `examples/demo.html` for a runnable browser demo (uses client mode + fake definitions). To try it:
|
|
274
|
+
1. Build the project (`npm run build`).
|
|
275
|
+
2. Open `examples/demo.html` in a browser.
|
|
276
|
+
3. Use buttons to show popups and observe console + event log.
|
|
315
277
|
|
|
316
|
-
|
|
317
|
-
Para una experiencia 100% nativa se escribiría un nuevo renderer:
|
|
318
|
-
```typescript
|
|
319
|
-
class ReactNativePopupRenderer implements PopupRenderer {
|
|
320
|
-
init() { /* preparar store/modal */ }
|
|
321
|
-
show(surveyId, productId, data, emit, onClose) {
|
|
322
|
-
// 1. Mostrar un Modal nativo
|
|
323
|
-
// 2. Renderizar componentes equivalentes
|
|
324
|
-
// 3. Integrar MagicFeedback vía API HTTP si el SDK web no está disponible
|
|
325
|
-
emit('popup_clicked', surveyId, data); // cuando el usuario interactúe
|
|
326
|
-
}
|
|
327
|
-
hide() { /* cerrar modal */ }
|
|
328
|
-
}
|
|
329
|
-
```
|
|
330
|
-
Luego se inyecta:
|
|
331
|
-
```typescript
|
|
332
|
-
const popups = new DeepdotsPopups();
|
|
333
|
-
popups.setRenderer(new ReactNativePopupRenderer()); // inyectar renderer nativo
|
|
334
|
-
popups.init({...});
|
|
335
|
-
```
|
|
278
|
+
## Development
|
|
336
279
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
Ejemplo puente en React Native:
|
|
345
|
-
```js
|
|
346
|
-
window.addEventListener('message', (e) => {
|
|
347
|
-
// recibir comandos desde native -> web
|
|
348
|
-
});
|
|
349
|
-
// Envío desde web a native
|
|
350
|
-
function forwardEvent(ev) {
|
|
351
|
-
window.ReactNativeWebView?.postMessage(JSON.stringify(ev));
|
|
352
|
-
}
|
|
353
|
-
popups.on('popup_shown', forwardEvent);
|
|
354
|
-
popups.on('survey_completed', forwardEvent);
|
|
280
|
+
```bash
|
|
281
|
+
npm install # install dependencies
|
|
282
|
+
npm run build # build (CJS + ESM + d.ts)
|
|
283
|
+
npm run build:watch # watch build
|
|
284
|
+
npm run lint # eslint
|
|
285
|
+
npm test # run vitest
|
|
286
|
+
npm run test:watch # watch tests
|
|
355
287
|
```
|
|
356
288
|
|
|
357
|
-
|
|
358
|
-
- Reutilizas lógica de triggers sin duplicar código.
|
|
359
|
-
- Puedes iterar primero con WebView y luego migrar a UI nativa.
|
|
360
|
-
- Tests siguen funcionando porque usan el renderer de navegador.
|
|
289
|
+
Publishing uses `prepublishOnly` to ensure a fresh build.
|
|
361
290
|
|
|
362
|
-
##
|
|
363
|
-
|
|
364
|
-
|
|
291
|
+
## Notes & Limitations
|
|
292
|
+
- `server` mode currently simulates fetch; real network integration pending.
|
|
293
|
+
- `apiKey` is reserved for future authenticated endpoints.
|
|
294
|
+
- React Native renderer provided is a stub (example only).
|
|
295
|
+
- Sanitization of `message` HTML should be handled upstream if untrusted.
|
|
365
296
|
|
|
366
297
|
## Contributing
|
|
298
|
+
Issues & PRs welcome: https://github.com/MagicFeedback/deepdots-popup-sdk
|
|
367
299
|
|
|
368
|
-
|
|
300
|
+
## License
|
|
301
|
+
MIT
|
|
369
302
|
|
|
370
303
|
## Support
|
|
371
|
-
|
|
372
|
-
For issues and questions, please visit the [GitHub repository](https://github.com/MagicFeedback/deepdots-popup-sdk).
|
|
304
|
+
Open issues on the GitHub repository or contact maintainers.
|
package/dist/index.d.mts
CHANGED
|
@@ -121,7 +121,7 @@ interface PopupRenderer {
|
|
|
121
121
|
/** Preparar recursos si aplica */
|
|
122
122
|
init?(): void;
|
|
123
123
|
/** Mostrar popup */
|
|
124
|
-
show(surveyId: string, productId: string,
|
|
124
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void): void;
|
|
125
125
|
/** Ocultar popup */
|
|
126
126
|
hide(): void;
|
|
127
127
|
}
|
|
@@ -147,8 +147,12 @@ declare class DeepdotsPopups {
|
|
|
147
147
|
autoLaunch(): void;
|
|
148
148
|
/** Inicia los triggers configurados */
|
|
149
149
|
private startTriggers;
|
|
150
|
-
/** Show a popup immediately (
|
|
151
|
-
show(options:
|
|
150
|
+
/** Show a popup immediately (supports legacy ShowOptions and new PopupDefinition) */
|
|
151
|
+
show(options: PopupDefinition | {
|
|
152
|
+
surveyId: string;
|
|
153
|
+
productId: string;
|
|
154
|
+
data?: Record<string, unknown>;
|
|
155
|
+
}): void;
|
|
152
156
|
/** Mostrar popup por id de definición (usa surveyId interno) */
|
|
153
157
|
showByPopupId(popupId: string): void;
|
|
154
158
|
/** Configure triggers for auto-launching popups (manual) */
|
package/dist/index.d.ts
CHANGED
|
@@ -121,7 +121,7 @@ interface PopupRenderer {
|
|
|
121
121
|
/** Preparar recursos si aplica */
|
|
122
122
|
init?(): void;
|
|
123
123
|
/** Mostrar popup */
|
|
124
|
-
show(surveyId: string, productId: string,
|
|
124
|
+
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void): void;
|
|
125
125
|
/** Ocultar popup */
|
|
126
126
|
hide(): void;
|
|
127
127
|
}
|
|
@@ -147,8 +147,12 @@ declare class DeepdotsPopups {
|
|
|
147
147
|
autoLaunch(): void;
|
|
148
148
|
/** Inicia los triggers configurados */
|
|
149
149
|
private startTriggers;
|
|
150
|
-
/** Show a popup immediately (
|
|
151
|
-
show(options:
|
|
150
|
+
/** Show a popup immediately (supports legacy ShowOptions and new PopupDefinition) */
|
|
151
|
+
show(options: PopupDefinition | {
|
|
152
|
+
surveyId: string;
|
|
153
|
+
productId: string;
|
|
154
|
+
data?: Record<string, unknown>;
|
|
155
|
+
}): void;
|
|
152
156
|
/** Mostrar popup por id de definición (usa surveyId interno) */
|
|
153
157
|
showByPopupId(popupId: string): void;
|
|
154
158
|
/** Configure triggers for auto-launching popups (manual) */
|