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

PropTypeDefaultDescription
name *string-Field name prefix for form submission
label stringundefinedField label displayed above the range
description stringundefinedDescription text for voice extraction context
value { start: string, end: string }{ start: '', end: '' }Current date range in ISO format (bindable)
min stringundefinedMinimum allowed date (ISO format)
max stringundefinedMaximum allowed date (ISO format)
disabled booleanfalseDisables both inputs
required booleanfalseMarks both fields as required
error stringundefinedError message to display
onchange (value: { start: string, end: string }) => voidundefinedCallback 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/max bounds if specified
  • Both dates required when required is true
  • ISO date format (YYYY-MM-DD)

Form submission includes two fields: {name}_start and {name}_end.