Schema Definition
Schema definition for the Calendar node type:
{
calendar: {
group: 'block',
attrs: {
view: { default: 'month' },
date: { default: null }
},
}
}Model Representation
Example model representation:
{
type: 'calendar',
attrs: {
view: 'month',
date: '2024-01-01'
}
}HTML Serialization
Converting model to HTML:
function serializeCalendar(node) {
return '<div data-type="calendar" data-view="' + node.attrs.view +
'" data-date="' + (node.attrs.date || '') + '"></div>';
}HTML Deserialization
Parsing HTML to model:
function parseCalendar(domNode) {
return {
type: 'calendar',
attrs: {
view: domNode.getAttribute('data-view') || 'month',
date: domNode.getAttribute('data-date') || null
}
};
}View Integration
View Integration Notes: Pay special attention to contenteditable behavior, selection handling, and event management when implementing this node type in your view layer.
View integration code:
// Rendering calendar
const calendar = document.createElement('div');
calendar.setAttribute('data-type', 'calendar');
calendar.setAttribute('data-view', node.attrs.view);
if (node.attrs.date) calendar.setAttribute('data-date', node.attrs.date);
calendar.contentEditable = 'false'; // Calendars are typically renderedCommon Issues
Common Pitfalls: These are issues frequently encountered when implementing this node type. Review carefully before implementation.
Common issues and solutions:
// Issue: Calendar date format
// Solution: Use ISO date format
function formatCalendarDate(date) {
return date.toISOString().split('T')[0];
}
// Issue: Calendar view switching
// Solution: Handle view state
function switchCalendarView(calendar, view) {
calendar.setAttribute('data-view', view);
renderCalendar(calendar);
}Implementation
Complete implementation example:
class CalendarNode {
constructor(attrs) {
this.type = 'calendar';
this.attrs = {
view: attrs?.view || 'month',
date: attrs?.date || null
};
}
toDOM() {
const calendar = document.createElement('div');
calendar.setAttribute('data-type', 'calendar');
calendar.setAttribute('data-view', this.attrs.view);
if (this.attrs.date) calendar.setAttribute('data-date', this.attrs.date);
return calendar;
}
static fromDOM(domNode) {
return new CalendarNode({
view: domNode.getAttribute('data-view') || 'month',
date: domNode.getAttribute('data-date') || null
});
}
}