react-sharesheet 1.0.0 → 1.1.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 (41) hide show
  1. package/README.md +40 -53
  2. package/dist/content.d.mts +3 -3
  3. package/dist/content.d.ts +3 -3
  4. package/dist/content.js +192 -268
  5. package/dist/content.js.map +1 -1
  6. package/dist/content.mjs +194 -270
  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 +194 -272
  11. package/dist/drawer.js.map +1 -1
  12. package/dist/drawer.mjs +196 -274
  13. package/dist/drawer.mjs.map +1 -1
  14. package/dist/headless.d.mts +22 -3
  15. package/dist/headless.d.ts +22 -3
  16. package/dist/headless.js +72 -0
  17. package/dist/headless.js.map +1 -1
  18. package/dist/headless.mjs +70 -1
  19. package/dist/headless.mjs.map +1 -1
  20. package/dist/index.d.mts +2 -2
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +203 -272
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +202 -274
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/{platforms-DU1DVDFq.d.mts → platforms-CDJmSY8E.d.mts} +2 -19
  27. package/dist/{platforms-DU1DVDFq.d.ts → platforms-CDJmSY8E.d.ts} +2 -19
  28. package/package.json +12 -3
  29. package/src/ShareSheetContent.tsx +143 -306
  30. package/src/ShareSheetDrawer.tsx +2 -4
  31. package/src/__tests__/hooks.test.ts +213 -0
  32. package/src/__tests__/og-fetcher.test.ts +144 -0
  33. package/src/__tests__/platforms.test.ts +148 -0
  34. package/src/__tests__/setup.ts +22 -0
  35. package/src/__tests__/share-functions.test.ts +155 -0
  36. package/src/__tests__/utils.test.ts +64 -0
  37. package/src/headless.ts +4 -1
  38. package/src/hooks.ts +49 -1
  39. package/src/index.ts +4 -3
  40. package/src/og-fetcher.ts +64 -0
  41. package/src/types.ts +1 -20
