
TrueSheet Usage Guide
FreeIntegrate TrueSheet into your React Native app seamlessly.
Free · Opens the source repo
What TrueSheet Usage Guide does
The TrueSheet Usage Guide is an essential resource for developers looking to implement the TrueSheet component from the @lodev09/react-native-true-sheet library in their React Native applications. This guide provides detailed instructions on how to add, configure, control, and debug bottom sheets, which are crucial for enhancing user experience in mobile apps. Whether you are working with ref-based sheets, named global sheets, or need to incorporate web support with TrueSheetProvider, this guide covers all the necessary patterns and configurations.
With a focus on idiomatic code practices, the guide helps developers choose the right control pattern based on their app's architecture and the platforms they are targeting. It includes practical examples for various scenarios, such as using TrueSheet with React Navigation or Expo Router, implementing animations with Reanimated, and managing scrollable content. Additionally, it provides insights into handling detents, which define the heights at which the sheet can snap, allowing for a more dynamic user interface.
The guide also addresses common issues developers might face, such as migrating from version 2 to version 3 of TrueSheet, troubleshooting layout or gesture problems, and understanding the various props, events, and methods available in the TrueSheet API. This makes it a comprehensive tool for both new and experienced developers working with bottom sheets in React Native.
In summary, the TrueSheet Usage Guide is designed to streamline the integration process of TrueSheet into your application, ensuring that you can leverage its full capabilities while avoiding common pitfalls and maximizing performance.
When to use it
Use this skill when you need to implement bottom sheets in a React Native application using the TrueSheet library.
When not to use it
This skill may not be suitable for applications that do not require bottom sheets or for developers looking for a generic React Native guide without specific focus on TrueSheet.
What you can build with it
Basic Bottom Sheet
Implement a simple bottom sheet using a ref and a button to control its visibility.
Scrollable Content
Create a bottom sheet that contains scrollable content with headers and footers.
Web Integration
Set up TrueSheet in a web application using the TrueSheetProvider for hook-based control.
How to install TrueSheet Usage Guide
View source1. Install with the skills CLI
npx skills add lodev09/react-native-true-sheet/truesheet-usage --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by lodev09TrueSheet Consumer Guide
Use this skill to produce correct, idiomatic code for apps that consume @lodev09/react-native-true-sheet. It covers choosing the right integration pattern, applying the public API correctly, and avoiding platform-specific pitfalls.
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>
)
}
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() | 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):
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 for full setup with createTrueSheetNavigator, Expo Router layouts, screen options, and useTrueSheetNavigation.
Reanimated
See advanced patterns reference 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.
| Value | Meaning |
|---|---|
'auto' | Size to fit the content (iOS 16+, Android, Web) |
0 – 1 | Fraction of the screen height |
// Content-sized sheet
<TrueSheet detents={['auto']} />
// Half and full screen
<TrueSheet detents={[0.5, 1]} />
// Three stops: peek, half, full
<TrueSheet detents={[0.25, 0.5, 1]} />
The one rule you can't break: never combine 'auto' with scrollable. Auto-sizing needs to measure the full content, but a scrollable sheet clips it — they're fundamentally incompatible. Use fractional detents for scrollable sheets.
Common Recipes
Scrollable content
<TrueSheet detents={[0.5, 1]} scrollable cornerRadius={24} grabber>
<ScrollView>
{items.map(item => <ItemRow key={item.id} item={item} />)}
</ScrollView>
</TrueSheet>
- The
scrollableprop auto-detects ScrollView/FlatList up to 2 levels deep - On iOS, scrolling to top expands to next detent — disable with
scrollableOptions={{ scrollingExpandsSheet: false }} - On Android, nested scrolling is handled automatically
Fixed header and footer
<TrueSheet
detents={[0.5, 1]}
scrollable
header={
<View style={{ padding: 16 }}>
<Text style={{ fontSize: 18, fontWeight: 'bold' }}>Title</Text>
</View>
}
footer={<BottomActions />}
>
<ScrollView>{/* ... */}</ScrollView>
</TrueSheet>
Use the header and footer props — they render in native container views, so the layout math is handled for you. Don't fake it with absolute positioning.
Non-dismissible confirmation
<TrueSheet
ref={sheet}
detents={['auto']}
dismissible={false}
draggable={false}
dimmed
grabber={false}
>
<View style={{ padding: 24 }}>
<Text>Are you sure?</Text>
<Button title="Confirm" onPress={handleConfirm} />
<Button title="Cancel" onPress={() => sheet.current?.dismiss()} />
</View>
</TrueSheet>
iOS blur background
<TrueSheet detents={['auto']} backgroundBlur="system-material">
<View style={{ padding: 16 }}>
<Text>Blurred sheet</Text>
</View>
</TrueSheet>
Fine-tune with blurOptions={{ intensity: 80, interaction: true }}. Blur is iOS-only.
Present on mount
<TrueSheet detents={['auto', 1]} initialDetentIndex={0} initialDetentAnimated>
<WelcomeContent />
</TrueSheet>
Dimming control
// No dimming (allows background interaction)
<TrueSheet dimmed={false} detents={['auto']} />
// Dim only above a certain detent
<TrueSheet detents={['auto', 0.7, 1]} dimmedDetentIndex={1} />
Resize programmatically
resize() takes a detent index, not a value:
const sheet = useRef<TrueSheet>(null)
// detents={[0.3, 0.6, 1]}
await sheet.current?.resize(2) // expands to full (index 2)
Rules That Save Debugging Time
- Max 3 detents, sorted smallest → largest.
- Never
'auto'+scrollable— they're incompatible. resize()takes an index, not a fraction.resize(1)means "go to the second detent."- Sheet names must be unique across your entire app.
- Static methods are native-only — use
useTrueSheet()on web. - Don't use
autoFocuson TextInputs inside sheets. Focus inonDidPresentinstead:<TrueSheet onDidPresent={() => inputRef.current?.focus()}> - Use
flexGrow: 1(notflex: 1) insideGestureHandlerRootViewon Android. - Dismiss sheets before closing Modals on iOS — React Native has a bug where dismissing a Modal while a sheet is visible causes a blank screen.
- Use
header/footerprops for fixed chrome — don't reach for absolute positioning. - Liquid Glass is automatic on iOS 26+. Set
backgroundColorto disable it per-sheet, or addUIDesignRequiresCompatibilityto Info.plist to disable app-wide.
Platform Differences at a Glance
| Feature | iOS | Android | Web |
|---|---|---|---|
'auto' detent | iOS 16+ | Yes | Yes |
backgroundBlur | Yes | No | No |
| Liquid Glass | iOS 26+ | No | No |
| Static global methods | Yes | Yes | No (use provider) |
scrollable | Yes | Yes | No |
anchor / side sheets | System-controlled margins | anchorOffset prop | anchorOffset prop |
presentation | iOS 17+ (iPad) | N/A | Landscape/tablet |
detached mode | No | No | Yes |
| Edge-to-edge | N/A | Auto-detected | N/A |
| Keyboard handling | Built-in | Built-in | N/A |
Events
The most commonly used events:
| Event | When it fires | Payload |
|---|---|---|
onMount | Content is mounted and ready | — |
onDidPresent | Sheet finished presenting | { index, position, detent } |
onDidDismiss | Sheet finished dismissing | — |
onDetentChange | User dragged or resize() changed the detent | { index, position, detent } |
onPositionChange | Continuous position updates during drag/animation | { index, position, detent, realtime } |
For the full event list (drag events, focus/blur events, will/did lifecycle pairs, onBackPress), see the API reference.
Methods
On a ref:
present(index?, animated?)— show the sheetdismiss(animated?)— hide the sheet and all its childrendismissStack(animated?)— hide only sheets stacked on topresize(index)— snap to a detent by index
Global (native only):
TrueSheet.present(name, index?, animated?)TrueSheet.dismiss(name, animated?)TrueSheet.dismissStack(name, animated?)TrueSheet.resize(name, index)TrueSheet.dismissAll(animated?)
Web hook:
const { present, dismiss, dismissStack, resize, dismissAll } = useTrueSheet()
Stacking Sheets
Present a new sheet while another is visible and the first one hides automatically. Dismiss the top sheet and the previous one comes back. This is built-in — no extra config needed.
dismiss()cascades: it dismisses the current sheet plus everything stacked on topdismissStack()dismisses only the sheets on top, keeping the current one visible- Use
onDidFocus/onDidBlurto react to a sheet gaining or losing the top position
Deep-Dive References
When you need the full picture, load these reference files:
| Reference | What's inside |
|---|---|
| Configuration | Every prop with type, default, platform support, and notes |
| API | Complete events and methods reference with payload types |
| Advanced Patterns | Navigation, Reanimated, Web, Side sheets, Liquid Glass, Jest mocking, Migration v2→v3 |
| Troubleshooting | Common issues and fixes by platform |
Frequently asked questions about TrueSheet Usage Guide
Similar skills
Playwright Component Testing
Test React and Vue components in isolation with Playwright.
Fluent UI Blazor
Integrate Fluent UI components in Blazor applications effortlessly.
Build MCP App
Create interactive UI widgets for MCP servers.
Web Design Reviewer
Identify and fix design issues in websites efficiently.
Markstream Install
Seamlessly integrate Markstream for Markdown rendering.
GSAP & Framer Scroll Animation
Create advanced scroll animations effortlessly.
