react-sharesheet 1.9.0 → 1.10.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 +48 -13
- package/dist/content.d.mts +3 -3
- package/dist/content.d.ts +3 -3
- package/dist/content.js +12 -5
- package/dist/content.js.map +1 -1
- package/dist/content.mjs +11 -5
- 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 +40 -17
- package/dist/drawer.js.map +1 -1
- package/dist/drawer.mjs +29 -17
- package/dist/drawer.mjs.map +1 -1
- package/dist/{headless-lxSw27f0.d.ts → headless-CEUr7QJE.d.ts} +5 -14
- package/dist/{headless-x5iUF86E.d.mts → headless-JYVQPj9Q.d.mts} +5 -14
- package/dist/headless.d.mts +2 -2
- package/dist/headless.d.ts +2 -2
- package/dist/headless.js +6 -2
- package/dist/headless.js.map +1 -1
- package/dist/headless.mjs +7 -3
- 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 +36 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -16
- package/dist/index.mjs.map +1 -1
- package/dist/{platforms-BtmTZmgl.d.mts → platforms-B1VXTDkO.d.mts} +20 -2
- package/dist/{platforms-BtmTZmgl.d.ts → platforms-B1VXTDkO.d.ts} +20 -2
- package/package.json +2 -2
- package/src/ShareSheetContent.tsx +4 -2
- package/src/ShareSheetDrawer.tsx +32 -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__/preview-fetch.test.tsx +82 -0
- package/src/__tests__/setup.ts +1 -1
- package/src/content.ts +1 -0
- package/src/drawer.ts +1 -0
- package/src/headless.ts +1 -1
- package/src/hooks.ts +12 -5
- package/src/index.ts +1 -1
- package/src/og-fetcher.ts +6 -1
- package/src/types.ts +8 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://sharesheet.gwendall.com)
|
|
7
7
|
|
|
8
|
-
A mobile-first share sheet for React with native share support,
|
|
8
|
+
A mobile-first share sheet for React with native share support, link previews, and 15+ social platforms.
|
|
9
9
|
|
|
10
10
|
Designed for modern React apps, react-sharesheet ships with a beautiful Tailwind-based drawer UI out of the box, while also exposing fully headless APIs for complete customization.
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ Designed for modern React apps, react-sharesheet ships with a beautiful Tailwind
|
|
|
15
15
|
|
|
16
16
|
- 📱 **Mobile-first drawer UI** - feels native on iOS & Android
|
|
17
17
|
- 🔗 **Native Web Share API** - fallback handled automatically
|
|
18
|
-
- 🖼 **
|
|
18
|
+
- 🖼 **Link previews** - your own image, or an Open Graph lookup you opt into (no request leaves the page by default)
|
|
19
19
|
- 🧠 **Headless APIs** - build your own UI if needed
|
|
20
20
|
- 🎨 **Themeable** - CSS variables + Tailwind class overrides
|
|
21
21
|
- 🌍 **15+ social platforms** - WhatsApp, X, Telegram, Instagram, and more
|
|
@@ -133,27 +133,61 @@ function CustomShareUI() {
|
|
|
133
133
|
}
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
##
|
|
136
|
+
## Link Preview
|
|
137
137
|
|
|
138
|
-
The
|
|
138
|
+
The sheet shows a preview card above the buttons. Give it the image yourself with `previewImage`
|
|
139
|
+
(a URL or a data URL): it is shown as is, and nothing is fetched.
|
|
139
140
|
|
|
140
141
|
```tsx
|
|
141
142
|
<ShareSheetDrawer
|
|
142
|
-
shareUrl="https://gwendall.com"
|
|
143
|
+
shareUrl="https://gwendall.com"
|
|
143
144
|
shareText="Check out this site!"
|
|
145
|
+
previewImage="https://gwendall.com/og.png"
|
|
144
146
|
>
|
|
145
147
|
<button>Share</button>
|
|
146
148
|
</ShareSheetDrawer>
|
|
147
149
|
```
|
|
148
150
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
Without `previewImage`, the sheet sends the link nowhere and shows a link placeholder. To look the
|
|
152
|
+
link's Open Graph card up instead, opt in with `fetchPreview`:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import { ShareSheetDrawer, fetchOGData } from "react-sharesheet";
|
|
156
|
+
|
|
157
|
+
<ShareSheetDrawer
|
|
158
|
+
shareUrl="https://gwendall.com"
|
|
159
|
+
shareText="Check out this site!"
|
|
160
|
+
fetchPreview={fetchOGData} // asks api.microlink.io for the card of shareUrl
|
|
161
|
+
>
|
|
162
|
+
<button>Share</button>
|
|
163
|
+
</ShareSheetDrawer>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`fetchOGData` asks [Microlink](https://microlink.io) (free, no key), which means the link you share
|
|
167
|
+
is sent to a third party: keep it for public links. Any `(url) => Promise<OGData | null>` works, for
|
|
168
|
+
example one that asks your own server:
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<ShareSheetDrawer
|
|
172
|
+
shareUrl={url}
|
|
173
|
+
shareText="Check out this site!"
|
|
174
|
+
fetchPreview={(u) => fetch(`/api/og?url=${encodeURIComponent(u)}`).then((r) => r.json())}
|
|
175
|
+
>
|
|
176
|
+
<button>Share</button>
|
|
177
|
+
</ShareSheetDrawer>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
With a fetcher, the sheet shows a loading shimmer, then the card's image if it has one, or a
|
|
181
|
+
placeholder with the page title.
|
|
182
|
+
|
|
183
|
+
> **Changed in 1.10.0.** Before 1.10.0 the sheet called Microlink by itself whenever `previewImage`
|
|
184
|
+
> was missing. It no longer does: pass `fetchPreview={fetchOGData}` to keep the old behavior.
|
|
153
185
|
|
|
154
186
|
### Using the OG Hook Directly
|
|
155
187
|
|
|
156
|
-
You can also use the `useOGData` hook for custom implementations
|
|
188
|
+
You can also use the `useOGData` hook for custom implementations. It fetches through Microlink
|
|
189
|
+
(`fetchOGData`, cached per URL) unless you pass your own fetcher as the second argument: calling the
|
|
190
|
+
hook is the opt-in.
|
|
157
191
|
|
|
158
192
|
```tsx
|
|
159
193
|
import { useOGData } from "react-sharesheet/headless";
|
|
@@ -310,11 +344,12 @@ Override any part of the component with `classNames`:
|
|
|
310
344
|
| Prop | Type | Default | Description |
|
|
311
345
|
|------|------|---------|-------------|
|
|
312
346
|
| `title` | `string` | `"Share"` | Title displayed at the top |
|
|
313
|
-
| `shareUrl` | `string` | **required** | URL to share
|
|
347
|
+
| `shareUrl` | `string` | **required** | URL to share |
|
|
314
348
|
| `shareText` | `string` | **required** | Text to share |
|
|
315
349
|
| `downloadUrl` | `string` | - | URL for download button |
|
|
316
350
|
| `downloadFilename` | `string` | - | Filename for download |
|
|
317
351
|
| `previewImage` | `string \| null` | - | Custom preview image URL (skips OG fetching) |
|
|
352
|
+
| `fetchPreview` | `(url) => Promise<OGData \| null>` | - | Looks the link's card up when there is no `previewImage` (`fetchOGData` for Microlink). Unset: no request |
|
|
318
353
|
| `shareFile` | `string \| Blob \| null` | - | File shared via native share (data URL or Blob); takes priority over URL sharing |
|
|
319
354
|
| `shareFilename` | `string` | `"share.png"` | Filename for the shared file |
|
|
320
355
|
| `className` | `string` | - | Class for root container |
|
|
@@ -425,10 +460,10 @@ import {
|
|
|
425
460
|
} from "react-sharesheet";
|
|
426
461
|
|
|
427
462
|
// Content only (smaller bundle)
|
|
428
|
-
import { ShareSheetContent } from "react-sharesheet/content";
|
|
463
|
+
import { ShareSheetContent, fetchOGData } from "react-sharesheet/content";
|
|
429
464
|
|
|
430
465
|
// Drawer only
|
|
431
|
-
import { ShareSheetDrawer } from "react-sharesheet/drawer";
|
|
466
|
+
import { ShareSheetDrawer, fetchOGData } from "react-sharesheet/drawer";
|
|
432
467
|
|
|
433
468
|
// Headless (smallest bundle - no UI components)
|
|
434
469
|
import {
|
package/dist/content.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { S as ShareSheetContentProps } from './platforms-
|
|
3
|
-
export {
|
|
2
|
+
import { S as ShareSheetContentProps } from './platforms-B1VXTDkO.mjs';
|
|
3
|
+
export { o as CSS_VARS, C as CSS_VARS_UI, p as CSS_VAR_DEFAULTS, n as CSS_VAR_UI_DEFAULTS, O as OGData, a as OGFetcher, s as PLATFORM_COLORS, v as PLATFORM_CSS_VARS, i as ShareMenuContentClassNames, g as ShareMenuContentProps, k as ShareOption, d as ShareSheetContentClassNames, f as fetchOGData } from './platforms-B1VXTDkO.mjs';
|
|
4
4
|
import 'react';
|
|
5
5
|
|
|
6
|
-
declare function ShareSheetContent({ title, shareUrl, shareText, downloadUrl, downloadFilename, previewImage, shareFile, shareFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, onShare, onDownload, hide, show, labels, icons, }: ShareSheetContentProps): react_jsx_runtime.JSX.Element;
|
|
6
|
+
declare function ShareSheetContent({ title, shareUrl, shareText, downloadUrl, downloadFilename, previewImage, fetchPreview, shareFile, shareFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, onShare, onDownload, hide, show, labels, icons, }: ShareSheetContentProps): react_jsx_runtime.JSX.Element;
|
|
7
7
|
/** @deprecated Use ShareSheetContent instead */
|
|
8
8
|
declare const ShareMenuContent: typeof ShareSheetContent;
|
|
9
9
|
|
package/dist/content.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { S as ShareSheetContentProps } from './platforms-
|
|
3
|
-
export {
|
|
2
|
+
import { S as ShareSheetContentProps } from './platforms-B1VXTDkO.js';
|
|
3
|
+
export { o as CSS_VARS, C as CSS_VARS_UI, p as CSS_VAR_DEFAULTS, n as CSS_VAR_UI_DEFAULTS, O as OGData, a as OGFetcher, s as PLATFORM_COLORS, v as PLATFORM_CSS_VARS, i as ShareMenuContentClassNames, g as ShareMenuContentProps, k as ShareOption, d as ShareSheetContentClassNames, f as fetchOGData } from './platforms-B1VXTDkO.js';
|
|
4
4
|
import 'react';
|
|
5
5
|
|
|
6
|
-
declare function ShareSheetContent({ title, shareUrl, shareText, downloadUrl, downloadFilename, previewImage, shareFile, shareFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, onShare, onDownload, hide, show, labels, icons, }: ShareSheetContentProps): react_jsx_runtime.JSX.Element;
|
|
6
|
+
declare function ShareSheetContent({ title, shareUrl, shareText, downloadUrl, downloadFilename, previewImage, fetchPreview, shareFile, shareFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, onShare, onDownload, hide, show, labels, icons, }: ShareSheetContentProps): react_jsx_runtime.JSX.Element;
|
|
7
7
|
/** @deprecated Use ShareSheetContent instead */
|
|
8
8
|
declare const ShareMenuContent: typeof ShareSheetContent;
|
|
9
9
|
|
package/dist/content.js
CHANGED
|
@@ -27,7 +27,8 @@ __export(content_exports, {
|
|
|
27
27
|
PLATFORM_COLORS: () => PLATFORM_COLORS,
|
|
28
28
|
PLATFORM_CSS_VARS: () => PLATFORM_CSS_VARS,
|
|
29
29
|
ShareMenuContent: () => ShareMenuContent,
|
|
30
|
-
ShareSheetContent: () => ShareSheetContent
|
|
30
|
+
ShareSheetContent: () => ShareSheetContent,
|
|
31
|
+
fetchOGData: () => fetchOGData
|
|
31
32
|
});
|
|
32
33
|
module.exports = __toCommonJS(content_exports);
|
|
33
34
|
|
|
@@ -409,10 +410,14 @@ function useShareSheet({
|
|
|
409
410
|
shareReddit
|
|
410
411
|
};
|
|
411
412
|
}
|
|
412
|
-
function useOGData(url) {
|
|
413
|
+
function useOGData(url, fetcher = fetchOGData) {
|
|
413
414
|
const [ogData, setOgData] = (0, import_react.useState)(null);
|
|
414
415
|
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
415
416
|
const [error, setError] = (0, import_react.useState)(null);
|
|
417
|
+
const fetcherRef = (0, import_react.useRef)(fetcher);
|
|
418
|
+
(0, import_react.useEffect)(() => {
|
|
419
|
+
fetcherRef.current = fetcher;
|
|
420
|
+
});
|
|
416
421
|
(0, import_react.useEffect)(() => {
|
|
417
422
|
if (!url) {
|
|
418
423
|
setOgData(null);
|
|
@@ -423,7 +428,7 @@ function useOGData(url) {
|
|
|
423
428
|
let cancelled = false;
|
|
424
429
|
setLoading(true);
|
|
425
430
|
setError(null);
|
|
426
|
-
|
|
431
|
+
fetcherRef.current(url).then((data) => {
|
|
427
432
|
if (!cancelled) {
|
|
428
433
|
setOgData(data);
|
|
429
434
|
setLoading(false);
|
|
@@ -614,6 +619,7 @@ function ShareSheetContent({
|
|
|
614
619
|
downloadUrl,
|
|
615
620
|
downloadFilename,
|
|
616
621
|
previewImage,
|
|
622
|
+
fetchPreview,
|
|
617
623
|
shareFile,
|
|
618
624
|
shareFilename,
|
|
619
625
|
className,
|
|
@@ -631,7 +637,7 @@ function ShareSheetContent({
|
|
|
631
637
|
}) {
|
|
632
638
|
const [imageLoaded, setImageLoaded] = (0, import_react2.useState)(false);
|
|
633
639
|
const [imageError, setImageError] = (0, import_react2.useState)(false);
|
|
634
|
-
const { ogData, loading: ogLoading } = useOGData(previewImage ? void 0 : shareUrl);
|
|
640
|
+
const { ogData, loading: ogLoading } = useOGData(previewImage || !fetchPreview ? void 0 : shareUrl, fetchPreview);
|
|
635
641
|
const handleImageLoad = (0, import_react2.useCallback)(() => {
|
|
636
642
|
setImageLoaded(true);
|
|
637
643
|
}, []);
|
|
@@ -947,6 +953,7 @@ var ShareMenuContent = ShareSheetContent;
|
|
|
947
953
|
PLATFORM_COLORS,
|
|
948
954
|
PLATFORM_CSS_VARS,
|
|
949
955
|
ShareMenuContent,
|
|
950
|
-
ShareSheetContent
|
|
956
|
+
ShareSheetContent,
|
|
957
|
+
fetchOGData
|
|
951
958
|
});
|
|
952
959
|
//# sourceMappingURL=content.js.map
|
package/dist/content.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/content.ts","../src/ShareSheetContent.tsx","../src/utils.ts","../src/hooks.ts","../src/og-fetcher.ts","../src/share-functions.ts","../src/platforms.tsx","../src/types.ts"],"sourcesContent":["export { ShareSheetContent, ShareMenuContent } from \"./ShareSheetContent\";\nexport type { ShareSheetContentProps, ShareSheetContentClassNames, ShareMenuContentProps, ShareMenuContentClassNames, ShareOption } from \"./types\";\nexport { CSS_VARS_UI, CSS_VAR_UI_DEFAULTS, CSS_VARS, CSS_VAR_DEFAULTS } from \"./types\";\nexport { PLATFORM_COLORS, PLATFORM_CSS_VARS } from \"./platforms\";\n","\"use client\";\n\nimport { useMemo, useState, useCallback } from \"react\";\nimport { LuImage, LuLink2 } from \"react-icons/lu\";\nimport { cn } from \"./utils\";\nimport { useShareSheet, useOGData } from \"./hooks\";\nimport {\n PLATFORM_IDS,\n PLATFORM_COLORS,\n PLATFORM_LABELS,\n PLATFORM_ICONS,\n PLATFORM_CSS_VARS,\n} from \"./platforms\";\nimport {\n CSS_VARS_UI,\n CSS_VAR_UI_DEFAULTS,\n type ShareSheetContentProps,\n type ShareOption,\n type ShareButtonConfig,\n} from \"./types\";\n\nconst DEFAULT_BUTTON_SIZE = 45;\nconst DEFAULT_ICON_SIZE = 22;\n\n// Default class names\nconst defaultClasses = {\n root: \"max-w-md mx-auto\",\n header: \"text-center mb-2\",\n title: \"text-2xl font-black\",\n subtitle: \"mt-1 text-sm\",\n preview: \"flex justify-center my-4 px-4\",\n previewSkeleton: \"rounded-xl overflow-hidden\",\n previewImage: \"border border-white/10 rounded-xl\",\n previewMeta: \"\",\n grid: \"px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center\",\n button: \"flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group\",\n buttonIcon: \"p-2 rounded-full transition-all flex items-center justify-center group-hover:scale-110 group-active:scale-95 mb-2\",\n buttonLabel: \"\",\n};\n\n// Shimmer and fade-in keyframes as inline style\nconst shimmerKeyframes = `\n@keyframes sharesheet-shimmer {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(100%); }\n}\n@keyframes sharesheet-fadein {\n 0% { opacity: 0; }\n 100% { opacity: 1; }\n}\n.sharesheet-fadein {\n animation: sharesheet-fadein 0.3s ease-out forwards;\n}\n`;\n\n// Helper to create var() with fallback\nfunction cssVar(name: string, fallback: string): string {\n return `var(${name}, ${fallback})`;\n}\n\nexport function ShareSheetContent({\n title = \"Share\",\n shareUrl,\n shareText,\n downloadUrl,\n downloadFilename,\n previewImage,\n shareFile,\n shareFilename,\n className,\n classNames = {},\n buttonSize = DEFAULT_BUTTON_SIZE,\n iconSize = DEFAULT_ICON_SIZE,\n onNativeShare,\n onCopy,\n onShare,\n onDownload,\n hide = [],\n show,\n labels = {},\n icons = {},\n}: ShareSheetContentProps) {\n const [imageLoaded, setImageLoaded] = useState(false);\n const [imageError, setImageError] = useState(false);\n\n // Only fetch OG data if previewImage is not provided\n const { ogData, loading: ogLoading } = useOGData(previewImage ? undefined : shareUrl);\n\n const handleImageLoad = useCallback(() => {\n setImageLoaded(true);\n }, []);\n\n const handleImageError = useCallback(() => {\n setImageError(true);\n }, []);\n\n const shareSheet = useShareSheet({\n shareUrl,\n shareText,\n downloadUrl,\n downloadFilename,\n emailSubject: shareText,\n shareFile,\n shareFilename,\n onNativeShare,\n onCopy,\n onDownload,\n });\n\n // Map platform IDs to their share actions\n const shareActions: Record<ShareOption, () => void> = useMemo(() => ({\n native: () => void shareSheet.nativeShare(),\n copy: () => void shareSheet.copyLink(),\n download: () => void shareSheet.downloadFile(),\n whatsapp: shareSheet.shareWhatsApp,\n telegram: shareSheet.shareTelegram,\n instagram: shareSheet.shareInstagram,\n facebook: shareSheet.shareFacebook,\n snapchat: shareSheet.shareSnapchat,\n sms: shareSheet.shareSMS,\n email: shareSheet.shareEmail,\n linkedin: shareSheet.shareLinkedIn,\n reddit: shareSheet.shareReddit,\n x: shareSheet.shareX,\n tiktok: shareSheet.shareTikTok,\n threads: shareSheet.shareThreads,\n }), [shareSheet]);\n\n // Dynamic labels that depend on state\n const dynamicLabels: Partial<Record<ShareOption, string>> = useMemo(() => ({\n copy: shareSheet.copied ? \"Copied!\" : PLATFORM_LABELS.copy,\n download: shareSheet.downloading ? \"...\" : PLATFORM_LABELS.download,\n }), [shareSheet.copied, shareSheet.downloading]);\n\n // Build button configs from platform data\n const buttons: ShareButtonConfig[] = useMemo(() => {\n return PLATFORM_IDS.map((id) => {\n const Icon = PLATFORM_ICONS[id];\n const defaultLabel = dynamicLabels[id] ?? PLATFORM_LABELS[id];\n const availability = shareSheet.platformAvailability[id];\n \n // Determine if button should be shown based on various conditions\n let condition = true;\n if (id === \"native\") {\n condition = shareSheet.canNativeShare;\n } else if (id === \"download\") {\n condition = !!downloadUrl;\n } else if (!availability.available) {\n // Hide unavailable platforms (mobile-only on desktop)\n condition = false;\n }\n \n return {\n id,\n label: labels[id] ?? defaultLabel,\n icon: icons[id] ?? <Icon size={iconSize} />,\n // Use CSS var with fallback to platform color\n bgColor: cssVar(PLATFORM_CSS_VARS[id], PLATFORM_COLORS[id].bg),\n textColor: PLATFORM_COLORS[id].text,\n onClick: () => {\n onShare?.(id);\n shareActions[id]();\n },\n condition,\n };\n });\n }, [iconSize, labels, icons, dynamicLabels, shareActions, onShare, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);\n\n const visibleButtons = useMemo(() => {\n // If show is provided, use its order\n if (show && show.length > 0) {\n return show\n .map((id) => buttons.find((btn) => btn.id === id))\n .filter((btn): btn is NonNullable<typeof btn> => {\n if (!btn) return false;\n if (btn.condition === false) return false;\n if (hide.includes(btn.id)) return false;\n return true;\n });\n }\n \n // Otherwise use default order with hide filtering\n return buttons.filter((btn) => {\n if (btn.condition === false) return false;\n if (hide.includes(btn.id)) return false;\n return true;\n });\n }, [buttons, show, hide]);\n\n const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);\n const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);\n const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);\n\n // Render OG preview\n const renderPreview = () => {\n // Use previewImage if provided, otherwise use OG data\n const ogImage = previewImage || ogData?.image;\n const hasImage = ogImage && !imageError;\n const isLoading = !previewImage && ogLoading;\n\n // Loading state (only when fetching OG data, not when previewImage is provided)\n if (isLoading) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n <div\n className={cn(defaultClasses.previewSkeleton, classNames.previewSkeleton)}\n style={{\n position: \"relative\",\n backgroundColor: bgColor,\n width: \"100%\",\n maxWidth: \"320px\",\n aspectRatio: \"1.91 / 1\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ position: \"absolute\", inset: 0, overflow: \"hidden\" }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,\n animation: \"sharesheet-shimmer 1.5s infinite\",\n }}\n />\n </div>\n <LuLink2 size={32} style={{ color: textColor, opacity: 0.4 }} />\n </div>\n </div>\n );\n }\n\n // No image available - show link placeholder (skip if previewImage was provided)\n if (!hasImage) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n <div\n className={cn(defaultClasses.previewSkeleton, classNames.previewSkeleton)}\n style={{\n position: \"relative\",\n backgroundColor: bgColor,\n width: \"100%\",\n maxWidth: \"320px\",\n aspectRatio: \"1.91 / 1\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"8px\",\n padding: \"16px\",\n }}\n >\n <LuLink2 size={32} style={{ color: textColor, opacity: 0.4 }} />\n {ogData?.title && (\n <span \n style={{ \n color: textColor, \n fontSize: \"12px\", \n opacity: 0.6,\n textAlign: \"center\",\n maxWidth: \"280px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n }}\n >\n {ogData.title}\n </span>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n // If previewImage is a data URL, show it directly (no preloading needed)\n const isDataUrl = typeof ogImage === \"string\" && ogImage.startsWith(\"data:\");\n if (isDataUrl) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={ogImage}\n alt=\"Preview\"\n className={cn(defaultClasses.previewImage, classNames.previewImage)}\n style={{\n width: \"100%\",\n maxWidth: \"320px\",\n height: \"auto\",\n }}\n />\n </div>\n );\n }\n\n // Image loading state (for remote URLs)\n if (!imageLoaded) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n <div\n className={cn(defaultClasses.previewSkeleton, classNames.previewSkeleton)}\n style={{\n position: \"relative\",\n backgroundColor: bgColor,\n width: \"100%\",\n maxWidth: \"320px\",\n aspectRatio: \"1.91 / 1\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ position: \"absolute\", inset: 0, overflow: \"hidden\" }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,\n animation: \"sharesheet-shimmer 1.5s infinite\",\n }}\n />\n </div>\n <LuImage size={32} style={{ color: textColor, opacity: 0.4 }} />\n </div>\n {/* Hidden image for preloading */}\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={ogImage}\n alt={ogData?.title || \"Preview\"}\n onLoad={handleImageLoad}\n onError={handleImageError}\n style={{ display: \"none\" }}\n />\n </div>\n );\n }\n\n // Image loaded - show it with fade-in\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={ogImage}\n alt={ogData?.title || \"Preview\"}\n className={cn(defaultClasses.previewImage, classNames.previewImage, \"sharesheet-fadein\")}\n style={{\n width: \"100%\",\n maxWidth: \"320px\",\n height: \"auto\",\n }}\n />\n </div>\n );\n };\n\n return (\n <div className={cn(defaultClasses.root, classNames.root, className)}>\n {/* Inject shimmer keyframes */}\n <style dangerouslySetInnerHTML={{ __html: shimmerKeyframes }} />\n\n <div className={cn(defaultClasses.header, classNames.header)}>\n <div\n className={cn(defaultClasses.title, classNames.title)}\n style={{ color: cssVar(CSS_VARS_UI.titleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.titleColor]) }}\n >\n {title}\n </div>\n <div\n className={cn(defaultClasses.subtitle, classNames.subtitle)}\n style={{ color: cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]) }}\n >\n {shareText}\n </div>\n </div>\n\n {/* OG Preview - always shown */}\n <div className={cn(defaultClasses.preview, classNames.preview)}>\n {renderPreview()}\n </div>\n\n <div className={cn(defaultClasses.grid, classNames.grid)}>\n {visibleButtons.map((btn) => (\n <button\n key={btn.id}\n type=\"button\"\n className={cn(defaultClasses.button, classNames.button)}\n onClick={btn.onClick}\n >\n <div\n className={cn(defaultClasses.buttonIcon, classNames.buttonIcon)}\n style={{\n width: buttonSize,\n height: buttonSize,\n backgroundColor: btn.bgColor,\n color: btn.textColor,\n }}\n >\n {btn.icon}\n </div>\n <div\n className={cn(defaultClasses.buttonLabel, classNames.buttonLabel)}\n style={{ color: cssVar(CSS_VARS_UI.buttonLabelColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.buttonLabelColor]) }}\n >\n {btn.label}\n </div>\n </button>\n ))}\n </div>\n </div>\n );\n}\n\n// Legacy export for backwards compatibility\n/** @deprecated Use ShareSheetContent instead */\nexport const ShareMenuContent = ShareSheetContent;\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { ShareOption, PlatformAvailability } from \"./types\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function openUrl(url: string) {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n}\n\nexport function getSafeUrl(shareUrl: string): string {\n return shareUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n}\n\n/**\n * Detect if the current device is a mobile device.\n * Uses user agent detection as the primary method.\n */\nexport function isMobileDevice(): boolean {\n if (typeof navigator === \"undefined\") return false;\n \n const userAgent = navigator.userAgent || navigator.vendor || \"\";\n \n // Check for mobile user agents\n const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;\n \n // Also check for touch capability as a secondary signal\n const hasTouch = typeof window !== \"undefined\" && (\n \"ontouchstart\" in window ||\n navigator.maxTouchPoints > 0\n );\n \n // User agent is more reliable than touch detection alone\n // (many desktop browsers support touch)\n return mobileRegex.test(userAgent);\n}\n\n/**\n * Detect if the current device is iOS\n */\nexport function isIOSDevice(): boolean {\n if (typeof navigator === \"undefined\") return false;\n \n const userAgent = navigator.userAgent || \"\";\n return /iPhone|iPad|iPod/i.test(userAgent);\n}\n\n/**\n * Detect if the current device is Android\n */\nexport function isAndroidDevice(): boolean {\n if (typeof navigator === \"undefined\") return false;\n \n const userAgent = navigator.userAgent || \"\";\n return /Android/i.test(userAgent);\n}\n\n/** Platforms that require mobile devices (deep links / URL schemes) */\nexport const MOBILE_ONLY_PLATFORMS: readonly ShareOption[] = [\n \"instagram\",\n \"tiktok\", \n \"threads\",\n \"sms\",\n] as const;\n\n/** Platforms that work better on mobile but may partially work on desktop */\nexport const MOBILE_PREFERRED_PLATFORMS: readonly ShareOption[] = [\n \"snapchat\",\n \"whatsapp\",\n] as const;\n\n/**\n * Check if a share platform is available on the current device.\n * Returns availability status and reason if unavailable.\n */\nexport function checkPlatformAvailability(platform: ShareOption): PlatformAvailability {\n const isMobile = isMobileDevice();\n \n // Deep link platforms - require mobile device\n if (MOBILE_ONLY_PLATFORMS.includes(platform)) {\n if (!isMobile) {\n return {\n available: false,\n reason: `${platform} requires a mobile device with the app installed`,\n };\n }\n }\n \n // SMS - requires mobile or device with SMS capability\n if (platform === \"sms\" && !isMobile) {\n return {\n available: false,\n reason: \"SMS sharing requires a mobile device\",\n };\n }\n \n // Native share - check browser support\n if (platform === \"native\") {\n const canShare = typeof navigator !== \"undefined\" && \"share\" in navigator;\n if (!canShare) {\n return {\n available: false,\n reason: \"Native share is not supported by this browser\",\n };\n }\n }\n \n return { available: true };\n}\n\n/**\n * Get availability status for all platforms.\n */\nexport function getAllPlatformAvailability(): Record<ShareOption, PlatformAvailability> {\n const platforms: ShareOption[] = [\n \"native\", \"copy\", \"download\", \"whatsapp\", \"telegram\",\n \"instagram\", \"facebook\", \"snapchat\", \"sms\", \"email\",\n \"linkedin\", \"reddit\", \"x\", \"tiktok\", \"threads\",\n ];\n \n const result: Partial<Record<ShareOption, PlatformAvailability>> = {};\n for (const platform of platforms) {\n result[platform] = checkPlatformAvailability(platform);\n }\n \n return result as Record<ShareOption, PlatformAvailability>;\n}\n\n/**\n * Log a warning to console when a platform is not available.\n */\nexport function warnUnavailablePlatform(platform: ShareOption, reason: string): void {\n console.warn(\n `[react-sharesheet] ${platform} sharing is not available: ${reason}. ` +\n `This share option may not work correctly on this device.`\n );\n}\n\n","\"use client\";\n\nimport { useMemo, useState, useCallback, useEffect } from \"react\";\nimport { getSafeUrl, isMobileDevice, getAllPlatformAvailability } from \"./utils\";\nimport { fetchOGData, type OGData } from \"./og-fetcher\";\nimport {\n shareToWhatsApp,\n shareToTelegram,\n shareToX,\n shareToFacebook,\n openInstagram,\n openTikTok,\n openThreads,\n shareToSnapchat,\n shareViaSMS,\n shareViaEmail,\n shareToLinkedIn,\n shareToReddit,\n} from \"./share-functions\";\nimport type { UseShareSheetReturn, PlatformAvailability, ShareOption } from \"./types\";\n\n// Default platform availability (assumes desktop/all platforms available)\n// This is used for SSR to avoid hydration mismatch\nconst DEFAULT_PLATFORM_AVAILABILITY: Record<ShareOption, PlatformAvailability> = {\n native: { available: true },\n copy: { available: true },\n download: { available: true },\n whatsapp: { available: true },\n telegram: { available: true },\n instagram: { available: true },\n facebook: { available: true },\n snapchat: { available: true },\n sms: { available: true },\n email: { available: true },\n linkedin: { available: true },\n reddit: { available: true },\n x: { available: true },\n tiktok: { available: true },\n threads: { available: true },\n};\n\nexport interface UseShareSheetOptions {\n /** URL to share */\n shareUrl: string;\n /** Text to share */\n shareText: string;\n /** Download URL (optional) */\n downloadUrl?: string | null;\n /** Download filename (optional) */\n downloadFilename?: string;\n /** Email subject (optional) */\n emailSubject?: string;\n /** File to share via native share (data URL or Blob) - takes priority over URL sharing */\n shareFile?: string | Blob | null;\n /** Filename for the shared file */\n shareFilename?: string;\n /** Callback after native share */\n onNativeShare?: () => void;\n /** Callback after copy */\n onCopy?: () => void;\n /** Callback after download starts */\n onDownload?: () => void;\n}\n\n/**\n * Headless hook for share sheet functionality.\n * Use this to build your own custom share UI.\n */\nexport function useShareSheet({\n shareUrl,\n shareText,\n downloadUrl,\n downloadFilename,\n emailSubject = \"Share\",\n shareFile,\n shareFilename = \"share.png\",\n onNativeShare,\n onCopy,\n onDownload,\n}: UseShareSheetOptions): UseShareSheetReturn {\n const [copied, setCopied] = useState(false);\n const [downloading, setDownloading] = useState(false);\n\n // Use state for values that depend on browser APIs to avoid hydration mismatch\n // Initial values match what server renders (conservative defaults)\n const [canNativeShare, setCanNativeShare] = useState(false);\n const [isMobile, setIsMobile] = useState(false);\n const [platformAvailability, setPlatformAvailability] = useState<Record<ShareOption, PlatformAvailability>>(\n DEFAULT_PLATFORM_AVAILABILITY\n );\n\n // Detect browser capabilities after mount (client-side only)\n useEffect(() => {\n setCanNativeShare(typeof navigator !== \"undefined\" && \"share\" in navigator);\n setIsMobile(isMobileDevice());\n setPlatformAvailability(getAllPlatformAvailability());\n }, []);\n\n const safeUrl = getSafeUrl(shareUrl);\n\n const copyLink = useCallback(async () => {\n if (!safeUrl) return;\n try {\n await navigator.clipboard.writeText(safeUrl);\n setCopied(true);\n onCopy?.();\n setTimeout(() => setCopied(false), 1200);\n } catch {\n // ignore\n }\n }, [safeUrl, onCopy]);\n\n const nativeShare = useCallback(async () => {\n const nav = navigator as Navigator & {\n share?: (data: ShareData) => Promise<void>;\n canShare?: (data: ShareData) => boolean;\n };\n if (!(\"share\" in nav) || typeof nav.share !== \"function\") return;\n\n try {\n // If shareFile is provided, try to share as a file\n if (shareFile) {\n let blob: Blob;\n\n // Convert data URL to Blob if needed\n if (typeof shareFile === \"string\" && shareFile.startsWith(\"data:\")) {\n const response = await fetch(shareFile);\n blob = await response.blob();\n } else if (shareFile instanceof Blob) {\n blob = shareFile;\n } else {\n // Invalid shareFile, fall back to URL sharing\n if (!safeUrl) return;\n await nav.share({\n title: shareText,\n text: shareText,\n url: safeUrl,\n });\n onNativeShare?.();\n return;\n }\n\n // Create a File from the Blob\n const file = new File([blob], shareFilename, { type: blob.type || \"image/png\" });\n\n // Check if file sharing is supported\n const shareData: ShareData = {\n files: [file],\n title: shareText,\n text: shareText,\n };\n\n if (nav.canShare && !nav.canShare(shareData)) {\n // File sharing not supported, fall back to URL sharing\n if (!safeUrl) return;\n await nav.share({\n title: shareText,\n text: shareText,\n url: safeUrl,\n });\n onNativeShare?.();\n return;\n }\n\n await nav.share(shareData);\n onNativeShare?.();\n return;\n }\n\n // Fall back to URL sharing\n if (!safeUrl) return;\n await nav.share({\n title: shareText,\n text: shareText,\n url: safeUrl,\n });\n onNativeShare?.();\n } catch {\n // user canceled or share failed -> ignore\n }\n }, [safeUrl, shareText, shareFile, shareFilename, onNativeShare]);\n\n const downloadFile = useCallback(async () => {\n const url = (downloadUrl ?? \"\").trim();\n if (!url) return;\n try {\n setDownloading(true);\n onDownload?.();\n const res = await fetch(url);\n if (!res.ok) throw new Error(`Failed to fetch file (${res.status})`);\n const blob = await res.blob();\n const href = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = href;\n a.download = downloadFilename || \"download\";\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(href);\n } catch {\n // ignore\n } finally {\n setDownloading(false);\n }\n }, [downloadUrl, downloadFilename, onDownload]);\n\n const shareWhatsApp = useCallback(() => {\n shareToWhatsApp(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareTelegram = useCallback(() => {\n shareToTelegram(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareX = useCallback(() => {\n shareToX(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareFacebook = useCallback(() => {\n shareToFacebook(safeUrl);\n }, [safeUrl]);\n\n const shareInstagram = useCallback(() => {\n openInstagram();\n }, []);\n\n const shareTikTok = useCallback(() => {\n openTikTok();\n }, []);\n\n const shareThreads = useCallback(() => {\n openThreads();\n }, []);\n\n const shareSnapchat = useCallback(() => {\n shareToSnapchat(safeUrl);\n }, [safeUrl]);\n\n const shareSMS = useCallback(() => {\n shareViaSMS(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareEmail = useCallback(() => {\n shareViaEmail(safeUrl, shareText, emailSubject);\n }, [safeUrl, shareText, emailSubject]);\n\n const shareLinkedIn = useCallback(() => {\n shareToLinkedIn(safeUrl);\n }, [safeUrl]);\n\n const shareReddit = useCallback(() => {\n shareToReddit(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n return {\n canNativeShare,\n copied,\n downloading,\n safeUrl,\n isMobile,\n platformAvailability,\n copyLink,\n nativeShare,\n downloadFile,\n shareWhatsApp,\n shareTelegram,\n shareX,\n shareFacebook,\n shareInstagram,\n shareTikTok,\n shareThreads,\n shareSnapchat,\n shareSMS,\n shareEmail,\n shareLinkedIn,\n shareReddit,\n };\n}\n\n/**\n * Hook to fetch OG (Open Graph) data from a URL.\n * Automatically fetches and caches OG metadata for link previews.\n */\nexport function useOGData(url: string | undefined): {\n ogData: OGData | null;\n loading: boolean;\n error: string | null;\n} {\n const [ogData, setOgData] = useState<OGData | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (!url) {\n setOgData(null);\n setLoading(false);\n setError(null);\n return;\n }\n\n let cancelled = false;\n setLoading(true);\n setError(null);\n\n fetchOGData(url)\n .then((data) => {\n if (!cancelled) {\n setOgData(data);\n setLoading(false);\n }\n })\n .catch((err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : \"Failed to fetch OG data\");\n setLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [url]);\n\n return { ogData, loading, error };\n}\n\n// Legacy export for backwards compatibility\n/** @deprecated Use useShareSheet instead */\nexport const useShareMenu = useShareSheet;\n/** @deprecated Use UseShareSheetOptions instead */\nexport type UseShareMenuOptions = UseShareSheetOptions;\n","// OG Data fetcher using Microlink API (free, no API key required)\n\nexport interface OGData {\n title?: string;\n description?: string;\n image?: string;\n url?: string;\n siteName?: string;\n}\n\nexport interface OGFetchResult {\n data: OGData | null;\n loading: boolean;\n error: string | null;\n}\n\n// Cache to avoid re-fetching the same URL\nconst ogCache = new Map<string, OGData>();\n\nexport async function fetchOGData(url: string): Promise<OGData | null> {\n // Check cache first\n if (ogCache.has(url)) {\n return ogCache.get(url)!;\n }\n\n try {\n // Use Microlink API to fetch OG data (free tier, no API key needed)\n const apiUrl = `https://api.microlink.io?url=${encodeURIComponent(url)}`;\n const response = await fetch(apiUrl);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch OG data: ${response.status}`);\n }\n\n const json = await response.json();\n \n if (json.status !== \"success\" || !json.data) {\n return null;\n }\n\n const { title, description, image, url: canonicalUrl, publisher } = json.data;\n\n const ogData: OGData = {\n title: title || undefined,\n description: description || undefined,\n image: image?.url || undefined,\n url: canonicalUrl || url,\n siteName: publisher || undefined,\n };\n\n // Cache the result\n ogCache.set(url, ogData);\n\n return ogData;\n } catch (error) {\n console.warn(\"[react-sharesheet] Failed to fetch OG data:\", error);\n return null;\n }\n}\n\n// Clear cache (useful for testing or forcing refresh)\nexport function clearOGCache(): void {\n ogCache.clear();\n}\n","import { \n openUrl, \n checkPlatformAvailability, \n warnUnavailablePlatform,\n} from \"./utils\";\n\nexport function shareToWhatsApp(url: string, text: string) {\n const encoded = encodeURIComponent(`${text}\\n${url}`);\n openUrl(`https://api.whatsapp.com/send?text=${encoded}`);\n}\n\nexport function shareToTelegram(url: string, text: string) {\n const encodedText = encodeURIComponent(text);\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://t.me/share/url?url=${encodedUrl}&text=${encodedText}`);\n}\n\nexport function shareToX(url: string, text: string) {\n const encodedText = encodeURIComponent(text);\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://x.com/intent/tweet?text=${encodedText}&url=${encodedUrl}`);\n}\n\nexport function shareToFacebook(url: string) {\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`);\n}\n\nexport function openInstagram() {\n const availability = checkPlatformAvailability(\"instagram\");\n if (!availability.available) {\n warnUnavailablePlatform(\"instagram\", availability.reason!);\n // Still attempt to open - it may work on some desktop browsers with app installed\n }\n window.location.href = \"instagram://\";\n}\n\nexport function openTikTok() {\n const availability = checkPlatformAvailability(\"tiktok\");\n if (!availability.available) {\n warnUnavailablePlatform(\"tiktok\", availability.reason!);\n // Still attempt to open - it may work on some desktop browsers with app installed\n }\n window.location.href = \"tiktok://\";\n}\n\nexport function openThreads() {\n const availability = checkPlatformAvailability(\"threads\");\n if (!availability.available) {\n warnUnavailablePlatform(\"threads\", availability.reason!);\n // Still attempt to open - it may work on some desktop browsers with app installed\n }\n window.location.href = \"threads://\";\n}\n\nexport function shareToSnapchat(url: string) {\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.snapchat.com/scan?attachmentUrl=${encodedUrl}`);\n}\n\nexport function shareViaSMS(url: string, text: string) {\n const availability = checkPlatformAvailability(\"sms\");\n if (!availability.available) {\n warnUnavailablePlatform(\"sms\", availability.reason!);\n // Still attempt to open - it may work on some devices\n }\n const body = encodeURIComponent(`${text}\\n${url}`);\n window.location.href = `sms:?body=${body}`;\n}\n\nexport function shareViaEmail(url: string, text: string, subject = \"Share\") {\n const encodedSubject = encodeURIComponent(subject);\n const body = encodeURIComponent(`${text}\\n\\n${url}`);\n window.location.href = `mailto:?subject=${encodedSubject}&body=${body}`;\n}\n\nexport function shareToLinkedIn(url: string) {\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`);\n}\n\nexport function shareToReddit(url: string, text: string) {\n const encodedText = encodeURIComponent(text);\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.reddit.com/submit?url=${encodedUrl}&title=${encodedText}`);\n}\n\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n LuDownload,\n LuLink,\n LuMail,\n LuMessageCircle,\n LuSend,\n} from \"react-icons/lu\";\nimport {\n FaFacebookF,\n FaInstagram,\n FaLinkedin,\n FaReddit,\n FaTelegramPlane,\n FaTiktok,\n FaWhatsapp,\n} from \"react-icons/fa\";\nimport { FaXTwitter, FaThreads, FaSnapchat } from \"react-icons/fa6\";\nimport type { ShareOption } from \"./types\";\n\n/** Platform color configuration */\nexport interface PlatformColor {\n /** Background color (hex) */\n bg: string;\n /** Text/icon color (hex) */\n text: string;\n}\n\n/** Platform configuration */\nexport interface PlatformConfig {\n /** Platform identifier */\n id: ShareOption;\n /** Display label */\n label: string;\n /** Colors */\n colors: PlatformColor;\n /** Icon component (accepts size prop) */\n Icon: (props: { size?: number; className?: string }) => ReactNode;\n /** CSS variable name for background */\n cssVar: string;\n}\n\n/** All platform IDs in default order */\nexport const PLATFORM_IDS: readonly ShareOption[] = [\n \"native\",\n \"copy\",\n \"download\",\n \"whatsapp\",\n \"telegram\",\n \"instagram\",\n \"facebook\",\n \"snapchat\",\n \"sms\",\n \"email\",\n \"linkedin\",\n \"reddit\",\n \"x\",\n \"tiktok\",\n \"threads\",\n] as const;\n\n/** Platform colors - hex values for each platform (SOURCE OF TRUTH) */\nexport const PLATFORM_COLORS: Record<ShareOption, PlatformColor> = {\n native: { bg: \"#7c3aed\", text: \"#ffffff\" },\n copy: { bg: \"#3b82f6\", text: \"#ffffff\" },\n download: { bg: \"#ef4444\", text: \"#ffffff\" },\n whatsapp: { bg: \"#25D366\", text: \"#ffffff\" },\n telegram: { bg: \"#229ED9\", text: \"#ffffff\" },\n instagram: { bg: \"#E1306C\", text: \"#ffffff\" },\n facebook: { bg: \"#1877F2\", text: \"#ffffff\" },\n snapchat: { bg: \"#FFFC00\", text: \"#000000\" },\n sms: { bg: \"#22c55e\", text: \"#ffffff\" },\n email: { bg: \"#f97316\", text: \"#ffffff\" },\n linkedin: { bg: \"#0A66C2\", text: \"#ffffff\" },\n reddit: { bg: \"#FF4500\", text: \"#ffffff\" },\n x: { bg: \"#000000\", text: \"#ffffff\" },\n tiktok: { bg: \"#000000\", text: \"#ffffff\" },\n threads: { bg: \"#000000\", text: \"#ffffff\" },\n} as const;\n\n/** Platform labels (SOURCE OF TRUTH) */\nexport const PLATFORM_LABELS: Record<ShareOption, string> = {\n native: \"Share…\",\n copy: \"Copy\",\n download: \"Download\",\n whatsapp: \"WhatsApp\",\n telegram: \"Telegram\",\n instagram: \"Instagram\",\n facebook: \"Facebook\",\n snapchat: \"Snapchat\",\n sms: \"SMS\",\n email: \"Email\",\n linkedin: \"LinkedIn\",\n reddit: \"Reddit\",\n x: \"X\",\n tiktok: \"TikTok\",\n threads: \"Threads\",\n} as const;\n\n/** Platform icons - React components (SOURCE OF TRUTH) */\nexport const PLATFORM_ICONS: Record<ShareOption, (props: { size?: number; className?: string }) => ReactNode> = {\n native: ({ size = 22, className }) => <LuSend size={size} className={className} />,\n copy: ({ size = 22, className }) => <LuLink size={size} className={className} />,\n download: ({ size = 22, className }) => <LuDownload size={size} className={className} />,\n whatsapp: ({ size = 22, className }) => <FaWhatsapp size={size} className={className} />,\n telegram: ({ size = 22, className }) => <FaTelegramPlane size={size} className={className} />,\n instagram: ({ size = 22, className }) => <FaInstagram size={size} className={className} />,\n facebook: ({ size = 22, className }) => <FaFacebookF size={size} className={className} />,\n snapchat: ({ size = 22, className }) => <FaSnapchat size={size} className={className} />,\n sms: ({ size = 22, className }) => <LuMessageCircle size={size} className={className} />,\n email: ({ size = 22, className }) => <LuMail size={size} className={className} />,\n linkedin: ({ size = 22, className }) => <FaLinkedin size={size} className={className} />,\n reddit: ({ size = 22, className }) => <FaReddit size={size} className={className} />,\n x: ({ size = 22, className }) => <FaXTwitter size={size} className={className} />,\n tiktok: ({ size = 22, className }) => <FaTiktok size={size} className={className} />,\n threads: ({ size = 22, className }) => <FaThreads size={size} className={className} />,\n} as const;\n\n/** CSS variable names for platform backgrounds */\nexport const PLATFORM_CSS_VARS: Record<ShareOption, string> = {\n native: \"--sharesheet-native-bg\",\n copy: \"--sharesheet-copy-bg\",\n download: \"--sharesheet-download-bg\",\n whatsapp: \"--sharesheet-whatsapp-bg\",\n telegram: \"--sharesheet-telegram-bg\",\n instagram: \"--sharesheet-instagram-bg\",\n facebook: \"--sharesheet-facebook-bg\",\n snapchat: \"--sharesheet-snapchat-bg\",\n sms: \"--sharesheet-sms-bg\",\n email: \"--sharesheet-email-bg\",\n linkedin: \"--sharesheet-linkedin-bg\",\n reddit: \"--sharesheet-reddit-bg\",\n x: \"--sharesheet-x-bg\",\n tiktok: \"--sharesheet-tiktok-bg\",\n threads: \"--sharesheet-threads-bg\",\n} as const;\n\n/** Full platform configurations */\nexport const PLATFORMS: Record<ShareOption, PlatformConfig> = Object.fromEntries(\n PLATFORM_IDS.map((id) => [\n id,\n {\n id,\n label: PLATFORM_LABELS[id],\n colors: PLATFORM_COLORS[id],\n Icon: PLATFORM_ICONS[id],\n cssVar: PLATFORM_CSS_VARS[id],\n },\n ])\n) as Record<ShareOption, PlatformConfig>;\n\n/** Get platform config by id */\nexport function getPlatform(id: ShareOption): PlatformConfig {\n return PLATFORMS[id];\n}\n\n/** Get all platform configs as array */\nexport function getAllPlatforms(): PlatformConfig[] {\n return PLATFORM_IDS.map((id) => PLATFORMS[id]);\n}\n\n/** Get platform color */\nexport function getPlatformColor(id: ShareOption): PlatformColor {\n return PLATFORM_COLORS[id];\n}\n\n/** Get platform icon component */\nexport function getPlatformIcon(id: ShareOption): (props: { size?: number; className?: string }) => ReactNode {\n return PLATFORM_ICONS[id];\n}\n\n/** Get platform label */\nexport function getPlatformLabel(id: ShareOption): string {\n return PLATFORM_LABELS[id];\n}\n\n/** Generate CSS variable defaults from platform colors */\nexport function generateCssVarDefaults(): Record<string, string> {\n const defaults: Record<string, string> = {};\n PLATFORM_IDS.forEach((id) => {\n defaults[PLATFORM_CSS_VARS[id]] = PLATFORM_COLORS[id].bg;\n });\n return defaults;\n}\n","import type { ReactNode } from \"react\";\n\n/** CSS variable names for UI elements (non-platform specific) */\nexport const CSS_VARS_UI = {\n // Drawer\n overlayBg: \"--sharesheet-overlay-bg\",\n drawerBg: \"--sharesheet-drawer-bg\",\n drawerBorder: \"--sharesheet-drawer-border\",\n handleBg: \"--sharesheet-handle-bg\",\n // Content\n titleColor: \"--sharesheet-title-color\",\n subtitleColor: \"--sharesheet-subtitle-color\",\n buttonLabelColor: \"--sharesheet-button-label-color\",\n // Preview\n previewBg: \"--sharesheet-preview-bg\",\n previewShimmer: \"--sharesheet-preview-shimmer\",\n} as const;\n\n/** Default values for UI CSS variables */\nexport const CSS_VAR_UI_DEFAULTS = {\n [CSS_VARS_UI.overlayBg]: \"rgba(0, 0, 0, 0.7)\",\n [CSS_VARS_UI.drawerBg]: \"#09090b\",\n [CSS_VARS_UI.drawerBorder]: \"#27272a\",\n [CSS_VARS_UI.handleBg]: \"rgba(255, 255, 255, 0.2)\",\n [CSS_VARS_UI.titleColor]: \"#ffffff\",\n [CSS_VARS_UI.subtitleColor]: \"#a1a1aa\",\n [CSS_VARS_UI.buttonLabelColor]: \"#ffffff\",\n [CSS_VARS_UI.previewBg]: \"rgba(255, 255, 255, 0.05)\",\n [CSS_VARS_UI.previewShimmer]: \"rgba(255, 255, 255, 0.1)\",\n} as const;\n\n/** Available share options */\nexport type ShareOption =\n | \"native\"\n | \"copy\"\n | \"download\"\n | \"whatsapp\"\n | \"telegram\"\n | \"instagram\"\n | \"facebook\"\n | \"snapchat\"\n | \"sms\"\n | \"email\"\n | \"linkedin\"\n | \"reddit\"\n | \"x\"\n | \"tiktok\"\n | \"threads\";\n\n/** Class name overrides for ShareSheetContent */\nexport interface ShareSheetContentClassNames {\n /** Root container */\n root?: string;\n /** Title container */\n header?: string;\n /** Main title text */\n title?: string;\n /** Subtitle/share text */\n subtitle?: string;\n /** Preview container */\n preview?: string;\n /** Preview skeleton/loading wrapper */\n previewSkeleton?: string;\n /** Preview image element */\n previewImage?: string;\n /** Preview video element */\n previewVideo?: string;\n /** Preview file/audio container */\n previewFile?: string;\n /** Preview file icon */\n previewFileIcon?: string;\n /** Preview filename text */\n previewFilename?: string;\n /** Preview link container */\n previewLink?: string;\n /** Buttons grid container */\n grid?: string;\n /** Individual button wrapper */\n button?: string;\n /** Button icon container */\n buttonIcon?: string;\n /** Button label text */\n buttonLabel?: string;\n}\n\n/** Class name overrides for ShareSheetDrawer */\nexport interface ShareSheetDrawerClassNames extends ShareSheetContentClassNames {\n /** Drawer overlay */\n overlay?: string;\n /** Drawer content panel */\n drawer?: string;\n /** Drawer inner content wrapper */\n drawerInner?: string;\n /** Drawer handle */\n handle?: string;\n /** Trigger wrapper */\n trigger?: string;\n}\n\nexport interface ShareSheetContentProps {\n /** Title displayed at the top of the sheet */\n title?: string;\n /** URL to share (OG preview will be fetched automatically) */\n shareUrl: string;\n /** Text to share alongside the URL */\n shareText: string;\n /** Optional URL for download functionality */\n downloadUrl?: string | null;\n /** Filename for downloaded file */\n downloadFilename?: string;\n /** Custom preview image URL (skips OG fetching if provided) */\n previewImage?: string | null;\n /** File to share via native share (data URL or Blob) - takes priority over URL sharing */\n shareFile?: string | Blob | null;\n /** Filename for the shared file */\n shareFilename?: string;\n /** Custom class name for the container (shorthand for classNames.root) */\n className?: string;\n /** Override class names for sub-components */\n classNames?: ShareSheetContentClassNames;\n /** Button size in pixels */\n buttonSize?: number;\n /** Icon size in pixels */\n iconSize?: number;\n /** Called when native share is triggered */\n onNativeShare?: () => void;\n /** Called when link is copied */\n onCopy?: () => void;\n /** Called when download starts */\n onDownload?: () => void;\n /** Called on every share option click, with the option id (analytics-friendly) */\n onShare?: (option: ShareOption) => void;\n /** Hide specific share options */\n hide?: ShareOption[];\n /** Show only these platforms, in this exact order */\n show?: ShareOption[];\n /** Custom labels for buttons */\n labels?: Partial<Record<ShareOption, string>>;\n /** Custom icons for buttons */\n icons?: Partial<Record<ShareOption, ReactNode>>;\n}\n\nexport interface ShareSheetDrawerProps extends ShareSheetContentProps {\n /** Whether the drawer is disabled */\n disabled?: boolean;\n /** Trigger element for the drawer */\n children: React.ReactNode;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Override class names for sub-components */\n classNames?: ShareSheetDrawerClassNames;\n}\n\n/** Share button configuration (internal) */\nexport interface ShareButtonConfig {\n id: ShareOption;\n label: string;\n icon: ReactNode;\n bgColor: string;\n textColor?: string;\n onClick: () => void;\n condition?: boolean;\n}\n\n/** Platform availability status */\nexport interface PlatformAvailability {\n /** Whether the platform is available on this device */\n available: boolean;\n /** Reason why platform is unavailable (if applicable) */\n reason?: string;\n}\n\n/** Return type of useShareSheet hook */\nexport interface UseShareSheetReturn {\n /** Whether the browser supports native share */\n canNativeShare: boolean;\n /** Whether the link was recently copied */\n copied: boolean;\n /** Whether a download is in progress */\n downloading: boolean;\n /** The safe URL (falls back to current page URL) */\n safeUrl: string;\n /** Whether the current device is mobile */\n isMobile: boolean;\n /** Availability status for each platform */\n platformAvailability: Record<ShareOption, PlatformAvailability>;\n /** Copy the share URL to clipboard */\n copyLink: () => Promise<void>;\n /** Trigger native share dialog */\n nativeShare: () => Promise<void>;\n /** Download the file from downloadUrl */\n downloadFile: () => Promise<void>;\n /** Share to WhatsApp */\n shareWhatsApp: () => void;\n /** Share to Telegram */\n shareTelegram: () => void;\n /** Share to X (Twitter) */\n shareX: () => void;\n /** Share to Facebook */\n shareFacebook: () => void;\n /** Open Instagram app (mobile only - will warn on desktop) */\n shareInstagram: () => void;\n /** Open TikTok app (mobile only - will warn on desktop) */\n shareTikTok: () => void;\n /** Open Threads app (mobile only - will warn on desktop) */\n shareThreads: () => void;\n /** Share to Snapchat */\n shareSnapchat: () => void;\n /** Share via SMS (mobile only - will warn on desktop) */\n shareSMS: () => void;\n /** Share via Email */\n shareEmail: () => void;\n /** Share to LinkedIn */\n shareLinkedIn: () => void;\n /** Share to Reddit */\n shareReddit: () => void;\n}\n\n// Legacy exports for backwards compatibility\n/** @deprecated Use CSS_VARS_UI instead */\nexport const CSS_VARS = CSS_VARS_UI;\n/** @deprecated Use CSS_VAR_UI_DEFAULTS instead */\nexport const CSS_VAR_DEFAULTS = CSS_VAR_UI_DEFAULTS;\n\n// Legacy type aliases for backwards compatibility\n/** @deprecated Use ShareSheetContentClassNames instead */\nexport type ShareMenuContentClassNames = ShareSheetContentClassNames;\n/** @deprecated Use ShareSheetDrawerClassNames instead */\nexport type ShareMenuDrawerClassNames = ShareSheetDrawerClassNames;\n/** @deprecated Use ShareSheetContentProps instead */\nexport type ShareMenuContentProps = ShareSheetContentProps;\n/** @deprecated Use ShareSheetDrawerProps instead */\nexport type ShareMenuDrawerProps = ShareSheetDrawerProps;\n/** @deprecated Use UseShareSheetReturn instead */\nexport type UseShareMenuReturn = UseShareSheetReturn;\n"],"mappings":"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","names":["import_react","import_lu","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/content.ts","../src/ShareSheetContent.tsx","../src/utils.ts","../src/hooks.ts","../src/og-fetcher.ts","../src/share-functions.ts","../src/platforms.tsx","../src/types.ts"],"sourcesContent":["export { ShareSheetContent, ShareMenuContent } from \"./ShareSheetContent\";\nexport type { ShareSheetContentProps, ShareSheetContentClassNames, ShareMenuContentProps, ShareMenuContentClassNames, ShareOption } from \"./types\";\nexport { CSS_VARS_UI, CSS_VAR_UI_DEFAULTS, CSS_VARS, CSS_VAR_DEFAULTS } from \"./types\";\nexport { PLATFORM_COLORS, PLATFORM_CSS_VARS } from \"./platforms\";\nexport { fetchOGData, type OGData, type OGFetcher } from \"./og-fetcher\";\n","\"use client\";\n\nimport { useMemo, useState, useCallback } from \"react\";\nimport { LuImage, LuLink2 } from \"react-icons/lu\";\nimport { cn } from \"./utils\";\nimport { useShareSheet, useOGData } from \"./hooks\";\nimport {\n PLATFORM_IDS,\n PLATFORM_COLORS,\n PLATFORM_LABELS,\n PLATFORM_ICONS,\n PLATFORM_CSS_VARS,\n} from \"./platforms\";\nimport {\n CSS_VARS_UI,\n CSS_VAR_UI_DEFAULTS,\n type ShareSheetContentProps,\n type ShareOption,\n type ShareButtonConfig,\n} from \"./types\";\n\nconst DEFAULT_BUTTON_SIZE = 45;\nconst DEFAULT_ICON_SIZE = 22;\n\n// Default class names\nconst defaultClasses = {\n root: \"max-w-md mx-auto\",\n header: \"text-center mb-2\",\n title: \"text-2xl font-black\",\n subtitle: \"mt-1 text-sm\",\n preview: \"flex justify-center my-4 px-4\",\n previewSkeleton: \"rounded-xl overflow-hidden\",\n previewImage: \"border border-white/10 rounded-xl\",\n previewMeta: \"\",\n grid: \"px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center\",\n button: \"flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group\",\n buttonIcon: \"p-2 rounded-full transition-all flex items-center justify-center group-hover:scale-110 group-active:scale-95 mb-2\",\n buttonLabel: \"\",\n};\n\n// Shimmer and fade-in keyframes as inline style\nconst shimmerKeyframes = `\n@keyframes sharesheet-shimmer {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(100%); }\n}\n@keyframes sharesheet-fadein {\n 0% { opacity: 0; }\n 100% { opacity: 1; }\n}\n.sharesheet-fadein {\n animation: sharesheet-fadein 0.3s ease-out forwards;\n}\n`;\n\n// Helper to create var() with fallback\nfunction cssVar(name: string, fallback: string): string {\n return `var(${name}, ${fallback})`;\n}\n\nexport function ShareSheetContent({\n title = \"Share\",\n shareUrl,\n shareText,\n downloadUrl,\n downloadFilename,\n previewImage,\n fetchPreview,\n shareFile,\n shareFilename,\n className,\n classNames = {},\n buttonSize = DEFAULT_BUTTON_SIZE,\n iconSize = DEFAULT_ICON_SIZE,\n onNativeShare,\n onCopy,\n onShare,\n onDownload,\n hide = [],\n show,\n labels = {},\n icons = {},\n}: ShareSheetContentProps) {\n const [imageLoaded, setImageLoaded] = useState(false);\n const [imageError, setImageError] = useState(false);\n\n // Only look the link up when there is no previewImage and the caller opted in: the lookup\n // sends shareUrl somewhere else\n const { ogData, loading: ogLoading } = useOGData(previewImage || !fetchPreview ? undefined : shareUrl, fetchPreview);\n\n const handleImageLoad = useCallback(() => {\n setImageLoaded(true);\n }, []);\n\n const handleImageError = useCallback(() => {\n setImageError(true);\n }, []);\n\n const shareSheet = useShareSheet({\n shareUrl,\n shareText,\n downloadUrl,\n downloadFilename,\n emailSubject: shareText,\n shareFile,\n shareFilename,\n onNativeShare,\n onCopy,\n onDownload,\n });\n\n // Map platform IDs to their share actions\n const shareActions: Record<ShareOption, () => void> = useMemo(() => ({\n native: () => void shareSheet.nativeShare(),\n copy: () => void shareSheet.copyLink(),\n download: () => void shareSheet.downloadFile(),\n whatsapp: shareSheet.shareWhatsApp,\n telegram: shareSheet.shareTelegram,\n instagram: shareSheet.shareInstagram,\n facebook: shareSheet.shareFacebook,\n snapchat: shareSheet.shareSnapchat,\n sms: shareSheet.shareSMS,\n email: shareSheet.shareEmail,\n linkedin: shareSheet.shareLinkedIn,\n reddit: shareSheet.shareReddit,\n x: shareSheet.shareX,\n tiktok: shareSheet.shareTikTok,\n threads: shareSheet.shareThreads,\n }), [shareSheet]);\n\n // Dynamic labels that depend on state\n const dynamicLabels: Partial<Record<ShareOption, string>> = useMemo(() => ({\n copy: shareSheet.copied ? \"Copied!\" : PLATFORM_LABELS.copy,\n download: shareSheet.downloading ? \"...\" : PLATFORM_LABELS.download,\n }), [shareSheet.copied, shareSheet.downloading]);\n\n // Build button configs from platform data\n const buttons: ShareButtonConfig[] = useMemo(() => {\n return PLATFORM_IDS.map((id) => {\n const Icon = PLATFORM_ICONS[id];\n const defaultLabel = dynamicLabels[id] ?? PLATFORM_LABELS[id];\n const availability = shareSheet.platformAvailability[id];\n \n // Determine if button should be shown based on various conditions\n let condition = true;\n if (id === \"native\") {\n condition = shareSheet.canNativeShare;\n } else if (id === \"download\") {\n condition = !!downloadUrl;\n } else if (!availability.available) {\n // Hide unavailable platforms (mobile-only on desktop)\n condition = false;\n }\n \n return {\n id,\n label: labels[id] ?? defaultLabel,\n icon: icons[id] ?? <Icon size={iconSize} />,\n // Use CSS var with fallback to platform color\n bgColor: cssVar(PLATFORM_CSS_VARS[id], PLATFORM_COLORS[id].bg),\n textColor: PLATFORM_COLORS[id].text,\n onClick: () => {\n onShare?.(id);\n shareActions[id]();\n },\n condition,\n };\n });\n }, [iconSize, labels, icons, dynamicLabels, shareActions, onShare, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);\n\n const visibleButtons = useMemo(() => {\n // If show is provided, use its order\n if (show && show.length > 0) {\n return show\n .map((id) => buttons.find((btn) => btn.id === id))\n .filter((btn): btn is NonNullable<typeof btn> => {\n if (!btn) return false;\n if (btn.condition === false) return false;\n if (hide.includes(btn.id)) return false;\n return true;\n });\n }\n \n // Otherwise use default order with hide filtering\n return buttons.filter((btn) => {\n if (btn.condition === false) return false;\n if (hide.includes(btn.id)) return false;\n return true;\n });\n }, [buttons, show, hide]);\n\n const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);\n const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);\n const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);\n\n // Render OG preview\n const renderPreview = () => {\n // Use previewImage if provided, otherwise use OG data\n const ogImage = previewImage || ogData?.image;\n const hasImage = ogImage && !imageError;\n const isLoading = !previewImage && ogLoading;\n\n // Loading state (only when fetching OG data, not when previewImage is provided)\n if (isLoading) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n <div\n className={cn(defaultClasses.previewSkeleton, classNames.previewSkeleton)}\n style={{\n position: \"relative\",\n backgroundColor: bgColor,\n width: \"100%\",\n maxWidth: \"320px\",\n aspectRatio: \"1.91 / 1\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ position: \"absolute\", inset: 0, overflow: \"hidden\" }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,\n animation: \"sharesheet-shimmer 1.5s infinite\",\n }}\n />\n </div>\n <LuLink2 size={32} style={{ color: textColor, opacity: 0.4 }} />\n </div>\n </div>\n );\n }\n\n // No image available - show link placeholder (skip if previewImage was provided)\n if (!hasImage) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n <div\n className={cn(defaultClasses.previewSkeleton, classNames.previewSkeleton)}\n style={{\n position: \"relative\",\n backgroundColor: bgColor,\n width: \"100%\",\n maxWidth: \"320px\",\n aspectRatio: \"1.91 / 1\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"8px\",\n padding: \"16px\",\n }}\n >\n <LuLink2 size={32} style={{ color: textColor, opacity: 0.4 }} />\n {ogData?.title && (\n <span \n style={{ \n color: textColor, \n fontSize: \"12px\", \n opacity: 0.6,\n textAlign: \"center\",\n maxWidth: \"280px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n }}\n >\n {ogData.title}\n </span>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n // If previewImage is a data URL, show it directly (no preloading needed)\n const isDataUrl = typeof ogImage === \"string\" && ogImage.startsWith(\"data:\");\n if (isDataUrl) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={ogImage}\n alt=\"Preview\"\n className={cn(defaultClasses.previewImage, classNames.previewImage)}\n style={{\n width: \"100%\",\n maxWidth: \"320px\",\n height: \"auto\",\n }}\n />\n </div>\n );\n }\n\n // Image loading state (for remote URLs)\n if (!imageLoaded) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n <div\n className={cn(defaultClasses.previewSkeleton, classNames.previewSkeleton)}\n style={{\n position: \"relative\",\n backgroundColor: bgColor,\n width: \"100%\",\n maxWidth: \"320px\",\n aspectRatio: \"1.91 / 1\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ position: \"absolute\", inset: 0, overflow: \"hidden\" }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,\n animation: \"sharesheet-shimmer 1.5s infinite\",\n }}\n />\n </div>\n <LuImage size={32} style={{ color: textColor, opacity: 0.4 }} />\n </div>\n {/* Hidden image for preloading */}\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={ogImage}\n alt={ogData?.title || \"Preview\"}\n onLoad={handleImageLoad}\n onError={handleImageError}\n style={{ display: \"none\" }}\n />\n </div>\n );\n }\n\n // Image loaded - show it with fade-in\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", width: \"100%\" }}>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={ogImage}\n alt={ogData?.title || \"Preview\"}\n className={cn(defaultClasses.previewImage, classNames.previewImage, \"sharesheet-fadein\")}\n style={{\n width: \"100%\",\n maxWidth: \"320px\",\n height: \"auto\",\n }}\n />\n </div>\n );\n };\n\n return (\n <div className={cn(defaultClasses.root, classNames.root, className)}>\n {/* Inject shimmer keyframes */}\n <style dangerouslySetInnerHTML={{ __html: shimmerKeyframes }} />\n\n <div className={cn(defaultClasses.header, classNames.header)}>\n <div\n className={cn(defaultClasses.title, classNames.title)}\n style={{ color: cssVar(CSS_VARS_UI.titleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.titleColor]) }}\n >\n {title}\n </div>\n <div\n className={cn(defaultClasses.subtitle, classNames.subtitle)}\n style={{ color: cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]) }}\n >\n {shareText}\n </div>\n </div>\n\n {/* OG Preview - always shown */}\n <div className={cn(defaultClasses.preview, classNames.preview)}>\n {renderPreview()}\n </div>\n\n <div className={cn(defaultClasses.grid, classNames.grid)}>\n {visibleButtons.map((btn) => (\n <button\n key={btn.id}\n type=\"button\"\n className={cn(defaultClasses.button, classNames.button)}\n onClick={btn.onClick}\n >\n <div\n className={cn(defaultClasses.buttonIcon, classNames.buttonIcon)}\n style={{\n width: buttonSize,\n height: buttonSize,\n backgroundColor: btn.bgColor,\n color: btn.textColor,\n }}\n >\n {btn.icon}\n </div>\n <div\n className={cn(defaultClasses.buttonLabel, classNames.buttonLabel)}\n style={{ color: cssVar(CSS_VARS_UI.buttonLabelColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.buttonLabelColor]) }}\n >\n {btn.label}\n </div>\n </button>\n ))}\n </div>\n </div>\n );\n}\n\n// Legacy export for backwards compatibility\n/** @deprecated Use ShareSheetContent instead */\nexport const ShareMenuContent = ShareSheetContent;\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { ShareOption, PlatformAvailability } from \"./types\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function openUrl(url: string) {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n}\n\nexport function getSafeUrl(shareUrl: string): string {\n return shareUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n}\n\n/**\n * Detect if the current device is a mobile device.\n * Uses user agent detection as the primary method.\n */\nexport function isMobileDevice(): boolean {\n if (typeof navigator === \"undefined\") return false;\n \n const userAgent = navigator.userAgent || navigator.vendor || \"\";\n \n // Check for mobile user agents\n const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;\n \n // Also check for touch capability as a secondary signal\n const hasTouch = typeof window !== \"undefined\" && (\n \"ontouchstart\" in window ||\n navigator.maxTouchPoints > 0\n );\n \n // User agent is more reliable than touch detection alone\n // (many desktop browsers support touch)\n return mobileRegex.test(userAgent);\n}\n\n/**\n * Detect if the current device is iOS\n */\nexport function isIOSDevice(): boolean {\n if (typeof navigator === \"undefined\") return false;\n \n const userAgent = navigator.userAgent || \"\";\n return /iPhone|iPad|iPod/i.test(userAgent);\n}\n\n/**\n * Detect if the current device is Android\n */\nexport function isAndroidDevice(): boolean {\n if (typeof navigator === \"undefined\") return false;\n \n const userAgent = navigator.userAgent || \"\";\n return /Android/i.test(userAgent);\n}\n\n/** Platforms that require mobile devices (deep links / URL schemes) */\nexport const MOBILE_ONLY_PLATFORMS: readonly ShareOption[] = [\n \"instagram\",\n \"tiktok\", \n \"threads\",\n \"sms\",\n] as const;\n\n/** Platforms that work better on mobile but may partially work on desktop */\nexport const MOBILE_PREFERRED_PLATFORMS: readonly ShareOption[] = [\n \"snapchat\",\n \"whatsapp\",\n] as const;\n\n/**\n * Check if a share platform is available on the current device.\n * Returns availability status and reason if unavailable.\n */\nexport function checkPlatformAvailability(platform: ShareOption): PlatformAvailability {\n const isMobile = isMobileDevice();\n \n // Deep link platforms - require mobile device\n if (MOBILE_ONLY_PLATFORMS.includes(platform)) {\n if (!isMobile) {\n return {\n available: false,\n reason: `${platform} requires a mobile device with the app installed`,\n };\n }\n }\n \n // SMS - requires mobile or device with SMS capability\n if (platform === \"sms\" && !isMobile) {\n return {\n available: false,\n reason: \"SMS sharing requires a mobile device\",\n };\n }\n \n // Native share - check browser support\n if (platform === \"native\") {\n const canShare = typeof navigator !== \"undefined\" && \"share\" in navigator;\n if (!canShare) {\n return {\n available: false,\n reason: \"Native share is not supported by this browser\",\n };\n }\n }\n \n return { available: true };\n}\n\n/**\n * Get availability status for all platforms.\n */\nexport function getAllPlatformAvailability(): Record<ShareOption, PlatformAvailability> {\n const platforms: ShareOption[] = [\n \"native\", \"copy\", \"download\", \"whatsapp\", \"telegram\",\n \"instagram\", \"facebook\", \"snapchat\", \"sms\", \"email\",\n \"linkedin\", \"reddit\", \"x\", \"tiktok\", \"threads\",\n ];\n \n const result: Partial<Record<ShareOption, PlatformAvailability>> = {};\n for (const platform of platforms) {\n result[platform] = checkPlatformAvailability(platform);\n }\n \n return result as Record<ShareOption, PlatformAvailability>;\n}\n\n/**\n * Log a warning to console when a platform is not available.\n */\nexport function warnUnavailablePlatform(platform: ShareOption, reason: string): void {\n console.warn(\n `[react-sharesheet] ${platform} sharing is not available: ${reason}. ` +\n `This share option may not work correctly on this device.`\n );\n}\n\n","\"use client\";\n\nimport { useMemo, useState, useCallback, useEffect, useRef } from \"react\";\nimport { getSafeUrl, isMobileDevice, getAllPlatformAvailability } from \"./utils\";\nimport { fetchOGData, type OGData, type OGFetcher } from \"./og-fetcher\";\nimport {\n shareToWhatsApp,\n shareToTelegram,\n shareToX,\n shareToFacebook,\n openInstagram,\n openTikTok,\n openThreads,\n shareToSnapchat,\n shareViaSMS,\n shareViaEmail,\n shareToLinkedIn,\n shareToReddit,\n} from \"./share-functions\";\nimport type { UseShareSheetReturn, PlatformAvailability, ShareOption } from \"./types\";\n\n// Default platform availability (assumes desktop/all platforms available)\n// This is used for SSR to avoid hydration mismatch\nconst DEFAULT_PLATFORM_AVAILABILITY: Record<ShareOption, PlatformAvailability> = {\n native: { available: true },\n copy: { available: true },\n download: { available: true },\n whatsapp: { available: true },\n telegram: { available: true },\n instagram: { available: true },\n facebook: { available: true },\n snapchat: { available: true },\n sms: { available: true },\n email: { available: true },\n linkedin: { available: true },\n reddit: { available: true },\n x: { available: true },\n tiktok: { available: true },\n threads: { available: true },\n};\n\nexport interface UseShareSheetOptions {\n /** URL to share */\n shareUrl: string;\n /** Text to share */\n shareText: string;\n /** Download URL (optional) */\n downloadUrl?: string | null;\n /** Download filename (optional) */\n downloadFilename?: string;\n /** Email subject (optional) */\n emailSubject?: string;\n /** File to share via native share (data URL or Blob) - takes priority over URL sharing */\n shareFile?: string | Blob | null;\n /** Filename for the shared file */\n shareFilename?: string;\n /** Callback after native share */\n onNativeShare?: () => void;\n /** Callback after copy */\n onCopy?: () => void;\n /** Callback after download starts */\n onDownload?: () => void;\n}\n\n/**\n * Headless hook for share sheet functionality.\n * Use this to build your own custom share UI.\n */\nexport function useShareSheet({\n shareUrl,\n shareText,\n downloadUrl,\n downloadFilename,\n emailSubject = \"Share\",\n shareFile,\n shareFilename = \"share.png\",\n onNativeShare,\n onCopy,\n onDownload,\n}: UseShareSheetOptions): UseShareSheetReturn {\n const [copied, setCopied] = useState(false);\n const [downloading, setDownloading] = useState(false);\n\n // Use state for values that depend on browser APIs to avoid hydration mismatch\n // Initial values match what server renders (conservative defaults)\n const [canNativeShare, setCanNativeShare] = useState(false);\n const [isMobile, setIsMobile] = useState(false);\n const [platformAvailability, setPlatformAvailability] = useState<Record<ShareOption, PlatformAvailability>>(\n DEFAULT_PLATFORM_AVAILABILITY\n );\n\n // Detect browser capabilities after mount (client-side only)\n useEffect(() => {\n setCanNativeShare(typeof navigator !== \"undefined\" && \"share\" in navigator);\n setIsMobile(isMobileDevice());\n setPlatformAvailability(getAllPlatformAvailability());\n }, []);\n\n const safeUrl = getSafeUrl(shareUrl);\n\n const copyLink = useCallback(async () => {\n if (!safeUrl) return;\n try {\n await navigator.clipboard.writeText(safeUrl);\n setCopied(true);\n onCopy?.();\n setTimeout(() => setCopied(false), 1200);\n } catch {\n // ignore\n }\n }, [safeUrl, onCopy]);\n\n const nativeShare = useCallback(async () => {\n const nav = navigator as Navigator & {\n share?: (data: ShareData) => Promise<void>;\n canShare?: (data: ShareData) => boolean;\n };\n if (!(\"share\" in nav) || typeof nav.share !== \"function\") return;\n\n try {\n // If shareFile is provided, try to share as a file\n if (shareFile) {\n let blob: Blob;\n\n // Convert data URL to Blob if needed\n if (typeof shareFile === \"string\" && shareFile.startsWith(\"data:\")) {\n const response = await fetch(shareFile);\n blob = await response.blob();\n } else if (shareFile instanceof Blob) {\n blob = shareFile;\n } else {\n // Invalid shareFile, fall back to URL sharing\n if (!safeUrl) return;\n await nav.share({\n title: shareText,\n text: shareText,\n url: safeUrl,\n });\n onNativeShare?.();\n return;\n }\n\n // Create a File from the Blob\n const file = new File([blob], shareFilename, { type: blob.type || \"image/png\" });\n\n // Check if file sharing is supported\n const shareData: ShareData = {\n files: [file],\n title: shareText,\n text: shareText,\n };\n\n if (nav.canShare && !nav.canShare(shareData)) {\n // File sharing not supported, fall back to URL sharing\n if (!safeUrl) return;\n await nav.share({\n title: shareText,\n text: shareText,\n url: safeUrl,\n });\n onNativeShare?.();\n return;\n }\n\n await nav.share(shareData);\n onNativeShare?.();\n return;\n }\n\n // Fall back to URL sharing\n if (!safeUrl) return;\n await nav.share({\n title: shareText,\n text: shareText,\n url: safeUrl,\n });\n onNativeShare?.();\n } catch {\n // user canceled or share failed -> ignore\n }\n }, [safeUrl, shareText, shareFile, shareFilename, onNativeShare]);\n\n const downloadFile = useCallback(async () => {\n const url = (downloadUrl ?? \"\").trim();\n if (!url) return;\n try {\n setDownloading(true);\n onDownload?.();\n const res = await fetch(url);\n if (!res.ok) throw new Error(`Failed to fetch file (${res.status})`);\n const blob = await res.blob();\n const href = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = href;\n a.download = downloadFilename || \"download\";\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(href);\n } catch {\n // ignore\n } finally {\n setDownloading(false);\n }\n }, [downloadUrl, downloadFilename, onDownload]);\n\n const shareWhatsApp = useCallback(() => {\n shareToWhatsApp(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareTelegram = useCallback(() => {\n shareToTelegram(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareX = useCallback(() => {\n shareToX(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareFacebook = useCallback(() => {\n shareToFacebook(safeUrl);\n }, [safeUrl]);\n\n const shareInstagram = useCallback(() => {\n openInstagram();\n }, []);\n\n const shareTikTok = useCallback(() => {\n openTikTok();\n }, []);\n\n const shareThreads = useCallback(() => {\n openThreads();\n }, []);\n\n const shareSnapchat = useCallback(() => {\n shareToSnapchat(safeUrl);\n }, [safeUrl]);\n\n const shareSMS = useCallback(() => {\n shareViaSMS(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n const shareEmail = useCallback(() => {\n shareViaEmail(safeUrl, shareText, emailSubject);\n }, [safeUrl, shareText, emailSubject]);\n\n const shareLinkedIn = useCallback(() => {\n shareToLinkedIn(safeUrl);\n }, [safeUrl]);\n\n const shareReddit = useCallback(() => {\n shareToReddit(safeUrl, shareText);\n }, [safeUrl, shareText]);\n\n return {\n canNativeShare,\n copied,\n downloading,\n safeUrl,\n isMobile,\n platformAvailability,\n copyLink,\n nativeShare,\n downloadFile,\n shareWhatsApp,\n shareTelegram,\n shareX,\n shareFacebook,\n shareInstagram,\n shareTikTok,\n shareThreads,\n shareSnapchat,\n shareSMS,\n shareEmail,\n shareLinkedIn,\n shareReddit,\n };\n}\n\n/**\n * Hook to fetch OG (Open Graph) data from a URL.\n * Fetches with `fetcher`, the Microlink lookup (`fetchOGData`, cached) unless another is given:\n * calling this hook is the opt-in, since the lookup sends `url` to a third party.\n */\nexport function useOGData(url: string | undefined, fetcher: OGFetcher = fetchOGData): {\n ogData: OGData | null;\n loading: boolean;\n error: string | null;\n} {\n const [ogData, setOgData] = useState<OGData | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n // Read at fetch time, so an inline fetcher does not refetch on every render\n // (this effect runs before the one below in the same commit)\n const fetcherRef = useRef(fetcher);\n useEffect(() => {\n fetcherRef.current = fetcher;\n });\n\n useEffect(() => {\n if (!url) {\n setOgData(null);\n setLoading(false);\n setError(null);\n return;\n }\n\n let cancelled = false;\n setLoading(true);\n setError(null);\n\n fetcherRef.current(url)\n .then((data) => {\n if (!cancelled) {\n setOgData(data);\n setLoading(false);\n }\n })\n .catch((err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : \"Failed to fetch OG data\");\n setLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [url]);\n\n return { ogData, loading, error };\n}\n\n// Legacy export for backwards compatibility\n/** @deprecated Use useShareSheet instead */\nexport const useShareMenu = useShareSheet;\n/** @deprecated Use UseShareSheetOptions instead */\nexport type UseShareMenuOptions = UseShareSheetOptions;\n","// OG data fetcher using the Microlink API (free, no API key required).\n// The sheet never calls it on its own: a caller opts in with `fetchPreview={fetchOGData}`,\n// because the lookup sends the shared link to a third party.\n\nexport interface OGData {\n title?: string;\n description?: string;\n image?: string;\n url?: string;\n siteName?: string;\n}\n\n/** Looks up a link's card. Resolves to null when there is none. */\nexport type OGFetcher = (url: string) => Promise<OGData | null>;\n\nexport interface OGFetchResult {\n data: OGData | null;\n loading: boolean;\n error: string | null;\n}\n\n// Cache to avoid re-fetching the same URL\nconst ogCache = new Map<string, OGData>();\n\nexport async function fetchOGData(url: string): Promise<OGData | null> {\n // Check cache first\n if (ogCache.has(url)) {\n return ogCache.get(url)!;\n }\n\n try {\n // Use Microlink API to fetch OG data (free tier, no API key needed)\n const apiUrl = `https://api.microlink.io?url=${encodeURIComponent(url)}`;\n const response = await fetch(apiUrl);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch OG data: ${response.status}`);\n }\n\n const json = await response.json();\n \n if (json.status !== \"success\" || !json.data) {\n return null;\n }\n\n const { title, description, image, url: canonicalUrl, publisher } = json.data;\n\n const ogData: OGData = {\n title: title || undefined,\n description: description || undefined,\n image: image?.url || undefined,\n url: canonicalUrl || url,\n siteName: publisher || undefined,\n };\n\n // Cache the result\n ogCache.set(url, ogData);\n\n return ogData;\n } catch (error) {\n console.warn(\"[react-sharesheet] Failed to fetch OG data:\", error);\n return null;\n }\n}\n\n// Clear cache (useful for testing or forcing refresh)\nexport function clearOGCache(): void {\n ogCache.clear();\n}\n","import { \n openUrl, \n checkPlatformAvailability, \n warnUnavailablePlatform,\n} from \"./utils\";\n\nexport function shareToWhatsApp(url: string, text: string) {\n const encoded = encodeURIComponent(`${text}\\n${url}`);\n openUrl(`https://api.whatsapp.com/send?text=${encoded}`);\n}\n\nexport function shareToTelegram(url: string, text: string) {\n const encodedText = encodeURIComponent(text);\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://t.me/share/url?url=${encodedUrl}&text=${encodedText}`);\n}\n\nexport function shareToX(url: string, text: string) {\n const encodedText = encodeURIComponent(text);\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://x.com/intent/tweet?text=${encodedText}&url=${encodedUrl}`);\n}\n\nexport function shareToFacebook(url: string) {\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`);\n}\n\nexport function openInstagram() {\n const availability = checkPlatformAvailability(\"instagram\");\n if (!availability.available) {\n warnUnavailablePlatform(\"instagram\", availability.reason!);\n // Still attempt to open - it may work on some desktop browsers with app installed\n }\n window.location.href = \"instagram://\";\n}\n\nexport function openTikTok() {\n const availability = checkPlatformAvailability(\"tiktok\");\n if (!availability.available) {\n warnUnavailablePlatform(\"tiktok\", availability.reason!);\n // Still attempt to open - it may work on some desktop browsers with app installed\n }\n window.location.href = \"tiktok://\";\n}\n\nexport function openThreads() {\n const availability = checkPlatformAvailability(\"threads\");\n if (!availability.available) {\n warnUnavailablePlatform(\"threads\", availability.reason!);\n // Still attempt to open - it may work on some desktop browsers with app installed\n }\n window.location.href = \"threads://\";\n}\n\nexport function shareToSnapchat(url: string) {\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.snapchat.com/scan?attachmentUrl=${encodedUrl}`);\n}\n\nexport function shareViaSMS(url: string, text: string) {\n const availability = checkPlatformAvailability(\"sms\");\n if (!availability.available) {\n warnUnavailablePlatform(\"sms\", availability.reason!);\n // Still attempt to open - it may work on some devices\n }\n const body = encodeURIComponent(`${text}\\n${url}`);\n window.location.href = `sms:?body=${body}`;\n}\n\nexport function shareViaEmail(url: string, text: string, subject = \"Share\") {\n const encodedSubject = encodeURIComponent(subject);\n const body = encodeURIComponent(`${text}\\n\\n${url}`);\n window.location.href = `mailto:?subject=${encodedSubject}&body=${body}`;\n}\n\nexport function shareToLinkedIn(url: string) {\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`);\n}\n\nexport function shareToReddit(url: string, text: string) {\n const encodedText = encodeURIComponent(text);\n const encodedUrl = encodeURIComponent(url);\n openUrl(`https://www.reddit.com/submit?url=${encodedUrl}&title=${encodedText}`);\n}\n\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n LuDownload,\n LuLink,\n LuMail,\n LuMessageCircle,\n LuSend,\n} from \"react-icons/lu\";\nimport {\n FaFacebookF,\n FaInstagram,\n FaLinkedin,\n FaReddit,\n FaTelegramPlane,\n FaTiktok,\n FaWhatsapp,\n} from \"react-icons/fa\";\nimport { FaXTwitter, FaThreads, FaSnapchat } from \"react-icons/fa6\";\nimport type { ShareOption } from \"./types\";\n\n/** Platform color configuration */\nexport interface PlatformColor {\n /** Background color (hex) */\n bg: string;\n /** Text/icon color (hex) */\n text: string;\n}\n\n/** Platform configuration */\nexport interface PlatformConfig {\n /** Platform identifier */\n id: ShareOption;\n /** Display label */\n label: string;\n /** Colors */\n colors: PlatformColor;\n /** Icon component (accepts size prop) */\n Icon: (props: { size?: number; className?: string }) => ReactNode;\n /** CSS variable name for background */\n cssVar: string;\n}\n\n/** All platform IDs in default order */\nexport const PLATFORM_IDS: readonly ShareOption[] = [\n \"native\",\n \"copy\",\n \"download\",\n \"whatsapp\",\n \"telegram\",\n \"instagram\",\n \"facebook\",\n \"snapchat\",\n \"sms\",\n \"email\",\n \"linkedin\",\n \"reddit\",\n \"x\",\n \"tiktok\",\n \"threads\",\n] as const;\n\n/** Platform colors - hex values for each platform (SOURCE OF TRUTH) */\nexport const PLATFORM_COLORS: Record<ShareOption, PlatformColor> = {\n native: { bg: \"#7c3aed\", text: \"#ffffff\" },\n copy: { bg: \"#3b82f6\", text: \"#ffffff\" },\n download: { bg: \"#ef4444\", text: \"#ffffff\" },\n whatsapp: { bg: \"#25D366\", text: \"#ffffff\" },\n telegram: { bg: \"#229ED9\", text: \"#ffffff\" },\n instagram: { bg: \"#E1306C\", text: \"#ffffff\" },\n facebook: { bg: \"#1877F2\", text: \"#ffffff\" },\n snapchat: { bg: \"#FFFC00\", text: \"#000000\" },\n sms: { bg: \"#22c55e\", text: \"#ffffff\" },\n email: { bg: \"#f97316\", text: \"#ffffff\" },\n linkedin: { bg: \"#0A66C2\", text: \"#ffffff\" },\n reddit: { bg: \"#FF4500\", text: \"#ffffff\" },\n x: { bg: \"#000000\", text: \"#ffffff\" },\n tiktok: { bg: \"#000000\", text: \"#ffffff\" },\n threads: { bg: \"#000000\", text: \"#ffffff\" },\n} as const;\n\n/** Platform labels (SOURCE OF TRUTH) */\nexport const PLATFORM_LABELS: Record<ShareOption, string> = {\n native: \"Share…\",\n copy: \"Copy\",\n download: \"Download\",\n whatsapp: \"WhatsApp\",\n telegram: \"Telegram\",\n instagram: \"Instagram\",\n facebook: \"Facebook\",\n snapchat: \"Snapchat\",\n sms: \"SMS\",\n email: \"Email\",\n linkedin: \"LinkedIn\",\n reddit: \"Reddit\",\n x: \"X\",\n tiktok: \"TikTok\",\n threads: \"Threads\",\n} as const;\n\n/** Platform icons - React components (SOURCE OF TRUTH) */\nexport const PLATFORM_ICONS: Record<ShareOption, (props: { size?: number; className?: string }) => ReactNode> = {\n native: ({ size = 22, className }) => <LuSend size={size} className={className} />,\n copy: ({ size = 22, className }) => <LuLink size={size} className={className} />,\n download: ({ size = 22, className }) => <LuDownload size={size} className={className} />,\n whatsapp: ({ size = 22, className }) => <FaWhatsapp size={size} className={className} />,\n telegram: ({ size = 22, className }) => <FaTelegramPlane size={size} className={className} />,\n instagram: ({ size = 22, className }) => <FaInstagram size={size} className={className} />,\n facebook: ({ size = 22, className }) => <FaFacebookF size={size} className={className} />,\n snapchat: ({ size = 22, className }) => <FaSnapchat size={size} className={className} />,\n sms: ({ size = 22, className }) => <LuMessageCircle size={size} className={className} />,\n email: ({ size = 22, className }) => <LuMail size={size} className={className} />,\n linkedin: ({ size = 22, className }) => <FaLinkedin size={size} className={className} />,\n reddit: ({ size = 22, className }) => <FaReddit size={size} className={className} />,\n x: ({ size = 22, className }) => <FaXTwitter size={size} className={className} />,\n tiktok: ({ size = 22, className }) => <FaTiktok size={size} className={className} />,\n threads: ({ size = 22, className }) => <FaThreads size={size} className={className} />,\n} as const;\n\n/** CSS variable names for platform backgrounds */\nexport const PLATFORM_CSS_VARS: Record<ShareOption, string> = {\n native: \"--sharesheet-native-bg\",\n copy: \"--sharesheet-copy-bg\",\n download: \"--sharesheet-download-bg\",\n whatsapp: \"--sharesheet-whatsapp-bg\",\n telegram: \"--sharesheet-telegram-bg\",\n instagram: \"--sharesheet-instagram-bg\",\n facebook: \"--sharesheet-facebook-bg\",\n snapchat: \"--sharesheet-snapchat-bg\",\n sms: \"--sharesheet-sms-bg\",\n email: \"--sharesheet-email-bg\",\n linkedin: \"--sharesheet-linkedin-bg\",\n reddit: \"--sharesheet-reddit-bg\",\n x: \"--sharesheet-x-bg\",\n tiktok: \"--sharesheet-tiktok-bg\",\n threads: \"--sharesheet-threads-bg\",\n} as const;\n\n/** Full platform configurations */\nexport const PLATFORMS: Record<ShareOption, PlatformConfig> = Object.fromEntries(\n PLATFORM_IDS.map((id) => [\n id,\n {\n id,\n label: PLATFORM_LABELS[id],\n colors: PLATFORM_COLORS[id],\n Icon: PLATFORM_ICONS[id],\n cssVar: PLATFORM_CSS_VARS[id],\n },\n ])\n) as Record<ShareOption, PlatformConfig>;\n\n/** Get platform config by id */\nexport function getPlatform(id: ShareOption): PlatformConfig {\n return PLATFORMS[id];\n}\n\n/** Get all platform configs as array */\nexport function getAllPlatforms(): PlatformConfig[] {\n return PLATFORM_IDS.map((id) => PLATFORMS[id]);\n}\n\n/** Get platform color */\nexport function getPlatformColor(id: ShareOption): PlatformColor {\n return PLATFORM_COLORS[id];\n}\n\n/** Get platform icon component */\nexport function getPlatformIcon(id: ShareOption): (props: { size?: number; className?: string }) => ReactNode {\n return PLATFORM_ICONS[id];\n}\n\n/** Get platform label */\nexport function getPlatformLabel(id: ShareOption): string {\n return PLATFORM_LABELS[id];\n}\n\n/** Generate CSS variable defaults from platform colors */\nexport function generateCssVarDefaults(): Record<string, string> {\n const defaults: Record<string, string> = {};\n PLATFORM_IDS.forEach((id) => {\n defaults[PLATFORM_CSS_VARS[id]] = PLATFORM_COLORS[id].bg;\n });\n return defaults;\n}\n","import type { ReactNode } from \"react\";\nimport type { OGFetcher } from \"./og-fetcher\";\n\n/** CSS variable names for UI elements (non-platform specific) */\nexport const CSS_VARS_UI = {\n // Drawer\n overlayBg: \"--sharesheet-overlay-bg\",\n drawerBg: \"--sharesheet-drawer-bg\",\n drawerBorder: \"--sharesheet-drawer-border\",\n handleBg: \"--sharesheet-handle-bg\",\n // Content\n titleColor: \"--sharesheet-title-color\",\n subtitleColor: \"--sharesheet-subtitle-color\",\n buttonLabelColor: \"--sharesheet-button-label-color\",\n // Preview\n previewBg: \"--sharesheet-preview-bg\",\n previewShimmer: \"--sharesheet-preview-shimmer\",\n} as const;\n\n/** Default values for UI CSS variables */\nexport const CSS_VAR_UI_DEFAULTS = {\n [CSS_VARS_UI.overlayBg]: \"rgba(0, 0, 0, 0.7)\",\n [CSS_VARS_UI.drawerBg]: \"#09090b\",\n [CSS_VARS_UI.drawerBorder]: \"#27272a\",\n [CSS_VARS_UI.handleBg]: \"rgba(255, 255, 255, 0.2)\",\n [CSS_VARS_UI.titleColor]: \"#ffffff\",\n [CSS_VARS_UI.subtitleColor]: \"#a1a1aa\",\n [CSS_VARS_UI.buttonLabelColor]: \"#ffffff\",\n [CSS_VARS_UI.previewBg]: \"rgba(255, 255, 255, 0.05)\",\n [CSS_VARS_UI.previewShimmer]: \"rgba(255, 255, 255, 0.1)\",\n} as const;\n\n/** Available share options */\nexport type ShareOption =\n | \"native\"\n | \"copy\"\n | \"download\"\n | \"whatsapp\"\n | \"telegram\"\n | \"instagram\"\n | \"facebook\"\n | \"snapchat\"\n | \"sms\"\n | \"email\"\n | \"linkedin\"\n | \"reddit\"\n | \"x\"\n | \"tiktok\"\n | \"threads\";\n\n/** Class name overrides for ShareSheetContent */\nexport interface ShareSheetContentClassNames {\n /** Root container */\n root?: string;\n /** Title container */\n header?: string;\n /** Main title text */\n title?: string;\n /** Subtitle/share text */\n subtitle?: string;\n /** Preview container */\n preview?: string;\n /** Preview skeleton/loading wrapper */\n previewSkeleton?: string;\n /** Preview image element */\n previewImage?: string;\n /** Preview video element */\n previewVideo?: string;\n /** Preview file/audio container */\n previewFile?: string;\n /** Preview file icon */\n previewFileIcon?: string;\n /** Preview filename text */\n previewFilename?: string;\n /** Preview link container */\n previewLink?: string;\n /** Buttons grid container */\n grid?: string;\n /** Individual button wrapper */\n button?: string;\n /** Button icon container */\n buttonIcon?: string;\n /** Button label text */\n buttonLabel?: string;\n}\n\n/** Class name overrides for ShareSheetDrawer */\nexport interface ShareSheetDrawerClassNames extends ShareSheetContentClassNames {\n /** Drawer overlay */\n overlay?: string;\n /** Drawer content panel */\n drawer?: string;\n /** Drawer inner content wrapper */\n drawerInner?: string;\n /** Drawer handle */\n handle?: string;\n /** Trigger wrapper */\n trigger?: string;\n}\n\nexport interface ShareSheetContentProps {\n /** Title displayed at the top of the sheet */\n title?: string;\n /** URL to share */\n shareUrl: string;\n /** Text to share alongside the URL */\n shareText: string;\n /** Optional URL for download functionality */\n downloadUrl?: string | null;\n /** Filename for downloaded file */\n downloadFilename?: string;\n /** Custom preview image URL (skips OG fetching if provided) */\n previewImage?: string | null;\n /**\n * Looks up the link's card when there is no `previewImage`. Unset (the default), no request\n * leaves the page and the sheet shows a link placeholder. Pass `fetchOGData` for the Microlink\n * lookup the sheet made by itself before 1.10.0: it sends `shareUrl` to api.microlink.io.\n */\n fetchPreview?: OGFetcher;\n /** File to share via native share (data URL or Blob) - takes priority over URL sharing */\n shareFile?: string | Blob | null;\n /** Filename for the shared file */\n shareFilename?: string;\n /** Custom class name for the container (shorthand for classNames.root) */\n className?: string;\n /** Override class names for sub-components */\n classNames?: ShareSheetContentClassNames;\n /** Button size in pixels */\n buttonSize?: number;\n /** Icon size in pixels */\n iconSize?: number;\n /** Called when native share is triggered */\n onNativeShare?: () => void;\n /** Called when link is copied */\n onCopy?: () => void;\n /** Called when download starts */\n onDownload?: () => void;\n /** Called on every share option click, with the option id (analytics-friendly) */\n onShare?: (option: ShareOption) => void;\n /** Hide specific share options */\n hide?: ShareOption[];\n /** Show only these platforms, in this exact order */\n show?: ShareOption[];\n /** Custom labels for buttons */\n labels?: Partial<Record<ShareOption, string>>;\n /** Custom icons for buttons */\n icons?: Partial<Record<ShareOption, ReactNode>>;\n}\n\nexport interface ShareSheetDrawerProps extends ShareSheetContentProps {\n /** Whether the drawer is disabled */\n disabled?: boolean;\n /** Trigger element for the drawer */\n children: React.ReactNode;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Override class names for sub-components */\n classNames?: ShareSheetDrawerClassNames;\n}\n\n/** Share button configuration (internal) */\nexport interface ShareButtonConfig {\n id: ShareOption;\n label: string;\n icon: ReactNode;\n bgColor: string;\n textColor?: string;\n onClick: () => void;\n condition?: boolean;\n}\n\n/** Platform availability status */\nexport interface PlatformAvailability {\n /** Whether the platform is available on this device */\n available: boolean;\n /** Reason why platform is unavailable (if applicable) */\n reason?: string;\n}\n\n/** Return type of useShareSheet hook */\nexport interface UseShareSheetReturn {\n /** Whether the browser supports native share */\n canNativeShare: boolean;\n /** Whether the link was recently copied */\n copied: boolean;\n /** Whether a download is in progress */\n downloading: boolean;\n /** The safe URL (falls back to current page URL) */\n safeUrl: string;\n /** Whether the current device is mobile */\n isMobile: boolean;\n /** Availability status for each platform */\n platformAvailability: Record<ShareOption, PlatformAvailability>;\n /** Copy the share URL to clipboard */\n copyLink: () => Promise<void>;\n /** Trigger native share dialog */\n nativeShare: () => Promise<void>;\n /** Download the file from downloadUrl */\n downloadFile: () => Promise<void>;\n /** Share to WhatsApp */\n shareWhatsApp: () => void;\n /** Share to Telegram */\n shareTelegram: () => void;\n /** Share to X (Twitter) */\n shareX: () => void;\n /** Share to Facebook */\n shareFacebook: () => void;\n /** Open Instagram app (mobile only - will warn on desktop) */\n shareInstagram: () => void;\n /** Open TikTok app (mobile only - will warn on desktop) */\n shareTikTok: () => void;\n /** Open Threads app (mobile only - will warn on desktop) */\n shareThreads: () => void;\n /** Share to Snapchat */\n shareSnapchat: () => void;\n /** Share via SMS (mobile only - will warn on desktop) */\n shareSMS: () => void;\n /** Share via Email */\n shareEmail: () => void;\n /** Share to LinkedIn */\n shareLinkedIn: () => void;\n /** Share to Reddit */\n shareReddit: () => void;\n}\n\n// Legacy exports for backwards compatibility\n/** @deprecated Use CSS_VARS_UI instead */\nexport const CSS_VARS = CSS_VARS_UI;\n/** @deprecated Use CSS_VAR_UI_DEFAULTS instead */\nexport const CSS_VAR_DEFAULTS = CSS_VAR_UI_DEFAULTS;\n\n// Legacy type aliases for backwards compatibility\n/** @deprecated Use ShareSheetContentClassNames instead */\nexport type ShareMenuContentClassNames = ShareSheetContentClassNames;\n/** @deprecated Use ShareSheetDrawerClassNames instead */\nexport type ShareMenuDrawerClassNames = ShareSheetDrawerClassNames;\n/** @deprecated Use ShareSheetContentProps instead */\nexport type ShareMenuContentProps = ShareSheetContentProps;\n/** @deprecated Use ShareSheetDrawerProps instead */\nexport type ShareMenuDrawerProps = ShareSheetDrawerProps;\n/** @deprecated Use UseShareSheetReturn instead */\nexport type UseShareMenuReturn = UseShareSheetReturn;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAAA,gBAA+C;AAC/C,IAAAC,aAAiC;;;ACHjC,kBAAsC;AACtC,4BAAwB;AAGjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;AAEO,SAAS,QAAQ,KAAa;AACnC,SAAO,KAAK,KAAK,UAAU,qBAAqB;AAClD;AAEO,SAAS,WAAW,UAA0B;AACnD,SAAO,aAAa,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAC7E;AAMO,SAAS,iBAA0B;AACxC,MAAI,OAAO,cAAc,YAAa,QAAO;AAE7C,QAAM,YAAY,UAAU,aAAa,UAAU,UAAU;AAG7D,QAAM,cAAc;AAGpB,QAAM,WAAW,OAAO,WAAW,gBACjC,kBAAkB,UAClB,UAAU,iBAAiB;AAK7B,SAAO,YAAY,KAAK,SAAS;AACnC;AAuBO,IAAM,wBAAgD;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAYO,SAAS,0BAA0B,UAA6C;AACrF,QAAM,WAAW,eAAe;AAGhC,MAAI,sBAAsB,SAAS,QAAQ,GAAG;AAC5C,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,WAAW;AAAA,QACX,QAAQ,GAAG,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,aAAa,SAAS,CAAC,UAAU;AACnC,WAAO;AAAA,MACL,WAAW;AAAA,MACX,QAAQ;AAAA,IACV;AAAA,EACF;AAGA,MAAI,aAAa,UAAU;AACzB,UAAM,WAAW,OAAO,cAAc,eAAe,WAAW;AAChE,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,WAAW;AAAA,QACX,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,KAAK;AAC3B;AAKO,SAAS,6BAAwE;AACtF,QAAM,YAA2B;AAAA,IAC/B;AAAA,IAAU;AAAA,IAAQ;AAAA,IAAY;AAAA,IAAY;AAAA,IAC1C;AAAA,IAAa;AAAA,IAAY;AAAA,IAAY;AAAA,IAAO;AAAA,IAC5C;AAAA,IAAY;AAAA,IAAU;AAAA,IAAK;AAAA,IAAU;AAAA,EACvC;AAEA,QAAM,SAA6D,CAAC;AACpE,aAAW,YAAY,WAAW;AAChC,WAAO,QAAQ,IAAI,0BAA0B,QAAQ;AAAA,EACvD;AAEA,SAAO;AACT;AAKO,SAAS,wBAAwB,UAAuB,QAAsB;AACnF,UAAQ;AAAA,IACN,sBAAsB,QAAQ,8BAA8B,MAAM;AAAA,EAEpE;AACF;;;ACxIA,mBAAkE;;;ACoBlE,IAAM,UAAU,oBAAI,IAAoB;AAExC,eAAsB,YAAY,KAAqC;AAErE,MAAI,QAAQ,IAAI,GAAG,GAAG;AACpB,WAAO,QAAQ,IAAI,GAAG;AAAA,EACxB;AAEA,MAAI;AAEF,UAAM,SAAS,gCAAgC,mBAAmB,GAAG,CAAC;AACtE,UAAM,WAAW,MAAM,MAAM,MAAM;AAEnC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,EAAE;AAAA,IAC/D;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,QAAI,KAAK,WAAW,aAAa,CAAC,KAAK,MAAM;AAC3C,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,OAAO,aAAa,OAAO,KAAK,cAAc,UAAU,IAAI,KAAK;AAEzE,UAAM,SAAiB;AAAA,MACrB,OAAO,SAAS;AAAA,MAChB,aAAa,eAAe;AAAA,MAC5B,OAAO,OAAO,OAAO;AAAA,MACrB,KAAK,gBAAgB;AAAA,MACrB,UAAU,aAAa;AAAA,IACzB;AAGA,YAAQ,IAAI,KAAK,MAAM;AAEvB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,KAAK,+CAA+C,KAAK;AACjE,WAAO;AAAA,EACT;AACF;;;ACzDO,SAAS,gBAAgB,KAAa,MAAc;AACzD,QAAM,UAAU,mBAAmB,GAAG,IAAI;AAAA,EAAK,GAAG,EAAE;AACpD,UAAQ,sCAAsC,OAAO,EAAE;AACzD;AAEO,SAAS,gBAAgB,KAAa,MAAc;AACzD,QAAM,cAAc,mBAAmB,IAAI;AAC3C,QAAM,aAAa,mBAAmB,GAAG;AACzC,UAAQ,8BAA8B,UAAU,SAAS,WAAW,EAAE;AACxE;AAEO,SAAS,SAAS,KAAa,MAAc;AAClD,QAAM,cAAc,mBAAmB,IAAI;AAC3C,QAAM,aAAa,mBAAmB,GAAG;AACzC,UAAQ,mCAAmC,WAAW,QAAQ,UAAU,EAAE;AAC5E;AAEO,SAAS,gBAAgB,KAAa;AAC3C,QAAM,aAAa,mBAAmB,GAAG;AACzC,UAAQ,gDAAgD,UAAU,EAAE;AACtE;AAEO,SAAS,gBAAgB;AAC9B,QAAM,eAAe,0BAA0B,WAAW;AAC1D,MAAI,CAAC,aAAa,WAAW;AAC3B,4BAAwB,aAAa,aAAa,MAAO;AAAA,EAE3D;AACA,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,aAAa;AAC3B,QAAM,eAAe,0BAA0B,QAAQ;AACvD,MAAI,CAAC,aAAa,WAAW;AAC3B,4BAAwB,UAAU,aAAa,MAAO;AAAA,EAExD;AACA,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,cAAc;AAC5B,QAAM,eAAe,0BAA0B,SAAS;AACxD,MAAI,CAAC,aAAa,WAAW;AAC3B,4BAAwB,WAAW,aAAa,MAAO;AAAA,EAEzD;AACA,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,gBAAgB,KAAa;AAC3C,QAAM,aAAa,mBAAmB,GAAG;AACzC,UAAQ,+CAA+C,UAAU,EAAE;AACrE;AAEO,SAAS,YAAY,KAAa,MAAc;AACrD,QAAM,eAAe,0BAA0B,KAAK;AACpD,MAAI,CAAC,aAAa,WAAW;AAC3B,4BAAwB,OAAO,aAAa,MAAO;AAAA,EAErD;AACA,QAAM,OAAO,mBAAmB,GAAG,IAAI;AAAA,EAAK,GAAG,EAAE;AACjD,SAAO,SAAS,OAAO,aAAa,IAAI;AAC1C;AAEO,SAAS,cAAc,KAAa,MAAc,UAAU,SAAS;AAC1E,QAAM,iBAAiB,mBAAmB,OAAO;AACjD,QAAM,OAAO,mBAAmB,GAAG,IAAI;AAAA;AAAA,EAAO,GAAG,EAAE;AACnD,SAAO,SAAS,OAAO,mBAAmB,cAAc,SAAS,IAAI;AACvE;AAEO,SAAS,gBAAgB,KAAa;AAC3C,QAAM,aAAa,mBAAmB,GAAG;AACzC,UAAQ,uDAAuD,UAAU,EAAE;AAC7E;AAEO,SAAS,cAAc,KAAa,MAAc;AACvD,QAAM,cAAc,mBAAmB,IAAI;AAC3C,QAAM,aAAa,mBAAmB,GAAG;AACzC,UAAQ,qCAAqC,UAAU,UAAU,WAAW,EAAE;AAChF;;;AF9DA,IAAM,gCAA2E;AAAA,EAC/E,QAAQ,EAAE,WAAW,KAAK;AAAA,EAC1B,MAAM,EAAE,WAAW,KAAK;AAAA,EACxB,UAAU,EAAE,WAAW,KAAK;AAAA,EAC5B,UAAU,EAAE,WAAW,KAAK;AAAA,EAC5B,UAAU,EAAE,WAAW,KAAK;AAAA,EAC5B,WAAW,EAAE,WAAW,KAAK;AAAA,EAC7B,UAAU,EAAE,WAAW,KAAK;AAAA,EAC5B,UAAU,EAAE,WAAW,KAAK;AAAA,EAC5B,KAAK,EAAE,WAAW,KAAK;AAAA,EACvB,OAAO,EAAE,WAAW,KAAK;AAAA,EACzB,UAAU,EAAE,WAAW,KAAK;AAAA,EAC5B,QAAQ,EAAE,WAAW,KAAK;AAAA,EAC1B,GAAG,EAAE,WAAW,KAAK;AAAA,EACrB,QAAQ,EAAE,WAAW,KAAK;AAAA,EAC1B,SAAS,EAAE,WAAW,KAAK;AAC7B;AA6BO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AACF,GAA8C;AAC5C,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAC1C,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AAIpD,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,uBAAS,KAAK;AAC1D,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,CAAC,sBAAsB,uBAAuB,QAAI;AAAA,IACtD;AAAA,EACF;AAGA,8BAAU,MAAM;AACd,sBAAkB,OAAO,cAAc,eAAe,WAAW,SAAS;AAC1E,gBAAY,eAAe,CAAC;AAC5B,4BAAwB,2BAA2B,CAAC;AAAA,EACtD,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,WAAW,QAAQ;AAEnC,QAAM,eAAW,0BAAY,YAAY;AACvC,QAAI,CAAC,QAAS;AACd,QAAI;AACF,YAAM,UAAU,UAAU,UAAU,OAAO;AAC3C,gBAAU,IAAI;AACd,eAAS;AACT,iBAAW,MAAM,UAAU,KAAK,GAAG,IAAI;AAAA,IACzC,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,CAAC;AAEpB,QAAM,kBAAc,0BAAY,YAAY;AAC1C,UAAM,MAAM;AAIZ,QAAI,EAAE,WAAW,QAAQ,OAAO,IAAI,UAAU,WAAY;AAE1D,QAAI;AAEF,UAAI,WAAW;AACb,YAAI;AAGJ,YAAI,OAAO,cAAc,YAAY,UAAU,WAAW,OAAO,GAAG;AAClE,gBAAM,WAAW,MAAM,MAAM,SAAS;AACtC,iBAAO,MAAM,SAAS,KAAK;AAAA,QAC7B,WAAW,qBAAqB,MAAM;AACpC,iBAAO;AAAA,QACT,OAAO;AAEL,cAAI,CAAC,QAAS;AACd,gBAAM,IAAI,MAAM;AAAA,YACd,OAAO;AAAA,YACP,MAAM;AAAA,YACN,KAAK;AAAA,UACP,CAAC;AACD,0BAAgB;AAChB;AAAA,QACF;AAGA,cAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,eAAe,EAAE,MAAM,KAAK,QAAQ,YAAY,CAAC;AAG/E,cAAM,YAAuB;AAAA,UAC3B,OAAO,CAAC,IAAI;AAAA,UACZ,OAAO;AAAA,UACP,MAAM;AAAA,QACR;AAEA,YAAI,IAAI,YAAY,CAAC,IAAI,SAAS,SAAS,GAAG;AAE5C,cAAI,CAAC,QAAS;AACd,gBAAM,IAAI,MAAM;AAAA,YACd,OAAO;AAAA,YACP,MAAM;AAAA,YACN,KAAK;AAAA,UACP,CAAC;AACD,0BAAgB;AAChB;AAAA,QACF;AAEA,cAAM,IAAI,MAAM,SAAS;AACzB,wBAAgB;AAChB;AAAA,MACF;AAGA,UAAI,CAAC,QAAS;AACd,YAAM,IAAI,MAAM;AAAA,QACd,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,MACP,CAAC;AACD,sBAAgB;AAAA,IAClB,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,SAAS,WAAW,WAAW,eAAe,aAAa,CAAC;AAEhE,QAAM,mBAAe,0BAAY,YAAY;AAC3C,UAAM,OAAO,eAAe,IAAI,KAAK;AACrC,QAAI,CAAC,IAAK;AACV,QAAI;AACF,qBAAe,IAAI;AACnB,mBAAa;AACb,YAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,yBAAyB,IAAI,MAAM,GAAG;AACnE,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,OAAO,IAAI,gBAAgB,IAAI;AACrC,YAAM,IAAI,SAAS,cAAc,GAAG;AACpC,QAAE,OAAO;AACT,QAAE,WAAW,oBAAoB;AACjC,eAAS,KAAK,YAAY,CAAC;AAC3B,QAAE,MAAM;AACR,QAAE,OAAO;AACT,UAAI,gBAAgB,IAAI;AAAA,IAC1B,QAAQ;AAAA,IAER,UAAE;AACA,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,aAAa,kBAAkB,UAAU,CAAC;AAE9C,QAAM,oBAAgB,0BAAY,MAAM;AACtC,oBAAgB,SAAS,SAAS;AAAA,EACpC,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,QAAM,oBAAgB,0BAAY,MAAM;AACtC,oBAAgB,SAAS,SAAS;AAAA,EACpC,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,QAAM,aAAS,0BAAY,MAAM;AAC/B,aAAS,SAAS,SAAS;AAAA,EAC7B,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,QAAM,oBAAgB,0BAAY,MAAM;AACtC,oBAAgB,OAAO;AAAA,EACzB,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,qBAAiB,0BAAY,MAAM;AACvC,kBAAc;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAc,0BAAY,MAAM;AACpC,eAAW;AAAA,EACb,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAe,0BAAY,MAAM;AACrC,gBAAY;AAAA,EACd,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAgB,0BAAY,MAAM;AACtC,oBAAgB,OAAO;AAAA,EACzB,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,eAAW,0BAAY,MAAM;AACjC,gBAAY,SAAS,SAAS;AAAA,EAChC,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,QAAM,iBAAa,0BAAY,MAAM;AACnC,kBAAc,SAAS,WAAW,YAAY;AAAA,EAChD,GAAG,CAAC,SAAS,WAAW,YAAY,CAAC;AAErC,QAAM,oBAAgB,0BAAY,MAAM;AACtC,oBAAgB,OAAO;AAAA,EACzB,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,kBAAc,0BAAY,MAAM;AACpC,kBAAc,SAAS,SAAS;AAAA,EAClC,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOO,SAAS,UAAU,KAAyB,UAAqB,aAItE;AACA,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAwB,IAAI;AACxD,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAwB,IAAI;AAGtD,QAAM,iBAAa,qBAAO,OAAO;AACjC,8BAAU,MAAM;AACd,eAAW,UAAU;AAAA,EACvB,CAAC;AAED,8BAAU,MAAM;AACd,QAAI,CAAC,KAAK;AACR,gBAAU,IAAI;AACd,iBAAW,KAAK;AAChB,eAAS,IAAI;AACb;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,eAAW,IAAI;AACf,aAAS,IAAI;AAEb,eAAW,QAAQ,GAAG,EACnB,KAAK,CAAC,SAAS;AACd,UAAI,CAAC,WAAW;AACd,kBAAU,IAAI;AACd,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,CAAC,WAAW;AACd,iBAAS,eAAe,QAAQ,IAAI,UAAU,yBAAyB;AACvE,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AAER,SAAO,EAAE,QAAQ,SAAS,MAAM;AAClC;;;AGxUA,gBAMO;AACP,gBAQO;AACP,iBAAkD;AAoFV;AA1DjC,IAAM,eAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,kBAAsD;AAAA,EACjE,QAAQ,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EACzC,MAAM,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EACvC,UAAU,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EAC3C,UAAU,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EAC3C,UAAU,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EAC3C,WAAW,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EAC5C,UAAU,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EAC3C,UAAU,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EAC3C,KAAK,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EACtC,OAAO,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EACxC,UAAU,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EAC3C,QAAQ,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EACzC,GAAG,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EACpC,QAAQ,EAAE,IAAI,WAAW,MAAM,UAAU;AAAA,EACzC,SAAS,EAAE,IAAI,WAAW,MAAM,UAAU;AAC5C;AAGO,IAAM,kBAA+C;AAAA,EAC1D,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,KAAK;AAAA,EACL,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,GAAG;AAAA,EACH,QAAQ;AAAA,EACR,SAAS;AACX;AAGO,IAAM,iBAAmG;AAAA,EAC9G,QAAQ,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,oBAAO,MAAY,WAAsB;AAAA,EAChF,MAAM,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,oBAAO,MAAY,WAAsB;AAAA,EAC9E,UAAU,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,wBAAW,MAAY,WAAsB;AAAA,EACtF,UAAU,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,wBAAW,MAAY,WAAsB;AAAA,EACtF,UAAU,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,6BAAgB,MAAY,WAAsB;AAAA,EAC3F,WAAW,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,yBAAY,MAAY,WAAsB;AAAA,EACxF,UAAU,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,yBAAY,MAAY,WAAsB;AAAA,EACvF,UAAU,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,yBAAW,MAAY,WAAsB;AAAA,EACtF,KAAK,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,6BAAgB,MAAY,WAAsB;AAAA,EACtF,OAAO,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,oBAAO,MAAY,WAAsB;AAAA,EAC/E,UAAU,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,wBAAW,MAAY,WAAsB;AAAA,EACtF,QAAQ,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,sBAAS,MAAY,WAAsB;AAAA,EAClF,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,yBAAW,MAAY,WAAsB;AAAA,EAC/E,QAAQ,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,sBAAS,MAAY,WAAsB;AAAA,EAClF,SAAS,CAAC,EAAE,OAAO,IAAI,UAAU,MAAM,4CAAC,wBAAU,MAAY,WAAsB;AACtF;AAGO,IAAM,oBAAiD;AAAA,EAC5D,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,KAAK;AAAA,EACL,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,GAAG;AAAA,EACH,QAAQ;AAAA,EACR,SAAS;AACX;AAGO,IAAM,YAAiD,OAAO;AAAA,EACnE,aAAa,IAAI,CAAC,OAAO;AAAA,IACvB;AAAA,IACA;AAAA,MACE;AAAA,MACA,OAAO,gBAAgB,EAAE;AAAA,MACzB,QAAQ,gBAAgB,EAAE;AAAA,MAC1B,MAAM,eAAe,EAAE;AAAA,MACvB,QAAQ,kBAAkB,EAAE;AAAA,IAC9B;AAAA,EACF,CAAC;AACH;;;ACnJO,IAAM,cAAc;AAAA;AAAA,EAEzB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,cAAc;AAAA,EACd,UAAU;AAAA;AAAA,EAEV,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,kBAAkB;AAAA;AAAA,EAElB,WAAW;AAAA,EACX,gBAAgB;AAClB;AAGO,IAAM,sBAAsB;AAAA,EACjC,CAAC,YAAY,SAAS,GAAG;AAAA,EACzB,CAAC,YAAY,QAAQ,GAAG;AAAA,EACxB,CAAC,YAAY,YAAY,GAAG;AAAA,EAC5B,CAAC,YAAY,QAAQ,GAAG;AAAA,EACxB,CAAC,YAAY,UAAU,GAAG;AAAA,EAC1B,CAAC,YAAY,aAAa,GAAG;AAAA,EAC7B,CAAC,YAAY,gBAAgB,GAAG;AAAA,EAChC,CAAC,YAAY,SAAS,GAAG;AAAA,EACzB,CAAC,YAAY,cAAc,GAAG;AAChC;AAuMO,IAAM,WAAW;AAEjB,IAAM,mBAAmB;;;AN1EL,IAAAC,sBAAA;AAxI3B,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAG1B,IAAM,iBAAiB;AAAA,EACrB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,aAAa;AACf;AAGA,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAezB,SAAS,OAAO,MAAc,UAA0B;AACtD,SAAO,OAAO,IAAI,KAAK,QAAQ;AACjC;AAEO,SAAS,kBAAkB;AAAA,EAChC,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa,CAAC;AAAA,EACd,aAAa;AAAA,EACb,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO,CAAC;AAAA,EACR;AAAA,EACA,SAAS,CAAC;AAAA,EACV,QAAQ,CAAC;AACX,GAA2B;AACzB,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,KAAK;AAIlD,QAAM,EAAE,QAAQ,SAAS,UAAU,IAAI,UAAU,gBAAgB,CAAC,eAAe,SAAY,UAAU,YAAY;AAEnH,QAAM,sBAAkB,2BAAY,MAAM;AACxC,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,QAAM,uBAAmB,2BAAY,MAAM;AACzC,kBAAc,IAAI;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,cAAc;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,QAAM,mBAAgD,uBAAQ,OAAO;AAAA,IACnE,QAAQ,MAAM,KAAK,WAAW,YAAY;AAAA,IAC1C,MAAM,MAAM,KAAK,WAAW,SAAS;AAAA,IACrC,UAAU,MAAM,KAAK,WAAW,aAAa;AAAA,IAC7C,UAAU,WAAW;AAAA,IACrB,UAAU,WAAW;AAAA,IACrB,WAAW,WAAW;AAAA,IACtB,UAAU,WAAW;AAAA,IACrB,UAAU,WAAW;AAAA,IACrB,KAAK,WAAW;AAAA,IAChB,OAAO,WAAW;AAAA,IAClB,UAAU,WAAW;AAAA,IACrB,QAAQ,WAAW;AAAA,IACnB,GAAG,WAAW;AAAA,IACd,QAAQ,WAAW;AAAA,IACnB,SAAS,WAAW;AAAA,EACtB,IAAI,CAAC,UAAU,CAAC;AAGhB,QAAM,oBAAsD,uBAAQ,OAAO;AAAA,IACzE,MAAM,WAAW,SAAS,YAAY,gBAAgB;AAAA,IACtD,UAAU,WAAW,cAAc,QAAQ,gBAAgB;AAAA,EAC7D,IAAI,CAAC,WAAW,QAAQ,WAAW,WAAW,CAAC;AAG/C,QAAM,cAA+B,uBAAQ,MAAM;AACjD,WAAO,aAAa,IAAI,CAAC,OAAO;AAC9B,YAAM,OAAO,eAAe,EAAE;AAC9B,YAAM,eAAe,cAAc,EAAE,KAAK,gBAAgB,EAAE;AAC5D,YAAM,eAAe,WAAW,qBAAqB,EAAE;AAGvD,UAAI,YAAY;AAChB,UAAI,OAAO,UAAU;AACnB,oBAAY,WAAW;AAAA,MACzB,WAAW,OAAO,YAAY;AAC5B,oBAAY,CAAC,CAAC;AAAA,MAChB,WAAW,CAAC,aAAa,WAAW;AAElC,oBAAY;AAAA,MACd;AAEA,aAAO;AAAA,QACL;AAAA,QACA,OAAO,OAAO,EAAE,KAAK;AAAA,QACrB,MAAM,MAAM,EAAE,KAAK,6CAAC,QAAK,MAAM,UAAU;AAAA;AAAA,QAEzC,SAAS,OAAO,kBAAkB,EAAE,GAAG,gBAAgB,EAAE,EAAE,EAAE;AAAA,QAC7D,WAAW,gBAAgB,EAAE,EAAE;AAAA,QAC/B,SAAS,MAAM;AACb,oBAAU,EAAE;AACZ,uBAAa,EAAE,EAAE;AAAA,QACnB;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,QAAQ,OAAO,eAAe,cAAc,SAAS,WAAW,gBAAgB,WAAW,sBAAsB,WAAW,CAAC;AAE3I,QAAM,qBAAiB,uBAAQ,MAAM;AAEnC,QAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,aAAO,KACJ,IAAI,CAAC,OAAO,QAAQ,KAAK,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC,EAChD,OAAO,CAAC,QAAwC;AAC/C,YAAI,CAAC,IAAK,QAAO;AACjB,YAAI,IAAI,cAAc,MAAO,QAAO;AACpC,YAAI,KAAK,SAAS,IAAI,EAAE,EAAG,QAAO;AAClC,eAAO;AAAA,MACT,CAAC;AAAA,IACL;AAGA,WAAO,QAAQ,OAAO,CAAC,QAAQ;AAC7B,UAAI,IAAI,cAAc,MAAO,QAAO;AACpC,UAAI,KAAK,SAAS,IAAI,EAAE,EAAG,QAAO;AAClC,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,MAAM,IAAI,CAAC;AAExB,QAAM,UAAU,OAAO,YAAY,WAAW,oBAAoB,YAAY,SAAS,CAAC;AACxF,QAAM,eAAe,OAAO,YAAY,gBAAgB,oBAAoB,YAAY,cAAc,CAAC;AACvG,QAAM,YAAY,OAAO,YAAY,eAAe,oBAAoB,YAAY,aAAa,CAAC;AAGlG,QAAM,gBAAgB,MAAM;AAE1B,UAAM,UAAU,gBAAgB,QAAQ;AACxC,UAAM,WAAW,WAAW,CAAC;AAC7B,UAAM,YAAY,CAAC,gBAAgB;AAGnC,QAAI,WAAW;AACb,aACE,6CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,OAAO,OAAO,GAC1F;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,eAAe,iBAAiB,WAAW,eAAe;AAAA,UACxE,OAAO;AAAA,YACL,UAAU;AAAA,YACV,iBAAiB;AAAA,YACjB,OAAO;AAAA,YACP,UAAU;AAAA,YACV,aAAa;AAAA,YACb,UAAU;AAAA,YACV,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,gBAAgB;AAAA,UAClB;AAAA,UAEA;AAAA,yDAAC,SAAI,OAAO,EAAE,UAAU,YAAY,OAAO,GAAG,UAAU,SAAS,GAC/D;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,UAAU;AAAA,kBACV,OAAO;AAAA,kBACP,YAAY,uCAAuC,YAAY;AAAA,kBAC/D,WAAW;AAAA,gBACb;AAAA;AAAA,YACF,GACF;AAAA,YACA,6CAAC,sBAAQ,MAAM,IAAI,OAAO,EAAE,OAAO,WAAW,SAAS,IAAI,GAAG;AAAA;AAAA;AAAA,MAChE,GACF;AAAA,IAEJ;AAGA,QAAI,CAAC,UAAU;AACb,aACE,6CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,OAAO,OAAO,GAC1F;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,eAAe,iBAAiB,WAAW,eAAe;AAAA,UACxE,OAAO;AAAA,YACL,UAAU;AAAA,YACV,iBAAiB;AAAA,YACjB,OAAO;AAAA,YACP,UAAU;AAAA,YACV,aAAa;AAAA,YACb,UAAU;AAAA,YACV,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,gBAAgB;AAAA,UAClB;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,eAAe;AAAA,gBACf,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,KAAK;AAAA,gBACL,SAAS;AAAA,cACX;AAAA,cAEA;AAAA,6DAAC,sBAAQ,MAAM,IAAI,OAAO,EAAE,OAAO,WAAW,SAAS,IAAI,GAAG;AAAA,gBAC7D,QAAQ,SACP;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,OAAO;AAAA,sBACP,UAAU;AAAA,sBACV,SAAS;AAAA,sBACT,WAAW;AAAA,sBACX,UAAU;AAAA,sBACV,UAAU;AAAA,sBACV,cAAc;AAAA,sBACd,SAAS;AAAA,sBACT,iBAAiB;AAAA,sBACjB,iBAAiB;AAAA,oBACnB;AAAA,oBAEC,iBAAO;AAAA;AAAA,gBACV;AAAA;AAAA;AAAA,UAEJ;AAAA;AAAA,MACF,GACF;AAAA,IAEJ;AAGA,UAAM,YAAY,OAAO,YAAY,YAAY,QAAQ,WAAW,OAAO;AAC3E,QAAI,WAAW;AACb,aACE,6CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,OAAO,OAAO,GAE1F;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAI;AAAA,UACJ,WAAW,GAAG,eAAe,cAAc,WAAW,YAAY;AAAA,UAClE,OAAO;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,QAAQ;AAAA,UACV;AAAA;AAAA,MACF,GACF;AAAA,IAEJ;AAGA,QAAI,CAAC,aAAa;AAChB,aACE,8CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,OAAO,OAAO,GAC1F;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,GAAG,eAAe,iBAAiB,WAAW,eAAe;AAAA,YACxE,OAAO;AAAA,cACL,UAAU;AAAA,cACV,iBAAiB;AAAA,cACjB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa;AAAA,cACb,UAAU;AAAA,cACV,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,YAClB;AAAA,YAEA;AAAA,2DAAC,SAAI,OAAO,EAAE,UAAU,YAAY,OAAO,GAAG,UAAU,SAAS,GAC/D;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,OAAO;AAAA,oBACP,YAAY,uCAAuC,YAAY;AAAA,oBAC/D,WAAW;AAAA,kBACb;AAAA;AAAA,cACF,GACF;AAAA,cACA,6CAAC,sBAAQ,MAAM,IAAI,OAAO,EAAE,OAAO,WAAW,SAAS,IAAI,GAAG;AAAA;AAAA;AAAA,QAChE;AAAA,QAGA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK,QAAQ,SAAS;AAAA,YACtB,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,OAAO,EAAE,SAAS,OAAO;AAAA;AAAA,QAC3B;AAAA,SACF;AAAA,IAEJ;AAGA,WACE,6CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,OAAO,OAAO,GAE1F;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,KAAK,QAAQ,SAAS;AAAA,QACtB,WAAW,GAAG,eAAe,cAAc,WAAW,cAAc,mBAAmB;AAAA,QACvF,OAAO;AAAA,UACL,OAAO;AAAA,UACP,UAAU;AAAA,UACV,QAAQ;AAAA,QACV;AAAA;AAAA,IACF,GACF;AAAA,EAEJ;AAEA,SACE,8CAAC,SAAI,WAAW,GAAG,eAAe,MAAM,WAAW,MAAM,SAAS,GAEhE;AAAA,iDAAC,WAAM,yBAAyB,EAAE,QAAQ,iBAAiB,GAAG;AAAA,IAE9D,8CAAC,SAAI,WAAW,GAAG,eAAe,QAAQ,WAAW,MAAM,GACzD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,eAAe,OAAO,WAAW,KAAK;AAAA,UACpD,OAAO,EAAE,OAAO,OAAO,YAAY,YAAY,oBAAoB,YAAY,UAAU,CAAC,EAAE;AAAA,UAE3F;AAAA;AAAA,MACH;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,eAAe,UAAU,WAAW,QAAQ;AAAA,UAC1D,OAAO,EAAE,OAAO,OAAO,YAAY,eAAe,oBAAoB,YAAY,aAAa,CAAC,EAAE;AAAA,UAEjG;AAAA;AAAA,MACH;AAAA,OACF;AAAA,IAGA,6CAAC,SAAI,WAAW,GAAG,eAAe,SAAS,WAAW,OAAO,GAC1D,wBAAc,GACjB;AAAA,IAEA,6CAAC,SAAI,WAAW,GAAG,eAAe,MAAM,WAAW,IAAI,GACpD,yBAAe,IAAI,CAAC,QACnB;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,WAAW,GAAG,eAAe,QAAQ,WAAW,MAAM;AAAA,QACtD,SAAS,IAAI;AAAA,QAEb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,GAAG,eAAe,YAAY,WAAW,UAAU;AAAA,cAC9D,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,iBAAiB,IAAI;AAAA,gBACrB,OAAO,IAAI;AAAA,cACb;AAAA,cAEC,cAAI;AAAA;AAAA,UACP;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,GAAG,eAAe,aAAa,WAAW,WAAW;AAAA,cAChE,OAAO,EAAE,OAAO,OAAO,YAAY,kBAAkB,oBAAoB,YAAY,gBAAgB,CAAC,EAAE;AAAA,cAEvG,cAAI;AAAA;AAAA,UACP;AAAA;AAAA;AAAA,MArBK,IAAI;AAAA,IAsBX,CACD,GACH;AAAA,KACF;AAEJ;AAIO,IAAM,mBAAmB;","names":["import_react","import_lu","import_jsx_runtime"]}
|
package/dist/content.mjs
CHANGED
|
@@ -85,7 +85,7 @@ function warnUnavailablePlatform(platform, reason) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// src/hooks.ts
|
|
88
|
-
import { useState, useCallback, useEffect } from "react";
|
|
88
|
+
import { useState, useCallback, useEffect, useRef } from "react";
|
|
89
89
|
|
|
90
90
|
// src/og-fetcher.ts
|
|
91
91
|
var ogCache = /* @__PURE__ */ new Map();
|
|
@@ -376,10 +376,14 @@ function useShareSheet({
|
|
|
376
376
|
shareReddit
|
|
377
377
|
};
|
|
378
378
|
}
|
|
379
|
-
function useOGData(url) {
|
|
379
|
+
function useOGData(url, fetcher = fetchOGData) {
|
|
380
380
|
const [ogData, setOgData] = useState(null);
|
|
381
381
|
const [loading, setLoading] = useState(false);
|
|
382
382
|
const [error, setError] = useState(null);
|
|
383
|
+
const fetcherRef = useRef(fetcher);
|
|
384
|
+
useEffect(() => {
|
|
385
|
+
fetcherRef.current = fetcher;
|
|
386
|
+
});
|
|
383
387
|
useEffect(() => {
|
|
384
388
|
if (!url) {
|
|
385
389
|
setOgData(null);
|
|
@@ -390,7 +394,7 @@ function useOGData(url) {
|
|
|
390
394
|
let cancelled = false;
|
|
391
395
|
setLoading(true);
|
|
392
396
|
setError(null);
|
|
393
|
-
|
|
397
|
+
fetcherRef.current(url).then((data) => {
|
|
394
398
|
if (!cancelled) {
|
|
395
399
|
setOgData(data);
|
|
396
400
|
setLoading(false);
|
|
@@ -595,6 +599,7 @@ function ShareSheetContent({
|
|
|
595
599
|
downloadUrl,
|
|
596
600
|
downloadFilename,
|
|
597
601
|
previewImage,
|
|
602
|
+
fetchPreview,
|
|
598
603
|
shareFile,
|
|
599
604
|
shareFilename,
|
|
600
605
|
className,
|
|
@@ -612,7 +617,7 @@ function ShareSheetContent({
|
|
|
612
617
|
}) {
|
|
613
618
|
const [imageLoaded, setImageLoaded] = useState2(false);
|
|
614
619
|
const [imageError, setImageError] = useState2(false);
|
|
615
|
-
const { ogData, loading: ogLoading } = useOGData(previewImage ? void 0 : shareUrl);
|
|
620
|
+
const { ogData, loading: ogLoading } = useOGData(previewImage || !fetchPreview ? void 0 : shareUrl, fetchPreview);
|
|
616
621
|
const handleImageLoad = useCallback2(() => {
|
|
617
622
|
setImageLoaded(true);
|
|
618
623
|
}, []);
|
|
@@ -927,6 +932,7 @@ export {
|
|
|
927
932
|
PLATFORM_COLORS,
|
|
928
933
|
PLATFORM_CSS_VARS,
|
|
929
934
|
ShareMenuContent,
|
|
930
|
-
ShareSheetContent
|
|
935
|
+
ShareSheetContent,
|
|
936
|
+
fetchOGData
|
|
931
937
|
};
|
|
932
938
|
//# sourceMappingURL=content.mjs.map
|