suiss/uim · React Native Component

Field

Building blocks for form fields: labels, descriptions, errors, validation and grouped layouts.

Field 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
Field on iOS in light mode

Field wraps one control, such as an Input, Textarea or Switch, with a FieldLabel, an optional FieldDescription and a FieldError. It shares the field's disabled and invalid state with the control and handles validation: required values, length limits and custom validate functions, checked on submit, blur or change.

FieldSet and FieldLegend group related fields under a heading, and FieldGroup stacks fields. The inset variant of FieldGroup turns the fields into rows on a rounded secondary surface with hairlines between them, like a settings list.

Installation

$ pnpm dlx @esuiss/uim@latest add field

The CLI also adds what it builds on: Separator.

Manual

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

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

uniwind/components/ui/field.tsx
import { cn } from "cn"
import * as React from "react"
import { Text as RNText, View } from "react-native"
import * as FieldPrimitive from "@/components/primitives/field"
import * as FieldsetPrimitive from "@/components/primitives/fieldset"
import { resolveClassName } from "@/components/primitives/use-render"
import { Separator } from "@/components/ui/separator"

type FieldGroupVariant = "default" | "inset"

type FieldOrientation = "vertical" | "horizontal" | "responsive"

interface FieldGroupItemContextValue {
  variant: FieldGroupVariant
  index: number
}
  1. Update the import paths to match your project.

Usage

import { FieldSet, FieldLegend, FieldGroup, Field, FieldContent, FieldLabel, FieldTitle, FieldDescription, FieldSeparator, FieldError } from "@/components/ui/field"
<Field>
  <FieldLabel>Username</FieldLabel>
  <Input placeholder="evilrabbit" autoCapitalize="none" />
  <FieldDescription>
    Choose a unique username for your account.
  </FieldDescription>
</Field>

Put a FieldLabel, the control and a FieldError inside Field. The control is labelled by the label and uses the description and error text as its accessibility hint. Set invalid to force the error state, or let validation decide it.

FieldError shows its children, or the messages from errors (for example from a form library), and can be limited to one failure with match, such as tooShort. Use orientation="horizontal" for a label beside a switch or checkbox, with FieldContent holding a FieldTitle and FieldDescription.

FieldSeparator divides fields and can show short text such as "or" in the middle.

Examples

Invalid

A field in the invalid state with an error message.

iOS
Field (invalid) on iOS in light mode

Validation

Required, custom and minimum-length validation on blur and on change.

iOS
Field (validation) on iOS in light mode

Disabled

A disabled field.

iOS
Field (disabled) on iOS in light mode

Horizontal

Switch rows with a title and description beside the control.

iOS
Field (horizontal) on iOS in light mode

Checkbox group

A fieldset of checkboxes with a legend.

iOS
Field (checkbox group) on iOS in light mode

Inset

An inset group of rows on a rounded surface.

iOS
Field (inset) on iOS in light mode

Form

A complete form with validation and a submit button.

iOS
Field (form) on iOS in light mode

API Reference

FieldSet

Group of related fields.

ExtendsReact.ComponentProps<typeof FieldsetPrimitive.Root>

FieldLegend

Heading for a fieldset.

ExtendsReact.ComponentProps<typeof FieldsetPrimitive.Legend>
PropType
About
legend (heading) or label.
Type
"legend""label"
Default
"legend"

FieldGroup

Stack of fields, plain or inset.

ExtendsReact.ComponentProps<typeof View>
PropType
About
default or inset.
Type
FieldGroupVariant
Default
"default"

Field

One field that shares state with its control.

ExtendsReact.ComponentProps<typeof FieldPrimitive.Root>
PropType
About
vertical, horizontal or responsive.
Type
FieldOrientation
Default
"vertical"

FieldContent

Column for a title and description beside a control.

ExtendsReact.ComponentProps<typeof View>

FieldLabel

Label linked to the control.

ExtendsReact.ComponentProps<typeof FieldPrimitive.Label>

FieldTitle

Bold text for a field's title.

ExtendsReact.ComponentProps<typeof RNText>

FieldDescription

Helper text.

ExtendsReact.ComponentProps<typeof FieldPrimitive.Description>

FieldSeparator

Divider with optional centered text.

ExtendsReact.ComponentProps<typeof View>
PropType
Type
React.ReactNode
Default
—

FieldError

Error message shown when validation fails.

ExtendsReact.ComponentProps<typeof FieldPrimitive.Error>
PropType
About
Array of { message } objects to show.
Type
Array<{ message?: string } | undefined>
Default
—

Accessibility

  • The control is labelled by FieldLabel and gets the description and error text as its accessibility hint.
  • FieldError has the alert role, so screen readers announce it when it appears.
  • FieldSet has the group role labelled by its legend; the legend has the header role.
  • Disabled state is passed to the label and control.

Notes

  • Uses text-label, text-label-secondary, text-danger and bg-surface-secondary tokens; light and dark follow the system appearance.
  • Inset separators use start and end offsets, so they flip in right-to-left layouts.