Skip to content
omaris

Inputs

Text Field

Text field.

import { Input } from 'omaris'
Learn

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.

We only use this for billing.
<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.

That is not an email address.
<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.

Shown under your name. 17/60
<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.

Monospace digits, italic help
<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. type and format decide what the keyboard shows and what the field accepts.
  • A number typed by hand: format="decimal" or integer with suffix="kg", not type="number" and its spinner. Eastern-Arabic digits type as digits.
  • A password. The eye toggle is on by default. clearable adds the × a search or filter field wants.
  • A value with a fixed part: prefix="https://" or suffix=".com" is drawn beside the value and never ends up inside it.

Not for

Do

  • Say what is wrong in supportingText and set invalid. The helper line becomes the error line, where the person is already looking.
  • Pick the variant by the surface: outline on the page background, filled inside a card, ghost inside another control such as a table cell or a toolbar.
  • Set format and the keyboard follows. inputmode, autocapitalize and spellcheck come with it, so a slug field never autocorrects.
  • Use counter only with a maxlength, 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. sm is for a dense filter row.
  • Disable a field to show a value that cannot change. readonly keeps it selectable and copyable; disabled greys it out and skips it in Tab order.

Quick reference

variant
  • outline (default)
  • filled
  • ghost
size
  • sm
  • default (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
sm
default
lg
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 bindable
string | 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 bindable

Defaults 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 bindable

Defaults to null

HTMLInputElement | null