Elements

Inputs

Single-line text fields with validation states.


Setup

Input styles are included in Manifest CSS or a standalone stylesheet, both referencing theme variables.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mnfst@latest/lib/manifest.min.css" />

Default


<input placeholder="Type here" />

Utilities

Inputs accept Manifest utility classes, which can be stacked in any combination.

Colors


<!-- Brand variant -->
<input class="brand" placeholder="Brand" />

<!-- Accent variant -->
<input class="accent" placeholder="Accent" />

<!-- Positive variant -->
<input class="positive" placeholder="Positive" />

<!-- Negative variant -->
<input class="negative" placeholder="Negative" />

Size


<!-- Small variant -->
<input class="sm" placeholder="Small" />

<!-- Large variant -->
<input class="lg" placeholder="Large" />

Appearance


<!-- No background until hover -->
<input class="ghost" placeholder="Ghost" />

<!-- Border included -->
<input class="outlined" placeholder="Outlined" />

<!-- No background at all -->
<input class="transparent" placeholder="Transparent" />

Variants

Inputs of type="search" work on their own, or can be placed in a label to facilitate a search icon.


<label role="button">
    <span x-icon="lucide:search"></span>
    <input type="search" placeholder="Search" aria-label="Search" />
</label>

See the local data plugin for wiring up search functionality.


Copy

Pair an input with a copy button by placing both in a label, and marking the button with command="--copy". No wiring is required; clicking the button copies the field's value and flashes a confirmation tooltip, just like copyable code blocks.


<label>
    <input value="MNFST-20" aria-label="Coupon code" />
    <button command="--copy" aria-label="Copy to clipboard"></button>
</label>

This works with any text-like input type (text, email, tel, number, url). The -- prefix is native HTML syntax for custom button commands and carries no default browser behaviour, so Manifest uses it as the styling and behaviour hook. Use commandfor with an input's id when the button sits outside the label.

Both tooltips are customizable. Set the button's value to replace the confirmation icon with text, or bind it for localized or dynamic phrasing. Add an x-tooltip to label the button on hover. The hover label steps aside for the confirmation flash, then returns on the next hover.


<label>
    <input type="email" value="hello@manifestx.dev" aria-label="Email" />
    <button command="--copy" :value="$x.content.copied" x-tooltip.top.end="Copy email"
        aria-label="Copy to clipboard"></button>
</label>

Override the button icons with the --icon-field-copy and --icon-field-copied variables.


File Uploads

Inputs of type="file" work on their own, or can be placed in a label to facilitate an upload icon.


<label role="button">
    <input type="file" />
    <span x-icon="lucide:upload"></span>
    Upload
</label>

Form Layouts

Labels

Placing the input and text inside a <label> automatically stacks them with spacing.


<label>
    Email
    <input placeholder="Enter your email" />
</label>

To horizontally inline the label text with the input, place the text in a <data> element. This is used as a CSS hook with no semantic impact.


<label>
    <data>Email</data>
    <input placeholder="Enter your email" />
</label>

Groups

Horizontally group inputs, buttons, or selects together with a role="group" attribute on the parent container.


<div role="group">
    <input placeholder="Insert email" />
    <button class="brand">Signup</button>
</div>

When these elements are grouped, only the outer elements' outer corners retain their border radii for a seamless appearance.


Validation

Inputs support native HTML5 validation through attributes like required, pattern, minlength, maxlength, min, max, and type="email" / type="url". Style the invalid and valid states with Tailwind pseudo-class variants.


<input type="email" required
    class="user-invalid:border-negative-surface user-valid:border-positive-surface" />

Prefer user-invalid: and user-valid: over the unprefixed invalid: and valid:. They wait until the user has actually engaged with the field, avoiding the awkward "everything is red on page load" effect. See forms for the full variant reference and inline-message patterns.


Styles

Theme

Default inputs use the following theme variables:

Variable Purpose
--color-field-surface Input background color
--color-field-surface-hover Input hover/active background color
--color-field-inverse Text and selection highlight color
--spacing-field-height Input height
--spacing-field-padding Horizontal padding for input content
--radius Border radius for input corners
--transition Transition for interactive states

Customization

Modify base input styles with custom CSS for the input selector.


input {
    background-color: #f0f8ff;
    border: 2px solid #3b82f6;
    border-radius: 8px;
    color: #1e40af;

    &::placeholder {
        color: #60a5fa;
    }

    &:focus-visible {
        border-color: #1d4ed8;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
    }
}