npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dope-dev/vue-calendar

v0.1.1

Published

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

Readme

@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