Start typing to search components and docs…
select navigate ESC close

Floating Label Input

<div class="input-wrapper-filled">
<input id="name-filled" type="text" placeholder=" "
  class="peer input-base input-filled input-md" />
<label for="name-filled"
  class="input-label-base input-label-filled input-label-md input-label-filled-state">
  Floating filled
</label>
</div>
<div class="input-wrapper-standard">
<input id="email-standard" type="text" placeholder=" "
  class="peer input-base input-standard input-md" />
<label for="email-standard"
  class="input-label-base input-label-standard input-label-md input-label-standard-state">
  Floating standard
</label>
</div>

Floating Textarea

<div class="input-wrapper-filled">
<textarea id="ta-filled" rows="3" placeholder=" "
  class="peer input-base input-filled input-md input-textarea"></textarea>
<label for="ta-filled"
  class="input-label-base input-label-filled input-label-md input-label-filled-state">
  Floating filled
</label>
</div>
<div class="input-wrapper-standard">
<textarea id="ta-standard" rows="3" placeholder=" "
  class="peer input-base input-standard input-md input-textarea"></textarea>
<label for="ta-standard"
  class="input-label-base input-label-standard input-label-md input-label-standard-state">
  Floating standard
</label>
</div>

Input with Error State

The Input component supports error states to provide validation feedback to users. You can pass a string as the error prop to display a specific error message. Pass true for visual-only error state without a message.

This field is required
Please enter a valid email
<div class="input-wrapper-filled">
<input id="error-filled" type="text" placeholder=" "
  class="peer input-base input-filled input-md input-error" />
<label for="error-filled"
  class="input-label-base input-label-filled input-label-md input-label-filled-state input-label-error">
  With error
</label>
<div class="input-error-message">This field is required</div>
</div>
<div class="input-wrapper-standard">
<input id="error-standard" type="text" placeholder=" "
  class="peer input-base input-standard input-md input-error" />
<label for="error-standard"
  class="input-label-base input-label-standard input-label-md input-label-standard-state input-label-error">
  With error
</label>
<div class="input-error-message">Please enter a valid email</div>
</div>

Input with Success State

Similar to errors, you can indicate a successful validation state using the success prop.

Username is available
<div class="input-wrapper-filled">
<input id="success-filled" type="text" placeholder=" "
  class="peer input-base input-filled input-md input-success" />
<label for="success-filled"
  class="input-label-base input-label-filled input-label-md input-label-filled-state input-label-success">
  With success
</label>
<div class="input-success-message">Username is available</div>
</div>
<div class="input-wrapper-standard">
<input id="success-standard" type="text" placeholder=" "
  class="peer input-base input-standard input-md input-success" />
<label for="success-standard"
  class="input-label-base input-label-standard input-label-md input-label-standard-state input-label-success">
  With success
</label>
</div>

Input Sizes

The Input component supports different sizes: sm, md (default), and lg.

<div class="input-wrapper-filled">
<input id="small-input" type="text" placeholder=" "
  class="peer input-base input-filled input-sm" />
<label for="small-input"
  class="input-label-base input-label-filled input-label-sm input-label-filled-state">
  Small input
</label>
</div>
<div class="input-wrapper-filled">
<input id="medium-input" type="text" placeholder=" "
  class="peer input-base input-filled input-md" />
<label for="medium-input"
  class="input-label-base input-label-filled input-label-md input-label-filled-state">
  Medium input (default)
</label>
</div>
<div class="input-wrapper-filled">
<input id="large-input" type="text" placeholder=" "
  class="peer input-base input-filled input-lg" />
<label for="large-input"
  class="input-label-base input-label-filled input-label-lg input-label-filled-state">
  Large input
</label>
</div>

Required Input

You can mark an input as required, which will add a red asterisk to the label.

<div class="input-wrapper-filled">
<input id="required-filled" type="text" placeholder=" " required
  class="peer input-base input-filled input-md" />
<label for="required-filled"
  class="input-label-base input-label-filled input-label-md input-label-filled-state">
  Required field<span class="text-red-500 ml-1">*</span>
</label>
</div>

Input Types

The Input component supports all standard HTML input types, plus a special textarea type.

<div class="input-wrapper-filled">
<input id="email-input" type="email" placeholder=" "
  class="peer input-base input-filled input-md" />
