Recurrence editor in Vue Schedule component

12 Jul 202424 minutes to read

The Recurrence editor is integrated into Scheduler editor window by default, to process the recurrence rule generation for events. Apart from this, it can also be used as an individual component referring from the Scheduler repository to work with the recurrence related processes.

All the valid recurrence rule string mentioned in the iCalendar specifications are applicable to use with the recurrence editor.

Customizing the repeat type option in editor

By default, there are 5 types of repeat options available in recurrence editor such as,

  • Never
  • Daily
  • Weekly
  • Monthly
  • Yearly

It is possible to customize the recurrence editor to display only the specific repeat options such as Daily and Weekly options alone by setting the appropriate frequencies option.

<template>
  <div id='app'>
    <div id='container'>
      <ejs-schedule height='550px' width='100%' :selectedDate='selectedDate' :eventSettings='eventSettings'
        :popupOpen='onPopupOpen'>
      </ejs-schedule>
    </div>
  </div>
</template>
<script setup>
import { provide } from "vue";
import { scheduleData } from './datasource.js';
import { ScheduleComponent as EjsSchedule, Day, Week, WorkWeek, Month, Agenda } from '@syncfusion/ej2-vue-schedule';

const selectedDate = new Date(2018, 1, 15);
const eventSettings = { dataSource: scheduleData }

const onPopupOpen = function (args) {
  if (args.type == 'Editor') {
    let recurrenceEditorObj =
      args.element.querySelector('.e-recurrenceeditor').ej2_instances[0];
    recurrenceEditorObj.frequencies = ['none', 'daily', 'weekly'];
  }
}

provide('schedule', [Day, Week, WorkWeek, Month, Agenda]);

</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';
</style>
<template>
  <div id='app'>
    <div id='container'>
      <ejs-schedule height='550px' width='100%' :selectedDate='selectedDate' :eventSettings='eventSettings'
        :popupOpen='onPopupOpen'>
      </ejs-schedule>
    </div>
  </div>
</template>
<script>
import { scheduleData } from './datasource.js';
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda } from '@syncfusion/ej2-vue-schedule';

export default {
  name: "App",
  components: {
    "ejs-schedule": ScheduleComponent
  },
  data() {
    return {
      selectedDate: new Date(2018, 1, 15),
      eventSettings: { dataSource: scheduleData }
    }
  },
  methods: {
    onPopupOpen: function (args) {
      if (args.type == 'Editor') {
        let recurrenceEditorObj =
          args.element.querySelector('.e-recurrenceeditor').ej2_instances[0];
        recurrenceEditorObj.frequencies = ['none', 'daily', 'weekly'];
      }
    }
  },
  provide: {
    schedule: [Day, Week, WorkWeek, Month, Agenda]
  }
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';
</style>

The other properties available in recurrence editor are tabulated below,

Properties Type Description
firstDayOfWeek number Sets the first day of the week on recurrence editor.
startDate Date Sets the start date from which date the recurrence event starts.
dateFormat string Sets the specific date format on recurrence editor.
locale string Sets the locale to be applied on recurrence editor.
cssClass string Allows styling to be applied on recurrence editor with custom class names.
enableRtl boolean Allows recurrence editor to render in RTL mode.
minDate Date Sets the minimum date on recurrence editor.
maxDate Date Sets the maximum date on recurrence editor.
value string Sets the recurrence rule value on recurrence editor.
selectedType number Sets the specific repeat type on the recurrence editor.

Customizing the End Type Option in Editor

By default, there are 3 types of end options available in the recurrence editor such as:

  • Never
  • Until
  • Count

It is possible to customize the recurrence editor to display only the specific end options, such as the Until and Count options alone, by setting the appropriate endTypes option.

<template>
  <div id="app">
    <div id="container">
      <ejs-recurrenceeditor ref="EditorObj"></ejs-recurrenceeditor>
    </div>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { RecurrenceEditorComponent as EjsRecurrenceeditor } from "@syncfusion/ej2-vue-schedule";

const EditorObj = ref(null);
onMounted(function () {
  EditorObj.value.endTypes = ["until", "count"];
})

</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css";
</style>
<template>
  <div id="app">
    <div id="container">
      <ejs-recurrenceeditor ref="EditorObj"></ejs-recurrenceeditor>
    </div>
  </div>
</template>
<script>
import { RecurrenceEditorComponent } from "@syncfusion/ej2-vue-schedule";

export default {
  name: "App",
  components: {
    "ejs-recurrenceeditor": RecurrenceEditorComponent
  },
  mounted: function () {
    let recObject = this.$refs.EditorObj;
    recObject.endTypes = ["until", "count"];
  }
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css";
</style>

Accessing the recurrence rule string

The recurrence rule is usually generated based on the options selected from the recurrence editor and also it follows the iCalendar specifications. The generated recurrence rule string is a valid one to be used with the Scheduler event’s recurrence rule field.

There is a change event available in recurrence editor, that triggers on every time the fields of recurrence editor tends to change. Within this event argument, you can access the generated recurrence value through the value option as shown in the following code example.

<template>
    <div id='app'>
        <div id='container'>
            <div style='padding-bottom:15px;'>
                <label>Rule Output</label>
                <div class='rule-output-container'>
                    <div id='rule-output'></div>
                </div>
            </div>
            <ejs-recurrenceeditor :selectedType='selectedType' :change='onChange'></ejs-recurrenceeditor>
        </div>
    </div>
</template>
<script setup>
import { ref } from "vue";
import { RecurrenceEditorComponent as EjsRecurrenceeditor } from '@syncfusion/ej2-vue-schedule';

const selectedType = 1;
const selectRule = ref('Select Rule');

const onChange = function (args) {
    if (args.value == "") {
        selectRule.value = 'Select Rule';
    } else {
        selectRule.value = args.value;
    }
}

</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
    margin: 0 25%;
}

.rule-output-container {
    height: auto;
    border: 1px solid #969696;
}

#rule-output {
    padding: 8px 4px;
    text-align: center;
    min-height: 20px;
    overflow: hidden;
    overflow-wrap: break-word;
}

