Date Picker

A date picker built from Popover and Calendar, with optional range and presets.

Loading preview…

Installation

Usage

Date picker composes Popover, Calendar, Button, and Label. Install those primitives (and range-calendar when you need ranges), then use or adapt this example.

1<script lang="ts">
2	import DatePicker from '~/components/datepicker/datepicker.svelte';
3</script>
4
5<DatePicker label="Date of birth" />

Custom composition:

1<script lang="ts">
2	import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
3	import { getLocalTimeZone, today, type CalendarDate } from '@internationalized/date';
4	import Button from '~/components/button/button.svelte';
5	import { Calendar } from '~/components/calendar';
6	import { Label } from '~/components/label';
7	import * as Popover from '~/components/popover';
8
9	let open = $state(false);
10	let value = $state<CalendarDate | undefined>();
11</script>
12
13<div class="flex flex-col gap-3">
14	<Label for="date">Date of birth</Label>
15	<Popover.Root bind:open>
16		<Popover.Trigger id="date">
17			{#snippet child({ props })}
18				<Button {...props} variant="outline" class="w-48 justify-between font-normal">
19					{value ? value.toDate(getLocalTimeZone()).toLocaleDateString() : 'Select date'}
20					<ChevronDownIcon />
21				</Button>
22			{/snippet}
23		</Popover.Trigger>
24		<Popover.Content class="w-auto overflow-hidden p-0" align="start">
25			<Calendar
26				type="single"
27				bind:value
28				captionLayout="dropdown"
29				onValueChange={() => {
30					open = false;
31				}}
32				maxValue={today(getLocalTimeZone())}
33			/>
34		</Popover.Content>
35	</Popover.Root>
36</div>