Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/next version #152

Merged
merged 7 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions demo/main.ts
Original file line number Diff line number Diff line change
@@ -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: {
Expand Down
12 changes: 9 additions & 3 deletions demo/pages/input/main.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
12 changes: 9 additions & 3 deletions demo/pages/multiple/main.ts
Original file line number Diff line number Diff line change
@@ -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',
Expand Down
2 changes: 1 addition & 1 deletion package/package.json
Original file line number Diff line number Diff line change
@@ -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": [
Expand Down
4 changes: 2 additions & 2 deletions package/src/scripts/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion package/src/scripts/handles/handleClickDay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]();
Expand Down
61 changes: 36 additions & 25 deletions package/src/scripts/handles/handleDayRangedSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLElement> | undefined = currentSelf.HTMLElement?.querySelectorAll(`[data-calendar-day="${formattedDate}"]`);
dayEls?.forEach((d) => d.classList.add((currentSelf as VanillaCalendar).CSSClasses.dayBtnHover));
const dayEls: NodeListOf<HTMLElement> | 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];

Expand All @@ -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: () => {
Expand Down
13 changes: 12 additions & 1 deletion package/src/scripts/helpers/setVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
6 changes: 3 additions & 3 deletions package/src/scripts/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions package/src/styles/vanilla-calendar.css
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -109,7 +109,7 @@
}

.vanilla-calendar-week-numbers {
@apply flex flex-col grow
@apply flex flex-col
}

.vanilla-calendar-week-numbers__title {
Expand All @@ -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 {
Expand Down
9 changes: 4 additions & 5 deletions package/src/vanilla-calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <T extends object>(original: T, replacement: T) => {
(Object.keys(replacement) as Array<keyof T>).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);
Expand Down