@fluid-app/portal-sdk 0.1.216 → 0.1.217
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/dist/EmbedWidget-BysWpVIC.cjs +684 -0
- package/dist/EmbedWidget-BysWpVIC.cjs.map +1 -0
- package/dist/EmbedWidget-tU8njf5H.mjs +654 -0
- package/dist/EmbedWidget-tU8njf5H.mjs.map +1 -0
- package/dist/{FluidProvider-D0ZapBR-.mjs → FluidProvider-02beRTpR.mjs} +3 -3
- package/dist/{FluidProvider-D0ZapBR-.mjs.map → FluidProvider-02beRTpR.mjs.map} +1 -1
- package/dist/{FluidProvider-ZbTGc_uY.cjs → FluidProvider-BgFmXtHo.cjs} +3 -3
- package/dist/{FluidProvider-ZbTGc_uY.cjs.map → FluidProvider-BgFmXtHo.cjs.map} +1 -1
- package/dist/{MessagingScreen-CkwCSMou.cjs → MessagingScreen-BkLcqJbs.cjs} +2 -2
- package/dist/{MessagingScreen-CkwCSMou.cjs.map → MessagingScreen-BkLcqJbs.cjs.map} +1 -1
- package/dist/{MessagingScreen-B8azvEc0.mjs → MessagingScreen-CJlVOY5R.mjs} +2 -2
- package/dist/{MessagingScreen-B8azvEc0.mjs.map → MessagingScreen-CJlVOY5R.mjs.map} +1 -1
- package/dist/{MessagingScreen-C5QOgB1w.cjs → MessagingScreen-sN7aBvGk.cjs} +3 -3
- package/dist/{ProfileScreen-DMmfRQp8.cjs → ProfileScreen-Bgo6iTKe.cjs} +3 -3
- package/dist/{ProfileScreen-BhmbCKGd.mjs → ProfileScreen-CNYqUDNB.mjs} +2 -2
- package/dist/{ProfileScreen-BhmbCKGd.mjs.map → ProfileScreen-CNYqUDNB.mjs.map} +1 -1
- package/dist/{ProfileScreen-DsEH0aZU.cjs → ProfileScreen-rPqgsNCc.cjs} +2 -2
- package/dist/{ProfileScreen-DsEH0aZU.cjs.map → ProfileScreen-rPqgsNCc.cjs.map} +1 -1
- package/dist/{ShopScreen-CWCPGEbn.mjs → ShopScreen-B9lHJ8L2.mjs} +2 -2
- package/dist/{ShopScreen-CWCPGEbn.mjs.map → ShopScreen-B9lHJ8L2.mjs.map} +1 -1
- package/dist/{ShopScreen-C6UUeGA9.cjs → ShopScreen-DUHzufCU.cjs} +2 -2
- package/dist/{ShopScreen-C6UUeGA9.cjs.map → ShopScreen-DUHzufCU.cjs.map} +1 -1
- package/dist/{ShopScreen-BBPH0l23.cjs → ShopScreen-g6FQ4R1_.cjs} +3 -3
- package/dist/index.cjs +11 -11
- package/dist/index.d.cts +21 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +21 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +11 -11
- package/package.json +10 -10
- package/dist/EmbedWidget-C3mGurOv.mjs +0 -221
- package/dist/EmbedWidget-C3mGurOv.mjs.map +0 -1
- package/dist/EmbedWidget-PIWoA9sU.cjs +0 -251
- package/dist/EmbedWidget-PIWoA9sU.cjs.map +0 -1
|
@@ -0,0 +1,684 @@
|
|
|
1
|
+
const require_chunk = require("./chunk-9hOWP6kD.cjs");
|
|
2
|
+
const require_registries = require("./registries-CpUM406S.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_chunk.__toESM(react);
|
|
5
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
+
let lucide_react = require("lucide-react");
|
|
7
|
+
let react_dom = require("react-dom");
|
|
8
|
+
//#region ../widgets/src/contexts/RepUserContext.tsx
|
|
9
|
+
const RepUserContext = (0, react.createContext)(null);
|
|
10
|
+
function RepUserProvider({ user, children }) {
|
|
11
|
+
const value = (0, react.useMemo)(() => user, [user]);
|
|
12
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RepUserContext.Provider, {
|
|
13
|
+
value,
|
|
14
|
+
children
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function useRepUser() {
|
|
18
|
+
return (0, react.useContext)(RepUserContext);
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region ../widgets/src/widgets/EmbedWidget.tsx
|
|
22
|
+
var EmbedWidget_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
23
|
+
EmbedWidget: () => EmbedWidget,
|
|
24
|
+
embedWidgetPropertySchema: () => embedWidgetPropertySchema
|
|
25
|
+
});
|
|
26
|
+
function isValidHttpUrl(urlString) {
|
|
27
|
+
try {
|
|
28
|
+
const parsed = new URL(urlString);
|
|
29
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:";
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function useEmbedUrl(url, publicId) {
|
|
35
|
+
return (0, react.useMemo)(() => {
|
|
36
|
+
const normalizedUrl = url && (url.startsWith("http://") || url.startsWith("https://")) ? url : url ? `https://${url}` : "";
|
|
37
|
+
let isValidUrl = false;
|
|
38
|
+
if (normalizedUrl) try {
|
|
39
|
+
const parsed = new URL(normalizedUrl);
|
|
40
|
+
isValidUrl = (parsed.protocol === "http:" || parsed.protocol === "https:") && (parsed.hostname.includes(".") || parsed.hostname === "localhost");
|
|
41
|
+
} catch {}
|
|
42
|
+
if (!isValidUrl || !publicId) return {
|
|
43
|
+
normalizedUrl,
|
|
44
|
+
isValidUrl,
|
|
45
|
+
iframeSrc: normalizedUrl
|
|
46
|
+
};
|
|
47
|
+
const urlObj = new URL(normalizedUrl);
|
|
48
|
+
urlObj.searchParams.set("public_id", publicId);
|
|
49
|
+
return {
|
|
50
|
+
normalizedUrl,
|
|
51
|
+
isValidUrl,
|
|
52
|
+
iframeSrc: urlObj.toString()
|
|
53
|
+
};
|
|
54
|
+
}, [url, publicId]);
|
|
55
|
+
}
|
|
56
|
+
function useEmbedPostMessageBridge({ iframeRef, normalizedUrl, isValidUrl, editMode }) {
|
|
57
|
+
(0, react.useEffect)(() => {
|
|
58
|
+
if (!isValidUrl || editMode) return;
|
|
59
|
+
const expectedOrigin = new URL(normalizedUrl).origin;
|
|
60
|
+
function handleMessage(event) {
|
|
61
|
+
if (event.origin !== expectedOrigin) return;
|
|
62
|
+
if (event.source !== iframeRef.current?.contentWindow) return;
|
|
63
|
+
let data;
|
|
64
|
+
if (typeof event.data === "string") try {
|
|
65
|
+
data = JSON.parse(event.data);
|
|
66
|
+
} catch {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
else data = event.data;
|
|
70
|
+
if (typeof data === "object" && data !== null && "type" in data && data.type === "OPEN_FULL_SCREEN_WEBVIEW") {
|
|
71
|
+
const messageUrl = data.url;
|
|
72
|
+
if (messageUrl && isValidHttpUrl(messageUrl)) window.open(messageUrl, "_blank", "noopener,noreferrer");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
window.addEventListener("message", handleMessage);
|
|
76
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
77
|
+
}, [
|
|
78
|
+
iframeRef,
|
|
79
|
+
normalizedUrl,
|
|
80
|
+
isValidUrl,
|
|
81
|
+
editMode
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
function useModalBodyScrollLock(isOpen) {
|
|
85
|
+
(0, react.useEffect)(() => {
|
|
86
|
+
if (!isOpen) return;
|
|
87
|
+
const previousOverflow = document.body.style.overflow;
|
|
88
|
+
document.body.style.overflow = "hidden";
|
|
89
|
+
return () => {
|
|
90
|
+
document.body.style.overflow = previousOverflow;
|
|
91
|
+
};
|
|
92
|
+
}, [isOpen]);
|
|
93
|
+
}
|
|
94
|
+
function useModalEscapeClose(isOpen, onClose) {
|
|
95
|
+
(0, react.useEffect)(() => {
|
|
96
|
+
if (!isOpen) return;
|
|
97
|
+
const handleKeyDown = (event) => {
|
|
98
|
+
if (event.key === "Escape") onClose();
|
|
99
|
+
};
|
|
100
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
101
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
102
|
+
}, [isOpen, onClose]);
|
|
103
|
+
}
|
|
104
|
+
function useDialogFocusRestore(dialogRef) {
|
|
105
|
+
(0, react.useEffect)(() => {
|
|
106
|
+
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
107
|
+
dialogRef.current?.focus();
|
|
108
|
+
return () => {
|
|
109
|
+
previouslyFocused?.focus();
|
|
110
|
+
};
|
|
111
|
+
}, [dialogRef]);
|
|
112
|
+
}
|
|
113
|
+
const HEADER_ICON_MAP = {
|
|
114
|
+
GraduationCap: lucide_react.GraduationCap,
|
|
115
|
+
Video: lucide_react.Video,
|
|
116
|
+
BookOpen: lucide_react.BookOpen,
|
|
117
|
+
Globe: lucide_react.Globe,
|
|
118
|
+
User: lucide_react.User,
|
|
119
|
+
Star: lucide_react.Star,
|
|
120
|
+
Heart: lucide_react.Heart,
|
|
121
|
+
Trophy: lucide_react.Trophy,
|
|
122
|
+
Sparkles: lucide_react.Sparkles,
|
|
123
|
+
Zap: lucide_react.Zap,
|
|
124
|
+
Gift: lucide_react.Gift,
|
|
125
|
+
ShoppingBag: lucide_react.ShoppingBag,
|
|
126
|
+
Bell: lucide_react.Bell,
|
|
127
|
+
Calendar: lucide_react.Calendar,
|
|
128
|
+
Bookmark: lucide_react.BookmarkIcon
|
|
129
|
+
};
|
|
130
|
+
const HEADER_ICON_OPTIONS = [
|
|
131
|
+
{
|
|
132
|
+
label: "Graduation Cap",
|
|
133
|
+
value: "GraduationCap"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
label: "Video",
|
|
137
|
+
value: "Video"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
label: "Book",
|
|
141
|
+
value: "BookOpen"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
label: "Globe",
|
|
145
|
+
value: "Globe"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
label: "User",
|
|
149
|
+
value: "User"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
label: "Star",
|
|
153
|
+
value: "Star"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
label: "Heart",
|
|
157
|
+
value: "Heart"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
label: "Trophy",
|
|
161
|
+
value: "Trophy"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
label: "Sparkles",
|
|
165
|
+
value: "Sparkles"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
label: "Zap / Lightning",
|
|
169
|
+
value: "Zap"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
label: "Gift",
|
|
173
|
+
value: "Gift"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
label: "Shopping Bag",
|
|
177
|
+
value: "ShoppingBag"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
label: "Bell",
|
|
181
|
+
value: "Bell"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
label: "Calendar",
|
|
185
|
+
value: "Calendar"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
label: "Bookmark",
|
|
189
|
+
value: "Bookmark"
|
|
190
|
+
}
|
|
191
|
+
];
|
|
192
|
+
const getHeaderIcon = (name) => {
|
|
193
|
+
if (!name) return lucide_react.GraduationCap;
|
|
194
|
+
return HEADER_ICON_MAP[name] ?? lucide_react.GraduationCap;
|
|
195
|
+
};
|
|
196
|
+
function EmbedWidget({ url = "", title = "Embedded Content", height = "400px", fullScreen = false, allowFullscreen = true, loading = "lazy", borderRadius = "md", borderWidth = "none", borderColor = "muted", editMode = false, isSelected = false, displayMode = "inline", coverResource, coverUseCustomUrl = false, coverImageUrl = "", coverTitle = "", coverMeta = "", coverShowHeader = true, coverHeaderIcon = "GraduationCap", coverHeaderIconColor = "primary", coverHeight = "320px", className, ...props }) {
|
|
197
|
+
const isFullScreen = fullScreen;
|
|
198
|
+
const iframeRef = (0, react.useRef)(null);
|
|
199
|
+
const publicId = useRepUser()?.publicId;
|
|
200
|
+
const [modalOpen, setModalOpen] = (0, react.useState)(false);
|
|
201
|
+
const [coverReloadKey, setCoverReloadKey] = (0, react.useState)(0);
|
|
202
|
+
const [iframeReloadKey, setIframeReloadKey] = (0, react.useState)(0);
|
|
203
|
+
const closeModal = (0, react.useCallback)(() => setModalOpen(false), []);
|
|
204
|
+
const { normalizedUrl, isValidUrl, iframeSrc } = useEmbedUrl(url, publicId);
|
|
205
|
+
useEmbedPostMessageBridge({
|
|
206
|
+
iframeRef,
|
|
207
|
+
normalizedUrl,
|
|
208
|
+
isValidUrl,
|
|
209
|
+
editMode
|
|
210
|
+
});
|
|
211
|
+
useModalBodyScrollLock(modalOpen);
|
|
212
|
+
useModalEscapeClose(modalOpen, closeModal);
|
|
213
|
+
if (!url || !isValidUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
214
|
+
className: `flex items-center justify-center rounded-${borderRadius} border-border bg-muted text-muted-foreground border-2 border-dashed ${isFullScreen ? "h-full" : ""} ${className ?? ""}`,
|
|
215
|
+
style: isFullScreen ? void 0 : { height: displayMode === "cover" ? coverHeight : height },
|
|
216
|
+
...props,
|
|
217
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
218
|
+
className: "flex flex-col items-center gap-2 p-6 text-center",
|
|
219
|
+
children: [
|
|
220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "h-12 w-12 opacity-50" }),
|
|
221
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
222
|
+
className: "text-sm font-medium",
|
|
223
|
+
children: "Enter a URL to embed external content"
|
|
224
|
+
}),
|
|
225
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
226
|
+
className: "text-xs opacity-75",
|
|
227
|
+
children: "Configure the URL in the properties panel"
|
|
228
|
+
})
|
|
229
|
+
]
|
|
230
|
+
})
|
|
231
|
+
});
|
|
232
|
+
if (displayMode === "cover") {
|
|
233
|
+
const resolvedCoverImage = coverUseCustomUrl ? coverImageUrl : coverResource?.imageUrl || coverResource?.image_url || coverImageUrl;
|
|
234
|
+
const effectiveTitle = coverTitle || title;
|
|
235
|
+
const HeaderIcon = getHeaderIcon(coverHeaderIcon);
|
|
236
|
+
const handleOpenModal = () => {
|
|
237
|
+
if (editMode) return;
|
|
238
|
+
setModalOpen(true);
|
|
239
|
+
};
|
|
240
|
+
const handleReload = () => {
|
|
241
|
+
if (editMode) return;
|
|
242
|
+
setCoverReloadKey((key) => key + 1);
|
|
243
|
+
};
|
|
244
|
+
const handleOpenNewTab = (e) => {
|
|
245
|
+
e.stopPropagation();
|
|
246
|
+
if (editMode) return;
|
|
247
|
+
window.open(iframeSrc, "_blank", "noopener,noreferrer");
|
|
248
|
+
};
|
|
249
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
250
|
+
className: `relative w-full overflow-hidden rounded-${borderRadius} ${require_registries.borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? require_registries.borderColorClasses[borderColor] : ""} bg-background ${className ?? ""}`,
|
|
251
|
+
style: { boxShadow: "0 1px 2px color-mix(in oklch, var(--color-foreground) 5%, transparent), 0 12px 32px -16px color-mix(in oklch, var(--color-foreground) 10%, transparent)" },
|
|
252
|
+
...props,
|
|
253
|
+
children: [
|
|
254
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
255
|
+
"aria-hidden": "true",
|
|
256
|
+
className: `pointer-events-none absolute inset-0 z-[1] rounded-${borderRadius}`,
|
|
257
|
+
style: { boxShadow: "inset 0 0 0 1px color-mix(in oklch, var(--color-foreground) 8%, transparent)" }
|
|
258
|
+
}),
|
|
259
|
+
coverShowHeader && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
260
|
+
className: "relative z-[2] flex items-center gap-3 px-5 py-3",
|
|
261
|
+
children: [
|
|
262
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
263
|
+
"aria-hidden": "true",
|
|
264
|
+
className: `text-${coverHeaderIconColor}-foreground flex size-7 shrink-0 items-center justify-center rounded-${borderRadius}`,
|
|
265
|
+
style: {
|
|
266
|
+
background: `linear-gradient(135deg, color-mix(in oklch, var(--color-${coverHeaderIconColor}) 75%, white 25%) 0%, var(--color-${coverHeaderIconColor}) 100%)`,
|
|
267
|
+
boxShadow: `
|
|
268
|
+
inset 0 1px 0 rgba(255,255,255,0.25),
|
|
269
|
+
inset 0 -1px 0 rgba(0,0,0,0.08),
|
|
270
|
+
0 1px 2px color-mix(in oklch, var(--color-${coverHeaderIconColor}) 25%, transparent)
|
|
271
|
+
`
|
|
272
|
+
},
|
|
273
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIcon, {
|
|
274
|
+
className: "size-3.5",
|
|
275
|
+
strokeWidth: 2.25
|
|
276
|
+
})
|
|
277
|
+
}),
|
|
278
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
279
|
+
className: "min-w-0 flex-1",
|
|
280
|
+
children: [effectiveTitle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
281
|
+
className: "text-foreground truncate text-[15px] leading-tight font-semibold tracking-tight",
|
|
282
|
+
children: effectiveTitle
|
|
283
|
+
}), coverMeta && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
284
|
+
className: "text-foreground/40 mt-0.5 truncate text-[11px] font-medium tracking-[0.08em] uppercase",
|
|
285
|
+
children: coverMeta
|
|
286
|
+
})]
|
|
287
|
+
}),
|
|
288
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
289
|
+
className: "bg-foreground/5 flex shrink-0 items-center rounded-lg p-0.5",
|
|
290
|
+
children: [
|
|
291
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
|
|
292
|
+
Icon: lucide_react.RotateCw,
|
|
293
|
+
label: "Reload",
|
|
294
|
+
onClick: (e) => {
|
|
295
|
+
e.stopPropagation();
|
|
296
|
+
handleReload();
|
|
297
|
+
}
|
|
298
|
+
}),
|
|
299
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
|
|
300
|
+
Icon: lucide_react.Maximize2,
|
|
301
|
+
label: "Open",
|
|
302
|
+
onClick: (e) => {
|
|
303
|
+
e.stopPropagation();
|
|
304
|
+
handleOpenModal();
|
|
305
|
+
}
|
|
306
|
+
}),
|
|
307
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
|
|
308
|
+
Icon: lucide_react.ExternalLink,
|
|
309
|
+
label: "Open in new tab",
|
|
310
|
+
onClick: handleOpenNewTab
|
|
311
|
+
})
|
|
312
|
+
]
|
|
313
|
+
})
|
|
314
|
+
]
|
|
315
|
+
}),
|
|
316
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
317
|
+
type: "button",
|
|
318
|
+
onClick: handleOpenModal,
|
|
319
|
+
disabled: editMode,
|
|
320
|
+
className: `relative block w-full overflow-hidden ${editMode ? "cursor-default" : "cursor-pointer"}`,
|
|
321
|
+
style: { height: coverHeight },
|
|
322
|
+
"aria-label": `Open ${effectiveTitle || title}`,
|
|
323
|
+
children: resolvedCoverImage ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
324
|
+
src: resolvedCoverImage,
|
|
325
|
+
alt: effectiveTitle || title,
|
|
326
|
+
className: "h-full w-full object-cover"
|
|
327
|
+
}, `cover-${coverReloadKey}`) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
328
|
+
className: "bg-muted flex h-full w-full items-center justify-center",
|
|
329
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "text-muted-foreground/40 size-16" })
|
|
330
|
+
})
|
|
331
|
+
}),
|
|
332
|
+
editMode && !isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "absolute inset-0 z-10" })
|
|
333
|
+
]
|
|
334
|
+
}), modalOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmbedModal, {
|
|
335
|
+
src: iframeSrc,
|
|
336
|
+
title: effectiveTitle || title,
|
|
337
|
+
allowFullscreen,
|
|
338
|
+
iframeRef,
|
|
339
|
+
onClose: closeModal,
|
|
340
|
+
onReload: () => setIframeReloadKey((key) => key + 1)
|
|
341
|
+
}, `modal-${iframeReloadKey}`)] });
|
|
342
|
+
}
|
|
343
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
344
|
+
className: `relative w-full rounded-${borderRadius} ${require_registries.borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? require_registries.borderColorClasses[borderColor] : ""} ${isFullScreen ? "h-full" : ""} ${className ?? ""}`,
|
|
345
|
+
...props,
|
|
346
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
347
|
+
ref: iframeRef,
|
|
348
|
+
src: iframeSrc,
|
|
349
|
+
title,
|
|
350
|
+
width: "100%",
|
|
351
|
+
style: isFullScreen ? { height: "100%" } : { height },
|
|
352
|
+
loading,
|
|
353
|
+
allowFullScreen: allowFullscreen,
|
|
354
|
+
className: `rounded-${borderRadius} border-border border`,
|
|
355
|
+
sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"
|
|
356
|
+
}), editMode && !isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "absolute inset-0 z-10" })]
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
function HeaderIconButton({ Icon, label, onClick }) {
|
|
360
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
361
|
+
type: "button",
|
|
362
|
+
onClick,
|
|
363
|
+
"aria-label": label,
|
|
364
|
+
className: "text-foreground/45 hover:text-foreground hover:bg-background flex size-7 items-center justify-center rounded-md transition-colors",
|
|
365
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
366
|
+
className: "size-3.5",
|
|
367
|
+
strokeWidth: 2.25
|
|
368
|
+
})
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
function EmbedModal({ src, title, allowFullscreen, iframeRef, onClose, onReload }) {
|
|
372
|
+
const dialogRef = (0, react.useRef)(null);
|
|
373
|
+
useDialogFocusRestore(dialogRef);
|
|
374
|
+
return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
375
|
+
ref: dialogRef,
|
|
376
|
+
tabIndex: -1,
|
|
377
|
+
className: "fixed inset-0 z-[100] flex items-center justify-center p-4 focus:outline-none sm:p-8",
|
|
378
|
+
style: { background: "color-mix(in oklch, var(--color-foreground) 80%, black)" },
|
|
379
|
+
onClick: onClose,
|
|
380
|
+
role: "dialog",
|
|
381
|
+
"aria-modal": "true",
|
|
382
|
+
"aria-label": title,
|
|
383
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
384
|
+
className: "bg-background relative flex h-full max-h-[95vh] w-full max-w-[1400px] flex-col overflow-hidden rounded-2xl shadow-2xl",
|
|
385
|
+
onClick: (e) => e.stopPropagation(),
|
|
386
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
387
|
+
className: "flex items-center justify-between gap-4 px-5 py-3",
|
|
388
|
+
style: { borderBottom: "1px solid color-mix(in oklch, var(--color-foreground) 8%, transparent)" },
|
|
389
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
390
|
+
className: "text-foreground truncate text-sm font-semibold tracking-tight",
|
|
391
|
+
children: title
|
|
392
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
393
|
+
className: "flex shrink-0 items-center gap-1",
|
|
394
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
|
|
395
|
+
Icon: lucide_react.RotateCw,
|
|
396
|
+
label: "Reload",
|
|
397
|
+
onClick: (e) => {
|
|
398
|
+
e.stopPropagation();
|
|
399
|
+
onReload();
|
|
400
|
+
}
|
|
401
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
402
|
+
type: "button",
|
|
403
|
+
onClick: onClose,
|
|
404
|
+
"aria-label": "Close",
|
|
405
|
+
className: "text-foreground/60 hover:text-foreground hover:bg-foreground/5 flex size-9 shrink-0 items-center justify-center rounded-full transition-colors",
|
|
406
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "size-5" })
|
|
407
|
+
})]
|
|
408
|
+
})]
|
|
409
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
410
|
+
ref: iframeRef,
|
|
411
|
+
src,
|
|
412
|
+
title,
|
|
413
|
+
className: "flex-1 border-0",
|
|
414
|
+
allowFullScreen: allowFullscreen,
|
|
415
|
+
sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"
|
|
416
|
+
})]
|
|
417
|
+
})
|
|
418
|
+
}), document.body);
|
|
419
|
+
}
|
|
420
|
+
const embedWidgetPropertySchema = {
|
|
421
|
+
widgetType: "EmbedWidget",
|
|
422
|
+
displayName: "Embed",
|
|
423
|
+
fields: [
|
|
424
|
+
{
|
|
425
|
+
key: "url",
|
|
426
|
+
label: "URL",
|
|
427
|
+
type: "text",
|
|
428
|
+
description: "The URL of the external site to embed",
|
|
429
|
+
placeholder: "https://example.com",
|
|
430
|
+
defaultValue: "",
|
|
431
|
+
group: "Content"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
key: "title",
|
|
435
|
+
label: "Title",
|
|
436
|
+
type: "text",
|
|
437
|
+
description: "Accessibility title for the embedded content",
|
|
438
|
+
defaultValue: "Embedded Content",
|
|
439
|
+
group: "Content"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
key: "displayMode",
|
|
443
|
+
label: "Display Mode",
|
|
444
|
+
type: "buttonGroup",
|
|
445
|
+
description: "Inline: iframe renders directly. Cover: shows a card that opens the embed in a full-screen modal.",
|
|
446
|
+
defaultValue: "inline",
|
|
447
|
+
options: [{
|
|
448
|
+
label: "Inline",
|
|
449
|
+
value: "inline"
|
|
450
|
+
}, {
|
|
451
|
+
label: "Cover + Modal",
|
|
452
|
+
value: "cover"
|
|
453
|
+
}],
|
|
454
|
+
group: "Display Mode"
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
key: "coverResource",
|
|
458
|
+
label: "Cover Image",
|
|
459
|
+
type: "resource",
|
|
460
|
+
description: "Select the image shown before the embed opens",
|
|
461
|
+
allowedTypes: ["Medium"],
|
|
462
|
+
group: "Cover",
|
|
463
|
+
requiresKeyValue: {
|
|
464
|
+
key: "displayMode",
|
|
465
|
+
value: "cover"
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
key: "coverUseCustomUrl",
|
|
470
|
+
label: "Use Custom URL",
|
|
471
|
+
type: "boolean",
|
|
472
|
+
description: "Enter a custom image URL instead of selecting media",
|
|
473
|
+
defaultValue: false,
|
|
474
|
+
group: "Cover",
|
|
475
|
+
requiresKeyValue: {
|
|
476
|
+
key: "displayMode",
|
|
477
|
+
value: "cover"
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
key: "coverImageUrl",
|
|
482
|
+
label: "Cover Image URL",
|
|
483
|
+
type: "text",
|
|
484
|
+
description: "Direct URL to the cover image",
|
|
485
|
+
placeholder: "https://example.com/cover.jpg",
|
|
486
|
+
defaultValue: "",
|
|
487
|
+
group: "Cover",
|
|
488
|
+
requiresKeyValue: [{
|
|
489
|
+
key: "displayMode",
|
|
490
|
+
value: "cover"
|
|
491
|
+
}, {
|
|
492
|
+
key: "coverUseCustomUrl",
|
|
493
|
+
value: true
|
|
494
|
+
}]
|
|
495
|
+
},
|
|
496
|
+
require_registries.getHeightField({
|
|
497
|
+
key: "coverHeight",
|
|
498
|
+
label: "Cover Height",
|
|
499
|
+
description: "Height of the cover image area",
|
|
500
|
+
defaultValue: "320px",
|
|
501
|
+
group: "Cover",
|
|
502
|
+
requiresKeyValue: {
|
|
503
|
+
key: "displayMode",
|
|
504
|
+
value: "cover"
|
|
505
|
+
}
|
|
506
|
+
}),
|
|
507
|
+
{
|
|
508
|
+
key: "coverShowHeader",
|
|
509
|
+
label: "Show Card Header",
|
|
510
|
+
type: "boolean",
|
|
511
|
+
description: "Show the header with icon, title, and action buttons",
|
|
512
|
+
defaultValue: true,
|
|
513
|
+
group: "Cover Header",
|
|
514
|
+
requiresKeyValue: {
|
|
515
|
+
key: "displayMode",
|
|
516
|
+
value: "cover"
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
key: "coverHeaderIcon",
|
|
521
|
+
label: "Header Icon",
|
|
522
|
+
type: "select",
|
|
523
|
+
description: "Icon displayed in the colored badge on the left",
|
|
524
|
+
options: HEADER_ICON_OPTIONS,
|
|
525
|
+
defaultValue: "GraduationCap",
|
|
526
|
+
group: "Cover Header",
|
|
527
|
+
requiresKeyValue: [{
|
|
528
|
+
key: "displayMode",
|
|
529
|
+
value: "cover"
|
|
530
|
+
}, {
|
|
531
|
+
key: "coverShowHeader",
|
|
532
|
+
value: true
|
|
533
|
+
}]
|
|
534
|
+
},
|
|
535
|
+
require_registries.getColorField({
|
|
536
|
+
key: "coverHeaderIconColor",
|
|
537
|
+
label: "Icon Badge Color",
|
|
538
|
+
description: "Background color of the icon badge",
|
|
539
|
+
defaultValue: "primary",
|
|
540
|
+
group: "Cover Header",
|
|
541
|
+
requiresKeyValue: [{
|
|
542
|
+
key: "displayMode",
|
|
543
|
+
value: "cover"
|
|
544
|
+
}, {
|
|
545
|
+
key: "coverShowHeader",
|
|
546
|
+
value: true
|
|
547
|
+
}]
|
|
548
|
+
}),
|
|
549
|
+
{
|
|
550
|
+
key: "coverTitle",
|
|
551
|
+
label: "Header Title",
|
|
552
|
+
type: "text",
|
|
553
|
+
description: "Title shown in the card header and modal (falls back to the widget Title if empty). Available even when the card header is hidden so the modal still has a meaningful title.",
|
|
554
|
+
defaultValue: "",
|
|
555
|
+
group: "Cover Header",
|
|
556
|
+
requiresKeyValue: {
|
|
557
|
+
key: "displayMode",
|
|
558
|
+
value: "cover"
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
key: "coverMeta",
|
|
563
|
+
label: "Meta Text",
|
|
564
|
+
type: "text",
|
|
565
|
+
description: "Small uppercase meta line below the title (e.g. 'APR 16 · COACHING THE HOSTESS')",
|
|
566
|
+
defaultValue: "",
|
|
567
|
+
group: "Cover Header",
|
|
568
|
+
requiresKeyValue: [{
|
|
569
|
+
key: "displayMode",
|
|
570
|
+
value: "cover"
|
|
571
|
+
}, {
|
|
572
|
+
key: "coverShowHeader",
|
|
573
|
+
value: true
|
|
574
|
+
}]
|
|
575
|
+
},
|
|
576
|
+
require_registries.getBorderRadiusField({
|
|
577
|
+
key: "borderRadius",
|
|
578
|
+
label: "Border Radius",
|
|
579
|
+
description: "Border radius for the embed container",
|
|
580
|
+
defaultValue: "md",
|
|
581
|
+
group: "Design"
|
|
582
|
+
}),
|
|
583
|
+
require_registries.getBorderWidthField({
|
|
584
|
+
key: "borderWidth",
|
|
585
|
+
label: "Border Width",
|
|
586
|
+
description: "Border width for the widget",
|
|
587
|
+
defaultValue: "none",
|
|
588
|
+
group: "Design"
|
|
589
|
+
}),
|
|
590
|
+
require_registries.getBorderColorField({
|
|
591
|
+
key: "borderColor",
|
|
592
|
+
label: "Border Color",
|
|
593
|
+
description: "Border color for the widget",
|
|
594
|
+
defaultValue: "muted",
|
|
595
|
+
group: "Design"
|
|
596
|
+
}),
|
|
597
|
+
{
|
|
598
|
+
key: "fullScreen",
|
|
599
|
+
label: "Full Screen",
|
|
600
|
+
type: "boolean",
|
|
601
|
+
description: "Inline mode: fill the available space instead of a fixed height",
|
|
602
|
+
defaultValue: false,
|
|
603
|
+
group: "Design",
|
|
604
|
+
requiresKeyValue: {
|
|
605
|
+
key: "displayMode",
|
|
606
|
+
value: "inline"
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
require_registries.getHeightField({
|
|
610
|
+
key: "height",
|
|
611
|
+
label: "Height",
|
|
612
|
+
description: "Height of the inline embed iframe",
|
|
613
|
+
defaultValue: "400px",
|
|
614
|
+
group: "Design",
|
|
615
|
+
requiresKeyValue: [{
|
|
616
|
+
key: "displayMode",
|
|
617
|
+
value: "inline"
|
|
618
|
+
}, {
|
|
619
|
+
key: "fullScreen",
|
|
620
|
+
value: false
|
|
621
|
+
}]
|
|
622
|
+
}),
|
|
623
|
+
{
|
|
624
|
+
key: "allowFullscreen",
|
|
625
|
+
label: "Allow Fullscreen",
|
|
626
|
+
type: "boolean",
|
|
627
|
+
description: "Allow the embedded content to use fullscreen mode",
|
|
628
|
+
defaultValue: true,
|
|
629
|
+
group: "Settings"
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
key: "loading",
|
|
633
|
+
label: "Loading",
|
|
634
|
+
type: "select",
|
|
635
|
+
description: "When to load the embedded content (inline mode only)",
|
|
636
|
+
options: [{
|
|
637
|
+
label: "Lazy (on scroll)",
|
|
638
|
+
value: "lazy"
|
|
639
|
+
}, {
|
|
640
|
+
label: "Eager (immediately)",
|
|
641
|
+
value: "eager"
|
|
642
|
+
}],
|
|
643
|
+
defaultValue: "lazy",
|
|
644
|
+
group: "Settings",
|
|
645
|
+
requiresKeyValue: {
|
|
646
|
+
key: "displayMode",
|
|
647
|
+
value: "inline"
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
]
|
|
651
|
+
};
|
|
652
|
+
//#endregion
|
|
653
|
+
Object.defineProperty(exports, "EmbedWidget", {
|
|
654
|
+
enumerable: true,
|
|
655
|
+
get: function() {
|
|
656
|
+
return EmbedWidget;
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
Object.defineProperty(exports, "EmbedWidget_exports", {
|
|
660
|
+
enumerable: true,
|
|
661
|
+
get: function() {
|
|
662
|
+
return EmbedWidget_exports;
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
Object.defineProperty(exports, "RepUserProvider", {
|
|
666
|
+
enumerable: true,
|
|
667
|
+
get: function() {
|
|
668
|
+
return RepUserProvider;
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
Object.defineProperty(exports, "embedWidgetPropertySchema", {
|
|
672
|
+
enumerable: true,
|
|
673
|
+
get: function() {
|
|
674
|
+
return embedWidgetPropertySchema;
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
Object.defineProperty(exports, "useRepUser", {
|
|
678
|
+
enumerable: true,
|
|
679
|
+
get: function() {
|
|
680
|
+
return useRepUser;
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
//# sourceMappingURL=EmbedWidget-BysWpVIC.cjs.map
|