suiss/uim · React Native Component

Drawer

A panel that slides in from any edge and can be swiped away, with snap points and a floating style.

Drawer 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
Drawer (open by default) on iOS in light mode

Drawer presents content in a panel attached to an edge of the screen. It slides in from the bottom by default, or from the top, left or right with swipeDirection, and the user can drag it closed in that direction. The content renders through a portal (inside a full-window overlay on iOS) and respects the safe-area insets.

Set floating to inset the panel from the screen edges with all corners rounded. Use snapPoints to let a bottom drawer rest at several heights. Wrap your app in DrawerProvider and its screen in DrawerIndent to scale the page back behind an open bottom drawer.

Installation

$ pnpm dlx @esuiss/uim@latest add drawer

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/drawer.tsx:

uniwind/components/ui/drawer.tsx
import { cn } from "cn"
import { XIcon } from "phosphor-react-native"
import * as React from "react"
import {
  Platform,
  useWindowDimensions,
  View,
  type ViewProps,
  type ViewStyle,
} from "react-native"
import {
  FadeIn,
  FadeOut,
  ReduceMotion,
  SlideInDown,
  SlideInLeft,
  1. Update the import paths to match your project.

Usage

import { DrawerProvider, DrawerIndentBackground, DrawerIndent, Drawer, DrawerOverlay, DrawerSwipeHandle, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription } from "@/components/ui/drawer"
<View className="items-start">
  <Drawer defaultOpen showSwipeHandle>
    <DrawerTrigger render={<Button variant="outline" />}>
      <Text>Open drawer</Text>
    </DrawerTrigger>
    <GoalContent />
  </Drawer>
</View>

Compose DrawerTrigger and DrawerContent with a DrawerHeader (DrawerTitle, DrawerDescription), your content and a DrawerFooter. Use DrawerClose to close it from a button.

Set showSwipeHandle to show a grab handle, and showCloseButton on the content for a corner close button, with closeLabel for a text button. snapPoints accepts fractions of the screen such as [0.4, 1]; control the current one with snapPoint and onSnapPointChange.

With modal={false} there is no scrim. For the scaled background, render DrawerIndentBackground behind a DrawerIndent inside DrawerProvider.

Examples

Default

iOS
Drawer on iOS in light mode

Snap points

A drawer that rests at 40% and full height.

iOS
Drawer (snap points) on iOS in light mode

Floating

A floating drawer inset from the edges.

iOS
Drawer (floating) on iOS in light mode

Sides

Drawers from the top, bottom, left and right.

iOS
Drawer (sides) on iOS in light mode

API Reference

DrawerProvider

Tracks open drawers for the indent effect.

ExtendsDrawerPrimitive.ProviderProps

DrawerIndentBackground

Background shown behind the scaled screen.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.IndentBackground>

DrawerIndent

Screen wrapper that scales back while a bottom drawer is open.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Indent>

Drawer

Root that holds the open state, direction and snap points.

ExtendsDrawerPrimitive.RootProps
PropType
About
Insets the panel from the edges.
Type
boolean
Default
false
About
Shows a grab handle.
Type
boolean
Default
false

DrawerOverlay

Dimmed scrim behind a modal drawer.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Backdrop>

DrawerSwipeHandle

Grab handle on the dragging edge.

ExtendsViewProps

DrawerContent

Sliding panel with optional handle and close button.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Popup>
PropType
About
Name of the portal host to render into.
Type
string
Default
—
About
Shows a corner close button.
Type
boolean
Default
false
About
Text for the close button instead of the icon.
Type
string
Default
—

DrawerHeader

Area for the title and description.

ExtendsViewProps

DrawerFooter

Area for actions at the end of the panel.

ExtendsViewProps

DrawerTitle

Drawer heading, centered for top and bottom drawers.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Title>

DrawerDescription

Supporting text.

ExtendsReact.ComponentProps<typeof DrawerPrimitive.Description>

Accessibility

  • The popup has the dialog role and is labelled by the title.
  • The swipe handle and decorative edge fill are hidden from screen readers.
  • The icon close button is labelled "Close".

Notes

  • Padding follows the safe-area insets, and a docked drawer extends its background past the screen edge so drag overshoot shows no gap.
  • Animations respect the system Reduce Motion setting.
  • Uses bg-surface-raised, bg-scrim and bg-label-quaternary tokens; light and dark follow the system appearance.