🚧 True Sheet 4.0 beta rewrites the layout engine. npx expo install @lodev09/react-native-true-sheet@beta Migration guide
Guides

Foldables

Rest the bottom sheet on the hinge of a half-folded device, and keep it off the fold.

Foldables like the iPhone Duo can stand half-open on a table, with the screen split by the hinge. A sheet that spans the hinge is hard to use there. With foldOptions, the sheet can rest right on the hinge and fill the panel below it, like a media player on a laptop-style screen.

Requires iOS 27.1+ on a foldable. On other devices, platforms, and iOS versions, foldOptions has no effect.

Postures

A foldable can be in one of these postures. foldOptions only acts in tabletop.

PostureFoldSheet behavior
Closednone (cover screen)Like a phone
FlatinactiveLike a tablet, the sheet spans the whole screen
Bookvertical, half-openiOS docks the sheet to one panel — see Book Posture
Tabletophorizontal, half-openThe hinge splits the screen into a top and a bottom panel

Resting on the Hinge

Set hingeDetentIndex to the detent that should rest on the hinge. In tabletop, that detent resolves to the height of the bottom panel. In any other posture, it keeps its own value, so it doubles as the fallback.

export const App = () => {
  return (
    <TrueSheet
      detents={[0.5, 1]}
      foldOptions={{ hingeDetentIndex: 0 }}
    >
      <View />
    </TrueSheet>
  )
}

Here the sheet opens at 0.5 on a flat screen. Half-fold the device and detent 0 moves onto the hinge. The other detents keep their values, so the sheet can still expand past the hinge to 1. They also keep their order: a lower detent never rises above the hinge detent, and a higher one never drops below it.

Keeping the Sheet Off the Hinge

Set hingeBehavior to 'avoid' to cap every detent at the hinge. The sheet never crosses it, even at its tallest detent.

export const App = () => {
  return (
    <TrueSheet
      detents={['auto', 1]}
      foldOptions={{ hingeBehavior: 'avoid' }}
    >
      <View />
    </TrueSheet>
  )
}

Detents that reach above the hinge collapse onto it, so they all stop at the same height. 'avoid' works best with one detent above the hinge.

Snapping to the Hinge

'avoid' keeps the sheet where it is when the device folds. A sheet resting low stays low. Set hingeBehavior to 'snap' to also move the sheet to hingeDetentIndex when the device enters tabletop, and back to its previous detent when it leaves. If the user moves the sheet off the hinge while folded, it stays where they put it.

export const NowPlaying = () => {
  return (
    <TrueSheet
      detents={['peek', 0.6, 1]}
      foldOptions={{
        hingeDetentIndex: 1,
        hingeBehavior: 'snap',
      }}
    >
      <TrueSheetPeek>
        <MiniPlayer />
      </TrueSheetPeek>
      <PlayerControls />
    </TrueSheet>
  )
}

On a flat screen this is a mini player at peek. Half-fold the device and the full controls fill the bottom panel. Unfold it and the sheet goes back to the mini player.

hingeBehaviorCrosses the hingeMoves on fold
'none'YesNo
'avoid'NoNo
'snap'NoYes, to hingeDetentIndex and back

The usual onDetentChange and onPositionChange events fire when the sheet moves for the hinge.

Book Posture

With a vertical fold, iOS already keeps the sheet on one panel, so foldOptions has nothing to do there. Use placement to pick the panel. 'automatic' and 'center' dock to the leading panel.

export const App = () => {
  return (
    <TrueSheet
      placement="trailing"
      foldOptions={{ hingeBehavior: 'avoid' }}
    >
      <View />
    </TrueSheet>
  )
}

foldOptions is a screen option in the Sheet Navigator and the Expo Router Sheet layout, like any other prop.

<Sheet.Screen
  name="Player"
  component={PlayerScreen}
  options={{
    detents: ['peek', 0.6, 1],
    foldOptions: { hingeDetentIndex: 1, hingeBehavior: 'snap' },
  }}
/>

Testing on the Simulator

Use the iPhone Duo simulator on iOS 27.1+.

  1. Unfold the device, then rotate it so the UI is in portrait. The fold is now horizontal.
  2. Present your sheet.
  3. Half-fold the device to enter tabletop. Unfold it to leave.

The example app's TrueSheet View sheet uses foldOptions with hingeBehavior: 'snap'.

Edit on GitHub

On this page