FullScheduler - Calendar - Gallery Image

FullScheduler — Events Customization - Full Guide

Docs, demos, API

Events customizationRenderer & HTML template
Renderer props { event, api } (v1.0.35)eventTemplate(event, api) (v1.0.35)

Two ways to draw events: a component renderer (Vue) and a pure HTML eventTemplate (string; available in all frameworks). Both receive typed event and the scheduler api.

Support scope

The renderer is currently Vue-only. In Angular and Vanilla JS use eventTemplate(event, api) exclusively. Version v1.0.80 will bring slot-override and compatible renderers for non-Vue runtimes together with official React support.

Register renderer globallyVue
main.ts
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import MyEventRenderer from './renderers/MyEventRenderer.vue'

const app = createApp(App)
app.component('MyEventRenderer', MyEventRenderer)
app.mount('#app')
Interactive demo (HTML template)Live
Use the renderer via optionsVue
Vue SFC (script setup)
import { ref } from 'vue'
import FullScheduler from 'fullscheduler'
import type { FullSchedulerApiInitOptions, FullSchedulerUserApi, FullSchedulerEvent } from 'fullscheduler'

type RendererData = { color?: string; icon?: string; description?: string }

const api = ref<FullSchedulerUserApi<RendererData> | null>(null)

const options: FullSchedulerApiInitOptions<RendererData> = {
  height: 560,
  theme: 'light',
  startDate: new Date(),
  endDate: new Date(new Date().setDate(new Date().getDate() + 5)),
  startHour: 8,
  endHour: 18,
  renderer: 'MyEventRenderer',

  onFullSchedulerApiReady: (readyApi) => {
    api.value = readyApi
    const events: FullSchedulerEvent<RendererData>[] = [
      { id: '1', label: 'Design review', start: at(9),  end: at(11), data: { color: '#93c5fd', icon: 'pi-briefcase' } },
      { id: '2', label: 'Client call',   start: at(12), end: at(13), data: { color: '#86efac', icon: 'pi-phone' } },
    ]
    readyApi.setEvents(events)
  }
}

function at(h: number, m = 0) { const d = new Date(); d.setHours(h, m, 0, 0); return d }
Minimal Vue rendererVue
MyEventRenderer.vue
<!-- ./renderers/MyEventRenderer.vue -->
<script setup lang="ts">
import type { FullSchedulerEvent, FullSchedulerUserApi } from 'fullscheduler'
type RendererData = { color?: string; icon?: string; description?: string }

const props = defineProps<{
  event: FullSchedulerEvent<RendererData>;
  api: FullSchedulerUserApi<RendererData>;
}>()
</script>

<template>
  <div
    class="h-full w-full rounded-xl px-2 py-1 ring-1 ring-black/5 flex items-center gap-2"
    :style="{ background: props.event.data?.color || 'var(--p-togglebutton-background)' }"
    role="group"
    :aria-label="`Event ${props.event.label}`"
  >
    <i v-if="props.event.data?.icon" class="pi" :class="props.event.data.icon" />
    <div class="min-w-0">
      <strong class="truncate">{{ props.event.label }}</strong>
      <div v-if="props.event.data?.description" class="text-xs opacity-70 truncate">
        {{ props.event.data.description }}
      </div>
    </div>
  </div>
</template>
Minimal HTML eventTemplateAll frameworks

Template factory (shared):

eventTemplate.ts
// eventTemplate.ts
import type { FullSchedulerEvent, FullSchedulerUserApi } from 'fullscheduler'
type RendererData = { color?: string; icon?: string; description?: string }

/**
 * @summary Return HTML string for an event card.
 * @remarks Keep it simple; for actions, bridge to your app code.
 */
export const eventTemplate = (
  event: FullSchedulerEvent<RendererData>,
  api: FullSchedulerUserApi<RendererData>
): string => {
  const color = event.data?.color || '#e5e7eb'
  const icon  = event.data?.icon  || 'pi-calendar'
  const label = event.label || ''
  const start = event.start.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
  const end   = event.end.toLocaleTimeString([],   { hour: '2-digit', minute: '2-digit' })

  return \`
  <div role="group" aria-label="Event ${label}"
       style="background:${color}; border-radius:.75rem; padding:.25rem .5rem; display:flex; align-items:center; gap:.5rem;">
    <i class="pi ${icon}"></i>
    <div style="min-width:0; flex:1;">
      <div style="font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">${label}</div>
      <div style="opacity:.7; font-size:12px">${start} – ${end}</div>
    </div>
  </div>\`
}

Wire it via options (Vue):

Vue SFC (script setup)
import { ref } from 'vue'
import FullScheduler from 'fullscheduler'
import type { FullSchedulerApiInitOptions, FullSchedulerUserApi, FullSchedulerEvent } from 'fullscheduler'
import { eventTemplate } from './eventTemplate'

type RendererData = { color?: string; icon?: string; description?: string }

const api = ref<FullSchedulerUserApi<RendererData> | null>(null)

const options: FullSchedulerApiInitOptions<RendererData> = {
  height: 560,
  theme: 'light',
  startDate: new Date(),
  endDate: new Date(new Date().setDate(new Date().getDate() + 5)),
  startHour: 8,
  endHour: 18,

  eventTemplate, // HTML template instead of component renderer

  onFullSchedulerApiReady: (readyApi) => {
    api.value = readyApi
    const events: FullSchedulerEvent<RendererData>[] = [
      { id: 'a', label: 'HTML card',    start: at(9),  end: at(10), data: { color: '#93c5fd', icon: 'pi-briefcase' } },
      { id: 'b', label: 'Another card', start: at(11), end: at(12), data: { color: '#86efac', icon: 'pi-users' } },
    ]
    readyApi.setEvents(events)
  }
}

function at(h: number, m = 0) { const d = new Date(); d.setHours(h, m, 0, 0); return d }