fullcalendar
Version:
FullCalendar Vanilla JS package for rendering a calendar
145 lines (142 loc) • 5.51 kB
JavaScript
import { jsx } from 'preact/jsx-runtime';
import { flushSync } from 'preact/compat';
import { createRoot } from 'preact/compat/client';
import { C as CalendarApiImpl, a as CalendarMediaRoot, c as computeRootClassName, b as CalendarInner, d as CalendarDataManager } from './29a5fccb.js';
import { g as guid } from './2add5508.js';
import { R as RenderId, D as DelayedRunner } from './66c53e04.js';
import { a as applyStyleProp } from './56f74c4a.js';
import { Fragment } from 'preact';
/*
Vanilla JS API
*/
class Calendar extends CalendarApiImpl {
constructor(el, optionOverrides = {}) {
super();
this.baseId = `fc:${guid()}:`;
this.isRendering = false;
this.isRendered = false;
this.customContentRenderId = 0;
this.currentClassName = '';
this.currentColorScheme = '';
this.handleDataChange = (data, actions) => {
this.currentData = data;
let renderImmediate = false;
for (const action of actions) {
if (action.type === 'SET_EVENT_DRAG' ||
action.type === 'UNSET_EVENT_DRAG' ||
action.type === 'SET_EVENT_RESIZE' ||
action.type === 'UNSET_EVENT_RESIZE' ||
// could happen as a result of a drag or resize and must be part of same sync pipeline
action.type === 'MERGE_EVENTS') {
renderImmediate = true;
break;
}
}
this.renderRunner.request(renderImmediate ? undefined : data.calendarOptions.rerenderDelay);
};
this.handleRenderRequest = () => {
if (this.isRendering) {
let { currentData } = this;
this.isRendered = true;
flushSync(() => {
this.vdomRoot.render(jsx(Fragment, { children: jsx(RenderId.Provider, { value: this.customContentRenderId, children: jsx(CalendarMediaRoot, { emitter: currentData.emitter, children: (forPrint) => {
const options = currentData.calendarOptions;
const isRtl = options.direction === 'rtl';
const className = computeRootClassName(options, forPrint);
this.setIsRtl(isRtl);
this.setClassName(className);
this.setHeight(options.height);
this.setColorScheme(options.colorScheme || '');
return (jsx(CalendarInner, { ...currentData, forPrint: forPrint, baseId: this.baseId }));
} }) }) }));
});
}
else if (this.isRendered) {
this.isRendered = false;
this.vdomRoot.unmount();
this.setIsRtl(false);
this.setClassName('');
this.setHeight('');
this.setColorScheme('');
}
};
this.el = el;
this.vdomRoot = createRoot(el);
this.renderRunner = new DelayedRunner(this.handleRenderRequest);
this.dataManager = new CalendarDataManager({
calendarApi: this,
onDataChange: this.handleDataChange,
});
this.currentData = this.dataManager.update(optionOverrides);
}
render() {
let wasRendering = this.isRendering;
if (!wasRendering) {
this.isRendering = true;
}
else {
this.customContentRenderId += 1;
}
this.renderRunner.request();
}
destroy() {
if (this.isRendering) {
this.isRendering = false;
this.renderRunner.request();
}
this.dataManager.destroy();
}
batchRendering(func) {
this.renderRunner.pause('batchRendering');
func();
this.renderRunner.resume('batchRendering');
}
pauseRendering() {
this.renderRunner.pause('pauseRendering');
}
resumeRendering() {
this.renderRunner.resume('pauseRendering', true);
}
resetOptions(optionOverrides, changedOptionNames) {
this.currentDataManager.resetOptions(optionOverrides, changedOptionNames);
}
setClassName(className) {
if (className !== this.currentClassName) {
let { classList } = this.el;
for (let singleClassName of this.currentClassName.split(' ')) {
if (singleClassName) {
classList.remove(singleClassName);
}
}
for (let singleClassName of className.split(' ')) {
if (singleClassName) {
classList.add(singleClassName);
}
}
this.currentClassName = className;
}
}
setHeight(height) {
applyStyleProp(this.el, 'height', height);
}
setColorScheme(colorScheme) {
if (colorScheme !== this.currentColorScheme) {
if (colorScheme) {
this.el.dataset.colorScheme = colorScheme;
}
else {
delete this.el.dataset.colorScheme;
}
this.currentColorScheme = colorScheme;
}
}
setIsRtl(isRtl) {
if (isRtl) {
this.el.dir = 'rtl';
}
else {
this.el.removeAttribute('dir');
}
}
}
export { Calendar as C };