Components

Inputs

Collect user input with text, select, checkbox, radio, range, file, and color inputs.

All Colorffy form inputs share a common base — label, placeholder, disabled, required, readonly, errorMessages, variant, size, hideLabel — and bind with v-model.

Text and textarea

<script setup lang="ts">
import { ref } from 'vue'

const name = ref('')
const bio = ref('')
</script>

<template>
  <UiInputText v-model="name" label="Name" placeholder="Jane Doe" required />
  <UiInputTextarea v-model="bio" label="Bio" :rows="4" />
</template>

Select

options accepts an array; map labels / values with optionLabel / optionValue:

<script setup lang="ts">
import { ref } from 'vue'

const role = ref(null)
const options = [
  { name: 'Admin', value: 'admin' },
  { name: 'User', value: 'user' },
]
</script>

<template>
  <UiInputSelect
    v-model="role"
    :options="options"
    option-label="name"
    option-value="value"
    label="Role"
  />
</template>

Checkbox, switch, and radio

<template>
  <UiInputCheck v-model="agree" label="I agree to the terms" required />
  <UiInputCheck v-model="dark" label="Dark mode" variant="switch" />
  <UiInputRadio v-model="plan" :options="plans" option-label="name" option-value="id" inline />
</template>

Range, file, color, and phone

UiInputFile, UiInputColorPicker, and UiInputCheck share the same base props as the other inputs (errorMessages, disabled, required, optionalLabel, hideLabel) and bind with v-model like the rest:

<template>
  <UiInputRange v-model="volume" :min="0" :max="100" :step="5" label="Volume" />
  <UiInputFile v-model="file" label="Upload" input-label="Choose a file" :error-messages="fileErrors" />
  <UiInputPhoneNumber v-model="phone" label="Phone" />
  <UiInputColorPicker v-model="color" label="Brand color" :maxlength="7" />
</template>

OTP Input

UiInputOtp renders one box per character of a segmented PIN or verification code. It auto-advances focus as boxes fill, supports Backspace/Arrow key navigation, and distributes pasted (or autofilled) codes across boxes. modelValue is always a plain string; length (default 6) controls the number of boxes.

<script setup lang="ts">
import { ref } from 'vue'

const code = ref('')

function handleComplete(value: string) {
  console.log('Code complete:', value)
}
</script>

<template>
  <UiInputOtp v-model="code" label="Verification code" @complete="handleComplete" />
  <UiInputOtp v-model="pin" label="4-digit PIN" :length="4" />
</template>

Props: length (default 6), integerOnly (default true — numeric inputmode, non-digit characters discarded on input/paste; set to false for alphanumeric codes), autofocus, plus the shared base props (errorMessages, disabled, required, readonly, variant, size, rounded, hideLabel).

Events: update:modelValue, onUpdate, and complete — fired once with the full value when every box is filled.

Prefix and suffix

UiInputText exposes #prefix and #suffix named slots. Content rendered in either slot gets a bordered box attached to the input — useful for icons or units.

<template>
  <UiInputText v-model="search" label="Search">
    <template #prefix>
      <UiIconMaterial icon-code="&#xe8b6;" />
    </template>
  </UiInputText>

  <UiInputText v-model="price" label="Price" type="number">
    <template #prefix>
      $
    </template>
    <template #suffix>
      USD
    </template>
  </UiInputText>
</template>

Shared base props

PropTypeDefaultDescription
labelstring | nullField label.
placeholderstring | nullPlaceholder text.
errorMessagesstring[]Validation messages shown below the field.
variant'filled' | 'outline' | 'transparent' | nullVisual style.
size'sm' | 'lg' | nullField size.
disabled / required / readonly / roundedbooleanfalseField states.
hideLabelbooleanfalseVisually hide the label.

Per-input highlights

ComponentNotable propsv-model type
UiInputTexttype, maxlength, min, max, autofocusstring | number | null
UiInputTextarearows, cols, resizestring | null
UiInputSelectoptions, optionLabel, optionValuestring | number | object | null
UiInputRadiooptions, optionLabel, optionValue, inlinestring | number | null
UiInputRangemin, max, stepstring | number | null
UiInputCheckvariant: 'switch', label (required)string | boolean | null
UiInputFileinputLabel, largeFile | null
UiInputColorPickermaxlengthstring | null
UiInputPhoneNumbermaxlength, autofocusstring | null
UiInputOtplength, integerOnly, autofocusstring
Most inputs emit both update:modelValue (for v-model) and an onUpdate convenience event with the same payload — this now includes UiInputCheck.
Breaking change:UiInputColorPicker's length-limit prop was renamed from maxLength to maxlength (lowercase, matching the other text inputs).
Copyright © 2026