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

@nuvaprd/production-calendar

v1.2.1

Published

Web Component de calendario de producción compatible con Angular 8+

Downloads

1,058

Readme

📅 @nuvaprd/production-calendar

Web Component moderno para gestión de calendario de producción, construido con Lit y totalmente compatible con Angular 8+

npm version License: MIT TypeScript

✨ Características

  • 🎯 Compatible con Angular 8+ - TypeScript 3.4+ soportado
  • 🔄 Migración fácil desde angular-calendar - API similar
  • 📱 3 Vistas: Mes, Semana, Día con navegación intuitiva
  • 🎨 Colores personalizables por evento
  • 📊 Panel lateral dinámico con vista Lista y Gantt
  • Control de visualización de horas - Ocultar/mostrar horas de eventos según necesidad
  • 🚀 Rendimiento optimizado con Shadow DOM
  • 🎭 Framework agnostic - Funciona con React, Vue, vanilla JS
  • 🌍 i18n ready - Soporte multiidioma
  • Accesible - ARIA labels y navegación por teclado

📦 Instalación

npm install @nuvaprd/production-calendar

🚀 Integración con Angular 8+

1. Configurar el módulo

Agrega CUSTOM_ELEMENTS_SCHEMA en tu módulo para permitir Web Components:

// app-schedule.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  declarations: [ScheduleListComponent],
  imports: [CommonModule, FormsModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA] // ← Importante para Web Components
})
export class AppScheduleModule { }

2. Agregar script en angular.json

Agrega el archivo UMD en los scripts para carga global:

{
  "architect": {
    "build": {
      "options": {
        "scripts": [
          "node_modules/@nuvaprd/production-calendar/dist/production-calendar.umd.js"
        ]
      }
    }
  }
}

3. Definir tipos en el componente

Dado que Angular 8 usa TypeScript 3.4 (sin soporte para import type), define los tipos localmente:

// schedule-list.component.ts
import { Component, OnInit } from '@angular/core';

// Tipos locales para compatibilidad con TS 3.4
type CalendarViewMode = 'month' | 'week' | 'day';

interface ProductionCalendarEvent {
  id?: string | number;
  title: string;
  start: Date | string;
  end?: Date | string;
  color?: {
    primary?: string;
    secondary?: string;
  };
  meta?: any;
}

@Component({
  selector: 'app-schedule-list',
  templateUrl: './schedule-list.component.html'
})
export class ScheduleListComponent implements OnInit {
  newCalendarView: CalendarViewMode = 'month';
  newCalendarEvents: ProductionCalendarEvent[] = [];
  viewDate: Date = new Date();

  // ... resto del componente
}

4. Usar en el template

<!-- schedule-list.component.html -->
<production-calendar
  [attr.viewDate]="viewDate.toISOString()"
  [attr.view]="newCalendarView"
  (dayClick)="onDayClick($event)"
  (eventClick)="onEventClick($event)">
</production-calendar>

5. Manejar eventos

export class ScheduleListComponent {
  
  // Sincronizar eventos al Web Component
  syncEventsToNewCalendar() {
    this.newCalendarEvents = this.events.map((event: any) => ({
      id: event.id || 'evt-' + Math.random().toString(36).substr(2, 9),
      title: event.title,
      start: event.start,
      end: event.end || event.start,
      color: {
        primary: (event.color && event.color.primary) || '#1e90ff',
        secondary: (event.color && event.color.secondary) || '#D1E8FF'
      },
      meta: event // Guardar evento completo para recuperar después
    }));

    // Actualizar Web Component
    setTimeout(() => {
      const calendarElement: any = document.querySelector('production-calendar');
      if (calendarElement) {
        calendarElement.events = this.newCalendarEvents;
        calendarElement.viewDate = this.viewDate;
        calendarElement.view = this.newCalendarView;
      }
    }, 50);
  }

  // Manejar click en evento
  onEventClick(event: any) {
    const detail = event.detail;
    const originalEvent = detail.event.meta; // Recuperar evento original
    
    // ✨ Nuevo en v1.1.0: Usar la fecha clickeada en lugar de la fecha de inicio
    const clickedDate = detail.clickedDate 
      ? (typeof detail.clickedDate === 'string' ? new Date(detail.clickedDate) : detail.clickedDate)
      : (typeof detail.event.start === 'string' ? new Date(detail.event.start) : detail.event.start);
    
    // Abrir modal o realizar acción con la fecha exacta donde se hizo clic
    this.openDialog(originalEvent, clickedDate);
  }

  // Manejar click en día
  onDayClick(event: any) {
    const detail = event.detail;
    console.log('Día clickeado:', detail.date);
    console.log('Eventos del día:', detail.events);
  }
}

📖 API Completa

