캘린더 노드 타입

카테고리: 커스텀 • 뷰 연동 노트를 포함한 상세 구현 가이드

스키마 정의

캘린더 노드 타입의 스키마 정의:

{
  calendar: {
    group: 'block',
    attrs: {
      view: { default: 'month' },
      date: { default: null }
    },
  }
}

모델 표현

모델 표현 예제:

{
  type: 'calendar',
  attrs: {
    view: 'month',
    date: '2024-01-01'
  }
}

HTML 직렬화

모델을 HTML로 변환:

function serializeCalendar(node) {
  return '<div data-type="calendar" data-view="' + node.attrs.view + 
         '" data-date="' + (node.attrs.date || '') + '"></div>';
}

HTML 역직렬화

HTML을 모델로 파싱:

function parseCalendar(domNode) {
  return {
    type: 'calendar',
    attrs: {
      view: domNode.getAttribute('data-view') || 'month',
      date: domNode.getAttribute('data-date') || null
    }
  };
}

뷰 연동

뷰 연동 노트: 이 노드 타입을 뷰 레이어에서 구현할 때 contenteditable 동작, 선택 처리, 이벤트 관리에 특히 주의하세요.

뷰 연동 코드:

// 캘린더 렌더링
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'; // 캘린더는 일반적으로 렌더링됨

일반적인 문제

일반적인 함정: 이 노드 타입을 구현할 때 자주 발생하는 문제들입니다. 구현 전에 주의 깊게 검토하세요.

일반적인 문제 및 해결 방법:

// 문제: 캘린더 날짜 형식
// 해결: ISO 날짜 형식 사용
function formatCalendarDate(date) {
  return date.toISOString().split('T')[0];
}

// 문제: 캘린더 뷰 전환
// 해결: 뷰 상태 처리
function switchCalendarView(calendar, view) {
  calendar.setAttribute('data-view', view);
  renderCalendar(calendar);
}

구현

완전한 구현 예제:

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
    });
  }
}