@media (max-width: 580px) {
    .recurrence-editor-wrap {
        margin: 0 5%;
    }
}
</style>
<template>
    <div id='app'>
        <div id='container'>
            <div style='padding-bottom:15px;'>
                <label>Rule Output</label>
                <div class='rule-output-container'>
                    <div id='rule-output'></div>
                </div>
            </div>
            <ejs-recurrenceeditor :selectedType='selectedType' :change='onChange'></ejs-recurrenceeditor>
        </div>
    </div>
</template>
<script>
import { RecurrenceEditorComponent } from '@syncfusion/ej2-vue-schedule';

export default {
    name: "App",
    components: {
        "ejs-recurrenceeditor": RecurrenceEditorComponent
    },
    data() {
        return {
            selectedType: 1,
            selectRule: 'Select Rule'
        }
    },
    methods: {
        onChange: function (args) {
            if (args.value == "") {
                this.selectRule = 'Select Rule';
            } else {
                this.selectRule = args.value;
            }
        }
    }
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
    margin: 0 25%;
}

.rule-output-container {
    height: auto;
    border: 1px solid #969696;
}

#rule-output {
    padding: 8px 4px;
    text-align: center;
    min-height: 20px;
    overflow: hidden;
    overflow-wrap: break-word;
}

@media (max-width: 580px) {
    .recurrence-editor-wrap {
        margin: 0 5%;
    }
}
</style>

Set specific value on recurrence editor

It is possible to display the recurrence editor with specific options loaded initially, based on the rule string that we provide. The fields of recurrence editor will change its values accordingly, when we provide a particular rule through the setRecurrenceRule method.

<template>
  <div id='app'>
    <div id='container'>
      <div style='padding-bottom:15px;'>
        <label>Rule Output</label>
        <div class='rule-output-container'>
          <div id='rule-output'></div>
        </div>
      </div>
      <ejs-recurrenceeditor id='editor' ref='EditorObj' :selectedType='selectedType'
        :change='onChange'></ejs-recurrenceeditor>
    </div>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { RecurrenceEditorComponent as EjsRecurrenceeditor } from '@syncfusion/ej2-vue-schedule';

const selectedType = 1;
const selectRule = ref('');
const EditorObj = ref(null);

onMounted(function () {
  EditorObj.value.setRecurrenceRule('FREQ=DAILY;INTERVAL=2;COUNT=8');
})
const onChange = function (args) {
  if (args.value == "") {
    selectRule.value = 'Select Rule';
  } else {
    selectRule.value = args.value;
  }
}

</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
  margin: 0 25%;
}

.rule-output-container {
  height: auto;
  border: 1px solid #969696;
}

#rule-output {
  padding: 8px 4px;
  text-align: center;
  min-height: 20px;
  overflow: hidden;
  overflow-wrap: break-word;
}

@media (max-width: 580px) {
  .recurrence-editor-wrap {
    margin: 0 5%;
  }
}
</style>
<template>
  <div id='app'>
    <div id='container'>
      <div style='padding-bottom:15px;'>
        <label>Rule Output</label>
        <div class='rule-output-container'>
          <div id='rule-output'></div>
        </div>
      </div>
      <ejs-recurrenceeditor id='editor' ref='EditorObj' :selectedType='selectedType'
        :change='onChange'></ejs-recurrenceeditor>
    </div>
  </div>
