Element Components
Element components are reusable UI primitives. They are used internally by the form and flow components and can also be used directly.
Available elements
| Component | Web Component Tag | Events dispatched |
|---|---|---|
Button |
alviere-button |
(none) |
Badge |
alviere-badge |
(none) |
Spinner |
alviere-spinner |
(none) |
Callout |
alviere-callout |
(none) |
Timeline |
alviere-timeline |
(none) |
Modal |
alviere-modal |
close |
Checkbox |
alviere-checkbox |
change |
Radio |
alviere-radio |
(none) |
List |
alviere-list |
(none) |
ListItem |
alviere-list-item |
select |
LegalTextConsent |
(Svelte only — no web component) | legal-texts-change, view |
Button
Usage
<script lang="ts">
import { Button } from '@alviere/ui';
</script>
<Button variant="primary" size="md" handler={() => console.log('clicked')}>
Continue
</Button>
<Button variant="secondary" iconName="ArrowLeft" handler={goBack}>
Back
</Button>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
'primary' | 'secondary' | 'tertiary' | 'link' |
'primary' |
Visual style |
size |
'sm' | 'md' | 'lg' |
'md' |
Button size |
type |
'button' | 'submit' | 'reset' |
'button' |
HTML button type |
disabled |
boolean |
false |
Disables interaction |
handler |
(e: MouseEvent) => void |
— | Click handler |
iconName |
'ArrowLeft' | 'ArrowRight' | 'Plus' | 'X' | 'Trash' | 'Starred' | null |
null |
Icon rendered before label |
ariaLabel |
string |
'' |
Accessibility label |
color |
string |
'' |
Sets --alv-color-primary CSS variable |
primaryColor |
string |
'' |
Alias for color — both set the same variable |
backgroundColor |
string |
'' |
Sets --alv-button-primary-bg CSS variable |
class |
string |
'' |
Additional CSS classes |
Badge
Usage
<alviere-badge variant="success" size="sm">Active</alviere-badge>
Props
| Prop | Type | Default |
|---|---|---|
variant |
'primary' | 'secondary' | 'tertiary' | 'error' | 'warning' | 'info' | 'success' |
'primary' |
size |
'sm' | 'md' | 'lg' |
'md' |
Content is rendered via the default slot.
Spinner
Usage
<script lang="ts">
import { Spinner } from '@alviere/ui';
</script>
<Spinner size="md" variant="circular" />
<Spinner size="lg" variant="dots" color="#227e9e" />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Spinner size |
variant |
'circular' | 'dots' |
'circular' |
Animation style |
color |
string |
'' |
Spinner color (sets --spinner-color) |
primaryColor |
string |
'' |
Alias for color |
ariaLabel |
string |
'Loading...' |
Screen reader announcement |
class |
string |
'' |
Additional CSS classes |
Use the message slot to show loading text alongside the spinner:
<alviere-spinner size="md" variant="dots">
<span slot="message">Loading data...</span>
</alviere-spinner>
Callout
Inline status or alert message. Only renders when message is non-empty.
Usage
<alviere-callout message="Your session will expire soon." variant="warning"></alviere-callout>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
message |
string |
'' |
Message text — component renders nothing if empty |
variant |
'warning' | 'info' |
'warning' |
Controls icon and color scheme |
role |
'status' | 'alert' |
'status' |
ARIA role |
ariaLive |
'polite' | 'assertive' | 'off' |
'polite' |
Live region politeness |
Timeline
Progress indicator for multi-step journeys.
Usage
<script lang="ts">
import { Timeline } from '@alviere/ui';
const steps = [
{ id: 'create', label: 'Create Account', status: 'completed' },
{ id: 'onboarding', label: 'Start Onboarding', status: 'active' },
{ id: 'bank', label: 'Add Bank Account', status: 'pending' }
];
</script>
<Timeline {steps} orientation="horizontal" />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
steps |
TimelineStep[] |
[] |
Step definitions |
size |
'sm' | 'md' | 'lg' |
'md' |
Size token |
orientation |
'horizontal' | 'vertical' |
'horizontal' |
Layout direction |
showLabels |
boolean |
true |
Show step text labels |
showDescriptions |
boolean |
false |
Show optional step descriptions |
class |
string |
'' |
Additional CSS classes |
TimelineStep
interface TimelineStep {
id: string;
label: string;
status: 'pending' | 'active' | 'completed' | 'error' | 'info' | 'warning';
description?: string;
}
When a step transitions to completed, a ripple animation triggers automatically. This is not configurable.
Modal
Usage
<script lang="ts">
import { Modal } from '@alviere/ui';
let open = false;
</script>
<Modal bind:open title="Review Terms" on:close={(e) => console.log(e.detail.reason)}>
<p>Modal body content goes here.</p>
<svelte:fragment slot="footer">
<Button handler={() => (open = false)}>Close</Button>
</svelte:fragment>
</Modal>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open |
boolean |
false |
Controls modal visibility |
title |
string |
'' |
Header title text |
dismissible |
boolean |
true |
Allow user to close the modal |
closeOnBackdrop |
boolean |
true |
Clicking the backdrop closes the modal (requires dismissible: true) |
closeOnEscape |
boolean |
true |
ESC key closes the modal (requires dismissible: true) |
Slots
| Slot | Description |
|---|---|
title |
Overrides the title prop for custom header content |
| (default) | Modal body |
footer |
Footer area, typically for action buttons |
Events
| Event | Payload |
|---|---|
close |
{ reason: 'backdrop' | 'escape' | 'button' | 'programmatic' } |
Behavioral notes
The modal DOM is moved into a #alviere-modal-root container appended to document.body (created if absent). This avoids z-index and overflow: hidden stacking context issues that would otherwise clip the overlay when the modal is nested inside a positioned or scrollable ancestor. When open, document.body overflow is locked and restored on close.
Checkbox
Usage
<alviere-checkbox label="I agree to the terms" name="terms"></alviere-checkbox>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string |
'' |
Input element ID (auto-generated if empty) |
name |
string |
'' |
Input name attribute |
value |
boolean |
false |
Form value |
checked |
boolean |
false |
Checked state |
label |
string |
'' |
Label text |
disabled |
boolean |
false |
Disable input |
onchange |
(event: Event) => void |
— | Callback alternative to the change event |
Use the label slot to render rich label content instead of a plain text string:
<alviere-checkbox name="terms">
<span slot="label">I agree to the <a href="/terms">Terms of Service</a></span>
</alviere-checkbox>
Events
change — dispatched on toggle:
{ checked: boolean; value: boolean; name: string }
Note: value in the payload is always the boolean checked state, not the HTML value attribute.
Radio
Usage
<alviere-radio name="accountType" value="CHECKING" checked="true">Checking</alviere-radio>
<alviere-radio name="accountType" value="SAVINGS">Savings</alviere-radio>
Props
| Prop | Type | Default |
|---|---|---|
name |
string |
'' |
value |
string |
'' |
checked |
boolean |
false |
Label text is rendered via the default slot.
Radio dispatches no events. State management and selection handling are the caller's responsibility.
List and ListItem
List is a container for ListItem elements. It validates its children on mount and warns if non-alviere-list-item elements are found.
Usage
<alviere-list>
<alviere-list-item selectable='{"name":"account","value":"checking"}'>
<span slot="primary-text">Checking Account</span>
<span slot="secondary-text">••••1234</span>
<span slot="monetary-text-amount">$2,400.00</span>
</alviere-list-item>
<alviere-list-item selectable='{"name":"account","value":"savings"}'>
<span slot="primary-text">Savings Account</span>
<span slot="secondary-text">••••5678</span>
</alviere-list-item>
</alviere-list>
ListItem props
| Prop | Type | Default | Description |
|---|---|---|---|
selectable |
{ name: string; value: any } | null |
null |
If set, renders a radio and fires select on click |
expandable |
boolean |
false |
Show an expand/collapse toggle |
selected |
boolean |
false |
Initial selection state |
last |
boolean |
false |
Removes bottom border styling for the last item |
selectLabel |
string |
'Select' |
Aria-label for the radio input |
ListItem slots
| Slot | Description |
|---|---|
badge |
Badge shown in the top-left corner |
leading |
Icon or avatar area on the left |
primary-text |
Main label text |
secondary-text |
Subtitle or sub-label |
tertiary-text |
Additional descriptive text |
monetary-text-method |
Payment method label |
monetary-text-amount |
Amount or balance |
badges |
Badge group area |
actions |
Right-side action buttons |
expanded-content |
Content shown when expandable is true and the item is expanded |
ListItem events
select — fired when a selectable item is clicked:
{ value: any } // the value from the selectable prop
LegalTextConsent
Loads legal text documents and tracks per-document acceptance state. Svelte only — no web component registration.
Usage — legacy mode
Pass a documents array and a jwt. The component fetches the legal texts from the API itself.
<script lang="ts">
import { LegalTextConsent } from '@alviere/ui';
</script>
<LegalTextConsent
{jwt}
documents={[
{ type: 'TERMS_AND_CONDITIONS' },
{ type: 'PRIVACY_POLICY' }
]}
on:legal-texts-change={(e) => console.log(e.detail.allAccepted)}
/>
Usage — resolved mode
Pass resolvedDocuments (pre-fetched). The component skips the API call and renders immediately.
<LegalTextConsent
resolvedDocuments={prefetchedDocs}
on:legal-texts-change={(e) => console.log(e.detail.acceptedLegalTextUuids)}
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
documents |
LegalTextDocumentConfig[] |
[] |
Documents to fetch (legacy mode) |
jwt |
string |
'' |
JWT for the fetch call (legacy mode) |
debug |
boolean |
false |
Enable debug logging |
resolvedDocuments |
ResolvedLegalTextDocument[] |
— | Pre-fetched documents (resolved mode) |
interface LegalTextDocumentConfig {
type: string;
version?: string;
label?: string;
}
Events
| Event | Payload | Description |
|---|---|---|
legal-texts-change |
{ accepted: Record<string, boolean>; allAccepted: boolean; acceptedLegalTextUuids: string[] } |
Acceptance state changed |
view |
{ document: LegalTextDocumentConfig; legalText: LegalText } |
User opened a document |
Clicking "view" on a document opens a modal if document_text is present, or navigates to document_url in a new tab otherwise.

