s-m-r-t

AddressInput

A comprehensive address input component with street, city, province/state, postal code, and country fields. Supports voice input in smrt mode with intelligent address parsing.

Installation

typescript
import { AddressInput } from '@happyvertical/smrt-svelte';

Basic Usage

A complete address form with all fields.

svelte
<script lang="ts">
  let value = $state({});
</script>

<AddressInput
  name="shipping"
  label="Shipping Address"
  bind:value
/>

With Default Values

Pre-populate the address with existing data.

svelte
<AddressInput
  name="billing"
  label="Billing Address"
  value={{
    street: '123 Main Street',
    city: 'Toronto',
    province: 'ON',
    postalCode: 'M5V 1A1',
    country: 'CA'
  }}
/>

Custom Fields

Show only specific fields using the fields prop.

svelte
<AddressInput
  name="simple"
  label="Location"
  fields={['city', 'province', 'country']}
  bind:value
/>

Required Field

Add required to mark all visible fields as required.

svelte
<AddressInput
  name="required"
  label="Delivery Address"
  required
/>

Disabled State

Use disabled to prevent user interaction.

svelte
<AddressInput
  name="disabled"
  label="Confirmed Address"
  value={{
    street: '456 Oak Avenue',
    city: 'Vancouver',
    province: 'BC',
    postalCode: 'V6B 2K1',
    country: 'CA'
  }}
  disabled
/>

With Error

Display validation errors using the error prop.

Please enter a valid postal code
svelte
<AddressInput
  name="error"
  label="Address"
  error="Please enter a valid postal code"
/>

Custom Countries and Provinces

Provide custom options for countries and provinces.

svelte
<AddressInput
  name="custom"
  label="UK Address"
  countries={[
    { value: 'GB', label: 'United Kingdom' },
    { value: 'IE', label: 'Ireland' }
  ]}
  provinces={[
    { value: 'ENG', label: 'England' },
    { value: 'SCT', label: 'Scotland' },
    { value: 'WLS', label: 'Wales' },
    { value: 'NIR', label: 'Northern Ireland' }
  ]}
/>

Voice Input (smrt Mode)

In smrt mode, users can speak their address naturally. The component parses spoken text to extract:

  • Street addresses (e.g., "123 Main Street")
  • Cities
  • Provinces/states by name or abbreviation
  • Postal/ZIP codes (Canadian and US formats)
  • Countries
svelte
<!-- Voice example: "123 Main Street, Toronto, Ontario, M5V 1A1, Canada" -->
<AddressInput
  name="voice"
  label="Address"
  description="A mailing address including street, city, and postal code"
/>

Interactive Example

Fill out the address to see the bound value:

{}
svelte
<script lang="ts">
  let value = $state({});
</script>

<AddressInput
  name="interactive"
  label="Your Address"
  bind:value
/>
<pre>{JSON.stringify(value, null, 2)}</pre>

Props

PropTypeDefaultDescription
name *string-Field name prefix for form submission
label stringundefinedField label displayed above the address group
description stringundefinedDescription text for voice extraction context
value Partial<AddressValue>{}Current address value (bindable)
fields AddressField[]['street', 'city', 'province', 'postalCode', 'country']Which address fields to display
disabled booleanfalseDisables all inputs
required booleanfalseMarks all visible fields as required
error stringundefinedError message to display
countries Array<{value: string, label: string}>Canada, United StatesCountry options for dropdown
provinces Array<{value: string, label: string}>Canadian provinces + US statesProvince/state options for dropdown
onchange (value: Partial<AddressValue>) => voidundefinedCallback when any field changes

TypeScript

typescript
import { AddressInput } from '@happyvertical/smrt-svelte';

// AddressValue interface
interface AddressValue {
  street: string;
  city: string;
  province: string;
  postalCode: string;
  country: string;
}

// AddressField type
type AddressField = 'street' | 'city' | 'province' | 'postalCode' | 'country';

// Props interface
interface Props {
  name: string;
  label?: string;
  description?: string;
  value?: Partial<AddressValue>;
  fields?: AddressField[];
  disabled?: boolean;
  required?: boolean;
  error?: string;
  countries?: Array<{ value: string; label: string }>;
  provinces?: Array<{ value: string; label: string }>;
  onchange?: (value: Partial<AddressValue>) => void;
}