react-sharesheet 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -102
- package/dist/content.d.mts +3 -3
- package/dist/content.d.ts +3 -3
- package/dist/content.js +296 -271
- package/dist/content.js.map +1 -1
- package/dist/content.mjs +298 -273
- package/dist/content.mjs.map +1 -1
- package/dist/drawer.d.mts +3 -3
- package/dist/drawer.d.ts +3 -3
- package/dist/drawer.js +298 -275
- package/dist/drawer.js.map +1 -1
- package/dist/drawer.mjs +300 -277
- package/dist/drawer.mjs.map +1 -1
- package/dist/headless-B7I228Dt.d.mts +98 -0
- package/dist/headless-BiSYHizs.d.ts +98 -0
- package/dist/headless.d.mts +3 -50
- package/dist/headless.d.ts +3 -50
- package/dist/headless.js +165 -0
- package/dist/headless.js.map +1 -1
- package/dist/headless.mjs +163 -1
- package/dist/headless.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +339 -277
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +329 -278
- package/dist/index.mjs.map +1 -1
- package/dist/{platforms-DU1DVDFq.d.mts → platforms-omqzPfYX.d.mts} +17 -23
- package/dist/{platforms-DU1DVDFq.d.ts → platforms-omqzPfYX.d.ts} +17 -23
- package/package.json +24 -7
- package/src/ShareSheetContent.tsx +157 -311
- package/src/ShareSheetDrawer.tsx +2 -4
- package/src/__tests__/hooks.test.ts +203 -0
- package/src/__tests__/og-fetcher.test.ts +144 -0
- package/src/__tests__/platforms.test.ts +148 -0
- package/src/__tests__/setup.ts +22 -0
- package/src/__tests__/share-functions.test.ts +152 -0
- package/src/__tests__/utils.test.ts +64 -0
- package/src/headless.ts +4 -1
- package/src/hooks.ts +60 -2
- package/src/index.ts +20 -4
- package/src/og-fetcher.ts +64 -0
- package/src/share-functions.ts +25 -1
- package/src/types.ts +17 -24
- package/src/utils.ts +125 -0
package/dist/drawer.js
CHANGED
|
@@ -47,6 +47,75 @@ function openUrl(url) {
|
|
|
47
47
|
function getSafeUrl(shareUrl) {
|
|
48
48
|
return shareUrl || (typeof window !== "undefined" ? window.location.href : "");
|
|
49
49
|
}
|
|
50
|
+
function isMobileDevice() {
|
|
51
|
+
if (typeof navigator === "undefined") return false;
|
|
52
|
+
const userAgent = navigator.userAgent || navigator.vendor || "";
|
|
53
|
+
const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
|
|
54
|
+
const hasTouch = typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
55
|
+
return mobileRegex.test(userAgent);
|
|
56
|
+
}
|
|
57
|
+
var MOBILE_ONLY_PLATFORMS = [
|
|
58
|
+
"instagram",
|
|
59
|
+
"tiktok",
|
|
60
|
+
"threads",
|
|
61
|
+
"sms"
|
|
62
|
+
];
|
|
63
|
+
function checkPlatformAvailability(platform) {
|
|
64
|
+
const isMobile = isMobileDevice();
|
|
65
|
+
if (MOBILE_ONLY_PLATFORMS.includes(platform)) {
|
|
66
|
+
if (!isMobile) {
|
|
67
|
+
return {
|
|
68
|
+
available: false,
|
|
69
|
+
reason: `${platform} requires a mobile device with the app installed`
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (platform === "sms" && !isMobile) {
|
|
74
|
+
return {
|
|
75
|
+
available: false,
|
|
76
|
+
reason: "SMS sharing requires a mobile device"
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (platform === "native") {
|
|
80
|
+
const canShare = typeof navigator !== "undefined" && "share" in navigator;
|
|
81
|
+
if (!canShare) {
|
|
82
|
+
return {
|
|
83
|
+
available: false,
|
|
84
|
+
reason: "Native share is not supported by this browser"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return { available: true };
|
|
89
|
+
}
|
|
90
|
+
function getAllPlatformAvailability() {
|
|
91
|
+
const platforms = [
|
|
92
|
+
"native",
|
|
93
|
+
"copy",
|
|
94
|
+
"download",
|
|
95
|
+
"whatsapp",
|
|
96
|
+
"telegram",
|
|
97
|
+
"instagram",
|
|
98
|
+
"facebook",
|
|
99
|
+
"snapchat",
|
|
100
|
+
"sms",
|
|
101
|
+
"email",
|
|
102
|
+
"linkedin",
|
|
103
|
+
"reddit",
|
|
104
|
+
"x",
|
|
105
|
+
"tiktok",
|
|
106
|
+
"threads"
|
|
107
|
+
];
|
|
108
|
+
const result = {};
|
|
109
|
+
for (const platform of platforms) {
|
|
110
|
+
result[platform] = checkPlatformAvailability(platform);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
function warnUnavailablePlatform(platform, reason) {
|
|
115
|
+
console.warn(
|
|
116
|
+
`[react-sharesheet] ${platform} sharing is not available: ${reason}. This share option may not work correctly on this device.`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
50
119
|
|
|
51
120
|
// src/ShareSheetContent.tsx
|
|
52
121
|
var import_react2 = require("react");
|
|
@@ -55,6 +124,38 @@ var import_lucide_react2 = require("lucide-react");
|
|
|
55
124
|
// src/hooks.ts
|
|
56
125
|
var import_react = require("react");
|
|
57
126
|
|
|
127
|
+
// src/og-fetcher.ts
|
|
128
|
+
var ogCache = /* @__PURE__ */ new Map();
|
|
129
|
+
async function fetchOGData(url) {
|
|
130
|
+
if (ogCache.has(url)) {
|
|
131
|
+
return ogCache.get(url);
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const apiUrl = `https://api.microlink.io?url=${encodeURIComponent(url)}`;
|
|
135
|
+
const response = await fetch(apiUrl);
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
throw new Error(`Failed to fetch OG data: ${response.status}`);
|
|
138
|
+
}
|
|
139
|
+
const json = await response.json();
|
|
140
|
+
if (json.status !== "success" || !json.data) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
const { title, description, image, url: canonicalUrl, publisher } = json.data;
|
|
144
|
+
const ogData = {
|
|
145
|
+
title: title || void 0,
|
|
146
|
+
description: description || void 0,
|
|
147
|
+
image: image?.url || void 0,
|
|
148
|
+
url: canonicalUrl || url,
|
|
149
|
+
siteName: publisher || void 0
|
|
150
|
+
};
|
|
151
|
+
ogCache.set(url, ogData);
|
|
152
|
+
return ogData;
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.warn("[react-sharesheet] Failed to fetch OG data:", error);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
58
159
|
// src/share-functions.ts
|
|
59
160
|
function shareToWhatsApp(url, text) {
|
|
60
161
|
const encoded = encodeURIComponent(`${text}
|
|
@@ -76,12 +177,24 @@ function shareToFacebook(url) {
|
|
|
76
177
|
openUrl(`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`);
|
|
77
178
|
}
|
|
78
179
|
function openInstagram() {
|
|
180
|
+
const availability = checkPlatformAvailability("instagram");
|
|
181
|
+
if (!availability.available) {
|
|
182
|
+
warnUnavailablePlatform("instagram", availability.reason);
|
|
183
|
+
}
|
|
79
184
|
window.location.href = "instagram://";
|
|
80
185
|
}
|
|
81
186
|
function openTikTok() {
|
|
187
|
+
const availability = checkPlatformAvailability("tiktok");
|
|
188
|
+
if (!availability.available) {
|
|
189
|
+
warnUnavailablePlatform("tiktok", availability.reason);
|
|
190
|
+
}
|
|
82
191
|
window.location.href = "tiktok://";
|
|
83
192
|
}
|
|
84
193
|
function openThreads() {
|
|
194
|
+
const availability = checkPlatformAvailability("threads");
|
|
195
|
+
if (!availability.available) {
|
|
196
|
+
warnUnavailablePlatform("threads", availability.reason);
|
|
197
|
+
}
|
|
85
198
|
window.location.href = "threads://";
|
|
86
199
|
}
|
|
87
200
|
function shareToSnapchat(url) {
|
|
@@ -89,6 +202,10 @@ function shareToSnapchat(url) {
|
|
|
89
202
|
openUrl(`https://www.snapchat.com/scan?attachmentUrl=${encodedUrl}`);
|
|
90
203
|
}
|
|
91
204
|
function shareViaSMS(url, text) {
|
|
205
|
+
const availability = checkPlatformAvailability("sms");
|
|
206
|
+
if (!availability.available) {
|
|
207
|
+
warnUnavailablePlatform("sms", availability.reason);
|
|
208
|
+
}
|
|
92
209
|
const body = encodeURIComponent(`${text}
|
|
93
210
|
${url}`);
|
|
94
211
|
window.location.href = `sms:?body=${body}`;
|
|
@@ -126,6 +243,12 @@ function useShareSheet({
|
|
|
126
243
|
const canNativeShare = (0, import_react.useMemo)(() => {
|
|
127
244
|
return typeof navigator !== "undefined" && "share" in navigator;
|
|
128
245
|
}, []);
|
|
246
|
+
const isMobile = (0, import_react.useMemo)(() => {
|
|
247
|
+
return isMobileDevice();
|
|
248
|
+
}, []);
|
|
249
|
+
const platformAvailability = (0, import_react.useMemo)(() => {
|
|
250
|
+
return getAllPlatformAvailability();
|
|
251
|
+
}, []);
|
|
129
252
|
const safeUrl = getSafeUrl(shareUrl);
|
|
130
253
|
const copyLink = (0, import_react.useCallback)(async () => {
|
|
131
254
|
if (!safeUrl) return;
|
|
@@ -214,6 +337,8 @@ function useShareSheet({
|
|
|
214
337
|
copied,
|
|
215
338
|
downloading,
|
|
216
339
|
safeUrl,
|
|
340
|
+
isMobile,
|
|
341
|
+
platformAvailability,
|
|
217
342
|
copyLink,
|
|
218
343
|
nativeShare,
|
|
219
344
|
downloadFile,
|
|
@@ -231,6 +356,37 @@ function useShareSheet({
|
|
|
231
356
|
shareReddit
|
|
232
357
|
};
|
|
233
358
|
}
|
|
359
|
+
function useOGData(url) {
|
|
360
|
+
const [ogData, setOgData] = (0, import_react.useState)(null);
|
|
361
|
+
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
362
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
363
|
+
(0, import_react.useEffect)(() => {
|
|
364
|
+
if (!url) {
|
|
365
|
+
setOgData(null);
|
|
366
|
+
setLoading(false);
|
|
367
|
+
setError(null);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
let cancelled = false;
|
|
371
|
+
setLoading(true);
|
|
372
|
+
setError(null);
|
|
373
|
+
fetchOGData(url).then((data) => {
|
|
374
|
+
if (!cancelled) {
|
|
375
|
+
setOgData(data);
|
|
376
|
+
setLoading(false);
|
|
377
|
+
}
|
|
378
|
+
}).catch((err) => {
|
|
379
|
+
if (!cancelled) {
|
|
380
|
+
setError(err instanceof Error ? err.message : "Failed to fetch OG data");
|
|
381
|
+
setLoading(false);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
return () => {
|
|
385
|
+
cancelled = true;
|
|
386
|
+
};
|
|
387
|
+
}, [url]);
|
|
388
|
+
return { ogData, loading, error };
|
|
389
|
+
}
|
|
234
390
|
|
|
235
391
|
// src/platforms.tsx
|
|
236
392
|
var import_lucide_react = require("lucide-react");
|
|
@@ -368,32 +524,6 @@ var CSS_VAR_DEFAULTS = CSS_VAR_UI_DEFAULTS;
|
|
|
368
524
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
369
525
|
var DEFAULT_BUTTON_SIZE = 45;
|
|
370
526
|
var DEFAULT_ICON_SIZE = 22;
|
|
371
|
-
var IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "ico", "avif"];
|
|
372
|
-
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov", "avi", "mkv", "m4v", "ogv"];
|
|
373
|
-
var AUDIO_EXTENSIONS = ["mp3", "wav", "ogg", "m4a", "aac", "flac", "wma"];
|
|
374
|
-
function detectPreviewType(url) {
|
|
375
|
-
try {
|
|
376
|
-
const pathname = new URL(url, "http://localhost").pathname;
|
|
377
|
-
const ext = pathname.split(".").pop()?.toLowerCase() || "";
|
|
378
|
-
if (IMAGE_EXTENSIONS.includes(ext)) return "image";
|
|
379
|
-
if (VIDEO_EXTENSIONS.includes(ext)) return "video";
|
|
380
|
-
if (AUDIO_EXTENSIONS.includes(ext)) return "audio";
|
|
381
|
-
if (url.includes("/api/og") || url.includes("og-image")) return "image";
|
|
382
|
-
if (url.includes("youtube.com") || url.includes("vimeo.com")) return "video";
|
|
383
|
-
return "link";
|
|
384
|
-
} catch {
|
|
385
|
-
return "link";
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
function getFilenameFromUrl(url) {
|
|
389
|
-
try {
|
|
390
|
-
const pathname = new URL(url, "http://localhost").pathname;
|
|
391
|
-
const filename = pathname.split("/").pop() || "";
|
|
392
|
-
return decodeURIComponent(filename);
|
|
393
|
-
} catch {
|
|
394
|
-
return url;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
527
|
var defaultClasses = {
|
|
398
528
|
root: "max-w-md mx-auto",
|
|
399
529
|
header: "text-center mb-2",
|
|
@@ -402,12 +532,8 @@ var defaultClasses = {
|
|
|
402
532
|
preview: "flex justify-center mb-4 px-4",
|
|
403
533
|
previewSkeleton: "rounded-xl overflow-hidden",
|
|
404
534
|
previewImage: "",
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
previewFileIcon: "",
|
|
408
|
-
previewFilename: "truncate",
|
|
409
|
-
previewLink: "",
|
|
410
|
-
grid: "px-2 py-6 flex flex-row items-center gap-4 gap-y-6 flex-wrap justify-center",
|
|
535
|
+
previewMeta: "",
|
|
536
|
+
grid: "px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center",
|
|
411
537
|
button: "flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group",
|
|
412
538
|
buttonIcon: "p-2 rounded-full transition-all flex items-center justify-center group-hover:scale-110 group-active:scale-95 mb-2",
|
|
413
539
|
buttonLabel: ""
|
|
@@ -421,28 +547,10 @@ var shimmerKeyframes = `
|
|
|
421
547
|
function cssVar(name, fallback) {
|
|
422
548
|
return `var(${name}, ${fallback})`;
|
|
423
549
|
}
|
|
424
|
-
function normalizePreview(preview) {
|
|
425
|
-
if (!preview) return null;
|
|
426
|
-
if (typeof preview === "string") {
|
|
427
|
-
const type2 = detectPreviewType(preview);
|
|
428
|
-
return {
|
|
429
|
-
url: preview,
|
|
430
|
-
type: type2,
|
|
431
|
-
filename: getFilenameFromUrl(preview)
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
const type = preview.type === "auto" || !preview.type ? detectPreviewType(preview.url) : preview.type;
|
|
435
|
-
return {
|
|
436
|
-
...preview,
|
|
437
|
-
type,
|
|
438
|
-
filename: preview.filename || getFilenameFromUrl(preview.url)
|
|
439
|
-
};
|
|
440
|
-
}
|
|
441
550
|
function ShareSheetContent({
|
|
442
551
|
title = "Share",
|
|
443
552
|
shareUrl,
|
|
444
553
|
shareText,
|
|
445
|
-
preview,
|
|
446
554
|
downloadUrl,
|
|
447
555
|
downloadFilename,
|
|
448
556
|
className,
|
|
@@ -457,15 +565,15 @@ function ShareSheetContent({
|
|
|
457
565
|
labels = {},
|
|
458
566
|
icons = {}
|
|
459
567
|
}) {
|
|
460
|
-
const [
|
|
461
|
-
const [
|
|
462
|
-
const
|
|
463
|
-
|
|
568
|
+
const [imageLoaded, setImageLoaded] = (0, import_react2.useState)(false);
|
|
569
|
+
const [imageError, setImageError] = (0, import_react2.useState)(false);
|
|
570
|
+
const { ogData, loading: ogLoading } = useOGData(shareUrl);
|
|
571
|
+
const handleImageLoad = (0, import_react2.useCallback)(() => {
|
|
572
|
+
setImageLoaded(true);
|
|
464
573
|
}, []);
|
|
465
|
-
const
|
|
466
|
-
|
|
574
|
+
const handleImageError = (0, import_react2.useCallback)(() => {
|
|
575
|
+
setImageError(true);
|
|
467
576
|
}, []);
|
|
468
|
-
const previewConfig = (0, import_react2.useMemo)(() => normalizePreview(preview), [preview]);
|
|
469
577
|
const shareSheet = useShareSheet({
|
|
470
578
|
shareUrl,
|
|
471
579
|
shareText,
|
|
@@ -501,6 +609,15 @@ function ShareSheetContent({
|
|
|
501
609
|
return PLATFORM_IDS.map((id) => {
|
|
502
610
|
const Icon = PLATFORM_ICONS[id];
|
|
503
611
|
const defaultLabel = dynamicLabels[id] ?? PLATFORM_LABELS[id];
|
|
612
|
+
const availability = shareSheet.platformAvailability[id];
|
|
613
|
+
let condition = true;
|
|
614
|
+
if (id === "native") {
|
|
615
|
+
condition = shareSheet.canNativeShare;
|
|
616
|
+
} else if (id === "download") {
|
|
617
|
+
condition = !!downloadUrl;
|
|
618
|
+
} else if (!availability.available) {
|
|
619
|
+
condition = false;
|
|
620
|
+
}
|
|
504
621
|
return {
|
|
505
622
|
id,
|
|
506
623
|
label: labels[id] ?? defaultLabel,
|
|
@@ -509,11 +626,10 @@ function ShareSheetContent({
|
|
|
509
626
|
bgColor: cssVar(PLATFORM_CSS_VARS[id], PLATFORM_COLORS[id].bg),
|
|
510
627
|
textColor: PLATFORM_COLORS[id].text,
|
|
511
628
|
onClick: shareActions[id],
|
|
512
|
-
|
|
513
|
-
condition: id === "native" ? shareSheet.canNativeShare : id === "download" ? !!downloadUrl : true
|
|
629
|
+
condition
|
|
514
630
|
};
|
|
515
631
|
});
|
|
516
|
-
}, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, downloadUrl]);
|
|
632
|
+
}, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);
|
|
517
633
|
const visibleButtons = (0, import_react2.useMemo)(() => {
|
|
518
634
|
return buttons.filter((btn) => {
|
|
519
635
|
if (btn.condition === false) return false;
|
|
@@ -522,49 +638,30 @@ function ShareSheetContent({
|
|
|
522
638
|
return true;
|
|
523
639
|
});
|
|
524
640
|
}, [buttons, show, hide]);
|
|
525
|
-
const
|
|
641
|
+
const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);
|
|
642
|
+
const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
|
|
643
|
+
const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
|
|
526
644
|
const renderPreview = () => {
|
|
527
|
-
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
|
|
532
|
-
const UrlLabel = ({ displayUrl = url }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
533
|
-
"div",
|
|
534
|
-
{
|
|
535
|
-
className: cn(defaultClasses.previewFilename, classNames.previewFilename),
|
|
536
|
-
style: {
|
|
537
|
-
color: textColor,
|
|
538
|
-
fontSize: "10px",
|
|
539
|
-
opacity: 0.5,
|
|
540
|
-
textAlign: "center",
|
|
541
|
-
marginTop: "6px"
|
|
542
|
-
},
|
|
543
|
-
children: displayUrl
|
|
544
|
-
}
|
|
545
|
-
);
|
|
546
|
-
const PlaceholderCard = ({
|
|
547
|
-
icon: IconComponent,
|
|
548
|
-
isLoading = false,
|
|
549
|
-
label,
|
|
550
|
-
displayUrl
|
|
551
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
552
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
645
|
+
const ogImage = ogData?.image;
|
|
646
|
+
const hasImage = ogImage && !imageError;
|
|
647
|
+
if (ogLoading) {
|
|
648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
553
649
|
"div",
|
|
554
650
|
{
|
|
555
651
|
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
556
652
|
style: {
|
|
557
653
|
position: "relative",
|
|
558
654
|
backgroundColor: bgColor,
|
|
559
|
-
width: "
|
|
560
|
-
|
|
655
|
+
width: "100%",
|
|
656
|
+
maxWidth: "320px",
|
|
657
|
+
aspectRatio: "1.91 / 1",
|
|
561
658
|
overflow: "hidden",
|
|
562
659
|
display: "flex",
|
|
563
660
|
alignItems: "center",
|
|
564
661
|
justifyContent: "center"
|
|
565
662
|
},
|
|
566
663
|
children: [
|
|
567
|
-
|
|
664
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
568
665
|
"div",
|
|
569
666
|
{
|
|
570
667
|
style: {
|
|
@@ -575,197 +672,125 @@ function ShareSheetContent({
|
|
|
575
672
|
}
|
|
576
673
|
}
|
|
577
674
|
) }),
|
|
578
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
579
|
-
"div",
|
|
580
|
-
{
|
|
581
|
-
style: {
|
|
582
|
-
display: "flex",
|
|
583
|
-
flexDirection: "column",
|
|
584
|
-
alignItems: "center",
|
|
585
|
-
justifyContent: "center",
|
|
586
|
-
gap: "8px"
|
|
587
|
-
},
|
|
588
|
-
children: [
|
|
589
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconComponent, { size: 32, style: { color: textColor, opacity: 0.4 } }),
|
|
590
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: textColor, fontSize: "11px", opacity: 0.4 }, children: label })
|
|
591
|
-
]
|
|
592
|
-
}
|
|
593
|
-
)
|
|
675
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
594
676
|
]
|
|
595
677
|
}
|
|
596
|
-
)
|
|
597
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, { displayUrl })
|
|
598
|
-
] });
|
|
599
|
-
if (mediaError && (type === "image" || type === "video")) {
|
|
600
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
|
|
678
|
+
) });
|
|
601
679
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
children: [
|
|
621
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
622
|
-
"div",
|
|
623
|
-
{
|
|
624
|
-
style: {
|
|
625
|
-
position: "absolute",
|
|
626
|
-
inset: 0,
|
|
627
|
-
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
628
|
-
animation: "sharesheet-shimmer 1.5s infinite"
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
) }),
|
|
632
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
633
|
-
]
|
|
634
|
-
}
|
|
635
|
-
),
|
|
636
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
|
|
637
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
638
|
-
"img",
|
|
639
|
-
{
|
|
640
|
-
src: url,
|
|
641
|
-
alt: alt || "Preview",
|
|
642
|
-
onLoad: handleMediaLoad,
|
|
643
|
-
onError: handleMediaError,
|
|
644
|
-
style: { display: "none" }
|
|
645
|
-
}
|
|
646
|
-
)
|
|
647
|
-
] });
|
|
648
|
-
}
|
|
649
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
650
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
651
|
-
"img",
|
|
680
|
+
if (!ogData || !hasImage) {
|
|
681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
682
|
+
"div",
|
|
683
|
+
{
|
|
684
|
+
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
685
|
+
style: {
|
|
686
|
+
position: "relative",
|
|
687
|
+
backgroundColor: bgColor,
|
|
688
|
+
width: "100%",
|
|
689
|
+
maxWidth: "320px",
|
|
690
|
+
aspectRatio: "1.91 / 1",
|
|
691
|
+
overflow: "hidden",
|
|
692
|
+
display: "flex",
|
|
693
|
+
alignItems: "center",
|
|
694
|
+
justifyContent: "center"
|
|
695
|
+
},
|
|
696
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
697
|
+
"div",
|
|
652
698
|
{
|
|
653
|
-
src: url,
|
|
654
|
-
alt: alt || "Preview",
|
|
655
|
-
className: cn(defaultClasses.previewImage, classNames.previewImage),
|
|
656
699
|
style: {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
if (!mediaLoaded) {
|
|
669
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
670
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
671
|
-
"div",
|
|
672
|
-
{
|
|
673
|
-
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
674
|
-
style: {
|
|
675
|
-
position: "relative",
|
|
676
|
-
backgroundColor: bgColor,
|
|
677
|
-
width: "200px",
|
|
678
|
-
height: "120px",
|
|
679
|
-
overflow: "hidden",
|
|
680
|
-
display: "flex",
|
|
681
|
-
alignItems: "center",
|
|
682
|
-
justifyContent: "center"
|
|
683
|
-
},
|
|
684
|
-
children: [
|
|
685
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
686
|
-
"div",
|
|
687
|
-
{
|
|
688
|
-
style: {
|
|
689
|
-
position: "absolute",
|
|
690
|
-
inset: 0,
|
|
691
|
-
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
692
|
-
animation: "sharesheet-shimmer 1.5s infinite"
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
) }),
|
|
696
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Film, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
697
|
-
]
|
|
698
|
-
}
|
|
699
|
-
),
|
|
700
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
|
|
701
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
702
|
-
"video",
|
|
703
|
-
{
|
|
704
|
-
src: url,
|
|
705
|
-
poster,
|
|
706
|
-
onLoadedData: handleMediaLoad,
|
|
707
|
-
onError: handleMediaError,
|
|
708
|
-
style: { display: "none" },
|
|
709
|
-
muted: true,
|
|
710
|
-
playsInline: true,
|
|
711
|
-
preload: "metadata"
|
|
712
|
-
}
|
|
713
|
-
)
|
|
714
|
-
] });
|
|
715
|
-
}
|
|
716
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
717
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", borderRadius: "12px", overflow: "hidden" }, children: [
|
|
718
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
719
|
-
"video",
|
|
720
|
-
{
|
|
721
|
-
src: url,
|
|
722
|
-
poster,
|
|
723
|
-
className: cn(defaultClasses.previewVideo, classNames.previewVideo),
|
|
724
|
-
style: {
|
|
725
|
-
maxWidth: "100%",
|
|
726
|
-
maxHeight: "180px",
|
|
727
|
-
display: "block"
|
|
728
|
-
},
|
|
729
|
-
muted: true,
|
|
730
|
-
playsInline: true,
|
|
731
|
-
preload: "metadata"
|
|
732
|
-
}
|
|
733
|
-
),
|
|
734
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
735
|
-
"div",
|
|
736
|
-
{
|
|
737
|
-
style: {
|
|
738
|
-
position: "absolute",
|
|
739
|
-
inset: 0,
|
|
740
|
-
display: "flex",
|
|
741
|
-
alignItems: "center",
|
|
742
|
-
justifyContent: "center",
|
|
743
|
-
pointerEvents: "none"
|
|
744
|
-
},
|
|
745
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
746
|
-
"div",
|
|
700
|
+
display: "flex",
|
|
701
|
+
flexDirection: "column",
|
|
702
|
+
alignItems: "center",
|
|
703
|
+
justifyContent: "center",
|
|
704
|
+
gap: "8px",
|
|
705
|
+
padding: "16px"
|
|
706
|
+
},
|
|
707
|
+
children: [
|
|
708
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } }),
|
|
709
|
+
ogData?.title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
710
|
+
"span",
|
|
747
711
|
{
|
|
748
712
|
style: {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
713
|
+
color: textColor,
|
|
714
|
+
fontSize: "12px",
|
|
715
|
+
opacity: 0.6,
|
|
716
|
+
textAlign: "center",
|
|
717
|
+
maxWidth: "280px",
|
|
718
|
+
overflow: "hidden",
|
|
719
|
+
textOverflow: "ellipsis",
|
|
720
|
+
display: "-webkit-box",
|
|
721
|
+
WebkitLineClamp: 2,
|
|
722
|
+
WebkitBoxOrient: "vertical"
|
|
752
723
|
},
|
|
753
|
-
children:
|
|
724
|
+
children: ogData.title
|
|
754
725
|
}
|
|
755
726
|
)
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
case "audio":
|
|
762
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Music, label: filename || "Audio", displayUrl: url });
|
|
763
|
-
case "file":
|
|
764
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.FileText, label: filename || "File", displayUrl: url });
|
|
765
|
-
case "link":
|
|
766
|
-
default:
|
|
767
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
|
|
727
|
+
]
|
|
728
|
+
}
|
|
729
|
+
)
|
|
730
|
+
}
|
|
731
|
+
) });
|
|
768
732
|
}
|
|
733
|
+
if (!imageLoaded) {
|
|
734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: [
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
736
|
+
"div",
|
|
737
|
+
{
|
|
738
|
+
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
739
|
+
style: {
|
|
740
|
+
position: "relative",
|
|
741
|
+
backgroundColor: bgColor,
|
|
742
|
+
width: "100%",
|
|
743
|
+
maxWidth: "320px",
|
|
744
|
+
aspectRatio: "1.91 / 1",
|
|
745
|
+
overflow: "hidden",
|
|
746
|
+
display: "flex",
|
|
747
|
+
alignItems: "center",
|
|
748
|
+
justifyContent: "center"
|
|
749
|
+
},
|
|
750
|
+
children: [
|
|
751
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
752
|
+
"div",
|
|
753
|
+
{
|
|
754
|
+
style: {
|
|
755
|
+
position: "absolute",
|
|
756
|
+
inset: 0,
|
|
757
|
+
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
758
|
+
animation: "sharesheet-shimmer 1.5s infinite"
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
) }),
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
763
|
+
]
|
|
764
|
+
}
|
|
765
|
+
),
|
|
766
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
767
|
+
"img",
|
|
768
|
+
{
|
|
769
|
+
src: ogImage,
|
|
770
|
+
alt: ogData.title || "Preview",
|
|
771
|
+
onLoad: handleImageLoad,
|
|
772
|
+
onError: handleImageError,
|
|
773
|
+
style: { display: "none" }
|
|
774
|
+
}
|
|
775
|
+
)
|
|
776
|
+
] });
|
|
777
|
+
}
|
|
778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
779
|
+
"img",
|
|
780
|
+
{
|
|
781
|
+
src: ogImage,
|
|
782
|
+
alt: ogData.title || "Preview",
|
|
783
|
+
className: cn(defaultClasses.previewImage, classNames.previewImage),
|
|
784
|
+
style: {
|
|
785
|
+
width: "100%",
|
|
786
|
+
maxWidth: "320px",
|
|
787
|
+
height: "auto",
|
|
788
|
+
borderRadius: "12px",
|
|
789
|
+
opacity: 1,
|
|
790
|
+
transition: "opacity 0.3s ease-in-out"
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
) });
|
|
769
794
|
};
|
|
770
795
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn(defaultClasses.root, classNames.root, className), children: [
|
|
771
796
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { dangerouslySetInnerHTML: { __html: shimmerKeyframes } }),
|
|
@@ -787,7 +812,7 @@ function ShareSheetContent({
|
|
|
787
812
|
}
|
|
788
813
|
)
|
|
789
814
|
] }),
|
|
790
|
-
|
|
815
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.preview, classNames.preview), children: renderPreview() }),
|
|
791
816
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.grid, classNames.grid), children: visibleButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
792
817
|
"button",
|
|
793
818
|
{
|
|
@@ -827,8 +852,8 @@ function ShareSheetContent({
|
|
|
827
852
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
828
853
|
var defaultDrawerClasses = {
|
|
829
854
|
overlay: "fixed inset-0 z-[70]",
|
|
830
|
-
drawer: "flex flex-col rounded-t-[14px] h-[
|
|
831
|
-
drawerInner: "p-4 rounded-t-[14px]
|
|
855
|
+
drawer: "flex flex-col rounded-t-[14px] max-h-[90%] fixed bottom-0 left-0 right-0 z-[80] border-t outline-none",
|
|
856
|
+
drawerInner: "p-4 pb-8 rounded-t-[14px] overflow-auto",
|
|
832
857
|
handle: "mx-auto w-12 h-1.5 shrink-0 rounded-full mb-6",
|
|
833
858
|
trigger: ""
|
|
834
859
|
};
|
|
@@ -839,7 +864,6 @@ function ShareSheetDrawer({
|
|
|
839
864
|
title = "Share",
|
|
840
865
|
shareUrl,
|
|
841
866
|
shareText,
|
|
842
|
-
preview,
|
|
843
867
|
downloadUrl,
|
|
844
868
|
downloadFilename,
|
|
845
869
|
disabled,
|
|
@@ -917,7 +941,6 @@ function ShareSheetDrawer({
|
|
|
917
941
|
title,
|
|
918
942
|
shareUrl,
|
|
919
943
|
shareText,
|
|
920
|
-
preview,
|
|
921
944
|
downloadUrl,
|
|
922
945
|
downloadFilename,
|
|
923
946
|
className,
|