cnc-calendar
A month grid that doubles as a date input: click a day to select it, navigate by month, and lay events over the cells. It reports four distinct signals — a day chosen, an event activated, a collapsed day expanded, and a range dragged — and submits the selected date as an ordinary form field.
Quick start
With no month pinned it opens on today. Click a day to select it, and click the same day again to clear the selection.
<div x-data="{ day: '' }">
<cnc-calendar
name="date"
$value="day"
></cnc-calendar>
</div>
The event shape
Events are matched to cells by an exact date string, so a day carries an event when
the two spell the same YYYY-MM-DD.
| Field | Required | Purpose |
|---|---|---|
| date | yes | YYYY-MM-DD; the cell it lands in. |
| name | yes | The label shown in the cell. |
| time | no | Free text beside the name — "9:30 AM", "All Day". |
| url | no | Renders the event as a link that navigates. A linked event never emits event-select. |
<cnc-calendar
start-month="2026-08"
events='[
{"name":"Sprint Planning","time":"11 AM","date":"2026-08-15"},
{"name":"Launch Day","time":"All Day","date":"2026-08-22"},
{"name":"Release notes","date":"2026-08-22","url":"/notes"}
]'
></cnc-calendar>
Usage guidance
Use the full calendar when the month itself carries meaning — when what is already booked
on nearby days should inform the choice. For a date field where surrounding days are irrelevant,
cnc-calendar-compact
is the picker-sized variant and costs far less room. Keep
max-events
matched to your cell height rather than raising it to fit a busy day: the "+N more" is the
designed answer to a crowded cell, and a row that reflows is worse than one that summarises.