Inputs
Text Field
Text field.
import { Input } from 'omaris' Examples
Basic
A label, a field and a helper line — the shape every field in a settings form takes. Nothing moves when the field is filled.
<script lang="ts"> import { Input } from 'omaris'; let email = $state('');</script><Input class="w-80 max-w-full" label="Work email" type="email" placeholder="you@example.com" supportingText="We only use this for billing." bind:value={email}/> Variants
outline on the page background, filled for a softer well, ghost inside another surface.
<script lang="ts"> import { Input } from 'omaris';</script><Input class="w-64 max-w-full" variant="outline" label="Outline" placeholder="The default" /><Input class="w-64 max-w-full" variant="filled" label="Filled" placeholder="A tinted well" /><Input class="w-64 max-w-full" variant="ghost" label="Ghost" placeholder="No frame until you touch it"/> Sizes
Three heights, and the label and helper text scale with the field. sm for a dense filter row, lg for a sign-in screen.
<script lang="ts"> import { Input } from 'omaris';</script><Input class="w-56 max-w-full" size="sm" label="Small" placeholder="sm" /><Input class="w-56 max-w-full" label="Default" placeholder="default" /><Input class="w-56 max-w-full" size="lg" label="Large" placeholder="lg" /> Icons and affixes
start and end take icons. prefix and suffix are flat text glued to the value — they are not part of it, so the value stays clean.
<script lang="ts"> import { Input } from 'omaris'; let site = $state(''); let weight = $state('');</script><Input class="w-72 max-w-full" label="Search" placeholder="Find an order"> {#snippet start()} ... {/snippet}</Input><Input class="w-72 max-w-full" label="Website" prefix="https://" placeholder="example.com" bind:value={site}/><Input class="w-40 max-w-full" label="Weight" suffix="kg" bind:value={weight} /> Password and clear
A password field gets the eye toggle by default — that is what every password field wants and nobody wants to rebuild. clearable adds the ×.
<script lang="ts"> import { Input } from 'omaris'; let password = $state('hunter2'); let query = $state('Baghdad');</script><Input class="w-72 max-w-full" type="password" label="Password" bind:value={password} /><Input class="w-72 max-w-full" label="Search" clearable bind:value={query} /> States
The supporting text turns into the error text when the field is invalid, so the reason sits where the person is already looking.
<script lang="ts"> import { Input } from 'omaris';</script><Input class="w-64 max-w-full" label="Required" required placeholder="Has to be filled in" /><Input class="w-64 max-w-full" label="Invalid" invalid value="not-an-email" supportingText="That is not an email address."/><Input class="w-64 max-w-full" label="Disabled" disabled value="Read only" /><Input class="w-64 max-w-full" label="Loading" loading value="Checking…" /> Counter
counter needs a maxlength to count against — for a headline or a bio with a hard limit the person should see coming.
<script lang="ts"> import { Input } from 'omaris'; let bio = $state('Ships dashboards.');</script><Input class="w-80 max-w-full" label="Headline" counter maxlength={60} supportingText="Shown under your name." bind:value={bio}/> Formats
A format gets first refusal on every keystroke, so rejected characters never make it in and the keyboard hints come along with it.
<script lang="ts"> import { Input } from 'omaris'; let slug = $state(''); let amount = $state(''); let handle = $state(''); let code = $state('');</script><Input class="w-56 max-w-full" label="Slug" format="slug" placeholder="my-first-post" bind:value={slug}/><Input class="w-56 max-w-full" label="Amount" format="decimal" placeholder="0.00" bind:value={amount}/><Input class="w-56 max-w-full" label="Handle" format="handle" placeholder="omerchetin" bind:value={handle}/><Input class="w-56 max-w-full" label="Code" format="code" placeholder="A1B2C3" bind:value={code} /> Overridden
Every part is reachable by name. class still covers the root.
<script lang="ts"> import { Input } from 'omaris';</script><Input class="w-80 max-w-full" label="Reading" value="42.0000" supportingText="Monospace digits, italic help" classes={{ control: 'font-mono tabular-nums', support: 'italic', label: 'uppercase tracking-wide' }}/> When to use it
Use it for
- One line of text a form collects: a name, an email, a URL, a filter box.
typeandformatdecide what the keyboard shows and what the field accepts. - A number typed by hand:
format="decimal"orintegerwithsuffix="kg", nottype="number"and its spinner. Eastern-Arabic digits type as digits. - A password. The eye toggle is on by default.
clearableadds the × a search or filter field wants. - A value with a fixed part:
prefix="https://"orsuffix=".com"is drawn beside the value and never ends up inside it.
Not for
- More than a line → Textarea.
- Bold, a list, a link → Rich Text Editor. Source with syntax → Code Editor.
- A value chosen from a list → Select. A list you search → Combobox.
- Money → Price Input. A phone number with a country → Phone Input.
format="phone"is an Iraqi mobile number only. - A label for something that is not an Input → Label.
Do
- Say what is wrong in
supportingTextand setinvalid. The helper line becomes the error line, where the person is already looking. - Pick the variant by the surface:
outlineon the page background,filledinside a card,ghostinside another control such as a table cell or a toolbar. - Set
formatand the keyboard follows.inputmode,autocapitalizeandspellcheckcome with it, so a slug field never autocorrects. - Use
counteronly with amaxlength, and only where the limit is real, like a headline shown elsewhere at a fixed width.
Don't
- Use the placeholder as the label. The label stays above the field; the placeholder vanishes on the first keystroke.
- Type the unit into the value.
suffix="kg"keeps the number a number. - Use
size="lg"in a dashboard form. It is for a sign-in screen.smis for a dense filter row. - Disable a field to show a value that cannot change.
readonlykeeps it selectable and copyable;disabledgreys it out and skips it in Tab order.
Quick reference
variant outline(default)filledghost
size smdefault(default)lg
API
Input
Text field.
A quiet frame that wakes up on focus: the border takes the accent and a soft ring blooms around it. The label sits above the field and the supporting text below, so nothing moves when the field is filled in.
Everything a field usually needs is built in — a password eye, a clear button, affixes, a counter, a loading state — so a form is one line per field instead of a nest of wrappers.
import { Input } from 'omaris' Parts
Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.
root- Wrapper: label, field, supporting text.
field- The frame: border, background, height, adornment layout.
control- The bare <input>; the frame owns every decoration.
label- No description in the source yet.
adornment- Icon slots at either end of the frame.
affix- Flat text glued to the value — "https://", "kg".
action- An interactive trailing control: reveal, clear.
support- Helper line under the field, and the counter beside it.
counter- No description in the source yet.
Props
variant Defaults to 'outline'
InputVariant outline- The default: a hairline frame on the page background.
filled- Softer — a tinted well with no border until you touch it.
ghost- No frame at all, for fields nested in another surface.
size Defaults to 'default'
InputSize smdefaultlg
type Defaults to 'text'
HTMLInputTypeAttribute format InputFormatName | InputFormat What the field accepts. A built-in name (decimal, slug, phone, …) or your own InputFormat. Rejected characters never make it in, and the format's keyboard hints come along with it.
label string Label above the field. Wired to the control, so clicking focuses it.
required boolean Marks the label required and sets required on the control. Inside a Field, defaults to the field's.
supportingText string Helper line under the field. Turns into the error text when invalid.
invalid boolean Marks the field invalid and wires up aria-invalid. Inside a Field, defaults to the field's.
value bindablestring | number | null revealable Defaults to true
boolean Show the eye toggle on a password field. On by default — that's the behaviour every password field wants and nobody wants to rebuild.
revealed bindableDefaults to false
boolean Starts a password field revealed. Bindable.
clearable Defaults to false
boolean Adds a clear (×) button once the field has a value.
loading Defaults to false
boolean Swaps the trailing controls for a spinner and blocks interaction.
counter Defaults to false
boolean Live n/maxlength count beside the supporting text.
prefix string Flat text glued to the start of the value — "https://", "@".
suffix string Flat text glued to the end of the value — "kg", ".com".
start Snippet Leading icon.
end Snippet Trailing icon or control, after the built-in actions.
supporting Snippet Richer supporting text — a link, a strength meter.
onclear () => void Fires after the clear button empties the field.
class string classes InputClasses Per-part Tailwind overrides. class still covers the root.
ref bindableDefaults to null
HTMLInputElement | null