Skip to content

Input

SInput is a text field with a label, a hint, an error state and correct a11y wiring (label, aria-describedby, aria-invalid). It works through v-model. The use-tags flag turns it into a tags input (see below).

Basic usage

Square corners

The square prop removes the rounding of the field border (fields are rounded by default). Available on all fields.

Floating label

By default the label floats: at rest it looks like a placeholder inside the border, and on focus or once filled it moves up onto the top border with a notch cut into it. The label size is fixed and does not depend on size. Turn it off with :floating-label="false" — the label then renders as a regular line above the field.

Hint and error

Your work email
This field is required

Sizes

The size prop (sm/md/lg) controls padding and font size.

Icons and clearing

icon draws a leading icon (a name from the registry — here a custom search icon registered with registerIcons). The clearable flag adds a clear button, visible while the value is not empty.

prepend / append slots

The prepend and append slots put arbitrary content inside the field border — an icon, text or a button. Unlike the decorative icon prop, slot content is interactive.

$

States

disabled blocks input, invalid marks the field as invalid (in addition to error), required adds * to the label and sets the native required attribute.

Input types

The type prop is the native <input> type: password (masks input), email (email keyboard and validation), and so on.

type="number" never reaches the DOM

On intermediate invalid input, a native number field hands the browser an empty string: typing 12,75 can turn into 5 while the field stays empty — the value gets corrupted silently. That is why type="number" enables numeric mode (see below) and renders as text.

Numeric mode

The numeric prop restricts input to a number: letters and a second decimal separator simply never appear in the field, rather than being removed after typing. true means integers; an object sets precision and bounds. v-model holds a normalized string (dot as the decimal separator, no group separators), so Number(value) always works, while the field shows the locale's usual formatting.

It also sets inputmode, so phones open a numeric keyboard.

pcs
kg
$
KeyWhat it does
decimalsdigits after the separator; 0 (default) allows integers only
unsigneddisallows the minus sign
min/maxvalue bounds — applied on change, not on every keystroke
localeformatting locale, en by default

Bounds are checked on the change event on purpose: if they were applied on every keystroke, with min: 10 you could not type the first digit — it would immediately be replaced with 10.

For a field with a stepper — "minus" and "plus" buttons — there is a separate SNumberField.

Units

The prefix and suffix props draw text inside the border, before and after the input: units of measure, a currency sign, a country code. Unlike the prepend/append slots, they do not intercept clicks — tapping next to the unit moves focus into the field.

kg
$
+1

Read-only

readonly keeps the value visible and selectable but not editable. Unlike disabled, the field is not dimmed, stays in the tab order and is submitted with the form; the clear button is hidden.

Native attributes and events

Everything not declared as a prop goes to the <input> itself: maxlength, autocomplete, name, pattern, @blur, @focus, @change handlers. Only class and style stay on the outer border.

vue
<template>
  <SInput
    v-model="zip"
    label="ZIP code"
    name="postal-code"
    autocomplete="postal-code"
    maxlength="5"
    class="own-class"
    @blur="validate"
  />
</template>

This matters for @blur: the event does not bubble, so the handler has to sit on the field itself. Attached to the outer div, it would silently never fire.

Trailing icon and custom clear icon

iconRight draws a decorative icon on the right inside the field; clearIcon sets a custom icon for the clear button (instead of the default cross).

Input mask

The mask prop formats input by a template of tokens; the fill-mask flag shows the template in the field and keeps it visible while typing (__/__/____). Tokens, named masks and options are listed in the API table below.

Raw value and letters

With unmasked-value, v-model receives the value without separators (handy for sending to the backend). Letter tokens with a case transform suit IDs such as a license number: AA ###### (letters are uppercased).

v-model: —
Letters are uppercased

Tags mode (use-tags)

The use-tags flag enables entering multiple tags (it replaces the former standalone STagsInput component). In this mode v-model is a string[]: a new tag is added on Enter, and each tag is an STag chip with a remove button. The duplicate, add-on-paste and max props control input behavior.

Vue
Nuxt

API

Props

