Input
Primitive

Input

Native single-line input primitive with controlled value state, Field wiring, and an optional clear control.

Live behavior

Input in motion

Interactive
Atom behavior · App-owned appearance
Clear remains synchronized with the native input.

Interact with the specimen and inspect the behavior Atom contributes.

waiting for input

When to Use

Use Input for one line of text such as a name, email, or search query. Use Textarea for multi-line text and NumberInput when numeric stepping and numeric keyboard behavior are required. Wrap Input in Field when it needs a generated label, description, error, or shared validation state.

Features

The behavior Atom owns before your product adds appearance.

  • Supports controlled and uncontrolled string values.
  • Preserves native input types, attributes, and event handlers.
  • Inherits IDs, descriptions, and state from Field unless locally overridden.
  • Exposes filled, focused, disabled, required, read-only, and invalid state.
  • Includes a Clear control that clears and refocuses Root.
  • Exposes state and actions through useInputContext.

Import

tsx
import { Input } from "@flowstack-ui/atom";

Anatomy

tsx
<Input.Root>
  <Input.Clear />
</Input.Root>

useInputContext()

API Reference

Root

Renders a native input followed by its compound children, without adding a wrapper element. Local state props override Field context.

PropTypeDefault
valuestring-
defaultValuestring""
onValueChange(value: string) => void-
disabledbooleanField state or false
requiredbooleanField state or false
readOnlybooleanField state or false
invalidbooleanField state or false
validationBehavior"inline" | "native"Field/Form value or "native"

Native input props, including type, name, form, onChange, and explicit ARIA relationships, pass through. Uncontrolled values return to defaultValue on native form reset.

ARIA attributeValues
aria-describedbyExplicit value or mounted Field Description/Error IDs
aria-invalid"true" when invalid
aria-readonly"true" when read only
aria-required"true" when required
Data attributeValues
[data-slot]"input"
[data-filled]Present when value is not empty
[data-focused]Present while focused
[data-disabled]Present when disabled
[data-required]Present when required
[data-readonly]Present when read only
[data-invalid]Present when invalid

Clear

Renders a button that clears Root, calls onClear, and restores focus. It is always removed from sequential tab order and becomes hidden and disabled when Root is empty, disabled, or read-only.

PropTypeDefault
onClear() => void-
childrenReactNode-
asChildbooleanfalse
renderRenderProp-
ARIA attributeValues
aria-labelConsumer value or "Clear input"
aria-hidden"true" while unavailable
Data attributeValues
[data-slot]"input-clear"
[data-disabled]Present when Root is disabled or read-only
[data-hidden]Present while unavailable

useInputContext

Returns the current value, state, input ref, setValue, and clearValue for advanced custom parts. It must be used below Root.

Examples

Field-Wired Email

tsx
import { Field, Input } from "@flowstack-ui/atom";

export function EmailField() {
  return (
    <Field.Root id="email" required>
      <Field.Label>Email</Field.Label>
      <Input.Root name="email" type="email" />
      <Field.Description>Use a work email address.</Field.Description>
    </Field.Root>
  );
}
tsx
import { useState } from "react";
import { Input } from "@flowstack-ui/atom";

export function SearchInput() {
  const [query, setQuery] = useState("");

  return (
    <label>
      Search
      <Input.Root value={query} onValueChange={setQuery} type="search">
        <Input.Clear>Clear search</Input.Clear>
      </Input.Root>
    </label>
  );
}

Accessibility

After native constraint validation runs, Root mirrors ValidityState through aria-invalid and data-invalid. Inline behavior suppresses the browser bubble while preserving native submission blocking; native behavior keeps it.

Root uses native input semantics. Give it an accessible name with a native label, Field.Label, aria-label, or aria-labelledby. Clear has an accessible default label but is intentionally outside the Tab sequence; pointer users can activate it, while keyboard users can select and delete the input value with normal editing keys.

Changelog

0.6.16

  • Explicitly scrolled inline validation-directed focus into view.

0.6.15

  • Exposed inline validation-directed focus through [data-focus-visible] until blur.

0.6.13

  • Mirrored attempted native validity to Input, Field, and Form under the new inline/native validation presentation contract.

0.5.0

  • Synchronized uncontrolled Field-aware values with native form reset.

0.2.0

  • Added data-required to Input.Root when required state is inherited from Field context or provided directly.

0.1.0

  • Initial Atom release.