Input Components

Input components are validated, accessible field primitives. They handle formatting, validation state, and event dispatch — and are used internally by the form components.

Available inputs

Component Web Component Tag Events dispatched
TextInput alviere-text-input text-input, text-change, text-focus, text-blur
CurrencyInput alviere-currency-input text-input, text-change, text-focus, text-blur
PhoneInput alviere-phone-input phone-input, phone-change, phone-focus, phone-blur
DateOfBirthInput alviere-date-of-birth-input text-input, text-change, text-focus, text-blur
SearchSelect alviere-search-select search-select-change, search-select-input, search-select-open, search-select-close
EinInput alviere-ein-input text-input, text-change, text-focus, text-blur
FileUpload alviere-file-upload (none — use bind:value)
CardPanInput alviere-card-pan-input (legacy/stale)
CardCVVInput alviere-card-cvv-input (legacy/stale)
CardExpInput alviere-card-exp-input (legacy/stale)

Common props

The following props are shared by TextInput, CurrencyInput, PhoneInput, DateOfBirthInput, and EinInput:

Prop Type Default Description
value string '' Current field value
label string '' Field label
placeholder string '' Placeholder text
disabled boolean false Disable the input
required boolean false Mark field as required
readonly boolean false Read-only mode
size 'sm' | 'md' | 'lg' 'md' Field size
id string '' Input element ID
name string '' Field name
autocomplete string varies Browser autocomplete hint
validationState ValidationState 'neutral' Override the visual validation state
errorMessage string '' Override the displayed error message
helpText string '' Help text shown below the field
validationSchema ValidationSchema {} Declarative validation rules

Validation timing: all inputs validate on both blur and input events. Errors are not shown until the user has interacted with the field (hasInteracted: true in event payloads).

Common event payload

Text-style inputs (TextInput, CurrencyInput, DateOfBirthInput, EinInput) dispatch events with this shape:

interface InputEventDetail {
  value: string;         // formatted display value
  rawValue: string;      // unformatted value (see per-component notes)
  isValid: boolean;
  validationState: ValidationState;
  errorMessage: string;
  characterCount: number;
  maxLength: number | undefined;
  hasInteracted: boolean;
}

rawValue differs from value for formatted inputs — see individual component sections for specifics.


TextInput

General-purpose text and textarea input.

Usage

<script lang="ts">
  import { TextInput } from '@alviere/ui';
</script>

<TextInput
  label="Full Name"
  placeholder="Enter your full name"
  validationSchema={{
    required: true,
    minLength: { value: 2, message: 'Minimum 2 characters' },
    maxLength: { value: 100, message: 'Maximum 100 characters' }
  }}
  on:text-change={(e) => console.log(e.detail.value)}
/>

Extra props

Prop Type Default Description
type 'text' | 'textarea' 'text' Render as single-line input or textarea
rows number 3 Textarea row count
cols number Textarea column count
resize 'none' | 'both' | 'horizontal' | 'vertical' 'vertical' Textarea resize handle
maxlength number Maximum character count; shows counter on textarea
minlength number Minimum character count
sensitive boolean false Renders as password field with a show/hide toggle button
blockPaste boolean false Disables paste
suffixActionLabel string '' Label for an inline suffix action button
suffixActionAriaLabel string '' Aria label for the suffix button
suffixActionHandler () => void Callback for the suffix button

Events

text-input · text-change · text-focus · text-blur — all dispatch InputEventDetail.

rawValue equals value for TextInput (no special formatting).


CurrencyInput

Numeric currency input with locale-aware formatting.

Usage

<script lang="ts">
  import { CurrencyInput } from '@alviere/ui';
</script>

<CurrencyInput
  label="Amount"
  currency="USD"
  locale="en-US"
  validationSchema={{
    required: true,
    minValue: { value: 1, message: 'Amount must be greater than zero' }
  }}
  on:text-change={(e) => console.log(e.detail.rawValue)}
/>

Extra props

Prop Type Default Description
currency string 'USD' ISO 4217 currency code
locale string 'en-US' BCP 47 locale for number formatting

Events

text-input · text-change · text-focus · text-blur — all dispatch InputEventDetail.

value vs rawValue: value is the formatted display string (e.g. "$1,234.56"). rawValue is the decimal string your code should use (e.g. "1234.56"). Always read rawValue from event payloads when passing the amount to an API or downstream component.


PhoneInput

Phone number input that normalises values to E.164 format.

Usage

<script lang="ts">
  import { PhoneInput } from '@alviere/ui';
</script>

<PhoneInput
  label="Phone Number"
  validationSchema={{ phone: true }}
  on:phone-change={(e) => console.log(e.detail.value)}
/>

Events

phone-input · phone-change · phone-focus · phone-blur — all dispatch PhoneInputEventDetail:

interface PhoneInputEventDetail extends InputEventDetail {
  formattedValue: string;
  countryCode: string;
}

value in the payload is the normalised E.164 string (e.g. "+14155552671"). rawValue contains digits only, no + prefix.

If no validationSchema is provided, { phone: true } is applied by default.


DateOfBirthInput

Date input with YYYY-MM-DD auto-formatting and built-in date validation.

Usage

<script lang="ts">
  import { DateOfBirthInput } from '@alviere/ui';
</script>

<DateOfBirthInput
  label="Date of Birth"
  validationSchema={{ required: true }}
  on:text-change={(e) => console.log(e.detail.value)}
/>

Events

text-input · text-change · text-focus · text-blur — all dispatch InputEventDetail.

