| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import { defineComponent, h, Fragment, Teleport } from 'vue';
- import { Calendar } from '@fullcalendar/core';
- import { CustomRenderingStore } from '@fullcalendar/core/internal';
- import { OPTION_IS_COMPLEX } from './options.js';
- const FullCalendar = defineComponent({
- props: {
- options: Object
- },
- data() {
- return {
- renderId: 0,
- customRenderingMap: new Map()
- };
- },
- methods: {
- getApi() {
- return getSecret(this).calendar;
- },
- buildOptions(suppliedOptions) {
- return {
- ...suppliedOptions,
- customRenderingMetaMap: kebabToCamelKeys(this.$slots),
- handleCustomRendering: getSecret(this).handleCustomRendering,
- };
- },
- },
- render() {
- const customRenderingNodes = [];
- for (const customRendering of this.customRenderingMap.values()) {
- customRenderingNodes.push(h(CustomRenderingComponent, {
- key: customRendering.id,
- customRendering,
- }));
- }
- return h('div', {
- // when renderId is changed, Vue will trigger a real-DOM async rerender, calling beforeUpdate/updated
- attrs: { 'data-fc-render-id': this.renderId }
- }, h(Fragment, customRenderingNodes)); // for containing CustomRendering keys
- },
- mounted() {
- const customRenderingStore = new CustomRenderingStore();
- getSecret(this).handleCustomRendering = customRenderingStore.handle.bind(customRenderingStore);
- const calendarOptions = this.buildOptions(this.options);
- const calendar = new Calendar(this.$el, calendarOptions);
- getSecret(this).calendar = calendar;
- calendar.render();
- customRenderingStore.subscribe((customRenderingMap) => {
- this.customRenderingMap = customRenderingMap; // likely same reference, so won't rerender
- this.renderId++; // force rerender
- getSecret(this).needCustomRenderingResize = true;
- });
- },
- beforeUpdate() {
- this.getApi().resumeRendering(); // the watcher handlers paused it
- },
- updated() {
- if (getSecret(this).needCustomRenderingResize) {
- getSecret(this).needCustomRenderingResize = false;
- this.getApi().updateSize();
- }
- },
- beforeUnmount() {
- this.getApi().destroy();
- },
- watch: buildWatchers()
- });
- export default FullCalendar;
- // Custom Rendering
- // -------------------------------------------------------------------------------------------------
- const CustomRenderingComponent = defineComponent({
- props: {
- customRendering: Object
- },
- render() {
- const customRendering = this.customRendering;
- const innerContent = typeof customRendering.generatorMeta === 'function' ?
- customRendering.generatorMeta(customRendering.renderProps) : // vue-normalized slot function
- customRendering.generatorMeta; // probably a vue JSX node returned from content-inject func
- return h(Teleport, { to: customRendering.containerEl }, innerContent);
- }
- });
- // storing internal state:
- // https://github.com/vuejs/vue/issues/1988#issuecomment-163013818
- function getSecret(inst) {
- return inst;
- }
- function buildWatchers() {
- let watchers = {
- // watches changes of ALL options and their nested objects,
- // but this is only a means to be notified of top-level non-complex options changes.
- options: {
- deep: true,
- handler(options) {
- let calendar = this.getApi();
- calendar.pauseRendering();
- let calendarOptions = this.buildOptions(options);
- calendar.resetOptions(calendarOptions);
- this.renderId++; // will queue a rerender
- }
- }
- };
- for (let complexOptionName in OPTION_IS_COMPLEX) {
- // handlers called when nested objects change
- watchers[`options.${complexOptionName}`] = {
- deep: true,
- handler(val) {
- // unfortunately the handler is called with undefined if new props were set, but the complex one wasn't ever set
- if (val !== undefined) {
- let calendar = this.getApi();
- calendar.pauseRendering();
- calendar.resetOptions({
- [complexOptionName]: val
- }, [complexOptionName]);
- this.renderId++; // will queue a rerender
- }
- }
- };
- }
- return watchers;
- }
- // General Utils
- // -------------------------------------------------------------------------------------------------
- function kebabToCamelKeys(map) {
- const newMap = {};
- for (const key in map) {
- newMap[kebabToCamel(key)] = map[key];
- }
- return newMap;
- }
- function kebabToCamel(s) {
- return s
- .split('-')
- .map((word, index) => index ? capitalize(word) : word)
- .join('');
- }
- function capitalize(s) {
- return s.charAt(0).toUpperCase() + s.slice(1);
- }
- //# sourceMappingURL=FullCalendar.js.map
|