NativeUI Primitives

Input

Cross-platform text input primitive that wraps React Native's TextInput. Compatible with React Hook Form and native forms. Use asChild to compose with file pickers, selects, or any custom input component.


Installation

npm install @native-ui-org/primitives
pnpm add @native-ui-org/primitives
yarn add @native-ui-org/primitives
bun add @native-ui-org/primitives

Overview

Input is a cross-platform text input primitive that provides a consistent API for text inputs across iOS, Android, and Web. It's designed to be the foundation for building any type of text-based form field.

FeatureDescriptionPlatforms
Text InputStandard text input with all TextInput propsiOS, Android, Web
File PickerUse asChild with file input or image pickeriOS, Android, Web
SelectUse asChild to create custom dropdown/selectiOS, Android, Web
FormsCompatible with React Hook Form and native formsiOS, Android, Web
asChildPolymorphic rendering for any componentiOS, Android, Web
AccessibilityProper ARIA attributes and rolesWeb

Setup & Usage Guide

Input works out of the box with no configuration. It's a drop-in replacement for React Native's TextInput with enhanced form compatibility.

1. Install and Import

Install from npm:

npm install @native-ui-org/primitives

Then import from the package:

import { Input } from "@native-ui-org/primitives";

2. Basic Usage

Use Input just like React Native's TextInput:

import { Input } from "@native-ui-org/primitives";
import { useState } from "react";

function MyForm() {
  const [value, setValue] = useState("");
  
  return (
    <Input 
      placeholder="Enter your name"
      value={value}
      onChangeText={setValue}
    />
  );
}

3. React Hook Form Integration

Input works seamlessly with React Hook Form:

import { useForm, Controller } from "react-hook-form";
import { Input } from "@native-ui-org/primitives";

function MyForm() {
  const { control, handleSubmit } = useForm();
  
  return (
    <Controller
      control={control}
      name="email"
      render={({ field: { onChange, value } }) => (
        <Input
          placeholder="Email"
          value={value}
          onChangeText={onChange}
          keyboardType="email-address"
        />
      )}
    />
  );
}

4. Different Input Types

Input supports all TextInput types:

// Email input
<Input 
  keyboardType="email-address"
  autoCapitalize="none"
  placeholder="Email"
/>

// Password input
<Input 
  secureTextEntry
  placeholder="Password"
/>

// Multiline input
<Input 
  multiline
  numberOfLines={4}
  placeholder="Message"
/>

// Numeric input
<Input 
  keyboardType="numeric"
  placeholder="Phone number"
/>

5. File/Image Picker

Use asChild to create file or image pickers:

// Web: Use native file input
<Input asChild>
  <input 
    type="file" 
    accept="image/*"
    onChange={(e) => {
      const file = e.target.files?.[0];
      // Handle file selection
    }}
  />
</Input>

// Native: Use with image picker library
<Input asChild>
  <Button onPress={openImagePicker}>
    <Text>Select Image</Text>
  </Button>
</Input>

6. Custom Select/Dropdown

Use asChild to create custom select components:

<Input asChild>
  <View>
    <Button onPress={toggleDropdown}>
      <Text>{selectedValue || "Select..."}</Text>
    </Button>
    {isOpen && (
      <View>
        {options.map(option => (
          <Button key={option} onPress={() => select(option)}>
            <Text>{option}</Text>
          </Button>
        ))}
      </View>
    )}
  </View>
</Input>

7. Polymorphic Components

Use asChild for any custom input component:

<Input asChild onChangeText={handleChange}>
  <CustomTextInput placeholder="Custom input" />
</Input>

API Reference

Input

The base text input component for all platforms.

PropTypeDefaultDescription
asChildbooleanfalseRender child element without Input wrapper
valuestringControlled value
defaultValuestringUncontrolled default value
onChangeText(text: string) => voidCallback when text changes
placeholderstringPlaceholder text
multilinebooleanfalseEnable multiline input
secureTextEntrybooleanfalseHide text (for passwords)
keyboardTypeKeyboardTypeOptionsKeyboard type (email, numeric, etc.)
editablebooleantrueWhether the field is editable
...propsTextInputPropsAll React Native TextInput props

Platform Behavior

PlatformImplementationCharacteristics
iOS / AndroidStandard React Native TextInputNative keyboard and input handling
WebRenders as <input> or <textarea>Proper form integration
All PlatformsConsistent APISame props, same behavior

Accessibility

Web:

  • Proper ARIA attributes (role="textbox")
  • Form label association
  • Keyboard navigation support

Mobile:

  • Standard React Native accessibility props
  • Works with VoiceOver and TalkBack

Version History

VersionNotes
0.9.0Initial release — cross-platform Input with form compatibility and asChild polymorphism.

Summary: Input is the foundation for all text-based form inputs in cross-platform apps. Use it everywhere you'd use React Native's TextInput, with the added benefit of better form library compatibility.