package/dist/content.js CHANGED
@@ -51,6 +51,38 @@ function getSafeUrl(shareUrl) {
51
51
  // src/hooks.ts
52
52
  var import_react = require("react");
53
53
 
54
+ // src/og-fetcher.ts
55
+ var ogCache = /* @__PURE__ */ new Map();
56
+ async function fetchOGData(url) {
57
+ if (ogCache.has(url)) {
58
+ return ogCache.get(url);
59
+ }
60
+ try {
61
+ const apiUrl = `https://api.microlink.io?url=${encodeURIComponent(url)}`;
62
+ const response = await fetch(apiUrl);
63
+ if (!response.ok) {
64
+ throw new Error(`Failed to fetch OG data: ${response.status}`);
65
+ }
66
+ const json = await response.json();
67
+ if (json.status !== "success" || !json.data) {
68
+ return null;
69
+ }
70
+ const { title, description, image, url: canonicalUrl, publisher } = json.data;
71
+ const ogData = {
72
+ title: title || void 0,
73
+ description: description || void 0,
74
+ image: image?.url || void 0,
75
+ url: canonicalUrl || url,
76
+ siteName: publisher || void 0
77
+ };
78
+ ogCache.set(url, ogData);
79
+ return ogData;
80
+ } catch (error) {
81
+ console.warn("[react-sharesheet] Failed to fetch OG data:", error);
82
+ return null;
83
+ }
84
+ }
85
+
54
86
  // src/share-functions.ts
55
87
  function shareToWhatsApp(url, text) {
56
88
  const encoded = encodeURIComponent(`${text}
@@ -227,6 +259,37 @@ function useShareSheet({
227
259
  shareReddit
228
260
  };
229
261
  }
262
+ function useOGData(url) {
263
+ const [ogData, setOgData] = (0, import_react.useState)(null);
264
+ const [loading, setLoading] = (0, import_react.useState)(false);
265
+ const [error, setError] = (0, import_react.useState)(null);
266
+ (0, import_react.useEffect)(() => {
267
+ if (!url) {
268
+ setOgData(null);
269
+ setLoading(false);
270
+ setError(null);
271
+ return;
272
+ }
273
+ let cancelled = false;
274
+ setLoading(true);
275
+ setError(null);
276
+ fetchOGData(url).then((data) => {
277
+ if (!cancelled) {
278
+ setOgData(data);
279
+ setLoading(false);
280
+ }
281
+ }).catch((err) => {
282
+ if (!cancelled) {
283
+ setError(err instanceof Error ? err.message : "Failed to fetch OG data");
284
+ setLoading(false);
285
+ }
286
+ });
287
+ return () => {
288
+ cancelled = true;
289
+ };
290
+ }, [url]);
291
+ return { ogData, loading, error };
292
+ }
230
293
 
231
294
  // src/platforms.tsx
232
295
  var import_lucide_react = require("lucide-react");
@@ -364,32 +427,6 @@ var CSS_VAR_DEFAULTS = CSS_VAR_UI_DEFAULTS;
364
427
  var import_jsx_runtime2 = require("react/jsx-runtime");
365
428
  var DEFAULT_BUTTON_SIZE = 45;
366
429
  var DEFAULT_ICON_SIZE = 22;
367
- var IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "ico", "avif"];
368
- var VIDEO_EXTENSIONS = ["mp4", "webm", "mov", "avi", "mkv", "m4v", "ogv"];
369
- var AUDIO_EXTENSIONS = ["mp3", "wav", "ogg", "m4a", "aac", "flac", "wma"];
370
- function detectPreviewType(url) {
371
- try {
372
- const pathname = new URL(url, "http://localhost").pathname;
373
- const ext = pathname.split(".").pop()?.toLowerCase() || "";
374
- if (IMAGE_EXTENSIONS.includes(ext)) return "image";
375
- if (VIDEO_EXTENSIONS.includes(ext)) return "video";
376
- if (AUDIO_EXTENSIONS.includes(ext)) return "audio";
377
- if (url.includes("/api/og") || url.includes("og-image")) return "image";
378
- if (url.includes("youtube.com") || url.includes("vimeo.com")) return "video";
379
- return "link";
380
- } catch {
381
- return "link";
382
- }
383
- }
384
- function getFilenameFromUrl(url) {
385
- try {
386
- const pathname = new URL(url, "http://localhost").pathname;
387
- const filename = pathname.split("/").pop() || "";
388
- return decodeURIComponent(filename);
389
- } catch {
390
- return url;
391
- }
392
- }
393
430
  var defaultClasses = {
394
431
  root: "max-w-md mx-auto",
395
432
  header: "text-center mb-2",
@@ -398,12 +435,8 @@ var defaultClasses = {
398
435
  preview: "flex justify-center mb-4 px-4",
399
436
  previewSkeleton: "rounded-xl overflow-hidden",
400
437
  previewImage: "",
401
- previewVideo: "",
402
- previewFile: "",
403
- previewFileIcon: "",
404
- previewFilename: "truncate",
405
- previewLink: "",
406
- grid: "px-2 py-6 flex flex-row items-center gap-4 gap-y-6 flex-wrap justify-center",
438
+ previewMeta: "",
439
+ grid: "px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center",
407
440
  button: "flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group",
408
441
  buttonIcon: "p-2 rounded-full transition-all flex items-center justify-center group-hover:scale-110 group-active:scale-95 mb-2",
409
442
  buttonLabel: ""
@@ -417,28 +450,10 @@ var shimmerKeyframes = `
417
450
  function cssVar(name, fallback) {
418
451
  return `var(${name}, ${fallback})`;
419
452
  }
420
- function normalizePreview(preview) {
421
- if (!preview) return null;
422
- if (typeof preview === "string") {
423
- const type2 = detectPreviewType(preview);
424
- return {
425
- url: preview,
426
- type: type2,
427
- filename: getFilenameFromUrl(preview)
428
- };
429
- }
430
- const type = preview.type === "auto" || !preview.type ? detectPreviewType(preview.url) : preview.type;
431
- return {
432
- ...preview,
433
- type,
434
- filename: preview.filename || getFilenameFromUrl(preview.url)
435
- };
436
- }
437
453
  function ShareSheetContent({
438
454
  title = "Share",
439
455
  shareUrl,
440
456
  shareText,
441
- preview,
442
457
  downloadUrl,
443
458
  downloadFilename,
444
459
  className,
@@ -453,15 +468,15 @@ function ShareSheetContent({
453
468
  labels = {},
454
469
  icons = {}
455
470
  }) {
456
- const [mediaLoaded, setMediaLoaded] = (0, import_react2.useState)(false);
457
- const [mediaError, setMediaError] = (0, import_react2.useState)(false);
458
- const handleMediaLoad = (0, import_react2.useCallback)(() => {
459
- setMediaLoaded(true);
471
+ const [imageLoaded, setImageLoaded] = (0, import_react2.useState)(false);
472
+ const [imageError, setImageError] = (0, import_react2.useState)(false);
473
+ const { ogData, loading: ogLoading } = useOGData(shareUrl);
474
+ const handleImageLoad = (0, import_react2.useCallback)(() => {
475
+ setImageLoaded(true);
460
476
  }, []);
461
- const handleMediaError = (0, import_react2.useCallback)(() => {
462
- setMediaError(true);
477
+ const handleImageError = (0, import_react2.useCallback)(() => {
478
+ setImageError(true);
463
479
  }, []);
464
- const previewConfig = (0, import_react2.useMemo)(() => normalizePreview(preview), [preview]);
465
480
  const shareSheet = useShareSheet({
466
481
  shareUrl,
467
482
  shareText,
@@ -518,49 +533,30 @@ function ShareSheetContent({
518
533
  return true;
519
534
  });
520
535
  }, [buttons, show, hide]);
521
- const showPreview = !!previewConfig;
536
+ const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);
537
+ const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
538
+ const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
522
539
  const renderPreview = () => {
523
- if (!previewConfig) return null;
524
- const { type, url, filename, alt, poster } = previewConfig;
525
- const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);
526
- const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
527
- const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
528
- const UrlLabel = ({ displayUrl = url }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
529
- "div",
530
- {
531
- className: cn(defaultClasses.previewFilename, classNames.previewFilename),
532
- style: {
533
- color: textColor,
534
- fontSize: "10px",
535
- opacity: 0.5,
536
- textAlign: "center",
537
- marginTop: "6px"
538
- },
539
- children: displayUrl
540
- }
541
- );
542
- const PlaceholderCard = ({
543
- icon: IconComponent,
544
- isLoading = false,
545
- label,
546
- displayUrl
547
- }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
548
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
540
+ const ogImage = ogData?.image;
541
+ const hasImage = ogImage && !imageError;
542
+ if (ogLoading) {
543
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
549
544
  "div",
550
545
  {
551
546
  className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
552
547
  style: {
553
548
  position: "relative",
554
549
  backgroundColor: bgColor,
555
- width: "200px",
556
- height: "120px",
550
+ width: "100%",
551
+ maxWidth: "320px",
552
+ aspectRatio: "1.91 / 1",
557
553
  overflow: "hidden",
558
554
  display: "flex",
559
555
  alignItems: "center",
560
556
  justifyContent: "center"
561
557
  },
562
558
  children: [
563
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
559
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
564
560
  "div",
565
561
  {
566
562
  style: {
@@ -571,197 +567,125 @@ function ShareSheetContent({
571
567
  }
572
568
  }
573
569
  ) }),
574
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
575
- "div",
576
- {
577
- style: {
578
- display: "flex",
579
- flexDirection: "column",
580
- alignItems: "center",
581
- justifyContent: "center",
582
- gap: "8px"
583
- },
584
- children: [
585
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconComponent, { size: 32, style: { color: textColor, opacity: 0.4 } }),
586
- label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: textColor, fontSize: "11px", opacity: 0.4 }, children: label })
587
- ]
588
- }
589
- )
570
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } })
590
571
  ]
591
572
  }
592
- ),
593
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, { displayUrl })
594
- ] });
595
- if (mediaError && (type === "image" || type === "video")) {
596
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
573
+ ) });
597
574
  }