<label for="email-input"
  class="input-label-base input-label-filled input-label-md input-label-filled-state">
  Email
</label>
</div>
<div class="input-wrapper-standard">
<input id="password-input" type="password" placeholder=" "
  class="peer input-base input-standard input-md" />
<label for="password-input"
  class="input-label-base input-label-standard input-label-md input-label-standard-state">
  Password
</label>
</div>

Using with v-model

The Input component fully supports Vue’s v-model for two-way binding:

<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#E1E4E8">&#x3C;</span><span style="color:#85E89D">script</span><span style="color:#B392F0"> setup</span><span style="color:#E1E4E8">></span></span> <span class="line"><span style="color:#E1E4E8">import { ref } from 'vue';</span></span> <span class="line"><span style="color:#E1E4E8">import { Input } from 'spoko-design-system';</span></span> <span class="line"></span> <span class="line"><span style="color:#E1E4E8">const username = ref('');</span></span> <span class="line"><span style="color:#E1E4E8">const email = ref('');</span></span> <span class="line"><span style="color:#E1E4E8">&#x3C;/</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">></span></span> <span class="line"></span> <span class="line"><span style="color:#E1E4E8">&#x3C;</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">></span></span> <span class="line"><span style="color:#E1E4E8"> &#x3C;</span><span style="color:#79B8FF">Input</span></span> <span class="line"><span style="color:#B392F0"> v-model</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"username"</span></span> <span class="line"><span style="color:#B392F0"> label</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"Username"</span></span> <span class="line"><span style="color:#B392F0"> variant</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"filled"</span></span> <span class="line"><span style="color:#E1E4E8"> /></span></span> <span class="line"><span style="color:#E1E4E8"> </span></span> <span class="line"><span style="color:#E1E4E8"> &#x3C;</span><span style="color:#79B8FF">Input</span></span> <span class="line"><span style="color:#B392F0"> v-model</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"email"</span></span> <span class="line"><span style="color:#B392F0"> label</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"Email"</span></span> <span class="line"><span style="color:#B392F0"> variant</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"standard"</span></span> <span class="line"><span style="color:#B392F0"> type</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"email"</span></span> <span class="line"><span style="color:#E1E4E8"> /></span></span> <span class="line"><span style="color:#E1E4E8"> </span></span> <span class="line"><span style="color:#E1E4E8"> &#x3C;</span><span style="color:#85E89D">div</span><span style="color:#E1E4E8">></span></span> <span class="line"><span style="color:#E1E4E8"> Current values:</span></span> <span class="line"><span style="color:#E1E4E8"> &#x3C;</span><span style="color:#85E89D">p</span><span style="color:#E1E4E8">>Username: {{ username }}&#x3C;/</span><span style="color:#85E89D">p</span><span style="color:#E1E4E8">></span></span> <span class="line"><span style="color:#E1E4E8"> &#x3C;</span><span style="color:#85E89D">p</span><span style="color:#E1E4E8">>Email: {{ email }}&#x3C;/</span><span style="color:#85E89D">p</span><span style="color:#E1E4E8">></span></span> <span class="line"><span style="color:#E1E4E8"> &#x3C;/</span><span style="color:#85E89D">div</span><span style="color:#E1E4E8">></span></span> <span class="line"><span style="color:#E1E4E8">&#x3C;/</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">></span></span></code></pre>

Props Reference

PropTypeDefaultDescription
label*stringLabel text for the floating label
variant'standard' | 'filled''standard'Visual style variant
idstringrandomUnique identifier; also used as name if name not set
namestringsame as idName attribute for the input field
typestring'text'Input type — all HTML types plus 'textarea'
modelValuestring | number''Value for v-model binding
requiredbooleanfalseAdds required asterisk to label
rowsnumber3Number of rows (textarea only)
placeholderstring' 'Space keeps floating label working; override with caution
errorstring | booleanfalseError state — true for visual only, string to show message
successstring | booleanfalseSuccess state — true for visual only, string to show message
size'sm' | 'md' | 'lg''md'Size of the input field
classstring''Additional CSS classes on the wrapper element

Events

Event Parameters Description
update:modelValue (value: string | number) Emitted when input value changes (for v-model)
input (event: Event) Native input event
focus (event: FocusEvent) Native focus event
blur (event: FocusEvent) Native blur event