crispmeasured from Attio

Input

A single-line text input with an inset border, a brand focus ring, and a danger ring for the invalid state.

Measured from Attio — heights 32/36px, radii r9/r10, inset-only focus ring.

Preview

Installation

bun add crisp
import "crisp/styles.css";
import { Input } from "crisp";

Usage

import { Input } from "crisp";

export function Example() {
  return <Input placeholder="Search tasks…" />;
}

Props

PropTypeDefaultDescription
size"medium" | "large""medium"Sets height, padding, and border radius — 32/r9 or 36/r10.
invalidbooleanfalseSwaps the ring to the danger color and sets aria-invalid.
...propsComponentPropsWithoutRef<"input"> (excl. native size)All native input attributes: value, onChange, placeholder, disabled, type, etc.

Examples

Sizes

32px (medium) and 36px (large).

<Input size="medium" placeholder="Medium" />
<Input size="large" placeholder="Large" />

Invalid state

invalid swaps the ring to the danger color and sets aria-invalid="true".

Enter a valid email address.

<Input invalid defaultValue="not-an-email" aria-describedby="email-error" />
<p id="email-error">Enter a valid email address.</p>

Disabled

Native disabled — 50% opacity, not focusable.

<Input disabled placeholder="Disabled" />

With label

Always pair an input with a visible <label>.

<label htmlFor="task-name">Task name</label>
<Input id="task-name" placeholder="e.g. Follow up with Acme" />

Accessibility

Always pair an Input with a <label> — via htmlFor/id, or aria-label/aria-labelledby for icon-only fields like search boxes. Setting invalid adds aria-invalid="true"; pair it with aria-describedby pointing at the error message so screen readers announce why the field failed. Disabled inputs are removed from the tab order automatically — this is native browser behavior, not something crisp adds.

KeyAction
Tab / Shift+TabMoves focus in and out of the field.
Standard text-editing keysNative input editing behavior applies.

On this page