Data Display
Calendar
A date picker supporting single, multiple, and range selection. Built on @internationalized/date for timezone-aware dates.
Playground
Experiment with different props.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
Basic Usage
Single date selection with bind:value.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
<script lang="ts">
import { Calendar } from 'sv5ui';
import { today, getLocalTimeZone } from '@internationalized/date';
let value = $state(today(getLocalTimeZone()));
</script>
<Calendar bind:value />Variants
4 visual styles.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
<Calendar variant="solid" />
<Calendar variant="outline" />
<Calendar variant="soft" />
<Calendar variant="subtle" />Sizes
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
<Calendar size="xs" />
<Calendar size="sm" />
<Calendar size="md" />
<Calendar size="lg" />
<Calendar size="xl" />Colors
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
<Calendar color="primary" />
<Calendar color="secondary" />
<Calendar color="tertiary" />
<Calendar color="success" />
<Calendar color="warning" />
<Calendar color="error" />
<Calendar color="info" />
<Calendar color="surface" />Multiple Selection
Select multiple dates with type="multiple".
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
Selected: 0 date(s)
<script lang="ts">
import { Calendar } from 'sv5ui';
import type { DateValue } from '@internationalized/date';
let values = $state<DateValue[]>([]);
</script>
<Calendar type="multiple" bind:value={values} />Multiple Months
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 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 | 10 | 11 |
<Calendar numberOfMonths={2} />Min & Max Date
Restrict selectable dates to a range.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 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 |
<script lang="ts">
import { Calendar } from 'sv5ui';
import { today, getLocalTimeZone } from '@internationalized/date';
const now = today(getLocalTimeZone());
</script>
<Calendar
minValue={now}
maxValue={now.add({ days: 14 })}
/>Week Numbers
| # | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|---|
| 1 | 26 | 27 | 28 | 29 | 30 | 1 | 2 |
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 3 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 5 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 6 | 31 | 1 | 2 | 3 | 4 | 5 | 6 |
<Calendar weekNumbers />In a Popover
Combine with Popover for a date picker dropdown.
<script lang="ts">
import { Calendar, Popover, Button } from 'sv5ui';
import type { DateValue } from '@internationalized/date';
let value = $state<DateValue | undefined>(undefined);
let open = $state(false);
let display = $derived(value ? value.toString() : '');
</script>
<Popover bind:open>
<Button
variant="outline"
color="surface"
leadingIcon="lucide:calendar"
label={display || 'Pick a date'}
/>
{#snippet content()}
<div class="p-3">
<Calendar
bind:value
onValueChange={() => open = false}
size="sm"
/>
</div>
{/snippet}
</Popover>UI Slots
| Slot | Description |
|---|---|
root | Outermost wrapper |
header | Navigation and heading |
body | Main grid area |
navButton | Nav buttons |
navButtonIcon | Nav button icons |
grid | Calendar grid table |
heading | Month/year heading |
headCell | Weekday header cell |
cell | Date cell wrapper |
cellTrigger | Clickable date button |
Snippets
| Snippet | Description |
|---|---|
heading | Custom month/year heading (receives value string) |
day | Custom date cell content (receives day DateValue) |
weekDay | Custom weekday name (receives day string) |
Props
| Prop | Type | Default |
|---|---|---|
value | DateValue | DateValue[] | - |
type | 'single' | 'multiple' | 'single' |
range | boolean | false |
color | ColorType | 'primary' |
size | 'xs'|'sm'|'md'|'lg'|'xl' | 'md' |
variant | 'solid'|'outline'|'soft'|'subtle' | 'solid' |
numberOfMonths | number | 1 |
minValue | DateValue | - |
maxValue | DateValue | - |
isDateDisabled | DateMatcher | - |
fixedWeeks | boolean | true |
weekNumbers | boolean | false |
weekStartsOn | 0-6 | 0 |
locale | string | 'en' |
monthControls | boolean | true |
yearControls | boolean | true |
disabled | boolean | false |
readonly | boolean | false |
ref | HTMLElement | null | null |
class | string | - |
ui | Record<Slot, Class> | - |