1
ComponentsForm Controls

Input

Input is the standard control for short free-text values, search fields, and compact form data.

Purpose

Input is the standard control for short free-text values, search fields, and compact form data.

Text input states

import { Input } from "@/components/ui/input";

export function Example() {
  return <Input aria-label="Workspace name" placeholder="Workspace name" />;
}

Installation

With the Siteplane registry alias configured, add the component and import the installed source from your app.

CLI

pnpm dlx shadcn@4.16.1 add @siteplane/input

Import

import { Input } from "@/components/ui/input";

Need the machine-readable source metadata? View registry JSON.

Usage

Use Input for single-line text entry. Put it inside Field when it needs a visible label. Two functional special cases without a visual example: size also accepts a number for the native character-width attribute, and type="hidden" renders a bare input without the control shell.

import { Input } from "@/components/ui/input";

export function Example() {
  return <Input aria-label="Workspace name" placeholder="Workspace name" />;
}

Examples

Sizes, states, native input types, the soft variant and Field composition are props and compositions of the same primitive.

Sizes

<Input aria-label="Small input" placeholder="Small" size="sm" />
<Input aria-label="Default input" placeholder="Default" />
<Input aria-label="Large input" placeholder="Large" size="lg" />
<Input aria-label="Extra large input" placeholder="Extra large" size="xl" />

Disabled and invalid states

{/* Disabled */}
<Input aria-label="Workspace" defaultValue="Plane workspace" disabled />

{/* Invalid */}
<Input aria-invalid aria-label="Slug" defaultValue="invalid slug!" />

Search and email types

<Input aria-label="Email" placeholder="team@ui.siteplane.io" type="email" />
<Input aria-label="Search" placeholder="Search clients" type="search" />

File input

No file chosen

function FileUpload() {
  const [fileName, setFileName] = useState("No file chosen");

  return (
    <div className="grid gap-2">
      <Input
        aria-label="Upload logo"
        nativeInput
        onChange={(event) => {
          setFileName(event.currentTarget.files?.[0]?.name ?? "No file chosen");
        }}
        type="file"
      />
      <p className="text-muted-foreground text-xs">{fileName}</p>
    </div>
  );
}

Soft variant

<Input
  aria-label="Search teams or members"
  placeholder="Search teams or members..."
  type="search"
  variant="soft"
/>

With Field

Invoices and receipts go to this address.

Not submitted
<Form onSubmit={onSubmit}>
  <Field name="email">
    <FieldLabel>Billing email</FieldLabel>
    <Input name="email" placeholder="team@ui.siteplane.io" required type="email" />
    <FieldDescription>Invoices and receipts go to this address.</FieldDescription>
    <FieldError>Please enter a valid email.</FieldError>
  </Field>
  <Button type="submit">Submit</Button>
</Form>

With input group

Icons, hints and shortcuts compose around the input. See the Input Group docs for the full API.

.ui.siteplane.io
/
{/* Leading icon */}
<InputGroup>
  <InputGroupAddon>
    <SearchIcon />
  </InputGroupAddon>
  <InputGroupInput aria-label="Search projects" placeholder="Search projects" />
</InputGroup>

{/* Trailing hint */}
<InputGroup>
  <InputGroupInput aria-label="Subdomain" placeholder="acme" />
  <InputGroupAddon align="inline-end">
    <InputGroupText>.ui.siteplane.io</InputGroupText>
  </InputGroupAddon>
</InputGroup>

{/* Keyboard shortcut */}
<InputGroup>
  <InputGroupAddon>
    <SearchIcon />
  </InputGroupAddon>
  <InputGroupInput aria-label="Command search" placeholder="Jump to" />
  <InputGroupAddon align="inline-end">
    <Kbd>/</Kbd>
  </InputGroupAddon>
</InputGroup>

With button

<Group aria-label="Email subscription" className="w-full gap-2">
  <Input
    aria-label="Email"
    className="min-w-0 flex-1"
    placeholder="you@example.com"
    type="email"
  />
  <div className="shrink-0">
    <Button variant="outline">Send</Button>
  </div>
</Group>

Unstyled

unstyled drops the form control shell so a custom surface can provide its own.

{/* Default keeps the form control shell. */}
<Input aria-label="Default input" placeholder="Default form control" />

{/* unstyled drops the shell so a custom surface provides its own. */}
<div className="rounded-lg border border-border border-dashed">
  <Input
    aria-label="Unstyled input"
    className="flex w-full"
    placeholder="Unstyled inside a custom shell"
    unstyled
  />
</div>

API Reference

The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.

  • Use native input props for value, type, autocomplete, required, disabled, and form participation.
  • variant="soft" provides the borderless search and filter surface.
  • Visual size accepts Siteplane control sizes and otherwise inherits SiteplaneUIProvider controlSize; the numeric native HTML size attribute remains a width hint.
  • size="xl" uses the customer-facing single-line field format: 56px outer height, 16px/24px input text and 16px horizontal inset including the border. Pair it with a surrounding SiteplaneUIProvider radius="sm" for the global 8px main corner; size itself never overrides radius.
  • Use Input Group for tightly connected icons, units, shortcuts, or actions.

Motion

Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.

  • Input does not translate or scale.
  • Focus remains visible through the native border, surface, ring, and shadow contract.
  • Disabled and invalid state do not change dimensions.

Accessibility

  • Use a visible label in product forms; placeholder text is supporting context, not a label.
  • Connect invalid state to the Input and render a visible FieldError.
  • Keep browser autocomplete and input type appropriate to the value.
  • File inputs remain the Input primitive with the native file input behavior.

Implementation Guidance

  • Use Input for free text and Select for a closed option set.
  • Do not use placeholder-only labels.
  • Preserve native focus, disabled, invalid, and form semantics.

On This Page