Range Calendar
Kalender pemilihan rentang tanggal dengan pemilihan mulai/akhir, preview hover, dan navigasi keyboard.
bun x bosia@latest add range-calendarKalender komposabel untuk memilih rentang tanggal. Dibangun di atas komponen calendar — memakai ulang CalendarHeader untuk navigasi. Date JS native, tanpa dependensi eksternal.
Preview
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
Props
RangeCalendar
| Prop | Type | Default |
|---|---|---|
value |
{ start?: Date; end?: Date } |
{ start: undefined, end: undefined } |
month |
Date | undefined |
undefined |
min |
Date | undefined |
undefined |
max |
Date | undefined |
undefined |
disabled |
((date: Date) => boolean) | undefined |
undefined |
weekStartsOn |
0 | 1 | 2 | 3 | 4 | 5 | 6 |
0 |
fixedWeeks |
boolean |
false |
value— objek rentang bindable dengan tanggalstartdanendmonth— bulan tampil terkontrol yang bindablemin/max— tanggal paling awal/akhir yang bisa dipilihdisabled— fungsi kustom untuk menonaktifkan tanggal tertentuweekStartsOn— hari pertama dalam pekan (0= Minggu,1= Senin, dst.)fixedWeeks— selalu merender 6 baris (42 sel)
Sub-komponen
RangeCalendar— wrapper root, menyimpan state rentang dan menyediakan konteks gandaRangeCalendarHeader—CalendarHeaderyang di-re-export dengan prev/next dan select bulan/tahunRangeCalendarGrid—<table>dengan header hari-dalam-pekan dan sel tanggal sadar-rentangRangeCalendarDay— tombol hari individual dengan styling rentang (dipakai internal olehRangeCalendarGrid)
Perilaku Pemilihan
- Klik — menyetel tanggal mulai
- Klik lagi (pada atau setelah mulai) — menyetel tanggal akhir
- Klik sebelum mulai — mereset dan menyetel mulai baru
- Klik saat keduanya terset — mereset rentang, menyetel mulai baru
Selama memilih (mulai terset, belum ada akhir), hover menampilkan rentang preview dengan styling lebih terang.
Penggunaan
<script lang="ts">
import { RangeCalendar, RangeCalendarGrid } from "$lib/components/ui/range-calendar";
import { CalendarHeader } from "$lib/components/ui/calendar";
let value = $state<{ start?: Date; end?: Date }>({ start: undefined, end: undefined });
</script>
<RangeCalendar bind:value class="rounded-md border">
<CalendarHeader />
<RangeCalendarGrid />
</RangeCalendar>Batasan Min / Max
<RangeCalendar
bind:value
min={new Date(2026, 0, 1)}
max={new Date(2026, 11, 31)}
class="rounded-md border"
>
<CalendarHeader />
<RangeCalendarGrid />
</RangeCalendar>Nonaktifkan Akhir Pekan
<RangeCalendar
bind:value
disabled={(date) => date.getDay() === 0 || date.getDay() === 6}
class="rounded-md border"
>
<CalendarHeader />
<RangeCalendarGrid />
</RangeCalendar>Navigasi Keyboard
| Tombol | Aksi |
|---|---|
ArrowLeft / ArrowRight |
Hari sebelumnya / berikutnya |
ArrowUp / ArrowDown |
Pekan sebelumnya / berikutnya |
Home / End |
Hari pertama / terakhir dalam pekan |
PageUp / PageDown |
Bulan sebelumnya / berikutnya |
Enter / Space |
Pilih hari yang difokuskan |