NameTypeDefaultDescription
idstringundefinedInput id. Generated automatically when not set (SSR-safe).
typestring"text"Type of the native input (plain mode only, not use-tags). number never reaches the DOM: on intermediate invalid input the browser returns an empty string and silently loses what was typed, so numeric mode is enabled instead, see numeric.
labelstringundefinedField label (linked to the input via for/id).
floating-labelbooleantrueFloating label: the label sits inside the border, looks like a placeholder at rest and floats up to the top edge on focus or when filled. On by default; false renders a regular label above the field. The label size is fixed and does not depend on size.
hintstringundefinedHint below the field.
errorstringundefinedError message. When set, the field is marked invalid.
placeholderstringundefinedPlaceholder text in an empty field.
size"md" | "sm" | "lg""md"Field size: sm (32px), md (40px) or lg (48px).
disabledbooleanfalseDisables input and makes the field inactive.
requiredbooleanfalseMarks the field as required: adds * to the label and sets required.
invalidbooleanfalseExplicitly marks the field invalid (in addition to error).
readonlybooleanundefinedRead-only field: the value is visible and selectable but cannot be edited.
squarebooleanundefinedSquare corners: removes the field border radius (rounded by default).
prefixstringundefinedText prefix inside the border, before the input (e.g. $, +1).
suffixstringundefinedText suffix inside the border, after the input: a unit of measure (kg, cm, pcs).
iconstringundefinedRegistry name or raw path of the leading icon, drawn on the left inside the field.
icon-rightstringundefinedRegistry name or raw path of the trailing icon, drawn on the right (plain mode only).
clearablebooleanfalseShows a clear button that resets the field value (plain mode only).
clear-iconstring"x"Registry name or raw path of the clear button icon.
clear-labelstringundefinedAccessible name of the clear button (defaults to the locale dictionary).
maskstringundefinedInput mask (plain mode only, not use-tags). A pattern of tokens: # is a digit, S a letter, N alphanumeric, A/a an upper/lowercase letter, X/x upper/lowercase alphanumeric; any other character is a literal separator. Escape a literal with \ (e.g. \#). Named masks are supported: phone, date, datetime, time, fulltime, card. Example: mask="(###) ### - ####".
unmasked-valuebooleanfalseWith a mask: v-model holds the raw value without separators/literals (e.g. 9991234567 instead of (999) 123 - 4567). By default the model contains the masked string.
fill-maskstring | false | trueundefinedWith a mask: shows the mask template right in the field, with empty slots filled by a character that **stays visible while typing** (e.g. (123) 45_ - ____). true uses _; a string sets a custom character (e.g. fill-mask="·"). Drawn as a "ghost" layer behind the text, so the caret works natively. The label stays floated at the top.
numeric | false | true | { decimals?: number; unsigned?: boolean; min?: number; max?: number; locale?: string }undefinedNumeric mode (plain mode only, not use-tags; incompatible with mask). true allows integers; an object sets precision and bounds. v-model holds a normalized string: a dot as the decimal separator and no group separators, so Number(value) always works. Example: :numeric="{ decimals: 2, unsigned: true, max: 1000 }".
use-tagsbooleanfalseTags mode: the field becomes an input for multiple tags. In this mode modelValue is a string[] rather than a string; the type/iconRight/clearable props do not apply.
duplicatebooleanfalseTags mode: allows duplicate tags.
add-on-pastebooleantrueTags mode: adds tags when pasting from the clipboard (split by the delimiter).
maxnumberundefinedTags mode: maximum number of tags.
remove-iconstring"x"Tags mode: icon of the tag remove button (registry name or raw path).
remove-tag-labelstringundefinedTags mode: accessible name of the tag remove button (defaults to the locale dictionary).
model-valuestring | string[]undefinedField value: string in regular mode, string[] (the tag list) with use-tags. Two-way bound via v-model.

Events

NameSignatureDescription
update:modelValue( value: | string | string[] | undefined ) => voidEmitted when modelValue changes. Used for two-way binding (v-model).

Slots

NameDescription
prependContent at the start of the field, inside the border (icon, button).
appendContent at the end of the field, inside the border (icon, button).