Input

A text input component with label, helper text, error state, size variants, clearable support, readonly/loading states, and full native form integration.

Basic

basic.html
html
1 <nana-input
2 label="Email address"
3 placeholder="you@example.com"
4 type="email"
5 helper-text="We'll never share your email."
6 ></nana-input>

Types

types.html
html
1 <nana-input label="Text" placeholder="Enter text" type="text"></nana-input>
2 <nana-input label="Email" placeholder="you@example.com" type="email"></nana-input>
3 <nana-input label="Password" placeholder="Enter password" type="password"></nana-input>
4 <nana-input label="Number" placeholder="42" type="number"></nana-input>
5 <nana-input label="Search" placeholder="Search..." type="search"></nana-input>
6 <nana-input label="Phone" placeholder="+1 (555) 000-0000" type="tel"></nana-input>
7 <nana-input label="Website" placeholder="https://example.com" type="url"></nana-input>

Sizes

sizes.html
html
1 <nana-input label="Extra Small" placeholder="xs" size="xs"></nana-input>
2 <nana-input label="Small" placeholder="sm" size="sm"></nana-input>
3 <nana-input label="Medium" placeholder="md" size="md"></nana-input>
4 <nana-input label="Large" placeholder="lg" size="lg"></nana-input>

States

states.html
html
1 <nana-input label="Normal" placeholder="Enter text"></nana-input>
2 <nana-input label="Disabled" placeholder="Disabled input" disabled></nana-input>
3 <nana-input label="Readonly" value="Read-only value" readonly></nana-input>
4 <nana-input label="Loading" placeholder="Checking..." loading></nana-input>
5 <nana-input label="Invalid" value="bad-value" invalid error-message="Please enter a valid email address"></nana-input>

Prefix, Suffix & Clearable

prefix-suffix.html
html
1 <!-- Prefix icon -->
2 <nana-input label="Search" placeholder="Search...">
3 <nana-icon slot="prefix" name="search"></nana-icon>
4 </nana-input>
5
6 <!-- Suffix icon -->
7 <nana-input label="Website" placeholder="https://example.com" type="url">
8 <nana-icon slot="suffix" name="external-link"></nana-icon>
9 </nana-input>
10
11 <!-- Clearable -->
12 <nana-input label="Username" placeholder="john_doe" clearable></nana-input>

Validation

validation.html
html
1 <nana-input
2 label="Username"
3 placeholder="Choose a username"
4 helper-text="3–20 characters, letters and numbers only"
5 minlength="3"
6 maxlength="20"
7 ></nana-input>
8
9 <nana-input
10 label="Confirm password"
11 type="password"
12 value="mismatch"
13 invalid
14 error-message="Passwords do not match"
15 ></nana-input>

Events

events.html
html
1 <nana-input id="my-input" label="Live value" placeholder="Type something..."></nana-input>
2
3 <script>
4 const input = document.querySelector('#my-input');
5
6 // Fires on every keystroke
7 input.addEventListener('nana-input', (e) => console.log('input:', e.detail.value));
8
9 // Fires on blur or Enter (committed value)
10 input.addEventListener('nana-change', (e) => console.log('change:', e.detail.value));
11
12 // Fires when cleared via the × button or .clear()
13 input.addEventListener('nana-clear', () => console.log('cleared'));
14 </script>

Customization

Use size for scale and the boolean props for state. The field is built on theme tokens, so it follows light/dark automatically; to match a brand, three CSS variables cover colour and radius, and the parts handle anything finer.

input.css
css
1 /* Theming hooks */
2 .search-input {
3 --nana-input-bg: #0b1220;
4 --nana-input-color: #e5edff;
5 --nana-input-radius: 9999px;
6 }
7
8 /* Or reach into a part for anything else */
9 .search-input::part(input) {
10 font-variant-numeric: tabular-nums;
11 }
CSS Variable Description
--nana-input-bgField background colour
--nana-input-colorInput text colour
--nana-input-radiusField corner radius
Part Description
wrapperThe bordered field container
inputThe native <input> element

Props

Attribute Type Default Description
label string "" Label text
value string "" Current value
name string "" Name submitted with the form
placeholder string "" Placeholder text
type string "text" Native input type (text, email, password, number, search, tel, url)
size xs | sm | md | lg "md" Size variant
disabled boolean false Disables the input
required boolean false Marks as required
readonly boolean false Read-only — focusable but not editable
loading boolean false Shows a spinner; implies non-interactive
clearable boolean false Shows × button when the field has a value
invalid boolean false Marks as invalid and shows error message
helper-text string "" Help text shown below the input
error-message string "" Error message shown when invalid
autocomplete string "off" Native autocomplete hint
maxlength number Maximum character length
minlength number Minimum character length
input-id string auto-generated Forwarded to the native input as id

Slots

Slot Description
prefix Icon or content rendered inside the input on the left
suffix Icon or content rendered inside the input on the right (hidden when loading is true)

Events

Event Detail Description
nana-input { value: string } Every keystroke — mirrors the native input event
nana-change { value: string } Value committed — fires on blur or Enter
nana-clear Clear button was clicked or .clear() was called
nana-focus Input gained focus
nana-blur Input lost focus

Methods

Method Parameters Description
focus() options?: FocusOptions Focuses the native input
blur() Removes focus from the input
clear() Clears the value and fires nana-clear