react-sharesheet 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +84 -102
  2. package/dist/content.d.mts +3 -3
  3. package/dist/content.d.ts +3 -3
  4. package/dist/content.js +296 -271
  5. package/dist/content.js.map +1 -1
  6. package/dist/content.mjs +298 -273
  7. package/dist/content.mjs.map +1 -1
  8. package/dist/drawer.d.mts +3 -3
  9. package/dist/drawer.d.ts +3 -3
  10. package/dist/drawer.js +298 -275
  11. package/dist/drawer.js.map +1 -1
  12. package/dist/drawer.mjs +300 -277
  13. package/dist/drawer.mjs.map +1 -1
  14. package/dist/headless-B7I228Dt.d.mts +98 -0
  15. package/dist/headless-BiSYHizs.d.ts +98 -0
  16. package/dist/headless.d.mts +3 -50
  17. package/dist/headless.d.ts +3 -50
  18. package/dist/headless.js +165 -0
  19. package/dist/headless.js.map +1 -1
  20. package/dist/headless.mjs +163 -1
  21. package/dist/headless.mjs.map +1 -1
  22. package/dist/index.d.mts +2 -2
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +339 -277
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +329 -278
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/{platforms-DU1DVDFq.d.mts → platforms-omqzPfYX.d.mts} +17 -23
  29. package/dist/{platforms-DU1DVDFq.d.ts → platforms-omqzPfYX.d.ts} +17 -23
  30. package/package.json +24 -7
  31. package/src/ShareSheetContent.tsx +157 -311
  32. package/src/ShareSheetDrawer.tsx +2 -4
  33. package/src/__tests__/hooks.test.ts +203 -0
  34. package/src/__tests__/og-fetcher.test.ts +144 -0
  35. package/src/__tests__/platforms.test.ts +148 -0
  36. package/src/__tests__/setup.ts +22 -0
  37. package/src/__tests__/share-functions.test.ts +152 -0
  38. package/src/__tests__/utils.test.ts +64 -0
  39. package/src/headless.ts +4 -1
  40. package/src/hooks.ts +60 -2
  41. package/src/index.ts +20 -4
  42. package/src/og-fetcher.ts +64 -0
  43. package/src/share-functions.ts +25 -1
  44. package/src/types.ts +17 -24
  45. package/src/utils.ts +125 -0
