Range Calendar

Enables users to select a range of dates using a calendar interface.

Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
	<script lang="ts">
  import { RangeCalendar } from "bits-ui";
  import CaretLeft from "phosphor-svelte/lib/CaretLeft";
  import CaretRight from "phosphor-svelte/lib/CaretRight";
  import cn from "clsx";
  import type { ComponentProps } from "svelte";
 
  let { value = $bindable() }: ComponentProps<typeof RangeCalendar.Root> =
    $props();
</script>
 
<RangeCalendar.Root
  class="mt-6 rounded-15px border border-dark-10 bg-background-alt p-[22px] shadow-card"
  weekdayFormat="short"
  fixedWeeks={true}
  bind:value
>
  {#snippet children({ months, weekdays })}
    <RangeCalendar.Header class="flex items-center justify-between">
      <RangeCalendar.PrevButton
        class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt hover:bg-muted active:scale-[0.98]"
      >
        <CaretLeft class="size-6" />
      </RangeCalendar.PrevButton>
      <RangeCalendar.Heading class="text-[15px] font-medium" />
      <RangeCalendar.NextButton
        class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt hover:bg-muted active:scale-[0.98]"
      >
        <CaretRight class="size-6" />
      </RangeCalendar.NextButton>
    </RangeCalendar.Header>
    <div
      class="flex flex-col space-y-4 pt-4 sm:flex-row sm:space-y-0 sm:space-x-4"
    >
      {#each months as month (month.value.month)}
        <RangeCalendar.Grid
          class="w-full border-collapse space-y-1 select-none"
        >
          <RangeCalendar.GridHead>
            <RangeCalendar.GridRow class="mb-1 flex w-full justify-between">
              {#each weekdays as day (day)}
                <RangeCalendar.HeadCell
                  class="w-10 rounded-md text-xs font-normal! text-muted-foreground"
                >
                  <div>{day.slice(0, 2)}</div>
                </RangeCalendar.HeadCell>
              {/each}
            </RangeCalendar.GridRow>
          </RangeCalendar.GridHead>
          <RangeCalendar.GridBody>
            {#each month.weeks as weekDates, i (i)}
              <RangeCalendar.GridRow class="flex w-full">
                {#each weekDates as date, d (d)}
                  <RangeCalendar.Cell
                    {date}
                    month={month.value}
                    class="relative m-0 size-10 p-0! text-center text-sm focus-within:z-20"
                  >
                    <RangeCalendar.Day
                      class={cn(
                        "group relative inline-flex size-10 items-center justify-center overflow-visible rounded-9px border border-transparent bg-transparent p-0 text-sm font-normal whitespace-nowrap text-foreground hover:border-foreground focus-visible:ring-foreground! data-disabled:pointer-events-none data-disabled:text-foreground/30 data-highlighted:rounded-none data-highlighted:bg-muted data-outside-month:pointer-events-none data-selected:bg-muted data-selected:font-medium data-selected:text-foreground data-selection-end:rounded-9px data-selection-end:bg-foreground data-selection-end:font-medium data-selection-end:text-background data-selection-start:rounded-9px data-selection-start:bg-foreground data-selection-start:font-medium data-selection-start:text-background data-selection-start:focus-visible:ring-2 data-selection-start:focus-visible:ring-offset-2! data-unavailable:text-muted-foreground data-unavailable:line-through data-selected:[&:not([data-selection-start])]:[&:not([data-selection-end])]:rounded-none data-selected:[&:not([data-selection-start])]:[&:not([data-selection-end])]:focus-visible:border-foreground data-selected:[&:not([data-selection-start])]:[&:not([data-selection-end])]:focus-visible:ring-0! data-selected:[&:not([data-selection-start])]:[&:not([data-selection-end])]:focus-visible:ring-offset-0!"
                      )}
                    >
                      <div
                        class="absolute top-[5px] hidden size-1 rounded-full bg-foreground group-data-selected:bg-background group-data-today:block"
                      ></div>
                      {date.day}
                    </RangeCalendar.Day>
                  </RangeCalendar.Cell>
                {/each}
              </RangeCalendar.GridRow>
            {/each}
          </RangeCalendar.GridBody>
        </RangeCalendar.Grid>
      {/each}
    </div>
  {/snippet}
</RangeCalendar.Root>

Structure

	<script lang="ts">
  import { RangeCalendar } from "bits-ui";
</script>
 
<RangeCalendar.Root>
  {#snippet children({ months, weekdays })}
    <RangeCalendar.Header>
      <RangeCalendar.PrevButton />
      <RangeCalendar.Heading />
      <RangeCalendar.NextButton />
    </RangeCalendar.Header>
    {#each months as month}
      <RangeCalendar.Grid>
        <RangeCalendar.GridHead>
          <RangeCalendar.GridRow>
            {#each weekdays as day}
              <RangeCalendar.HeadCell>
                {day}
              </RangeCalendar.HeadCell>
            {/each}
          </RangeCalendar.GridRow>
        </RangeCalendar.GridHead>
        <RangeCalendar.GridBody>
          {#each month.weeks as weekDates}
            <RangeCalendar.GridRow>
              {#each weekDates as date}
                <RangeCalendar.Cell {date} month={month.value}>
                  <RangeCalendar.Day />
                </RangeCalendar.Cell>
              {/each}
            </RangeCalendar.GridRow>
          {/each}
        </RangeCalendar.GridBody>
      </RangeCalendar.Grid>
    {/each}
  {/snippet}
</RangeCalendar.Root>

Examples

Min Days

You can set the minDays prop to limit the minimum number of days that must be selected for a range.

	<RangeCalendar.Root minDays={3}>
  <!-- ... -->
</RangeCalendar.Root>
Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12

Max Days

You can set the maxDays prop to limit the maximum number of days that can be selected for a range.

	<RangeCalendar.Root maxDays={7}>
  <!-- ... -->
</RangeCalendar.Root>
Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12

Min and Max Days

You can set both minDays and maxDays to limit the number of days that can be selected for a range.

	<RangeCalendar.Root minDays={3} maxDays={10}>
  <!-- ... -->
</RangeCalendar.Root>
Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12

Exclude Disabled

You can set the excludeDisabled prop to automatically reset the range if any date within the selected range becomes disabled.

	<RangeCalendar.Root
  excludeDisabled
  isDateDisabled={(date) => isWeekend(date, "en-US")}
>
  <!-- ... -->
</RangeCalendar.Root>
Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12

API Reference

RangeCalendar.Root

The root range calendar component which contains all other calendar components.

Property Details
value
onValueChange
placeholder
onPlaceholderChange
pagedNavigation
preventDeselect
weekdayFormat
weekStartsOn
calendarLabel
fixedWeeks
isDateDisabled
isDateUnavailable
maxValue
minValue
locale
numberOfMonths
disabled
readonly
disableDaysOutsideMonth
onStartValueChange
onEndValueChange
minDays
maxDays
excludeDisabled
monthFormat
yearFormat
child
children
ref
Data Attribute Details
data-invalid
data-disabled
data-readonly
data-range-calendar-root

The header of the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-readonly
data-range-calendar-header

RangeCalendar.Heading

The heading of the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-readonly
data-range-calendar-heading

RangeCalendar.NextButton

The next button of the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-range-calendar-next-button

RangeCalendar.PrevButton

The previous button of the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-range-calendar-prev-button

RangeCalendar.Cell

A cell in the calendar grid.

Property Details
date
month
ref
children
child
Data Attribute Details
data-disabled
data-unavailable
data-today
data-outside-month
data-outside-visible-months
data-focused
data-selected
data-value
data-range-calendar-cell
data-range-start
data-range-end
data-range-middle
data-highlighted

RangeCalendar.Day

A day in the calendar grid.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-unavailable
data-today
data-outside-month
data-outside-visible-months
data-focused
data-selected
data-value
data-range-calendar-day
data-range-start
data-range-end
data-range-middle
data-highlighted

RangeCalendar.Grid

The grid of dates in the calendar, typically representing a month.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-readonly
data-range-calendar-grid

RangeCalendar.GridBody

The body of the grid of dates in the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-readonly
data-range-calendar-grid-body

RangeCalendar.GridHead

The head of the grid of dates in the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-readonly
data-range-calendar-grid-head

RangeCalendar.GridRow

A row in the grid of dates in the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-readonly
data-range-calendar-grid-row

RangeCalendar.HeadCell

A cell in the head of the grid of dates in the calendar.

Property Details
ref
children
child
Data Attribute Details
data-disabled
data-readonly
data-range-calendar-head-cell

RangeCalendar.MonthSelect

A select you can use to navigate to a specific month in the calendar view.

Property Details
months
monthFormat
ref
children
child
Data Attribute Details
data-disabled
data-range-calendar-month-select

RangeCalendar.YearSelect

A select you can use to navigate to a specific year in the calendar view.

Property Details
years
yearFormat
ref
children
child
Data Attribute Details
data-disabled
data-range-calendar-year-select