basicrequirement
v1.1.2
Published
Reusable React Native UI components — inputs, buttons, loaders, and theme for astrology/login apps
Maintainers
Readme
basicrequirement
Reusable React Native UI components — inputs, buttons, loaders, and a shared theme for astrology/login-style apps.
Full setup guide: see INSTALLATION.md for prerequisites, Metro config, native setup, and troubleshooting.
Install
npm install basicrequirement react-native-svgInstall optional peer dependencies for the components you use:
# Phone / country code picker
npm install react-native-country-picker-modal
# Date & time pickers
npm install react-native-date-picker
# OptionMenu dropdown (wrap app with AppProviders)
npm install react-native-popup-menuQuick start
Wrap your app when using OptionMenu:
import { AppProviders } from 'basicrequirement';
export default function App() {
return (
<AppProviders>
{/* your screens */}
</AppProviders>
);
}Import everything you need:
import {
AppProviders,
Button,
InputField,
InputPhone,
InputEmailorPhone,
PasswordInput,
OtpInput,
CheckInput,
RadioSection,
DropdownInput,
DateInput,
TimeInput,
OptionMenu,
CountryCodePicker,
Loader,
LoaderType,
SocialSigninButton,
colors,
fonts,
} from 'basicrequirement';Shared types
| Type | Shape |
|------|-------|
| SelectOption | { label: string; value: string } |
| EmailOrPhoneMode | 'email' \| 'phone' \| 'empty' |
| ButtonVariant | 'primary' \| 'outline' \| 'ghost' |
| ButtonSize | 'sm' \| 'md' \| 'lg' |
| LoaderType | See Loader |
Components that extend React Native
TextInputPropsalso accept standardTextInputprops (keyboardType,autoFocus,placeholderTextColor, etc.) unless explicitly omitted in their type.
AppProviders
Required wrapper when using OptionMenu (provides MenuProvider from react-native-popup-menu).
Peer dependency: react-native-popup-menu
<AppProviders>
<YourApp />
</AppProviders>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | React.ReactNode | — | Required. App content |
InputField
Base text input with label, left/right slots, and error message.
const [name, setName] = useState('');
<InputField
label="Full name"
placeholder="Enter your name"
value={name}
onChangeText={setName}
error={name.length < 2 ? 'Name is too short' : undefined}
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | — | Required. Current input value |
| onChangeText | (text: string) => void | — | Required. Change handler |
| label | string | — | Label above the field |
| labelStyle | StyleProp<TextStyle> | — | Label text style |
| placeholder | string | 'Enter value' | Placeholder text |
| inputStyle | StyleProp<ViewStyle> | — | Container style |
| textStyle | StyleProp<TextStyle> | — | Input text style |
| maxLength | number | — | Max character length |
| leftComponent | ReactNode | — | Left accessory (icon, picker, etc.) |
| rightComponent | ReactNode | — | Right accessory |
| error | string | — | Error message below the field |
| editable | boolean | true | Disable input |
| + TextInputProps | — | — | All other React Native TextInput props |
PasswordInput
Password field with show/hide toggle.
const [password, setPassword] = useState('');
<PasswordInput
label="Password"
value={password}
onChangeText={setPassword}
placeholder="Enter your password"
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | — | Required. Current password |
| onChangeText | (text: string) => void | — | Required. Change handler |
| label | string | — | Label above the field |
| labelStyle | StyleProp<TextStyle> | — | Label text style |
| placeholder | string | 'Enter your password' | Placeholder text |
| inputStyle | StyleProp<ViewStyle> | — | Container style |
| textStyle | StyleProp<TextStyle> | — | Input text style |
| maxLength | number | — | Max character length |
| error | string | — | Error message |
| editable | boolean | true | Disable input |
| showToggle | boolean | true | Show Show/Hide toggle |
| toggleLabels | { show: string; hide: string } | { show: 'Show', hide: 'Hide' } | Toggle button labels |
| + TextInputProps | — | — | Excludes value, onChangeText, secureTextEntry |
OtpInput
Multi-digit OTP input with auto-focus, backspace navigation, and paste support.
const [otp, setOtp] = useState('');
<OtpInput
value={otp}
onChangeText={setOtp}
length={6}
onComplete={code => console.log('OTP complete:', code)}
label="Enter OTP"
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | — | Required. OTP digits (digits only) |
| onChangeText | (value: string) => void | — | Required. Change handler |
| length | number | 6 | Number of OTP boxes |
| onComplete | (value: string) => void | — | Called when all digits are entered |
| label | string | — | Label above boxes |
| labelStyle | StyleProp<TextStyle> | — | Label style |
| error | string | — | Error message |
| editable | boolean | true | Disable input |
| autoFocus | boolean | true | Focus first empty box on mount |
| style | StyleProp<ViewStyle> | — | Wrapper style |
| boxStyle | StyleProp<ViewStyle> | — | Individual box style |
| boxTextStyle | StyleProp<TextStyle> | — | Box text style |
InputPhone
Phone input with country code picker. The field shows local digits; onChangeText returns the full number with country code.
const [phone, setPhone] = useState('');
<InputPhone
label="Phone"
value={phone}
onChangeText={setPhone}
onCountryChange={country => console.log(country)}
/>
// onChangeText returns: "+91-9876543210"Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | — | Required. Full phone (+91-9876543210) or local digits |
| onChangeText | (text: string) => void | — | Required. Returns +{code}-{digits} |
| label | string | — | Label above the field |
| labelStyle | StyleProp<TextStyle> | — | Label style |
| placeholder | string | 'Enter your phone number' | Placeholder text |
| inputStyle | StyleProp<ViewStyle> | — | Container style |
| textStyle | StyleProp<TextStyle> | — | Input text style |
| codeTextStyle | StyleProp<TextStyle> | — | Country code text style |
| maxLength | number | 15 | Max local digit length |
| rightComponent | ReactNode | — | Right accessory |
| error | string | — | Error message |
| editable | boolean | true | Disable input |
| selectedCode | CountryCode | 'IN' | Default ISO country code |
| selectedCountry | Country \| null | — | Controlled selected country object |
| onCountryChange | (country: Country) => void | — | Country selection callback |
| + TextInputProps | — | — | Excludes value, onChangeText |
Peer dependency: react-native-country-picker-modal
InputEmailorPhone
Auto-detects email vs phone. In phone mode, shows the country picker and returns +{code}-{digits}.
const [contact, setContact] = useState('');
const [mode, setMode] = useState<EmailOrPhoneMode>('empty');
<InputEmailorPhone
label="Email or phone"
value={contact}
onChangeText={setContact}
onModeChange={setMode}
/>
// Email: "[email protected]"
// Phone: "+91-9876543210"Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | — | Required. Email or full phone value |
| onChangeText | (text: string) => void | — | Required. Change handler |
| label | string | — | Label above the field |
| labelStyle | StyleProp<TextStyle> | — | Label style |
| placeholder | string | 'Enter email or phone number' | Placeholder text |
| inputStyle | StyleProp<ViewStyle> | — | Container style |
| textStyle | StyleProp<TextStyle> | — | Input text style |
| codeTextStyle | StyleProp<TextStyle> | — | Country code text style |
| maxLength | number | 50 | Max character length |
| rightComponent | ReactNode | — | Right accessory |
| error | string | — | Error message |
| editable | boolean | true | Disable input |
| selectedCode | CountryCode | 'IN' | Default ISO country code |
| selectedCountry | Country \| null | — | Controlled selected country |
| onCountryChange | (country: Country) => void | — | Country selection callback |
| onModeChange | (mode: EmailOrPhoneMode) => void | — | Called when mode changes (email, phone, empty) |
| + TextInputProps | — | — | Excludes value, onChangeText |
Peer dependency: react-native-country-picker-modal
CountryCodePicker
Standalone country code picker (flag + calling code + dropdown). Used internally by InputPhone and InputEmailorPhone, also exported for custom layouts.
<CountryCodePicker
selectedCode="IN"
onSelect={country => console.log(country.callingCode)}
editable
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| onSelect | (country: Country) => void | — | Required. Country selection handler |
| selectedCode | CountryCode | 'IN' | ISO country code |
| selectedCountry | Country \| null | null | Controlled country object |
| editable | boolean | true | Allow opening the picker |
| codeTextStyle | StyleProp<TextStyle> | — | Calling code text style |
| defaultCallingCode | string | '91' | Fallback calling code |
| excludeCountries | CountryCode[] | ['AQ','BV',...] | Countries to hide |
| theme | typeof DARK_THEME | DARK_THEME | Picker modal theme |
Peer dependency: react-native-country-picker-modal
CheckInput
Multi-select checkbox group.
const [selected, setSelected] = useState<string[]>([]);
<CheckInput
options={[
{ label: 'Love', value: 'love' },
{ label: 'Career', value: 'career' },
]}
selectedValues={selected}
onChange={setSelected}
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| options | SelectOption[] | — | Required. Checkbox options |
| onChange | (values: string[]) => void | — | Required. Selection change handler |
| selectedValues | string[] | [] | Currently selected values |
| style | StyleProp<ViewStyle> | — | Container style |
| optionStyle | StyleProp<ViewStyle> | — | Individual option style |
| labelStyle | StyleProp<TextStyle> | — | Option label style |
| iconColor | string | colors.primary | Checkbox border/check color |
| iconSize | number | 20 (scaled) | Checkbox size |
RadioSection
Single-select radio button group.
const [gender, setGender] = useState<string | null>(null);
<RadioSection
options={[
{ label: 'Male', value: 'male' },
{ label: 'Female', value: 'female' },
]}
selectedValue={gender}
onSelect={setGender}
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| options | SelectOption[] | — | Required. Radio options |
| onSelect | (value: string) => void | — | Required. Selection handler |
| selectedValue | string \| null | null | Currently selected value |
| style | StyleProp<ViewStyle> | — | Container style |
| optionStyle | StyleProp<ViewStyle> | — | Individual option style |
| labelStyle | StyleProp<TextStyle> | — | Option label style |
| iconColor | string | colors.primary | Radio icon color |
| iconSize | number | 22 (scaled) | Radio icon size |
DropdownInput
Dropdown selector with inline or modal list.
const [city, setCity] = useState('');
<DropdownInput
label="City"
placeholder="Select city"
value={city}
onChangeText={setCity}
data={[
{ label: 'Mumbai', value: 'mumbai' },
{ label: 'Delhi', value: 'delhi' },
]}
isModal={false}
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | — | Required. Selected option value |
| onChangeText | (value: string) => void | — | Required. Selection handler |
| data | SelectOption[] | — | Required. Dropdown options |
| placeholder | string | 'Select' | Placeholder when empty |
| label | string | — | Label above the field |
| error | string | — | Error message |
| inputStyle | StyleProp<ViewStyle> | — | Container style |
| isModal | boolean | false | Open list in a modal |
| editable | boolean | true | Disable selection |
| onFocus | () => void | — | Called when dropdown opens |
| onBlur | () => void | — | Called when dropdown closes |
| closeTrigger | unknown | — | Change this value to force-close the dropdown |
DateInput
Native date (or datetime) picker wheel.
const [date, setDate] = useState(new Date());
<DateInput
value={date}
onChange={setDate}
mode="date"
minimumDate={new Date(1900, 0, 1)}
theme="dark"
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | Date | — | Required. Selected date |
| onChange | (date: Date) => void | — | Required. Change handler |
| mode | 'date' \| 'time' \| 'datetime' | 'date' | Picker mode |
| minimumDate | Date | — | Earliest selectable date |
| maximumDate | Date | — | Latest selectable date |
| theme | 'light' \| 'dark' \| 'auto' | 'dark' | Picker theme |
| style | StyleProp<ViewStyle> | — | Wrapper style |
| pickerStyle | StyleProp<ViewStyle> | — | Picker style |
Peer dependency: react-native-date-picker
TimeInput
Native time picker wheel.
const [time, setTime] = useState(new Date());
<TimeInput value={time} onChange={setTime} theme="dark" />Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | Date | — | Required. Selected time |
| onChange | (date: Date) => void | — | Required. Change handler |
| theme | 'light' \| 'dark' \| 'auto' | 'dark' | Picker theme |
| style | StyleProp<ViewStyle> | — | Wrapper style |
| pickerStyle | StyleProp<ViewStyle> | — | Picker style |
Peer dependency: react-native-date-picker
OptionMenu
Popup menu triggered by any custom element. Requires AppProviders at the app root.
<OptionMenu
triggerComponent={<Button title="Menu" onPress={() => {}} />}
options={[
{ label: 'Profile', value: 'profile' },
{ label: 'Settings', value: 'settings' },
]}
onSelect={value => console.log(value)}
menuWidth="50%"
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| options | SelectOption[] | — | Required. Menu items |
| triggerComponent | ReactNode | — | Required. Element that opens the menu |
| onSelect | (value: string) => void | — | Required. Selection handler |
| customMenuComponent | (option: SelectOption) => ReactNode | — | Custom render for each option |
| style | StyleProp<ViewStyle> | — | Menu wrapper style |
| menuWidth | number \| \${number}%`|'40%'| Dropdown width |
|menuOptionsContainerStyle|StyleProp| — | Options container style |
|menuOptionTextStyle|StyleProp| — | Option text style |
|customStyles|{ optionsContainer?: StyleProp }` | — | Extra style overrides |
Peer dependency: react-native-popup-menu + AppProviders
Button
Primary, outline, and ghost button with loading and icon support.
<Button
title="Continue"
onPress={() => {}}
variant="primary"
size="md"
loading={false}
fullWidth
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| title | string | — | Required. Button label |
| onPress | () => void | — | Required. Press handler |
| variant | ButtonVariant | 'primary' | 'primary', 'outline', or 'ghost' |
| size | ButtonSize | 'md' | 'sm', 'md', or 'lg' |
| disabled | boolean | false | Disable button |
| loading | boolean | false | Show loading spinner |
| fullWidth | boolean | true | Stretch to container width |
| style | StyleProp<ViewStyle> | — | Container style |
| textStyle | StyleProp<TextStyle> | — | Label style |
| icon | ReactNode | — | Optional icon |
| iconPosition | 'left' \| 'right' | 'left' | Icon placement |
SocialSigninButton
Styled button for Google / Apple / social sign-in flows.
<SocialSigninButton
title="Continue with Google"
onPress={() => {}}
icon={<YourGoogleIcon />}
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| title | string | — | Required. Button label |
| onPress | () => void | — | Required. Press handler |
| style | StyleProp<ViewStyle> | — | Container style |
| textStyle | StyleProp<TextStyle> | — | Label style |
| disabled | boolean | false | Disable button |
| icon | ReactNode \| null | null | Left icon |
Loader
Animated loading indicators with optional title.
<Loader title="Loading..." loaderType={LoaderType.TRIPLE_DOT} />LoaderType values
| Value | Animation |
|-------|-----------|
| LoaderType.TRIPLE_DOT | Three bouncing dots |
| LoaderType.WAVE | Wave bars |
| LoaderType.LINE | Sliding line |
| LoaderType.CIRCLE | Pulsing circle |
| LoaderType.RECTANGLE | Rectangle pulse |
| LoaderType.SPINNER | Spinner |
| LoaderType.PULSE | Pulse scale |
| LoaderType.BOUNCE | Bounce |
| LoaderType.ROTATE | Rotate |
| LoaderType.SPIN | Continuous spin |
| LoaderType.JUMP | Jump animation |
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| title | string | — | Optional text below loader |
| loaderType | LoaderType | LoaderType.TRIPLE_DOT | Animation style |
| textStyle | StyleProp<TextStyle> | — | Title text style |
| loaderStyle | StyleProp<ViewStyle> | — | Loader container style |
Theme
import { colors, fonts, defaults } from 'basicrequirement';colors
| Key | Value | Usage |
|-----|-------|-------|
| primary | #CC9E49 | Brand / accent |
| text | #FFFFFF | Light text |
| textDark | #000000 | Dark text |
| placeholder | #737373 | Placeholder text |
| error | #CD0D0D | Error messages |
| inputBackground | #A8A8A81A | Input background |
| border | #CC9E49 | Borders |
| menuBackground | #525252 | Menu background |
| buttonBackground | rgba(168,168,168,0.1) | Button background |
| loader | #CC9E49 | Loader color |
fonts
| Key | Value |
|-----|-------|
| regular | Inter-Regular |
| medium | Inter-Medium |
| semiBold | Inter-SemiBold |
defaults
| Key | Value |
|-----|-------|
| countryCode | 'IN' |
| callingCode | '91' |
| inputPlaceholder | 'Enter value' |
| phonePlaceholder | 'Enter your phone number' |
| emailOrPhonePlaceholder | 'Enter email or phone number' |
| passwordPlaceholder | 'Enter your password' |
Component → dependency map
| Component | Required | Optional peer |
|-----------|----------|---------------|
| InputField | react-native-svg | — |
| PasswordInput | react-native-svg | — |
| OtpInput | react-native-svg | — |
| CheckInput | react-native-svg | — |
| RadioSection | react-native-svg | — |
| DropdownInput | react-native-svg | — |
| Button | react-native-svg | — |
| Loader | react-native-svg | — |
| SocialSigninButton | react-native-svg | — |
| InputPhone | react-native-svg | react-native-country-picker-modal |
| InputEmailorPhone | react-native-svg | react-native-country-picker-modal |
| CountryCodePicker | react-native-svg | react-native-country-picker-modal |
| DateInput | react-native-svg | react-native-date-picker |
| TimeInput | react-native-svg | react-native-date-picker |
| OptionMenu | react-native-svg | react-native-popup-menu + AppProviders |
Development (this repo)
This repository doubles as a demo app and the library source.
npm install
npm run ios # or npm run android
npm run build # generate TypeScript declarations in lib/typescript/
npm run typecheckPublishing
- Update
name,version,repository, andauthorinpackage.json. - Build declarations:
npm run build - Dry-run the tarball:
npm pack --dry-run - Publish:
npm publish --access public
The package ships source (src/) so Metro in consumer apps compiles TypeScript. Type declarations are pre-built to lib/typescript/.
License
MIT
