MeasurementInput

A measurement input component combining a numeric value with a unit selector. The supported units are length units (ft, in, m, cm, mm, yd), making it ideal for heights, distances, and dimensions.

Installation

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

Basic Usage - Height

Measure height with common length units like centimeters, meters, inches, or feet.

svelte
<script lang="ts">
  import type { MeasurementUnit } from '@happyvertical/smrt-svelte';

  const heightUnits: MeasurementUnit[] = ['cm', 'm', 'in', 'ft'];

  let value = $state<number | null>(null);
  let unit = $state<MeasurementUnit>('cm');
</script>

<MeasurementInput
  name="height"
  label="Height"
  units={heightUnits}
  bind:value
  bind:unit
/>

With Default Value

Pre-populate the numeric value and unit.

svelte
<MeasurementInput
  name="length"
  label="Length"
  units={distanceUnits}
  value={2}
  unit="m"
/>

With Step and Range

Use step to control the numeric increment and min/max to constrain the value.

svelte
<MeasurementInput
  name="thickness"
  label="Thickness"
  units={distanceUnits}
  step={0.1}
  min={0}
  max={1000}
/>

Required Field

Add required to mark the field as required.

svelte
<MeasurementInput
  name="distance"
  label="Distance"
  units={distanceUnits}
  required
/>

Disabled State

Use disabled to prevent user interaction.

svelte
<MeasurementInput
  name="recorded"
  label="Recorded Length"
  units={distanceUnits}
  value={68.5}
  unit="cm"
  disabled
/>

With Error

Display validation errors using the error prop.

svelte
<MeasurementInput
  name="invalid"
  label="Height"
  units={heightUnits}
  value={500}
  unit="cm"
  error="Height seems unusually high. Please verify."
/>

Voice Input (smrt Mode)

In smrt mode, users can speak measurements with units naturally:

  • "one hundred seventy five centimeters" → { value: 175, unit: 'cm' }
  • "five foot ten" → { value: 5.83, unit: 'ft' } (converts 5'10" to decimal)
  • "two point five meters" → { value: 2.5, unit: 'm' }
  • "twelve inches" → { value: 12, unit: 'in' }
  • "three yards" → { value: 3, unit: 'yd' }
svelte
<!-- Voice example: "one hundred seventy five centimeters" -->
<MeasurementInput
  name="voice"
  label="Height"
  description="A height measurement with units"
  units={heightUnits}
/>

Interactive Example

Enter a measurement to see the combined value and unit:

Value: (empty) m

svelte
<script lang="ts">
  import type { MeasurementUnit } from '@happyvertical/smrt-svelte';

  let value = $state<number | null>(null);
  let unit = $state<MeasurementUnit>('m');
</script>

<MeasurementInput
  name="interactive"
  label="Distance"
  units={distanceUnits}
  bind:value
  bind:unit
/>
<p>Value: {value ?? '(empty)'} {unit}</p>

Props

PropTypeDefaultDescription
name *string-Field name for form submission
label stringundefinedField label displayed above the input
description stringundefinedDescription text for voice extraction context
value number | nullnullCurrent numeric value (bindable)
unit MeasurementUnitundefinedCurrently selected unit, e.g. 'cm' or 'ft' (bindable)
units MeasurementUnit[]undefinedAvailable units to choose from
placeholder stringundefinedPlaceholder text shown when empty
min numberundefinedMinimum allowed value
max numberundefinedMaximum allowed value
step numberundefinedStep increment for the numeric value
disabled booleanfalseDisables the input
required booleanfalseMarks field as required
error stringundefinedError message to display
onchange (measurement: MeasurementValue | null) => voidundefinedCallback when value or unit changes

TypeScript

typescript
import { MeasurementInput } from '@happyvertical/smrt-svelte';
import type { MeasurementUnit, MeasurementValue } from '@happyvertical/smrt-svelte';

// Supported units (length only)
type MeasurementUnit = 'ft' | 'in' | 'm' | 'cm' | 'mm' | 'yd';

// Value emitted by onchange
interface MeasurementValue {
  value: number;
  unit: MeasurementUnit;
}

// Props interface
interface Props {
  name: string;
  label?: string;
  description?: string;
  placeholder?: string;
  value?: number | null;   // bindable
  unit?: MeasurementUnit;  // bindable
  units?: MeasurementUnit[];
  min?: number;
  max?: number;
  step?: number;
  disabled?: boolean;
  required?: boolean;
  error?: string;
  onchange?: (measurement: MeasurementValue | null) => void;
}

Supported Units

units is a list of MeasurementUnit values. The component supports length units only; pass any subset you want to offer:

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

// All supported units:
// 'ft' | 'in' | 'm' | 'cm' | 'mm' | 'yd'

// Metric height
const heightUnits: MeasurementUnit[] = ['cm', 'm', 'in', 'ft'];

// Full length set
const distanceUnits: MeasurementUnit[] = ['m', 'cm', 'mm', 'ft', 'in', 'yd'];

// Small dimensions
const dimensionUnits: MeasurementUnit[] = ['mm', 'cm', 'in'];

Form Submission

The component submits two hidden fields for form integration:

  • {name}_value - The numeric value
  • {name}_unit - The selected unit

For example, name="height" creates height_value and height_unit fields.