598
- switch (type) {
599
- case "image":
600
- if (!mediaLoaded) {
601
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
602
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
603
- "div",
604
- {
605
- className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
606
- style: {
607
- position: "relative",
608
- backgroundColor: bgColor,
609
- width: "200px",
610
- height: "120px",
611
- overflow: "hidden",
612
- display: "flex",
613
- alignItems: "center",
614
- justifyContent: "center"
615
- },
616
- children: [
617
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
618
- "div",
619
- {
620
- style: {
621
- position: "absolute",
622
- inset: 0,
623
- background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
624
- animation: "sharesheet-shimmer 1.5s infinite"
625
- }
626
- }
627
- ) }),
628
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
629
- ]
630
- }
631
- ),
632
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
633
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
634
- "img",
635
- {
636
- src: url,
637
- alt: alt || "Preview",
638
- onLoad: handleMediaLoad,
639
- onError: handleMediaError,
640
- style: { display: "none" }
641
- }
642
- )
643
- ] });
644
- }
645
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
646
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
647
- "img",
575
+ if (!ogData || !hasImage) {
576
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
577
+ "div",
578
+ {
579
+ className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
580
+ style: {
581
+ position: "relative",
582
+ backgroundColor: bgColor,
583
+ width: "100%",
584
+ maxWidth: "320px",
585
+ aspectRatio: "1.91 / 1",
586
+ overflow: "hidden",
587
+ display: "flex",
588
+ alignItems: "center",
589
+ justifyContent: "center"
590
+ },
591
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
592
+ "div",
648
593
  {
649
- src: url,
650
- alt: alt || "Preview",
651
- className: cn(defaultClasses.previewImage, classNames.previewImage),
652
594
  style: {
653
- maxWidth: "100%",
654
- maxHeight: "180px",
655
- borderRadius: "12px",
656
- opacity: 1,
657
- transition: "opacity 0.3s ease-in-out"
658
- }
659
- }
660
- ),
661
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {})
662
- ] });
663
- case "video":
664
- if (!mediaLoaded) {
665
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
666
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
667
- "div",
668
- {
669
- className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
670
- style: {
671
- position: "relative",
672
- backgroundColor: bgColor,
673
- width: "200px",
674
- height: "120px",
675
- overflow: "hidden",
676
- display: "flex",
677
- alignItems: "center",
678
- justifyContent: "center"
679
- },
680
- children: [
681
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
682
- "div",
683
- {
684
- style: {
685
- position: "absolute",
686
- inset: 0,
687
- background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
688
- animation: "sharesheet-shimmer 1.5s infinite"
689
- }
690
- }
691
- ) }),
692
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Film, { size: 32, style: { color: textColor, opacity: 0.4 } })
693
- ]
694
- }
695
- ),
696
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
697
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
698
- "video",
699
- {
700
- src: url,
701
- poster,
702
- onLoadedData: handleMediaLoad,
703
- onError: handleMediaError,
704
- style: { display: "none" },
705
- muted: true,
706
- playsInline: true,
707
- preload: "metadata"
708
- }
709
- )
710
- ] });
711
- }
712
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
713
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", borderRadius: "12px", overflow: "hidden" }, children: [
714
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
715
- "video",
716
- {
717
- src: url,
718
- poster,
719
- className: cn(defaultClasses.previewVideo, classNames.previewVideo),
720
- style: {
721
- maxWidth: "100%",
722
- maxHeight: "180px",
723
- display: "block"
724
- },
725
- muted: true,
726
- playsInline: true,
727
- preload: "metadata"
728
- }
729
- ),
730
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
731
- "div",
732
- {
733
- style: {
734
- position: "absolute",
735
- inset: 0,
736
- display: "flex",
737
- alignItems: "center",
738
- justifyContent: "center",
739
- pointerEvents: "none"
740
- },
741
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
742
- "div",
595
+ display: "flex",
596
+ flexDirection: "column",
597
+ alignItems: "center",
598
+ justifyContent: "center",
599
+ gap: "8px",
600
+ padding: "16px"
601
+ },
602
+ children: [
603
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } }),
604
+ ogData?.title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
605
+ "span",
743
606
  {
744
607
  style: {
745
- backgroundColor: "rgba(0, 0, 0, 0.5)",
746
- borderRadius: "50%",
747
- padding: "10px"
608
+ color: textColor,
609
+ fontSize: "12px",
610
+ opacity: 0.6,
611
+ textAlign: "center",
612
+ maxWidth: "280px",
613
+ overflow: "hidden",
614
+ textOverflow: "ellipsis",
615
+ display: "-webkit-box",
616
+ WebkitLineClamp: 2,
617
+ WebkitBoxOrient: "vertical"
748
618
  },
749
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Play, { size: 20, fill: "white", color: "white" })
619
+ children: ogData.title
750
620
  }