Propiedades

| Propiedad | Tipo | Default | Descripción | |-----------|------|---------|-------------| | events | ProductionCalendarEvent[] | [] | Lista de eventos a mostrar | | viewDate | Date \| string | new Date() | Fecha central del calendario | | view | 'month' \| 'week' \| 'day' | 'month' | Vista actual del calendario | | showEventTime | boolean \| string | false | Mostrar u ocultar la hora de los eventos |

Eventos Emitidos

| Evento | Tipo del Detail | Descripción | |--------|-----------------|-------------| | dayClick | { date: Date, events: ProductionCalendarEvent[] } | Se dispara al hacer clic en un día | | eventClick | { event: ProductionCalendarEvent, clickedDate: Date, sourceEvent: Event } | Se dispara al hacer clic en un evento | | viewChange | { view: CalendarViewMode } | Se dispara al cambiar la vista |

✨ Nuevo en v1.1.0: El evento eventClick ahora incluye clickedDate, que representa la fecha de la celda del calendario donde se hizo clic. Esto es especialmente útil para eventos de múltiples días, donde event.start puede ser diferente de la fecha clickeada.

Control de Visualización de Horas

Por defecto, las horas de los eventos no se muestran (showEventTime = false). Puedes controlar esto de dos formas:

Opción 1: Como atributo HTML

<production-calendar
  [attr.showEventTime]="true"
  [attr.viewDate]="viewDate.toISOString()"
  [attr.view]="newCalendarView">
</production-calendar>

Opción 2: Vía JavaScript/TypeScript

const calendarElement: any = document.querySelector('production-calendar');
calendarElement.showEventTime = true;  // Mostrar horas
calendarElement.showEventTime = false; // Ocultar horas (default)

Resultado:

  • showEventTime = false (default): "OP-2026-001 Ensamble Motores"
  • showEventTime = true: "12:00 a.m. OP-2026-001 Ensamble Motores"

💡 Tip: Para eventos de producción, usualmente la hora exacta no es relevante, por eso está oculta por defecto. Actívala solo si tus eventos tienen horarios específicos importantes.

Tipo ProductionCalendarEvent

interface ProductionCalendarEvent {
  id?: string | number;           // ID único del evento
  title: string;                  // Título a mostrar
  start: Date | string;           // Fecha/hora inicio (ISO string o Date)
  end?: Date | string;            // Fecha/hora fin (opcional)
  color?: {
    primary?: string;             // Color principal (#hex)
    secondary?: string;           // Color secundario/fondo
  };
  meta?: Record<string, any>;    // Metadatos personalizados
  draggable?: boolean;            // Si se puede arrastrar (futuro)
  allDay?: boolean;               // Si es evento de todo el día
}

📅 Manejo de Eventos Multi-día

Cuando un evento tiene duración múltiple (ej: del 1 al 6 de marzo), aparece en varias celdas del calendario. Desde la v1.1.0, puedes obtener la fecha exacta donde el usuario hizo clic:

onEventClick(event: any) {
  const detail = event.detail;
  
  // Fecha de inicio del evento (siempre es la misma)
  const eventStartDate = detail.event.start; // "2026-03-01"
  
  // Fecha donde el usuario hizo clic (nueva en v1.1.0)
  const clickedDate = detail.clickedDate;     // "2026-03-04" si clickeó el día 4
  
  // Ejemplo: Mostrar "Programación del 04/03/2026" en vez de "01/03/2026"
  this.displayModal({
    title: detail.event.title,
    displayDate: clickedDate,  // Usar fecha clickeada
    eventData: detail.event.meta
  });
}

Beneficios:

  • ✅ Mejor UX: muestra la fecha que el usuario realmente seleccionó
  • ✅ Útil para modales de detalle o edición
  • ✅ Compatible hacia atrás: usa event.start si no necesitas esta funcionalidad

🎨 Personalización

Usando CSS Variables

El calendario usa CSS Variables para fácil personalización:

production-calendar {
  --calendar-bg: #ffffff;
  --calendar-header-bg: #f8fafc;
  --calendar-border: #e2e8f0;
  --text-primary: #1f2937;
  --text-secondary: #64748b;
  --accent: #3b82f6;
  --accent-light: #60a5fa;
}

Z-index y Modales

El calendario usa z-index: 100-101 para el panel lateral. Los modales de Angular Material (z-index ~1000) quedarán correctamente por encima.


🔧 Troubleshooting

Error: "Declaration or statement expected"

Causa: Angular 8 usa TypeScript 3.4 que no soporta import type.

Solución: Define los tipos localmente en tu componente (ver sección de integración).

El modal de Angular queda detrás del panel

Causa: Conflicto de z-index.

