FullScheduler — How to get started with our calendar
Docs, demos, API
Vue is the native framework of this component. Angular and Vanilla access is early since v1.0.67. Expect substantial improvements (APIs, templates, slot overrides) through v1.0.80, which will also bring official React support.
- Vue 3.3+ (package depends on
^3.3.8). - Node 18+ (recommended for modern toolchains).
- Bundlers: built with Vite 7; works in Vite/Nuxt/Vue CLI/Webpack (ESM & CJS exports).
- Exports:
module(ESM) +main(CJS) viapackage.exports. - License: MIT.
Actual package manifest (v1.0.36):
{
"dependencies": { "vue": "^3.3.8" },
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.4",
"autoprefixer": "^10.4.21",
"typescript": "^5.9.3",
"vite": "^7.1.10",
"vite-plugin-dts": "^4.5.4",
"vue-tsc": "^2.2.12"
}
}Roadmap — Custom Element (Web Component)
We plan to export a custom element (e.g., <full-scheduler-ce>) so you can embed it easily in React/Angular/Svelte and vanilla projects. This will land in upcoming releases.
Minimal calendar setup, seed events, and drag/resize handling with the new callback signature (payload, api). The examples below are fully aligned with the latest changes (v1.0.33–v1.0.36).
Install the calendar package:
npm i fullscheduler@latestThe shortest path: set date/time range, enable interactions, and pass a small seed of events.
<script setup lang="ts">
import { ref } from 'vue'
import FullScheduler from 'fullscheduler'
import {
type FullSchedulerApiInitOptions,
type FullSchedulerUserApi,
type FullSchedulerEvent,
type FullSchedulerDrop,
type FullSchedulerResize
} from 'fullscheduler'
type HappyEvent = { guests:Guest[], pictures, ... }
const api = ref<FullSchedulerUserApi<HappyEvent> | null>(null)
const options: FullSchedulerApiInitOptions<HappyEvent> = {
height: 560,
theme: 'light',
startDate: new Date(),
endDate: new Date(new Date().setDate(new Date().getDate() + 5)),
startHour: 8,
endHour: 18,
draggableEvents: true,
resizableEvents: true,
showCursorTime: true,
throwErrors: false,
colors: {
surface: 'var(--p-content-border-color)',
primary: 'var(--p-menubar-background)',
event: 'var(--p-togglebutton-background)',
highlight: 'var(--p-surface-50, #f1f5f9)',
textPrimary:'var(--p-surface-500, #0f172a)',
menuBg: 'var(--p-menubar-background, var(--p-surface-0, #ffffff))',
dragging: 'color-mix(in srgb, var(--p-panelmenu-item-focus-background) 50%, transparent)'
},
/** @type FullSchedulerUserApi<HappyEvent> **/
onFullSchedulerApiReady: (readyApi) => {
api.value = readyApi
readyApi.setEvents([
{ label: 'Design review', start: at(9), end: at(11), data: { id: '1', color: '#93c5fd' } },
{ label: 'Client call', start: at(12), end: at(13), data: { id: '2', color: '#86efac' } },
{ label: 'Dev pair', start: at(14), end: at(16), data: { id: '3', color: '#fda4af' } },
])
},
onEventDropped: (d, api) => {
d.accept()
},
onEventStartResized: (r, api) => {
r.accept()
},
onEventEndResized: (r, api) => {
r.accept()
}
}
function at(h: number, m = 0){
const d = new Date(); d.setHours(h, m, 0, 0); return d
}
</script>
<template>
<FullScheduler :full-scheduler-options="options" />
</template>startDate,endDate— view range (max 62 days withoutignoreSafety).startHour(0..23),endHour(1..24) — timeline hours.draggableEvents,resizableEvents— interactions.renderer— name of a globally registered Vue component.
eventTemplate(event, api)— HTML string; signature now includesapi.colors— consistent with the main demo; runtime override viaapi.setColors().showCursorTime,throwErrors,threshold.singleton-id— isolate or intentionally share instances (v1.0.36).
Renderer (Vue) — now receives { event, api }:
<!-- MyEventRenderer.vue -->
<script setup lang="ts">
import type { FullSchedulerEvent, FullSchedulerUserApi } from 'fullscheduler'
const props = defineProps<{ event: FullSchedulerEvent<HappyEvent>; api: FullSchedulerUserApi<HappyEvent> }>()
</script>
<template>
<div class="h-full w-full rounded-xl px-2 py-1" :style="{ background: props.event.data?.color || '#93c5fd' }">
<strong class="truncate">{{ props.event.label }}</strong>
</div>
</template>HTML template — signature (event, api):
const options = {
// ...
eventTemplate: (event, api) => \`
<div class="event" data-id="\${event.data?.id}">
<strong>\${event.label}</strong>
</div>
\`
}For frameworks other than Vue (Angular, Vanilla) the HTML template approach is currently available; the Renderer is native to Vue. With v1.0.80 (React support), we will introduce a compatible mechanism to override slots in non-Vue runtimes.
Common tasks: read visible range, change palette, switch views, adjust hours and days.
// Read current date range (v1.0.33)
const { startDate, endDate } = api.getDates()
// Change color palette at runtime (v1.0.33)
api.setColors({
primary: '#4f46e5',
surface: '#0b1020'
})
// View control
api.setDateRange(new Date(), new Date(new Date().setDate(new Date().getDate() + 7)))
api.setTimeRange(8, 18)
api.setDaysForward(7)
api.switchViewMode()
// Events
api.setEvents([...])
api.addEvents([...])
// Predicate-based updates/deletes (use data.id or any fields)
api.updateEvents(e => e.data?.id === '5', { end: new Date(), data: { ...e.data, status: 'confirmed' } })
api.deleteEvents(e => e.data?.id === '5')
// Drag snap threshold
api.setThreshold(15) Each instance has its own context by default. To deliberately share state, pass the same singleton-id to multiple calendars.
<FullScheduler :full-scheduler-options="optsA" singleton-id="shared-A" />
<FullScheduler :full-scheduler-options="optsB" singleton-id="shared-A" />
<!-- Both instances share the same context (v1.0.36) -->- No events visible? Check
startDate/endDateandstartHour/endHour. - Drag/resize not working? Enable
draggableEvents/resizableEventsand handle the callbacks. - Range too wide? There’s a 62-day cap (or set
ignoreSafety: true). - Theming/colors: use
api.setColors()at runtime.