751
621
  )
752
- }
753
- )
754
- ] }),
755
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {})
756
- ] });
757
- case "audio":
758
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Music, label: filename || "Audio", displayUrl: url });
759
- case "file":
760
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.FileText, label: filename || "File", displayUrl: url });
761
- case "link":
762
- default:
763
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
622
+ ]
623
+ }
624
+ )
625
+ }
626
+ ) });
627
+ }
628
+ if (!imageLoaded) {
629
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: [
630
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
631
+ "div",
632
+ {
633
+ className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
634
+ style: {
635
+ position: "relative",
636
+ backgroundColor: bgColor,
637
+ width: "100%",
638
+ maxWidth: "320px",
639
+ aspectRatio: "1.91 / 1",
640
+ overflow: "hidden",
641
+ display: "flex",
642
+ alignItems: "center",
643
+ justifyContent: "center"
644
+ },
645
+ children: [
646
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
647
+ "div",
648
+ {
649
+ style: {
650
+ position: "absolute",
651
+ inset: 0,
652
+ background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
653
+ animation: "sharesheet-shimmer 1.5s infinite"
654
+ }
655
+ }
656
+ ) }),
657
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
658
+ ]
659
+ }
660
+ ),
661
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
662
+ "img",
663
+ {
664
+ src: ogImage,
665
+ alt: ogData.title || "Preview",
666
+ onLoad: handleImageLoad,
667
+ onError: handleImageError,
668
+ style: { display: "none" }
669
+ }
670
+ )
671
+ ] });
764
672
  }
673
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
674
+ "img",
675
+ {
676
+ src: ogImage,
677
+ alt: ogData.title || "Preview",
678
+ className: cn(defaultClasses.previewImage, classNames.previewImage),
679
+ style: {
680
+ width: "100%",
681
+ maxWidth: "320px",
682
+ height: "auto",
683
+ borderRadius: "12px",
684
+ opacity: 1,
685
+ transition: "opacity 0.3s ease-in-out"
686
+ }
687
+ }
688
+ ) });
765
689
  };
766
690
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn(defaultClasses.root, classNames.root, className), children: [
767
691
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { dangerouslySetInnerHTML: { __html: shimmerKeyframes } }),
@@ -783,7 +707,7 @@ function ShareSheetContent({
783
707
  }
784
708
  )
785
709
  ] }),
786
- showPreview && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.preview, classNames.preview), children: renderPreview() }),
710
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.preview, classNames.preview), children: renderPreview() }),
787
711
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.grid, classNames.grid), children: visibleButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
788
712
  "button",
789
713
  {