HealthImportCard
HealthImportCard renders health-access state and per-type status for an app-provided HealthImportAdapter. It can also display optional SyncProgress values. Import the component from @ovok/native/ui and the adapter type from @ovok/native/bt-management.
import { HealthImportCard } from "@ovok/native/ui";
import type { HealthImportAdapter } from "@ovok/native/bt-management";
type HealthType = "steps" | "weight";
const adapter: HealthImportAdapter<HealthType> = {
getStatus: async (type) => readPermissionStatus(type),
request: async (types, background) => {
await requestAppHealthAccess(types, { background });
},
};
<HealthImportCard
types={["steps", "weight"]}
adapter={adapter}
background
labelForType={(type) => healthTypeLabels[type]}
/>
This is an adapter-driven UI component. It does not configure HealthKit or Health Connect, and it does not start the SDK's DataSync import pipeline. For those integrations, see DataSync and the HealthKit and Health Connect guide.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
types | readonly TType[] | Required | App-defined types to request and display. |
adapter | HealthImportAdapter<TType> | Required | Supplies asynchronous access-status and request methods. |
background | boolean | false | Passed to adapter.request(types, background). |
title | string | Health data import | Card title and switch accessibility label. |
labelForType | (type: TType) => string | Type key | Format each type's display label. |
progress | Partial<Record<TType, SyncProgress>> | — | Optional per-type import progress shown below access status. |
statusLabels | Partial<Record<SyncProgress["status"], string>> | — | Override labels in the nested progress list. Does not change access-status copy. |
reasonLabels | Partial<Record<SyncPauseReason, string>> | — | Override pause-reason labels in the progress list. |
theme, slots | OvokUiProps | Active Paper theme and SDK slots | Apply theme or replace Button, Card, Text, Switch, or ActivityIndicator. |
testID | string | — | Identifier applied to the card. |
The adapter contract is:
interface HealthImportAdapter<TType extends string = string> {
getStatus(type: TType): Promise<"authorized" | "shouldRequest" | "refused" | "unsupported">;
request(types: readonly TType[], background: boolean): Promise<void>;
}
Status and request behavior
The component calls getStatus for each listed type on mount and after a successful request. It shows these built-in labels:
| Adapter status | Displayed state |
|---|---|
authorized | Up to date |
shouldRequest | Waiting for permission |
refused | Not shared |
unsupported | Unavailable on this device |
| No status yet | Checking access |
The card is enabled only when every listed type is authorized. It marks refused types with an additional notice. If getStatus fails, the card displays the error and keeps that type's previous status, if one was already available.
Turning the card on calls adapter.request(types, background) and refreshes the statuses when the promise resolves. Turning it off only changes local UI state. The adapter contract has no revoke, stop, or cancel method, so switching off does not revoke OS permission or stop an app-owned import service. The card does not subscribe to permission changes made elsewhere; refresh or remount it from app-owned state when access may have changed in system settings.
The built-in access-status labels are fixed English copy. statusLabels and reasonLabels customize only the nested sync-progress list. Localize the card title and type names with title and labelForType, or use a custom app component if the access-status wording needs to vary.
See Reusable flows for the app integration boundary.