Skip to content

Input

A text input with optional leading and trailing icons.

Usage

vue
<script setup lang="ts">
const value = ref('')
</script>

<template>
  <SInput v-model="value" placeholder="Type something..." />
</template>

Input is full-width by default, rather than needing an opt-in flag to make it so - constrain it with a class on the component itself (as the examples on this page do with max-w-xs), not a wrapping element.

Icons

icon and trailingIcon add an icon before or after the text - the same props Button uses for its own.

vue-html
<SInput v-model="search" icon="hugeicons:search-01" placeholder="Search..." />
<SInput v-model="amount" trailing-icon="hugeicons:dollar-01" placeholder="0.00" />

Custom leading and trailing content

Use #leading and #trailing for text, icons, or buttons inside the field frame. The slots receive { disabled, size, buttonSize }; buttonSize fits a Button inside the current field size. Give interactive controls an accessible label, use type="button", and pass disabled through to match the field state.

Custom content stays visible alongside the built-in clear button. It replaces the corresponding decorative icon or trailingIcon. The field reserves space for the rendered content, including suffixes whose width changes. Use ui.leading and ui.trailing to customize its wrappers.

vue
<script setup lang="ts">
const password = ref('')
const visible = ref(false)
</script>

<template>
  <SInput v-model="password" :type="visible ? 'text' : 'password'" clearable aria-label="Password">
    <template #trailing="{ disabled, buttonSize }">
      <SButton
        type="button" :disabled="disabled" :size="buttonSize" variant="text" color="neutral" square
        :icon="visible ? 'hugeicons:view-off-slash' : 'hugeicons:view'"
        :aria-label="visible ? 'Hide password' : 'Show password'" :aria-pressed="visible"
        @click="visible = !visible"
      />
    </template>
  </SInput>
</template>

Text prefixes and suffixes use the same slots:

Rp
per month

Clear

clearable adds a button that empties the value, once there's something to clear - it takes over the trailing position from trailingIcon while active, the same way Select's does.

vue-html
<SInput v-model="value" clearable placeholder="Type something..." />

Sizes and states

size takes sm / md / lg, disabled prevents interaction and dims the input, and invalid switches the ring to the danger role's focus color:

vue-html
<SInput v-model="email" invalid placeholder="[email protected]" />

See the Props table below.

Colors

color sets the focus-ring color - the resting (unfocused) ring stays --selaras-resolved-border-default regardless, and invalid always wins over a custom color:

vue-html
<SInput v-model="primary" color="primary" placeholder="Primary" />
<SInput v-model="success" color="success" placeholder="Success" />
<SInput v-model="danger" color="danger" placeholder="Danger" />

Masking

Use the v-mask directive to format the text as it's typed. v-model keeps the raw value, while the field shows the formatted one - typing 5551234567 below shows (555) 123-4567, and phone is 5551234567:

Value: —

vue-html
<SInput v-model="phone" v-mask="'(###) ###-####'" inputmode="tel" />

Forms integration

Wrap it in FormField to get id/name/invalid and aria-describedby wired up automatically, plus a hint/error message underneath - FormField is also where size and invalid fall back to when not set directly on the input.

Accessibility

Input renders a plain native <input>, so browser and screen-reader support for typing, selection, and autofill all come for free. aria-invalid and aria-describedby are set automatically once invalid is true or the input is wrapped in FormField - nothing to configure by hand for the common case.

Custom :ui

To see exactly what you'd be overriding - the current default classes for every slot and variant - here's Input's own theme file:

Theme source "input" not found

Props

PropTypeDefault
idstring-
namestring-
modelValuestring | number-
typestringtext
placeholderstring-
size'sm' | 'md' | 'lg'md
disabledbooleanfalse
invalidbooleanfalse
color'primary' | 'neutral' | 'secondary' | 'success' | 'danger' | 'info' | 'warning'primary
clearablebooleanfalse
iconstring-
trailingIconstring-
uiPartial<Record<'root' | 'base' | 'leadingIcon' | 'trailingIcon' | 'leading' | 'trailing' | 'clear', string | object>>-

Slots

SlotPropsDescription
leading{ disabled, size, buttonSize }Custom content before the text; replaces icon
trailing{ disabled, size, buttonSize }Custom content after the text, alongside the clear button; replaces trailingIcon
clear-icon-Replaces the clear button's icon (default: hugeicons:cancel-01)
Edit this page