@drippr/embed-react 0.2.1 → 0.2.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 +3 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +68 -29
- package/dist/index.mjs +68 -29
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -158,6 +158,7 @@ function FeedbackDrawer() {
|
|
|
158
158
|
| `style` | `React.CSSProperties` | No | - | Inline styles for the container |
|
|
159
159
|
| `height` | `number` | No | `700` | Fallback height for the iframe (px) |
|
|
160
160
|
| `baseUrl` | `string` | No | `"https://app.drippr.io"` | Base URL for the embed |
|
|
161
|
+
| `prefetch` | `boolean` | No | `true` | Prefetch page content for faster loading (modal/drawer only). Set to `false` if it causes issues with your implementation. |
|
|
161
162
|
|
|
162
163
|
### PrefillData
|
|
163
164
|
|
|
@@ -199,6 +200,7 @@ interface DripprFlowApi {
|
|
|
199
200
|
- **Three Display Modes**: Inline, modal, and drawer
|
|
200
201
|
- **Flexible Triggers**: Use render props or controlled state with external buttons
|
|
201
202
|
- **Automatic Z-Index**: High z-index values prevent CSS framework conflicts (Tailwind, etc.)
|
|
203
|
+
- **Smart Preloading**: Iframe and page content are preloaded for instant opening (modal/drawer modes)
|
|
202
204
|
- **Prefill Support**: Pre-populate form fields with user data
|
|
203
205
|
- **Auto-resize**: Iframe automatically resizes based on content
|
|
204
206
|
- **TypeScript**: Full TypeScript support with exported types
|
|
@@ -210,6 +212,7 @@ interface DripprFlowApi {
|
|
|
210
212
|
- Render prop `children` pattern, OR
|
|
211
213
|
- External button with controlled `open`/`onOpenChange` props
|
|
212
214
|
- **Z-Index**: Automatically set to high values (99999+) to prevent conflicts with CSS frameworks like Tailwind CSS
|
|
215
|
+
- **Prefetching**: Enabled by default (`prefetch={true}`) for faster loading. The component automatically prefetches the page content when mounted (modal/drawer modes only). If this causes issues with your implementation (e.g., unwanted network requests, conflicts with your routing), you can disable it with `prefetch={false}`.
|
|
213
216
|
|
|
214
217
|
## Requirements
|
|
215
218
|
|
package/dist/index.d.mts
CHANGED
|
@@ -54,8 +54,10 @@ interface DripprFlowProps {
|
|
|
54
54
|
height?: number;
|
|
55
55
|
/** Base URL for the embed (defaults to production) */
|
|
56
56
|
baseUrl?: string;
|
|
57
|
+
/** Prefetch page content for faster loading (default: true). Set to false if it causes issues with your implementation. */
|
|
58
|
+
prefetch?: boolean;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
declare function DripprFlow({ flowId, mode, open: controlledOpen, onOpenChange, prefill, children, onSubmitted, className, style, height: fallbackHeight, baseUrl, }: DripprFlowProps): react_jsx_runtime.JSX.Element | null;
|
|
61
|
+
declare function DripprFlow({ flowId, mode, open: controlledOpen, onOpenChange, prefill, children, onSubmitted, className, style, height: fallbackHeight, baseUrl, prefetch, }: DripprFlowProps): react_jsx_runtime.JSX.Element | null;
|
|
60
62
|
|
|
61
63
|
export { DripprFlow, type DripprFlowApi, type DripprFlowProps, type DripprMessage, type DripprMessageFromChild, type DripprMessageToChild, type EmbedMode, type PrefillData };
|
package/dist/index.d.ts
CHANGED
|
@@ -54,8 +54,10 @@ interface DripprFlowProps {
|
|
|
54
54
|
height?: number;
|
|
55
55
|
/** Base URL for the embed (defaults to production) */
|
|
56
56
|
baseUrl?: string;
|
|
57
|
+
/** Prefetch page content for faster loading (default: true). Set to false if it causes issues with your implementation. */
|
|
58
|
+
prefetch?: boolean;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
declare function DripprFlow({ flowId, mode, open: controlledOpen, onOpenChange, prefill, children, onSubmitted, className, style, height: fallbackHeight, baseUrl, }: DripprFlowProps): react_jsx_runtime.JSX.Element | null;
|
|
61
|
+
declare function DripprFlow({ flowId, mode, open: controlledOpen, onOpenChange, prefill, children, onSubmitted, className, style, height: fallbackHeight, baseUrl, prefetch, }: DripprFlowProps): react_jsx_runtime.JSX.Element | null;
|
|
60
62
|
|
|
61
63
|
export { DripprFlow, type DripprFlowApi, type DripprFlowProps, type DripprMessage, type DripprMessageFromChild, type DripprMessageToChild, type EmbedMode, type PrefillData };
|
package/dist/index.js
CHANGED
|
@@ -204,22 +204,37 @@ function ModalContainer({
|
|
|
204
204
|
borderRadius: "2px",
|
|
205
205
|
margin: "6px auto 2px"
|
|
206
206
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
const iframeStyles = {
|
|
208
|
+
width: "100%",
|
|
209
|
+
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${Math.min(height, window.innerHeight * 0.85)}px`,
|
|
210
|
+
border: "none",
|
|
211
|
+
display: "block"
|
|
212
|
+
};
|
|
213
|
+
const containerStyles = mounted ? {} : {
|
|
214
|
+
position: "absolute",
|
|
215
|
+
left: "-9999px",
|
|
216
|
+
width: "1px",
|
|
217
|
+
height: "1px",
|
|
218
|
+
visibility: "hidden",
|
|
219
|
+
pointerEvents: "none",
|
|
220
|
+
overflow: "hidden"
|
|
221
|
+
};
|
|
210
222
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
211
223
|
trigger,
|
|
212
224
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
213
225
|
"div",
|
|
214
226
|
{
|
|
215
|
-
style:
|
|
227
|
+
style: {
|
|
228
|
+
...overlayStyles,
|
|
229
|
+
...containerStyles
|
|
230
|
+
},
|
|
216
231
|
onClick: (e) => {
|
|
217
|
-
if (e.target === e.currentTarget) {
|
|
232
|
+
if (mounted && e.target === e.currentTarget) {
|
|
218
233
|
onOpenChange(false);
|
|
219
234
|
}
|
|
220
235
|
},
|
|
221
236
|
role: "dialog",
|
|
222
|
-
"aria-modal": "true",
|
|
237
|
+
"aria-modal": mounted ? "true" : "false",
|
|
223
238
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
224
239
|
"div",
|
|
225
240
|
{
|
|
@@ -247,13 +262,8 @@ function ModalContainer({
|
|
|
247
262
|
{
|
|
248
263
|
ref: iframeRef,
|
|
249
264
|
src,
|
|
250
|
-
style:
|
|
251
|
-
|
|
252
|
-
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${Math.min(height, window.innerHeight * 0.85)}px`,
|
|
253
|
-
border: "none",
|
|
254
|
-
display: "block"
|
|
255
|
-
},
|
|
256
|
-
loading: "lazy",
|
|
265
|
+
style: iframeStyles,
|
|
266
|
+
loading: "eager",
|
|
257
267
|
title: "Drippr Feedback"
|
|
258
268
|
}
|
|
259
269
|
)
|
|
@@ -406,17 +416,37 @@ function DrawerContainer({
|
|
|
406
416
|
borderRadius: "2px",
|
|
407
417
|
margin: "6px auto 2px"
|
|
408
418
|
};
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
419
|
+
const iframeStyles = {
|
|
420
|
+
width: "100%",
|
|
421
|
+
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${height}px`,
|
|
422
|
+
minHeight: isMobile ? void 0 : "100%",
|
|
423
|
+
border: "none",
|
|
424
|
+
display: "block"
|
|
425
|
+
};
|
|
426
|
+
const containerStyles = mounted ? {} : {
|
|
427
|
+
position: "absolute",
|
|
428
|
+
left: "-9999px",
|
|
429
|
+
width: "1px",
|
|
430
|
+
height: "1px",
|
|
431
|
+
visibility: "hidden",
|
|
432
|
+
pointerEvents: "none",
|
|
433
|
+
overflow: "hidden"
|
|
434
|
+
};
|
|
412
435
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
413
436
|
trigger,
|
|
414
437
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
415
438
|
"div",
|
|
416
439
|
{
|
|
417
|
-
style:
|
|
418
|
-
|
|
419
|
-
|
|
440
|
+
style: {
|
|
441
|
+
...overlayStyles,
|
|
442
|
+
...containerStyles
|
|
443
|
+
},
|
|
444
|
+
onClick: () => {
|
|
445
|
+
if (mounted) {
|
|
446
|
+
onOpenChange(false);
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
"aria-hidden": mounted ? "false" : "true"
|
|
420
450
|
}
|
|
421
451
|
),
|
|
422
452
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
@@ -426,11 +456,12 @@ function DrawerContainer({
|
|
|
426
456
|
style: {
|
|
427
457
|
...drawerStyles,
|
|
428
458
|
...style,
|
|
459
|
+
...containerStyles,
|
|
429
460
|
// Ensure z-index is always set (user's style prop shouldn't override it)
|
|
430
461
|
zIndex: style?.zIndex ?? drawerStyles.zIndex
|
|
431
462
|
},
|
|
432
463
|
role: "dialog",
|
|
433
|
-
"aria-modal": "true",
|
|
464
|
+
"aria-modal": mounted ? "true" : "false",
|
|
434
465
|
children: [
|
|
435
466
|
isMobile && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: handleStyles }),
|
|
436
467
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: headerStyles, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -448,14 +479,8 @@ function DrawerContainer({
|
|
|
448
479
|
{
|
|
449
480
|
ref: iframeRef,
|
|
450
481
|
src,
|
|
451
|
-
style:
|
|
452
|
-
|
|
453
|
-
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${height}px`,
|
|
454
|
-
minHeight: isMobile ? void 0 : "100%",
|
|
455
|
-
border: "none",
|
|
456
|
-
display: "block"
|
|
457
|
-
},
|
|
458
|
-
loading: "lazy",
|
|
482
|
+
style: iframeStyles,
|
|
483
|
+
loading: "eager",
|
|
459
484
|
title: "Drippr Feedback"
|
|
460
485
|
}
|
|
461
486
|
) })
|
|
@@ -483,7 +508,8 @@ function DripprFlow({
|
|
|
483
508
|
className,
|
|
484
509
|
style,
|
|
485
510
|
height: fallbackHeight = DEFAULT_HEIGHT,
|
|
486
|
-
baseUrl = DEFAULT_BASE_URL
|
|
511
|
+
baseUrl = DEFAULT_BASE_URL,
|
|
512
|
+
prefetch = true
|
|
487
513
|
}) {
|
|
488
514
|
const [instanceId] = React3.useState(generateInstanceId);
|
|
489
515
|
const [height, setHeight] = React3.useState(fallbackHeight);
|
|
@@ -573,6 +599,19 @@ function DripprFlow({
|
|
|
573
599
|
);
|
|
574
600
|
}
|
|
575
601
|
}, [mode, children, isControlled]);
|
|
602
|
+
React3.useEffect(() => {
|
|
603
|
+
if (!prefetch || mode === "inline") return;
|
|
604
|
+
const link = document.createElement("link");
|
|
605
|
+
link.rel = "prefetch";
|
|
606
|
+
link.href = src;
|
|
607
|
+
link.as = "document";
|
|
608
|
+
document.head.appendChild(link);
|
|
609
|
+
return () => {
|
|
610
|
+
if (document.head.contains(link)) {
|
|
611
|
+
document.head.removeChild(link);
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
}, [src, mode, prefetch]);
|
|
576
615
|
const trigger = mode !== "inline" && children ? children(api) : null;
|
|
577
616
|
if (mode === "inline") {
|
|
578
617
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
package/dist/index.mjs
CHANGED
|
@@ -168,22 +168,37 @@ function ModalContainer({
|
|
|
168
168
|
borderRadius: "2px",
|
|
169
169
|
margin: "6px auto 2px"
|
|
170
170
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
const iframeStyles = {
|
|
172
|
+
width: "100%",
|
|
173
|
+
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${Math.min(height, window.innerHeight * 0.85)}px`,
|
|
174
|
+
border: "none",
|
|
175
|
+
display: "block"
|
|
176
|
+
};
|
|
177
|
+
const containerStyles = mounted ? {} : {
|
|
178
|
+
position: "absolute",
|
|
179
|
+
left: "-9999px",
|
|
180
|
+
width: "1px",
|
|
181
|
+
height: "1px",
|
|
182
|
+
visibility: "hidden",
|
|
183
|
+
pointerEvents: "none",
|
|
184
|
+
overflow: "hidden"
|
|
185
|
+
};
|
|
174
186
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
175
187
|
trigger,
|
|
176
188
|
/* @__PURE__ */ jsx2(
|
|
177
189
|
"div",
|
|
178
190
|
{
|
|
179
|
-
style:
|
|
191
|
+
style: {
|
|
192
|
+
...overlayStyles,
|
|
193
|
+
...containerStyles
|
|
194
|
+
},
|
|
180
195
|
onClick: (e) => {
|
|
181
|
-
if (e.target === e.currentTarget) {
|
|
196
|
+
if (mounted && e.target === e.currentTarget) {
|
|
182
197
|
onOpenChange(false);
|
|
183
198
|
}
|
|
184
199
|
},
|
|
185
200
|
role: "dialog",
|
|
186
|
-
"aria-modal": "true",
|
|
201
|
+
"aria-modal": mounted ? "true" : "false",
|
|
187
202
|
children: /* @__PURE__ */ jsxs(
|
|
188
203
|
"div",
|
|
189
204
|
{
|
|
@@ -211,13 +226,8 @@ function ModalContainer({
|
|
|
211
226
|
{
|
|
212
227
|
ref: iframeRef,
|
|
213
228
|
src,
|
|
214
|
-
style:
|
|
215
|
-
|
|
216
|
-
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${Math.min(height, window.innerHeight * 0.85)}px`,
|
|
217
|
-
border: "none",
|
|
218
|
-
display: "block"
|
|
219
|
-
},
|
|
220
|
-
loading: "lazy",
|
|
229
|
+
style: iframeStyles,
|
|
230
|
+
loading: "eager",
|
|
221
231
|
title: "Drippr Feedback"
|
|
222
232
|
}
|
|
223
233
|
)
|
|
@@ -370,17 +380,37 @@ function DrawerContainer({
|
|
|
370
380
|
borderRadius: "2px",
|
|
371
381
|
margin: "6px auto 2px"
|
|
372
382
|
};
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
383
|
+
const iframeStyles = {
|
|
384
|
+
width: "100%",
|
|
385
|
+
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${height}px`,
|
|
386
|
+
minHeight: isMobile ? void 0 : "100%",
|
|
387
|
+
border: "none",
|
|
388
|
+
display: "block"
|
|
389
|
+
};
|
|
390
|
+
const containerStyles = mounted ? {} : {
|
|
391
|
+
position: "absolute",
|
|
392
|
+
left: "-9999px",
|
|
393
|
+
width: "1px",
|
|
394
|
+
height: "1px",
|
|
395
|
+
visibility: "hidden",
|
|
396
|
+
pointerEvents: "none",
|
|
397
|
+
overflow: "hidden"
|
|
398
|
+
};
|
|
376
399
|
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
377
400
|
trigger,
|
|
378
401
|
/* @__PURE__ */ jsx3(
|
|
379
402
|
"div",
|
|
380
403
|
{
|
|
381
|
-
style:
|
|
382
|
-
|
|
383
|
-
|
|
404
|
+
style: {
|
|
405
|
+
...overlayStyles,
|
|
406
|
+
...containerStyles
|
|
407
|
+
},
|
|
408
|
+
onClick: () => {
|
|
409
|
+
if (mounted) {
|
|
410
|
+
onOpenChange(false);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
"aria-hidden": mounted ? "false" : "true"
|
|
384
414
|
}
|
|
385
415
|
),
|
|
386
416
|
/* @__PURE__ */ jsxs2(
|
|
@@ -390,11 +420,12 @@ function DrawerContainer({
|
|
|
390
420
|
style: {
|
|
391
421
|
...drawerStyles,
|
|
392
422
|
...style,
|
|
423
|
+
...containerStyles,
|
|
393
424
|
// Ensure z-index is always set (user's style prop shouldn't override it)
|
|
394
425
|
zIndex: style?.zIndex ?? drawerStyles.zIndex
|
|
395
426
|
},
|
|
396
427
|
role: "dialog",
|
|
397
|
-
"aria-modal": "true",
|
|
428
|
+
"aria-modal": mounted ? "true" : "false",
|
|
398
429
|
children: [
|
|
399
430
|
isMobile && /* @__PURE__ */ jsx3("div", { style: handleStyles }),
|
|
400
431
|
/* @__PURE__ */ jsx3("div", { style: headerStyles, children: /* @__PURE__ */ jsx3(
|
|
@@ -412,14 +443,8 @@ function DrawerContainer({
|
|
|
412
443
|
{
|
|
413
444
|
ref: iframeRef,
|
|
414
445
|
src,
|
|
415
|
-
style:
|
|
416
|
-
|
|
417
|
-
height: isMobile ? `${Math.min(height, window.innerHeight - 80)}px` : `${height}px`,
|
|
418
|
-
minHeight: isMobile ? void 0 : "100%",
|
|
419
|
-
border: "none",
|
|
420
|
-
display: "block"
|
|
421
|
-
},
|
|
422
|
-
loading: "lazy",
|
|
446
|
+
style: iframeStyles,
|
|
447
|
+
loading: "eager",
|
|
423
448
|
title: "Drippr Feedback"
|
|
424
449
|
}
|
|
425
450
|
) })
|
|
@@ -447,7 +472,8 @@ function DripprFlow({
|
|
|
447
472
|
className,
|
|
448
473
|
style,
|
|
449
474
|
height: fallbackHeight = DEFAULT_HEIGHT,
|
|
450
|
-
baseUrl = DEFAULT_BASE_URL
|
|
475
|
+
baseUrl = DEFAULT_BASE_URL,
|
|
476
|
+
prefetch = true
|
|
451
477
|
}) {
|
|
452
478
|
const [instanceId] = React3.useState(generateInstanceId);
|
|
453
479
|
const [height, setHeight] = React3.useState(fallbackHeight);
|
|
@@ -537,6 +563,19 @@ function DripprFlow({
|
|
|
537
563
|
);
|
|
538
564
|
}
|
|
539
565
|
}, [mode, children, isControlled]);
|
|
566
|
+
React3.useEffect(() => {
|
|
567
|
+
if (!prefetch || mode === "inline") return;
|
|
568
|
+
const link = document.createElement("link");
|
|
569
|
+
link.rel = "prefetch";
|
|
570
|
+
link.href = src;
|
|
571
|
+
link.as = "document";
|
|
572
|
+
document.head.appendChild(link);
|
|
573
|
+
return () => {
|
|
574
|
+
if (document.head.contains(link)) {
|
|
575
|
+
document.head.removeChild(link);
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
}, [src, mode, prefetch]);
|
|
540
579
|
const trigger = mode !== "inline" && children ? children(api) : null;
|
|
541
580
|
if (mode === "inline") {
|
|
542
581
|
return /* @__PURE__ */ jsx4(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drippr/embed-react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "React component for embedding Drippr feedback flows",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
21
21
|
"lint": "eslint src/",
|
|
22
22
|
"typecheck": "tsc --noEmit",
|
|
23
|
-
"prepublishOnly": "npm run build"
|
|
24
|
-
"publish": "npm publish --access public"
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
25
24
|
},
|
|
26
25
|
"peerDependencies": {
|
|
27
26
|
"react": ">=18.0.0",
|