UNPKG

light-datepicker

Version:
94 lines (81 loc) 2.94 kB
import { createNode } from './util'; import { nextMonth, prevMonth, startMonth, datesInMonth, isSame } from './date'; const MAXIMUM_NUMBER_OF_DAYS = 42; export class Calendar { constructor(weekdays) { this.decorators = []; this.listeners = []; this.container = createNode('div', 'calendar', null); this.nodes = new Array(MAXIMUM_NUMBER_OF_DAYS); this.weekdays = weekdays; this.render(); } render() { let container = this.container; let nodes = this.nodes; this.weekdays.forEach(weekday => container.appendChild(createNode('span', 'weekday', weekday))); let fragment = document.createDocumentFragment(); // TODO: Evited assign and use immutability for (let i = 0; i < MAXIMUM_NUMBER_OF_DAYS; i++) { nodes[i] = this.createDateNode(); fragment.appendChild(nodes[i]); } container.appendChild(fragment); } createDateNode() { let node = createNode('span', ''); node.addEventListener('click', (event) => this.emit('clickDate', node)); node.addEventListener('mouseover', (event) => this.emit('hoverDate', node)); return node; } on(eventName, callback) { this.container.addEventListener(eventName, callback); } emit(eventName, node) { if (!node.classList.contains('disabled')) { const event = new CustomEvent(eventName, { detail: node.date }); this.container.dispatchEvent(event); } } addDecorator(filter, className) { this.decorators.push({filter: filter, className: className}); } applyDecorators() { this.nodes.forEach(node => { this.decorators.some(decorator => { if (decorator.filter(node.date)) { node.classList.add(decorator.className); } else { node.classList.remove(decorator.className); } }); }); } datesOfCalendar(date) { let month = datesInMonth(date); let leftPadding = startMonth(date).getDay() || 7; let paddingLeftItems = datesInMonth(prevMonth(date)) .reverse() .slice(0, leftPadding) .reverse(); let paddingRightItems = datesInMonth(nextMonth(date)) .slice(0, 42 - leftPadding - month.length); return [...paddingLeftItems, ...month, ...paddingRightItems]; } draw(date) { let dates = this.datesOfCalendar(date); // TODO: Evited assign and use immutability this.nodes.forEach((node, index) => { node.date = dates[index]; node.innerText = dates[index].getDate(); }); this.applyDecorators(); return this.container; } }