package/README.md CHANGED
@@ -3,19 +3,24 @@
3
3
  [![npm version](https://img.shields.io/npm/v/react-sharesheet.svg)](https://www.npmjs.com/package/react-sharesheet)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/react-sharesheet.svg)](https://www.npmjs.com/package/react-sharesheet)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Demo](https://img.shields.io/badge/demo-live-brightgreen.svg)](https://sharesheet.gwendall.com)
6
7
 
7
- A beautiful, fully customizable share sheet component for React. Supports 15+ social platforms with a modern drawer UI, CSS variable theming, and headless mode for complete control.
8
+ A mobile-first share sheet for React with native share support, built-in Open Graph previews, and 15+ social platforms.
8
9
 
9
- ## Features
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.
10
11
 
11
- - 🎨 **Fully themeable** — CSS variables + Tailwind class overrides
12
- - 🧩 **Headless mode** — Use the hook to build your own UI
13
- - 📱 **Mobile-first** — Beautiful drawer with native share API support
14
- - 🔧 **Customizable** — Hide/show platforms, custom labels & icons
15
- - 📦 **Tree-shakeable** — Import only what you need
16
- - 🌐 **15+ platforms** — WhatsApp, X, Telegram, Instagram, and more
12
+ **[→ Live Demo](https://sharesheet.gwendall.com)**
17
13
 
18
- ## 📦 Installation
14
+ ## Why react-sharesheet?
15
+
16
+ - 📱 **Mobile-first drawer UI** - feels native on iOS & Android
17
+ - 🔗 **Native Web Share API** - fallback handled automatically
18
+ - 🖼 **Built-in Open Graph previews** - no extra setup
19
+ - 🧠 **Headless APIs** - build your own UI if needed
20
+ - 🎨 **Themeable** - CSS variables + Tailwind class overrides
21
+ - 🌍 **15+ social platforms** - WhatsApp, X, Telegram, Instagram, and more
22
+
23
+ ## Installation
19
24
 
20
25
  ```bash
21
26
  npm install react-sharesheet
@@ -40,13 +45,13 @@ Add the package to your `tailwind.config.js` content array:
40
45
  module.exports = {
41
46
  content: [
42
47
  "./src/**/*.{js,ts,jsx,tsx}",
43
- "./node_modules/react-sharesheet/dist/**/*.{js,mjs}", // 👈 Add this
48
+ "./node_modules/react-sharesheet/dist/**/*.{js,mjs}", // <-- Add this
44
49
  ],
45
50
  // ...
46
51
  }
47
52
  ```
48
53
 
49
- ## 🚀 Quick Start
54
+ ## Quick Start
50
55
 
51
56
  ### Full Drawer (recommended)
52
57
 
@@ -112,75 +117,60 @@ function CustomShareUI() {
112
117
  }
113
118
  ```
114
119
 
115
- ## 🖼️ Content Preview
120
+ ## Automatic Link Preview
116
121
 
117
- The share sheet can display a preview of the content being shared. It automatically detects the content type based on the URL and displays an appropriate preview.
118
-
119
- ### Auto-detection
122
+ The share sheet automatically fetches Open Graph (OG) metadata from the `shareUrl` and displays a rich preview - just like Twitter, Telegram, and other platforms do when you paste a link.
120
123
 
121
124
  ```tsx
122
- // Image preview (detected from extension)
123
- <ShareSheetDrawer preview="https://example.com/image.png" {...props} />
124
-
125
- // Video preview (detected from extension)
126
- <ShareSheetDrawer preview="https://example.com/video.mp4" {...props} />
125
+ <ShareSheetDrawer
126
+ shareUrl="https://gwendall.com" // OG data fetched automatically!
127
+ shareText="Check out this site!"
128
+ >
129
+ <button>Share</button>
130
+ </ShareSheetDrawer>
131
+ ```
127
132
 
128
- // Audio file (shows icon + filename)
129
- <ShareSheetDrawer preview="https://example.com/song.mp3" {...props} />
133
+ The component will:
134
+ 1. Fetch OG metadata (title, description, image) from the URL
135
+ 2. Display a loading shimmer while fetching
136
+ 3. Show the OG image if available, or a placeholder with the page title
130
137
 
131
- // Link (shows link icon + URL)
132
- <ShareSheetDrawer preview="https://example.com/page" {...props} />
133
- ```
138
+ ### Using the OG Hook Directly
134
139
 
135
- ### Explicit Type
140
+ You can also use the `useOGData` hook for custom implementations:
136
141
 
137
142
  ```tsx
138
- // Force image type (e.g., for API endpoints)
139
- <ShareSheetDrawer
140
- preview={{ url: "/api/og?id=123", type: "image" }}
141
- {...props}
142
- />
143
+ import { useOGData } from "react-sharesheet/headless";
143
144
 
144
- // Video with poster image
145
- <ShareSheetDrawer
146
- preview={{
147
- url: "https://example.com/video.mp4",
148
- type: "video",
149
- poster: "https://example.com/thumbnail.jpg"
150
- }}
151
- {...props}
152
- />
145
+ function CustomPreview({ url }: { url: string }) {
146
+ const { ogData, loading, error } = useOGData(url);
153
147
 
154
- // File with custom filename
155
- <ShareSheetDrawer
156
- preview={{
157
- url: "https://example.com/doc.pdf",
158
- type: "file",
159
- filename: "Report Q4 2024.pdf"
160
- }}
161
- {...props}
162
- />
148
+ if (loading) return <div>Loading...</div>;
149
+ if (!ogData) return <div>No preview available</div>;
150
+
151
+ return (
152
+ <div>
153
+ {ogData.image && <img src={ogData.image} alt={ogData.title} />}
154
+ <h3>{ogData.title}</h3>
155
+ <p>{ogData.description}</p>
156
+ </div>
157
+ );
158
+ }
163
159
  ```
164
160
 
165
- ### PreviewConfig
161
+ ### OGData Type
166
162
 
167
163
  ```ts
168
- interface PreviewConfig {
169
- url: string; // URL of the content
170
- type?: PreviewType; // "image" | "video" | "audio" | "file" | "link" | "auto"
171
- filename?: string; // Display name for file/audio types
172
- alt?: string; // Alt text for images
173
- poster?: string; // Poster image for videos
164
+ interface OGData {
165
+ title?: string; // Page title
166
+ description?: string; // Page description
167
+ image?: string; // OG image URL
168
+ url?: string; // Canonical URL
169
+ siteName?: string; // Site name
174
170
  }
175
171
  ```
176
172
 
177
- ### Supported Formats
178
-
179
- - **Images**: jpg, jpeg, png, gif, webp, svg, bmp, ico, avif
180
- - **Videos**: mp4, webm, mov, avi, mkv, m4v, ogv
181
- - **Audio**: mp3, wav, ogg, m4a, aac, flac, wma
182
-
183
- ## 🎨 Theming
173
+ ## Theming
184
174
 
185
175
  ### CSS Variables
186
176
 
@@ -287,7 +277,7 @@ Override any part of the component with `classNames`:
287
277
  >
288
278
  ```
289
279
 
290
- ## ⚙️ API Reference
280
+ ## API Reference
291
281
 
292
282
  ### Props
293
283
 
@@ -296,22 +286,21 @@ Override any part of the component with `classNames`:
296
286
  | Prop | Type | Default | Description |
297
287
  |------|------|---------|-------------|
298
288
  | `title` | `string` | `"Share"` | Title displayed at the top |
299
- | `shareUrl` | `string` | **required** | URL to share |
289
+ | `shareUrl` | `string` | **required** | URL to share (OG preview fetched automatically) |
300
290
  | `shareText` | `string` | **required** | Text to share |
301
- | `preview` | `string \| PreviewConfig` | | Preview of content (see Preview section below) |
302
- | `downloadUrl` | `string` | | URL for download button |
303
- | `downloadFilename` | `string` | | Filename for download |
304
- | `className` | `string` | | Class for root container |
305
- | `classNames` | `object` | — | Override sub-component classes |
291
+ | `downloadUrl` | `string` | - | URL for download button |
292
+ | `downloadFilename` | `string` | - | Filename for download |
293
+ | `className` | `string` | - | Class for root container |
294
+ | `classNames` | `object` | - | Override sub-component classes |
306
295
  | `buttonSize` | `number` | `45` | Button size in pixels |
307
296
  | `iconSize` | `number` | `22` | Icon size in pixels |
308
- | `show` | `ShareOption[]` | | Only show these platforms |
309
- | `hide` | `ShareOption[]` | | Hide these platforms |
310
- | `labels` | `object` | | Custom button labels |
311
- | `icons` | `object` | | Custom button icons |
312
- | `onNativeShare` | `() => void` | | Native share callback |
313
- | `onCopy` | `() => void` | | Copy callback |
314
- | `onDownload` | `() => void` | | Download callback |
297
+ | `show` | `ShareOption[]` | - | Only show these platforms |
298
+ | `hide` | `ShareOption[]` | - | Hide these platforms |
299
+ | `labels` | `object` | - | Custom button labels |
300
+ | `icons` | `object` | - | Custom button icons |
301
+ | `onNativeShare` | `() => void` | - | Native share callback |
302
+ | `onCopy` | `() => void` | - | Copy callback |
303
+ | `onDownload` | `() => void` | - | Download callback |
315
304
 
316
305
  #### ShareSheetDrawer (additional)
317
306
 
@@ -319,8 +308,8 @@ Override any part of the component with `classNames`:
319
308
  |------|------|---------|-------------|
320
309
  | `children` | `ReactNode` | **required** | Trigger element |
321
310
  | `disabled` | `boolean` | `false` | Disable the trigger |
322
- | `open` | `boolean` | | Controlled open state |
323
- | `onOpenChange` | `(open: boolean) => void` | | Open state callback |
311
+ | `open` | `boolean` | - | Controlled open state |
312
+ | `onOpenChange` | `(open: boolean) => void` | - | Open state callback |
324
313
 
325
314
  ### ShareOption
326
315
 
@@ -384,7 +373,7 @@ const {
384
373
  });
385
374
  ```
386
375
 
387
- ## 📦 Exports
376
+ ## Exports
388
377
 
389
378
  ```ts
390
379
  // Everything
@@ -425,7 +414,7 @@ import {
425
414
  } from "react-sharesheet/headless";
426
415
  ```
427
416
 
428
- ## 🎨 Platform Utilities
417
+ ## Platform Utilities
429
418
 
430
419
  Access platform colors, icons, and labels for custom UIs:
431
420
 
@@ -478,7 +467,7 @@ function WhatsAppButton({ url, text }: { url: string; text: string }) {
478
467
  }
479
468
  ```
480
469
 
481
- ## 🛠 Examples
470
+ ## Examples
482
471
 
483
472
  ### Filter platforms
484
473
 
@@ -547,35 +536,28 @@ function ControlledExample() {
547
536
  }
548
537
  ```
549
538
 
550
- ## 📋 Requirements
551
-
552
- - React 18+
553
- - Tailwind CSS (for default styling)
539
+ ## Styling & Tailwind
554
540
 
555
- > **Note:** If you're not using Tailwind, you can use the headless hook to build your own UI, or override all classes via `classNames`.
541
+ react-sharesheet ships with a Tailwind-based UI by default.
556
542
 
557
- ## 🔄 Migration from v0.x
543
+ Tailwind is **only required if you use the prebuilt components**.
544
+ If you don't use Tailwind, you can:
558
545
 
559
- If you're upgrading from `@gwendall/share-menu`:
546
+ - Use the **headless hook** to build your own UI
547
+ - Override all styles via `classNames`
548
+ - Use the exposed CSS variables
560
549
 
561
- ```tsx
562
- // Old imports
563
- import { ShareMenuDrawer, ShareMenuContent, useShareMenu } from "@gwendall/share-menu";
550
+ This makes react-sharesheet easy to integrate into any React stack.
564
551
 
565
- // New imports (backwards compatible aliases available)
566
- import { ShareSheetDrawer, ShareSheetContent, useShareSheet } from "react-sharesheet";
552
+ ## Requirements
567
553
 
568
- // CSS variables changed from --share-menu-* to --sharesheet-*
569
- // Old: --share-menu-drawer-bg
570
- // New: --sharesheet-drawer-bg
571
- ```
572
-
573
- Legacy exports (`ShareMenuDrawer`, `ShareMenuContent`, `useShareMenu`) are still available but deprecated.
554
+ - React 18+
555
+ - Tailwind CSS (only for prebuilt components)
574
556
 
575
- ## 🤝 Contributing
557
+ ## Contributing
576
558
 
577
559
  Contributions are welcome! Please feel free to submit a Pull Request.
578
560
 
579
- ## 📄 License
561
+ ## License
580
562
 
581
563
  MIT © [Gwendall](https://github.com/gwendall)
@@ -1,9 +1,9 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { S as ShareSheetContentProps } from './platforms-DU1DVDFq.mjs';
3
- export { m as CSS_VARS, C as CSS_VARS_UI, n as CSS_VAR_DEFAULTS, l as CSS_VAR_UI_DEFAULTS, q as PLATFORM_COLORS, t as PLATFORM_CSS_VARS, f as ShareMenuContentClassNames, d as ShareMenuContentProps, h as ShareOption, b as ShareSheetContentClassNames } from './platforms-DU1DVDFq.mjs';
2
+ import { S as ShareSheetContentProps } from './platforms-omqzPfYX.mjs';
3
+ export { l as CSS_VARS, C as CSS_VARS_UI, m as CSS_VAR_DEFAULTS, k as CSS_VAR_UI_DEFAULTS, p as PLATFORM_COLORS, s as PLATFORM_CSS_VARS, f as ShareMenuContentClassNames, d as ShareMenuContentProps, h as ShareOption, b as ShareSheetContentClassNames } from './platforms-omqzPfYX.mjs';
4
4
  import 'react';
5
5
 
6
- declare function ShareSheetContent({ title, shareUrl, shareText, preview, downloadUrl, downloadFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, onDownload, hide, show, labels, icons, }: ShareSheetContentProps): react_jsx_runtime.JSX.Element;
6
+ declare function ShareSheetContent({ title, shareUrl, shareText, downloadUrl, downloadFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, 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-DU1DVDFq.js';
3
- export { m as CSS_VARS, C as CSS_VARS_UI, n as CSS_VAR_DEFAULTS, l as CSS_VAR_UI_DEFAULTS, q as PLATFORM_COLORS, t as PLATFORM_CSS_VARS, f as ShareMenuContentClassNames, d as ShareMenuContentProps, h as ShareOption, b as ShareSheetContentClassNames } from './platforms-DU1DVDFq.js';
2
+ import { S as ShareSheetContentProps } from './platforms-omqzPfYX.js';
3
+ export { l as CSS_VARS, C as CSS_VARS_UI, m as CSS_VAR_DEFAULTS, k as CSS_VAR_UI_DEFAULTS, p as PLATFORM_COLORS, s as PLATFORM_CSS_VARS, f as ShareMenuContentClassNames, d as ShareMenuContentProps, h as ShareOption, b as ShareSheetContentClassNames } from './platforms-omqzPfYX.js';
4
4
  import 'react';
5
5
 
6
- declare function ShareSheetContent({ title, shareUrl, shareText, preview, downloadUrl, downloadFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, onDownload, hide, show, labels, icons, }: ShareSheetContentProps): react_jsx_runtime.JSX.Element;
6
+ declare function ShareSheetContent({ title, shareUrl, shareText, downloadUrl, downloadFilename, className, classNames, buttonSize, iconSize, onNativeShare, onCopy, 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