Un selector de fecha y hora limpio sin dependencias pesadas
Cada vez que un proyecto necesita un selector de fechas, se repite la misma historia. El <input type="date"> nativo se ve diferente en cada navegador, la personalización es dolorosa y se comporta de manera impredecible en plataformas móviles. Agregar bibliotecas UI monstruosas o contenedores obsoletos con docenas de paquetes transitivos solo por un simple calendario se siente incorrecto.
Hace poco descubrí el repositorio vanilla-calendar-pro. Es un componente TypeScript limpio para selección de fecha y hora sin dependencias externas. Funciona en JavaScript plano así como dentro de React, Vue o Svelte.
Qué hay adentro y por qué es conveniente
La biblioteca está construida para cubrir necesidades básicas de interfaz sin inflar el bundle. El calendario pesa solo unos pocos kilobytes, y aun así puede hacer casi todo lo que diseñadores y product managers típicamente requieren.
Aquí están las características principales que destacan:
- Cero dependencias. No usa utilidades de análisis de fechas de terceros como moment o date-fns, utiliza
Intlnativo internamente. - Modos de visualización flexibles. El calendario puede incrustarse directamente en el markup de la página o abrirse en un popup al hacer clic en un input.
- Selección de rango y múltiples meses a la vez. Ideal para reservas de hoteles, compra de boletos o dashboards de análisis.
- Selector de hora integrado. El tiempo puede configurarse en formato 24 horas o AM/PM.
- Temas. Hay temas claros y oscuros listos para usar, y la personalización se hace a través de variables CSS estándar.
Inicio rápido
La instalación es estándar a través de cualquier gestor de paquetes:
npm install vanilla-calendar-pro
Si no tienes un bundler, puedes incluir el script y los estilos directamente a través de CDN.
En el markup, solo necesitas crear un contenedor vacío:
<div id="calendar"></div>
La inicialización en código se ve limpia:
import { VanillaCalendar } from 'vanilla-calendar-pro';
import 'vanilla-calendar-pro/build/vanilla-calendar.min.css';
const calendar = new VanillaCalendar('#calendar', {
settings: {
lang: 'ru-RU',
iso8601: true,
selection: {
day: 'multiple-ranged',
},
},
actions: {
clickDay(event, self) {
console.log('Выбранные даты:', self.selectedDates);
},
},
});
calendar.init();
Solo un par de líneas de configuración, y tenemos un calendario funcional con soporte para selección de rango y localización en ruso.
Personalización para tareas específicas
Un problema común con componentes prehechos es que alejarse del diseño estándar se convierte en una pesadilla. En vanilla-calendar-pro, la estructura DOM puede reconstruirse para adaptarse a tus necesidades usando layouts personalizados.
Por ejemplo, si necesitas deshabilitar fechas pasadas y bloquear fines de semana, la configuración se pasa directamente al objeto de configuración:
const calendar = new VanillaCalendar('#calendar', {
settings: {
range: {
min: 'today',
disabled: ['2026-05-01', '2026-05-09'],
},
selection: {
time: 24,
},
},
actions: {
changeTime(event, self) {
console.log('Установленное время:', self.selectedTime);
},
},
});
calendar.init();
El componente maneja las actualizaciones de parámetros dinámicos sin problemas. Si el usuario cambia el idioma en la aplicación, simplemente llamas al método update() con nuevas opciones sin un redibujado completo de la página ni fugas de memoria.
Integración con frameworks
Aunque vanilla está en el nombre, el autor se aseguró de que sea conveniente trabajar con bibliotecas reactivas.
En React, el calendario se envuelve fácilmente en un hook useEffect:
import { useEffect, useRef } from 'react';
import { VanillaCalendar } from 'vanilla-calendar-pro';
import 'vanilla-calendar-pro/build/vanilla-calendar.min.css';
export function DatePicker({ onSelect }) {
const containerRef = useRef(null);
useEffect(() => {
if (!containerRef.current) return;
const calendar = new VanillaCalendar(containerRef.current, {
actions: {
clickDay(event, self) {
onSelect(self.selectedDates);
},
},
});
calendar.init();
return () => {
calendar.destroy();
};
}, [onSelect]);
return <div ref={containerRef} />;
}
El método destroy() limpia correctamente los event handlers, así que el componente no deja basura en memoria al desmontarse.
A quién le será útil
El proyecto llena el vacío entre los gigantes de UI pesados y los inputs nativos primitivos. Si estás escribiendo un proyecto personal, construyendo una landing page o haciendo un panel de administración donde no quieres agregar componentes voluminosos, esta es una gran opción.
El código está completamente tipado, las fuentes son abiertas y la documentación en el sitio oficial cubre a fondo todos los métodos de la API y ejemplos de estilos. Vale la pena guardar en favoritos para el próximo sprint.
Proyectos relacionados