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 navigation by month #348

Merged
merged 4 commits into from
Dec 17, 2024
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
18 changes: 10 additions & 8 deletions demo/pages/lang/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ const options: Options = {
selectionDatesMode: 'multiple-ranged',
disableDatesGaps: true,
// disableDatesPast: true,
dateMin: '2021-02-01',
dateMax: '2025-11-30',
displayDatesOutside: false,
selectionTimeMode: 12,
selectedMonth: 5,
selectedYear: 2024,
selectedMonth: 9,
selectedYear: 2025,
timeMinHour: 2,
timeMaxHour: 20,
timeMinMinute: 10,
Expand Down Expand Up @@ -63,12 +65,12 @@ const options: Options = {
};

document.addEventListener('DOMContentLoaded', () => {
const calendar = new Calendar('#calendar');
const calendar = new Calendar('#calendar', options);
calendar.init();

const btnSetEl = document.querySelector('#set-options');
btnSetEl?.addEventListener('click', () => {
calendar.set(options, { dates: false });
console.log(calendar);
});
// const btnSetEl = document.querySelector('#set-options');
// btnSetEl?.addEventListener('click', () => {
// calendar.set(options, { dates: false });
// console.log(calendar);
// });
});
17 changes: 7 additions & 10 deletions package/src/scripts/creators/createMonths.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import createLayouts from '@scripts/creators/createLayouts';
import setMonthOrYearModifier from '@scripts/creators/setMonthOrYearModifier';
import visibilityTitle from '@scripts/creators/visibilityTitle';
import getColumnID from '@scripts/utils/getColumnID';
import getDate from '@scripts/utils/getDate';
import setContext from '@scripts/utils/setContext';
import type { Calendar } from '@src/index';

const relationshipID = (self: Calendar) => {
if (self.type !== 'multiple') return 0;
const columnEls = self.context.mainElement.querySelectorAll<HTMLElement>('[data-vc="column"]');
const indexColumn = Array.from(columnEls).findIndex((column) => column.closest('[data-vc-column="month"]'));
return indexColumn > 0 ? indexColumn : 0;
};

const createMonthEl = (
self: Calendar,
templateEl: HTMLButtonElement,
Expand Down Expand Up @@ -60,10 +54,13 @@ const createMonths = (self: Calendar, target?: HTMLElement) => {
for (let i = 0; i < 12; i++) {
const dateMin = getDate(self.context.dateMin);
const dateMax = getDate(self.context.dateMax);
const monthCount = self.context.displayMonthsCount - 1;
const { columnID } = getColumnID(self, 'month');

const monthDisabled =
(i < dateMin.getMonth() + relationshipID(self) && selectedYear <= dateMin.getFullYear()) ||
(i > dateMax.getMonth() + relationshipID(self) && selectedYear >= dateMax.getFullYear()) ||
(selectedYear <= dateMin.getFullYear() && i < dateMin.getMonth() + columnID) ||
(selectedYear >= dateMax.getFullYear() && i > dateMax.getMonth() - monthCount + columnID) ||
selectedYear > dateMax.getFullYear() ||
(i !== selectedMonth && !activeMonthsID.includes(i));
const monthEl = createMonthEl(
self,
Expand All @@ -78,7 +75,7 @@ const createMonths = (self: Calendar, target?: HTMLElement) => {
if (self.onCreateMonthEls) self.onCreateMonthEls(self, monthEl);
}

self.context.mainElement.querySelector<HTMLElement>(`[data-vc-months-month]`)?.focus();
self.context.mainElement.querySelector<HTMLElement>(`[data-vc-months-month]:not([disabled])`)?.focus();
};

export default createMonths;
2 changes: 1 addition & 1 deletion package/src/scripts/creators/createYears.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const createYears = (self: Calendar, target?: HTMLElement) => {
if (self.onCreateYearEls) self.onCreateYearEls(self, yearEl);
}

self.context.mainElement.querySelector<HTMLElement>(`[data-vc-years-year]`)?.focus();
self.context.mainElement.querySelector<HTMLElement>(`[data-vc-years-year]:not([disabled])`)?.focus();
};

export default createYears;
2 changes: 1 addition & 1 deletion package/src/scripts/creators/visibilityArrows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const handleDefaultType = (self: Calendar, arrowPrevEl: HTMLElement, arrowNextEl
const isArrowNextHidden =
!self.selectionMonthsMode ||
jumpDateMax.getFullYear() > dateMax.getFullYear() ||
(jumpDateMax.getFullYear() === dateMax.getFullYear() && jumpDateMax.getMonth() > dateMax.getMonth());
(jumpDateMax.getFullYear() === dateMax.getFullYear() && jumpDateMax.getMonth() > dateMax.getMonth() - (self.context.displayMonthsCount - 1));

setVisibilityArrows(arrowPrevEl, arrowNextEl, isArrowPrevHidden, isArrowNextHidden);
};
Expand Down
43 changes: 21 additions & 22 deletions package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,49 @@ import create from '@scripts/creators/create';
import createMonths from '@scripts/creators/createMonths';
import createYears from '@scripts/creators/createYears';
import setMonthOrYearModifier from '@scripts/creators/setMonthOrYearModifier';
import getColumnID from '@scripts/utils/getColumnID';
import getDate from '@scripts/utils/getDate';
import setContext from '@scripts/utils/setContext';
import type { Calendar, Range } from '@src/index';

const typeClick = ['month', 'year'] as const;

const getColumnID = (self: Calendar, type: (typeof typeClick)[number], id: number) => {
const columnEls: NodeListOf<HTMLElement> = self.context.mainElement.querySelectorAll('[data-vc="column"]');
const indexColumn = Array.from(columnEls).findIndex((column) => column.closest(`[data-vc-column="${type}"]`));
const currentValue = Number((columnEls[indexColumn].querySelector(`[data-vc="${type}"]`) as HTMLElement).getAttribute(`data-vc-${type}`));
const getValue = (self: Calendar, type: (typeof typeClick)[number], id: number) => {
const { currentValue, columnID } = getColumnID(self, type);

return self.context.currentType === 'month' && indexColumn >= 0
? id - indexColumn
: self.context.currentType === 'year' && self.context.selectedYear !== currentValue
? id - 1
: id;
if (self.context.currentType === 'month' && columnID >= 0) return id - columnID;
if (self.context.currentType === 'year' && self.context.selectedYear !== currentValue) return id - 1;
return id;
};

const handleMultipleYearSelection = (self: Calendar, itemEl: HTMLElement) => {
const selectedYear = getColumnID(self, 'year', Number(itemEl.dataset.vcYearsYear));
const selectedYear = getValue(self, 'year', Number(itemEl.dataset.vcYearsYear));
const dateMin = getDate(self.context.dateMin);
const dateMax = getDate(self.context.dateMax);
const monthCount = self.context.displayMonthsCount - 1;
const { columnID } = getColumnID(self, 'year');

const isBeforeMinDate = self.context.selectedMonth < dateMin.getMonth() && selectedYear <= dateMin.getFullYear();
const isAfterMaxDate = self.context.selectedMonth > dateMax.getMonth() && selectedYear >= dateMax.getFullYear();
const isAfterMaxDate = self.context.selectedMonth > dateMax.getMonth() - monthCount + columnID && selectedYear >= dateMax.getFullYear();
const isBeforeMinYear = selectedYear < dateMin.getFullYear();
const isAfterMaxYear = selectedYear > dateMax.getFullYear();

setContext(
self,
'selectedYear',
isBeforeMinDate || isBeforeMinYear ? dateMin.getFullYear() : isAfterMaxDate || isAfterMaxYear ? dateMax.getFullYear() : selectedYear,
);
setContext(
self,
'selectedMonth',
(isBeforeMinDate || isBeforeMinYear ? dateMin.getMonth() : isAfterMaxDate || isAfterMaxYear ? dateMax.getMonth() : self.context.selectedMonth) as Range<12>,
);
const newSelectedYear = isBeforeMinDate || isBeforeMinYear ? dateMin.getFullYear() : isAfterMaxDate || isAfterMaxYear ? dateMax.getFullYear() : selectedYear;
const newSelectedMonth =
isBeforeMinDate || isBeforeMinYear
? dateMin.getMonth()
: isAfterMaxDate || isAfterMaxYear
? dateMax.getMonth() - monthCount + columnID
: self.context.selectedMonth;

setContext(self, 'selectedYear', newSelectedYear);
setContext(self, 'selectedMonth', newSelectedMonth as Range<12>);
};

const handleMultipleMonthSelection = (self: Calendar, itemEl: HTMLElement) => {
const column = itemEl.closest('[data-vc-column="month"]') as HTMLElement;
const yearEl = column.querySelector('[data-vc="year"]') as HTMLElement;
const selectedMonth = getColumnID(self, 'month', Number(itemEl.dataset.vcMonthsMonth));
const selectedMonth = getValue(self, 'month', Number(itemEl.dataset.vcMonthsMonth));
const selectedYear = Number(yearEl.dataset.vcYear);
const dateMin = getDate(self.context.dateMin);
const dateMax = getDate(self.context.dateMax);
Expand Down
15 changes: 15 additions & 0 deletions package/src/scripts/utils/getColumnID.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Calendar } from '@src/index';

const getColumnID = (self: Calendar, type: string) => {
if (self.type !== 'multiple') return { currentValue: null, columnID: 0 };

const columnEls = self.context.mainElement.querySelectorAll<HTMLElement>('[data-vc="column"]');
const columnID = Array.from(columnEls).findIndex((col) => col.closest(`[data-vc-column="${type}"]`));

return {
currentValue: columnID >= 0 ? Number(columnEls[columnID].querySelector<HTMLElement>(`[data-vc="${type}"]`)?.getAttribute(`data-vc-${type}`)) : null,
columnID: Math.max(columnID, 0),
};
};

export default getColumnID;
Loading