@acertijosapps/react-native-fold
v1.0.1
Published
Foldable detection (tabletop/book) for React Native on Android and iOS
Readme
@acertijosapps/react-native-fold
Foldable detection (tabletop/book) for React Native. Android reads folding posture
from androidx.window; iOS reads hinge state from UIHingeInteraction (iOS 27.1+).
[!WARNING] iOS detection requires building your app with Xcode 27.1 or later (iOS 27.1 SDK). With an older Xcode the library still compiles, but the hinge APIs are left out and
useFold()is alwaysnullon iOS, even on an iPhone Duo.
Screenshots
The example app on a half-opened device. The dark bar prints what useFold() returns.
| | Book posture · FoldBookPane | Tabletop posture · FoldPane |
|---|---|---|
| iOS · iPhone Duo | | |
| Android · Pixel 10 Pro Fold | | |
Requirements
- React Native 0.80 or later with the New Architecture (this is a Turbo Module).
- React 19.1 or later.
Installation
yarn add @acertijosapps/react-native-foldor with npm:
npm install @acertijosapps/react-native-foldUsage
import { FoldBookPane, FoldPane, FoldProvider } from '@acertijosapps/react-native-fold';
function App() {
return (
<FoldProvider>
<FoldBookPane
start={<Left />}
end={<Right />}
fallback={
<FoldPane
primary={<Top />}
secondary={<Bottom />}
fallback={<Single />}
/>
}
/>
</FoldProvider>
);
}useFold() returns:
type FoldState = {
isSeparating: boolean;
isHalfOpened: boolean;
orientation: 'horizontal' | 'vertical';
bounds: { x: number; y: number; width: number; height: number };
} | null;bounds is always in dp: Android divides by density in Kotlin; iOS points are already
density-independent.
FoldPane splits only when isSeparating && isHalfOpened && orientation === 'horizontal',
and falls back when the hinge is not strictly inside the pane. It measures its own position
in the window, so panels line up with the hinge even below a header; the spacer takes the
hinge height and it never splits 50/50.
FoldBookPane is the book-posture counterpart: it splits start | end side by side only
when isSeparating && isHalfOpened && orientation === 'vertical', measures its own x offset
in the window and reserves bounds.width between both panels (the fold plus its margins on
iOS, the fold line on Android). Nest FoldPane as its fallback to cover both postures.
Platform support
- Android:
WindowInfoTrackerCallbackAdapter+FoldingFeature(androidx.window1.5.1). - iOS 27.1+:
UIHingeInteractionfor the hinge status plusUIViewReservedRegion(divisionRegionKind) for the geometry.boundsis the division region frame, including the margins iOS reserves around the fold for interactive content.orientationcomes from the region's aspect,isSeparatingfrom the region being active andisHalfOpenedfromPartiallyOpen. On the cover display there is no division region anduseFold()isnull; below iOS 27.1 it is alwaysnull.
License
MIT
