A bottom sheet with a scrim, a drag handle, a channel grid and a copy link row. It lives in its own frame, closes on drag down, scrim click or Escape.
npx shadcn@latest add https://hyperblur.dev/r/share-sheet.jsonWorks in any React project set up with the shadcn CLI. The file lands in components/hyperblur/share-sheet.tsx.
import { ShareSheet } from "@/components/hyperblur/share-sheet"
<ShareSheet height={320} url="https://example.com/post">{({ setOpen }) => <button onClick={() => setOpen(true)}>Share</button>}</ShareSheet>| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | (api: { open: boolean; setOpen: (open: boolean) => void }) => ReactNode | Content behind the sheet. A function receives the open state and a setter so you can place your own trigger. | |
| open | boolean | Controlled open state. Pair with onOpenChange. | |
| defaultOpen | boolean | false | Initial open state when uncontrolled. |
| onOpenChange | (open: boolean) => void | Called when the sheet opens or closes. | |
| url | string | "" | Link to share. Falls back to the current page address when empty. |
| title | string | "" | Title used for the email subject, the message text and the native share sheet. |
| heading | string | "Share" | Heading shown at the top of the sheet. |
| channels | { id: string; label: string; icon?: string; href?: string; onSelect?: () => void }[] | [messages, email, embed, native] | Channel grid entries. Email and messages build their links, embed copies an iframe snippet and native opens the system share sheet or copies the link. |
| height | number | string | 320 | Height of the frame that contains the content and the sheet. |
| accent | string | "#2f7bff" | Focus ring and hover highlight color. |
| onShare | (id: string) => void | Called with the channel id, or copy for the link row, when something is shared. |