Skip to main content
‹ System UI
Hook

useHinge()

The device's hinge: its state and angle. Null on a device without a hinge, and for the moment before the first value comes. The screen renders again on every change, often while the hinge moves: for an animation driven by the angle, useHingeChange. For the layout of a screen the fold calls for, defineArrangement and useReservedRegions.

SectionSystem UIDraftDocumented, not reviewed yet: the API can change.
Import
import { useHinge } from '@apexnative/navigation';

useHinge gives the hinge of a device that folds: whether it is closed, partly open or open, and its angle. It is for effects that follow the device, such as a picture that tilts as the user opens it. The component renders again on every change. Any component can call it: it reads the device, not a screen.

Usage​

src/screens/Settings.tsx
import { Text } from 'react-native';
import { useHinge } from '@apexnative/navigation';

function HingeAngle() {
const hinge = useHinge();
if (!hinge || hinge.angle === null) return null;
return <Text>The device is open {Math.round(hinge.angle)}°</Text>;
}

On iPhone Duo or an Android foldable the text follows the angle as the user opens and folds the device. On a device without a hinge it renders nothing.

Signature​

function useHinge(): Hinge | null
Defined in src/api/hooks/useHinge.ts ↗

It takes nothing, and returns the hinge, or null on a device without one and for the moment before the first value comes.

The hinge​

state​

state: 'closed' | 'partiallyOpen' | 'fullyOpen' | 'unknown'
Type'closed' | 'partiallyOpen' | 'fullyOpen' | 'unknown' Required.PlatformsiOSiPadOSAndroid
  • 'closed': folded shut.
  • 'partiallyOpen': open part of the way, as a book or a laptop.
  • 'fullyOpen': open as far as the device goes.
  • 'unknown': the platform can't tell.

iOS As UIKit's UIHingeInteraction says (iOS 27.1). It turns 'partiallyOpen' early: iPhone Duo says so from 174°.

Android 'partiallyOpen' and 'fullyOpen' come from the fold of the app's window (HALF_OPENED and FLAT). Android has no public closed state, so 'closed' is told by the hinge angle sensor: the window has no fold and the angle is below 90°. 'unknown' otherwise.

angle​

angle: number | null
Typenumber | null Required.PlatformsiOSiPadOSAndroid

Degrees: 0 closed, 180 open flat. null where the platform gives none.

  • iOS: null while the state is 'unknown'.
  • Android: from the hinge angle sensor, Android 11+; null without one. Some devices give only 0, 90 and 180, and a device that folds back goes beyond 180.

The layout belongs to pairs and regions​

Apple's advice holds on both platforms: lay a screen out by the pair and the regions, not by the angle. The system decides when the screen divides, and a pair and useReservedRegions follow its decision; the angle at which it decides is the system's, and differs between devices. The hinge is for effects on top of that layout.

How often it renders​

While the user moves the hinge, a new value comes many times a second (on iPhone Duo every 30–50 ms), and the component renders each time. For an animation that follows the angle, use useHingeChange: it calls a function instead, without a render. Read useHinge in the small component that shows the value, not at the top of a screen.

What it costs​

The hinge is watched only while a component with useHinge or useHingeChange is mounted: the first one starts it, the last one to unmount stops it. On Android the hinge angle sensor costs power, and runs only while a hook is mounted and the app is in the foreground. Mount the hook on the screen that needs it, not around the whole app.

See also​

Generated from the types and their comments. Edit the source ↗