### Install scrollsheet with bun Source: https://scrollsheet.dev/docs/getting-started/install Adds the scrollsheet package using the bun package manager. ```bash bun add scrollsheet ``` -------------------------------- ### Install scrollsheet components via shadcn CLI Source: https://scrollsheet.dev/docs/getting-started/install Installs all scrollsheet registry items (drawer, sheet, dialog, confirm, share-sheet, sidebar, toast) using the shadcn CLI. Each writes one file into components/ui/. The confirm and share-sheet items build on drawer, and sidebar builds on sheet; the CLI pulls those dependencies automatically. ```bash bunx shadcn@latest add https://scrollsheet.dev/r/drawer.json bunx shadcn@latest add https://scrollsheet.dev/r/sheet.json bunx shadcn@latest add https://scrollsheet.dev/r/dialog.json bunx shadcn@latest add https://scrollsheet.dev/r/confirm.json bunx shadcn@latest add https://scrollsheet.dev/r/share-sheet.json bunx shadcn@latest add https://scrollsheet.dev/r/sidebar.json bunx shadcn@latest add https://scrollsheet.dev/r/toast.json ``` -------------------------------- ### Centered dialog with Sheet.Root side="center" Source: https://scrollsheet.dev/docs/presentation/centered-dialog Basic centered dialog example. The panel is content-sized, centered, and uses zoom+fade. The example's own class sets the width; drag does nothing here. ```jsx Delete project Delete this project? This can't be undone. Cancel ``` -------------------------------- ### Install scrollsheet with pnpm Source: https://scrollsheet.dev/docs/getting-started/install Adds the scrollsheet package using the pnpm package manager. ```bash pnpm add scrollsheet ``` -------------------------------- ### Install scrollsheet with yarn Source: https://scrollsheet.dev/docs/getting-started/install Adds the scrollsheet package using the yarn package manager. ```bash yarn add scrollsheet ``` -------------------------------- ### Install scrollsheet with npm Source: https://scrollsheet.dev/docs/getting-started/install Adds the scrollsheet package using the npm package manager. ```bash npm i scrollsheet ``` -------------------------------- ### OrderRow component with useTriggerMorph for bottom sheet Source: https://scrollsheet.dev/docs/presentation/trigger-morph Defines an OrderRow component that uses useTriggerMorph to morph a button into a bottom sheet. Each row gets a unique name based on order.id to avoid collisions. The sheet uses detents 'content' and 'full', and closes via closeMorph when the open state changes to false. ```tsx interface Order { id: string; title: string; detail: string; } function OrderRow({ order }: { order: Order }) { const [open, setOpen] = React.useState(false); // Unique per row: many rows are mounted at once, and each needs its own name. const name = `order-${order.id}`; const { triggerRef, openMorph, closeMorph } = useTriggerMorph(name, setOpen); return ( <> !next && closeMorph()} detents={['content', 'full']}> {order.title}

{order.detail}

