DateRangeInput
A date range picker with start and end date inputs. Automatically validates that end date comes after start date, with support for natural language in smrt mode.
Installation
typescript
import { DateRangeInput } from '@happyvertical/smrt-svelte';Basic Usage
A simple date range picker with start and end date fields.
svelte
<script lang="ts">
let value = $state({ start: '', end: '' });
</script>
<DateRangeInput
name="daterange"
label="Select Date Range"
bind:value
/>With Default Values
Pre-populate with start and end dates.
svelte
<DateRangeInput
name="vacation"
label="Vacation Period"
value={{ start: '2025-07-01', end: '2025-07-14' }}
/>With Constraints
Use min and max to limit the selectable date range.
svelte
<DateRangeInput
name="booking"
label="Booking Dates"
min="2025-01-01"
max="2025-12-31"
description="Select dates within 2025"
/>Required Field
Add required to mark both dates as required.
svelte
<DateRangeInput
name="availability"
label="Availability Period"
required
/>Disabled State
Use disabled to prevent user interaction.
svelte
<DateRangeInput
name="confirmed"
label="Confirmed Period"
value={{ start: '2025-03-01', end: '2025-03-15' }}
disabled
/>With Error
Display validation errors using the error prop.
End date must be after start date
svelte
<DateRangeInput
name="invalid"
label="Date Range"
value={{ start: '2025-03-15', end: '2025-03-01' }}
error="End date must be after start date"
/>Voice Input (smrt Mode)
In smrt mode, users can speak date ranges naturally. Examples:
- "from March first to March fifteenth"
- "July first through July fourteenth"
- "next week Monday to Friday"
- "from tomorrow to next Thursday"
- "January through March" (first and last day of months)
svelte
<!-- Voice example: "from March first to March fifteenth" -->
<DateRangeInput
name="voice"
label="Date Range"
description="A range with start and end dates"
/>Interactive Example
Select dates to see the range and calculated duration:
Range: (none) to (none)
Duration: N/A
svelte
<script lang="ts">
let value = $state({ start: '', end: '' });
$: duration = value.start && value.end
? Math.ceil((new Date(value.end).getTime() - new Date(value.start).getTime()) / (1000 * 60 * 60 * 24))
: null;
</script>
<DateRangeInput
name="interactive"
label="Select Range"
bind:value
/>
<p>Range: {value.start || '(none)'} to {value.end || '(none)'}</p>
<p>Duration: {duration ? `${duration} days` : 'N/A'}</p>Props
| Prop | Type | Default | Description |
|---|---|---|---|
name * | string | - | Field name prefix for form submission |
label | string | undefined | Field label displayed above the range |
description | string | undefined | Description text for voice extraction context |
value | { start: string, end: string } | { start: '', end: '' } | Current date range in ISO format (bindable) |
min | string | undefined | Minimum allowed date (ISO format) |
max | string | undefined | Maximum allowed date (ISO format) |
disabled | boolean | false | Disables both inputs |
required | boolean | false | Marks both fields as required |
error | string | undefined | Error message to display |
onchange | (value: { start: string, end: string }) => void | undefined | Callback when either date changes |
TypeScript
typescript
import { DateRangeInput } from '@happyvertical/smrt-svelte';
// DateRange interface
interface DateRange {
start: string; // ISO date format (YYYY-MM-DD)
end: string; // ISO date format (YYYY-MM-DD)
}
// Props interface
interface Props {
name: string;
label?: string;
description?: string;
value?: DateRange;
min?: string; // ISO date format
max?: string; // ISO date format
disabled?: boolean;
required?: boolean;
error?: string;
onchange?: (value: DateRange) => void;
}Validation
The component automatically validates:
- End date must be after or equal to start date
- Dates must be within
min/maxbounds if specified - Both dates required when
requiredis true - ISO date format (YYYY-MM-DD)
Form submission includes two fields: {name}_start and {name}_end.