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 startDate = $state('');
  let endDate = $state('');
</script>

<DateRangeInput
  name="daterange"
  label="Select Date Range"
  bind:startDate
  bind:endDate
/>

With Default Values

Pre-populate with start and end dates.

svelte
<DateRangeInput
  name="vacation"
  label="Vacation Period"
  startDate="2025-07-01"
  endDate="2025-07-14"
/>

With Constraints

Use minDate and maxDate to limit the selectable date range.

svelte
<DateRangeInput
  name="booking"
  label="Booking Dates"
  minDate="2025-01-01"
  maxDate="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"
  startDate="2025-03-01"
  endDate="2025-03-15"
  disabled
/>

With Error

Display validation errors using the error prop.

svelte
<DateRangeInput
  name="invalid"
  label="Date Range"
  startDate="2025-03-15"
  endDate="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 startDate = $state('');
  let endDate = $state('');

  let duration = $derived(
    startDate && endDate
      ? Math.ceil((new Date(endDate).getTime() - new Date(startDate).getTime()) / (1000 * 60 * 60 * 24))
      : null
  );
</script>

<DateRangeInput
  name="interactive"
  label="Select Range"
  bind:startDate
  bind:endDate
/>
<p>Range: {startDate || '(none)'} to {endDate || '(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
startDate stringundefinedCurrent start date in ISO format YYYY-MM-DD (bindable)
endDate stringundefinedCurrent end date in ISO format YYYY-MM-DD (bindable)
startPlaceholder stringundefinedPlaceholder for the start date input
endPlaceholder stringundefinedPlaceholder for the end date input
minDate stringundefinedMinimum selectable date (ISO format)
maxDate stringundefinedMaximum selectable date (ISO format)
disabled booleanfalseDisables both inputs
required booleanfalseMarks both fields as required
error stringundefinedError message to display
onchange (value: DateRangeValue) => voidundefinedCallback when either date changes

TypeScript

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

// Value emitted by onchange
interface DateRangeValue {
  startDate: string; // ISO date format (YYYY-MM-DD)
  endDate: string;   // ISO date format (YYYY-MM-DD)
}

// Props interface
interface Props {
  name: string;
  label?: string;
  description?: string;
  startPlaceholder?: string;
  endPlaceholder?: string;
  startDate?: string; // ISO date format, bindable
  endDate?: string;   // ISO date format, bindable
  minDate?: string;   // ISO date format
  maxDate?: string;   // ISO date format
  disabled?: boolean;
  required?: boolean;
  error?: string;
  onchange?: (value: DateRangeValue) => void;
}

Validation

The component automatically validates:

  • End date must be after or equal to start date
  • Dates must be within minDate/maxDate 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.