React Native component: use the native iOS Alert and a custom Modal-based alert on Android (since Alert on Android is limited and Alert.prompt is iOS-only).
From GitHub:
npm install github:AGLFlorida/react-native-crossplatform-alertOr add to package.json:
"react-native-crossplatform-alert": "github:AGLFlorida/react-native-crossplatform-alert#v0.1.0"Prefer a tag (e.g. #v0.1.0) or branch for reproducible installs.
Bundler: This package ships TypeScript source. If your app’s Metro (or other bundler) does not transpile node_modules by default, add this package to the list of modules to transpile (e.g. in Metro, use resolver.unstable_enablePackageExports and ensure the package is not excluded from transformation, or add it to watchFolders / transformer include if required by your setup).
On iOS: use Alert.alert() from React Native as usual.
On Android: render AndroidAlert with local state and pass your theme colors (or use the built-in light defaults).
import { Platform } from 'react-native';
import { Alert } from 'react-native';
import { AndroidAlert, defaultAlertColorsLight } from 'react-native-crossplatform-alert';
function MyScreen() {
const [showAlert, setShowAlert] = useState(false);
const openDialog = () => {
if (Platform.OS === 'android') {
setShowAlert(true);
} else {
Alert.alert('Title', 'Message', [
{ text: 'OK', onPress: () => {} },
]);
}
};
return (
<>
<Button onPress={openDialog} title="Show" />
<AndroidAlert
title="Title"
message="Message"
visible={showAlert}
onDismiss={() => setShowAlert(false)}
buttons={[{ text: 'OK', onPress: () => {} }]}
colors={defaultAlertColorsLight}
/>
</>
);
}Pass a colors prop to match your app theme. If you omit it, the light palette is used.
import { AndroidAlert, type AlertColors } from 'react-native-crossplatform-alert';
const myThemeColors: AlertColors = {
background: '#1C1C1E',
label: '#FFFFFF',
message: '#EBEBF5',
divider: '#747476',
highlight: '#2C2C2E',
};
<AndroidAlert
title="Title"
message="Message"
visible={visible}
onDismiss={onDismiss}
buttons={[{ text: 'OK' }]}
colors={myThemeColors}
/>The package also exports defaultAlertColorsDark for a dark appearance.
Buttons support style: 'cancel' | 'destructive' | 'default' (matching iOS semantics):
buttons={[
{ text: 'Cancel', style: 'cancel', onPress: () => {} },
{ text: 'Delete', style: 'destructive', onPress: handleDelete },
]}options.cancelable: iftrue(default), tapping the backdrop callsonDismiss.
- AndroidAlert – Modal alert; renders only on Android (returns
nullon iOS). - AlertColors – Type for the
colorsprop. - defaultAlertColorsLight / defaultAlertColorsDark – Built-in palettes.
- Scripts:
npm run lint(ESLint),npm run test(Jest),npm run test:coverage(coverage),npm run typecheck(TypeScripttsc --noEmit). - CI: GitHub Actions workflow
.github/workflows/ci.ymlruns on push/PR tomainormaster: lint → test → typecheck (each job depends on the previous). - Style: See
STYLEGUIDE.mdfor code and test conventions. - Dev dependencies: Jest and ts-jest for unit tests; ESLint with TypeScript, React, React Hooks, and Jest plugins for linting; React and React Native as dev peers for tests and typecheck.
MIT