Skip to content

Components

Learn how to customize individual calendar components.

Customize the calendar header appearance and behavior using className props or replace it entirely with a custom component.

Use the headerClassName prop to apply custom styles to the calendar header:

<IlamyCalendar
headerClassName="bg-blue-50 border-blue-200 text-blue-900"
// ... other props
/>

For complete control, you can replace the default header with your own element. It renders inside the calendar, so it can read and drive the calendar through useIlamyCalendarContext:

import { useIlamyCalendarContext } from '@ilamy/calendar';
const CustomHeader = () => {
const { currentDate, prevPeriod, nextPeriod } = useIlamyCalendarContext();
return (
<div className="flex items-center justify-between p-4 bg-gradient-to-r from-blue-500 to-purple-600">
<button onClick={prevPeriod}>← Previous</button>
<h2 className="text-white font-bold">{currentDate.format('MMMM YYYY')}</h2>
<button onClick={nextPeriod}>Next →</button>
</div>
);
};
<IlamyCalendar
headerComponent={<CustomHeader />}
// ... other props
/>

To drive the calendar from a toolbar you render yourself, outside the calendar, pass a ref instead; see Controlling the calendar from outside.

Customize the day headers (Mon, Tue, Wed, etc.) that appear at the top of the calendar grid.

To change the text of the day headers rather than their style, use dayHeaderFormat; see Formatting times and dates.

<IlamyCalendar
viewHeaderClassName="bg-gray-100 text-gray-700 font-semibold py-3"
// ... other props
/>

You can also pass a custom component to completely replace the view headers for advanced styling and functionality.

Create custom event renderers to control how events appear within calendar cells using the renderEvent prop.

const renderEvent = (event) => (
<div className={`
rounded-md p-2 text-sm font-medium
${event.priority === 'high' ? 'bg-red-100 text-red-800 border-l-4 border-red-500' :
event.priority === 'medium' ? 'bg-yellow-100 text-yellow-800 border-l-4 border-yellow-500' :
'bg-blue-100 text-blue-800 border-l-4 border-blue-500'}
`}>
<div className="flex items-center gap-2">
{event.priority === 'high' && <span>🔥</span>}
<span className="truncate">{event.title}</span>
</div>
{event.description && (
<p className="text-xs opacity-75 mt-1 truncate">{event.description}</p>
)}
</div>
);
<IlamyCalendar
renderEvent={renderEvent}
events={events}
// ... other props
/>

renderEvent receives the event and a segment. The event includes:

  • title - Event title
  • start - Start date/time
  • end - End date/time (exclusive)
  • color - Event color/theme
  • allDay - Whether it’s an all-day event
  • data - Any custom properties you include in your event data

segment is { isStart, isEnd }. An event too long for its row is drawn as one bar per row, and these say whether this bar holds the event’s real start or end, so you can square the cut edges. See Drawing a cut event. Your own markup does not keep its title in view while the bar is partly scrolled out; see Keeping the title in view.

When a day cell holds more events than dayMaxEvents (default 4), the calendar renders a “+N more” indicator. Clicking it opens the built-in all-events dialog. Provide onMoreEventsClick to replace that dialog with your own UI:

<IlamyCalendar
events={events}
dayMaxEvents={3}
onMoreEventsClick={(day, events) => {
// day: the cell's day (Dayjs); events: all events for that day
openDayDrawer(day, events);
}}
/>

When the callback is provided, the built-in dialog never opens. Omit it to keep the default behavior.