UNPKG

hotel-datepicker-responsive

Version:

Un selector de fechas moderno y flexible para reservas de hotel y vuelos con soporte para calendario de precios y diseño responsive

581 lines (442 loc) 17.3 kB
# Hotel DatePicker Responsive Un selector de fechas moderno y flexible para reservas de hotel y vuelos con soporte para calendario de precios y diseño responsive. **Sitio web:** [https://calendario-arg4qzs55-ramons-projects-e601971a.vercel.app/](https://calendario-arg4qzs55-ramons-projects-e601971a.vercel.app/) ## Características - **Diseño Responsive**: Adaptado para dispositivos móviles y escritorio - **Selección de Rangos**: Permite seleccionar rangos de fechas (check-in y check-out) - **Modo Fecha Única**: Opción para seleccionar una sola fecha - **Calendario de Precios**: Integración con APIs de precios para mostrar tarifas - **Personalizable**: Múltiples opciones de configuración y estilos - **Variables CSS Personalizables**: Personalización completa de colores y estilos mediante variables CSS - **Shadow DOM**: Aislamiento de estilos para evitar conflictos con CSS externo - **Internacionalización**: Soporte para múltiples idiomas - **Standalone**: Incluye Luxon y CSS directamente en el bundle - **Sin Dependencias Externas**: No requiere jQuery ni otras bibliotecas - **Optimizado para Rendimiento**: Caché de tarifas y renderizado eficiente - **Iconos SVG Inline**: No requiere bibliotecas de iconos externas - **Selección del Mismo Día**: Opción para permitir seleccionar el mismo día como fecha de inicio y fin (ideal para vuelos) - **Conteo Flexible**: Opción para mostrar "días" en lugar de "noches" en el tooltip ## Mejoras recientes ### Nuevas Funcionalidades #### Personalización de Estilos CSS El calendario ahora permite personalizar completamente los colores y estilos mediante variables CSS: ```javascript const datepicker = new HotelDatePicker('container-id', { // Colores principales primaryColor: '#3498db', primaryLight: '#ebf5fb', primaryDark: '#2980b9', // Colores para precios priceBest: '#27ae60', priceGood: '#f2faf0', priceBestLow: '#bbe5b3', // Colores de texto textPrimary: '#2c3e50', textSecondary: '#7f8c8d', textLight: '#ffffff', // Colores de fondo bgPrimary: '#ffffff', bgSecondary: '#f5f5f5', bgDisabled: '#e9ecef', // Colores de borde borderColor: '#bdc3c7', borderFocus: '#95a5a6', // Tamaños daySize: '40px', fontSizeNormal: '14px', fontSizeSmall: '12px', fontSizeXsmall: '10px', // Espaciado spacingXs: '2px', spacingSm: '5px', spacingMd: '10px', spacingLg: '15px', spacingXl: '20px' }); ``` También puedes actualizar los estilos después de la inicialización: ```javascript datepicker.updateCSSVars({ primaryColor: '#e74c3c', primaryLight: '#fadbd8', priceBest: '#2ecc71' }); ``` #### Shadow DOM para Aislamiento de Estilos El calendario ahora utiliza Shadow DOM para aislar sus estilos del resto de la página, evitando conflictos con CSS externo: ```html <div id="calendar-container" style="position: relative;"> <!-- El calendario se renderizará aquí dentro de un Shadow DOM --> </div> ``` Es importante que el contenedor tenga `position: relative` para que el calendario se posicione correctamente. #### Inyección de CSS Personalizado Ahora puedes inyectar CSS personalizado directamente en el calendario de dos formas: 1. **Al inicializar el calendario**: ```javascript const datepicker = new HotelDatePicker('container-id', { // Otras opciones... customCSS: ` .day.selected { background-color: #3498db !important; border-radius: 50% !important; } .day.in-range { background-color: #e0f7fa !important; } ` }); ``` 2. **Después de la inicialización**: ```javascript datepicker.injectCSS(` .day.selected { background-color: #3498db !important; border-radius: 50% !important; } .day.in-range { background-color: #e0f7fa !important; } `); ``` #### Variables CSS en CSS Personalizado También puedes definir variables CSS directamente en el CSS personalizado, y estas tendrán prioridad sobre las variables predeterminadas: 1. **Usando el selector `:host`**: ```javascript datepicker.injectCSS(` :host { --hdp-primary-color: #3498db; --hdp-primary-light: #ebf5fb; --hdp-primary-dark: #2980b9; } .day.selected { background-color: var(--hdp-primary-color) !important; border-radius: 50% !important; } `); ``` 2. **Definiendo variables directamente sin selectores**: ```javascript datepicker.injectCSS(` --hdp-primary-color: #3498db; --hdp-primary-light: #ebf5fb; --hdp-primary-dark: #2980b9; `); ``` Estas funcionalidades te permiten personalizar completamente el aspecto del calendario sin tener que modificar el archivo CSS original. #### Selección del Mismo Día La opción `allowSameDaySelection` permite seleccionar el mismo día como fecha de inicio y fin, lo que es útil para vuelos o reservas de un solo día: ```javascript const datepicker = new HotelDatePicker('container-id', { allowSameDaySelection: true }); ``` Cuando esta opción está habilitada: - Se puede seleccionar el mismo día como fecha de inicio y fin - El día se muestra como un círculo completo sin flechas de dirección - El conteo de días comienza desde 1 (el mismo día cuenta como 1 día) #### Mostrar Días en lugar de Noches La opción `displayDaysInsteadOfNights` permite mostrar "días" en lugar de "noches" en el tooltip: ```javascript const datepicker = new HotelDatePicker('container-id', { displayDaysInsteadOfNights: true }); ``` Cuando esta opción está habilitada: - El tooltip muestra "días" en lugar de "noches" - El conteo se ajusta para reflejar días en lugar de noches ### Estructura modular El código ha sido reorganizado en módulos independientes para facilitar el mantenimiento y la extensión: - `calendar.js`: Funciones para generar y manipular el calendario - `config.js`: Configuración por defecto - `dom.js`: Manipulación del DOM - `events.js`: Manejo de eventos - `initializer.js`: Inicialización del calendario - `mobile.js`: Funcionalidades específicas para móvil - `navigation.js`: Navegación entre meses - `rates.js`: Gestión de tarifas - `renderer.js`: Renderización del calendario - `utils.js`: Funciones de utilidad ### Optimización de rendimiento - Caché de tarifas para evitar cargas innecesarias - Renderizado optimizado para evitar parpadeos - Detección inteligente de meses visibles en móvil - Aplicación eficiente de estilos ### Mejoras en la vista móvil - Mejor respuesta táctil - Scroll más suave - Mejor visualización de los botones - Optimización del espacio en pantalla - Carga de tarifas solo para meses visibles ## Instalación ```bash npm install hotel-datepicker-responsive --save ``` ## Uso Básico ```html <div id="datepicker"></div> <script> const datepicker = new HotelDatePicker('datepicker', { minNights: 1, maxNights: 30, format: 'dd/MM/yyyy', lang: 'es' }); </script> ``` ### Versión Standalone (Recomendada) Esta versión incluye Luxon y CSS directamente en el bundle, por lo que solo necesitas incluir un archivo: ```html <!-- Incluir Hotel DatePicker (con Luxon y CSS incluidos) --> <script src="dist/hotel-datepicker.standalone.js"></script> ``` Para generar estos archivos, ejecuta: ``` npm run build ``` Esto creará en la carpeta `dist`: - `hotel-datepicker.standalone.js`: Librería completa con Luxon y CSS incluidos ### Inicialización del componente Una vez incluidos los archivos necesarios, inicializa el componente: ```javascript const datePicker = new HotelDatePicker('container-id', { minNights: 1, maxNights: 30, onDateSelect: function(dates) { console.log('Fechas seleccionadas:', dates); } }); ``` ## Servidor Python incluido Para facilitar la visualización del calendario, se incluye un servidor Python simple: 1. Ejecuta `start_server.bat` o `python server.py` desde la línea de comandos 2. Abre tu navegador en http://localhost:8000/HotelDatePicker.html ## Ejemplos incluidos Puedes ver ejemplos en vivo en: [https://calendario-arg4qzs55-ramons-projects-e601971a.vercel.app/examples/basic.html](https://calendario-arg4qzs55-ramons-projects-e601971a.vercel.app/examples/basic.html) El proyecto incluye varios ejemplos para mostrar diferentes funcionalidades: ### Ejemplo básico Muestra el uso básico del calendario con opciones para ocultar leyenda y atajos. ``` examples/basic.html ``` ### Ejemplo con tarifas Muestra cómo integrar el calendario con una API de tarifas. ``` examples/with-rates.html ``` ### Ejemplo móvil Muestra el calendario optimizado para dispositivos móviles. ``` examples/mobile.html ``` ### Ejemplo para vuelos (selección del mismo día) Muestra cómo configurar el calendario para reservas de vuelos, permitiendo seleccionar el mismo día y mostrando días en lugar de noches. ```javascript const datepicker = new HotelDatePicker('container-id', { isRange: true, allowSameDaySelection: true, displayDaysInsteadOfNights: true, i18n: { day: 'día', days: 'días' } }); ``` ### Ejemplo de modo fecha única Muestra cómo configurar el calendario para seleccionar una sola fecha. ```javascript const datepicker = new HotelDatePicker('container-id', { isRange: false }); ``` ## Opciones de configuración | Opción | Tipo | Valor por defecto | Descripción | |--------|------|-------------------|-------------| | minNights | Number | 1 | Número mínimo de noches | | maxNights | Number | 30 | Número máximo de noches | | initialStartDate | String | null | Fecha de inicio inicial (formato ISO) | | initialEndDate | String | null | Fecha de fin inicial (formato ISO) | | format | String | 'dd LLL yyyy' | Formato de fecha (usando Luxon) | | hideLegend | Boolean | false | Oculta la leyenda | | hideShortcuts | Boolean | false | Oculta los atajos rápidos | | mobileBreakpoint | Number | 768 | Punto de quiebre para vista móvil (en píxeles) | | onDateSelect | Function | () => {} | Callback cuando se seleccionan fechas | | onMonthChange | Function | () => {} | Callback cuando cambia el mes visible | | onView | Function | () => {} | Callback cuando se abre el calendario | | priceCalendar | Object | { enabled: false } | Configuración del calendario de precios | | i18n | Object | { ... } | Textos para internacionalización | | isRange | Boolean | true | Si es true, permite seleccionar un rango de fechas. Si es false, solo permite seleccionar una fecha | | allowSameDaySelection | Boolean | false | Si es true, permite seleccionar el mismo día como fecha de inicio y fin (útil para vuelos) | | displayDaysInsteadOfNights | Boolean | false | Si es true, muestra "días" en lugar de "noches" en el tooltip | | currency | String | 'MXN' | Moneda para mostrar en la leyenda de precios | | primaryColor | String | '#db006e' | Color principal del calendario | | primaryLight | String | '#fcf5f9' | Color principal claro (para días en rango) | | primaryDark | String | '#800d46' | Color principal oscuro | | priceBest | String | '#1c8207' | Color para los mejores precios | | priceGood | String | '#f2faf0' | Color para buenos precios | | priceBestLow | String | '#bbe5b3' | Color para mejores precios bajos | | textPrimary | String | '#333333' | Color de texto principal | | textSecondary | String | '#696770' | Color de texto secundario | | textLight | String | '#ffffff' | Color de texto claro | | bgPrimary | String | '#ffffff' | Color de fondo principal | | bgSecondary | String | '#f5f5f5' | Color de fondo secundario | | bgDisabled | String | '#e9ecef' | Color de fondo para elementos deshabilitados | | borderColor | String | '#e6e6e6' | Color de borde | | borderFocus | String | '#adb5bd' | Color de borde para elementos enfocados | | daySize | String | '40px' | Tamaño de los días en el calendario | | fontSizeNormal | String | '14px' | Tamaño de fuente normal | | fontSizeSmall | String | '12px' | Tamaño de fuente pequeña | | fontSizeXsmall | String | '10px' | Tamaño de fuente muy pequeña | | spacingXs | String | '2px' | Espaciado extra pequeño | | spacingSm | String | '5px' | Espaciado pequeño | | spacingMd | String | '10px' | Espaciado mediano | | spacingLg | String | '15px' | Espaciado grande | | spacingXl | String | '20px' | Espaciado extra grande | | customCSS | String | '' | CSS personalizado para inyectar directamente en el Shadow DOM | ## Métodos disponibles ### open() Abre el calendario. ```javascript datePicker.open(); ``` ### close() Cierra el calendario. ```javascript datePicker.close(); ``` ### toggle() Alterna entre abrir y cerrar el calendario. ```javascript datePicker.toggle(); ``` ### setRates(year, month, rates) Establece las tarifas para un mes específico. ```javascript // Formato simple de tarifas const rates = { '2023-05-01': 1200, '2023-05-02': 1500, '2023-05-03': 1800, '2023-05-04': 1000, '2023-05-05': 900 }; datePicker.setRates(2023, 5, rates); ``` ### getSelectedDates() Obtiene las fechas seleccionadas. ```javascript const dates = datePicker.getSelectedDates(); console.log(dates.startDate, dates.endDate, dates.nights); ``` ### setSelectedDates(startDate, endDate) Establece las fechas seleccionadas. ```javascript datePicker.setSelectedDates('2023-05-01', '2023-05-05'); ``` ### clearSelectedDates() Limpia las fechas seleccionadas. ```javascript datePicker.clearSelectedDates(); ``` ### clearRatesCache() Limpia la caché de tarifas. ```javascript datePicker.clearRatesCache(); ``` ### updateCSSVars(cssVars) Actualiza las variables CSS personalizadas. ```javascript datePicker.updateCSSVars({ primaryColor: '#3498db', primaryLight: '#ebf5fb', priceBest: '#27ae60' }); ``` ### injectCSS(css) Inyecta CSS personalizado en el Shadow DOM. ```javascript datePicker.injectCSS(` .day.selected { background-color: #3498db !important; border-radius: 50% !important; } .day.in-range { background-color: #e0f7fa !important; } `); ``` ## Estructura del proyecto ``` hotel-date-picker/ ├── dist/ # Archivos compilados │ ├── hotel-date-picker.js │ ├── hotel-date-picker.min.js │ └── luxon.min.js ├── examples/ # Ejemplos de uso │ ├── basic.html │ ├── with-rates.html │ └── mobile.html ├── src/ # Código fuente │ ├── modules/ # Módulos │ │ ├── calendar.js │ │ ├── config.js │ │ ├── dom.js │ │ ├── events.js │ │ ├── index.js │ │ ├── initializer.js │ │ ├── mobile.js │ │ ├── navigation.js │ │ ├── rates.js │ │ ├── renderer.js │ │ └── utils.js │ ├── HotelDatePicker.js │ ├── HotelDatePicker.modular.js │ ├── HotelDatePicker.css │ ├── HotelDatePicker.combined.css │ └── styles.css ├── package.json └── README.md ``` ## Publicación en npm Para publicar la librería en npm: 1. Actualiza la información en `package.json` (nombre, autor, repositorio, etc.) 2. Ejecuta `npm run build` para generar los archivos 3. Ejecuta `npm login` para iniciar sesión en npm 4. Ejecuta `npm publish` para publicar el paquete Los usuarios podrán instalar tu paquete con: ``` npm install hotel-datepicker-responsive ``` Y usarlo en sus proyectos: ```html <!-- Incluir Hotel DatePicker (con Luxon y CSS incluidos) --> <script src="node_modules/hotel-datepicker-responsive/dist/hotel-datepicker.standalone.js"></script> <script> const datepicker = new HotelDatePicker('container-id', { // opciones... }); </script> ``` ## Internacionalización El calendario soporta múltiples idiomas para los nombres de meses, días y textos: ```javascript const datepicker = new HotelDatePicker('container-id', { lang: 'es', // Código de idioma (es, en, fr, etc.) i18n: { night: 'noche', nights: 'noches', day: 'día', // Nuevo: para displayDaysInsteadOfNights days: 'días', // Nuevo: para displayDaysInsteadOfNights apply: 'Aplicar', cancel: 'Cancelar', selectDate: 'Seleccionar fecha', selectCheckout: 'Seleccionar salida', selectCheckin: 'Seleccionar entrada' } }); ``` ## Repositorio El código fuente está disponible en GitHub: [https://github.com/JoseRamonGraciaCalderon/HotelDatePicker](https://github.com/JoseRamonGraciaCalderon/HotelDatePicker) ## Licencia MIT