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:

<script setup>
import { ref } from 'vue';
import { Input } from 'spoko-design-system';

const username = ref('');
const email = ref('');
</script>

<template>
  <Input
    v-model="username"
    label="Username"
    variant="filled"
  />
  
  <Input
    v-model="email"
    label="Email"
    variant="standard"
    type="email"
  />
  
  <div>
    Current values:
    <p>Username: {{ username }}</p>
    <p>Email: {{ email }}</p>
  </div>
</template>

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