MeasurementInput
A measurement input component combining a numeric value with a unit selector. Perfect for physical quantities like height, weight, distance, temperature, and more.
Installation
import { MeasurementInput } from '@happyvertical/smrt-svelte';Basic Usage - Height
Measure height with common units like centimeters, meters, inches, or feet.
<script lang="ts">
const heightUnits = [
{ value: 'cm', label: 'Centimeters' },
{ value: 'm', label: 'Meters' },
{ value: 'in', label: 'Inches' },
{ value: 'ft', label: 'Feet' }
];
let value = $state({ value: null, unit: 'cm' });
</script>
<MeasurementInput
name="height"
label="Height"
units={heightUnits}
bind:value
/>Weight Measurement
Weight with default value and common units.
<MeasurementInput
name="weight"
label="Weight"
units={weightUnits}
value={{ value: 75, unit: 'kg' }}
/>Temperature with Precision
Temperature measurement with 1 decimal place precision.
<MeasurementInput
name="temperature"
label="Temperature"
units={temperatureUnits}
decimals={1}
min={-273.15}
max={1000}
bind:value
/>Required Field
Add required to mark the field as required.
<MeasurementInput
name="distance"
label="Distance"
units={distanceUnits}
required
/>Disabled State
Use disabled to prevent user interaction.
<MeasurementInput
name="recorded"
label="Recorded Weight"
units={weightUnits}
value={{ value: 68.5, unit: 'kg' }}
disabled
/>With Error
Display validation errors using the error prop.
<MeasurementInput
name="invalid"
label="Height"
units={heightUnits}
value={{ 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)
- "seventy five kilograms" → { value: 75, unit: 'kg' }
- "twenty two point five degrees celsius" → { value: 22.5, unit: 'C' }
- "ten miles" → { value: 10, unit: 'mi' }
<!-- 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
<script lang="ts">
let value = $state({ value: null, unit: 'm' });
</script>
<MeasurementInput
name="interactive"
label="Distance"
units={distanceUnits}
bind:value
/>
<p>Value: {value.value ?? '(empty)'} {value.unit}</p>Props
| Prop | Type | Default | Description |
|---|---|---|---|
name * | string | - | Field name for form submission |
label | string | undefined | Field label displayed above the input |
description | string | undefined | Description text for voice extraction context |
value | { value: number | null, unit: string } | { value: null, unit: "" } | Current measurement with value and unit (bindable) |
units * | Array<{value: string, label: string}> | - | Available units for measurement type |
min | number | undefined | Minimum allowed value |
max | number | undefined | Maximum allowed value |
decimals | number | 2 | Number of decimal places |
disabled | boolean | false | Disables the input |
required | boolean | false | Marks field as required |
error | string | undefined | Error message to display |
onchange | (value: { value: number | null, unit: string }) => void | undefined | Callback when value or unit changes |
TypeScript
import { MeasurementInput } from '@happyvertical/smrt-svelte';
// Measurement value interface
interface MeasurementValue {
value: number | null;
unit: string;
}
// Unit option interface
interface Unit {
value: string;
label: string;
}
// Props interface
interface Props {
name: string;
label?: string;
description?: string;
value?: MeasurementValue;
units: Unit[];
min?: number;
max?: number;
decimals?: number;
disabled?: boolean;
required?: boolean;
error?: string;
onchange?: (value: MeasurementValue) => void;
}Common Unit Sets
Pre-defined unit arrays for common measurement types:
// Length/Height
const heightUnits = [
{ value: 'cm', label: 'Centimeters' },
{ value: 'm', label: 'Meters' },
{ value: 'in', label: 'Inches' },
{ value: 'ft', label: 'Feet' }
];
// Weight/Mass
const weightUnits = [
{ value: 'kg', label: 'Kilograms' },
{ value: 'g', label: 'Grams' },
{ value: 'lb', label: 'Pounds' },
{ value: 'oz', label: 'Ounces' }
];
// Temperature
const temperatureUnits = [
{ value: 'C', label: '°C' },
{ value: 'F', label: '°F' },
{ value: 'K', label: 'Kelvin' }
];
// Distance
const distanceUnits = [
{ value: 'm', label: 'Meters' },
{ value: 'km', label: 'Kilometers' },
{ value: 'mi', label: 'Miles' },
{ value: 'ft', label: 'Feet' }
];
// Volume
const volumeUnits = [
{ value: 'ml', label: 'Milliliters' },
{ value: 'l', label: 'Liters' },
{ value: 'cup', label: 'Cups' },
{ value: 'gal', label: 'Gallons' }
];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.