suiss/uim · React Native Component

Input

A single-line text field with focus, invalid and disabled states, in three heights.

Input is an open-source mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Input on iOS in light mode

Input wraps a TextInput through the field control primitive. It tracks its own focused, filled, invalid and disabled state and styles itself from that state: a focus border while editing, a danger border and tint when invalid, and muted colors when disabled.

It comes in three sizes: default (44 pt), md and sm. Use the default size for forms on a full screen, and the smaller sizes inside dense layouts such as toolbars or sheets.

Installation

$ pnpm dlx @esuiss/uim@latest add input

Manual

  1. Install the dependencies:
npx expo install cn
  1. Add the pieces it builds on: the primitives components/primitives/input.tsx, components/primitives/use-render.tsx.

  2. Copy the source into components/ui/input.tsx:

uniwind/components/ui/input.tsx
import { cn } from "cn"
import * as InputPrimitive from "@/components/primitives/input"
import { resolveClassName } from "@/components/primitives/use-render"

type InputSize = "sm" | "md" | "default"

function Input({
  className,
  size = "default",
  ...props
}: React.ComponentProps<typeof InputPrimitive.Root> & {
  size?: InputSize
}) {
  return (
    <InputPrimitive.Root
      className={(state) =>
  1. Update the import paths to match your project.

Usage

import { Input } from "@/components/ui/input"
<Input placeholder="Email" />

Pass any TextInput prop, such as placeholder, secureTextEntry, keyboardType or inputMode, to get the matching field type.

The value works controlled with value and onValueChange(value, details), or uncontrolled with defaultValue. Inside a Field, the input picks up the field's label, description, invalid and disabled state, so you usually set invalid on the Field instead of on the input.

className can be a function that receives the state (focused, invalid, disabled, filled, …) and returns classes.

Examples

Types

Text, email, password, number and search fields set through standard TextInput props.

iOS
Input (types) on iOS in light mode

Sizes

The sm, md and default sizes.

iOS
Input (sizes) on iOS in light mode

With value

An input that starts with a defaultValue.

iOS
Input (with value) on iOS in light mode

With label

An input inside a Field with a label and description.

iOS
Input (with label) on iOS in light mode

Invalid

An input inside an invalid Field with an error message.

iOS
Input (invalid) on iOS in light mode

Controlled

A controlled input that mirrors its value below.

iOS
Input (controlled) on iOS in light mode

Disabled

A disabled input.

iOS
Input (disabled) on iOS in light mode

API Reference

Input

ExtendsReact.ComponentProps<typeof InputPrimitive.Root>
PropType
About
Height and text size: default, md or sm.
Type
InputSize
Default
"default"

Accessibility

  • Inside a Field, the input is linked to the field label through accessibilityLabelledBy and gets the label as accessibilityLabel and the description as accessibilityHint.
  • disabled is set in accessibilityState and makes the input non-editable.
  • Outside a Field, give the input an accessibilityLabel; a placeholder alone is not a label.

Notes

  • Uses the bg-control, border-focus, border-danger and bg-control-disabled tokens.
  • Placeholder, cursor and selection colors come from the label-secondary and accent tokens.
  • Light and dark colors follow the system appearance.