Input
A single-line text field for logins, search bars, and checkout forms — with the neobrutalist thick-border and hard-shadow treatment.
import {
Field,
FieldDescription,The input captures a single line of text — names, emails, search queries. Built on the Base UI Input component, a thin wrapper over the native <input>, and dressed in the neobrutalist recipe: thick border, hard shadow, and a high-contrast focus outline.
Reach for it when:
- Auth and signup forms — email, username, and password fields paired with
FieldandFieldLabel. - Search bars — inline with a
Button, or with icons viaInputGroup. - Checkout and settings pages — addresses, card numbers, and profile fields laid out in a
FieldGroup.
Installation#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/input.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/input.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/input.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/input.json
Install the following dependencies:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
Copy and paste the following code into your project.
import * as React from "react"
import { cn } from "@/lib/utils"
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
<input
type={type}
data-slot="input"
className={cn(
"h-8 w-full min-w-0 rounded border-2 bg-input px-3 py-2 text-sm shadow-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive",
className
)}
{...props}
/>
)
}
export { Input }
Update the import paths to match your project setup.
Usage#
import { Input } from "@/components/ui/input"<Input />Examples#
Basic#
import { Input } from "@/components/ui/input"
export function InputBasic() {Field#
Use Field, FieldLabel, and FieldDescription to create an input with a
label and description.
import {
Field,
FieldDescription,Field Group#
Use FieldGroup to show multiple Field blocks and to build forms.
import { Button } from "@/components/ui/button"
import {
Field,Disabled#
Use the disabled prop to disable the input. To style the disabled state, add the data-disabled attribute to the Field component.
import {
Field,
FieldDescription,Invalid#
Use the aria-invalid prop to mark the input as invalid. To style the invalid state, add the data-invalid attribute to the Field component.
import {
Field,
FieldDescription,File#
Use the type="file" prop to create a file input.
import {
Field,
FieldDescription,Inline#
Use Field with orientation="horizontal" to create an inline input.
Pair with Button to create a search input with a button.
import { Button } from "@/components/ui/button"
import { Field } from "@/components/ui/field"
import { Input } from "@/components/ui/input"Grid#
Use a grid layout to place multiple inputs side by side.
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
Required#
Use the required attribute to indicate required inputs.
import {
Field,
FieldDescription,Badge#
Use Badge in the label to highlight a recommended field.
import { Badge } from "@/components/ui/badge"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"Input Group#
To add icons, text, or buttons inside an input, use the InputGroup component. See the Input Group component for more examples.
import { InfoIcon } from "lucide-react"
import { Field, FieldLabel } from "@/components/ui/field"Button Group#
To add buttons to an input, use the ButtonGroup component. See the Button Group component for more examples.
import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
import { Field, FieldLabel } from "@/components/ui/field"Form#
A full form example with multiple inputs, a select, and a button.
import { Button } from "@/components/ui/button"
import {
Field,RTL#
To enable RTL support in Neobrutalism.com, see the RTL configuration guide.
"use client"
import * as React from "react"Accessibility#
Input renders a native <input>, so keyboard editing, focus, and form submission need no ARIA wiring. What's left is on you:
- Label every input. Pair it with
FieldLabel(or a<label htmlFor>) — aplaceholderis not a label; it disappears on type and isn't reliably announced. - Associate error text. Set
aria-invalidon the input and pointaria-describedbyat the id of yourFieldErrororFieldDescriptionso screen readers read the message with the field. - Pick the right
typeandautocomplete.type="email"plusautocomplete="email"gets the correct mobile keyboard and autofill.