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

@groooh/angular-calendar

v0.0.2

Published

A flexible and feature-rich calendar component for Angular applications. This library allows you to easily integrate a calendar with month, week, and day views, event management, drag-and-drop functionality, and recurrence support.

Readme

@groooh/angular-calendar

A flexible and feature-rich calendar component for Angular applications. This library allows you to easily integrate a calendar with month, week, and day views, event management, drag-and-drop functionality, and recurrence support.

This project was generated using Angular CLI version 19.2.0.

Installation

To install @groooh/angular-calendar in your project, run the following command:

npm install @groooh/angular-calendar

Or if you are using yarn:

yarn add @groooh/angular-calendar

Features

  • Multiple Views: Switch between month, week, and day views.
  • Event Management: Create, display, edit, and delete calendar events.
  • Drag & Drop:
    • Drag events to reschedule them.
    • Drag events from an external list onto the calendar.
    • Resize events in week and day views.
  • Recurrence: Support for recurring events (though the full implementation details of recurrence are not fully visible in the provided code snippets, it's a listed model).
  • Customizable:
    • Define event colors and styles.
    • Control the number of events displayed per day in month view before showing a "more events" indicator.
  • Navigation: Easily navigate to the next/previous period or jump to "Today".
  • Event Click Handling: Emit events when a calendar date or an event is clicked.
  • Time Slot Clicking: Emit events when a time slot in week/day view is clicked.
  • Standalone Components: Built with Angular standalone components for easier integration.

Integration

Follow these steps to integrate @groooh/angular-calendar into your Angular application:

  1. Import the AngularCalendarModule (or individual standalone components):

    The library exports AngularCalendarModule which bundles all the calendar components and directives. Alternatively, since the components like CalendarComponent are standalone, you can import them directly into your component or module.

    Option A: Using AngularCalendarModule (if you prefer NgModules)

    If AngularCalendarModule is intended to be the primary way to import, ensure it correctly imports and exports all necessary standalone components. Based on the provided my-library.module.ts (now angular-calendar.module.ts), it seems to be set up to export CalendarComponent, DraggableEventComponent, TimeSlotComponent, and DropZoneDirective.

    // src/app/app.module.ts (or your feature module)
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { AngularCalendarModule } from '@groooh/angular-calendar'; // Adjust path if installed from npm
    
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        AngularCalendarModule // Add AngularCalendarModule here
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

    Option B: Using Standalone CalendarComponent directly

    Since CalendarComponent is a standalone component, you can import it directly into the imports array of another standalone component or an NgModule.

    // src/app/your-component/your-component.ts
    import { Component } from '@angular/core';
    import { CalendarComponent, CalendarEvent } from '@groooh/angular-calendar'; // Adjust path
    import { CommonModule } from '@angular/common';
    
    @Component({
      selector: 'app-your-component',
      standalone: true,
      imports: [CommonModule, CalendarComponent], // Import CalendarComponent directly
      template: `
        <lib-calendar
          [events]="calendarEvents"
          (eventClicked)="handleEventClick($event)"
          (dateClicked)="handleDateClick($event)"
          (eventDropped)="handleEventDrop($event)"
          (timeSlotClicked)="handleTimeSlotClick($event)">
        </lib-calendar>
      `
    })
    export class YourComponent {
      calendarEvents: CalendarEvent[] = [
        // Populate with your events
        {
          id: '1',
          title: 'Team Meeting',
          start: new Date(),
          end: new Date(new Date().setHours(new Date().getHours() + 1)),
          color: 'blue',
          draggable: true,
          resizable: true
        }
      ];
    
      handleEventClick(event: CalendarEvent) {
        console.log('Event clicked:', event);
      }
    
      handleDateClick(date: Date) {
        console.log('Date clicked:', date);
      }
    
      handleEventDrop(data: { event: CalendarEvent, newDate: Date, newHour?: number }) {
        console.log('Event dropped:', data.event, 'New Date:', data.newDate, 'New Hour:', data.newHour);
        // Update your event's date/time here
      }
    
      handleTimeSlotClick(data: { date: Date, hour: number }) {
        console.log('Time slot clicked:', data.date, 'Hour:', data.hour);
        // Logic to handle time slot click, e.g., open new event form
      }
    }
  2. Add the calendar component to your template:

    Use the lib-calendar selector in your component's HTML template.

    <!-- src/app/your-component/your-component.html -->
    <lib-calendar
      [events]="calendarEvents"
      [currentView]="'month'"
      [selectedDate]="initialDate"
      (eventClicked)="handleEventClick($event)"
      (dateClicked)="handleDateClick($event)"
      (eventDropped)="handleEventDrop($event)"
      (newEvent)="handleNewEvent($event)"
      (timeSlotClicked)="handleTimeSlotClick($event)">
    </lib-calendar>
  3. Provide data and handle outputs:

    • [events] (Input): An array of CalendarEvent objects to display on the calendar.
      // CalendarEvent structure (example, refer to actual model in the library)
      export interface CalendarEvent {
        id: string;
        start: Date;
        end: Date;
        title: string;
        color?: string;       // e.g., 'blue', '#ff0000'
        draggable?: boolean;  // Defaults to true if not provided
        resizable?: boolean;  // For week/day views, defaults to true
        description?: string;
        // Potentially recurrence rule properties
      }
    • [currentView] (Input, Optional): Set the initial view ('month', 'week', or 'day'). Defaults to 'month'.
    • [selectedDate] (Input, Optional): Set the initially selected date. Defaults to the current date.
    • (eventClicked) (Output): Emits the CalendarEvent when an event is clicked.
    • (dateClicked) (Output): Emits the Date when a calendar day cell is clicked (in month view).
    • (timeSlotClicked) (Output): Emits { date: Date, hour: number } when a time slot is clicked in week or day view.
    • (eventDropped) (Output): Emits { event: CalendarEvent, newDate: Date, newHour?: number } when an event is dropped onto a new date/time. newHour is present for week/day views.
    • (newEvent) (Output): Emits data when the "add event" button is clicked or a new event is initiated, typically { date: Date }. The component has an internal form for creating/editing events.
    • (eventResized) (Output): Emits { event: CalendarEvent, newEnd: Date } when an event is resized.
  4. Styling:

    The component comes with its own styling. Ensure your global styles or build process includes the necessary CSS if it's not automatically handled (e.g., if styles are encapsulated and published with the library).

Key Components & Functionalities

lib-calendar (CalendarComponent)

This is the main component that renders the calendar.

Inputs:

  • events: CalendarEvent[]: Array of events to display.
  • currentView: CalendarViewMode: Initial view ('month', 'week', 'day').
  • selectedDate: Date: Initially selected date.
  • weekDays: string[]: Override default weekday names.
  • hoursOfDay: number[]: Define the hours to display in week/day views.
  • maxEventsPerDay: number: Max events shown in a month day cell before "+X more".

Outputs:

  • dateClicked: EventEmitter<Date>
  • eventClicked: EventEmitter<CalendarEvent>
  • eventDropped: EventEmitter<{ event: CalendarEvent, newDate: Date, newHour?: number }>
  • newEvent: EventEmitter<{ date: Date, hour?: number }>
  • viewChanged: EventEmitter<CalendarViewMode>
  • dateRangeChanged: EventEmitter<DateRange>
  • eventResized: EventEmitter<{ event: CalendarEvent, newEnd: Date }>

lib-draggable-event (DraggableEventComponent)

Represents an individual event that can be dragged. Used internally by CalendarComponent.

Inputs:

  • event: CalendarEvent
  • showResizeHandle: boolean

Outputs:

  • dragStart: EventEmitter<CalendarEvent>
  • dragEnd: EventEmitter<{ event: CalendarEvent, newDate?: Date }> (Note: newDate might be handled by the drop zone)
  • resizeStart: EventEmitter<CalendarEvent>
  • resizeEnd: EventEmitter<{ event: CalendarEvent, newEndTime: Date }> (or similar structure)

libDropZone (DropZoneDirective)

A directive applied to calendar cells (days or time slots) to make them valid drop targets for events.

Inputs:

  • date: Date
  • hour?: number (for week/day views)

Outputs:

  • `itemDropped: EventEmitter<{ event: CalendarEvent, date: Date, hour?: number }>```

CalendarService

A service likely used internally for date calculations, event management logic, and view transitions. It exposes types like CalendarEvent, CalendarViewMode, and DateRange.

Example Usage

// In your component.ts
import { Component } from '@angular/core';
import { CalendarEvent, CalendarViewMode } from '@groooh/angular-calendar'; // Adjust if path is different

@Component({
  selector: 'app-root',
  template: `
    <h1>My Calendar</h1>
    <lib-calendar
      [events]="myEvents"
      [currentView]="currentCalendarView"
      (eventClicked)="logEvent('Event Clicked', $event)"
      (dateClicked)="logEvent('Date Clicked', $event)"
      (eventDropped)="handleEventDrop($event)"
      (newEvent)="openMyEventModal($event)">
    </lib-calendar>
  `
})
export class AppComponent {
  currentCalendarView: CalendarViewMode = 'month';
  myEvents: CalendarEvent[] = [
    {
      id: 'evt1',
      title: 'Doctor Appointment',
      start: new Date(2025, 4, 25, 10, 0), // Note: Month is 0-indexed (4 = May)
      end: new Date(2025, 4, 25, 11, 0),
      color: '#1e90ff', // DodgerBlue
      draggable: true,
      resizable: true
    },
    {
      id: 'evt2',
      title: 'Project Deadline',
      start: new Date(2025, 4, 28),
      end: new Date(2025, 4, 28),
      color: 'red',
      draggable: false
    }
    // Add more events
  ];

  logEvent(type: string, eventData: any) {
    console.log(type, eventData);
  }

  handleEventDrop(dropped: { event: CalendarEvent, newDate: Date, newHour?: number }) {
    console.log('Event Dropped:', dropped);
    const eventToUpdate = this.myEvents.find(e => e.id === dropped.event.id);
    if (eventToUpdate) {
      const originalDuration = eventToUpdate.end.getTime() - eventToUpdate.start.getTime();
      eventToUpdate.start = dropped.newHour !== undefined ? 
                            new Date(dropped.newDate.getFullYear(), dropped.newDate.getMonth(), dropped.newDate.getDate(), dropped.newHour, 0) : 
                            dropped.newDate;
      eventToUpdate.end = new Date(eventToUpdate.start.getTime() + originalDuration);
      // Make sure to update your backend or state management system
    }
  }

  openMyEventModal(eventData: { date: Date, hour?: number }) {
    console.log('New event initiated for:', eventData.date, 'at hour:', eventData.hour);
    // Logic to open a modal or form to create a new event
  }
}