@wikicasa-dev/components · Forms · preferred

BaseInput

Single-line text field with floating label, validation state, feedback messages and optional icons.

import BaseInput from "@wikicasa-dev/components/UIKit/BaseInput";

Use for any single-line text entry in a form (name, email, phone, price, surface). For multi-line text use BaseTextarea; for search-as-you-type use ClearableAutocomplete.

Native input attributes go straight on the component (type, name, placeholder, maxlength, inputmode, pattern, min, max, disabled, readonly, autocomplete="on"). class styles the outer wrapper; inputClass styles the <input> itself. An id is generated if you don't pass one.

Usage

<script setup lang="ts">
import { ref } from "vue";
import BaseInput from "@wikicasa-dev/components/UIKit/BaseInput";
import { ViewPswIcon, HidePswIcon } from "@wikicasa-dev/svg-icons";

const email = ref("");
const price = ref<number | "">("");
const password = ref("");

// Shows 250000 as "250.000" while the model keeps the number
const priceFormatter = {
  formatFn: (v: string) => (v && !isNaN(Number(v)) ? Number(v).toLocaleString("it-IT") : ""),
  unFormatFn: (v: string) => (v.replace(/\D/g, "") ? Number(v.replace(/\D/g, "")) : null),
};
</script>

<template>
  <BaseInput
    v-model="email"
    type="email"
    name="email"
    label-text="Email"
    required
    :is-valid="email ? email.includes('@') : null"
    :feedback="{ invalid: 'Inserisci un indirizzo email valido' }"
  />
  <BaseInput v-model="price" label-text="Prezzo massimo (€)" inputmode="numeric" :formatter="priceFormatter" />
  <BaseInput v-model="password" type="password" label-text="Password">
    <template #righticon="{ handleShowPasswd, curType }">
      <span class="text-input-icon right md" @click.stop="handleShowPasswd">
        <ViewPswIcon v-if="curType === 'password'" />
        <HidePswIcon v-else />
      </span>
    </template>
  </BaseInput>
</template>

Do / Don't

  • Do always set labelText: it is the field's visible and accessible label (inline when empty, floating when focused or filled).
  • Do drive isValid with three states: null (neutral, the default), true (blue border + check) or false (red border + warning icon, shows feedback.invalid). feedback strings may be HTML; an array renders one line per entry.
  • Do use the feedback slot for richer error content, and under-label for a small italic hint below the field.
  • Do use formatter for display formatting (thousands separators): the model keeps the unformatted value. formatFn must handle any string it gets; an emptied field sets the model to "".
  • Do use the righticon slot props: handleClean() empties the field, handleShowPasswd() toggles a password field, curType is the current input type.
  • Don't expect required to block form submit: it only adds the asterisk to the label. Validate yourself.
  • Don't change type after mount: it is read once.

Styling hooks

  • Put icons in the leftIcon / righticon slots with the class text-input-icon plus left or right, and a size sm (16px), md (20px) or lg (25px).
  • --icon-default-size on the wrapper (default 44px): the icon hit area.
  • Wrapper state classes: is-valid, is-invalid, floating-state / inline-state, has-left-icon, has-right-icon.
  • labelClasses, labelTextClasses, fieldsetClasses (the border) and inputClass accept extra utility classes.

API

Generated from the component's types. Do not edit by hand.

Props

Name Type Default Required Description
id string
inputClass ClassType | ClassType[]
labelText string ""
feedback FeedbackLabels
isValid Nullable<boolean> null
keepFloatingLabel boolean false
formatter Nullable<Partial<{ formatFn: (value: string) => string; unFormatFn: (value: string) => Nullable<ModelValue>; }>> null
labelClasses ClassTypeProp
fieldsetClasses ClassTypeProp
labelTextClasses ClassTypeProp
withLeftIcon boolean undefined
withRightIcon boolean undefined
dataCy string
modelValue ModelValue "" as ModelValue & {}

Events

Name Payload
click [MouseEvent]
keydown [KeyboardEvent]
keydownEnterPressed
focusin
focusout
keyup [KeyboardEvent]
update:modelValue [value: ModelValue]

v-model

  • v-model binds modelValue (ModelValue)

Slots

Name Slot props
leftIcon
righticon { handleClean: () => void; handleShowPasswd: () => void; curType: InputTypeHTMLAttribute; }
feedback
under-label

Exposed (template ref)

None.