Skip to content

Commit

Permalink
dev selection
Browse files Browse the repository at this point in the history
  • Loading branch information
uvarov-frontend committed Sep 30, 2023
1 parent 3000839 commit 782d211
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 59 deletions.
4 changes: 4 additions & 0 deletions demo/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@
color: white !important;
}
}

.wrapper-calendar {
@apply w-[550px]
}
2 changes: 1 addition & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="initial-scale=1,width=device-width">
<meta name="format-detection" content="telephone=no">
<title>Vanilla Calendar - A pure JavaScript date and time picker using TypeScript so it supports any JS framework and library.</title>
<link rel="icon" type="image/svg+xml" href="@/demo/favicon.svg">
<link rel="icon" type="image/svg+xml" href="./favicon.svg">
<link rel="stylesheet" href="./index.css">
<script defer src="./main.ts" type="module"></script>
</head>
Expand Down
13 changes: 6 additions & 7 deletions demo/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ import VanillaCalendar from '@/package/src/scripts/vanilla-calendar';
import IVanillaCalendar, { Options } from '@/package/src';

const config: Options = {
type: 'multiple',
// settings: {
// selected: {
// month: 3,
// year: 2023,
// },
// },
settings: {
selected: {
month: 3,
year: 2023,
},
},
};

document.addEventListener('DOMContentLoaded', () => {
Expand Down
4 changes: 3 additions & 1 deletion demo/pages/multiple/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<body class="font-sans bg-white bg-light-mode text-slate-900 min-h-screen container mx-auto text-center flex flex-col items-center py-12 dark:bg-slate-900 dark:bg-dark-mode dark:text-white">
<h1 class="block mb-7 text-6xl font-extrabold">Vanilla Calendar</h1>
<p class="text-lg mb-12 dark:text-slate-400">A pure JavaScript date and time picker using TypeScript so it supports any JS framework and library.</p>
<div id="calendar"></div>
<div class="wrapper-calendar">
<div id="calendar"></div>
</div>
</body>
</html>
3 changes: 3 additions & 0 deletions package/src/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ const classes = {
calendarInputWrapper: 'vanilla-calendar-input-wrapper',
controls: 'vanilla-calendar-controls',
grid: 'vanilla-calendar-grid',
gridDisabled: 'vanilla-calendar-grid_disabled',
column: 'vanilla-calendar-column',
columnMonth: 'vanilla-calendar-column_month',
columnYear: 'vanilla-calendar-column_year',
header: 'vanilla-calendar-header',
headerContent: 'vanilla-calendar-header__content',
month: 'vanilla-calendar-month',
Expand Down
20 changes: 20 additions & 0 deletions package/src/scripts/helpers/getColumn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { IVanillaCalendar } from '../../types';

const getColumn = (self: IVanillaCalendar, columnClass: string, personalClass: string, id: number, dataAttr: string) => {
const columnEls = (self.HTMLElement as HTMLElement).querySelectorAll(`.${self.CSSClasses.column}`) as NodeListOf<HTMLElement>;
const firstColumnID = Number((columnEls[0].querySelector(`.${personalClass}`) as HTMLElement).getAttribute(dataAttr));
const lastColumnID = Number((columnEls[columnEls.length - 1].querySelector(`.${personalClass}`) as HTMLElement).getAttribute(dataAttr));
const indexColumn = [...columnEls].findIndex((column) => column.classList.contains(columnClass));

if (firstColumnID === lastColumnID || indexColumn < 0) {
return id;
}

if (firstColumnID < lastColumnID || (self.currentType !== 'year' && firstColumnID > lastColumnID)) {
return id - indexColumn;
}

return id;
};

export default getColumn;
32 changes: 25 additions & 7 deletions package/src/scripts/methods/clickCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import createYears from './createYears';
import generateDate from '../helpers/generateDate';
import mainMethod from './mainMethod';
import handlerMultipleRanged from './handlerMultipleRanged';
import getColumn from '../helpers/getColumn';

const clickCalendar = (self: IVanillaCalendar) => {
(self.HTMLElement as HTMLElement).addEventListener('click', (e) => {
Expand All @@ -22,6 +23,8 @@ const clickCalendar = (self: IVanillaCalendar) => {
const yearItemEl: HTMLElement | null = element.closest(`.${self.CSSClasses.yearsYear}`);
const monthHeaderEl: HTMLElement | null = element.closest(`.${self.CSSClasses.month}`);
const monthItemEl: HTMLElement | null = element.closest(`.${self.CSSClasses.monthsMonth}`);
const gridEl: HTMLElement | null = element.closest(`.${self.CSSClasses.grid}`);
const columnEl: HTMLElement | null = element.closest(`.${self.CSSClasses.column}`);

const clickArrowMonth = () => {
if (arrowEl && self.currentType !== 'year' && self.currentType !== 'month') {
Expand Down Expand Up @@ -141,23 +144,25 @@ const clickCalendar = (self: IVanillaCalendar) => {
};

const clickYear = () => {
if (!self.settings.selection.year || self.currentType === 'multiple') return;
if (!self.settings.selection.year) return;
if (arrowEl && self.currentType === 'year') {
if (self.viewYear === undefined) return;
if (arrowNextEl) {
self.viewYear += 15;
} else if (arrowPrevEl) {
self.viewYear -= 15;
}
createYears(self);
createYears(self, e.target as HTMLElement);
} else if (self.currentType !== 'year' && yearHeaderEl) {
createYears(self);
createYears(self, e.target as HTMLElement);
} else if (self.currentType === 'year' && yearHeaderEl) {
self.currentType = self.type;
mainMethod(self);
} else if (yearItemEl) {
if (self.selectedMonth === undefined || !self.dateMin || !self.dateMax) return;
self.selectedYear = Number(yearItemEl.dataset.calendarYear);
self.selectedYear = self.type === 'multiple'
? getColumn(self, self.CSSClasses.columnYear, self.CSSClasses.year, Number(yearItemEl.dataset.calendarYear), 'data-calendar-selected-year')
: Number(yearItemEl.dataset.calendarYear);
self.currentType = self.type;
if (self.selectedMonth < self.dateMin.getMonth() && self.selectedYear === self.dateMin.getFullYear()) {
self.selectedMonth = self.dateMin.getMonth();
Expand All @@ -167,21 +172,34 @@ const clickCalendar = (self: IVanillaCalendar) => {
}
if (self.actions.clickYear) self.actions.clickYear(e, self.selectedYear);
mainMethod(self);
} else if (self.type === 'multiple' && self.currentType === 'year' && gridEl && !columnEl) {
self.currentType = self.type;
mainMethod(self);
}
};

const clickMonth = () => {
if (!self.settings.selection.month || self.currentType === 'multiple') return;
if (!self.settings.selection.month) return;
if (self.currentType !== 'month' && monthHeaderEl) {
createMonths(self);
createMonths(self, e.target as HTMLElement);
} else if (self.currentType === 'month' && monthHeaderEl) {
self.currentType = self.type;
mainMethod(self);
} else if (monthItemEl) {
self.selectedMonth = Number(monthItemEl.dataset.calendarMonth);
self.selectedMonth = self.type === 'multiple'
? getColumn(self, self.CSSClasses.columnMonth, self.CSSClasses.month, Number(monthItemEl.dataset.calendarMonth), 'data-calendar-selected-month')
: Number(monthItemEl.dataset.calendarMonth);
if (self.type === 'multiple') {
const column = monthItemEl.closest(`.${self.CSSClasses.columnMonth}`) as HTMLElement;
const year = column.querySelector(`.${self.CSSClasses.year}`) as HTMLElement;
self.selectedYear = Number(year.dataset.calendarSelectedYear);
}
self.currentType = self.type;
if (self.actions.clickMonth) self.actions.clickMonth(e, self.selectedMonth);
mainMethod(self);
} else if (self.type === 'multiple' && self.currentType === 'month' && gridEl && !columnEl) {
self.currentType = self.type;
mainMethod(self);
}
};

Expand Down
23 changes: 21 additions & 2 deletions package/src/scripts/methods/createDOM.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { IVanillaCalendar } from '../../types';
import { IVanillaCalendar, TypesCalendar } from '../../types';
import { DOMParser, MultipleParser } from '../helpers/parserComponent';

const createDOM = (self: IVanillaCalendar) => {
const createDOM = (self: IVanillaCalendar, initType?: TypesCalendar, target?: HTMLElement) => {
const calendarElement = (self.HTMLElement as HTMLElement);
calendarElement.classList.add(self.CSSClasses.calendar);

const switcherTypeMultiple = (columnClass: string, DOMTemplates: string) => {
if (!target) return;
const controls = (self.HTMLElement as HTMLElement).querySelector(`.${self.CSSClasses.controls}`);
if (controls) (self.HTMLElement as HTMLElement).removeChild(controls);
const grid = (self.HTMLElement as HTMLElement).querySelector(`.${self.CSSClasses.grid}`) as HTMLElement;
grid.classList.add(self.CSSClasses.gridDisabled);
const columnElement = target.closest(`.${self.CSSClasses.column}`) as HTMLElement;
columnElement.classList.add(columnClass);
columnElement.innerHTML = DOMParser(self, DOMTemplates);
};

switch (self.currentType) {
case 'default':
calendarElement.classList.add(self.CSSClasses.calendarDefault);
Expand All @@ -20,12 +31,20 @@ const createDOM = (self: IVanillaCalendar) => {
calendarElement.innerHTML = MultipleParser(self, DOMParser(self, self.DOMTemplates.multiple));
break;
case 'month':
if (initType === 'multiple') {
switcherTypeMultiple(self.CSSClasses.columnMonth, self.DOMTemplates.month);
break;
}
calendarElement.classList.remove(self.CSSClasses.calendarDefault);
calendarElement.classList.add(self.CSSClasses.calendarMonth);
calendarElement.classList.remove(self.CSSClasses.calendarYear);
calendarElement.innerHTML = DOMParser(self, self.DOMTemplates.month);
break;
case 'year':
if (initType === 'multiple') {
switcherTypeMultiple(self.CSSClasses.columnYear, self.DOMTemplates.year);
break;
}
calendarElement.classList.remove(self.CSSClasses.calendarDefault);
calendarElement.classList.remove(self.CSSClasses.calendarMonth);
calendarElement.classList.add(self.CSSClasses.calendarYear);
Expand Down
9 changes: 5 additions & 4 deletions package/src/scripts/methods/createMonths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import createDOM from './createDOM';
import showMonth from './showMonth';
import showYear from './showYear';

const createMonths = (self: IVanillaCalendar) => {
const createMonths = (self: IVanillaCalendar, target?: HTMLElement) => {
const selectedMonth = target?.dataset.calendarSelectedMonth ? Number(target?.dataset.calendarSelectedMonth) : self.selectedMonth;
self.currentType = 'month';
createDOM(self);
createDOM(self, self.type, target);
showMonth(self);
showYear(self);

const monthsEl = (self.HTMLElement as HTMLElement).querySelector(`.${self.CSSClasses.months}`);
if (self.selectedMonth === undefined || self.selectedYear === undefined || !self.dateMin || !self.dateMax || !monthsEl) return;
if (self.selectedYear === undefined || !self.dateMin || !self.dateMax || !monthsEl) return;

if (self.settings.selection.month) monthsEl.classList.add(self.CSSClasses.monthsSelecting);

Expand All @@ -22,7 +23,7 @@ const createMonths = (self: IVanillaCalendar) => {
const month = self.locale.months[i];
const monthEl = templateMonthEl.cloneNode(true) as HTMLButtonElement;

if (i === self.selectedMonth) {
if (i === selectedMonth) {
monthEl.classList.add(self.CSSClasses.monthsMonthSelected);
}
if (i < self.dateMin.getMonth() && self.selectedYear === self.dateMin.getFullYear()) {
Expand Down
7 changes: 4 additions & 3 deletions package/src/scripts/methods/createYears.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import createDOM from './createDOM';
import showMonth from './showMonth';
import showYear from './showYear';

const createYears = (self: IVanillaCalendar) => {
const createYears = (self: IVanillaCalendar, target?: HTMLElement) => {
if (self.viewYear === undefined || !self.dateMin || !self.dateMax) return;
const selectedYear = target?.dataset.calendarSelectedYear ? Number(target?.dataset.calendarSelectedYear) : self.selectedYear;
self.currentType = 'year';
createDOM(self);
createDOM(self, self.type, target);
showMonth(self);
showYear(self);
controlArrows(self);
Expand All @@ -23,7 +24,7 @@ const createYears = (self: IVanillaCalendar) => {
const year = i;
const yearEl = templateYearEl.cloneNode(true) as HTMLButtonElement;

if (year === self.selectedYear) {
if (year === selectedYear) {
yearEl.classList.add(self.CSSClasses.yearsYearSelected);
}
if (year < self.dateMin.getFullYear()) {
Expand Down
2 changes: 1 addition & 1 deletion package/src/scripts/methods/showMonth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const showMonth = (self: IVanillaCalendar) => {
months[index].dataset.calendarSelectedMonth = String(selectedMonth);
months[index].innerText = self.locale.months[selectedMonth];

if (!self.settings.selection.month || self.currentType === 'multiple') {
if (!self.settings.selection.month) {
months[index].tabIndex = -1;
months[index].classList.add(self.CSSClasses.monthDisabled);
} else {
Expand Down
2 changes: 1 addition & 1 deletion package/src/scripts/methods/showYear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const showYear = (self: IVanillaCalendar) => {
years[index].dataset.calendarSelectedYear = String(selectedYear);
years[index].innerText = String(selectedYear);

if (!self.settings.selection.year || self.currentType === 'multiple') {
if (!self.settings.selection.year) {
years[index].tabIndex = -1;
years[index].classList.add(self.CSSClasses.yearDisabled);
} else {
Expand Down
10 changes: 0 additions & 10 deletions package/src/styles/themes/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@
@apply outline-orange-300
}

[data-calendar-theme="dark"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-month,
[data-calendar-theme="dark"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-year {
@apply text-white hover:text-white
}

[data-calendar-theme="dark"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-month.vanilla-calendar-month_disabled,
[data-calendar-theme="dark"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-year.vanilla-calendar-year_disabled {
@apply text-white
}

[data-calendar-theme="dark"] .vanilla-calendar-arrow::before {
@apply bg-white;
}
Expand Down
10 changes: 0 additions & 10 deletions package/src/styles/themes/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@
@apply outline-orange-300
}

[data-calendar-theme="light"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-month,
[data-calendar-theme="light"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-year {
@apply text-slate-900 hover:text-slate-900
}

[data-calendar-theme="light"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-month.vanilla-calendar-month_disabled,
[data-calendar-theme="light"].vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-year.vanilla-calendar-year_disabled {
@apply text-slate-900
}

[data-calendar-theme="light"] .vanilla-calendar-arrow::before {
@apply bg-slate-900;
}
Expand Down
23 changes: 11 additions & 12 deletions package/src/styles/vanilla-calendar.css
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
.vanilla-calendar {
@apply p-4 rounded-xl relative flex flex-col min-w-[275px] w-max h-max
@apply p-4 rounded-xl relative flex flex-col min-w-[275px] max-w-full
}

.vanilla-calendar button:focus-visible {
@apply outline outline-1 rounded-lg
}

.vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-month,
.vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-year {
@apply cursor-default
}

.vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-month.vanilla-calendar-month_disabled,
.vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-year.vanilla-calendar-year_disabled {
@apply pointer-events-auto
}

.vanilla-calendar.vanilla-calendar_multiple .vanilla-calendar-days {
@apply grow-0
}
Expand Down Expand Up @@ -56,7 +46,16 @@
}

.vanilla-calendar-grid {
@apply grid grid-flow-col gap-7 grow
@apply grid grid-cols-[repeat(auto-fill,_minmax(220px,_1fr))] gap-7 grow
}

.vanilla-calendar-grid.vanilla-calendar-grid_disabled .vanilla-calendar-column {
@apply opacity-30 pointer-events-none
}

.vanilla-calendar-grid.vanilla-calendar-grid_disabled .vanilla-calendar-column.vanilla-calendar-column_month,
.vanilla-calendar-grid.vanilla-calendar-grid_disabled .vanilla-calendar-column.vanilla-calendar-column_year {
@apply opacity-100 pointer-events-auto
}

.vanilla-calendar-column {
Expand Down
3 changes: 3 additions & 0 deletions package/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ export interface ICSSClasses {
calendarInputWrapper: string;
controls: string;
grid: string;
gridDisabled: string;
column: string;
columnMonth: string;
columnYear: string;
header: string;
headerContent: string;
month: string;
Expand Down

0 comments on commit 782d211

Please sign in to comment.