RangeCalendar
Select a date range by using the Calendar component with range={true}. This is not a separate component — it uses the same Calendar import from sv5ui.
Playground
Experiment with different props in real-time.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
Basic Usage
Import the Calendar component and pass range to enable range selection. Bind a DateRange value for two-way binding.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
<script lang="ts">
import { Calendar } from 'sv5ui';
import type { DateRange } from 'bits-ui';
let value = $state<DateRange>({});
</script>
<Calendar range bind:value />
{#if value.start && value.end}
<p>Selected: {value.start} — {value.end}</p>
{/if}Two Months
Display two months side by side with numberOfMonths={2} for a better range selection experience.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 29 | 30 | 31 | 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 |
<script lang="ts">
import { Calendar } from 'sv5ui';
import type { DateRange } from 'bits-ui';
let value = $state<DateRange>({});
</script>
<Calendar range numberOfMonths={2} bind:value />With Min/Max Days
Restrict the range length with minDays and maxDays. In this example the range must be between 3 and 14 days.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
<script lang="ts">
import { Calendar } from 'sv5ui';
import type { DateRange } from 'bits-ui';
let value = $state<DateRange>({});
</script>
<Calendar range minDays={3} maxDays={14} bind:value />Colors
Apply any semantic color to the selected range highlight.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
<Calendar range color="primary" />
<Calendar range color="secondary" />
<Calendar range color="success" />
<Calendar range color="error" />Sizes
3 sizes — small, medium, and large.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
<Calendar range size="xs" />
<Calendar range size="sm" />
<Calendar range size="md" />
<Calendar range size="lg" />
<Calendar range size="xl" />With Min/Max Date
Restrict the selectable date range with minValue and maxValue. In this example, only the next 30 days are selectable.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 31 | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
<script lang="ts">
import { Calendar } from 'sv5ui';
import type { DateRange } from 'bits-ui';
import { today, getLocalTimeZone } from '@internationalized/date';
const now = today(getLocalTimeZone());
let value = $state<DateRange>({});
</script>
<Calendar
range
minValue={now}
maxValue={now.add({ days: 30 })}
bind:value
/>In a Popover
Combine with a Popover to create a date range picker dropdown.
<script lang="ts">
import { Calendar, Popover, Button } from 'sv5ui';
import type { DateRange } from 'bits-ui';
let value = $state<DateRange>({});
let open = $state(false);
let display = $derived(
value.start && value.end
? `${value.start} — ${value.end}`
: ''
);
</script>
<Popover bind:open>
<Button
variant="outline"
color="surface"
leadingIcon="lucide:calendar"
label={display || 'Pick a date range'}
/>
{#snippet content()}
<div class="p-3">
<Calendar
range
bind:value
onValueChange={(v) => { if (v.start && v.end) open = false; }}
size="sm"
/>
</div>
{/snippet}
</Popover>Props
Range-specific and commonly used Calendar props. See the Calendar docs for the full prop list.
| Prop | Type | Default | Description |
|---|---|---|---|
range | boolean | false | |
value | { start?: DateValue; end?: DateValue } | {} | |
onValueChange | (value: DateRange) => void | - | |
minDays | number | - | |
maxDays | number | - | |
color | Color | 'primary' | |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | |
variant | 'solid' | 'outline' | 'soft' | 'subtle' | 'solid' | |
numberOfMonths | number | 1 | |
minValue | DateValue | - | |
maxValue | DateValue | - | |
weekNumbers | boolean | false | |
disabled | boolean | false | |
fixedWeeks | boolean | true | |
locale | string | 'en' | |
weekStartsOn | 0-6 | 0 | |
readonly | boolean | false | |
monthControls | boolean | true | |
yearControls | boolean | true | |
class | string | - | |
ui | Record<Slot, Class> | - |