behnoo-calendar

Multi-calendar Vue 3 component — Gregorian, Jalaali (Persian), and Islamic calendar systems
570
Install
npm install behnoo-calendar
Latest Version:1.0.2
Vue:3
License:MIT
Last Updated:Oct 5, 2026
Links: npm
Maintainer: saeed_p11

@dopedev/vue-calendar

A multi-calendar Vue 3 component supporting Gregorian, Jalaali (Persian), and Islamic calendar systems with full RTL support.

Features

  • Three calendar systems: Gregorian, Jalaali (Persian), Islamic (Umm al-Qura)
  • Three view modes: monthly, weekly, daily
  • RTL layout support
  • Fully customizable header via slot
  • Event display with color, duration, and full-day support
  • Dark mode via CSS custom properties
  • TypeScript support

Installation

npm install @dopedev/vue-calendar
# or
pnpm add @dopedev/vue-calendar

Setup

Import the stylesheet once in your app entry point:

import "@dopedev/vue-calendar/style.css";

Nuxt:

// nuxt.config.ts
export default defineNuxtConfig({
  css: ["@dopedev/vue-calendar/style.css"],
});

Basic Usage

<script setup lang="ts">
import { ref } from "vue";
import { VueCalendar } from "@dopedev/vue-calendar";
import type { CalendarEvent } from "@dopedev/vue-calendar";

const events = ref<CalendarEvent[]>([
  {
    id: 1,
    title: "Team Meeting",
    date: new Date(),
    time: "10:00",
    duration: 60,
    color: "#3b82f6",
  },
]);
</script>

<template>
  <div style="height: 600px">
    <VueCalendar :events="events" />
  </div>
</template>

The component fills its container — give the parent a fixed height.

Props

Prop Type Default Description
events CalendarEvent[] [] Events to display
mode CalendarMode 'monthly' View mode: 'monthly', 'weekly', 'daily'
locale string 'en-US' BCP 47 locale tag used for day/month names
calendarType CalendarType 'gregory' Calendar system: 'gregory', 'persian', 'islamic-uma'
startOfWeek number 0 First day of week: 0 = Sunday … 6 = Saturday
hours { start: number; end: number } { start: 0, end: 24 } Visible hour range in weekly/daily view
initialDate Date new Date() Date the calendar opens on

v-model

mode supports two-way binding:

<VueCalendar v-model:mode="mode" />

Events

Event Payload Description
update:mode CalendarMode Fired when the mode changes
range-change { start: Date; end: Date } Fired on mount and whenever the visible range changes
event-click CalendarEvent Fired when an event is clicked

Header Slot

Replace the default header entirely with the #header slot. All navigation and mode control is exposed through slot props:

<VueCalendar :events="events" v-model:mode="mode">
  <template #header="{ mode, range, next, prev, setMode }">
    <div class="flex items-center gap-2 p-3 border-b">
      <button @click="prev">←</button>
      <button @click="next">→</button>
      <span>{{ range.start.toLocaleDateString() }}</span>
      <div class="ml-auto flex gap-1">
        <button
          v-for="m in ['monthly', 'weekly', 'daily'] as const"
          :key="m"
          @click="setMode(m)"
          :class="mode === m ? 'font-bold' : ''"
        >
          {{ m }}
        </button>
      </div>
    </div>
  </template>
</VueCalendar>

Slot props

Prop Type Description
mode CalendarMode Current view mode
range { start: Date; end: Date } Currently visible date range
next () => void Navigate to the next period
prev () => void Navigate to the previous period
setMode (mode: CalendarMode) => void Switch view mode

Calendar Systems

Gregorian (English)

<VueCalendar calendar-type="gregory" locale="en-US" :start-of-week="1" />

Jalaali / Persian (RTL)

Wrap the component in dir="rtl" to get correct RTL layout. Note that next and prev in the header slot remain semantically correct — swap their visual arrow directions instead.

<div dir="rtl">
  <VueCalendar
    calendar-type="persian"
    locale="fa-IR"
    :start-of-week="6"
  />
</div>

Islamic / Umm al-Qura (RTL)

<div dir="rtl">
  <VueCalendar
    calendar-type="islamic-uma"
    locale="ar-SA"
    :start-of-week="0"
  />
</div>

Customizing Event Display

