Fork me on GitHub

@svelte-plugins/datepicker (dysfunc)

A simple datepicker component written in Svelte.


Overview

The DatePicker component allows users to easily select a date or date-range from one or more calendars.
March 2025
SuMoTuWeThFrSa
 
 
 
 
 
 
 
 
 
 
 
April 2025
SuMoTuWeThFrSa
 
 
 
 
 

Props

Name Type Description Default
startDate object The start date string or date object. null
endDate object The end date string or date object. null
startDateTime string The start date time string in 24 hour format. 00:00
endDateTime string The end date time string in 24 hour format. 00:00
defaultYear number The year you want to show as the default. 2025
align string The edge alignment of the datepicker.
Accepted values left or right
left
isRange boolean Changes the date picker into a range picker and allows start and end date selection. false
isMultipane boolean If true, two calendar months will be shown side-by-side instead of one. false
isOpen boolean If true, the picker will be shown without user interaction. false
showPresets boolean If true, the picker will show the preset ranges for selection. false
showPresetsOnly boolean If true, the preset ranges will only show. Requires range and showPreset to be set. false
showYearControls boolean If true, the picker will hide the year navigation controls. false
showTimePicker boolean If true, the picker will show the time picker. false
enableFutureDates boolean If true, the picker will allow the user to select future dates. false
enablePastDates boolean If disabled, the picker will prevent the user from selecting anything prior to today. true
theme string The theme name will be assigned to the theme data-attribute datepicker.[data-picker-theme="theme_value_here"]`. empty
defaultMonth number The month you want to show as the default.
Accepted values 0-11

  • 0 - January
  • 1 - February
  • 2 - March
  • 3 - April
  • 4 - May
  • 5 - June
  • 6 - July
  • 7 - August
  • 8 - September
  • 9 - October
  • 10 - November
  • 11 - December
3
startOfWeek number Defines what day will start your week.
Accepted values 0-6

  • 0 - Sunday
  • 1 - Monday
  • 2 - Tuesday
  • 3 - Wednesday
  • 4 - Thursday
  • 5 - Friday
  • 6 - Saturday
0
disabledDates array Determines which dates will be disabled.
Accepted format 'MM/DD/YYYY'

  • ['1/1/2023'] - Disables January 1st, 2023
  • ['1/1/2023', '1/2/2023'] - Disables January 1st and 2nd, 2023
  • ['1/1/2023:1/10/2023'] - Disables the range January 1st to 10th, 2023
[]
enabledDates array Determines which dates will be enabled only.
Accepted format 'MM/DD/YYYY'

  • ['1/1/2023'] - Enables January 1st, 2023
  • ['1/1/2023', '1/2/2023'] - Enables January 1st and 2nd, 2023
  • ['1/1/2023:1/10/2023'] - Enables the range January 1st to 10th, 2023
[]
dowLabels array An array of strings containing the days of the week. [  
  •   "Su",
  •   "Mo",
  •   "Tu",
  •   "We",
  •   "Th",
  •   "Fr",
  •   "Sa"
]
monthLabels array An array of strings containing the months of the year. [  
  •   "January",
  •   "February",
  •   "March",
  •   "April",
  •   "May",
  •   "June",
  •   "July",
  •   "August",
  •   "September",
  •   "October",
  •   "November",
  •   "Decemeber"
]
presetLabels array An array of strings of the default preset labels. [  
  •   "Today",
  •   "Last 7 Days",
  •   "Last 30 Days",
  •   "Last 60 Days",
  •   "Last 90 Days",
  •   "Last Year"
]
presetRanges array An array of objects containing preset configurations. [{  
  •   "label": "string",
  •   "start": "Date",
  •   "end": "Date"
}]
includeFont boolean If false, the default font "Rubik" will not be loaded. true

Events

Name Type Description Default
onDateChange function Callback function to handle when date changes. None
onDayClick function Callback function to handle day click events. None
onNavigationChange function Callback function to handle the navigation click event for months and years. None

Examples

Below are different examples of how you can configure the datepicker.

Single Date

April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  let startDate = new Date();
  let dateFormat = 'MM/dd/yy';
  let isOpen = false;

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };
  let formattedStartDate = formatDate(startDate);

  const onChange = () => {
    startDate = new Date(formattedStartDate);
  };

  $: formattedStartDate = formatDate(startDate);
</script>

<DatePicker bind:isOpen bind:startDate>
  <input type="text" placeholder="Select date" bind:value={formattedStartDate} on:click={toggleDatePicker} />
</DatePicker>

<style>
  input[type="text"] {
    border: 1px solid #e8e9ea;
    border-radius: 4px;
    padding: 8px;
  }
</style>

Date Range

Mar 4, 2025 - Apr 2, 2025
April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  const today = new Date();

  const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;

  const getDateFromToday = (days) => {
    return Date.now() - days * MILLISECONDS_IN_DAY;
  };

  let startDate = getDateFromToday(29);
  let endDate = today;
  let dateFormat = 'MMM d, yyyy';
  let isOpen = false;

  let formattedStartDate = '';

  const onClearDates = () => {
    startDate = '';
    endDate = '';
  };

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };

  $: formattedStartDate = formatDate(startDate);
  $: formattedEndDate = formatDate(endDate);
</script>

<div class="date-filter">
  <DatePicker bind:isOpen bind:startDate bind:endDate isRange>
    <div class="date-field" on:click={toggleDatePicker} class:open={isOpen}>
      <i class="icon-calendar" />
      <div class="date">
        {#if startDate}
          {formattedStartDate} - {formattedEndDate}
        {:else}
          Pick a date
        {/if}
      </div>
      {#if startDate}
        <span on:click={onClearDates}>
          <i class="os-icon-x" />
        </span>
      {/if}
    </div>
  </DatePicker>
</div>

<style>
  .date-field {
    align-items: center;
    background-color: #fff;
    border-bottom: 1px solid #e8e9ea;
    display: inline-flex;
    gap: 8px;
    min-width: 100px;
    padding: 16px;
  }

  .date-field.open {
    border-bottom: 1px solid #0087ff;
  }

  .date-field .icon-calendar {
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEmSURBVHgB7ZcPzcIwEMUfXz4BSCgKwAGgACRMAg6YBBxsOMABOAAHFAXgAK5Z2Y6lHbfQ8SfpL3lZaY/1rb01N+BHUKSMNBfEJjZWISA56Uo6C2KvVpkgFn9oRx9vICFtUT1JKO3tvRtZdjBxXQs+YY+1FenIfuesPUGVVLzfRWKvmrSzbbN19wS+kAb2+sCEuUxrYzkbe4YvCVM2Vr5NPAkVa+van7Wn38U95uTpN5TJ/A8ZKemAakmbmJJGpI0gVmwA0huieFItjG19DgTHtwIZhCfZq3ztCuzQYh+FKBSvusjAGs8PnLYkLgMf34JoIBqIBqKBaIAb0Kw9RlhMCTbzzPWAqYq7LsuPaGDUsYmznaOk5zChUJTNQ4TFVMkrOL4HPsoNn26PxROHCggAAAAASUVORK5CYII=) no-repeat center center;
    background-size: 14px 14px;
    height: 14px;
    width: 14px;
  }
</style>

Multipane Range

Mar 4, 2025 - Apr 2, 2025
April 2025
SuMoTuWeThFrSa
 
 
 
 
 
May 2025
SuMoTuWeThFrSa
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  const today = new Date();

  const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;

  const getDateFromToday = (days) => {
    return Date.now() - days * MILLISECONDS_IN_DAY;
  };

  let startDate = getDateFromToday(29);
  let endDate = today;
  let dateFormat = 'MMM d, yyyy';
  let isOpen = false;

  let formattedStartDate = '';

  const onClearDates = () => {
    startDate = '';
    endDate = '';
  };

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };

  $: formattedStartDate = formatDate(startDate);
  $: formattedEndDate = formatDate(endDate);
</script>

<div class="date-filter">
  <DatePicker bind:isOpen bind:startDate bind:endDate isRange isMultipane>
    <div class="date-field" on:click={toggleDatePicker} class:open={isOpen}>
      <i class="icon-calendar" />
      <div class="date">
        {#if startDate}
          {formattedStartDate} - {formattedEndDate}
        {:else}
          Pick a date
        {/if}
      </div>
      {#if startDate}
        <span on:click={onClearDates}>
          <i class="os-icon-x" />
        </span>
      {/if}
    </div>
  </DatePicker>
</div>

<style>
  .date-field {
    align-items: center;
    background-color: #fff;
    border-bottom: 1px solid #e8e9ea;
    display: inline-flex;
    gap: 8px;
    min-width: 100px;
    padding: 16px;
  }

  .date-field.open {
    border-bottom: 1px solid #0087ff;
  }

  .date-field .icon-calendar {
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEmSURBVHgB7ZcPzcIwEMUfXz4BSCgKwAGgACRMAg6YBBxsOMABOAAHFAXgAK5Z2Y6lHbfQ8SfpL3lZaY/1rb01N+BHUKSMNBfEJjZWISA56Uo6C2KvVpkgFn9oRx9vICFtUT1JKO3tvRtZdjBxXQs+YY+1FenIfuesPUGVVLzfRWKvmrSzbbN19wS+kAb2+sCEuUxrYzkbe4YvCVM2Vr5NPAkVa+van7Wn38U95uTpN5TJ/A8ZKemAakmbmJJGpI0gVmwA0huieFItjG19DgTHtwIZhCfZq3ztCuzQYh+FKBSvusjAGs8PnLYkLgMf34JoIBqIBqKBaIAb0Kw9RlhMCTbzzPWAqYq7LsuPaGDUsYmznaOk5zChUJTNQ4TFVMkrOL4HPsoNn26PxROHCggAAAAASUVORK5CYII=) no-repeat center center;
    background-size: 14px 14px;
    height: 14px;
    width: 14px;
  }
</style>

Preset Ranges

Mar 27, 2025 - Apr 2, 2025
April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  const today = new Date();

  const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;

  const getDateFromToday = (days) => {
    return Date.now() - days * MILLISECONDS_IN_DAY;
  };

  let startDate = getDateFromToday(29);
  let endDate = today;
  let dateFormat = 'MMM d, yyyy';
  let isOpen = false;

  let formattedStartDate = '';

  const onClearDates = () => {
    startDate = '';
    endDate = '';
  };

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };

  $: formattedStartDate = formatDate(startDate);
  $: formattedEndDate = formatDate(endDate);
</script>

<div class="date-filter">
  <DatePicker bind:isOpen bind:startDate bind:endDate isRange showPresets>
    <div class="date-field" on:click={toggleDatePicker} class:open={isOpen}>
      <i class="icon-calendar" />
      <div class="date">
        {#if startDate}
          {formattedStartDate} - {formattedEndDate}
        {:else}
          Pick a date
        {/if}
      </div>
      {#if startDate}
        <span on:click={onClearDates}>
          <i class="os-icon-x" />
        </span>
      {/if}
    </div>
  </DatePicker>
</div>

<style>
  .date-field {
    align-items: center;
    background-color: #fff;
    border-bottom: 1px solid #e8e9ea;
    display: inline-flex;
    gap: 8px;
    min-width: 100px;
    padding: 16px;
  }

  .date-field.open {
    border-bottom: 1px solid #0087ff;
  }

  .date-field .icon-calendar {
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEmSURBVHgB7ZcPzcIwEMUfXz4BSCgKwAGgACRMAg6YBBxsOMABOAAHFAXgAK5Z2Y6lHbfQ8SfpL3lZaY/1rb01N+BHUKSMNBfEJjZWISA56Uo6C2KvVpkgFn9oRx9vICFtUT1JKO3tvRtZdjBxXQs+YY+1FenIfuesPUGVVLzfRWKvmrSzbbN19wS+kAb2+sCEuUxrYzkbe4YvCVM2Vr5NPAkVa+van7Wn38U95uTpN5TJ/A8ZKemAakmbmJJGpI0gVmwA0huieFItjG19DgTHtwIZhCfZq3ztCuzQYh+FKBSvusjAGs8PnLYkLgMf34JoIBqIBqKBaIAb0Kw9RlhMCTbzzPWAqYq7LsuPaGDUsYmznaOk5zChUJTNQ4TFVMkrOL4HPsoNn26PxROHCggAAAAASUVORK5CYII=) no-repeat center center;
    background-size: 14px 14px;
    height: 14px;
    width: 14px;
  }
</style>

You can customize the presets by defining your own:

let presetRanges = [
  {
    label: 'Last Week',
    start: getDateFromToday(6),
    end: getDateFromToday(0)
  },
  {
    label: '12 days ago',
    start: getDateFromToday(11),
    end: getDateFromToday(0)
  },
  {
    label: '43 days ago',
    start: getDateFromToday(42),
    end: getDateFromToday(0)
  }
];

...

<DatePicker ... {presetRanges}></DatePicker>

Presets Only

Mar 4, 2025 - Apr 2, 2025
April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  const today = new Date();

  const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;

  const getDateFromToday = (days) => {
    return Date.now() - days * MILLISECONDS_IN_DAY;
  };

  let startDate = getDateFromToday(29);
  let endDate = today;
  let dateFormat = 'MMM d, yyyy';
  let isOpen = false;

  let formattedStartDate = '';

  const onClearDates = () => {
    startDate = '';
    endDate = '';
  };

  const onDateChange = (args) => {
    console.log(args, 'onDateChange');
  };

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };

  $: formattedStartDate = formatDate(startDate);
  $: formattedEndDate = formatDate(endDate);
</script>

<div class="date-filter">
  <DatePicker bind:isOpen bind:startDate bind:endDate isRange showPresets showPresetsOnly {onDateChange}>
    <div class="date-field" on:click={toggleDatePicker} class:open={isOpen}>
      <i class="icon-calendar" />
      <div class="date">
        {#if startDate}
          {formattedStartDate} - {formattedEndDate}
        {:else}
          Pick a date
        {/if}
      </div>
      {#if startDate}
        <span on:click={onClearDates}>
          <i class="os-icon-x" />
        </span>
      {/if}
    </div>
  </DatePicker>
</div>

<style>
  .date-field {
    align-items: center;
    background-color: #fff;
    border-bottom: 1px solid #e8e9ea;
    display: inline-flex;
    gap: 8px;
    min-width: 100px;
    padding: 16px;
  }

  .date-field.open {
    border-bottom: 1px solid #0087ff;
  }

  .date-field .icon-calendar {
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEmSURBVHgB7ZcPzcIwEMUfXz4BSCgKwAGgACRMAg6YBBxsOMABOAAHFAXgAK5Z2Y6lHbfQ8SfpL3lZaY/1rb01N+BHUKSMNBfEJjZWISA56Uo6C2KvVpkgFn9oRx9vICFtUT1JKO3tvRtZdjBxXQs+YY+1FenIfuesPUGVVLzfRWKvmrSzbbN19wS+kAb2+sCEuUxrYzkbe4YvCVM2Vr5NPAkVa+van7Wn38U95uTpN5TJ/A8ZKemAakmbmJJGpI0gVmwA0huieFItjG19DgTHtwIZhCfZq3ztCuzQYh+FKBSvusjAGs8PnLYkLgMf34JoIBqIBqKBaIAb0Kw9RlhMCTbzzPWAqYq7LsuPaGDUsYmznaOk5zChUJTNQ4TFVMkrOL4HPsoNn26PxROHCggAAAAASUVORK5CYII=) no-repeat center center;
    background-size: 14px 14px;
    height: 14px;
    width: 14px;
  }
</style>

Time Picker

April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  let startDate = new Date();
  let dateFormat = 'MM/dd/yy';
  let isOpen = false;

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };
  let formattedStartDate = formatDate(startDate);

  const onChange = () => {
    startDate = new Date(formattedStartDate);
  };

  $: formattedStartDate = formatDate(startDate);
</script>

<DatePicker bind:isOpen bind:startDate showTimePicker>
  <input type="text" placeholder="Select date" bind:value={formattedStartDate} on:click={toggleDatePicker} />
</DatePicker>

<style>
  input[type="text"] {
    border: 1px solid #e8e9ea;
    border-radius: 4px;
    padding: 8px;
  }
</style>

Disable Past dates

April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  let startDate = new Date();
  let dateFormat = 'MM/dd/yy';
  let isOpen = false;

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };
  let formattedStartDate = formatDate(startDate);

  const onChange = () => {
    startDate = new Date(formattedStartDate);
  };

  $: formattedStartDate = formatDate(startDate);
</script>

<DatePicker bind:isOpen bind:startDate enablePastDates={false}>
  <input type="text" placeholder="Select date" bind:value={formattedStartDate} on:click={toggleDatePicker} />
</DatePicker>

<style>
  input[type="text"] {
    border: 1px solid #e8e9ea;
    border-radius: 4px;
    padding: 8px;
  }
</style>

Enable Future dates

April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  let startDate = new Date();
  let dateFormat = 'MM/dd/yy';
  let isOpen = false;

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };
  let formattedStartDate = formatDate(startDate);

  const onChange = () => {
    startDate = new Date(formattedStartDate);
  };

  $: formattedStartDate = formatDate(startDate);
</script>

<DatePicker bind:isOpen bind:startDate enableFutureDates>
  <input type="text" placeholder="Select date" bind:value={formattedStartDate} on:click={toggleDatePicker} />
</DatePicker>

<style>
  input[type="text"] {
    border: 1px solid #e8e9ea;
    border-radius: 4px;
    padding: 8px;
  }
</style>

Disabled Dates

April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  let startDate = new Date();
  let dateFormat = 'MM/dd/yy';
  let isOpen = false;

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };
  let formattedStartDate = formatDate(startDate);

  const onChange = () => {
    startDate = new Date(formattedStartDate);
  };

  $: formattedStartDate = formatDate(startDate);
</script>

<DatePicker bind:isOpen bind:startDate disabledDates={["11/25/23:11/29/23","12/10/23","12/14/23:12/31/23","1/7/24:1/14/24"]} enableFutureDates>
  <input type="text" placeholder="Select date" bind:value={formattedStartDate} on:click={toggleDatePicker} />
</DatePicker>

<style>
  input[type="text"] {
    border: 1px solid #e8e9ea;
    border-radius: 4px;
    padding: 8px;
  }
</style>

Enabled Dates

April 2025
SuMoTuWeThFrSa
 
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  let startDate = new Date();
  let dateFormat = 'MM/dd/yy';
  let isOpen = false;

  const toggleDatePicker = () => (isOpen = !isOpen);

  const formatDate = (dateString) => {
    if (isNaN(new Date(dateString))) {
      return '';
    }

    return dateString && format(new Date(dateString), dateFormat) || '';
  };
  let formattedStartDate = formatDate(startDate);

  const onChange = () => {
    startDate = new Date(formattedStartDate);
  };

  $: formattedStartDate = formatDate(startDate);
</script>

<DatePicker bind:isOpen bind:startDate enabledDates={["1/14/23:3/16/24"]} enableFutureDates>
  <input type="text" placeholder="Select date" bind:value={formattedStartDate} on:click={toggleDatePicker} />
</DatePicker>

<style>
  input[type="text"] {
    border: 1px solid #e8e9ea;
    border-radius: 4px;
    padding: 8px;
  }
</style>

Theme

Mar 4, 2025 - Apr 2, 2025
April 2025
SuMoTuWeThFrSa
 
 
 
 
 
May 2025
SuMoTuWeThFrSa
 
 
 
 
<script>
  import { DatePicker } from '@svelte-plugins/datepicker';
  import { format } from 'date-fns';

  const today = new Date();

  const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;

  const getDateFromToday = (days) => {
    return Date.now() - days * MILLISECONDS_IN_DAY;
  };

  let startDate = getDateFromToday(29);
  let endDate = today;
  let dateFormat = 'MMM d, yyyy';
  let isOpen = false;

  let formattedStartDate = '';

  const onClearDates = () => {
    startDate = '';
    endDate = '';
  };

  const toggleDatePicker = () => (isOpen = !isOpen);
  const formatDate = (dateString) => dateString && format(new Date(dateString), dateFormat) || '';

  $: formattedStartDate = formatDate(startDate);
  $: formattedEndDate = formatDate(endDate);
</script>

<div class="date-filter">
  <DatePicker theme="custom-datepicker" bind:isOpen bind:startDate isRange isMultipane showPresets>
    <div class="date-field" on:click={toggleDatePicker} class:open={isOpen}>
      <i class="icon-calendar" />
      <div class="date">
        {#if startDate}
          {formattedStartDate} - {formattedEndDate}
        {:else}
          Pick a date
        {/if}
      </div>
      {#if startDate}
        <span on:click={onClearDates}>
          <i class="os-icon-x" />
        </span>
      {/if}
    </div>
  </DatePicker>
</div>

<style>
  .date-field {
    align-items: center;
    background-color: #fff;
    border-bottom: 1px solid #e8e9ea;
    display: inline-flex;
    gap: 8px;
    min-width: 100px;
    padding: 16px;
  }

  .date-field.open {
    border-bottom: 1px solid #0087ff;
  }

  .date-field .icon-calendar {
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEmSURBVHgB7ZcPzcIwEMUfXz4BSCgKwAGgACRMAg6YBBxsOMABOAAHFAXgAK5Z2Y6lHbfQ8SfpL3lZaY/1rb01N+BHUKSMNBfEJjZWISA56Uo6C2KvVpkgFn9oRx9vICFtUT1JKO3tvRtZdjBxXQs+YY+1FenIfuesPUGVVLzfRWKvmrSzbbN19wS+kAb2+sCEuUxrYzkbe4YvCVM2Vr5NPAkVa+van7Wn38U95uTpN5TJ/A8ZKemAakmbmJJGpI0gVmwA0huieFItjG19DgTHtwIZhCfZq3ztCuzQYh+FKBSvusjAGs8PnLYkLgMf34JoIBqIBqKBaIAb0Kw9RlhMCTbzzPWAqYq7LsuPaGDUsYmznaOk5zChUJTNQ4TFVMkrOL4HPsoNn26PxROHCggAAAAASUVORK5CYII=) no-repeat center center;
    background-size: 14px 14px;
    height: 14px;
    width: 14px;
  }

  :global(.datepicker[data-picker-theme="custom-datepicker"]) {
    --datepicker-container-background: #ff66ae;
    --datepicker-container-border: 1px solid #ff1683;

    --datepicker-calendar-header-text-color: #fff;
    --datepicker-calendar-dow-color: #fff;
    --datepicker-calendar-day-color: #fff;
    --datepicker-calendar-day-color-disabled: pink;
    --datepicker-calendar-range-selected-background: #ff1683;

    --datepicker-calendar-header-month-nav-background-hover: #ff1683;
    --datepicker-calendar-header-month-nav-icon-next-filter: invert(100);
    --datepicker-calendar-header-month-nav-icon-prev-filter: invert(100);
    --datepicker-calendar-header-year-nav-icon-next-filter: invert(100);
    --datepicker-calendar-header-year-nav-icon-prev-filter: invert(100);

    --datepicker-calendar-split-border: 1px solid pink;

    --datepicker-presets-border: 1px solid pink;
    --datepicker-presets-button-background-active: #ff1683;
    --datepicker-presets-button-color: #fff;
    --datepicker-presets-button-color-active: #fff;
    --datepicker-presets-button-color-hover: #333;
    --datepicker-presets-button-color-focus: #333;
  }
</style>