'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var reactDom = require('react-dom'); var index_cjs = require('@fullcalendar/core/index.cjs'); var internal_cjs = require('@fullcalendar/core/internal.cjs'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); const reactMajorVersion = parseInt(String(React__default["default"].version).split('.')[0]); const syncRenderingByDefault = reactMajorVersion < 18; class FullCalendar extends React.Component { constructor() { super(...arguments); this.elRef = React.createRef(); this.isUpdating = false; this.isUnmounting = false; this.state = { customRenderingMap: new Map() }; this.requestResize = () => { if (!this.isUnmounting) { this.cancelResize(); this.resizeId = requestAnimationFrame(() => { this.doResize(); }); } }; } render() { const customRenderingNodes = []; for (const customRendering of this.state.customRenderingMap.values()) { customRenderingNodes.push(React__default["default"].createElement(CustomRenderingComponent, { key: customRendering.id, customRendering: customRendering })); } return (React__default["default"].createElement("div", { ref: this.elRef }, customRenderingNodes)); } componentDidMount() { // reset b/c react strict-mode calls componentWillUnmount/componentDidMount this.isUnmounting = false; const customRenderingStore = new internal_cjs.CustomRenderingStore(); this.handleCustomRendering = customRenderingStore.handle.bind(customRenderingStore); this.calendar = new index_cjs.Calendar(this.elRef.current, Object.assign(Object.assign({}, this.props), { handleCustomRendering: this.handleCustomRendering })); this.calendar.render(); // attaching with .on() will cause this to fire AFTER internal preact rendering did flushSync this.calendar.on('_beforeprint', () => { reactDom.flushSync(() => { // our `customRenderingMap` state will be flushed at this point }); }); let lastRequestTimestamp; customRenderingStore.subscribe((customRenderingMap) => { const requestTimestamp = Date.now(); const isMounting = !lastRequestTimestamp; const runFunc = ( // don't call flushSync if React version already does sync rendering by default // guards against fatal errors: // https://github.com/fullcalendar/fullcalendar/issues/7448 syncRenderingByDefault || // isMounting || this.isUpdating || this.isUnmounting || (requestTimestamp - lastRequestTimestamp) < 100 // rerendering frequently ) ? runNow // either sync rendering (first-time or React 16/17) or async (React 18) : reactDom.flushSync; // guaranteed sync rendering runFunc(() => { this.setState({ customRenderingMap }, () => { lastRequestTimestamp = requestTimestamp; if (isMounting) { this.doResize(); } else { this.requestResize(); } }); }); }); } componentDidUpdate() { this.isUpdating = true; this.calendar.resetOptions(Object.assign(Object.assign({}, this.props), { handleCustomRendering: this.handleCustomRendering })); this.isUpdating = false; } componentWillUnmount() { this.isUnmounting = true; this.cancelResize(); this.calendar.destroy(); } doResize() { this.calendar.updateSize(); } cancelResize() { if (this.resizeId !== undefined) { cancelAnimationFrame(this.resizeId); this.resizeId = undefined; } } getApi() { return this.calendar; } } FullCalendar.act = runNow; // DEPRECATED. Not leveraged anymore class CustomRenderingComponent extends React.PureComponent { render() { const { customRendering } = this.props; const { generatorMeta } = customRendering; const vnode = typeof generatorMeta === 'function' ? generatorMeta(customRendering.renderProps) : generatorMeta; return reactDom.createPortal(vnode, customRendering.containerEl); } } // Util // ------------------------------------------------------------------------------------------------- function runNow(f) { f(); } exports["default"] = FullCalendar;