You can override how events are rendered in the time‑grid (weekly/daily) and in the mobile monthly list.

  • Desktop time‑grid: use the #event slot.
  • Mobile event list: use the #event-mobile slot.
<VueCalendar :events="events">
  <!-- Custom desktop event -->
  <template #event="{ event }">
    <div :style="{ background: event.color || '#3b82f6', padding: '4px', borderRadius: '6px' }">
      {{ event.title }}
    </div>
  </template>

  <!-- Custom mobile list event -->
  <template #event-mobile="{ event }">
    <div class="flex items-center gap-2">
      <span class="font-bold">{{ event.title }}</span>
      <span class="text-sm text-gray-500">{{ event.time }}</span>
    </div>
  </template>
</VueCalendar>

CalendarEvent

interface CalendarEvent {
  id: number | string;
  date: Date | string; // date of the event
  time: string; // 'HH:mm' format
  title: string;
  duration?: number; // minutes (used in weekly/daily view)
  color?: string; // hex or CSS value; defaults to --cal-primary
  isFullDay?: boolean;
  raw?: any; // attach your original API payload here
}

Theming

The calendar exposes a set of CSS custom properties for colours. You can override them on :root for the light theme and inside a .dark selector for the dark theme.

CSS Variable Description Light default Dark default
--color-surface Main background #ffffff #151823
--color-surface-variant Card / cell secondary background #f8f8fa #242836
--color-on-surface Primary text colour #2c2c2e #ffffff
--color-primary Accent colour, event background fallback #1a9d90 #40b8ac
--color-error Error colour (weekends, holidays, pointer) #e52b16 #ea5545
--color-outline Standard border colour #d1d0d2 #605f63
--color-outline-variant Light border colour #f0f0f0 #3a393c

Today badge gradient
You can change the gradient used for the “today” circle:

Variable Light default Dark default
--cal-today-bg-light radial-gradient(circle at 70% 0%, #10121b, #393e4d) –
--cal-today-bg-dark – radial-gradient(circle at 70% 0%, #d1d0d2, #9b9a9d)

Example customisation:

:root {
  --color-surface: #ffffff;
  --color-primary: #ff6b6b;
  --cal-today-bg-light: radial-gradient(circle at 70% 0%, #4a00e0, #8e2de2);
}

.dark {
  --color-surface: #111827;
  --color-primary: #ff8787;
  --cal-today-bg-dark: radial-gradient(circle at 70% 0%, #ffd700, #ff8c00);
}

Exposed Methods

When using a template ref, the component exposes:

const cal = ref<InstanceType<typeof VueCalendar>>();

cal.value?.goNext(); // navigate forward
cal.value?.goPrev(); // navigate backward
cal.value?.setMode("weekly"); // change view mode
cal.value?.currentRange; // { start: Date, end: Date }

TypeScript

All public types are exported from the package root:

import type {
  CalendarEvent,
  CalendarMode,
  CalendarType,
  CalendarDay,
  CalendarDateRange,
  CalendarTimeRange,
} from "@dopedev/vue-calendar";

Development

pnpm install
pnpm dev          # dev sandbox at http://localhost:5173
pnpm type-check   # TypeScript check
pnpm build:lib    # build the distributable package

Run the Nuxt example

pnpm build:lib

cd examples/nuxt-example
pnpm install
pnpm dev          # http://localhost:3000

Publishing

npm login         # log in with the @dopedev org account
npm publish       # prepublishOnly runs build:lib automatically

License

MIT

Related Packages

@dope-dev/vue-calendar

Multi-calendar Vue 3 component — Gregorian, Jalaali (Persian), and Islamic calen...

1,019
khorshid

Khorshid — one install for the Jalali & Gregorian date picker: headless core, va...

356
@mahlaparvaz/vue-datepicker

Vue 3 datepicker supporting Jalali, Hijri, Gregorian, Chinese calendars with ran...

3,683 3
@khorshid-js/vue

Idiomatic Vue 3 bindings for Khorshid — composables + styled components for the...

220
vue-jalali-datepicker

A lightweight, zero-dependency Persian (Jalali / Shamsi) date and range picker f...

539 0

Version History

Version Released Vue License
1.0.2 ^3.5.0 MIT
1.0.1 ^3.5.0 MIT
1.0.0 ^3.5.0 MIT