nori-ui

TextInput

Single-line text input with label, helper text, and validation states.

2.4 kBgzipped

At a glance

  • Single-line text field that forwards every native TextInput prop (value, onChangeText, placeholder, keyboardType, secureTextEntry, …) untouched.
  • Pair with Field for label, description, error wiring, and accessible id / aria-* attributes.
  • Compose with InputGroup when you need fixed prefix / suffix decorators (@username, https://, USD).

Preview

Direction:
Locale:

Use with Field

For labelled inputs with description, error, and a11y wiring, wrap in <Field>:

import { Field, TextInput } from '@nori-ui/core';
 
export const Example = () => (
    <Field label="Email" description="We won't share it.">
        <TextInput placeholder="you@example.com" />
    </Field>
);

With validation error:

import { Field, TextInput } from '@nori-ui/core';
 
export const Example = () => (
    <Field label="Email" error="That doesn't look like a valid email address.">
        <TextInput placeholder="you@example.com" />
    </Field>
);

See Field for the full API. For custom layouts (e.g., a control + button row), use the compound API.

disabled

Greys the field, blocks input, and forwards aria-disabled. The label keeps its color so the disabled control still reads as a labeled field.

import { Field, TextInput } from '@nori-ui/core';
 
export const Example = () => (
    <Field label="Email" disabled>
        <TextInput defaultValue="locked@example.com" />
    </Field>
);

leading and trailing

Inline visual decorations inside the field — typically icons or short labels. Unlike InputGroup addons, these don't get their own border; they sit flush in the same rounded box as the input.

import { Search, X } from 'lucide-react-native';
import { TextInput } from '@nori-ui/core';
 
export const Example = () => (
    <>
        <TextInput leading={<Search size={16} />} placeholder="Search…" />
        <TextInput trailing={<X size={16} />} value={value} onChangeText={setValue} />
    </>
);

For interactive trailing content (a clear button, a visibility toggle), wrap it in a Pressable — the slot accepts any React node.

containerClassName

Tailwind classes for the outer wrapper when used without <Field>, targeting the bordered field row. Use className on <Field> for grid sizing when wrapped.

import { TextInput } from '@nori-ui/core';
 
export const Example = () => (
    <TextInput containerClassName="w-full md:w-80" placeholder="Subject" />
);

Native preview

Props

PropTypeDefaultDescription
classNamestring
containerClassNamestringPass through a custom wrapper className
disabledboolean
leadingReactNode
namestring
trailingReactNode

On this page

Preview theme