Helpers
The SDK exports helpers used internally by its components so apps can reuse the same
Formik field wrappers, conditional rendering, logger, and telemetry utilities. Import
them from @ovok/native/helpers or the package root @ovok/native. Bottom-sheet
components remain on their own package and are not re-exported by the SDK root.
Source: src/modules/helpers/index.tsx.
Exports at a glance
import {
Conditional,
FormField,
FormSelect,
FormDateField,
slog,
configureOvokLogger,
ovokLogger,
configureOvokTelemetry,
sanitizeOvokTelemetryAttributes,
startOvokSpan,
recordOvokMetric,
recordOvokDuration,
addOvokSpanEvent,
emitOvokLog,
withOvokSpan,
withAnimated,
} from "@ovok/native";
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
| Export | Module path | Source library |
|---|---|---|
Conditional | ./conditional.tsx | SDK |
FormField | ./form-items/form-field.tsx | SDK (wraps react-native-paper TextInput) |
FormSelect | ./form-items/form-select.tsx | SDK (wraps react-native-element-dropdown) |
FormDateField | ./form-items/form-date-field.tsx | SDK (wraps react-native-modal-datetime-picker) |
slog | ./utils/s-log.ts | SDK logger compatibility helper; see Logging. |
configureOvokLogger, ovokLogger | ./utils/sentry-logger.ts | Configurable logger and direct log API; see Logging. |
configureOvokTelemetry and telemetry types | ./utils/telemetry.ts | Provider setup; see Telemetry. |
sanitizeOvokTelemetryAttributes and telemetry helpers | ./utils/telemetry.ts | Spans, metrics, durations, events, and OTel logs; see Telemetry. |
withAnimated | ./utils/with-animated.tsx | SDK (Reanimated HOC bridge) |
<Conditional>
Renders children only when condition is truthy. Cleaner than {cond && <View>...</View>} for multi-line branches and easier to scan in deeply-nested trees.
interface ConditionalProps {
condition: boolean;
children: React.ReactNode;
}
<Conditional condition={isMfaRequired}>
<MfaCodeInput onSubmit={handleMfa} />
</Conditional>
condition === false → returns null. No fallback prop; pair with a sibling for else branches.
See the form helper references and withAnimated for
the remaining helper APIs.
<FormField>
A Formik-bound text input. Reads value/error/touched from the Formik context you pass via context and routes change/blur back through the form. Renders react-native-paper's <TextInput mode="outlined"> plus a <HelperText> for errors, with the error message run through react-i18next's t().
interface FormFieldProps extends Omit<TextInputProps, "onChangeText" | "value" | "testID"> {
name: string;
context: React.Context<any>;
containerStyle?: ViewStyle;
inputRef?: React.Ref<{ focus: () => void }>;
testID?: string;
}
import { useFormik } from "formik";
import * as React from "react";
import { FormField } from "@ovok/native";
const FormContext = React.createContext<ReturnType<typeof useFormik> | null>(null);
function SignInForm() {
const form = useFormik({
initialValues: { email: "" },
onSubmit: async (values) => { /* ... */ },
});
return (
<FormContext.Provider value={form}>
<FormField name="email" context={FormContext} label="Email" />
</FormContext.Provider>
);
}
Error messages are looked up as translation keys, so feed Yup/Zod schemas key names like "validation.email.required" rather than raw English strings.
<FormSelect>
Formik-bound dropdown with an animated floating label. Wraps react-native-element-dropdown's <Dropdown>. Generic on the option type T.
interface FormSelectProps<T extends object> extends Omit<DropdownProps<T>, "data" | "onChange" | "onBlur" | "placeholder"> {
name: string;
context: React.Context<any>;
label?: string;
options: T[];
labelStyle?: TextStyle;
onChange?: (item: T) => void;
onBlur?: () => void;
}
<FormSelect
name="country"
context={FormContext}
label="Country"
options={countries}
labelField="name"
valueField="code"
/>
The selected value is written via setFieldValue(name, item[valueField]) — so valueField must be a key of T whose value is the discriminator your schema validates.
<FormDateField>
Formik-bound date picker. Wraps react-native-modal-datetime-picker and writes the result back as a YYYY-MM-DD string (via date.toISOString().split('T')[0]). Supports mode: 'date' | 'time' | 'datetime'; default is 'date'.
interface FormDateFieldProps {
name: string;
context: React.Context<any>;
label?: string;
testID?: string;
containerStyle?: ViewStyle;
labelStyle?: TextStyle;
mode?: "date" | "time" | "datetime";
}
<FormDateField name="dateOfBirth" context={FormContext} label="Date of birth" />
Note: every mode is serialized as YYYY-MM-DD; the time component is discarded even
when mode is 'time' or 'datetime'. If you need a time or full ISO timestamp,
write a separate field wrapper. labelStyle is part of the public type but is not
currently applied by the component.
Logging and telemetry
The helpers module exposes logging and telemetry functions rather than rendered UI components. Use the focused references for their complete signatures and behavior:
- Logging —
slog,configureOvokLogger, andovokLogger, including console behavior, callback routing, and log-data boundaries. - Telemetry — provider adapters, span and metric helpers, the attribute allowlist, and the built-in SDK signal catalog.
The app owns provider and exporter setup. OpenTelemetry peers are optional, and telemetry helpers remain best-effort when no provider is available.
withAnimated(Component)
Higher-order component that bridges a React Native Paper class component into a react-native-reanimated animated component. Worked around callstack/react-native-paper#2364 — createAnimatedComponent on a class component requires a class wrapper, which is what this HOC supplies.
const withAnimated: <T extends object>(
WrappedComponent: React.ComponentType<T>,
) => React.ComponentType<AnimatedProps<T>>;
import { Card } from "react-native-paper";
import { withAnimated } from "@ovok/native";
const AnimatedCard = withAnimated(Card);
Use only when a Paper class component needs useAnimatedStyle/useSharedValue. Function components don't need this — Animated.createAnimatedComponent accepts them directly.
BottomSheetModalProvider
Mount BottomSheetModalProvider from @gorhom/bottom-sheet once at the root when using <PickerSheet> or another bottom-sheet component. It is intentionally not exported from @ovok/native:
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { ThemeProvider as OvokThemeProvider } from "@ovok/native";
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<BottomSheetModalProvider>
<OvokThemeProvider theme={themeConfig}>
<YourScreens />
</OvokThemeProvider>
</BottomSheetModalProvider>
</GestureHandlerRootView>
);
}
This is the same provider you'd import from @gorhom/bottom-sheet directly. It is
not a public @ovok/native export; install the peer and import it from
@gorhom/bottom-sheet when your app uses bottom sheets.
Related
- PickerSheet — uses
BottomSheetModalProvider - Sign-In — uses
FormFieldinternally