Done
); } ``` -------------------------------- ### Import and use Toaster and toast Source: https://scrollsheet.dev/docs/toasts Shows how to import the Toaster component and toast function, mount the Toaster once, and fire toasts with options like description and action. The toast function supports success variants and action buttons. ```jsx import { Toaster, toast } from 'scrollsheet'; import 'scrollsheet/toast.css'; // mount once, anywhere ; // fire from any code, component or not toast('Saved to your list'); toast.success('Synced', { description: 'Two seconds ago.' }); toast('Archived', { action: { label: 'Undo', onClick: restore } }); ``` -------------------------------- ### Set dialog width with .sheet class Source: https://scrollsheet.dev/docs/presentation/centered-dialog Core sets no width on the panel, only guard rails. Size it the same way you'd size any card. ```css .sheet { width: 400px; } ``` -------------------------------- ### Check isSupported() to render a custom legacy modal Source: https://scrollsheet.dev/docs/browser-support Use this snippet to detect whether the browser supports the -based path. Call isSupported() client-side after mount so server and client agree on the first render. If unsupported, render your own LegacyModal instead of the built-in fallback. ```jsx import { Sheet, isSupported } from 'scrollsheet'; const [supported, setSupported] = useState(false); useEffect(() => setSupported(isSupported()), []); if (!supported) return ; return ...; ``` -------------------------------- ### Import Drawer from vaul and scrollsheet Source: https://scrollsheet.dev/docs/migrating/from-vaul Shows the import statements for using vaul and scrollsheet. The scrollsheet import replaces vaul's import and style. ```javascript import { Drawer } from 'vaul'; import 'vaul/style.css'; import { Drawer } from 'scrollsheet'; import 'scrollsheet/styles.css'; ``` -------------------------------- ### Basic morph trigger JavaScript Source: https://scrollsheet.dev/docs/presentation/trigger-morph Sets the trigger's view-transition-name, starts a view transition that flushes the state change, then clears the name. The panel's CSS uses the same name and disables its own travel. ```javascript trigger.style.viewTransitionName = 'morph'; document.startViewTransition(() => { flushSync(() => setOpen(true)); trigger.style.viewTransitionName = ''; }); ``` ```css /* on the panel */ view-transition-name: morph; --scrollsheet-travel: none; ``` -------------------------------- ### injectStylesInto(root, nonce?) Source: https://scrollsheet.dev/docs/reference/api The injectStylesInto function adopts the core stylesheet into a shadow root. It takes a ShadowRoot and an optional nonce string. ```APIDOC ## injectStylesInto(root, nonce?) ### Description Adopts the core stylesheet into a shadow root. ### Parameters - **root** (ShadowRoot) - Required - The shadow root to inject styles into. - **nonce** (string) - Optional - A nonce for Content Security Policy. ### Returns - **void** ``` -------------------------------- ### Sheet.Root with side and desktopSide Source: https://scrollsheet.dev/docs/presentation/responsive-profiles Basic responsive profile: a bottom sheet on mobile that becomes a centered dialog at the desktop breakpoint. No matchMedia hook or conditional detents needed. ```jsx ``` -------------------------------- ### Inject toast styles into a shadow root with injectToastStylesInto Source: https://scrollsheet.dev/docs/advanced/shadow-dom Sibling export for the toast stylesheet, not folded into injectStylesInto. Targets separate CSS that a core-only consumer's bundle tree-shakes away unless imported. ```javascript import { injectToastStylesInto } from 'scrollsheet/auto'; injectToastStylesInto(shadowRoot); ``` -------------------------------- ### Import toast and Toaster from sonner and scrollsheet Source: https://scrollsheet.dev/docs/migrating/from-sonner Shows the import statements for both Sonner and Scrollsheet, indicating that the exports are drop-in compatible. ```javascript import { toast, Toaster } from 'sonner'; import { toast, Toaster } from 'scrollsheet'; ``` -------------------------------- ### Inject core styles into a shadow root with injectStylesInto Source: https://scrollsheet.dev/docs/advanced/shadow-dom Import from 'scrollsheet/auto' and call injectStylesInto once per shadow root before any Sheet.Content inside it opens. The default entry ships no embedded CSS, so this is required for shadow DOM. ```javascript import { Sheet, injectStylesInto } from 'scrollsheet/auto'; injectStylesInto(shadowRoot); ``` -------------------------------- ### Add a scrollsheet component Source: https://scrollsheet.dev/docs/recipes Use the shadcn CLI to add a component from the scrollsheet registry. Replace drawer.json with the desired component name. ```bash bunx shadcn@latest add https://scrollsheet.dev/r/drawer.json ``` -------------------------------- ### spring(config?) Source: https://scrollsheet.dev/docs/reference/api The spring function converts a spring configuration into easing and duration values for animations. ```APIDOC ## spring(config?) ### Description Converts a spring configuration into easing and duration values for animations. ### Parameters - **config** (object) - Optional - Spring configuration with properties: `stiffness`, `damping`, `mass`, `velocity`, `restDelta`. ### Returns - **easing** - The easing function. - **durationMs** - The duration in milliseconds. ``` -------------------------------- ### Import Scrollsheet with auto-injected styles Source: https://scrollsheet.dev/docs/styling/css Use the auto entry point to inject the stylesheet automatically when the first sheet opens, avoiding the need for manual CSS handling. ```javascript import { Sheet } from "scrollsheet/auto"; ``` -------------------------------- ### Enable system-based dark mode Source: https://scrollsheet.dev/docs/styling/css Set the data-scrollsheet-theme attribute to system to automatically track the OS color scheme. ```html ``` -------------------------------- ### Sheet.Root with side bottom and desktopSide left Source: https://scrollsheet.dev/docs/presentation/responsive-profiles A bottom sheet on mobile that becomes a left drawer on desktop. side and desktopSide take the same five values and do not have to relate to each other. ```jsx ``` -------------------------------- ### Sheet.Title / Sheet.Description Source: https://scrollsheet.dev/docs/reference/api These exports render the title and description of the sheet, automatically wiring aria-labelledby and aria-describedby respectively. ```APIDOC ## Sheet.Title / Sheet.Description ### Description Renders the title and description of the sheet. Automatically wires `aria-labelledby` for `Sheet.Title` and `aria-describedby` for `Sheet.Description`. ### Type - `Sheet.Title` extends `

