@brinda_yawa/easycal
v1.0.17
Published
A lightweight, zero-dependency JavaScript calendar library
Readme
@brinda_yawa/easycal
A lightweight, zero-dependency JavaScript calendar library with:
mode: 'standard'formonth,week, anddayviewsmode: 'timeline'forresourceTimelineDay,resourceTimelineWeek, andresourceTimelineMonth- Built-in event form logic that can now be fully customized
Installation
npm install @brinda_yawa/easycalQuick start
import EasyCal from '@brinda_yawa/easycal';
import '@brinda_yawa/easycal/style.css';
const cal = new EasyCal('#calendar', {
mode: 'standard',
defaultView: 'month',
events: []
});Event Form Customization
Use eventFormRenderer to override create/edit form UI while keeping EasyCal's internal create/update/delete logic:
const cal = new EasyCal('#calendar', {
mode: 'timeline',
defaultView: 'resourceTimelineWeek',
eventFormRenderer: (context) => {
return `
<form data-ec-form>
<h3>${context.mode === 'edit' ? 'Edit event' : 'Create event'}</h3>
<input name="title" value="${context.event?.title || ''}" placeholder="Title" required />
<input name="start" type="datetime-local" required />
<input name="end" type="datetime-local" required />
<select name="resourceId"></select>
<p class="ec-popup-error" hidden></p>
<button type="button" data-ec-action="cancel">Cancel</button>
${context.mode === 'edit' ? '<button type="button" data-ec-action="delete">Delete</button>' : ''}
<button type="submit" data-ec-action="${context.mode === 'edit' ? 'update' : 'save'}">
${context.mode === 'edit' ? 'Update' : 'Save'}
</button>
</form>
`;
}
});Context Object Explained
eventFormRenderer receives:
{
mode: 'create' | 'edit',
event?: EventObject,
date?: Date,
resourceId?: string,
save: (data?) => void,
update: (data?) => void,
delete: () => void,
close: () => void,
}Behavior:
dateClickopens create mode with prefilleddateandresourceId.eventClickopens edit mode with the selectedevent.resourceIdis normalized and passed in standard/timeline payloads.- Internal event lifecycle stays centralized in EasyCal (
addEvent,updateEvent,removeEvent).
Event hooks
All hooks are supported and normalized:
dateClick(info)(alias:onDateClick)eventClick(info)(alias:onEventClick)eventDrop(info)(alias:eventDrag)onDateChange(info)
Resource Basics
Resources work out of the box with a minimal structure:
const cal = new EasyCal('#calendar', {
mode: 'timeline',
defaultView: 'resourceTimelineDay',
resources: [
{ id: 'room-a', title: 'Room A' },
{ id: 'room-b', title: 'Room B' }
]
});Custom Resource Structure
Resources are fully flexible. You can pass any shape (including nested children) as long as each resource resolves to a stable id.
const resources = [
{ id: 'a', label: 'Room A', icon: '🏢', description: 'Main hall' },
{ id: 'b', name: 'Room B', capacity: 50, type: 'conference' },
{
id: 'c',
name: 'Floor C',
children: [
{ id: 'c1', name: 'Room C1', capacity: 16 }
]
}
];resourceRenderer
Use resourceRenderer to fully control each resource row cell:
const cal = new EasyCal('#calendar', {
mode: 'timeline',
defaultView: 'resourceTimelineWeek',
resources,
resourceRenderer: (resource) => {
return `
<div class="my-resource">
<span>${resource.icon || ''}</span>
<strong>${resource.label || resource.title || resource.name}</strong>
<small>${resource.description || ''}</small>
</div>
`;
}
});resourceRenderer supports returning either:
string(HTML string)HTMLElement
Best practices
- Keep resource ids stable across renders (
resourceIdmatching depends on this). - Keep custom renderers lightweight.
- Use
resourceFieldMapfor API adaptation. - In custom forms, prefer
data-ec-form+data-ec-actionto reuse built-in validation + persistence.
API
cal.addEvent(event)
cal.removeEvent(id)
cal.updateEvent(id, patch)
cal.getEvents()
cal.changeView(viewName)
cal.next()
cal.prev()
cal.today()
cal.destroy()License
MIT