</template>
<script>
import { RecurrenceEditorComponent } from '@syncfusion/ej2-vue-schedule';

export default {
  name: "App",
  components: {
    "ejs-recurrenceeditor": RecurrenceEditorComponent
  },
  data() {
    return {
      selectedType: 1,
      selectRule: ''
    }
  },
  mounted: function () {
    let recObject = this.$refs.EditorObj;
    recObject.setRecurrenceRule('FREQ=DAILY;INTERVAL=2;COUNT=8');
  },
  methods: {
    onChange: function (args) {
      if (args.value == "") {
        this.selectRule = 'Select Rule';
      } else {
        this.selectRule = args.value;
      }
    }
  }
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
  margin: 0 25%;
}

.rule-output-container {
  height: auto;
  border: 1px solid #969696;
}

#rule-output {
  padding: 8px 4px;
  text-align: center;
  min-height: 20px;
  overflow: hidden;
  overflow-wrap: break-word;
}

@media (max-width: 580px) {
  .recurrence-editor-wrap {
    margin: 0 5%;
  }
}
</style>

Recurrence date generation

You can parse the recurrenceRule of an event to generate the date instances on which that particular event is going to occur, using the getRecurrenceDates method. It generates the dates based on the recurrenceRule that we provide. The parameters to be provided for getRecurrenceDates method are as follows.

Field name Type Description
startDate Date Appointment start date.
rule String Recurrence rule present in an event object.
excludeDate String Date collection (in ISO format) to be excluded. It is optional.
maximumCount Number Number of date count to be generated. It is optional.
viewDate Date Current view range’s first date. It is optional.
<template>
  <div id='app'>
    <div id='container'>
      <div style='padding-bottom:15px;'>
        <label id='rule-label'>Date Collections</label>
        <div class='rule-output-container'>
          <div id='rule-output'>
            <div v-for="(date, index) in dates" :key="index"></div>
          </div>
        </div>
      </div>
      <ejs-recurrenceeditor id='editor' style="display: none;" ref='EditorObj' :selectedType='selectedType'>
      </ejs-recurrenceeditor>
    </div>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { RecurrenceEditorComponent as EjsRecurrenceeditor } from '@syncfusion/ej2-vue-schedule';

const EditorObj = ref(null);
const selectedType = 1;
const dates = ref([]);

onMounted(function () {
  dates.value = EditorObj.value.getRecurrenceDates(new Date(2018, 0, 7, 10, 0), 'FREQ=DAILY;INTERVAL=1', '20180108T114224Z,20180110T114224Z', 4, new Date(2018, 0, 7));
  for (let index = 0; index < dates.value.length; index++) {
    dates.value[index] = new Date(dates.value[index]).toString();
  }
})

</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
  margin: 0 25%;
}

.rule-output-container {
  height: auto;
  border: 1px solid #969696;
}

#rule-output {
  padding: 8px 4px;
  text-align: center;
  min-height: 20px;
  overflow: hidden;
  overflow-wrap: break-word;
}

@media (max-width: 580px) {
  .recurrence-editor-wrap {
    margin: 0 5%;
  }
}
</style>
<template>
    <div id='app'>
        <div id='container'>
            <div style='padding-bottom:15px;'>
                <label id='rule-label'>Date Collections</label>
                <div class='rule-output-container'>
                    <div id='rule-output'>
                        <div v-for="(date, index) in dates" :key="index"></div>
                    </div>
                </div>
            </div>
            <ejs-recurrenceeditor id='editor' style="display: none;" ref='EditorObj' :selectedType='selectedType'>
            </ejs-recurrenceeditor>
        </div>
    </div>
</template>
<script>
import { RecurrenceEditorComponent } from '@syncfusion/ej2-vue-schedule';

export default {
    name: "App",
    components: {
        "ejs-recurrenceeditor": RecurrenceEditorComponent
    },
    data() {
        return {
            selectedType: 1,
            dates: []
        }
    },
    mounted: function () {
        let recObject = this.$refs.EditorObj;
        this.dates = recObject.getRecurrenceDates(new Date(2018, 0, 7, 10, 0), 'FREQ=DAILY;INTERVAL=1', '20180108T114224Z,20180110T114224Z', 4, new Date(2018, 0, 7));
        for (let index = 0; index < this.dates.length; index++) {
            this.dates[index] = new Date(this.dates[index]).toString();
        }
    }
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
    margin: 0 25%;
}

