npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

basicrequirement

v1.1.2

Published

Reusable React Native UI components — inputs, buttons, loaders, and theme for astrology/login apps

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-svg

Install 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-menu

Quick 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 TextInputProps also accept standard TextInput props (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 typecheck

Publishing

  1. Update name, version, repository, and author in package.json.
  2. Build declarations: npm run build
  3. Dry-run the tarball: npm pack --dry-run
  4. 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