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.
Files changed (45) hide show
  1. package/README.md +84 -102
  2. package/dist/content.d.mts +3 -3
  3. package/dist/content.d.ts +3 -3
  4. package/dist/content.js +296 -271
  5. package/dist/content.js.map +1 -1
  6. package/dist/content.mjs +298 -273
  7. package/dist/content.mjs.map +1 -1
  8. package/dist/drawer.d.mts +3 -3
  9. package/dist/drawer.d.ts +3 -3
  10. package/dist/drawer.js +298 -275
  11. package/dist/drawer.js.map +1 -1
  12. package/dist/drawer.mjs +300 -277
  13. package/dist/drawer.mjs.map +1 -1
  14. package/dist/headless-B7I228Dt.d.mts +98 -0
  15. package/dist/headless-BiSYHizs.d.ts +98 -0
  16. package/dist/headless.d.mts +3 -50
  17. package/dist/headless.d.ts +3 -50
  18. package/dist/headless.js +165 -0
  19. package/dist/headless.js.map +1 -1
  20. package/dist/headless.mjs +163 -1
  21. package/dist/headless.mjs.map +1 -1
  22. package/dist/index.d.mts +2 -2
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +339 -277
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +329 -278
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/{platforms-DU1DVDFq.d.mts → platforms-omqzPfYX.d.mts} +17 -23
  29. package/dist/{platforms-DU1DVDFq.d.ts → platforms-omqzPfYX.d.ts} +17 -23
  30. package/package.json +24 -7
  31. package/src/ShareSheetContent.tsx +157 -311
  32. package/src/ShareSheetDrawer.tsx +2 -4
  33. package/src/__tests__/hooks.test.ts +203 -0
  34. package/src/__tests__/og-fetcher.test.ts +144 -0
  35. package/src/__tests__/platforms.test.ts +148 -0
  36. package/src/__tests__/setup.ts +22 -0
  37. package/src/__tests__/share-functions.test.ts +152 -0
  38. package/src/__tests__/utils.test.ts +64 -0
  39. package/src/headless.ts +4 -1
  40. package/src/hooks.ts +60 -2
  41. package/src/index.ts +20 -4
  42. package/src/og-fetcher.ts +64 -0
  43. package/src/share-functions.ts +25 -1
  44. package/src/types.ts +17 -24
  45. package/src/utils.ts +125 -0
