Skip to main content

PairingFlow

PairingFlow renders devices discovered by the active Bluetooth runtime, starts pairing, presents a pairing-code field when the runtime requests one, and remembers the ID of a device after it becomes bonded. Import it from @ovok/native/ui and render it beneath BTProvider.

import { BTProvider } from "@ovok/native/bt-management";
import { PairingFlow } from "@ovok/native/ui";

<BTProvider bleManager={bleManager} acceptedDevices={acceptedDevices}>
<PairingFlow
storage={pairedDeviceStorage}
onPairingCode={(code, device) => confirmPairingCode(device, code)}
onPaired={(device) => navigation.navigate("DeviceDetails", { id: device.id })}
onError={(error, device) => reportPairingError(error, device?.id)}
/>
</BTProvider>

BTProvider owns discovery and the BLE runtime. This component does not create a manager or start a scan. Supply a PairedDeviceStorage implementation; the flow stores a JSON array of IDs, not device objects or credentials.

Props​

PropTypeDefaultDescription
storagePairedDeviceStorageRequiredAsync getItem and setItem adapter for remembered IDs.
storageKeystring@ovok/native/paired-devicesStorage key shared with the paired-device hook.
getDeviceImage(device: RuntimeDevice) => string | undefined—Return an image URI for a discovered device.
onPaired(device: RuntimeDevice) => void—Called after a bonded device has been remembered.
onPairingCode(code: string, device: RuntimeDevice) => Promise<void> | void—Handle a code when pairing requires app/device-specific confirmation.
onError(error: Error, device?: RuntimeDevice) => void—Observe pair or code-handler errors.
renderHeader(state: PairingFlowRenderState) => ReactNodeDefault headingReplace the heading and description.
renderEmpty(state: PairingFlowRenderState) => ReactNodeDefault empty messageReplace the no-devices content.
renderDevice(device, actions) => ReactNodeDefault pair rowReplace each row; actions provide pair, forget, and the flow status.
labelsRecord<string, string>English copyOverride built-in labels.
theme, slotsOvokUiPropsActive Paper theme and SDK slotsApply shared UI theme or replace Paper primitives.
testIDstring—Set the flow container ID; the code input appends -code.

The storage contract is:

interface PairedDeviceStorage {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
}

getItem should return the JSON array previously written by the flow, or null if the key is empty. The SDK validates parsed values as string IDs and treats invalid JSON as an empty list.

Pairing lifecycle​

The flow exposes these statuses through render state and custom device actions:

StatusMeaning
idleNo pairing attempt is active.
pairinguseNearbyDevices().pair is in progress or awaiting the bond event.
code-requiredA runtime pairing event requested a code; the flow shows its input.
pairedThe selected device emitted a bonded event.
errorPairing or code handling failed.

onPairingCode receives the trimmed value and selected runtime device. The flow does not confirm the code itself; provide a handler for the device's pairing procedure. A resolved handler returns the status to pairing. The matching bonded event updates the visible status to paired; after the underlying pair operation resolves, the flow stores the ID and calls onPaired only if it observed that event. If the pair operation rejects, the flow reports an error and does not store the ID.

The default row starts pairing and shows optional device image, name, manufacturer, and pair action. It does not render a forget control. To offer forgetting, supply renderDevice and call actions.forget() from your row. That method asks the active Bluetooth manager to forget the device, then removes its ID from storage; it rejects if the manager is not ready.

PairingFlowRenderState contains devices, paired IDs, optional selected device, status, and optional error. renderHeader and renderEmpty receive this state. renderDevice receives one device and an actions object:

{
pair: () => Promise<void>;
forget: () => Promise<void>;
status: PairingFlowStatus;
}

The status is shared by the flow's current selection. If rows need independent per-device state or richer accessibility behavior, own that presentation in the custom row.

The labels keys and default copy are:

KeyDefault
headerAdd a device
descriptionWake your monitor and choose it when it appears nearby.
emptyNo supported devices found yet.
deviceBluetooth device (used when the manufacturer name is empty)
pairPair
pairingCodePromptType the code your monitor shows
pairingCodePairing code
continueContinue
pairingPairing the selected device…
pairedThe selected device is ready.
retryTry again
rememberedA count-specific remembered-device message

The default pairing, paired, and remembered messages include the selected device name or count. A value supplied in labels replaces the message verbatim; the flow does not interpolate placeholders in custom strings.

See Reusable flows for integration guidance and Bluetooth for provider and device discovery setup.