Solución: Ya está resuelto en v1.0.2+. El calendario usa z-index bajo (100-101).

Eventos no se actualizan

Solución: Accede al elemento y actualiza la propiedad directamente:

const cal: any = document.querySelector('production-calendar');
cal.events = newEvents;
cal.viewDate = newDate;

� Compatibilidad y Build

Soporte de ES2015 para Angular 8+

Desde v1.2.0, la librería se compila con target ES2015 para garantizar compatibilidad con:

  • ✅ Angular 8+ (TypeScript 3.4+)
  • ✅ Webpack 4.x con UglifyJS/Terser antiguo
  • ✅ Navegadores desde IE11+ (con polyfills)

Problema Resuelto

Antes de v1.2.0:

ERROR in scripts.xxx.js from Terser
Unexpected token: punc (;) [scripts.xxx.js:3677,34]

Causa: La librería usaba ES2022, que incluye operadores modernos (?., ??) no soportados por las versiones de Terser incluidas en Angular 8.

Uso recomendado:

  • Angular 8-11: Usar UMD en angular.json scripts
  • Angular 12+: Puede usar ESM directamente

�🛠️ Desarrollo Local

# Clonar e instalar
git clone <repo-url>
cd lib-wc-vite-lit-calendar
npm install

# Desarrollo
npm run dev

# Build para producción
npm run build

# Publicar
npm version patch
npm publish

📜 Changelog

v1.2.1 (2026-04-09)

  • Nueva propiedad showEventTime: Control para mostrar/ocultar horas de eventos
  • 🎯 Default mejorado: Las horas ahora están ocultas por defecto (showEventTime = false)
  • 💡 UX optimizada: Enfoque en eventos de producción donde la hora suele no ser relevante
  • 📝 Documentación actualizada: Guía completa de uso de showEventTime
  • ⚙️ Soporte para configuración vía atributo HTML o propiedad JavaScript

v1.2.0 (2026-04-09)

  • 🔧 Compatibilidad mejorada con Angular 8+: Transpilación a ES2015 para evitar errores de Terser
  • ✅ Resuelto error Unexpected token en builds de producción (--prod)
  • 📦 Agregado @types/node para soporte completo de TypeScript
  • ⚙️ Configuración de build optimizada (Vite + Terser ES2015)
  • 🎯 Target ES2015 en tsconfig y vite.config para máxima compatibilidad
  • 🛠️ Elimina errores de minificación en Angular 8 con webpack/uglify antiguos

Migración desde v1.1.x: No requiere cambios en tu código, solo actualiza:

npm update @nuvaprd/production-calendar

v1.1.0 (2026-04-09)

  • Nueva funcionalidad: eventClick ahora incluye clickedDate en el detail
  • 🎯 Mejora para eventos multi-día: distingue entre fecha de inicio del evento y fecha donde se hizo clic
  • 📝 Útil para modales que necesitan mostrar la fecha específica seleccionada por el usuario
  • 🔄 Compatibilidad hacia atrás mantenida: el código existente sigue funcionando

v1.0.4 (2026-03-28)

  • ✅ Ajuste en el contraste de las letras

v1.0.2 (2026-03-28)

  • ✅ Ajustado z-index para compatibilidad con modales de Angular
  • ✅ Cambiada fuente a Roboto para consistencia con aplicaciones Angular
  • ✅ Mejorada sincronización de eventos con meta

v1.0.1 (2026-03-28)

  • ✅ Corregida exportación de tipos para TypeScript 3.4
  • ✅ Mejorada compatibilidad con Angular 8+

v1.0.0 (2026-03-27)

  • 🎉 Lanzamiento inicial
  • ✅ Vistas Mes, Semana, Día
  • ✅ Panel lateral con Lista y Gantt
  • ✅ API compatible con angular-calendar

📄 Licencia

MIT © [Nuvaprd]


Hecho con ❤️ usando Lit y Vite

# En el proyecto Angular de producción:
npm update @nuva/production-calendar

# O para forzar la última versión:
npm install @nuva/production-calendar@latest

--

🎯 Migración desde angular-calendar

| angular-calendar | production-calendar | |------------------|---------------------| | mwl-calendar-month-view | production-calendar | | [viewDate]="viewDate" | calendar.viewDate = viewDate | | [events]="events" | calendar.events = events | | (dayClicked)="fn($event)" | (dayClick)="fn($event)" | | (eventClicked)="fn($event)" | (eventClick)="fn($event)" | | CalendarEvent | ProductionCalendarEvent |


📋 Checklist de release

  • [ ] Código probado con npm run dev
  • [ ] Build sin errores: npm run build
  • [ ] Versión actualizada: npm version <tipo>
  • [ ] Publicado: npm publish
  • [ ] Tag en git: git push --tags