From 35340dbf1a9762abb571a4255e3176f661854dd6 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 28 Nov 2023 10:32:06 +0300 Subject: [PATCH 1/7] fix date settings --- package/src/scripts/default.ts | 4 ++-- package/src/vanilla-calendar.ts | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/package/src/scripts/default.ts b/package/src/scripts/default.ts index d63acd1d..57ac3059 100644 --- a/package/src/scripts/default.ts +++ b/package/src/scripts/default.ts @@ -19,8 +19,8 @@ export default class DefaultOptionsCalendar { lang: 'en', iso8601: true, range: { - min: '1970-01-01', - max: '2470-12-31', + min: this.date.min, + max: this.date.max, disablePast: false, disableGaps: false, disableAllDays: false, diff --git a/package/src/vanilla-calendar.ts b/package/src/vanilla-calendar.ts index 5c8805ed..6adb0104 100644 --- a/package/src/vanilla-calendar.ts +++ b/package/src/vanilla-calendar.ts @@ -13,20 +13,19 @@ export default class VanillaCalendar extends DefaultOptionsCalendar implements T if (!this.HTMLElement) throw new Error(`${selector} is not found, check the first argument passed to new VanillaCalendar.`); if (!options) return; - this.settings.range.min = options?.settings?.range?.min ?? this.date.min; - this.settings.range.max = options?.settings?.range?.max ?? this.date.max; - const replaceProperties = (original: T, replacement: T) => { (Object.keys(replacement) as Array).forEach((key) => { - if (typeof original[key] === 'object' && typeof replacement[key] === 'object') { + if (typeof original[key] === 'object' && typeof replacement[key] === 'object' && !(replacement[key] instanceof Date)) { replaceProperties(original[key] as object, replacement[key] as object); } else { original[key] = replacement[key]; } }); }; - replaceProperties(this, options); + + this.settings.range.min = options?.settings?.range?.min ?? this.date.min; + this.settings.range.max = options?.settings?.range?.max ?? this.date.max; } reset = () => reset(this); From c2a25097f570b7c73349d86fd13248f3352f3687 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 28 Nov 2023 10:43:56 +0300 Subject: [PATCH 2/7] fix styles --- package/src/styles/vanilla-calendar.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/src/styles/vanilla-calendar.css b/package/src/styles/vanilla-calendar.css index 3d686015..667e27d3 100644 --- a/package/src/styles/vanilla-calendar.css +++ b/package/src/styles/vanilla-calendar.css @@ -1,5 +1,5 @@ .vanilla-calendar { - @apply p-4 rounded-xl opacity-100 transition-opacity relative flex flex-col min-w-[275px] max-w-full h-max w-max + @apply p-4 rounded-xl opacity-100 transition-opacity relative flex flex-col min-w-[272px] max-w-full h-max w-max box-border } .vanilla-calendar_multiple { @@ -109,7 +109,7 @@ } .vanilla-calendar-week-numbers { - @apply flex flex-col grow + @apply flex flex-col } .vanilla-calendar-week-numbers__title { @@ -121,7 +121,7 @@ } .vanilla-calendar-week-number { - @apply text-xs font-semibold w-full h-full min-h-[1.875rem] min-w-[1.875rem] flex items-center justify-center cursor-pointer + @apply text-xs font-semibold w-full h-full min-h-[1.875rem] min-w-[1.875rem] flex items-center justify-center cursor-pointer bg-transparent border-none p-0 m-0 } .vanilla-calendar-wrapper { From a01a15bf29c80db4d199da5eabad01ea2e1dc651 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 28 Nov 2023 10:45:58 +0300 Subject: [PATCH 3/7] fix demo --- demo/main.ts | 12 +++++++++--- demo/pages/input/main.ts | 12 +++++++++--- demo/pages/multiple/main.ts | 12 +++++++++--- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/demo/main.ts b/demo/main.ts index ad6e95a0..95391eff 100644 --- a/demo/main.ts +++ b/demo/main.ts @@ -1,10 +1,16 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ +// import '@/package/build/vanilla-calendar.min.css'; +// import '@/package/build/themes/light.min.css'; +// import '@/package/build/themes/dark.min.css'; + +// import { IOptions } from '@src/types'; +// import VanillaCalendar from '@/package/build/vanilla-calendar.min'; + import '@src/styles/vanilla-calendar.css'; import '@src/styles/themes/light.css'; import '@src/styles/themes/dark.css'; -// import VanillaCalendar from '@/package/build/vanilla-calendar.min'; -import VanillaCalendar from '@src/vanilla-calendar'; + import { IOptions } from '@src/types'; +import VanillaCalendar from '@src/vanilla-calendar'; const config: IOptions = { settings: { diff --git a/demo/pages/input/main.ts b/demo/pages/input/main.ts index de52108e..25c9bb5f 100644 --- a/demo/pages/input/main.ts +++ b/demo/pages/input/main.ts @@ -1,10 +1,16 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ +// import '@/package/build/vanilla-calendar.min.css'; +// import '@/package/build/themes/light.min.css'; +// import '@/package/build/themes/dark.min.css'; + +// import { IOptions } from '@src/types'; +// import VanillaCalendar from '@/package/build/vanilla-calendar.min'; + import '@src/styles/vanilla-calendar.css'; import '@src/styles/themes/light.css'; import '@src/styles/themes/dark.css'; -// import VanillaCalendar from '@/package/build/vanilla-calendar.min'; -import VanillaCalendar from '@src/vanilla-calendar'; + import { IOptions } from '@src/types'; +import VanillaCalendar from '@src/vanilla-calendar'; const configInput: IOptions = { input: true, diff --git a/demo/pages/multiple/main.ts b/demo/pages/multiple/main.ts index 0c29d873..673ffb72 100644 --- a/demo/pages/multiple/main.ts +++ b/demo/pages/multiple/main.ts @@ -1,10 +1,16 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ +// import '@/package/build/vanilla-calendar.min.css'; +// import '@/package/build/themes/light.min.css'; +// import '@/package/build/themes/dark.min.css'; + +// import { IOptions } from '@src/types'; +// import VanillaCalendar from '@/package/build/vanilla-calendar.min'; + import '@src/styles/vanilla-calendar.css'; import '@src/styles/themes/light.css'; import '@src/styles/themes/dark.css'; -// import VanillaCalendar from '@/package/build/vanilla-calendar.min'; -import VanillaCalendar from '@src/vanilla-calendar'; + import { IOptions } from '@src/types'; +import VanillaCalendar from '@src/vanilla-calendar'; const config: IOptions = { type: 'multiple', From 23904e1b8f7911bfe8fd84f00eecddfba8f5171b Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 28 Nov 2023 11:19:44 +0300 Subject: [PATCH 4/7] fix update --- package/src/scripts/update.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/src/scripts/update.ts b/package/src/scripts/update.ts index c92a5a83..b5e47832 100644 --- a/package/src/scripts/update.ts +++ b/package/src/scripts/update.ts @@ -5,9 +5,9 @@ import create from '@scripts/create'; const update = (self: VanillaCalendar) => { const { dates, month, year } = self.settings.selected; - self.settings.selected.dates = self.selectedDates; - self.settings.selected.month = self.selectedMonth; - self.settings.selected.year = self.selectedYear; + self.settings.selected.dates = !dates?.[0] ? self.selectedDates : dates; + self.settings.selected.month = !month ? self.selectedMonth : month; + self.settings.selected.year = !year ? self.selectedYear : year; setVariables(self); create(self); From 1e4268cb7652b050a18ef8ed8586d13ec7fd3b25 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 28 Nov 2023 11:22:04 +0300 Subject: [PATCH 5/7] fix daySelectionActions multiple --- package/src/scripts/handles/handleClickDay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/src/scripts/handles/handleClickDay.ts b/package/src/scripts/handles/handleClickDay.ts index fa5f90e3..21a43f6b 100644 --- a/package/src/scripts/handles/handleClickDay.ts +++ b/package/src/scripts/handles/handleClickDay.ts @@ -14,7 +14,7 @@ const handleClickDay = (self: VanillaCalendar, event: MouseEvent) => { const daySelectionActions = { single: () => handleDaySelection(self, dayBtnEl, false), - multiple: () => handleDaySelection(self, dayBtnEl, false), + multiple: () => handleDaySelection(self, dayBtnEl, true), 'multiple-ranged': () => handleDayRangedSelection(self, dayBtnEl), }; daySelectionActions[self.settings.selection.day](); From 36d7b15795e56247da30d8d3b6e3c19ffdcf4442 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 28 Nov 2023 12:19:23 +0300 Subject: [PATCH 6/7] fix range variables --- demo/main.ts | 9 +++ .../handles/handleDayRangedSelection.ts | 61 +++++++++++-------- package/src/scripts/helpers/setVariables.ts | 13 +++- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/demo/main.ts b/demo/main.ts index 95391eff..c91204fa 100644 --- a/demo/main.ts +++ b/demo/main.ts @@ -14,6 +14,15 @@ import VanillaCalendar from '@src/vanilla-calendar'; const config: IOptions = { settings: { + range: { + disableAllDays: true, + // disablePast: true, + disableGaps: true, + enabled: ['2023-04-11:2023-04-16', '2023-04-26'], + }, + selection: { + day: 'multiple-ranged', + }, selected: { month: 3, year: 2023, diff --git a/package/src/scripts/handles/handleDayRangedSelection.ts b/package/src/scripts/handles/handleDayRangedSelection.ts index 51ff76a4..62a63338 100644 --- a/package/src/scripts/handles/handleDayRangedSelection.ts +++ b/package/src/scripts/handles/handleDayRangedSelection.ts @@ -4,32 +4,40 @@ import generateDate from '@scripts/helpers/generateDate'; import getDate from '@scripts/helpers/getDate'; import create from '@scripts/create'; -let currentSelf: null | VanillaCalendar = null; +const current: { + self: VanillaCalendar | null + rangeMin: FormatDateString | undefined; + rangeMax: FormatDateString | undefined; +} = { + self: null, + rangeMin: undefined, + rangeMax: undefined, +}; const removeHoverEffect = () => { - const dayEls = currentSelf?.HTMLElement?.querySelectorAll(`.${currentSelf.CSSClasses.dayBtnHover}`); - dayEls?.forEach((d) => d.classList.remove((currentSelf as VanillaCalendar).CSSClasses.dayBtnHover)); + const dayEls = current.self?.HTMLElement?.querySelectorAll(`.${current.self.CSSClasses.dayBtnHover}`); + dayEls?.forEach((d) => d.classList.remove((current.self as VanillaCalendar).CSSClasses.dayBtnHover)); }; const addHoverEffect = (day: Date) => { - if (!currentSelf?.selectedDates) return; + if (!current.self?.selectedDates) return; const formattedDate = generateDate(day); - if (currentSelf.rangeDisabled?.includes(formattedDate)) return; + if (current.self.rangeDisabled?.includes(formattedDate)) return; - const dayEls: NodeListOf | undefined = currentSelf.HTMLElement?.querySelectorAll(`[data-calendar-day="${formattedDate}"]`); - dayEls?.forEach((d) => d.classList.add((currentSelf as VanillaCalendar).CSSClasses.dayBtnHover)); + const dayEls: NodeListOf | undefined = current.self.HTMLElement?.querySelectorAll(`[data-calendar-day="${formattedDate}"]`); + dayEls?.forEach((d) => d.classList.add((current.self as VanillaCalendar).CSSClasses.dayBtnHover)); }; const handleHoverDaysEvent = (e: MouseEvent) => { - if (!e.target || !currentSelf?.selectedDates) return; + if (!e.target || !current.self?.selectedDates) return; removeHoverEffect(); const dayEl: HTMLElement | null = (e.target as HTMLElement).closest('[data-calendar-day]'); if (!dayEl) return; const formattedDate = dayEl.dataset.calendarDay as FormatDateString; - const startDate = getDate(currentSelf.selectedDates[0]); + const startDate = getDate(current.self.selectedDates[0]); const endDate = getDate(formattedDate); const [start, end] = startDate < endDate ? [startDate, endDate] : [endDate, startDate]; @@ -39,42 +47,45 @@ const handleHoverDaysEvent = (e: MouseEvent) => { }; const handleCancelSelectionDays = (e: KeyboardEvent) => { - if (!currentSelf || e.key !== 'Escape') return; - currentSelf.selectedDates = []; - (currentSelf.HTMLElement).removeEventListener('mousemove', handleHoverDaysEvent); + if (!current.self || e.key !== 'Escape') return; + current.self.selectedDates = []; + (current.self.HTMLElement).removeEventListener('mousemove', handleHoverDaysEvent); document.removeEventListener('keydown', handleCancelSelectionDays); - create(currentSelf); + create(current.self); }; const updateDisabledDates = () => { - if (!currentSelf?.selectedDates?.[0] || !currentSelf.rangeDisabled || currentSelf.rangeDisabled?.length < 2) return; - const selectedDate = getDate(currentSelf.selectedDates[0]); + if (!current.self?.selectedDates?.[0] || !current.self.rangeDisabled || current.self.rangeDisabled?.length < 2) return; + const selectedDate = getDate(current.self.selectedDates[0]); - const [startDate, endDate] = currentSelf.rangeDisabled + const [startDate, endDate] = current.self.rangeDisabled .map((dateStr) => getDate(dateStr)) .reduce<[Date | null, Date | null]>(([start, end], disabledDate) => [ selectedDate >= disabledDate ? disabledDate : start, selectedDate < disabledDate && end === null ? disabledDate : end, ], [null, null]); - if (startDate) currentSelf.rangeMin = generateDate(new Date(startDate.setDate(startDate.getDate() + 1))); - if (endDate) currentSelf.rangeMax = generateDate(new Date(endDate.setDate(endDate.getDate() - 1))); + if (startDate) current.self.rangeMin = generateDate(new Date(startDate.setDate(startDate.getDate() + 1))); + if (endDate) current.self.rangeMax = generateDate(new Date(endDate.setDate(endDate.getDate() - 1))); }; const resetDisabledDates = () => { - if (!currentSelf) return; - const minDate = getDate(currentSelf.settings.range.min); - currentSelf.rangeMin = currentSelf.settings.range.disablePast && minDate < currentSelf.date.today - ? generateDate(currentSelf.date.today) - : currentSelf.settings.range.min; - currentSelf.rangeMax = currentSelf.settings.range.max; + if (!current.self) return; + current.self.rangeMin = current.rangeMin as FormatDateString; + current.self.rangeMax = current.rangeMax as FormatDateString; }; const handleDayRangedSelection = (self: VanillaCalendar, dayBtnEl: HTMLElement) => { const formattedDate = dayBtnEl.dataset.calendarDay as FormatDateString; const selectedDateExists = self.selectedDates.length === 1 && self.selectedDates[0].includes(formattedDate); self.selectedDates = selectedDateExists ? [] : self.selectedDates.length > 1 ? [formattedDate] : [...self.selectedDates, formattedDate]; - currentSelf = self; + + if (self.settings.range.disableGaps) { + current.rangeMin = current.rangeMin ? current.rangeMin : self.rangeMin; + current.rangeMax = current.rangeMax ? current.rangeMax : self.rangeMax; + } + + current.self = self; const selectionHandlers = { set: () => { diff --git a/package/src/scripts/helpers/setVariables.ts b/package/src/scripts/helpers/setVariables.ts index 17edd7c3..d2e0deea 100644 --- a/package/src/scripts/helpers/setVariables.ts +++ b/package/src/scripts/helpers/setVariables.ts @@ -31,13 +31,24 @@ const initRange = (self: VanillaCalendar) => { firstDay.setDate(firstDay.getDate() - 1); lastDay.setDate(lastDay.getDate() + 1); self.rangeDisabled = self.settings.range.disabled ? parseDates(self.settings.range.disabled) : []; - if (self.settings.range.disableAllDays) self.rangeDisabled?.push(generateDate(new Date(self.selectedYear, self.selectedMonth, 1))); + + if (self.settings.range.disableAllDays) { + const daysInCurrentMonth = new Date(self.selectedYear, self.selectedMonth + 1, 0).getDate(); + for (let i = 1; i <= daysInCurrentMonth; i++) { + self.rangeDisabled.push(generateDate(new Date(self.selectedYear, self.selectedMonth, i))); + } + } + self.rangeDisabled.push(generateDate(firstDay)); self.rangeDisabled.push(generateDate(lastDay)); + self.rangeDisabled.sort((a, b) => +new Date(a) - +new Date(b)); // set self.rangeEnabled self.rangeEnabled = self.settings.range.enabled ? parseDates(self.settings.range.enabled) : []; if (self.rangeEnabled?.[0]) self.rangeDisabled = self.rangeDisabled?.filter((d) => !self.rangeEnabled?.includes(d)); + + self.rangeEnabled.sort((a, b) => +new Date(a) - +new Date(b)); + if (self.rangeEnabled?.[0] && self.settings.range.disableAllDays) { self.rangeMin = self.rangeEnabled[0]; self.rangeMax = self.rangeEnabled[self.rangeEnabled.length - 1]; From b4cd9da5ac0c0f571a82b03e76a112f8ff2816c7 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 28 Nov 2023 12:25:31 +0300 Subject: [PATCH 7/7] fix demo "default" --- demo/main.ts | 9 --------- package/package.json | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/demo/main.ts b/demo/main.ts index c91204fa..95391eff 100644 --- a/demo/main.ts +++ b/demo/main.ts @@ -14,15 +14,6 @@ import VanillaCalendar from '@src/vanilla-calendar'; const config: IOptions = { settings: { - range: { - disableAllDays: true, - // disablePast: true, - disableGaps: true, - enabled: ['2023-04-11:2023-04-16', '2023-04-26'], - }, - selection: { - day: 'multiple-ranged', - }, selected: { month: 3, year: 2023, diff --git a/package/package.json b/package/package.json index d576a8f4..5295c06f 100644 --- a/package/package.json +++ b/package/package.json @@ -1,6 +1,6 @@ { "name": "@uvarov.frontend/vanilla-calendar", - "version": "2.8.1-alpha.1", + "version": "2.8.1-alpha.2", "description": "Vanilla Calendar is a versatile JavaScript date and time picker with TypeScript support, making it compatible with any JavaScript framework or library. It is designed to be lightweight, simple to use, and feature-rich without relying on external dependencies.", "homepage": "https://vanilla-calendar.com", "keywords": [