iPhone Duo
Apple's first foldable (ships 2026-10-23) presents a 7.6" unfolded display with a reserved fold line down the middle, and a 5.4" folded cover display. AniUI's 150 components adapt out of the box; 10 overlay components also opt into fold-aware positioning when expo-hinge is installed.
What works out of the box#
All 149 AniUI components use useWindowDimensions() and useSafeAreaInsets() internally. Expo SDK 58's UIKit scene-based lifecycle resizes the window when the user unfolds the device; React Native re-lays out; your UI follows along. No code change required for most layouts to work on day one on both displays.
Horizontal safe-area insets (insets.left, insets.right) are read by animated-header-scrollview, tray, and all overlay primitives (popover, dropdown-menu, tooltip, …), so content respects the reserved region.
Opt-in fold awareness#
Install the expo-hinge peer dep to enable fold-aware overlay positioning. Ten overlay components (Dialog, AlertDialog, Popover, HoverCard, DropdownMenu, ContextMenu, Tooltip, BottomSheet, ActionSheet, Toast, CommandMenu) shift away from the fold line when the device reports as unfolded, so they stay inside one pane instead of visually bisecting the screen.
# Opt into fold-aware overlays
npx expo install expo-hinge
# No code change needed in your app — the 10 fold-aware overlays
# (Dialog, Popover, HoverCard, DropdownMenu, ContextMenu, Tooltip,
# BottomSheet, ActionSheet, Toast, CommandMenu) consume useFoldFeatures()
# internally and automatically shift away from the fold line on an
# unfolded Duo.Without expo-hinge installed, every component behaves exactly as it does today — the hook's require() is wrapped in a try/catch and returns all-null fields, which overlays short-circuit on.
useFoldFeatures()#
The primitive hook: a React hook that returns the current fold state. Returns all-null on non-fold devices.
import { useFoldFeatures } from "@/components/ui/fold";
import { View, Text } from "react-native";
function MyPane() {
const fold = useFoldFeatures();
// Pre-fold / non-Duo: fold.foldX is null — short-circuit back to normal.
if (fold.foldX === null) {
return <View><Text>Normal layout</Text></View>;
}
// Unfolded Duo: fold.foldX = window.width / 2 (the fold line).
// Pin content to the left pane:
return (
<View style={{ width: fold.foldX }}>
<Text>Left pane content</Text>
</View>
);
}Shape:
isFolded—boolean | null. True when closed, false when open, null on non-fold devices.foldX—number | null. The fold line's x-coordinate in window pixels when unfolded. Null otherwise.hingeAngle—number | null. Raw hinge angle in degrees (0 closed, 180 flat).postureHint—"flat" | "half-open" | "closed" | null.
foldPane prop (BottomSheet & ActionSheet)#
BottomSheet and ActionSheet accept a foldPane prop that picks which pane the sheet clamps to on an unfolded Duo. Default is "left"; set to "full" to opt out and keep the pre-fold screen-wide behavior.
// Clamp a BottomSheet to one pane on an unfolded Duo:
<BottomSheet ref={ref} foldPane="right">
<Text>Shows on the right pane only</Text>
</BottomSheet>
// Opt out — span the full screen like today:
<BottomSheet ref={ref} foldPane="full">
<Text>Spans both panes</Text>
</BottomSheet>
// Default is "left" (left pane is primary on iPhone Duo).What's not yet in 0.8.0#
Deferred to 0.8.1 — tracked separately because they need testing on real hardware (which ships 2026-10-23):
- Hinge-angle-reactive components (carousels that pause mid-flip at 90°, ArcList with hinge-synced scroll).
- A
DuoSplitprimitive wrapping Expo UI'sArrangementView/NavigationSplitViewfor two-pane layouts. - Posture-aware variants (tent mode, book mode). Apple's HIG explicitly warns against using hinge state for layout; this stays interactions-only.
See also: Expo SDK 58 guide · Compatibility matrix

