suiss/uim · React Native Component

Sheet

A panel that slides in from any edge of the screen, for secondary content and settings.

Sheet is an open-source mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Sheet (open by default) on iOS in light mode

Sheet is built on the drawer primitive. SheetContent renders in a portal, above a dimmed overlay, as a rounded floating panel inset from the screen edges and the safe area. It enters and exits with a Reanimated fade-and-slide from its side and can be dismissed by swiping toward that edge.

Use right or left for navigation and detail panels that span the screen height, and top or bottom for short panels that span the width. For snap points and a drag handle, use Drawer instead.

Installation

$ pnpm dlx @esuiss/uim@latest add sheet

The CLI also adds what it builds on: Button, Icon, Text.

Manual

  1. Install the dependencies:
npx expo install cn phosphor-react-native react-native-reanimated react-native-safe-area-context react-native-screens react-native-svg react-native-worklets
  1. Add the pieces it builds on: Button, Icon, Text, and the primitives components/primitives/drawer.tsx, components/primitives/use-render.tsx.

  2. Copy the source into components/ui/sheet.tsx:

uniwind/components/ui/sheet.tsx
import { cn } from "cn"
import { XIcon } from "phosphor-react-native"
import * as React from "react"
import { Platform, View, type ViewProps, type ViewStyle } from "react-native"
import {
  FadeIn,
  FadeInDown,
  FadeInLeft,
  FadeInRight,
  FadeInUp,
  FadeOut,
  FadeOutDown,
  FadeOutLeft,
  FadeOutRight,
  FadeOutUp,
  ReduceMotion,
  1. Update the import paths to match your project.

Usage

import { Sheet, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from "@/components/ui/sheet"
<View className="items-start">
  <Sheet defaultOpen>
    <SheetTrigger render={<Button variant="outline" />}>
      <Text>Open</Text>
    </SheetTrigger>
    <ProfileContent />
  </Sheet>
</View>

Wrap a SheetTrigger and a SheetContent in Sheet. Inside the content, compose SheetHeader with SheetTitle and SheetDescription, your body, and a SheetFooter, which is pushed to the bottom. Use SheetTrigger and SheetClose with render to turn a Button into a trigger or close control.

Sheet accepts open, defaultOpen and onOpenChange for controlled or uncontrolled use, plus modal, disablePointerDismissal, onOpenChangeComplete and actionsRef. The swipe direction follows the side of its content.

A close button is shown in the top corner by default. Set closeLabel to show a text button instead of the X icon, or showCloseButton={false} to remove it. SheetHeader adds end padding so the title does not run under the button.

Examples

Default

iOS
Sheet on iOS in light mode

Sides

One sheet for each side: top, right, bottom and left.

iOS
Sheet (sides) on iOS in light mode

With close label

A bottom sheet whose close button reads "Done" instead of showing an icon.

iOS
Sheet (with close label) on iOS in light mode

API Reference

Sheet

Root that holds the open state.

ExtendsDrawerPrimitive.RootProps

SheetContent

The panel, rendered in a portal with an overlay and an optional close button.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Popup>
PropType
About
Name of the portal host to render into.
Type
string
Default
—
About
Edge the sheet slides in from: top, right, bottom or left. Defaults to right.
Type
SheetSide
Default
"right"
About
Shows the close button in the top corner. Defaults to true.
Type
boolean
Default
true
About
Text for the close button. When omitted, an X icon is shown.
Type
string
Default
—

SheetHeader

Column for the title and description.

ExtendsViewProps

SheetFooter

Column of actions pushed to the bottom of the panel.

ExtendsViewProps

SheetTitle

Heading that labels the sheet.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Title>

SheetDescription

Secondary text under the title.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Description>

Accessibility

  • The panel has the dialog role and is labeled by SheetTitle when one is present.
  • It is modal by default, so VoiceOver keeps focus inside the sheet.
  • The VoiceOver escape gesture and the Android back button close the sheet.
  • The icon-only close button has the accessibility label "Close".
  • Animations respect the system reduce motion setting.

Notes

  • Uses bg-surface-raised for the panel and bg-scrim for the overlay; colors follow the system appearance.
  • On iOS the sheet renders inside a FullWindowOverlay from react-native-screens, so it appears above native modals.
  • Side sheets are three quarters of the screen width, capped at max-w-sm on larger screens.