Skip to content
Mobile
Skill

/truesheet-usage

Consumer-side guide for integrating @lodev09/react-native-true-sheet into a React Native app. Use this skill whenever the user wants to add, configure, control, or debug a bottom sheet using TrueSheet — including ref-based sheets, named global sheets, web support with

From plugin
react-native-true-sheet
2.1k1 skill

Claude Code

$ npx -y skills add lodev09/react-native-true-sheet --skill truesheet-usage --agent claude-code

SKILL.md

truesheet-usage.SKILL.md
name: truesheet-usage
description: >-
  Consumer-side guide for integrating @lodev09/react-native-true-sheet into a React Native app.
  Use this skill whenever the user wants to add, configure, control, or debug a bottom sheet using TrueSheet —
  including ref-based sheets, named global sheets, web support with TrueSheetProvider/useTrueSheet,
  React Navigation or Expo Router sheet flows, Reanimated-driven animations, scrolling content,
  stacking, headers/footers, detents, peeking, side sheets, keyboard handling, dimming, backgrounds, liquid glass,
  and Jest testing. Also use when the user is migrating from v3 to v4, troubleshooting layout or
  gesture issues, or asking about any TrueSheet prop, event, or method — even if they don't
  mention "TrueSheet" by name but describe a bottom sheet in a React Native context.

TrueSheet Consumer Guide

Use this skill to produce correct, idiomatic code for apps that consume `@lodev09/react-native-true-sheet` (v4). It covers choosing the right integration pattern, applying the public API correctly, and avoiding platform-specific pitfalls.

Requires React Native >= 0.82 (Expo SDK 55+) with the New Architecture.

Quick Start

The simplest sheet: a ref, a button, and some content.

import { useRef } from 'react'
import { Button, Text, View } from 'react-native'
import { TrueSheet } from '@lodev09/react-native-true-sheet'

export function App() {
  const sheet = useRef<TrueSheet>(null)

  return (
    <View>
      <Button title="Open" onPress={() => sheet.current?.present()} />
      <TrueSheet ref={sheet} detents={['auto']} cornerRadius={24} grabber>
        <View style={{ padding: 16 }}>
          <Text>Hello from the sheet</Text>
          <Button title="Close" onPress={() => sheet.current?.dismiss()} />
        </View>
      </TrueSheet>
    </View>
  )
}

Content Layout (v4)

The sheet's content lays out **naturally** — it wraps its children's height like a regular view or a React Navigation screen. It does **not** fill the sheet by default. Consequences:

  • A `flex: 1` child collapses to zero height unless the content is filled.
  • To fill the sheet's visible height per detent (spacers, centered content, bounded scroll views), pass `flex: 1` via the sheet's `style` prop:
<TrueSheet style={{ flex: 1 }} detents={[0.5, 1]}>
  <View style={{ flex: 1, justifyContent: 'center' }}>
    <Text>Centered</Text>
  </View>
</TrueSheet>

The content is sized to the sheet's visible height per detent and tracks it in realtime while dragging, so flex layouts follow the sheet's edge frame-by-frame.

Choose the Right Control Pattern

Pick one based on where the trigger lives relative to the sheet and which platforms you target.

| Pattern | When to use | Platform | |---------|------------|----------| | **Ref** | Trigger and sheet in the same component | All | | **Named + global methods** | Trigger is far from the sheet (different screen, deep in tree) | Native only | | **`TrueSheetProvider` + `useTrueSheet()`** | Web support needed, or you want hook-based control | All (required on web) | | **`createTrueSheetNavigator()` / Expo Router `Sheet`** | Sheets are part of a navigation flow | All | | **`ReanimatedTrueSheet`** | You need animated values synced to sheet position | All |

Ref-based

Already shown in Quick Start. Use `present()`, `dismiss()`, `resize(index)` on the ref.

Named sheet with global methods (native only)

When the trigger is far from where the sheet renders:

// Somewhere in the tree
<TrueSheet name="profile" detents={['auto', 1]}>
  <ProfileContent />
</TrueSheet>

// Anywhere else (native only)
await TrueSheet.present('profile')
await TrueSheet.dismiss('profile')
await TrueSheet.resize('profile', 1)
await TrueSheet.dismissAll()

Every `name` must be unique. Static methods don't exist on web — use the provider pattern instead.

Web control with provider

Wrap your app with `TrueSheetProvider` (on native this is a pass-through with zero overhead). Web also needs `@radix-ui/react-dialog` and `@radix-ui/react-presence` installed (optional peer deps):

import { TrueSheet, TrueSheetProvider, useTrueSheet } from '@lodev09/react-native-true-sheet'

function Toolbar() {
  const { present, dismiss } = useTrueSheet()
  return <Button title="Open" onPress={() => present('settings')} />
}

export function App() {
  return (
    <TrueSheetProvider>
      <Toolbar />
      <TrueSheet name="settings" detents={[0.5, 1]}>
        <SettingsContent />
      </TrueSheet>
    </TrueSheetProvider>
  )
}

Navigation (React Navigation / Expo Router)

See [advanced patterns reference](./references/advanced-patterns.md#react-navigation) for full setup with `createTrueSheetNavigator`, the static API (`createTrueSheetScreen`), the Expo Router `Sheet` layout from `/navigation/expo-router`, screen options (including `scrollableRef` via `setOptions`), multi-step flows as stacked sheet screens, and `useTrueSheetNavigation`.

Reanimated

See [advanced patterns reference](./references/advanced-patterns.md#reanimated) for `ReanimatedTrueSheet`, `ReanimatedTrueSheetProvider`, and animated values (`animatedPosition`, `animatedIndex`, `animatedDetent`).

Detents

Detents define the heights the sheet can snap to. You get up to **3 detents**, sorted smallest to largest. Default: `[0.5, 1]`.

| Value | Meaning | |-------|---------| | `'auto'` | Size to fit the content (iOS 16+, Android, Web). Works with scrollables — sizes to the scroll content and resizes as it grows/shrinks | | `'peek'` | Collapsed height from the measured `header` + absolute `footer` + content through a `TrueSheetPeek` marker (iOS 16+, Android, Web). Falls back to `150` when none provided | | `0` – `1` | Fraction of the screen height |

// Content-sized sheet
<TrueSheet detents={['auto']} />

// Half and full screen
<TrueSheet detents={[0.5, 1]} />

// Collapsed summary that expands to near-full
<TrueSheet detents={['peek', 0
Read more
@lodev09
Ships withreact-native-true-sheet

The true native bottom sheet experience for your React Native Apps. 💩

Stars on GitHub

Momentum

stars in total
2.1k
Star history of lodev09/react-native-true-sheet on GitHub, a chart by star-history.com

More skills from other plugins.

deep-code-review

deep-code-review

In-depth design-focused code review - understands codebase context before evaluating PR changes, posts structured feedback to…

expo2d53k
@expo@expoInstall Skill
modlens

modlens

Plug-in vision for text-only models. Hard rule: when a file path or URL with an image extension (.png, .jpg, .jpeg, .webp, .gif,…

modlens2w4.6k
@liustack@liustackInstall Skill
appllama-app-design-skill

appllama-app-design-sk…

Build native-feeling, benchmark-quality mobile app screens (Expo / React Native). Use when designing or implementing any mobile…

appllama2mo3.9k
@appllama@appllamaInstall Skill

Questions about truesheet-usage.

Which coding agents can use truesheet-usage?
truesheet-usage installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.