Deprecated compatibility wrapper that provides backward compatibility for applications migrating from legacy Unimodules infrastructure to Expo Modules API
—
Component creation utilities for integrating native UI components into React Native applications with automatic prop handling and cross-platform compatibility.
Drop-in replacement for React Native's requireNativeComponent that provides enhanced prop handling and view manager integration.
/**
* Create a React component for a native view manager
* Drop-in replacement for React Native's requireNativeComponent
* @param viewName - Name of the native view manager
* @returns React component for the native view
*/
function requireNativeViewManager<P = any>(viewName: string): React.ComponentType<P>;Usage Examples:
import { requireNativeViewManager } from "@unimodules/core";
import React from "react";
// Create native view component
interface CustomMapViewProps {
region: {
latitude: number;
longitude: number;
latitudeDelta: number;
longitudeDelta: number;
};
onRegionChange?: (region: any) => void;
showsUserLocation?: boolean;
style?: any;
}
const CustomMapView = requireNativeViewManager<CustomMapViewProps>('CustomMapView');
// Use in React component
function MapScreen() {
const [region, setRegion] = React.useState({
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
});
return (
<CustomMapView
style={{ flex: 1 }}
region={region}
showsUserLocation={true}
onRegionChange={(newRegion) => {
setRegion(newRegion);
}}
/>
);
}The function automatically handles prop separation between React Native standard props and custom view props.
Usage Examples:
import { requireNativeViewManager } from "@unimodules/core";
// Camera view with custom props
interface CameraViewProps {
// Standard React Native props (handled automatically)
style?: any;
testID?: string;
// Custom native view props (passed to native side)
cameraType?: 'front' | 'back';
flashMode?: 'on' | 'off' | 'auto';
quality?: number;
onCameraReady?: () => void;
onPictureTaken?: (data: { uri: string }) => void;
}
const CameraView = requireNativeViewManager<CameraViewProps>('ExpoCameraView');
function CameraScreen() {
return (
<CameraView
style={{ flex: 1 }}
testID="camera-view"
cameraType="back"
flashMode="auto"
quality={0.8}
onCameraReady={() => {
console.log('Camera is ready');
}}
onPictureTaken={(data) => {
console.log('Picture taken:', data.uri);
}}
/>
);
}Create multiple native view components for different native managers.
Usage Examples:
import { requireNativeViewManager } from "@unimodules/core";
// Different native views
const VideoView = requireNativeViewManager<{
source: { uri: string };
shouldPlay?: boolean;
isLooping?: boolean;
volume?: number;
onPlaybackStatusUpdate?: (status: any) => void;
}>('ExpoVideoView');
const WebView = requireNativeViewManager<{
source: { uri: string };
onLoadStart?: () => void;
onLoadEnd?: () => void;
onError?: (error: any) => void;
}>('ExpoWebView');
const BlurView = requireNativeViewManager<{
intensity?: number;
tint?: 'light' | 'dark' | 'default';
}>('ExpoBlurView');
// Use multiple views
function MediaScreen() {
return (
<View style={{ flex: 1 }}>
<VideoView
style={{ height: 200 }}
source={{ uri: 'https://example.com/video.mp4' }}
shouldPlay={true}
volume={0.8}
/>
<WebView
style={{ flex: 1 }}
source={{ uri: 'https://example.com' }}
onLoadEnd={() => console.log('Web page loaded')}
/>
<BlurView
style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 100 }}
intensity={50}
tint="light"
/>
</View>
);
}The function includes development-time validation to ensure view managers are properly registered.
Usage Examples:
import { requireNativeViewManager } from "@unimodules/core";
// This will warn in development if 'MyCustomView' is not registered
const MyCustomView = requireNativeViewManager('MyCustomView');
// Handle potential missing view managers gracefully
function createOptionalNativeView(viewName: string) {
try {
return requireNativeViewManager(viewName);
} catch (error) {
console.warn(`Native view ${viewName} not available:`, error.message);
return null;
}
}
// Conditional native view usage
const OptionalView = createOptionalNativeView('OptionalNativeView');
function ConditionalViewScreen() {
if (OptionalView) {
return <OptionalView style={{ flex: 1 }} />;
} else {
return <View style={{ flex: 1 }}><Text>Native view not available</Text></View>;
}
}Working with refs to access native view methods.
Usage Examples:
import { requireNativeViewManager } from "@unimodules/core";
import React, { useRef } from "react";
interface CameraViewRef {
takePictureAsync: (options?: any) => Promise<{ uri: string }>;
recordAsync: (options?: any) => Promise<{ uri: string }>;
stopRecording: () => void;
}
const CameraView = requireNativeViewManager<{
ref?: React.Ref<CameraViewRef>;
cameraType?: 'front' | 'back';
}>('ExpoCameraView');
function CameraWithControls() {
const cameraRef = useRef<CameraViewRef>(null);
const takePicture = async () => {
if (cameraRef.current) {
try {
const result = await cameraRef.current.takePictureAsync({
quality: 0.8,
base64: false
});
console.log('Picture saved to:', result.uri);
} catch (error) {
console.error('Failed to take picture:', error);
}
}
};
const startRecording = async () => {
if (cameraRef.current) {
try {
const result = await cameraRef.current.recordAsync({
maxDuration: 10, // 10 seconds
quality: 'high'
});
console.log('Video saved to:', result.uri);
} catch (error) {
console.error('Failed to record video:', error);
}
}
};
return (
<View style={{ flex: 1 }}>
<CameraView
ref={cameraRef}
style={{ flex: 1 }}
cameraType="back"
/>
<View style={{ flexDirection: 'row', justifyContent: 'space-around', padding: 20 }}>
<Button title="Take Picture" onPress={takePicture} />
<Button title="Record Video" onPress={startRecording} />
</View>
</View>
);
}Add runtime prop validation for native views.
Usage Examples:
import { requireNativeViewManager } from "@unimodules/core";
import React from "react";
// Create wrapper with prop validation
function createValidatedNativeView<P>(viewName: string, validator?: (props: P) => void) {
const NativeView = requireNativeViewManager<P>(viewName);
return React.forwardRef<any, P>((props, ref) => {
if (validator) {
validator(props);
}
return <NativeView ref={ref} {...props} />;
});
}
// Example with validation
interface MapViewProps {
region: {
latitude: number;
longitude: number;
latitudeDelta: number;
longitudeDelta: number;
};
zoom?: number;
}
const MapView = createValidatedNativeView<MapViewProps>('MapView', (props) => {
if (props.zoom && (props.zoom < 0 || props.zoom > 20)) {
throw new Error('Zoom level must be between 0 and 20');
}
if (Math.abs(props.region.latitude) > 90) {
throw new Error('Latitude must be between -90 and 90');
}
if (Math.abs(props.region.longitude) > 180) {
throw new Error('Longitude must be between -180 and 180');
}
});Handle platform-specific view managers.
Usage Examples:
import { requireNativeViewManager, Platform } from "@unimodules/core";
// Platform-specific view creation
function createPlatformNativeView(viewNames: { ios?: string; android?: string; web?: string }) {
const viewName = Platform.select(viewNames);
if (!viewName) {
console.warn('No native view available for current platform');
return null;
}
return requireNativeViewManager(viewName);
}
// Platform-specific implementation
const PlatformSpecificView = createPlatformNativeView({
ios: 'IOSSpecificView',
android: 'AndroidSpecificView',
web: 'WebSpecificView'
});
function PlatformViewScreen() {
if (!PlatformSpecificView) {
return <Text>Platform-specific view not available</Text>;
}
return (
<PlatformSpecificView
style={{ flex: 1 }}
// Platform-specific props will be different
{...Platform.select({
ios: { iosSpecificProp: true },
android: { androidSpecificProp: 'value' },
web: { webSpecificProp: 42 }
})}
/>
);
}type NativeViewComponent<P = any> = React.ComponentType<P>;
interface NativeViewManagerAdapter {
<P = any>(viewName: string): NativeViewComponent<P>;
}
interface ViewManagerConfig {
viewManagersNames: string[];
}
interface NativeExpoComponentProps {
proxiedProperties: object;
}Install with Tessl CLI
npx tessl i tessl/npm-unimodules--core