value and rawValue are both the YYYY-MM-DD string. maxLength in the payload is always 10.

Behavioral notes

Hard-coded minimum age of 13. The component rejects dates less than 13 years in the past with the message "Must be at least 13 years old". This is not configurable via props.

Future dates are also rejected automatically, regardless of validationSchema.


SearchSelect

Searchable dropdown with keyboard navigation and option filtering.

Usage

<script lang="ts">
  import { SearchSelect } from '@alviere/ui';

  const options = [
    { label: 'Checking', value: 'CHECKING' },
    { label: 'Savings', value: 'SAVINGS' }
  ];
</script>

<SearchSelect
  label="Account Type"
  {options}
  required
  on:search-select-change={(e) => console.log(e.detail.value)}
/>

Props

Prop Type Default Description
value any '' Currently selected value
options Array<{ value: any; label: string }> [] Option list
label string '' Field label
placeholder string 'Search...' Trigger placeholder
searchPlaceholder string '' Search input placeholder
noOptionsMessage string 'No options found' Empty-state message
loadingMessage string 'Loading...' Loading-state message
isLoading boolean false Show loading state
maxHeight string '300px' Dropdown max height
disabled boolean false Disable the select
required boolean false Mark as required
readonly boolean false Read-only mode
size 'sm' | 'md' | 'lg' 'md' Field size
validationSchema ValidationSchema {} Validation rules
errorMessage string '' Override error message
helpText string '' Help text

Events

Event Payload Description
search-select-change SearchSelectEventDetail User selected or cleared an option
search-select-input SearchSelectEventDetail Search query changed
search-select-open SearchSelectEventDetail Dropdown opened
search-select-close SearchSelectEventDetail Dropdown closed
change { value, label } Legacy compatibility — fires alongside search-select-change
interface SearchSelectEventDetail {
  value: any;
  rawValue: any;
  isValid: boolean;
  validationState: ValidationState;
  errorMessage: string;
  hasInteracted: boolean;
  selectedOption: { value: any; label: string } | null; // full option object
  options: Array<{ value: any; label: string }>;
  searchQuery: string;
}

selectedOption contains the full option object, not just the value — useful when you need both value and label from the selection.


EinInput

EIN-specific input with XX-XXXXXXX auto-formatting.

Usage

<script lang="ts">
  import { EinInput } from '@alviere/ui';
</script>

<EinInput
  label="EIN"
  invalidFormatMessage="Use format XX-XXXXXXX"
  validationSchema={{ required: true }}
  on:text-change={(e) => console.log(e.detail.rawValue)}
/>

Extra props

Prop Type Default Description
invalidFormatMessage string 'Please enter a valid EIN (XX-XXXXXXX)' Error shown for invalid EIN format

Events

text-input · text-change · text-focus · text-blur — all dispatch InputEventDetail.

value is the formatted string (e.g. "12-3456789"). rawValue is the 9-digit string without the dash (e.g. "123456789"). Use rawValue when submitting to the API.


FileUpload

File picker for document uploads. Accepts PDF, JPEG, and PNG.

Usage

<script lang="ts">
  import { FileUpload } from '@alviere/ui';

  let file: File | null = null;
</script>

<FileUpload
  bind:value={file}
  label="Upload Document"
  required
  validationSchema={{ required: true }}
/>

Props

Prop Type Default Description
value File | null null Selected File object
label string '' Field label
disabled boolean false Disable the input
required boolean false Mark as required
readonly boolean false Read-only mode
size 'sm' | 'md' | 'lg' 'md' Size token
id string '' Field ID
name string '' Field name
validationState ValidationState 'neutral' Validation state override
errorMessage string '' Error message override
helpText string '' Help text
validationSchema ValidationSchema {} Validation rules

FileUpload dispatches no events. Use bind:value to read the selected File object. Validation state is reflected via validationState and errorMessage props, which you can bind to for external access.

Accepted MIME types: application/pdf, image/jpeg, image/png. Type validation is enforced by the component; there is no configurable accept list and no maximum file size limit.

Supports drag-and-drop in addition to click-to-upload.


Validation types

ValidationState

type ValidationState = 'valid' | 'invalid' | 'neutral' | 'warning';

ValidationSchema

interface ValidationSchema {
  required?: boolean | string;
  email?: boolean | string;
  phone?: boolean | string;
  url?: boolean | string;
  numeric?: boolean | string;
  alphabetic?: boolean | string;
  alphanumeric?: boolean | string;
  pattern?: { regex: RegExp | string; flags?: string; message?: string };
  minLength?: number | { value: number; message?: string };
  maxLength?: number | { value: number; message?: string };
  minValue?: number | { value: number; message?: string };
  maxValue?: number | { value: number; message?: string };
  postalCode?: boolean | string | { country?: string; message?: string };
  date?: boolean | string | { format?: string; message?: string };
  uuid?: boolean | string;
  match?: { fieldId?: string; fieldRef?: { value: string } | (() => string); message?: string };
}

When a rule value is a string, that string is used as the error message. When it is true, the built-in message is used.

<TextInput
  label="Confirmation Code"
  validationSchema={{
    required: 'This field is required',
    alphanumeric: true,
    minLength: { value: 6, message: 'Minimum 6 characters' },
    maxLength: { value: 10, message: 'Maximum 10 characters' },
    pattern: { regex: '^[A-Z0-9]+$', message: 'Use uppercase letters and numbers only' }
  }}
/>
Form Components Link to a page in the guide Flow Components Link to a page in the guide Events Link to a page in the guide