Dashral Pro is on the wayGet 30% off at launch

Dashral

Input

Input with motion: a short shake when it turns invalid, and its error message grows in under the box and folds away when it's fixed.

$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-input.json

We'll never share your email.

Installation

$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-input.json

Adds components/dashral/motion/input.tsx, the Input it builds on (in components/dashral/), motion and the motion files every motion component shares. With the registry in your components.json:

$ pnpm dlx shadcn@latest add @dashral/motion-input

Usage

The same as Input, imported from components/dashral/motion/: swap the import and it moves.

example.tsx
import { Input } from "@/components/dashral/motion/input"

<Input label="Email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} error={errors.email} />

Examples

A sign-up form

Press Create with a bad email or a short password: that field shakes and its error grows in, and shakes again at each press until it's fixed. Fix it, and Creating… gives way to a welcome.

Create your account

Free for 14 days, no card needed.

8 characters or more.

Checking as you type

A moment after you stop typing, the spinner in the box pops over to a tick or a cross; taken shakes and suggests another, Claim pops a badge in.

acme.app/

Letters, numbers and dashes. Try maya.

Compared with Default

Default

The error message fades in under the box; the lines below jump down to make room.

Motion

The box gives a short shake as it turns invalid; the error grows in, the lines below gliding down, folds away when fixed, and a new one crosses over the old.

How the two editions differ in general, and which to use where: Motion.

API reference

Every prop of Input, and every attribute of the element it renders. The Motion edition adds no props of its own.

Input

Also takes every prop of <input>(opens in a new tab).

PropTypeDefault
labelReactNode

Shown above, linked to the control.

—
descriptionReactNode

A hint under the control.

—
errorboolean | ReactNode

true shows the error style; a message also shows under the control.

—
labelActionReactNode

At the end of the label's row, e.g. a “Forgot password?” link or the current value.

—
withAsteriskboolean

Marks the label with an asterisk, e.g. alongside required.

false
prefix / suffixReactNode

Inside the box, before or after the text: an icon, text, or a button.

—
unstyledboolean

Drops the border, background and focus ring.

false
revealableboolean

With type="password": a button at the end that shows and hides the password, after any suffix. false turns it off.

true
format"card" | "phone" | "date" | "expiry" | "time" | "number" | { type: "number", decimals } | { pattern }

Formats as you type and keeps the caret in place: card groups and brand, the locale's date order, thousands separators, or a pattern (# digit, A letter). Sets the keyboard and autofill hints. No library.

—
onValueChange(raw, { formatted, brand }) => void

With format: the raw value (digits, or "1234.5" for numbers), the text as shown, and a card's brand.

—
classNames{ root, label, wrapper, input, prefix, suffix, description, error }

Classes for each part.

—
classNamestring

Extra classes, merged with cn() so yours win.

—

Motion

  • When it turns invalid, or the error changes, the box shakes sideways a few pixels and settles (360ms), affixes and all; and again at every try to submit its form while it's still invalid, or when the browser's own check (required, type="email") finds it invalid.
  • The error message grows in under the box (--duration-standard), so the hint and anything below glide down instead of jumping; it folds away (--duration-fast) when the error clears.
  • A new message fades in rising 4px as the old one fades out, in the same space.
  • With reduced motion nothing shakes, and messages only appear and disappear.