A lightweight, feature-rich calendar component for Alpine.js. Inline & popup display, range selection, date constraints, input masking, and CSS custom property theming.
Single date, range, and multiple selection — all inline with zero config.
<div x-data="calendar({ mode: 'single' })"></div>
<div x-data="calendar({ mode: 'range' })"></div>
<div x-data="calendar({ mode: 'multiple' })"></div>
firstDay: 0.<div x-data="calendar({ mode: 'single', firstDay: 0 })"></div>
<div x-data="calendar({ mode: 'range', months: 2 })"></div>
Bind to an input with auto-masking. Calendar opens on focus, closes on outside click.
<div x-data="calendar({ mode: 'single', display: 'popup' })">
<input x-ref="rc-input" type="text" class="rc-input"
placeholder="Pick a date...">
</div>
<div x-data="calendar({
mode: 'range',
months: 3,
display: 'popup'})">
<input x-ref="rc-input" type="text" class="rc-input"
placeholder="Check-in — Check-out">
</div>
Pre-select dates via config or change them dynamically with setValue() and clear().
<div x-data="calendar({
mode: 'single',
value: '2026-03-15'
})"></div>
<div x-data="calendar({ mode: 'single' })" x-ref="cal"></div>
<button @click="$refs.cal.setValue('2026-06-15')">Set June 15</button>
<button @click="$refs.cal.setValue('2026-12-25')">Set Dec 25</button>
<button @click="$refs.cal.clear()">Clear</button>
<div x-data="calendar({
mode: 'range',
value: '2026-03-10 - 2026-03-20'
})"></div>
<form @submit.prevent="handleSubmit">
<div x-data="calendar({
mode: 'single',
name: 'appointment'
})"></div>
<button type="submit">Submit</button>
</form>
Restrict selection with min/max dates, disabled weekdays, specific dates, and range limits.
<div x-data="calendar({
mode: 'single',
minDate: '2026-02-01',
maxDate: '2026-04-30',
disabledDaysOfWeek: [0, 6],
})"></div>
<div x-data="calendar({
mode: 'single',
disabledDaysOfWeek: [0, 6],
enabledDates: ['2026-03-07', '2026-03-08'],
disabledDates: ['2026-03-09', '2026-03-10', '2026-03-11'],
})"></div>
<div x-data="calendar({
mode: 'range',
minRange: 3,
maxRange: 10,
})"></div>
Apply different constraint rules for specific date periods — perfect for seasonal booking systems.
<div x-data="calendar({
mode: 'range',
months: 2,
minRange: 2,
maxRange: 14,
disabledDaysOfWeek: [0],
rules: [
{
from: '2026-06-01', to: '2026-08-31',
minRange: 7, maxRange: 21,
disabledDaysOfWeek: [],
},
{
from: '2026-12-20', to: '2027-01-05',
minRange: 3, maxRange: 7,
enabledDaysOfWeek: [1, 2, 3, 4, 5, 6, 0],
}
],
})"></div>
Step-by-step date selection: Year → Month → Day. Great for birth dates and historical dates.
<div x-data="calendar({
mode: 'single',
wizard: true})"></div>
<div x-data="calendar({
mode: 'single',
wizard: 'year-month'})"></div>
<div x-data="calendar({
mode: 'single',
wizard: 'month-day'})"></div>
<div x-data="calendar({
mode: 'single',
wizard: true,
display: 'popup'})">
<input x-ref="rc-input" type="text" class="rc-input"
placeholder="Birth date...">
</div>
Attach labels, pricing, availability, and custom colors to individual dates. Uses a static map or dynamic callback.
<div x-data="calendar({
mode: 'single',
dateMetadata: {
'2026-03-01': { label: '$120', availability: 'available' },
'2026-03-03': { label: '$150', availability: 'available', color: '#16a34a' },
'2026-03-05': { label: '$180', availability: 'available', color: '#ea580c' },
'2026-03-06': { availability: 'unavailable' },
'2026-03-07': { label: 'Sold', availability: 'unavailable' },
'2026-03-09': { label: '$99', availability: 'available', color: '#2563eb' },
}
})"></div>
<div x-data="calendar({
mode: 'range',
dateMetadata: (date) => {
const d = date.toNativeDate().getDay()
if (d === 0 || d === 6)
return { availability: 'unavailable' }
return {
label: '$' + (100 + date.day * 3),
availability: 'available'
}
}
})"></div>
Display 3+ months in a scrollable container. Great for long-range booking flows.
<div x-data="calendar({
mode: 'single',
months: 3})"></div>
<div x-data="calendar({
mode: 'range',
months: 12,
scrollHeight: 400
})"></div>
Fully customizable via CSS custom properties. Override any --color-calendar-* variable.
.dark-calendar {
--color-calendar-bg: #1e293b;
--color-calendar-text: #f1f5f9;
--color-calendar-border: #334155;
--color-calendar-hover: #334155;
--color-calendar-primary: #818cf8;
--color-calendar-primary-text: #1e293b;
--color-calendar-today-ring: #818cf8;
--color-calendar-range: #312e81;
}
.green-theme {
--color-calendar-primary: #059669;
--color-calendar-primary-text: #ffffff;
--color-calendar-today-ring: #34d399;
--color-calendar-range: #ecfdf5;
}