package/dist/index.js CHANGED
@@ -24,6 +24,8 @@ __export(src_exports, {
24
24
  CSS_VARS_UI: () => CSS_VARS_UI,
25
25
  CSS_VAR_DEFAULTS: () => CSS_VAR_DEFAULTS,
26
26
  CSS_VAR_UI_DEFAULTS: () => CSS_VAR_UI_DEFAULTS,
27
+ MOBILE_ONLY_PLATFORMS: () => MOBILE_ONLY_PLATFORMS,
28
+ MOBILE_PREFERRED_PLATFORMS: () => MOBILE_PREFERRED_PLATFORMS,
27
29
  PLATFORMS: () => PLATFORMS,
28
30
  PLATFORM_COLORS: () => PLATFORM_COLORS,
29
31
  PLATFORM_CSS_VARS: () => PLATFORM_CSS_VARS,
@@ -34,14 +36,21 @@ __export(src_exports, {
34
36
  ShareMenuDrawer: () => ShareMenuDrawer,
35
37
  ShareSheetContent: () => ShareSheetContent,
36
38
  ShareSheetDrawer: () => ShareSheetDrawer,
39
+ checkPlatformAvailability: () => checkPlatformAvailability,
40
+ clearOGCache: () => clearOGCache,
37
41
  cn: () => cn,
42
+ fetchOGData: () => fetchOGData,
38
43
  generateCssVarDefaults: () => generateCssVarDefaults,
44
+ getAllPlatformAvailability: () => getAllPlatformAvailability,
39
45
  getAllPlatforms: () => getAllPlatforms,
40
46
  getPlatform: () => getPlatform,
41
47
  getPlatformColor: () => getPlatformColor,
42
48
  getPlatformIcon: () => getPlatformIcon,
43
49
  getPlatformLabel: () => getPlatformLabel,
44
50
  getSafeUrl: () => getSafeUrl,
51
+ isAndroidDevice: () => isAndroidDevice,
52
+ isIOSDevice: () => isIOSDevice,
53
+ isMobileDevice: () => isMobileDevice,
45
54
  openInstagram: () => openInstagram,
46
55
  openThreads: () => openThreads,
47
56
  openTikTok: () => openTikTok,
@@ -55,8 +64,10 @@ __export(src_exports, {
55
64
  shareToX: () => shareToX,
56
65
  shareViaEmail: () => shareViaEmail,
57
66
  shareViaSMS: () => shareViaSMS,
67
+ useOGData: () => useOGData,
58
68
  useShareMenu: () => useShareMenu,
59
- useShareSheet: () => useShareSheet
69
+ useShareSheet: () => useShareSheet,
70
+ warnUnavailablePlatform: () => warnUnavailablePlatform
60
71
  });
61
72
  module.exports = __toCommonJS(src_exports);
62
73
 
@@ -76,10 +87,128 @@ function openUrl(url) {
76
87
  function getSafeUrl(shareUrl) {
77
88
  return shareUrl || (typeof window !== "undefined" ? window.location.href : "");
78
89
  }
90
+ function isMobileDevice() {
91
+ if (typeof navigator === "undefined") return false;
92
+ const userAgent = navigator.userAgent || navigator.vendor || "";
93
+ const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
94
+ const hasTouch = typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0);
95
+ return mobileRegex.test(userAgent);
96
+ }
97
+ function isIOSDevice() {
98
+ if (typeof navigator === "undefined") return false;
99
+ const userAgent = navigator.userAgent || "";
100
+ return /iPhone|iPad|iPod/i.test(userAgent);
101
+ }
102
+ function isAndroidDevice() {
103
+ if (typeof navigator === "undefined") return false;
104
+ const userAgent = navigator.userAgent || "";
105
+ return /Android/i.test(userAgent);
106
+ }
107
+ var MOBILE_ONLY_PLATFORMS = [
108
+ "instagram",
109
+ "tiktok",
110
+ "threads",
111
+ "sms"
112
+ ];
113
+ var MOBILE_PREFERRED_PLATFORMS = [
114
+ "snapchat",
115
+ "whatsapp"
116
+ ];
117
+ function checkPlatformAvailability(platform) {
118
+ const isMobile = isMobileDevice();
119
+ if (MOBILE_ONLY_PLATFORMS.includes(platform)) {
120
+ if (!isMobile) {
121
+ return {
122
+ available: false,
123
+ reason: `${platform} requires a mobile device with the app installed`
124
+ };
125
+ }
126
+ }
127
+ if (platform === "sms" && !isMobile) {
128
+ return {
129
+ available: false,
130
+ reason: "SMS sharing requires a mobile device"
131
+ };
132
+ }
133
+ if (platform === "native") {
134
+ const canShare = typeof navigator !== "undefined" && "share" in navigator;
135
+ if (!canShare) {
136
+ return {
137
+ available: false,
138
+ reason: "Native share is not supported by this browser"
139
+ };
140
+ }
141
+ }
142
+ return { available: true };
143
+ }
144
+ function getAllPlatformAvailability() {
145
+ const platforms = [
146
+ "native",
147
+ "copy",
148
+ "download",
149
+ "whatsapp",
150
+ "telegram",
151
+ "instagram",
152
+ "facebook",
153
+ "snapchat",
154
+ "sms",
155
+ "email",
156
+ "linkedin",
157
+ "reddit",
158
+ "x",
159
+ "tiktok",
160
+ "threads"
161
+ ];
162
+ const result = {};
163
+ for (const platform of platforms) {
164
+ result[platform] = checkPlatformAvailability(platform);
165
+ }
166
+ return result;
167
+ }
168
+ function warnUnavailablePlatform(platform, reason) {
169
+ console.warn(
170
+ `[react-sharesheet] ${platform} sharing is not available: ${reason}. This share option may not work correctly on this device.`
171
+ );
172
+ }
79
173
 
80
174
  // src/hooks.ts
81
175
  var import_react = require("react");
82
176
 
177
+ // src/og-fetcher.ts
178
+ var ogCache = /* @__PURE__ */ new Map();
179
+ async function fetchOGData(url) {
180
+ if (ogCache.has(url)) {
181
+ return ogCache.get(url);
182
+ }
183
+ try {
184
+ const apiUrl = `https://api.microlink.io?url=${encodeURIComponent(url)}`;
185
+ const response = await fetch(apiUrl);
186
+ if (!response.ok) {
187
+ throw new Error(`Failed to fetch OG data: ${response.status}`);
188
+ }
189
+ const json = await response.json();
190
+ if (json.status !== "success" || !json.data) {
191
+ return null;
192
+ }
193
+ const { title, description, image, url: canonicalUrl, publisher } = json.data;
194
+ const ogData = {
195
+ title: title || void 0,
196
+ description: description || void 0,
197
+ image: image?.url || void 0,
198
+ url: canonicalUrl || url,
199
+ siteName: publisher || void 0
200
+ };
201
+ ogCache.set(url, ogData);
202
+ return ogData;
203
+ } catch (error) {
204
+ console.warn("[react-sharesheet] Failed to fetch OG data:", error);
205
+ return null;
206
+ }
207
+ }
208
+ function clearOGCache() {
209
+ ogCache.clear();
210
+ }
211
+
83
212
  // src/share-functions.ts
84
213
  function shareToWhatsApp(url, text) {
85
214
  const encoded = encodeURIComponent(`${text}
@@ -101,12 +230,24 @@ function shareToFacebook(url) {
101
230
  openUrl(`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`);
102
231
  }
103
232
  function openInstagram() {
233
+ const availability = checkPlatformAvailability("instagram");
234
+ if (!availability.available) {
235
+ warnUnavailablePlatform("instagram", availability.reason);
236
+ }
104
237
  window.location.href = "instagram://";
105
238
  }
106
239
  function openTikTok() {
240
+ const availability = checkPlatformAvailability("tiktok");
241
+ if (!availability.available) {
242
+ warnUnavailablePlatform("tiktok", availability.reason);
243
+ }
107
244
  window.location.href = "tiktok://";
108
245
  }
109
246
  function openThreads() {
247
+ const availability = checkPlatformAvailability("threads");
248
+ if (!availability.available) {
249
+ warnUnavailablePlatform("threads", availability.reason);
250
+ }
110
251
  window.location.href = "threads://";
111
252
  }
112
253
  function shareToSnapchat(url) {
@@ -114,6 +255,10 @@ function shareToSnapchat(url) {
114
255
  openUrl(`https://www.snapchat.com/scan?attachmentUrl=${encodedUrl}`);
115
256
  }
116
257
  function shareViaSMS(url, text) {
258
+ const availability = checkPlatformAvailability("sms");
259
+ if (!availability.available) {
260
+ warnUnavailablePlatform("sms", availability.reason);
261
+ }
117
262
  const body = encodeURIComponent(`${text}
118
263
  ${url}`);
119
264
  window.location.href = `sms:?body=${body}`;
@@ -151,6 +296,12 @@ function useShareSheet({
151
296
  const canNativeShare = (0, import_react.useMemo)(() => {
152
297
  return typeof navigator !== "undefined" && "share" in navigator;
153
298
  }, []);
299
+ const isMobile = (0, import_react.useMemo)(() => {
300
+ return isMobileDevice();
301
+ }, []);
302
+ const platformAvailability = (0, import_react.useMemo)(() => {
303
+ return getAllPlatformAvailability();
304
+ }, []);
154
305
  const safeUrl = getSafeUrl(shareUrl);
155
306
  const copyLink = (0, import_react.useCallback)(async () => {
156
307
  if (!safeUrl) return;
@@ -239,6 +390,8 @@ function useShareSheet({
239
390
  copied,
240
391
  downloading,
241
392
  safeUrl,
393
+ isMobile,
394
+ platformAvailability,
242
395
  copyLink,
243
396
  nativeShare,
244
397
  downloadFile,
@@ -256,6 +409,37 @@ function useShareSheet({
256
409
  shareReddit
257
410
  };
258
411
  }
412
+ function useOGData(url) {
413
+ const [ogData, setOgData] = (0, import_react.useState)(null);
414
+ const [loading, setLoading] = (0, import_react.useState)(false);
415
+ const [error, setError] = (0, import_react.useState)(null);
416
+ (0, import_react.useEffect)(() => {
417
+ if (!url) {
418
+ setOgData(null);
419
+ setLoading(false);
420
+ setError(null);
421
+ return;
422
+ }
423
+ let cancelled = false;
424
+ setLoading(true);
425
+ setError(null);
426
+ fetchOGData(url).then((data) => {
427
+ if (!cancelled) {
428
+ setOgData(data);
429
+ setLoading(false);
430
+ }
431
+ }).catch((err) => {
432
+ if (!cancelled) {
433
+ setError(err instanceof Error ? err.message : "Failed to fetch OG data");
434
+ setLoading(false);
435
+ }
436
+ });
437
+ return () => {
438
+ cancelled = true;
439
+ };
440
+ }, [url]);
441
+ return { ogData, loading, error };
442
+ }
259
443
  var useShareMenu = useShareSheet;
260
444
 
261
445
  // src/platforms.tsx
@@ -416,32 +600,6 @@ var CSS_VAR_DEFAULTS = CSS_VAR_UI_DEFAULTS;
416
600
  var import_jsx_runtime2 = require("react/jsx-runtime");
417
601
  var DEFAULT_BUTTON_SIZE = 45;
418
602
  var DEFAULT_ICON_SIZE = 22;
419
- var IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "ico", "avif"];
420
- var VIDEO_EXTENSIONS = ["mp4", "webm", "mov", "avi", "mkv", "m4v", "ogv"];
421
- var AUDIO_EXTENSIONS = ["mp3", "wav", "ogg", "m4a", "aac", "flac", "wma"];
422
- function detectPreviewType(url) {
423
- try {
424
- const pathname = new URL(url, "http://localhost").pathname;
425
- const ext = pathname.split(".").pop()?.toLowerCase() || "";
426
- if (IMAGE_EXTENSIONS.includes(ext)) return "image";
427
- if (VIDEO_EXTENSIONS.includes(ext)) return "video";
428
- if (AUDIO_EXTENSIONS.includes(ext)) return "audio";
429
- if (url.includes("/api/og") || url.includes("og-image")) return "image";
430
- if (url.includes("youtube.com") || url.includes("vimeo.com")) return "video";
431
- return "link";
432
- } catch {
433
- return "link";
434
- }
435
- }
436
- function getFilenameFromUrl(url) {
437
- try {
438
- const pathname = new URL(url, "http://localhost").pathname;
439
- const filename = pathname.split("/").pop() || "";
440
- return decodeURIComponent(filename);
441
- } catch {
442
- return url;
443
- }
444
- }
445
603
  var defaultClasses = {
446
604
  root: "max-w-md mx-auto",
447
605
  header: "text-center mb-2",
@@ -450,12 +608,8 @@ var defaultClasses = {
450
608
  preview: "flex justify-center mb-4 px-4",
451
609
  previewSkeleton: "rounded-xl overflow-hidden",
452
610
  previewImage: "",
453
- previewVideo: "",
454
- previewFile: "",
455
- previewFileIcon: "",
456
- previewFilename: "truncate",
457
- previewLink: "",
458
- grid: "px-2 py-6 flex flex-row items-center gap-4 gap-y-6 flex-wrap justify-center",
611
+ previewMeta: "",
612
+ grid: "px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center",
459
613
  button: "flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group",
460
614
  buttonIcon: "p-2 rounded-full transition-all flex items-center justify-center group-hover:scale-110 group-active:scale-95 mb-2",
461
615
  buttonLabel: ""
@@ -469,28 +623,10 @@ var shimmerKeyframes = `
469
623
  function cssVar(name, fallback) {
470
624
  return `var(${name}, ${fallback})`;
471
625
  }
472
- function normalizePreview(preview) {
473
- if (!preview) return null;
474
- if (typeof preview === "string") {
475
- const type2 = detectPreviewType(preview);
476
- return {
477
- url: preview,
478
- type: type2,
479
- filename: getFilenameFromUrl(preview)
480
- };
481
- }
482
- const type = preview.type === "auto" || !preview.type ? detectPreviewType(preview.url) : preview.type;
483
- return {
484
- ...preview,
485
- type,
486
- filename: preview.filename || getFilenameFromUrl(preview.url)
487
- };
488
- }
489
626
  function ShareSheetContent({
490
627
  title = "Share",
491
628
  shareUrl,
492
629
  shareText,
493
- preview,
494
630
  downloadUrl,
495
631
  downloadFilename,
496
632
  className,
@@ -505,15 +641,15 @@ function ShareSheetContent({
505
641
  labels = {},
506
642
  icons = {}
507
643
  }) {
508
- const [mediaLoaded, setMediaLoaded] = (0, import_react2.useState)(false);
509
- const [mediaError, setMediaError] = (0, import_react2.useState)(false);
510
- const handleMediaLoad = (0, import_react2.useCallback)(() => {
511
- setMediaLoaded(true);
644
+ const [imageLoaded, setImageLoaded] = (0, import_react2.useState)(false);
645
+ const [imageError, setImageError] = (0, import_react2.useState)(false);
646
+ const { ogData, loading: ogLoading } = useOGData(shareUrl);
647
+ const handleImageLoad = (0, import_react2.useCallback)(() => {
648
+ setImageLoaded(true);
512
649
  }, []);
513
- const handleMediaError = (0, import_react2.useCallback)(() => {
514
- setMediaError(true);
650
+ const handleImageError = (0, import_react2.useCallback)(() => {
651
+ setImageError(true);
515
652
  }, []);
516
- const previewConfig = (0, import_react2.useMemo)(() => normalizePreview(preview), [preview]);
517
653
  const shareSheet = useShareSheet({
518
654
  shareUrl,
519
655
  shareText,
@@ -549,6 +685,15 @@ function ShareSheetContent({
549
685
  return PLATFORM_IDS.map((id) => {
550
686
  const Icon = PLATFORM_ICONS[id];
551
687
  const defaultLabel = dynamicLabels[id] ?? PLATFORM_LABELS[id];
688
+ const availability = shareSheet.platformAvailability[id];
689
+ let condition = true;
690
+ if (id === "native") {
691
+ condition = shareSheet.canNativeShare;
692
+ } else if (id === "download") {
693
+ condition = !!downloadUrl;
694
+ } else if (!availability.available) {
695
+ condition = false;
696
+ }
552
697
  return {
553
698
  id,
554
699
  label: labels[id] ?? defaultLabel,
@@ -557,11 +702,10 @@ function ShareSheetContent({
557
702
  bgColor: cssVar(PLATFORM_CSS_VARS[id], PLATFORM_COLORS[id].bg),
558
703
  textColor: PLATFORM_COLORS[id].text,
559
704
  onClick: shareActions[id],
560
- // Conditions for showing certain buttons
561
- condition: id === "native" ? shareSheet.canNativeShare : id === "download" ? !!downloadUrl : true
705
+ condition
562
706
  };
563
707
  });
564
- }, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, downloadUrl]);
708
+ }, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);
565
709
  const visibleButtons = (0, import_react2.useMemo)(() => {
566
710
  return buttons.filter((btn) => {
567
711
  if (btn.condition === false) return false;
@@ -570,49 +714,30 @@ function ShareSheetContent({
570
714
  return true;
571
715
  });
572
716
  }, [buttons, show, hide]);
573
- const showPreview = !!previewConfig;
717
+ const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);
718
+ const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
719
+ const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
574
720
  const renderPreview = () => {
575
- if (!previewConfig) return null;
576
- const { type, url, filename, alt, poster } = previewConfig;
577
- const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);
578
- const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
579
- const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
580
- const UrlLabel = ({ displayUrl = url }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
581
- "div",
582
- {
583
- className: cn(defaultClasses.previewFilename, classNames.previewFilename),
584
- style: {
585
- color: textColor,
586
- fontSize: "10px",
587
- opacity: 0.5,
588
- textAlign: "center",
589
- marginTop: "6px"
590
- },
591
- children: displayUrl
592
- }
593
- );
594
- const PlaceholderCard = ({
595
- icon: IconComponent,
596
- isLoading = false,
597
- label,
598
- displayUrl
599
- }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
600
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
721
+ const ogImage = ogData?.image;
722
+ const hasImage = ogImage && !imageError;
723
+ if (ogLoading) {
724
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
601
725
  "div",
602
726
  {
603
727
  className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
604
728
  style: {
605
729
  position: "relative",
606
730
  backgroundColor: bgColor,
607
- width: "200px",
608
- height: "120px",
731
+ width: "100%",
732
+ maxWidth: "320px",
733
+ aspectRatio: "1.91 / 1",
609
734
  overflow: "hidden",
610
735
  display: "flex",
611
736
  alignItems: "center",
612
737
  justifyContent: "center"
613
738
  },
614
739
  children: [
615
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
740
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
616
741
  "div",
617
742
  {
618
743
  style: {
@@ -623,197 +748,125 @@ function ShareSheetContent({
623
748
  }
624
749
  }
625
750
  ) }),
626
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
627
- "div",
628
- {
629
- style: {
630
- display: "flex",
631
- flexDirection: "column",
632
- alignItems: "center",
633
- justifyContent: "center",
634
- gap: "8px"
635
- },
636
- children: [
637
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconComponent, { size: 32, style: { color: textColor, opacity: 0.4 } }),
638
- label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: textColor, fontSize: "11px", opacity: 0.4 }, children: label })
639
- ]
640
- }
641
- )
751
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } })
642
752
  ]
643
753
  }
644
- ),
645
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, { displayUrl })
646
- ] });
647
- if (mediaError && (type === "image" || type === "video")) {
648
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
754
+ ) });
649
755
  }
650
- switch (type) {
651
- case "image":
652
- if (!mediaLoaded) {
653
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
654
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
655
- "div",
656
- {
657
- className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
658
- style: {
659
- position: "relative",
660
- backgroundColor: bgColor,
661
- width: "200px",
662
- height: "120px",
663
- overflow: "hidden",
664
- display: "flex",
665
- alignItems: "center",
666
- justifyContent: "center"
667
- },
668
- children: [
669
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
670
- "div",
671
- {
672
- style: {
673
- position: "absolute",
674
- inset: 0,
675
- background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
676
- animation: "sharesheet-shimmer 1.5s infinite"
677
- }
678
- }
679
- ) }),
680
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
681
- ]
682
- }
683
- ),
684
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
685
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
686
- "img",
687
- {
688
- src: url,
689
- alt: alt || "Preview",
690
- onLoad: handleMediaLoad,
691
- onError: handleMediaError,
692
- style: { display: "none" }
693
- }
694
- )
695
- ] });
696
- }
697
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
698
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
699
- "img",
756
+ if (!ogData || !hasImage) {
757
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
758
+ "div",
759
+ {
760
+ className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
761
+ style: {
762
+ position: "relative",
763
+ backgroundColor: bgColor,
764
+ width: "100%",
765
+ maxWidth: "320px",
766
+ aspectRatio: "1.91 / 1",
767
+ overflow: "hidden",
768
+ display: "flex",
769
+ alignItems: "center",
770
+ justifyContent: "center"
771
+ },
772
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
773
+ "div",
700
774
  {
701
- src: url,
702
- alt: alt || "Preview",
703
- className: cn(defaultClasses.previewImage, classNames.previewImage),
704
775
  style: {
705
- maxWidth: "100%",
706
- maxHeight: "180px",
707
- borderRadius: "12px",
708
- opacity: 1,
709
- transition: "opacity 0.3s ease-in-out"
710
- }
711
- }
712
- ),
713
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {})
714
- ] });
715
- case "video":
716
- if (!mediaLoaded) {
717
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
718
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
719
- "div",
720
- {
721
- className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
722
- style: {
723
- position: "relative",
724
- backgroundColor: bgColor,
725
- width: "200px",
726
- height: "120px",
727
- overflow: "hidden",
728
- display: "flex",
729
- alignItems: "center",
730
- justifyContent: "center"
731
- },
732
- children: [
733
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
734
- "div",
735
- {
736
- style: {
737
- position: "absolute",
738
- inset: 0,
739
- background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
740
- animation: "sharesheet-shimmer 1.5s infinite"
741
- }
742
- }
743
- ) }),
744
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Film, { size: 32, style: { color: textColor, opacity: 0.4 } })
745
- ]
746
- }
747
- ),
748
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
749
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
750
- "video",
751
- {
752
- src: url,
753
- poster,
754
- onLoadedData: handleMediaLoad,
755
- onError: handleMediaError,
756
- style: { display: "none" },
757
- muted: true,
758
- playsInline: true,
759
- preload: "metadata"
760
- }
761
- )
762
- ] });
763
- }
764
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
765
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", borderRadius: "12px", overflow: "hidden" }, children: [
766
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
767
- "video",
768
- {
769
- src: url,
770
- poster,
771
- className: cn(defaultClasses.previewVideo, classNames.previewVideo),
772
- style: {
773
- maxWidth: "100%",
774
- maxHeight: "180px",
775
- display: "block"
776
- },
777
- muted: true,
778
- playsInline: true,
779
- preload: "metadata"
780
- }
781
- ),
782
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
783
- "div",
784
- {
785
- style: {
786
- position: "absolute",
787
- inset: 0,
788
- display: "flex",
789
- alignItems: "center",
790
- justifyContent: "center",
791
- pointerEvents: "none"
792
- },
793
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
794
- "div",
776
+ display: "flex",
777
+ flexDirection: "column",
778
+ alignItems: "center",
779
+ justifyContent: "center",
780
+ gap: "8px",
781
+ padding: "16px"
782
+ },
783
+ children: [
784
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } }),
785
+ ogData?.title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
786
+ "span",
795
787
  {
796
788
  style: {
797
- backgroundColor: "rgba(0, 0, 0, 0.5)",
798
- borderRadius: "50%",
799
- padding: "10px"
789
+ color: textColor,
790
+ fontSize: "12px",
791
+ opacity: 0.6,
792
+ textAlign: "center",
793
+ maxWidth: "280px",
794
+ overflow: "hidden",
795
+ textOverflow: "ellipsis",
796
+ display: "-webkit-box",
797
+ WebkitLineClamp: 2,
798
+ WebkitBoxOrient: "vertical"
800
799
  },
801
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Play, { size: 20, fill: "white", color: "white" })
800
+ children: ogData.title
802
801
  }
803
802
  )
804
- }
805
- )
806
- ] }),
807
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {})
808
- ] });
809
- case "audio":
810
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Music, label: filename || "Audio", displayUrl: url });
811
- case "file":
812
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.FileText, label: filename || "File", displayUrl: url });
813
- case "link":
814
- default:
815
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
803
+ ]
804
+ }
805
+ )
806
+ }
807
+ ) });
808
+ }
809
+ if (!imageLoaded) {
810
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: [
811
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
812
+ "div",
813
+ {
814
+ className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
815
+ style: {
816
+ position: "relative",
817
+ backgroundColor: bgColor,
818
+ width: "100%",
819
+ maxWidth: "320px",
820
+ aspectRatio: "1.91 / 1",
821
+ overflow: "hidden",
822
+ display: "flex",
823
+ alignItems: "center",
824
+ justifyContent: "center"
825
+ },
826
+ children: [
827
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
828
+ "div",
829
+ {
830
+ style: {
831
+ position: "absolute",
832
+ inset: 0,
833
+ background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
834
+ animation: "sharesheet-shimmer 1.5s infinite"
835
+ }
836
+ }
837
+ ) }),
838
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
839
+ ]
840
+ }
841
+ ),
842
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
843
+ "img",
844
+ {
845
+ src: ogImage,
846
+ alt: ogData.title || "Preview",
847
+ onLoad: handleImageLoad,
848
+ onError: handleImageError,
849
+ style: { display: "none" }
850
+ }
851
+ )
852
+ ] });
816
853
  }
854
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
855
+ "img",
856
+ {
857
+ src: ogImage,
858
+ alt: ogData.title || "Preview",
859
+ className: cn(defaultClasses.previewImage, classNames.previewImage),
860
+ style: {
861
+ width: "100%",
862
+ maxWidth: "320px",
863
+ height: "auto",
864
+ borderRadius: "12px",
865
+ opacity: 1,
866
+ transition: "opacity 0.3s ease-in-out"
867
+ }
868
+ }
869
+ ) });
817
870
  };
818
871
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn(defaultClasses.root, classNames.root, className), children: [
819
872
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { dangerouslySetInnerHTML: { __html: shimmerKeyframes } }),
@@ -835,7 +888,7 @@ function ShareSheetContent({
835
888
  }
836
889
  )
837
890
  ] }),
838
- showPreview && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.preview, classNames.preview), children: renderPreview() }),
891
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.preview, classNames.preview), children: renderPreview() }),
839
892
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.grid, classNames.grid), children: visibleButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
840
893
  "button",
841
894
  {
@@ -878,8 +931,8 @@ var import_vaul = require("vaul");
878
931
  var import_jsx_runtime3 = require("react/jsx-runtime");
879
932
  var defaultDrawerClasses = {
880
933
  overlay: "fixed inset-0 z-[70]",
881
- drawer: "flex flex-col rounded-t-[14px] h-[70%] mt-24 fixed bottom-0 left-0 right-0 z-[80] border-t outline-none",
882
- drawerInner: "p-4 rounded-t-[14px] flex-1 overflow-auto",
934
+ drawer: "flex flex-col rounded-t-[14px] max-h-[90%] fixed bottom-0 left-0 right-0 z-[80] border-t outline-none",
935
+ drawerInner: "p-4 pb-8 rounded-t-[14px] overflow-auto",
883
936
  handle: "mx-auto w-12 h-1.5 shrink-0 rounded-full mb-6",
884
937
  trigger: ""
885
938
  };
@@ -890,7 +943,6 @@ function ShareSheetDrawer({
890
943
  title = "Share",
891
944
  shareUrl,
892
945
  shareText,
893
- preview,
894
946
  downloadUrl,
895
947
  downloadFilename,
896
948
  disabled,
@@ -968,7 +1020,6 @@ function ShareSheetDrawer({
968
1020
  title,
969
1021
  shareUrl,
970
1022
  shareText,
971
- preview,
972
1023
  downloadUrl,
973
1024
  downloadFilename,
974
1025
  className,
@@ -1003,6 +1054,8 @@ var ShareMenuDrawer = ShareSheetDrawer;
1003
1054
  CSS_VARS_UI,
1004
1055
  CSS_VAR_DEFAULTS,
1005
1056
  CSS_VAR_UI_DEFAULTS,
1057
+ MOBILE_ONLY_PLATFORMS,
1058
+ MOBILE_PREFERRED_PLATFORMS,
1006
1059
  PLATFORMS,
1007
1060
  PLATFORM_COLORS,
1008
1061
  PLATFORM_CSS_VARS,
@@ -1013,14 +1066,21 @@ var ShareMenuDrawer = ShareSheetDrawer;
1013
1066
  ShareMenuDrawer,
1014
1067
  ShareSheetContent,
1015
1068
  ShareSheetDrawer,
1069
+ checkPlatformAvailability,
1070
+ clearOGCache,
1016
1071
  cn,
1072
+ fetchOGData,
1017
1073
  generateCssVarDefaults,
1074
+ getAllPlatformAvailability,
1018
1075
  getAllPlatforms,
1019
1076
  getPlatform,
1020
1077
  getPlatformColor,
1021
1078
  getPlatformIcon,
1022
1079
  getPlatformLabel,
1023
1080
  getSafeUrl,
1081
+ isAndroidDevice,
1082
+ isIOSDevice,
1083
+ isMobileDevice,
1024
1084
  openInstagram,
1025
1085
  openThreads,
1026
1086
  openTikTok,
@@ -1034,7 +1094,9 @@ var ShareMenuDrawer = ShareSheetDrawer;
1034
1094
  shareToX,
1035
1095
  shareViaEmail,
1036
1096
  shareViaSMS,
1097
+ useOGData,
1037
1098
  useShareMenu,
1038
- useShareSheet
1099
+ useShareSheet,
1100
+ warnUnavailablePlatform
1039
1101
  });
1040
1102
  //# sourceMappingURL=index.js.map