Skip to main content
VitalsReadingFlow is a complete, full-screen reading for React Native and Flutter, in the style of the NEUROFIT app. It uses only the wrapper’s public API, adds no dependency and needs no setup beyond the platform setup and activate. Present it with the React Native or Flutter quickstart. This page is the reference. The flow is a preview in 1.0.0.
The default light theme on the iOS Simulator, with sample values. The simulator has no camera, so a flat colour stands in for the camera preview.

Screens

When a reading is cancelled (the fingertip moved, the signal was poor, or the reading failed the quality check), the flow returns to positioning with a short note in the card, and the SDK starts the next reading by itself. After an interruption (the app went to the background, or another app took the camera) the card says the reading starts again by itself. If the paused screen or the tips stay open for 2 minutes, the flow turns the camera and torch off and lets the screen lock. Try again or Continue turns them back on.

Callbacks

Exactly one callback fires per mount, when the user leaves the flow. The flow then keeps showing its last screen, frozen, until you remove it. Removing the flow before then (your navigation, an iOS swipe back) stops the session and calls nothing. Every exit leaves setAutoStartEnabled(true) behind. Activation is your app’s job: without it the flow shows that readings aren’t available right now and ends with onError (notActivated). System back closes the tips first, then leaves as the close button does. In React Native, inside a Modal on Android, back goes to the Modal’s onRequestClose: forward it with the flow’s ref, onRequestClose={() => flowRef.current?.back()}. In Flutter the flow refuses the route pop and handles back itself, so the iOS swipe back is off while it shows. The close button and the callbacks cover it.

Presenting the flow

  • Full screen, with no navigation header: a React Native Modal or a header-less screen, or a Flutter route with no app bar. The flow draws its own header under the status bar.
  • In a portrait-locked screen. The SDK asks for a locked orientation during a reading.
  • One flow at a time: the wrapper runs one session.
  • Collect any consent your app needs before you show the flow. The flow explains the camera, not your app’s handling of results.
  • React Native: the flow needs the New Architecture (the default since React Native 0.76). It reads the safe-area insets of the app’s window from the native module. Pass safeAreaInsets to set them yourself, for example in a Modal with statusBarTranslucent in an Android app that does not draw edge to edge.

Camera preview

VitalsCameraPreview is a native view of the wrapper session’s camera: the session’s previewLayer on iOS, and on Android a CameraX PreviewView the session binds at start(). The flow mounts it before it calls start() and keeps the same one mounted from positioning to the end of the reading. Do the same in your own layout:
  • Mount the preview, wait for its onReady, then call start(). On Android the session binds its preview to the view that exists at start(). If it never reports ready, the flow starts after 1.5 seconds without a preview.
  • One preview shows the camera at a time: the last one mounted.
  • It keeps the screen awake while it is shown, and it is hidden from screen readers (a fingertip covers the lens).

Theme

Every colour, the font family and the corner radii can be overridden, for light and dark separately. React Native takes partial objects (theme={{ cornerRadius: 12, light: { accent: '#0055FFFF' } }}), Flutter takes defaultVitalsTheme.copyWith(...) with VitalsColors.copyWith(...). appearance is system (the default, which follows the phone), light or dark. The bundled Jost ships with its license and needs no font setup in your app. React Native registers it on Android under the private family name NeurofitVitalsJost, so a font your app calls Jost is never replaced. On iOS, if another font in your app already uses Jost’s names, the React Native flow uses the system font throughout. Colours are #RRGGBBAA strings in React Native and Color(0xAARRGGBB) in Dart. The default text and signal colours meet WCAG AA contrast over the camera preview. If you change them, check the contrast in both appearances.

Strings

Every string can be overridden: React Native strings={{ titleReading: 'Heart check' }}, Flutter defaultVitalsStrings.copyWith(titleReading: 'Heart check'). The flow fills {value} and {seconds}. Strings marked “no torch” replace their neighbour on a phone without a torch.

Accessibility

Every control and value has a screen-reader label, with units spoken in full. Focus moves to each new screen’s heading (a denied camera request counts as a new screen). The guidance, notes, a reading starting and checking are announced on iOS and read from a polite live region on Android. Text follows the system text size within a limit per element, and Reduce Motion turns the animations off.

Building blocks

For your own layout, the flow’s pieces are exported: VitalsCameraPreview, VitalsProgressRing, VitalsGuidanceCard, VitalsSignalIndicator, VitalsLiveStrip, VitalsResultsCard, vitalsGuidanceText, vitalsCancelNotice, defaultVitalsTheme and defaultVitalsStrings. Each takes the same theme and strings.