I've created my first NPM package which is a React Native component library. I have have published it, but I can't seem to figure out what I'm doing wrong to get it working in my project. I'm getting the error Can't find variable: React
.
index.js (Am I correctly exporting my react native components here?)
// Exports: Components
export { DateRangePicker } from './DateRangePicker';
export { DatePicker } from './DatePicker';
export { TimePicker } from './TimePicker';
export { DateTimePicker } from './DateTimePicker';
export { ListPicker } from './ListPicker';
export { StatePicker } from './StatePicker';
export { StatePickerSmall } from './StatePickerSmall';
DatePicker.tsx
// Imports: Dependencies
import * as React from 'react';
import { DatePickerAndroid, DatePickerIOS, Dimensions, Platform, StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import Modal from 'react-native-modal';
import moment from 'moment';
import Icon from 'react-native-vector-icons/Ionicons';
Icon.loadFont();
// Screen Dimensions
const { height, width } = Dimensions.get('window');
// TypeScript: Types
interface Props {
title: string,
onPress: Function,
onValueChange: Function,
mode: 'calendar' | 'spinner' | 'default',
minDate?: Date | number;
maxDate?: Date | number;
}
interface AndroidProps {
action: 'dateSetAction' | 'dismissedAction',
newDate?: Date;
year?: number;
month?: number;
day?: number;
}
// Component: Date Picker
export const DatePicker = (props: Props) => {
// React Hooks: State
const [ modalVisible, toggle ] = React.useState(false);
const [ date, setDate ] = React.useState(new Date());
// Toggle Modal
const toggleModal = async (props: Props) => {
try {
// Check Platform (iOS)
if (Platform.OS === 'ios') {
// React Hook: Toggle Modal
toggle((modalVisible) => !modalVisible);
}
// Check Platform (Android)
if (Platform.OS === 'android') {
const { action, year, month, day } : AndroidProps = await DatePickerAndroid.open({
date: date,
mode: props.mode,
});
// Action: Date Set
if (
action === DatePickerAndroid.dateSetAction
&& year !== undefined
&& month !== undefined
&& day !== undefined
) {
// New Date
let newDate:Date = new Date(year, month, day);
// Select Date
selectDate(newDate);
}
// Action: Dismissed
else if (action === DatePickerAndroid.dismissedAction) {
// Do Nothing
}
};
}
catch (error) {
console.log(error);
}
};
// Select Date
const selectDate = (date: Date) => {
try {
// React Hook: Set Date
setDate(date);
// React Props: onValueChange
props.onValueChange(date);
}
catch (error) {
console.log(error);
}
};
// Render Picker
const renderPicker = () => {
try {
return (
<DatePickerIOS
mode="date"
date={date}
onDateChange={() => selectDate(date)}
/>
)
}
catch (error) {
console.log(error);
}
};
return (
<View style={styles.container}>
<View style={styles.inputTitleContainer}>
<Text style={styles.inputTitle}>{props.title}</Text>
</View>
<TouchableOpacity onPress={() => toggleModal(props)} style={styles.fieldTextContainer}>
<Text style={styles.fieldText} numberOfLines={1}>{date ? moment(date).format('MMM Do, YYYY') : 'Select'}</Text>
<Icon name="ios-arrow-forward" size={22} style={styles.arrowForward}/>
</TouchableOpacity>
<Modal isVisible={modalVisible} style={styles.modal}>
<View style={styles.modalContainer}>
<View style={styles.pickerHeaderContainer}>
<TouchableOpacity onPress={() => toggleModal(props)} >
<Text style={styles.doneText}>Done</Text>
</TouchableOpacity>
</View>
<View style={styles.pickerContainer}>
{renderPicker()}
</View>
</View>
</Modal>
</View>
);
}
// Styles
const styles = StyleSheet.create({
container: {
display: 'flex',
width: width - 32,
marginLeft: 16,
marginRight: 16,
justifyContent: 'center',
},
modal: {
margin: 0,
},
modalContainer: {
height: '100%',
alignItems: 'center',
justifyContent: 'flex-end',
},
pickerHeaderContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
height: 40,
width: width,
backgroundColor: '#FAFAF8',
borderColor: '#7D7D7D',
borderBottomWidth: StyleSheet.hairlineWidth,
},
pickerContainer: {
height: 220,
width: width,
// backgroundColor: '#CFD3D9',
backgroundColor: 'white',
},
doneText: {
fontFamily: 'System',
color: '#007AFF',
fontWeight: '600',
fontSize: 17,
marginRight: 16,
},
stateContainer: {
alignItems: 'center',
width: 75,
borderColor: '#7D7D7D',
borderBottomWidth: StyleSheet.hairlineWidth,
},
inputTitleContainer: {
width: 75,
marginBottom: 4,
},
inputTitle: {
color: '#7D7D7D',
borderColor: '#7D7D7D',
fontSize: 10,
fontWeight: '600',
textTransform: 'uppercase',
},
fieldTextContainer: {
height: 40,
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 4,
borderColor: '#7D7D7D',
borderBottomWidth: StyleSheet.hairlineWidth,
},
fieldText: {
width: width - 32 - 20,
fontFamily: 'System',
fontSize: 17,
fontWeight: '400',
color: '#000000',
alignSelf: 'center',
},
arrowForward: {
color: 'black',
opacity: .3,
marginRight: 7,
},
});
package.json (Link)
My NPM package is a React Native library. I have React and React Native installed as dev dependencies as well as react and react native as peerDependencies
"name": "react-native-ultimate-modal-picker",
"version": "0.1.6",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"dependencies": {
"moment": "^2.24.0",
"react-native-modal": "^11.5.3",
"react-native-vector-icons": "^6.6.0"
},
"devDependencies": {
"@babel/core": "7.7.7",
"@babel/runtime": "7.7.7",
"@react-native-community/eslint-config": "0.0.5",
"@types/jest": "^24.0.24",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.25",
"@types/react-native-vector-icons": "^6.4.5",
"@types/react-test-renderer": "16.9.1",
"@typescript-eslint/eslint-plugin": "^2.12.0",
"@typescript-eslint/parser": "^2.12.0",
"babel-jest": "24.9.0",
"eslint": "6.8.0",
"jest": "24.9.0",
"metro-react-native-babel-preset": "0.56.3",
"react": "16.9.0",
"react-native": "0.61.5",
"react-test-renderer": "16.9.0",
"typescript": "^3.7.3"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
},
When I use npm i react-native-ultimate-modal-picker to install the package in my project, it builds the app. However, when I finally get to the screen with the imported component, this error pops up.