react-sharesheet 1.8.0 → 1.9.1
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 +9 -0
- package/dist/content.d.mts +3 -3
- package/dist/content.d.ts +3 -3
- package/dist/content.js +79 -15
- package/dist/content.js.map +1 -1
- package/dist/content.mjs +79 -15
- 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 +111 -27
- package/dist/drawer.js.map +1 -1
- package/dist/drawer.mjs +101 -27
- package/dist/drawer.mjs.map +1 -1
- package/dist/{headless-BTnsV8ZO.d.ts → headless-lxSw27f0.d.ts} +6 -2
- package/dist/{headless-DzKMJ3eW.d.mts → headless-x5iUF86E.d.mts} +6 -2
- package/dist/headless.d.mts +2 -2
- package/dist/headless.d.ts +2 -2
- package/dist/headless.js +41 -2
- package/dist/headless.js.map +1 -1
- package/dist/headless.mjs +41 -2
- 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 +111 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -27
- package/dist/index.mjs.map +1 -1
- package/dist/{platforms-BgGzSDRk.d.mts → platforms-BtmTZmgl.d.mts} +10 -2
- package/dist/{platforms-BgGzSDRk.d.ts → platforms-BtmTZmgl.d.ts} +10 -2
- package/package.json +18 -16
- package/src/ShareSheetContent.tsx +45 -15
- package/src/ShareSheetDrawer.tsx +36 -9
- package/src/__tests__/drawer-trigger.test.tsx +50 -0
- package/src/__tests__/hooks.test.ts +3 -3
- package/src/__tests__/og-fetcher.test.ts +9 -9
- package/src/__tests__/setup.ts +1 -1
- package/src/hooks.ts +60 -2
- package/src/types.ts +9 -1
package/dist/index.mjs
CHANGED
|
@@ -231,6 +231,8 @@ function useShareSheet({
|
|
|
231
231
|
downloadUrl,
|
|
232
232
|
downloadFilename,
|
|
233
233
|
emailSubject = "Share",
|
|
234
|
+
shareFile,
|
|
235
|
+
shareFilename = "share.png",
|
|
234
236
|
onNativeShare,
|
|
235
237
|
onCopy,
|
|
236
238
|
onDownload
|
|
@@ -259,10 +261,47 @@ function useShareSheet({
|
|
|
259
261
|
}
|
|
260
262
|
}, [safeUrl, onCopy]);
|
|
261
263
|
const nativeShare = useCallback(async () => {
|
|
262
|
-
if (!safeUrl) return;
|
|
263
264
|
const nav = navigator;
|
|
264
265
|
if (!("share" in nav) || typeof nav.share !== "function") return;
|
|
265
266
|
try {
|
|
267
|
+
if (shareFile) {
|
|
268
|
+
let blob;
|
|
269
|
+
if (typeof shareFile === "string" && shareFile.startsWith("data:")) {
|
|
270
|
+
const response = await fetch(shareFile);
|
|
271
|
+
blob = await response.blob();
|
|
272
|
+
} else if (shareFile instanceof Blob) {
|
|
273
|
+
blob = shareFile;
|
|
274
|
+
} else {
|
|
275
|
+
if (!safeUrl) return;
|
|
276
|
+
await nav.share({
|
|
277
|
+
title: shareText,
|
|
278
|
+
text: shareText,
|
|
279
|
+
url: safeUrl
|
|
280
|
+
});
|
|
281
|
+
onNativeShare?.();
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const file = new File([blob], shareFilename, { type: blob.type || "image/png" });
|
|
285
|
+
const shareData = {
|
|
286
|
+
files: [file],
|
|
287
|
+
title: shareText,
|
|
288
|
+
text: shareText
|
|
289
|
+
};
|
|
290
|
+
if (nav.canShare && !nav.canShare(shareData)) {
|
|
291
|
+
if (!safeUrl) return;
|
|
292
|
+
await nav.share({
|
|
293
|
+
title: shareText,
|
|
294
|
+
text: shareText,
|
|
295
|
+
url: safeUrl
|
|
296
|
+
});
|
|
297
|
+
onNativeShare?.();
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
await nav.share(shareData);
|
|
301
|
+
onNativeShare?.();
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (!safeUrl) return;
|
|
266
305
|
await nav.share({
|
|
267
306
|
title: shareText,
|
|
268
307
|
text: shareText,
|
|
@@ -271,7 +310,7 @@ function useShareSheet({
|
|
|
271
310
|
onNativeShare?.();
|
|
272
311
|
} catch {
|
|
273
312
|
}
|
|
274
|
-
}, [safeUrl, shareText, onNativeShare]);
|
|
313
|
+
}, [safeUrl, shareText, shareFile, shareFilename, onNativeShare]);
|
|
275
314
|
const downloadFile = useCallback(async () => {
|
|
276
315
|
const url = (downloadUrl ?? "").trim();
|
|
277
316
|
if (!url) return;
|
|
@@ -545,7 +584,7 @@ var CSS_VAR_UI_DEFAULTS = {
|
|
|
545
584
|
[CSS_VARS_UI.overlayBg]: "rgba(0, 0, 0, 0.7)",
|
|
546
585
|
[CSS_VARS_UI.drawerBg]: "#09090b",
|
|
547
586
|
[CSS_VARS_UI.drawerBorder]: "#27272a",
|
|
548
|
-
[CSS_VARS_UI.handleBg]: "
|
|
587
|
+
[CSS_VARS_UI.handleBg]: "rgba(255, 255, 255, 0.2)",
|
|
549
588
|
[CSS_VARS_UI.titleColor]: "#ffffff",
|
|
550
589
|
[CSS_VARS_UI.subtitleColor]: "#a1a1aa",
|
|
551
590
|
[CSS_VARS_UI.buttonLabelColor]: "#ffffff",
|
|
@@ -564,9 +603,9 @@ var defaultClasses = {
|
|
|
564
603
|
header: "text-center mb-2",
|
|
565
604
|
title: "text-2xl font-black",
|
|
566
605
|
subtitle: "mt-1 text-sm",
|
|
567
|
-
preview: "flex justify-center
|
|
606
|
+
preview: "flex justify-center my-4 px-4",
|
|
568
607
|
previewSkeleton: "rounded-xl overflow-hidden",
|
|
569
|
-
previewImage: "border border-white/10",
|
|
608
|
+
previewImage: "border border-white/10 rounded-xl",
|
|
570
609
|
previewMeta: "",
|
|
571
610
|
grid: "px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center",
|
|
572
611
|
button: "flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group",
|
|
@@ -595,12 +634,16 @@ function ShareSheetContent({
|
|
|
595
634
|
shareText,
|
|
596
635
|
downloadUrl,
|
|
597
636
|
downloadFilename,
|
|
637
|
+
previewImage,
|
|
638
|
+
shareFile,
|
|
639
|
+
shareFilename,
|
|
598
640
|
className,
|
|
599
641
|
classNames = {},
|
|
600
642
|
buttonSize = DEFAULT_BUTTON_SIZE,
|
|
601
643
|
iconSize = DEFAULT_ICON_SIZE,
|
|
602
644
|
onNativeShare,
|
|
603
645
|
onCopy,
|
|
646
|
+
onShare,
|
|
604
647
|
onDownload,
|
|
605
648
|
hide = [],
|
|
606
649
|
show,
|
|
@@ -609,7 +652,7 @@ function ShareSheetContent({
|
|
|
609
652
|
}) {
|
|
610
653
|
const [imageLoaded, setImageLoaded] = useState2(false);
|
|
611
654
|
const [imageError, setImageError] = useState2(false);
|
|
612
|
-
const { ogData, loading: ogLoading } = useOGData(shareUrl);
|
|
655
|
+
const { ogData, loading: ogLoading } = useOGData(previewImage ? void 0 : shareUrl);
|
|
613
656
|
const handleImageLoad = useCallback2(() => {
|
|
614
657
|
setImageLoaded(true);
|
|
615
658
|
}, []);
|
|
@@ -622,6 +665,8 @@ function ShareSheetContent({
|
|
|
622
665
|
downloadUrl,
|
|
623
666
|
downloadFilename,
|
|
624
667
|
emailSubject: shareText,
|
|
668
|
+
shareFile,
|
|
669
|
+
shareFilename,
|
|
625
670
|
onNativeShare,
|
|
626
671
|
onCopy,
|
|
627
672
|
onDownload
|
|
@@ -667,11 +712,14 @@ function ShareSheetContent({
|
|
|
667
712
|
// Use CSS var with fallback to platform color
|
|
668
713
|
bgColor: cssVar(PLATFORM_CSS_VARS[id], PLATFORM_COLORS[id].bg),
|
|
669
714
|
textColor: PLATFORM_COLORS[id].text,
|
|
670
|
-
onClick:
|
|
715
|
+
onClick: () => {
|
|
716
|
+
onShare?.(id);
|
|
717
|
+
shareActions[id]();
|
|
718
|
+
},
|
|
671
719
|
condition
|
|
672
720
|
};
|
|
673
721
|
});
|
|
674
|
-
}, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);
|
|
722
|
+
}, [iconSize, labels, icons, dynamicLabels, shareActions, onShare, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);
|
|
675
723
|
const visibleButtons = useMemo2(() => {
|
|
676
724
|
if (show && show.length > 0) {
|
|
677
725
|
return show.map((id) => buttons.find((btn) => btn.id === id)).filter((btn) => {
|
|
@@ -691,9 +739,10 @@ function ShareSheetContent({
|
|
|
691
739
|
const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
|
|
692
740
|
const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
|
|
693
741
|
const renderPreview = () => {
|
|
694
|
-
const ogImage = ogData?.image;
|
|
742
|
+
const ogImage = previewImage || ogData?.image;
|
|
695
743
|
const hasImage = ogImage && !imageError;
|
|
696
|
-
|
|
744
|
+
const isLoading = !previewImage && ogLoading;
|
|
745
|
+
if (isLoading) {
|
|
697
746
|
return /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ jsxs(
|
|
698
747
|
"div",
|
|
699
748
|
{
|
|
@@ -726,7 +775,7 @@ function ShareSheetContent({
|
|
|
726
775
|
}
|
|
727
776
|
) });
|
|
728
777
|
}
|
|
729
|
-
if (!
|
|
778
|
+
if (!hasImage) {
|
|
730
779
|
return /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ jsx2(
|
|
731
780
|
"div",
|
|
732
781
|
{
|
|
@@ -779,6 +828,22 @@ function ShareSheetContent({
|
|
|
779
828
|
}
|
|
780
829
|
) });
|
|
781
830
|
}
|
|
831
|
+
const isDataUrl = typeof ogImage === "string" && ogImage.startsWith("data:");
|
|
832
|
+
if (isDataUrl) {
|
|
833
|
+
return /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ jsx2(
|
|
834
|
+
"img",
|
|
835
|
+
{
|
|
836
|
+
src: ogImage,
|
|
837
|
+
alt: "Preview",
|
|
838
|
+
className: cn(defaultClasses.previewImage, classNames.previewImage),
|
|
839
|
+
style: {
|
|
840
|
+
width: "100%",
|
|
841
|
+
maxWidth: "320px",
|
|
842
|
+
height: "auto"
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
) });
|
|
846
|
+
}
|
|
782
847
|
if (!imageLoaded) {
|
|
783
848
|
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: [
|
|
784
849
|
/* @__PURE__ */ jsxs(
|
|
@@ -816,7 +881,7 @@ function ShareSheetContent({
|
|
|
816
881
|
"img",
|
|
817
882
|
{
|
|
818
883
|
src: ogImage,
|
|
819
|
-
alt: ogData
|
|
884
|
+
alt: ogData?.title || "Preview",
|
|
820
885
|
onLoad: handleImageLoad,
|
|
821
886
|
onError: handleImageError,
|
|
822
887
|
style: { display: "none" }
|
|
@@ -828,13 +893,12 @@ function ShareSheetContent({
|
|
|
828
893
|
"img",
|
|
829
894
|
{
|
|
830
895
|
src: ogImage,
|
|
831
|
-
alt: ogData
|
|
896
|
+
alt: ogData?.title || "Preview",
|
|
832
897
|
className: cn(defaultClasses.previewImage, classNames.previewImage, "sharesheet-fadein"),
|
|
833
898
|
style: {
|
|
834
899
|
width: "100%",
|
|
835
900
|
maxWidth: "320px",
|
|
836
|
-
height: "auto"
|
|
837
|
-
borderRadius: "12px"
|
|
901
|
+
height: "auto"
|
|
838
902
|
}
|
|
839
903
|
}
|
|
840
904
|
) });
|
|
@@ -897,7 +961,7 @@ function ShareSheetContent({
|
|
|
897
961
|
var ShareMenuContent = ShareSheetContent;
|
|
898
962
|
|
|
899
963
|
// src/ShareSheetDrawer.tsx
|
|
900
|
-
import { useState as useState3 } from "react";
|
|
964
|
+
import React, { useState as useState3 } from "react";
|
|
901
965
|
import { Drawer } from "vaul";
|
|
902
966
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
903
967
|
var defaultDrawerClasses = {
|
|
@@ -907,6 +971,16 @@ var defaultDrawerClasses = {
|
|
|
907
971
|
handle: "mx-auto w-12 h-1.5 shrink-0 rounded-full mb-6",
|
|
908
972
|
trigger: ""
|
|
909
973
|
};
|
|
974
|
+
function renderTrigger(children, className) {
|
|
975
|
+
if (React.isValidElement(children)) {
|
|
976
|
+
if (!className) return children;
|
|
977
|
+
const childClassName = children.props.className;
|
|
978
|
+
return React.cloneElement(children, {
|
|
979
|
+
className: cn(childClassName, className)
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
return /* @__PURE__ */ jsx3("button", { type: "button", className, children });
|
|
983
|
+
}
|
|
910
984
|
function cssVar2(name, fallback) {
|
|
911
985
|
return `var(${name}, ${fallback})`;
|
|
912
986
|
}
|
|
@@ -927,6 +1001,9 @@ function ShareSheetDrawer({
|
|
|
927
1001
|
shareText,
|
|
928
1002
|
downloadUrl,
|
|
929
1003
|
downloadFilename,
|
|
1004
|
+
previewImage,
|
|
1005
|
+
shareFile,
|
|
1006
|
+
shareFilename,
|
|
930
1007
|
disabled,
|
|
931
1008
|
children,
|
|
932
1009
|
open: controlledOpen,
|
|
@@ -948,17 +1025,11 @@ function ShareSheetDrawer({
|
|
|
948
1025
|
const open = isControlled ? controlledOpen : internalOpen;
|
|
949
1026
|
const setOpen = isControlled ? (value) => controlledOnOpenChange?.(value) : setInternalOpen;
|
|
950
1027
|
return /* @__PURE__ */ jsxs2(Drawer.Root, { open, onOpenChange: setOpen, shouldScaleBackground: true, children: [
|
|
951
|
-
/* @__PURE__ */ jsx3(Drawer.Trigger, { asChild: true, children:
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
classNames.trigger,
|
|
957
|
-
disabled ? "pointer-events-none opacity-50" : ""
|
|
958
|
-
),
|
|
959
|
-
children
|
|
960
|
-
}
|
|
961
|
-
) }),
|
|
1028
|
+
/* @__PURE__ */ jsx3(Drawer.Trigger, { asChild: true, children: renderTrigger(children, cn(
|
|
1029
|
+
defaultDrawerClasses.trigger,
|
|
1030
|
+
classNames.trigger,
|
|
1031
|
+
disabled ? "pointer-events-none opacity-50" : ""
|
|
1032
|
+
)) }),
|
|
962
1033
|
/* @__PURE__ */ jsxs2(Drawer.Portal, { children: [
|
|
963
1034
|
/* @__PURE__ */ jsx3(
|
|
964
1035
|
Drawer.Overlay,
|
|
@@ -1004,6 +1075,9 @@ function ShareSheetDrawer({
|
|
|
1004
1075
|
shareText,
|
|
1005
1076
|
downloadUrl,
|
|
1006
1077
|
downloadFilename,
|
|
1078
|
+
previewImage,
|
|
1079
|
+
shareFile,
|
|
1080
|
+
shareFilename,
|
|
1007
1081
|
className,
|
|
1008
1082
|
classNames,
|
|
1009
1083
|
buttonSize,
|