Skip to content

Calendar Component

The Calendar component is a reusable and customizable calendar designed for employee scheduling.

Usage

Basic Example

Jun 2025

Employee Name
22
SUN
23
MON
24
TUE
25
WED
26
THU
27
FRI
28
SAT
TW
Theresa Webb
Senior UX Researcher
40/48 HRS
KM
Kathryn Murphy
Interaction Designer
35/48 HRS
KM
Kathryn Murphy
Interaction Designer
35/48 HRS
KM
Kathryn Murphy
Interaction Designer
35/48 HRS
vue
<template>
  <SprCalendar
    v-model:search="searchEmployee"
    v-model:selected-cell="selectedCell"
    v-model:selected-company="selectedCompany"
    v-model:selected-department="selectedDepartment"
    v-model:selected-branch="selectedBranch"
    :employees="employees"
    :initial-date="initialDate"
    :company-options="companyOptions"
    :department-options="departmentOptions"
    :branch-options="branchOptions"
  />
</template>

<script setup lang="ts">
import SprCalendar from '@/components/calendar/calendar.vue';
import { ref } from 'vue';

const initialDate = new Date();
const searchEmployee = ref();
const selectedCompany = ref('');
const selectedDepartment = ref('');
const selectedBranch = ref('');
const selectedCell = ref({
  employeeId: '',
  date: '',
  schedule: null,
});

const employees = [
  {
    id: 1,
    name: 'Theresa Webb',
    position: 'Senior UX Researcher',
    avatar: '',
    highlight: true,
    hoursWorked: 40,
    hoursTarget: 48,
    schedule: {
      '2025-05-05': [{ type: 'restday' }],
      '2025-05-06': [{ startTime: '09:00AM', endTime: '06:00PM', location: 'Office A', type: 'Standard Day Shift' }],
      '2025-05-07': [{ startTime: '09:00AM', endTime: '06:00PM', location: 'Office A', type: 'Standard Day Shift' }],
      '2025-05-13': [{ startTime: '09:00AM', endTime: '06:00PM', location: 'Office A', type: 'Standard Day Shift' }],
      // ...other dates
    },
  },
  {
    id: 2,
    name: 'Kathryn Murphy',
    position: 'Interaction Designer',
    avatar: '',
    highlight: true,
    hoursWorked: 35,
    hoursTarget: 48,
    schedule: {
      '2025-05-05': [{ type: 'restday' }],
      '2025-05-08': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
      '2025-05-10': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
      '2025-05-13': [
        { startTime: '10:00AM', endTime: '06:00PM', location: 'Office a', type: 'Morning Shift' },
        { startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' },
        { startTime: '10:00AM', endTime: '08:00PM', location: 'Office c', type: 'Morning Shift' },
        { startTime: '10:00AM', endTime: '09:00PM', location: 'Office d', type: 'Morning Shift' },
      ],
      // ...other dates
    },
  },
  {
    id: 3,
    name: 'Kathryn Murphy',
    position: 'Interaction Designer',
    avatar: '',
    highlight: true,
    hoursWorked: 35,
    hoursTarget: 48,
    schedule: {
      '2025-05-01': [{ type: 'restday' }],
      '2025-05-02': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
      // ...other dates
    },
  },
  {
    id: 4,
    name: 'Kathryn Murphy',
    position: 'Interaction Designer',
    avatar: '',
    highlight: true,
    hoursWorked: 35,
    hoursTarget: 48,
    schedule: {
      '2025-05-12': [{ type: 'restday' }],
      '2025-05-15': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
      // ...other dates
    },
  },
];

const companyOptions = [
  { text: 'All Companies', value: 'all' },
  { text: 'Company A', value: 'company-a' },
  { text: 'Company B', value: 'company-b' },
];

const departmentOptions = [
  { text: 'All Departments', value: 'all' },
  { text: 'Design', value: 'design' },
  { text: 'Development', value: 'development' },
];

const branchOptions = [
  { text: 'All Branches', value: 'all' },
  { text: 'Branch A', value: 'branch-a' },
  { text: 'Branch B', value: 'branch-b' },
];
</script>

Slots

filter

  • Description: Slot for customizing the filter section.
  • Example:
    vue
    <template #filter>
      <div>Custom Filter Content</div>
    </template>

loading

  • Description: Slot for customizing the filter section.
  • Example:
    vue
    <template #loading>
      <div>loading</div>
    </template>

API Reference

Props

PropTypeDefaultDescription
employees (required)Array<Employee[]>N/AList of employees to display in the calendar.
initialDateDatenew Date()The initial date to display in the calendar.
companyOptionsArray<FilterOption[]>[ { text: 'All Companies', value: 'all' } ]Options for the company filter dropdown.
departmentOptionsArray<FilterOption[]>[ { text: 'All Departments', value: 'all' } ]Options for the department filter dropdown.
branchOptionsArray<FilterOption[]>[ { text: 'All Branches', value: 'all' } ]Options for the branch filter dropdown.
searchString''The search term for filtering employees.
selectedCellObject<SelectedShift>{ employeeId: '', date: '', shift: null }The currently selected cell in the calendar.
selectedCompanyString''The currently selected company filter.
selectedDepartmentString''The currently selected department filter.
selectedBranchString''The currently selected branch filter.
emptyStateTitle''-The title text displayed when the calendar has no events or data to show.
emptyStateButtonTextstring-The text displayed on the action button in the empty state, prompting the user to take an action (e.g., "Add Event").
emptyStateDescriptionstring-The text displayed description for empty state
Loadingboolean-Displays a loading state for the calendar, typically shown as a spinner or skeleton while data is being fetched.