@fluid-app/portal-sdk 0.1.208 → 0.1.210
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/{FluidProvider-Df88VSWk.cjs → FluidProvider-CZSbUoDH.cjs} +5 -5
- package/dist/{FluidProvider-Df88VSWk.cjs.map → FluidProvider-CZSbUoDH.cjs.map} +1 -1
- package/dist/{FluidProvider-0Mba_MWW.mjs → FluidProvider-DBh92Dz3.mjs} +5 -5
- package/dist/{FluidProvider-0Mba_MWW.mjs.map → FluidProvider-DBh92Dz3.mjs.map} +1 -1
- package/dist/{MessagingScreen-BE9FZr7f.cjs → MessagingScreen-C9pAZqA0.cjs} +2 -2
- package/dist/{MessagingScreen-BE9FZr7f.cjs.map → MessagingScreen-C9pAZqA0.cjs.map} +1 -1
- package/dist/{MessagingScreen-BKgNsHdQ.mjs → MessagingScreen-DhtepYkU.mjs} +2 -2
- package/dist/{MessagingScreen-BKgNsHdQ.mjs.map → MessagingScreen-DhtepYkU.mjs.map} +1 -1
- package/dist/{MessagingScreen-BrHK0nrA.cjs → MessagingScreen-FyP5WFDU.cjs} +4 -4
- package/dist/{ProfileScreen-DYHRKKVI.cjs → ProfileScreen-0ZfgjXvC.cjs} +4 -4
- package/dist/{ProfileScreen-WC3LIwDh.mjs → ProfileScreen-BEZneAry.mjs} +2 -2
- package/dist/{ProfileScreen-WC3LIwDh.mjs.map → ProfileScreen-BEZneAry.mjs.map} +1 -1
- package/dist/{ProfileScreen-DtNJ1sdF.cjs → ProfileScreen-Dyh4GP76.cjs} +2 -2
- package/dist/{ProfileScreen-DtNJ1sdF.cjs.map → ProfileScreen-Dyh4GP76.cjs.map} +1 -1
- package/dist/QuickShareWidget-BdAgexWk.cjs +583 -0
- package/dist/QuickShareWidget-BdAgexWk.cjs.map +1 -0
- package/dist/QuickShareWidget-CunkC1r8.mjs +566 -0
- package/dist/QuickShareWidget-CunkC1r8.mjs.map +1 -0
- package/dist/RecentActivityWidget-C6qm5x9b.mjs +560 -0
- package/dist/RecentActivityWidget-C6qm5x9b.mjs.map +1 -0
- package/dist/RecentActivityWidget-Cw5Qxx_x.cjs +577 -0
- package/dist/RecentActivityWidget-Cw5Qxx_x.cjs.map +1 -0
- package/dist/{ShopScreen-Bo9YZ_EO.cjs → ShopScreen-D06ln7AW.cjs} +2 -2
- package/dist/{ShopScreen-Bo9YZ_EO.cjs.map → ShopScreen-D06ln7AW.cjs.map} +1 -1
- package/dist/{ShopScreen-MZm20clN.cjs → ShopScreen-DTtw168w.cjs} +4 -4
- package/dist/{ShopScreen-BfexFHUc.mjs → ShopScreen-DeVoH7co.mjs} +2 -2
- package/dist/{ShopScreen-BfexFHUc.mjs.map → ShopScreen-DeVoH7co.mjs.map} +1 -1
- package/dist/index.cjs +12 -12
- package/dist/index.d.cts +15 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +15 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +12 -12
- package/package.json +11 -11
- package/dist/QuickShareWidget-DRbErOlt.cjs +0 -268
- package/dist/QuickShareWidget-DRbErOlt.cjs.map +0 -1
- package/dist/QuickShareWidget-Dbjueevf.mjs +0 -251
- package/dist/QuickShareWidget-Dbjueevf.mjs.map +0 -1
- package/dist/RecentActivityWidget-CWr6bFgP.cjs +0 -394
- package/dist/RecentActivityWidget-CWr6bFgP.cjs.map +0 -1
- package/dist/RecentActivityWidget-D-uJcFkE.mjs +0 -377
- package/dist/RecentActivityWidget-D-uJcFkE.mjs.map +0 -1
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
const require_chunk = require("./chunk-9hOWP6kD.cjs");
|
|
2
|
+
const require_registries = require("./registries-CpUM406S.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
let lucide_react = require("lucide-react");
|
|
6
|
+
let qrcode_react = require("qrcode.react");
|
|
7
|
+
//#region ../widgets/src/widgets/QuickShareWidget.tsx
|
|
8
|
+
var QuickShareWidget_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
9
|
+
QuickShareWidget: () => QuickShareWidget,
|
|
10
|
+
quickShareWidgetPropertySchema: () => quickShareWidgetPropertySchema
|
|
11
|
+
});
|
|
12
|
+
const RESOURCE_TYPE_MAP = {
|
|
13
|
+
Product: {
|
|
14
|
+
label: "Product",
|
|
15
|
+
icon: lucide_react.Package
|
|
16
|
+
},
|
|
17
|
+
Page: {
|
|
18
|
+
label: "Page",
|
|
19
|
+
icon: lucide_react.FileText
|
|
20
|
+
},
|
|
21
|
+
EnrollmentPack: {
|
|
22
|
+
label: "Enrollment",
|
|
23
|
+
icon: lucide_react.Ticket
|
|
24
|
+
},
|
|
25
|
+
Medium: {
|
|
26
|
+
label: "Media",
|
|
27
|
+
icon: lucide_react.Image
|
|
28
|
+
},
|
|
29
|
+
Library: {
|
|
30
|
+
label: "Library",
|
|
31
|
+
icon: lucide_react.BookOpen
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const getResourceDescriptor = (resource) => {
|
|
35
|
+
const rawType = resource?.type || resource?.shareableType || "";
|
|
36
|
+
if (!rawType) return null;
|
|
37
|
+
return RESOURCE_TYPE_MAP[rawType] ?? {
|
|
38
|
+
label: rawType,
|
|
39
|
+
icon: lucide_react.CircleDot
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const splitUrl = (url) => {
|
|
43
|
+
try {
|
|
44
|
+
const parsed = new URL(url);
|
|
45
|
+
return {
|
|
46
|
+
prefix: `${parsed.protocol}//${parsed.host}`,
|
|
47
|
+
path: `${parsed.pathname}${parsed.search}${parsed.hash}`
|
|
48
|
+
};
|
|
49
|
+
} catch {
|
|
50
|
+
return {
|
|
51
|
+
prefix: "",
|
|
52
|
+
path: url
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const CURRENCY_FIELD_KEYS = [
|
|
57
|
+
"currency",
|
|
58
|
+
"currency_code",
|
|
59
|
+
"currencyCode",
|
|
60
|
+
"currencyIso",
|
|
61
|
+
"currency_iso"
|
|
62
|
+
];
|
|
63
|
+
const getResourceCurrency = (resource) => {
|
|
64
|
+
if (!resource) return null;
|
|
65
|
+
for (const key of CURRENCY_FIELD_KEYS) {
|
|
66
|
+
const value = resource[key];
|
|
67
|
+
if (typeof value === "string" && /^[A-Z]{3}$/i.test(value)) return value.toUpperCase();
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
};
|
|
71
|
+
const formatNumericPrice = (price, resource) => {
|
|
72
|
+
const currency = getResourceCurrency(resource);
|
|
73
|
+
if (!currency) return String(price);
|
|
74
|
+
try {
|
|
75
|
+
return price.toLocaleString(void 0, {
|
|
76
|
+
style: "currency",
|
|
77
|
+
currency
|
|
78
|
+
});
|
|
79
|
+
} catch {
|
|
80
|
+
return String(price);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const getDisplayPrice = (resource) => {
|
|
84
|
+
if (!resource) return null;
|
|
85
|
+
if (typeof resource.display_price === "string" && resource.display_price) return resource.display_price;
|
|
86
|
+
if (resource.price != null) return typeof resource.price === "number" ? formatNumericPrice(resource.price, resource) : String(resource.price);
|
|
87
|
+
return null;
|
|
88
|
+
};
|
|
89
|
+
const getColorCssValue = (color) => color === "transparent" ? "transparent" : `var(--color-${color})`;
|
|
90
|
+
const colorMix = (color, amount) => color === "transparent" ? "transparent" : `color-mix(in oklch, ${getColorCssValue(color)} ${amount}%, transparent)`;
|
|
91
|
+
const insetBorder = (color, amount) => `inset 0 0 0 1px ${colorMix(color, amount)}`;
|
|
92
|
+
function QuickShareWidget({ shareableResource, titleEnabled = true, titleText = "", titleFontSize = "2xl", titleColor = "background", textColor = "background", accentColor = "primary", padding = 6, borderRadius = "xl", borderWidth = "none", borderColor = "muted", overlayEnabled = true, overlayType = "gradient", overlayIntensity = 70, showBuyButton = false, showResourceType = true, showShareActions = true, showDomainPrefix = true, className, style, ...props }) {
|
|
93
|
+
const [copyState, setCopyState] = (0, react.useState)("idle");
|
|
94
|
+
const [imageFailed, setImageFailed] = (0, react.useState)(false);
|
|
95
|
+
(0, react.useEffect)(() => {
|
|
96
|
+
if (copyState !== "copied") return;
|
|
97
|
+
const id = window.setTimeout(() => setCopyState("idle"), 1600);
|
|
98
|
+
return () => window.clearTimeout(id);
|
|
99
|
+
}, [copyState]);
|
|
100
|
+
const backgroundImageUrl = shareableResource?.image_url || shareableResource?.imageUrl || "";
|
|
101
|
+
(0, react.useEffect)(() => {
|
|
102
|
+
setImageFailed(false);
|
|
103
|
+
}, [backgroundImageUrl]);
|
|
104
|
+
const showHeroImage = Boolean(backgroundImageUrl) && !imageFailed;
|
|
105
|
+
const shareLink = shareableResource?.share_link || "";
|
|
106
|
+
const hasShareLink = !!shareLink;
|
|
107
|
+
const displayTitle = titleText || shareableResource?.title || "Select content to share";
|
|
108
|
+
const resourceDescriptor = getResourceDescriptor(shareableResource);
|
|
109
|
+
const displayPrice = getDisplayPrice(shareableResource);
|
|
110
|
+
const isProduct = shareableResource?.type === "Product" || shareableResource?.shareableType === "Product";
|
|
111
|
+
const shouldShowBuyButton = showBuyButton && isProduct;
|
|
112
|
+
const parsedOverlayIntensity = Number(String(overlayIntensity).replace("%", ""));
|
|
113
|
+
const overlayOpacity = (Number.isFinite(parsedOverlayIntensity) ? Math.min(100, Math.max(0, parsedOverlayIntensity)) : 70) / 100;
|
|
114
|
+
const editorialGradient = overlayEnabled && showHeroImage ? { background: `linear-gradient(to top, color-mix(in oklch, var(--color-foreground) ${Math.round(overlayOpacity * 100)}%, transparent), color-mix(in oklch, var(--color-foreground) ${Math.round(overlayOpacity * 55)}%, transparent) 45%, transparent 85%)` } : void 0;
|
|
115
|
+
const handleCopy = async () => {
|
|
116
|
+
if (!hasShareLink) return;
|
|
117
|
+
try {
|
|
118
|
+
await navigator.clipboard.writeText(shareLink);
|
|
119
|
+
setCopyState("copied");
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error("Failed to copy to clipboard:", error);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const handleNativeShare = async () => {
|
|
125
|
+
if (!hasShareLink) return;
|
|
126
|
+
if (typeof navigator.share === "function") try {
|
|
127
|
+
await navigator.share({
|
|
128
|
+
title: displayTitle,
|
|
129
|
+
url: shareLink
|
|
130
|
+
});
|
|
131
|
+
} catch {}
|
|
132
|
+
else await handleCopy();
|
|
133
|
+
};
|
|
134
|
+
const { prefix, path } = hasShareLink ? splitUrl(shareLink) : {
|
|
135
|
+
prefix: "",
|
|
136
|
+
path: ""
|
|
137
|
+
};
|
|
138
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
139
|
+
className: `relative isolate overflow-hidden rounded-${borderRadius} ${require_registries.borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? require_registries.borderColorClasses[borderColor] : ""} bg-muted text-${textColor} ${className ?? ""}`,
|
|
140
|
+
style: {
|
|
141
|
+
boxShadow: `0 1px 2px color-mix(in oklch, var(--color-foreground) 4%, transparent), 0 20px 40px -20px color-mix(in oklch, var(--color-foreground) 25%, transparent)`,
|
|
142
|
+
...style
|
|
143
|
+
},
|
|
144
|
+
...props,
|
|
145
|
+
children: [showHeroImage ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
146
|
+
className: "absolute inset-0",
|
|
147
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
148
|
+
src: backgroundImageUrl,
|
|
149
|
+
alt: "",
|
|
150
|
+
loading: "lazy",
|
|
151
|
+
onError: () => setImageFailed(true),
|
|
152
|
+
className: "h-full w-full object-cover"
|
|
153
|
+
}), overlayEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
154
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
155
|
+
className: "pointer-events-none absolute inset-0",
|
|
156
|
+
style: editorialGradient
|
|
157
|
+
}),
|
|
158
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
159
|
+
className: "pointer-events-none absolute inset-0",
|
|
160
|
+
style: { background: `linear-gradient(to top right, color-mix(in oklch, var(--color-foreground) ${Math.round(overlayOpacity * 65)}%, transparent), color-mix(in oklch, var(--color-foreground) ${Math.round(overlayOpacity * 25)}%, transparent) 35%, transparent 65%)` }
|
|
161
|
+
}),
|
|
162
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
163
|
+
className: "pointer-events-none absolute inset-0",
|
|
164
|
+
style: { background: `radial-gradient(ellipse 70% 55% at 15% 100%, color-mix(in oklch, var(--color-foreground) ${Math.round(overlayOpacity * 45)}%, transparent), transparent 70%)` }
|
|
165
|
+
}),
|
|
166
|
+
overlayType === "solid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
167
|
+
className: "bg-foreground pointer-events-none absolute inset-0",
|
|
168
|
+
style: { opacity: overlayOpacity * .35 }
|
|
169
|
+
})
|
|
170
|
+
] })]
|
|
171
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyHero, {
|
|
172
|
+
accentColor,
|
|
173
|
+
textColor
|
|
174
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
175
|
+
className: `relative flex min-h-[440px] flex-col p-${padding}`,
|
|
176
|
+
children: [
|
|
177
|
+
showResourceType && resourceDescriptor || displayPrice ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
178
|
+
className: "flex items-start justify-between gap-3",
|
|
179
|
+
children: [showResourceType && resourceDescriptor ? (() => {
|
|
180
|
+
const { icon: ResourceIcon, label } = resourceDescriptor;
|
|
181
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
182
|
+
className: `inline-flex items-center gap-1.5 rounded-${borderRadius} bg-${textColor}/15 px-2.5 py-1 text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor} backdrop-blur-sm`,
|
|
183
|
+
style: { boxShadow: insetBorder(textColor, 15) },
|
|
184
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResourceIcon, { className: "size-3" }), label]
|
|
185
|
+
});
|
|
186
|
+
})() : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {}), displayPrice && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
187
|
+
className: `inline-flex items-center rounded-${borderRadius} bg-${accentColor} px-2.5 py-1 text-[11px] font-bold tabular-nums text-${accentColor}-foreground`,
|
|
188
|
+
style: { boxShadow: `0 4px 14px -4px color-mix(in oklch, var(--color-foreground) 30%, transparent)` },
|
|
189
|
+
children: displayPrice
|
|
190
|
+
})]
|
|
191
|
+
}) : null,
|
|
192
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
193
|
+
className: "mt-4 flex flex-1 flex-col justify-end",
|
|
194
|
+
children: titleEnabled && displayTitle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
195
|
+
className: `text-${titleFontSize} font-header leading-[1.12] font-bold tracking-[-0.015em] text-${titleColor}`,
|
|
196
|
+
style: { textShadow: showHeroImage ? `0 2px 12px color-mix(in oklch, var(--color-foreground) 40%, transparent)` : void 0 },
|
|
197
|
+
children: displayTitle
|
|
198
|
+
})
|
|
199
|
+
}),
|
|
200
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
201
|
+
className: "mt-6 flex flex-col gap-3",
|
|
202
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
203
|
+
className: "flex items-stretch gap-3",
|
|
204
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
205
|
+
className: `group relative shrink-0 rounded-${borderRadius} bg-white p-2.5 transition-transform duration-300 hover:scale-[1.02]`,
|
|
206
|
+
style: { boxShadow: `0 4px 16px -4px color-mix(in oklch, var(--color-foreground) 25%, transparent), inset 0 0 0 1px rgba(255,255,255,0.4)` },
|
|
207
|
+
"aria-label": "QR code for share link",
|
|
208
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(qrcode_react.QRCodeSVG, {
|
|
209
|
+
value: shareLink || "https://example.com",
|
|
210
|
+
size: 96,
|
|
211
|
+
level: "H",
|
|
212
|
+
bgColor: "#ffffff",
|
|
213
|
+
fgColor: "#0f172a"
|
|
214
|
+
})
|
|
215
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
216
|
+
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
217
|
+
children: [
|
|
218
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
219
|
+
className: `text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/70`,
|
|
220
|
+
children: "Share link"
|
|
221
|
+
}),
|
|
222
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
223
|
+
type: "button",
|
|
224
|
+
onClick: handleCopy,
|
|
225
|
+
disabled: !hasShareLink,
|
|
226
|
+
"aria-label": copyState === "copied" ? "Copied to clipboard" : "Copy link",
|
|
227
|
+
className: `group flex items-center justify-between gap-2 rounded-${borderRadius} bg-${textColor}/10 px-3 py-2 text-left text-[12px] backdrop-blur-sm transition-all duration-300 hover:bg-${textColor}/15 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--quick-share-focus-ring)] disabled:opacity-50 ${copyState === "copied" ? `bg-${accentColor}/20` : ""}`,
|
|
228
|
+
style: {
|
|
229
|
+
"--quick-share-focus-ring": colorMix(accentColor, 40),
|
|
230
|
+
boxShadow: insetBorder(textColor, 15)
|
|
231
|
+
},
|
|
232
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
233
|
+
className: `min-w-0 flex-1 truncate font-medium tabular-nums text-${textColor}`,
|
|
234
|
+
children: hasShareLink ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [showDomainPrefix && prefix && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
235
|
+
className: `opacity-60`,
|
|
236
|
+
children: prefix
|
|
237
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
238
|
+
className: "font-semibold",
|
|
239
|
+
children: path
|
|
240
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
241
|
+
className: `opacity-60`,
|
|
242
|
+
children: "No link yet"
|
|
243
|
+
})
|
|
244
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
245
|
+
className: `flex size-7 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === "copied" ? `bg-${accentColor} text-${accentColor}-foreground scale-110` : `bg-${textColor}/15 text-${textColor}`}`,
|
|
246
|
+
children: copyState === "copied" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "size-3.5" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Copy, { className: "size-3.5" })
|
|
247
|
+
})]
|
|
248
|
+
}),
|
|
249
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
250
|
+
className: "sr-only",
|
|
251
|
+
"aria-live": "polite",
|
|
252
|
+
role: "status",
|
|
253
|
+
children: copyState === "copied" ? "Copied to clipboard" : ""
|
|
254
|
+
}),
|
|
255
|
+
showShareActions && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareActionRow, {
|
|
256
|
+
shareLink,
|
|
257
|
+
displayTitle,
|
|
258
|
+
accentColor,
|
|
259
|
+
textColor,
|
|
260
|
+
borderRadius,
|
|
261
|
+
onNative: handleNativeShare
|
|
262
|
+
})
|
|
263
|
+
]
|
|
264
|
+
})]
|
|
265
|
+
}), shouldShowBuyButton && (hasShareLink ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
266
|
+
href: shareLink,
|
|
267
|
+
target: "_blank",
|
|
268
|
+
rel: "noopener noreferrer",
|
|
269
|
+
className: `flex w-full items-center justify-center gap-2 rounded-${borderRadius} bg-${accentColor} px-4 py-3 text-[13px] font-bold text-${accentColor}-foreground transition-transform hover:scale-[1.01]`,
|
|
270
|
+
style: { boxShadow: `0 8px 22px -8px color-mix(in oklch, var(--color-foreground) 35%, transparent)` },
|
|
271
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ShoppingCart, { className: "size-4" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Buy now" })]
|
|
272
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
273
|
+
type: "button",
|
|
274
|
+
disabled: true,
|
|
275
|
+
className: `flex w-full cursor-not-allowed items-center justify-center gap-2 rounded-${borderRadius} bg-${accentColor} px-4 py-3 text-[13px] font-bold text-${accentColor}-foreground opacity-50`,
|
|
276
|
+
style: { boxShadow: `0 8px 22px -8px color-mix(in oklch, var(--color-foreground) 35%, transparent)` },
|
|
277
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ShoppingCart, { className: "size-4" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Buy now" })]
|
|
278
|
+
}))]
|
|
279
|
+
})
|
|
280
|
+
]
|
|
281
|
+
})]
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
function ShareActionRow({ shareLink, displayTitle, accentColor, textColor, borderRadius, onNative }) {
|
|
285
|
+
const disabled = !shareLink;
|
|
286
|
+
const [canNativeShare, setCanNativeShare] = (0, react.useState)(false);
|
|
287
|
+
const [canSendSms, setCanSendSms] = (0, react.useState)(false);
|
|
288
|
+
(0, react.useEffect)(() => {
|
|
289
|
+
setCanNativeShare(typeof navigator !== "undefined" && typeof navigator.share === "function");
|
|
290
|
+
setCanSendSms(typeof navigator !== "undefined" && (/Android|iPhone|iPad|iPod/i.test(navigator.userAgent) || /Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints > 1));
|
|
291
|
+
}, []);
|
|
292
|
+
const emailHref = shareLink ? `mailto:?subject=${encodeURIComponent(displayTitle)}&body=${encodeURIComponent(shareLink)}` : void 0;
|
|
293
|
+
const smsHref = shareLink ? `sms:?body=${encodeURIComponent(`${displayTitle} — ${shareLink}`)}` : void 0;
|
|
294
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
295
|
+
className: "flex items-center gap-1.5",
|
|
296
|
+
children: [
|
|
297
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareActionButton, {
|
|
298
|
+
icon: lucide_react.Mail,
|
|
299
|
+
label: "Email",
|
|
300
|
+
href: emailHref,
|
|
301
|
+
disabled,
|
|
302
|
+
accentColor,
|
|
303
|
+
textColor,
|
|
304
|
+
borderRadius
|
|
305
|
+
}),
|
|
306
|
+
canSendSms && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareActionButton, {
|
|
307
|
+
icon: lucide_react.MessageCircle,
|
|
308
|
+
label: "Text",
|
|
309
|
+
href: smsHref,
|
|
310
|
+
disabled,
|
|
311
|
+
accentColor,
|
|
312
|
+
textColor,
|
|
313
|
+
borderRadius
|
|
314
|
+
}),
|
|
315
|
+
canNativeShare && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareActionButton, {
|
|
316
|
+
icon: lucide_react.Share2,
|
|
317
|
+
label: "Share",
|
|
318
|
+
onClick: onNative,
|
|
319
|
+
disabled,
|
|
320
|
+
accentColor,
|
|
321
|
+
textColor,
|
|
322
|
+
borderRadius
|
|
323
|
+
})
|
|
324
|
+
]
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
function ShareActionButton({ icon: Icon, label, href, onClick, disabled, accentColor, textColor, borderRadius }) {
|
|
328
|
+
const className = `group inline-flex items-center gap-1.5 rounded-${borderRadius} bg-${textColor}/10 px-2.5 py-1.5 text-[11px] font-semibold text-${textColor} backdrop-blur-sm transition-all duration-200 hover:-translate-y-0.5 hover:bg-${accentColor} hover:text-${accentColor}-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--quick-share-focus-ring)] disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:translate-y-0`;
|
|
329
|
+
const style = {
|
|
330
|
+
"--quick-share-focus-ring": colorMix(accentColor, 40),
|
|
331
|
+
boxShadow: insetBorder(textColor, 15)
|
|
332
|
+
};
|
|
333
|
+
const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "size-3" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })] });
|
|
334
|
+
if (href && !disabled) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
335
|
+
href,
|
|
336
|
+
className,
|
|
337
|
+
style,
|
|
338
|
+
"aria-label": label,
|
|
339
|
+
children: content
|
|
340
|
+
});
|
|
341
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
342
|
+
type: "button",
|
|
343
|
+
onClick,
|
|
344
|
+
disabled,
|
|
345
|
+
className,
|
|
346
|
+
style,
|
|
347
|
+
"aria-label": label,
|
|
348
|
+
children: content
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
function EmptyHero({ accentColor, textColor }) {
|
|
352
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
353
|
+
className: `bg-muted absolute inset-0`,
|
|
354
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
355
|
+
className: "absolute inset-0",
|
|
356
|
+
style: { background: `radial-gradient(circle at 30% 20%, ${colorMix(accentColor, 15)}, transparent 60%), radial-gradient(circle at 80% 90%, ${colorMix(accentColor, 10)}, transparent 55%)` }
|
|
357
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
358
|
+
className: "absolute inset-0 flex flex-col items-center justify-center gap-3",
|
|
359
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
360
|
+
className: `flex size-14 items-center justify-center rounded-2xl bg-${textColor}/5`,
|
|
361
|
+
style: { boxShadow: insetBorder(textColor, 10) },
|
|
362
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Image, { className: `size-6 text-${textColor}/40` })
|
|
363
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
364
|
+
className: `text-[10px] font-bold tracking-[0.2em] uppercase text-${textColor}/45`,
|
|
365
|
+
children: "Nothing selected"
|
|
366
|
+
})]
|
|
367
|
+
})]
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
const quickShareWidgetPropertySchema = {
|
|
371
|
+
widgetType: "QuickShareWidget",
|
|
372
|
+
displayName: "Quick Share Widget",
|
|
373
|
+
tabsConfig: [{
|
|
374
|
+
id: "styling",
|
|
375
|
+
label: "Styling"
|
|
376
|
+
}],
|
|
377
|
+
fields: [
|
|
378
|
+
{
|
|
379
|
+
key: "shareableResource",
|
|
380
|
+
label: "Shareable Content",
|
|
381
|
+
type: "resource",
|
|
382
|
+
description: "Select the content to generate a share link for",
|
|
383
|
+
allowedTypes: [
|
|
384
|
+
"Product",
|
|
385
|
+
"Page",
|
|
386
|
+
"EnrollmentPack",
|
|
387
|
+
"Medium",
|
|
388
|
+
"Library"
|
|
389
|
+
],
|
|
390
|
+
tab: "styling",
|
|
391
|
+
group: "Content"
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
key: "titleEnabled",
|
|
395
|
+
label: "Show Title",
|
|
396
|
+
type: "boolean",
|
|
397
|
+
description: "Display a title on the hero",
|
|
398
|
+
defaultValue: true,
|
|
399
|
+
tab: "styling",
|
|
400
|
+
group: "Title"
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
key: "titleText",
|
|
404
|
+
label: "Title",
|
|
405
|
+
type: "text",
|
|
406
|
+
description: "Custom title text (defaults to the resource title if empty)",
|
|
407
|
+
defaultValue: "",
|
|
408
|
+
tab: "styling",
|
|
409
|
+
group: "Title",
|
|
410
|
+
requiresKeyToBeTrue: "titleEnabled"
|
|
411
|
+
},
|
|
412
|
+
require_registries.getFontSizeField({
|
|
413
|
+
key: "titleFontSize",
|
|
414
|
+
label: "Title Font Size",
|
|
415
|
+
description: "Font size for the title",
|
|
416
|
+
defaultValue: "2xl",
|
|
417
|
+
tab: "styling",
|
|
418
|
+
group: "Title",
|
|
419
|
+
requiresKeyToBeTrue: "titleEnabled"
|
|
420
|
+
}),
|
|
421
|
+
require_registries.getColorField({
|
|
422
|
+
key: "titleColor",
|
|
423
|
+
label: "Title Color",
|
|
424
|
+
description: "Color for the title",
|
|
425
|
+
defaultValue: "background",
|
|
426
|
+
tab: "styling",
|
|
427
|
+
group: "Title",
|
|
428
|
+
requiresKeyToBeTrue: "titleEnabled"
|
|
429
|
+
}),
|
|
430
|
+
{
|
|
431
|
+
key: "showResourceType",
|
|
432
|
+
label: "Show Resource Type Pill",
|
|
433
|
+
type: "boolean",
|
|
434
|
+
description: "Display a small type eyebrow chip (Product · Page · Media…)",
|
|
435
|
+
defaultValue: true,
|
|
436
|
+
tab: "styling",
|
|
437
|
+
group: "Share Panel"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
key: "showShareActions",
|
|
441
|
+
label: "Show Share Actions",
|
|
442
|
+
type: "boolean",
|
|
443
|
+
description: "Show Email, Text, and native Share buttons under the link chip",
|
|
444
|
+
defaultValue: true,
|
|
445
|
+
tab: "styling",
|
|
446
|
+
group: "Share Panel"
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
key: "showDomainPrefix",
|
|
450
|
+
label: "Show Domain Prefix",
|
|
451
|
+
type: "boolean",
|
|
452
|
+
description: "Include the domain in the link chip (dimmed) with the path emphasized",
|
|
453
|
+
defaultValue: true,
|
|
454
|
+
tab: "styling",
|
|
455
|
+
group: "Share Panel"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
key: "showBuyButton",
|
|
459
|
+
label: "Show Buy Button",
|
|
460
|
+
type: "boolean",
|
|
461
|
+
description: "Display the Buy button (only shown for Product resources)",
|
|
462
|
+
defaultValue: false,
|
|
463
|
+
tab: "styling",
|
|
464
|
+
group: "Share Panel"
|
|
465
|
+
},
|
|
466
|
+
require_registries.getColorField({
|
|
467
|
+
key: "textColor",
|
|
468
|
+
label: "Text Color",
|
|
469
|
+
description: "Default text color for widget content (over the hero)",
|
|
470
|
+
defaultValue: "background",
|
|
471
|
+
tab: "styling",
|
|
472
|
+
group: "Design"
|
|
473
|
+
}),
|
|
474
|
+
require_registries.getColorField({
|
|
475
|
+
key: "accentColor",
|
|
476
|
+
label: "Accent Color",
|
|
477
|
+
description: "Drives the price chip, primary button, and copy-success flash",
|
|
478
|
+
defaultValue: "primary",
|
|
479
|
+
tab: "styling",
|
|
480
|
+
group: "Design"
|
|
481
|
+
}),
|
|
482
|
+
{
|
|
483
|
+
key: "overlayEnabled",
|
|
484
|
+
label: "Enable Overlay",
|
|
485
|
+
type: "boolean",
|
|
486
|
+
description: "Add editorial gradient stack for legibility over the hero",
|
|
487
|
+
defaultValue: true,
|
|
488
|
+
tab: "styling",
|
|
489
|
+
group: "Design"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
key: "overlayType",
|
|
493
|
+
label: "Overlay Type",
|
|
494
|
+
type: "buttonGroup",
|
|
495
|
+
description: "Gradient only (recommended) or gradient + solid wash (heavier)",
|
|
496
|
+
defaultValue: "gradient",
|
|
497
|
+
options: [{
|
|
498
|
+
label: "Gradient",
|
|
499
|
+
value: "gradient"
|
|
500
|
+
}, {
|
|
501
|
+
label: "Solid",
|
|
502
|
+
value: "solid"
|
|
503
|
+
}],
|
|
504
|
+
tab: "styling",
|
|
505
|
+
group: "Design",
|
|
506
|
+
requiresKeyToBeTrue: "overlayEnabled"
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
key: "overlayIntensity",
|
|
510
|
+
label: "Overlay Intensity",
|
|
511
|
+
type: "slider",
|
|
512
|
+
description: "Opacity of the overlay (0-100)",
|
|
513
|
+
min: 0,
|
|
514
|
+
max: 100,
|
|
515
|
+
step: 5,
|
|
516
|
+
defaultValue: 70,
|
|
517
|
+
unit: "%",
|
|
518
|
+
tab: "styling",
|
|
519
|
+
group: "Design",
|
|
520
|
+
requiresKeyToBeTrue: "overlayEnabled"
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
key: "separator",
|
|
524
|
+
type: "separator",
|
|
525
|
+
label: "Separator",
|
|
526
|
+
tab: "styling",
|
|
527
|
+
group: "Design"
|
|
528
|
+
},
|
|
529
|
+
require_registries.getPaddingField({
|
|
530
|
+
key: "padding",
|
|
531
|
+
label: "Padding",
|
|
532
|
+
description: "Padding around the widget content",
|
|
533
|
+
defaultValue: 6,
|
|
534
|
+
tab: "styling",
|
|
535
|
+
group: "Design"
|
|
536
|
+
}),
|
|
537
|
+
require_registries.getBorderRadiusField({
|
|
538
|
+
key: "borderRadius",
|
|
539
|
+
label: "Border Radius",
|
|
540
|
+
description: "Border radius for the widget container",
|
|
541
|
+
defaultValue: "xl",
|
|
542
|
+
tab: "styling",
|
|
543
|
+
group: "Design"
|
|
544
|
+
}),
|
|
545
|
+
require_registries.getBorderWidthField({
|
|
546
|
+
key: "borderWidth",
|
|
547
|
+
label: "Border Width",
|
|
548
|
+
description: "Border width for the widget container",
|
|
549
|
+
defaultValue: "none",
|
|
550
|
+
tab: "styling",
|
|
551
|
+
group: "Design"
|
|
552
|
+
}),
|
|
553
|
+
require_registries.getBorderColorField({
|
|
554
|
+
key: "borderColor",
|
|
555
|
+
label: "Border Color",
|
|
556
|
+
description: "Border color for the widget container",
|
|
557
|
+
defaultValue: "muted",
|
|
558
|
+
tab: "styling",
|
|
559
|
+
group: "Design"
|
|
560
|
+
})
|
|
561
|
+
]
|
|
562
|
+
};
|
|
563
|
+
//#endregion
|
|
564
|
+
Object.defineProperty(exports, "QuickShareWidget", {
|
|
565
|
+
enumerable: true,
|
|
566
|
+
get: function() {
|
|
567
|
+
return QuickShareWidget;
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
Object.defineProperty(exports, "QuickShareWidget_exports", {
|
|
571
|
+
enumerable: true,
|
|
572
|
+
get: function() {
|
|
573
|
+
return QuickShareWidget_exports;
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
Object.defineProperty(exports, "quickShareWidgetPropertySchema", {
|
|
577
|
+
enumerable: true,
|
|
578
|
+
get: function() {
|
|
579
|
+
return quickShareWidgetPropertySchema;
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
//# sourceMappingURL=QuickShareWidget-BdAgexWk.cjs.map
|