` - `Sheet.Description` extends `

` ``` -------------------------------- ### Mark page wrapper and use scale effect Source: https://scrollsheet.dev/docs/presentation/page-transitions Mark the page wrapper with `data-scrollsheet-background` and set `backgroundEffect="scale"` on the sheet root with a `'full'` detent to create an iOS-style card transition. The wrapper is scaled, inset, and rounded in sync with the sheet's travel. ```jsx

{/* your page content */}
``` -------------------------------- ### Sheet.Root with custom desktopBreakpoint Source: https://scrollsheet.dev/docs/presentation/responsive-profiles Overrides the default desktopBreakpoint (768) to 1024 for a specific Sheet.Root. desktopBreakpoint only works when paired with desktopSide; setting it alone warns once in dev and does nothing. ```jsx ``` -------------------------------- ### Manual full-height layout without fill prop Source: https://scrollsheet.dev/docs/scrolling-and-keyboard/keyboard Use this CSS to achieve the same full-height layout as the fill prop by hand. [data-scrollsheet-body] is the wrapper the library already renders around your content; fill just sets these two rules for you off one attribute. ```css .sheet { display: flex; flex-direction: column; } .sheet [data-scrollsheet-body] { display: flex; flex-direction: column; flex: 1; min-height: 0; } .sheet .results { flex: 1; min-height: 0; overflow-y: auto; } ``` -------------------------------- ### Drawer Source: https://scrollsheet.dev/docs/reference/api The Drawer export is a vaul-compatible namespace mapped onto Sheet.* components, including Root, Trigger, Portal, Overlay, Content, Handle, Title, Description, and Close. NestedRoot is an alias of Root. ```APIDOC ## Drawer ### Description A vaul-compatible namespace mapped onto `Sheet.*` components. Provides `Root`, `Trigger`, `Portal`, `Overlay`, `Content`, `Handle`, `Title`, `Description`, `Close`. `NestedRoot` is an alias of `Root`. ### Exports - **Root** - Alias for `Sheet.Root`. - **Trigger** - Alias for `Sheet.Trigger`. - **Portal** - Alias for `Sheet.Portal`. - **Overlay** - Alias for `Sheet.Overlay`. - **Content** - Alias for `Sheet.Content`. - **Handle** - Alias for `Sheet.Handle`. - **Title** - Alias for `Sheet.Title`. - **Description** - Alias for `Sheet.Description`. - **Close** - Alias for `Sheet.Close`. - **NestedRoot** - Alias for `Sheet.Root`. ``` -------------------------------- ### Import scrollsheet component and stylesheet Source: https://scrollsheet.dev/docs/getting-started/install Imports the Sheet component and the default stylesheet once per app. The Sheet component is client-only; in Next.js App Router, add "use client" to the file that renders it. ```javascript import { Sheet } from 'scrollsheet'; import 'scrollsheet/styles.css'; ``` -------------------------------- ### Sheet.Root with detents and active detent Source: https://scrollsheet.dev/docs/detents-and-control/detents Configures a Sheet.Root with three detents (0.35, 0.7, 'full') and binds the active detent state. ```tsx ``` -------------------------------- ### Apply Tailwind utilities to Sheet.Content Source: https://scrollsheet.dev/docs/styling/tailwind Demonstrates applying Tailwind utility classes directly to the Sheet.Content component for background and shadow styling. ```jsx ``` -------------------------------- ### isSupported() Source: https://scrollsheet.dev/docs/reference/api The isSupported function checks whether the browser supports the element. Returns false on the ~4% of browsers without support, where the sheet falls back to a plain modal. ```APIDOC ## isSupported() ### Description Checks whether the browser supports the `` element. Returns `false` on the ~4% of browsers without support, where the sheet falls back to a plain modal. ### Returns - **boolean** - `true` if supported, `false` otherwise. ``` -------------------------------- ### Apply custom styles to Sheet component Source: https://scrollsheet.dev/docs/styling/css Use the .sheet class to define custom background, border-radius, and box-shadow for the Sheet component. ```css .sheet { background: white; border-radius: 16px 16px 0 0; box-shadow: 0 -8px 40px rgb(0 0 0 / 0.16); } ``` -------------------------------- ### Basic Sheet component implementation Source: https://scrollsheet.dev/docs/presentation/side-panels A standard implementation of the Sheet component anchored to the right side with a fixed width detent. ```jsx Notifications {/* ... */} ``` -------------------------------- ### Target wrapper with backgroundRef Source: https://scrollsheet.dev/docs/presentation/page-transitions Use `backgroundRef` to target the wrapper directly instead of the `data-scrollsheet-background` query. This is useful when you don't want to stamp an attribute or when multiple sheets on the same page could collide. The ref skips the marker lookup and its ownership check. ```jsx const pageRef = useRef(null);
{/* your page content, no attribute needed */}
``` -------------------------------- ### Toaster, toast, useToasts Source: https://scrollsheet.dev/docs/reference/api Toast exports that work on their own per-toast DOM without involving Sheet.Root. They support all six positions with per-toast overrides, hide-not-evict overflow, and swipe-to-dismiss. They are Sonner-compatible with useSonner, toasterId, and existing .sonner-toast CSS, controlled by the prop. ```APIDOC ## Toaster, toast, useToasts ### Description Toast exports that work on their own per-toast DOM without involving `Sheet.Root`. Support all six positions with per-toast overrides, hide-not-evict overflow, and swipe-to-dismiss. Sonner-compatible: `useSonner`, `toasterId`, and existing `.sonner-toast` CSS all keep working, controlled by ``. ### Exports - **Toaster** - Component that renders toasts. - **toast** - Function to create a toast. - **useToasts** - Hook to access toast state. ### Props - **sonnerCompat** (boolean) - Optional - Default `true`. When `false`, drops every `.sonner-*` class and `data-sonner-*` attribute, using neutral `.scrollsheet-*` names only. ``` -------------------------------- ### Imperative control with actionsRef Source: https://scrollsheet.dev/docs/detents-and-control/imperative-control Use actionsRef to access imperative methods like snapTo, open, and close on the Sheet component. This approach is recommended for deep links, push notifications, or avoiding prop-drilling. ```typescript const actionsRef = useRef(null); {/* ... */} ``` -------------------------------- ### Sheet.Content with input for keyboard inset Source: https://scrollsheet.dev/docs/scrolling-and-keyboard/keyboard Use this JSX to render a sheet content area with an input field. The library automatically keeps the input clear of the on-screen keyboard by listening to iOS visualViewport changes and writing the inset to --scrollsheet-keyboard, no prop required. ```jsx {/* stays clear of the on-screen keyboard automatically */} ``` -------------------------------- ### Sheet.Content fill for full-height content Source: https://scrollsheet.dev/docs/scrolling-and-keyboard/keyboard Use the fill prop on Sheet.Content to stretch the body to the panel (flex column) so a fixed header plus an independently scrolling list needs no CSS chain of your own. The list then sizes to whatever the sheet has left, including when the keyboard caps the panel at the visual viewport. fill is off by default because it changes how the content detent measures. ```jsx
{/* fixed */}
{/* flex: 1; min-height: 0; overflow-y: auto */}
``` -------------------------------- ### Configure non-modal Sheet Source: https://scrollsheet.dev/docs/presentation/non-modal Setting modal={false} on the Sheet.Root component prevents the backdrop and focus trap, allowing the rest of the page to remain interactive. ```jsx ``` -------------------------------- ### Set custom properties with arbitrary values Source: https://scrollsheet.dev/docs/styling/tailwind Use arbitrary properties to set library-specific CSS variables directly on the Sheet.Content component. ```jsx ``` -------------------------------- ### Sheet.Trigger Source: https://scrollsheet.dev/docs/reference/api The Sheet.Trigger export is a button that opens the sheet on click. It supports the asChild prop to render your own element instead. ```APIDOC ## Sheet.Trigger ### Description A button that opens the sheet on click. Supports `asChild` to render your own element instead. ### Type Extends `