ui · 6 variants · 1 categories
Calendar
Date display — month grid, agenda, year heatmap, range selection.
npx "@rueda.dev/gems-diamond" add calendar Display
6 variantsApril 2026
S
M
T
W
T
F
S
monthApril 2026
M
T
W
T
F
S
S
minimalApril 2026
S
M
T
W
T
F
S
weekagendayearApril 2026
S
M
T
W
T
F
S
rangeUsage Guide
How to wire up this component in your app — props, callbacks, customization, and the conventions Diamond shares across the library.
Click handlers
By default, every cell is rendered as a real <button> but nothing happens on click. Pass any of these to react:
| Prop | Type | Description |
|---|---|---|
onDayClick | (date, event) => void | Fires on every day cell click. Receives the JS Date and the React mouse event. |
onSelect | (date) => void | Convenience alias that also fires on day click. Use whichever reads better in your code. Both fire together if both are provided. |
onMonthClick | (monthIndex, event) => void | Fires when a month tile is clicked in the year variant. |
onAgendaItemClick | (item, index, event) => void | Fires when an agenda row is clicked in the agenda variant. |
onPrevMonth / onNextMonth | () => void | Header chevrons only render when these are provided. The component never mutates `month` on its own. |
Open a modal on day click
<Calendar
variant="month"
events={events}
onDayClick={(date) => {
setModalDate(date);
setModalOpen(true);
}}
/>Custom rendering
For total control of what each cell looks like, pass a render override. You still get the default classes and click handler — combine them with whatever extra UI you want.
| Prop | Type | Description |
|---|---|---|
renderDay | (info) => ReactNode | info has date, muted, isToday, isSelected, inRange, event, defaultClassName, and handleClick. |
renderMonth | (info) => ReactNode | For the year grid. Receives index, name, isCurrent, isHighlighted, defaultClassName. |
renderAgendaItem | (info) => ReactNode | For agenda rows. Receives item, index, defaultClassName. |
<Calendar
variant="month"
renderDay={({ date, defaultClassName, event }) => (
<button
type="button"
className={defaultClassName + " relative"}
onClick={() => openDetails(date)}
>
{date.getDate()}
{event && (
<span className="absolute bottom-1 size-1 rounded-full bg-rose-500" />
)}
</button>
)}
/>Events and ranges
eventsaccepts an array of{ date, label?, color?, meta? }. Days with an event get a tinted background;coloroverrides the accent for that day.rangeis purely visual highlight:{ start, end }. You manage range selection in your own state.selectedhighlights one cell. The component never sets state itself — keep your ownuseStateand update it fromonDayClick.weekStartsOn(0=Sun, 1=Mon) andweekdays(custom 7-string array) control the header row.
Universal patterns
Every Diamond component shares the same prop conventions, so once you learn one you can predict the others.
variant— discriminated union of every visual option. Categories shown above are docs-only metadata; the prop is a flat string union.accent— any CSS color string. Overrides--diamond-accentjust for that instance via inlinestyle. Cascades into hover, ring, and selection states.asChild(when present) — renders the underlying primitive via@radix-ui/react-slot, letting you compose with<Link>,motion.button, etc.className— merged with internal Tailwind classes viacn(). Use it to override layout, spacing, or colors.- Native HTML attributes (
onClick,aria-*,data-*,ref, etc.) flow through to the root element without any whitelist. - Diamond is the skin: zero domain state, zero fetch, zero providers. You wire data and reactions in your app code; the components just render and emit events.