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' }
}}
/>