.rule-output-container {
    height: auto;
    border: 1px solid #969696;
}

#rule-output {
    padding: 8px 4px;
    text-align: center;
    min-height: 20px;
    overflow: hidden;
    overflow-wrap: break-word;
}

@media (max-width: 580px) {
    .recurrence-editor-wrap {
        margin: 0 5%;
    }
}
</style>

Above example will generate two dates January 7, 2018 & January 9 2018 by excluding the in between dates January 8 2018 & January 10 2018, since those dates were given in the exclusion list. Generated dates can then be utilised to create appointments.

Recurrence date generation in server-side

It is also possible to generate recurrence date instances from server-side by manually referring the RecurrenceHelper class, which is specifically written and referred from application end to handle this date generation process.

Refer here for the step by step procedure to achieve date generation in server-side.

Restrict date generation with specific count

In case, if the rule is given in “NEVER ENDS” category, then you can mention the maximum count when you actually want to stop the date generation starting from the provided start date. To do so, provide the appropriate maximumCount value within the getRecurrenceDates method as shown in the following code example.

<template>
  <div id='app'>
    <div id='container'>
      <div style='padding-bottom:15px;'>
        <label ref='ruleLabel' id='rule-label'>Rule Output</label>
        <div id='rule-output'>
          <div v-for="(date, index) in dates" :key="index"></div>
        </div>
      </div>
      <ejs-recurrenceeditor id='editor' style="display: none;" ref='EditorObj' :selectedType='selectedType'>
      </ejs-recurrenceeditor>
    </div>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { RecurrenceEditorComponent as EjsRecurrenceeditor } from '@syncfusion/ej2-vue-schedule';
import { createElement } from '@syncfusion/ej2-base';

const EditorObj = ref(null);
const selectedType = 1;
const dates = ref([]);

onMounted(function () {
  dates.value = EditorObj.value.getRecurrenceDates(new Date(2018, 0, 7, 10, 0), 'FREQ=DAILY;INTERVAL=1; COUNT=30', '20180108T114224Z,20180110T114224Z', 10, new Date(2018, 0, 7));
  for (let index = 0; index < dates.value.length; index++) {
    dates.value.push(new Date(dates.value[index]).toString());
  }
})
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
  margin: 0 25%;
}

.rule-output-container {
  height: auto;
  border: 1px solid #969696;
}

#rule-output {
  padding: 8px 4px;
  text-align: center;
  min-height: 20px;
  overflow: hidden;
  overflow-wrap: break-word;
}

@media (max-width: 580px) {
  .recurrence-editor-wrap {
    margin: 0 5%;
  }
}
</style>
<template>
  <div id='app'>
    <div id='container'>
      <div style='padding-bottom:15px;'>
        <label ref='ruleLabel' id='rule-label'>Rule Output</label>
        <div id='rule-output'>
          <div v-for="(date, index) in dates" :key="index"></div>
        </div>
      </div>
      <ejs-recurrenceeditor id='editor' style="display: none;" ref='EditorObj' :selectedType='selectedType'>
      </ejs-recurrenceeditor>
    </div>
  </div>
</template>
<script>
import { RecurrenceEditorComponent } from '@syncfusion/ej2-vue-schedule';
import { createElement } from '@syncfusion/ej2-base';

export default {
  name: "App",
  components: {
    "ejs-recurrenceeditor": RecurrenceEditorComponent
  },
  data() {
    return {
      selectedType: 1,
      dates: []
    }
  },
  mounted: function () {
    let recObject = this.$refs.EditorObj;
    this.dates = recObject.getRecurrenceDates(new Date(2018, 0, 7, 10, 0), 'FREQ=DAILY;INTERVAL=1; COUNT=30', '20180108T114224Z,20180110T114224Z', 10, new Date(2018, 0, 7));
    for (let index = 0; index < dates.length; index++) {
      this.dates.push(new Date(dates[index]).toString());
    }
  }
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-schedule/styles/material.css';

.recurrence-editor-wrap {
  margin: 0 25%;
}

.rule-output-container {
  height: auto;
  border: 1px solid #969696;
}

#rule-output {
  padding: 8px 4px;
  text-align: center;
  min-height: 20px;
  overflow: hidden;
  overflow-wrap: break-word;
}

@media (max-width: 580px) {
  .recurrence-editor-wrap {
    margin: 0 5%;
  }
}
</style>

You can refer to our Vue Scheduler feature tour page for its groundbreaking feature representations. You can also explore our Vue Scheduler example to knows how to present and manipulate data.