Stacking Sheets
TrueSheet automatically handles stacking when you present a sheet while another is already visible. The currently visible sheet will be hidden, and when the new sheet is dismissed, the previous sheet will be shown again.
How?
Simply present a new sheet while another is visible. The sheets don't need to be in a parent-child relationship - they can be defined anywhere in your component tree.
const presentSheet2 = async () => {
await sheet2.current?.present() // Sheet 2 will present, Sheet 1 will be hidden
}
return (
<>
<TrueSheet ref={sheet1}>
<Button onPress={presentSheet2} title="Present Sheet 2" />
<View />
</TrueSheet>
<TrueSheet ref={sheet2}>
<View />
</TrueSheet>
</>
)
When Sheet 2 is dismissed, Sheet 1 will automatically be shown again.
The previous sheet is only hidden if it's not fully expanded. When expanded, the new sheet simply presents on top.
Dismissing Stacked Sheets
When you have stacked sheets, calling dismiss() on a sheet that has other sheets presented on top of it will dismiss all sheets above it, but the sheet itself will remain presented. This matches iOS's native UIViewController behavior.
// If Sheet 1 → Sheet 2 → Sheet 3 (Sheet 1 presented Sheet 2, Sheet 2 presented Sheet 3)
await sheet1.current?.dismiss() // Dismisses Sheet 2 and Sheet 3, Sheet 1 stays
await sheet2.current?.dismiss() // Dismisses Sheet 3, Sheet 1 and Sheet 2 stay
await sheet3.current?.dismiss() // Dismisses Sheet 3, Sheet 1 and Sheet 2 stay
This is useful when you need to dismiss all child sheets and return focus to a parent sheet without closing it.
Stack Behavior (Web)
On web, you can customize the stacking behavior using the stackBehavior prop:
<TrueSheet stackBehavior="push">
<View />
</TrueSheet>
| Value | Description |
|---|---|
"push" | Mount the modal on top of the current one. |
"switch" | Minimize the current modal then mount the new one. (default) |
"replace" | Dismiss the current modal then mount the new one. |
Focus Events
When stacking sheets, you can listen to focus events to know when a sheet gains or loses focus:
onDidBlur- Called when the sheet loses focus because another sheet is presented on toponDidFocus- Called when the sheet regains focus after a sheet on top is dismissed
This is useful for pausing/resuming updates, refreshing data, or managing interactions when the sheet is not the topmost.
const handleFocus = () => {
console.log('Sheet regained focus - refresh data')
}
const handleBlur = () => {
console.log('Sheet lost focus - pause updates')
}
return (
<TrueSheet
ref={sheet1}
onDidFocus={handleFocus}
onDidBlur={handleBlur}
>
<Button onPress={() => sheet2.current?.present()} title="Present Sheet 2" />
<TrueSheet ref={sheet2}>
<View />
</TrueSheet>
</TrueSheet>
)