Input

A tokened text input with error/warning/success field status (border + icon + message) layered over the base control, never a bespoke variant.

Colors

Sizes

Real form · Field + validation

We'll send a magic link to sign in.

Using Input

Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.

Plain HTML — CSS classes

The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path is complete for Input — it needs no JavaScript, so the classes below are the whole story.

/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";

Root class input, with 15 modifiers:

  • .input
  • .input-accent
  • .input-affix-end
  • .input-affix-start
  • .input-error
  • .input-info
  • .input-lg
  • .input-md
  • .input-neutral
  • .input-primary
  • .input-secondary
  • .input-sm
  • .input-success
  • .input-warning
  • .input-xl
  • .input-xs

React

Typed components over those same classes, with behavior and accessibility from Base UI.

npm i @wizeworks/silicaui-react
import { Input } from "@wizeworks/silicaui-react";

Props

PropTypeRequiredDescription
colorInputColornoAccent color; maps to input-<color> (border + focus ring).
sizeInputSizenoDefault md. Matches same-size Button heights.

Source of the demo above

The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.

Show source
import { useState } from "react";
import {
    Input,
    Field,
    FieldLabel,
    FieldControl,
    FieldDescription,
    FieldError,
    FloatingLabel,
    Button,
} from "@wizeworks/silicaui-react";
import { Section, Row, Stack } from "../lib/Section";
import { SIZES } from "../lib/data";

export function InputDemo() {
    const [email, setEmail] = useState("not-an-email");
    const invalid = email.length > 0 && !email.includes("@");

    return (
        <>
            <Section title="Colors">
                <Stack className="max-w-md">
                    <Input placeholder="Default (focus for primary ring)" />
                    <Input color="primary" placeholder="Primary" />
                    <Input color="success" placeholder="Success" />
                    <Input color="error" placeholder="Error" defaultValue="not-an-email" />
                    <Input color="brand" placeholder="SilicaUI" />
                    <Input disabled placeholder="Disabled" />
                </Stack>
            </Section>

            <Section title="Sizes">
                <Stack className="max-w-md">
                    {SIZES.map((size) => (
                        <Input key={size} size={size} placeholder={size} />
                    ))}
                </Stack>
            </Section>

            <Section title="Real form · Field + validation">
                <div className="max-w-sm rounded-box border border-base-300 bg-base-100 p-5 shadow-sm">
                    <div className="flex flex-col gap-4">
                        <Field
                            validationMode="onChange"
                            validate={() => (invalid ? "Enter a valid email address" : null)}
                        >
                            <FieldLabel>Work email</FieldLabel>
                            <FieldControl
                                type="email"
                                value={email}
                                onChange={(e) => setEmail(e.target.value)}
                                placeholder="you@company.com"
                            />
                            <FieldDescription>
                                We'll send a magic link to sign in.
                            </FieldDescription>
                            <FieldError />
                        </Field>
                        <FloatingLabel label="Company name">
                            <Input />
                        </FloatingLabel>
                        <Row>
                            <Button color="primary" block>
                                Continue
                            </Button>
                        </Row>
                    </div>
                </div>
            </Section>
        </>
    );
}

Vanilla — node tree to HTML

Each lowers to a native form element, so the browser's built-in behavior + accessibility come for free and the Phase 2 form contract wires the same tags. Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.

npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviors
import { atom, toHtml } from "@wizeworks/silicaui-html";

const node = atom("Input", "input", { /* props */ });
const markup = toHtml(node);

Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "input input-primary" rather than passing a colour as a prop.

Takes children
no
Hydrated by
nothing — this one is static markup

The full API for Input, on every path, is available through the Silica MCP server.