From 46df593b788aa1b75f59e444570d410984c4d8f6 Mon Sep 17 00:00:00 2001 From: Gustavo Rodrigo Gularte Arend Date: Fri, 26 Apr 2024 00:20:53 -0300 Subject: [PATCH 01/20] chore: update branch --- .../Calendar/components/DateButton/index.js | 28 +++ .../Calendar/components/DateButton/index.scss | 63 +++++ .../Calendar/components/DateSelector/index.js | 219 ++++++++++++++++++ .../components/DateSelector/index.scss | 92 ++++++++ .../Calendar/components/Day/index.js | 43 ++++ .../Calendar/components/Day/index.scss | 53 +++++ .../Calendar/components/Days/index.js | 54 +++++ .../Calendar/components/NavButton/index.js | 36 +++ .../Calendar/components/NavButton/index.scss | 41 ++++ src/components/Calendar/images/arrows.svg | 4 + src/components/Calendar/images/navButton.svg | 3 + src/components/Calendar/index.js | 200 ++++++++++++++++ src/components/Calendar/index.scss | 77 ++++++ src/stories/Calendar.stories.js | 14 ++ 14 files changed, 927 insertions(+) create mode 100644 src/components/Calendar/components/DateButton/index.js create mode 100644 src/components/Calendar/components/DateButton/index.scss create mode 100644 src/components/Calendar/components/DateSelector/index.js create mode 100644 src/components/Calendar/components/DateSelector/index.scss create mode 100644 src/components/Calendar/components/Day/index.js create mode 100644 src/components/Calendar/components/Day/index.scss create mode 100644 src/components/Calendar/components/Days/index.js create mode 100644 src/components/Calendar/components/NavButton/index.js create mode 100644 src/components/Calendar/components/NavButton/index.scss create mode 100644 src/components/Calendar/images/arrows.svg create mode 100644 src/components/Calendar/images/navButton.svg create mode 100644 src/components/Calendar/index.js create mode 100644 src/components/Calendar/index.scss create mode 100644 src/stories/Calendar.stories.js diff --git a/src/components/Calendar/components/DateButton/index.js b/src/components/Calendar/components/DateButton/index.js new file mode 100644 index 00000000..0b75dc66 --- /dev/null +++ b/src/components/Calendar/components/DateButton/index.js @@ -0,0 +1,28 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; + +const html = ` +
  • +`; + +export default function DateButton(date) { + Component.call(this, { html }); + + const $button = this.selected.get('date').children[0]; + $button.innerText = date; +} + +DateButton.prototype = Object.assign( + DateButton.prototype, + Component.prototype, + { + active() { + this.selected.get('date').classList.add('active'); + }, + + setYear(year) { + const $button = this.selected.get('date').children[0]; + $button.innerText = year; + }, + }, +); diff --git a/src/components/Calendar/components/DateButton/index.scss b/src/components/Calendar/components/DateButton/index.scss new file mode 100644 index 00000000..8c5a228e --- /dev/null +++ b/src/components/Calendar/components/DateButton/index.scss @@ -0,0 +1,63 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.date { + button { + font-family: fonts.$primaryFont; + color: colors.$gray500; + font-size: 1.4rem; + font-weight: fonts.$medium; + line-height: 2rem; + + border: 0; + + background-color: transparent; + + cursor: pointer; + } +} + +.date.active { + button { + color: colors.$primary200; + font-size: 2.6rem; + font-weight: fonts.$bold; + line-height: 3.4rem; + + padding: 0.6rem 1.2rem; + border: 0.1rem solid rgb(209, 230, 255); + + background-color: rgba(209, 230, 255, 0.502); + border-radius: 1.4rem; + } +} + +@include breakpoints.from667 { + .date { + display: none; + + button { + width: 100%; + + font-size: fonts.$md; + line-height: 34px; + } + } + + .date.active { + display: flex; + + button { + color: colors.$gray800; + font-size: 2.6rem; + font-weight: fonts.$regular; + + padding: 0.6rem; + border: 0; + + background-color: transparent; + } + } +} diff --git a/src/components/Calendar/components/DateSelector/index.js b/src/components/Calendar/components/DateSelector/index.js new file mode 100644 index 00000000..ad50af7f --- /dev/null +++ b/src/components/Calendar/components/DateSelector/index.js @@ -0,0 +1,219 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; +import { listenBreakpoint } from '../../../../utils/breakpoints/breakpoints'; +import DateButton from '../DateButton'; + +const events = ['changeMonth', 'changeYear']; + +const html = ` + +`; + +const monthsBR = [ + 'Janeiro', + 'Fevereiro', + 'Março', + 'Abril', + 'Maio', + 'Junho', + 'Julho', + 'Agosto', + 'Setembro', + 'Outubro', + 'Novembro', + 'Dezembro', +]; + +let handleTouchStart; +let handleTouchMove; +function addTouchEvents(selector) { + let startTouch; + + handleTouchStart = (event) => { + startTouch = selector.isDesktop + ? event.touches[0].clientY + : event.touches[0].clientX; + }; + + handleTouchMove = (event) => { + event.preventDefault(); + const currentTouch = selector.isDesktop + ? event.touches[0].clientY + : event.touches[0].clientX; + let move = 0; + const moveRange = 20; + move = currentTouch - startTouch; + + if (Math.abs(move) > moveRange) { + const isSlideNext = move < 0; + const nextYear = +selector.dates[3].children[0].innerText; + const prevYear = +selector.dates[1].children[0].innerText; + const nextMonth = monthsBR.indexOf( + selector.dates[3].children[0].innerText, + ); + const prevMonth = monthsBR.indexOf( + selector.dates[1].children[0].innerText, + ); + if (isSlideNext && selector.isYear) selector.setYear(nextYear); + if (!isSlideNext && selector.isYear) selector.setYear(prevYear); + if (isSlideNext && !selector.isYear) selector.setMonth(nextMonth); + if (!isSlideNext && !selector.isYear) selector.setMonth(prevMonth); + startTouch = currentTouch; + } + }; + selector.dateSelector.addEventListener('touchstart', handleTouchStart); + selector.dateSelector.addEventListener('touchmove', handleTouchMove); +} + +let handleScroll; +function scrollModal(selector) { + const $dateSelector = selector.dateSelector; + + handleScroll = (event) => { + event.preventDefault(); + const isScrollNext = event.deltaY > 0; + + if (selector.isYear) { + const nextYear = +selector.dates[3].children[0].innerText; + const prevYear = +selector.dates[1].children[0].innerText; + const newYear = isScrollNext ? nextYear : prevYear; + selector.setYear(newYear); + } else { + const nextMonth = monthsBR.indexOf( + selector.dates[3].children[0].innerText, + ); + const prevMonth = monthsBR.indexOf( + selector.dates[1].children[0].innerText, + ); + const newMonth = isScrollNext ? nextMonth : prevMonth; + selector.setMonth(newMonth); + } + }; + + $dateSelector.addEventListener('wheel', handleScroll); + addTouchEvents(selector); +} + +function openModal(selector) { + const $dateSelector = selector.dateSelector; + $dateSelector.classList.add('active'); + const $activeDate = selector.date; + $activeDate.scrollIntoView({ + behavior: 'instant', + block: 'center', + inline: 'center', + }); +} + +function closeModal(selector, event) { + const $dateSelector = selector.dateSelector; + if ( + $dateSelector.classList.contains('active') && + !$dateSelector.contains(event.target) + ) { + $dateSelector.classList.remove('active'); + } +} + +export default function DateSelector(dateArray) { + Component.call(this, { html, events }); + + this.dateSelector = this.selected.get('date-selector'); + this.dateArray = dateArray; + + this.dateArray.forEach((item, index) => { + const dateButton = new DateButton(item); + dateButton.mount(this.dateSelector); + if (index === 2) { + dateButton.active(); + } + }); + + this.dates = this.dateSelector.querySelectorAll('li'); + this.date = this.dateSelector.querySelector('li.active'); + this.isYear = !Number.isNaN(+this.date.innerText); + listenBreakpoint('from667', (matches) => { + this.isDesktop = matches; + }); + + this.dateClickHandle = (index) => () => { + if (this.isYear) { + this.setYear(this.dateArray[index]); + } else { + this.setMonth(monthsBR.indexOf(this.dateArray[index])); + } + }; + + this.dates.forEach(($date, index) => { + $date.addEventListener('click', this.dateClickHandle(index)); + }); + this.openModalHandle = () => openModal(this); + this.dateSelector.addEventListener('click', this.openModalHandle); + + this.closeModalHandle = (event) => closeModal(this, event); + window.addEventListener('click', this.closeModalHandle); + + scrollModal(this); + + setTimeout(() => { + this.date.scrollIntoView({ + behavior: 'instant', + block: 'center', + inline: 'center', + }); + }); + + this.unmount(() => { + this.dateSelector.removeEventListener('click', this.openModalHandle); + window.removeEventListener('click', this.closeModalHandle); + this.dates.forEach(($date, index) => { + $date.removeEventListener('click', this.dateClickHandle(index)); + }); + this.dateSelector.removeEventListener('wheel', handleScroll); + this.dateSelector.removeEventListener('touchstart', handleTouchStart); + this.dateSelector.removeEventListener('touchmove', handleTouchMove); + }); +} + +DateSelector.prototype = Object.assign( + DateSelector.prototype, + Component.prototype, + { + setMonth(newMonth) { + for (let i = 0; i < this.dateArray.length; i += 1) { + const index = (newMonth - (2 - i) + 12) % 12; + this.dateArray[i] = monthsBR[index]; + } + + this.dateArray.forEach((item, index) => { + this.dates[index].children[0].innerText = item; + }); + + this.date.scrollIntoView({ + behavior: 'instant', + block: 'center', + inline: 'center', + }); + + this.emit('changeMonth', newMonth); + }, + + setYear(newYear) { + for (let i = 0; i < this.dateArray.length; i += 1) { + this.dateArray[i] = newYear - (2 - i); + } + + this.dateArray.forEach((item, index) => { + this.dates[index].children[0].innerText = item; + }); + + this.date.scrollIntoView({ + behavior: 'instant', + block: 'center', + inline: 'center', + }); + + this.emit('changeYear', newYear); + }, + }, +); diff --git a/src/components/Calendar/components/DateSelector/index.scss b/src/components/Calendar/components/DateSelector/index.scss new file mode 100644 index 00000000..5ab3b7d2 --- /dev/null +++ b/src/components/Calendar/components/DateSelector/index.scss @@ -0,0 +1,92 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.date-selector { + max-width: 33rem; + overflow-x: hidden; + + display: flex; + gap: 0.8rem; + + align-items: center; + + margin-bottom: 2.4rem; + padding-bottom: 2.4rem; + border-bottom: 0.1rem solid colors.$gray100; + + &:first-child { + order: 2; + } +} + +@include breakpoints.from667 { + .date-selector { + margin-bottom: 0; + padding: 0; + border-bottom: 0; + + &:last-child { + display: flex; + + align-items: center; + + order: 2; + + &::after { + width: 1.6rem; + height: 2.3rem; + + display: inline; + + background-image: url('../../images/arrows.svg'); + + content: ''; + } + } + } + + .date-selector.active { + width: 23.1rem; + max-height: 22.8rem; + overflow-y: hidden; + + display: grid; + gap: 0.6rem; + + position: absolute; + left: -4rem; + + background-color: colors.$secondary100; + + .date { + display: block; + } + + .date.active { + &::after { + width: 1.6rem; + height: 2.3rem; + + display: inline-block; + + margin-top: 1.4rem; + + position: absolute; + right: 2rem; + + background-image: url('../../images/arrows.svg'); + + content: ''; + } + + button { + font-weight: fonts.$bold; + + border-top: 0.1rem solid colors.$gray100; + border-bottom: 0.1rem solid colors.$gray100; + } + } + } +} diff --git a/src/components/Calendar/components/Day/index.js b/src/components/Calendar/components/Day/index.js new file mode 100644 index 00000000..97e08897 --- /dev/null +++ b/src/components/Calendar/components/Day/index.js @@ -0,0 +1,43 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; + +const events = ['changeDay']; + +const html = ` + +`; + +export default function Day(day, dayClass) { + Component.call(this, { html, events }); + + this.$day = this.selected.get('day-button'); + this.$day.innerText = day; + this.$day.setAttribute('aria-label', `Dia ${day}`); + if (dayClass) this.setClass(dayClass); + + const setActiveDayHandle = (event) => this.setClassActive(event); + this.$day.addEventListener('click', setActiveDayHandle); + + this.unmount(() => { + this.$day.removeEventListener('click', setActiveDayHandle); + }); +} + +Day.prototype = Object.assign(Day.prototype, Component.prototype, { + setClass(dayClass) { + this.$day.classList.add(dayClass); + }, + + setClassPrevMonth() { + this.$day.classList.add('prev-month'); + }, + + setClassActive() { + this.$day.classList.add('active'); + this.emit('changeDay', this.$day); + }, + + setClassNextMonth() { + this.$day.classList.add('next-month'); + }, +}); diff --git a/src/components/Calendar/components/Day/index.scss b/src/components/Calendar/components/Day/index.scss new file mode 100644 index 00000000..987e96fd --- /dev/null +++ b/src/components/Calendar/components/Day/index.scss @@ -0,0 +1,53 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.day-button { + width: 4rem; + height: 4rem; + + font-family: fonts.$primaryFont; + color: colors.$gray500; + font-size: 1.6rem; + font-weight: fonts.$medium; + + padding: 0; + border: 0.1rem solid colors.$gray100; + + background-color: colors.$secondary100; + border-radius: 1rem; + + cursor: pointer; + + &.prev-month, + &.next-month { + color: rgb(160, 174, 192); + + background-color: rgb(247, 250, 252); + } + + &:hover, + &.active { + color: colors.$primary200; + font-weight: fonts.$semiBold; + + border: 0.1rem solid rgb(209, 230, 255); + + background-color: rgba(209, 230, 255, 0.502); + } +} + +@include breakpoints.from667 { + .day-button { + width: 5.4rem; + height: 5.4rem; + + font-size: 1.8rem; + + &:hover, + &.active { + border: 0.2rem solid rgb(209, 230, 255); + } + } +} diff --git a/src/components/Calendar/components/Days/index.js b/src/components/Calendar/components/Days/index.js new file mode 100644 index 00000000..6eda5ae1 --- /dev/null +++ b/src/components/Calendar/components/Days/index.js @@ -0,0 +1,54 @@ +import { Component } from 'pet-dex-utilities'; +import Day from '../Day'; + +const events = ['changeDay', 'changeToPrevMonth', 'changeToNextMonth']; + +const html = ` +
    +`; + +function changeDay(days, newDayActive) { + const day = +newDayActive.innerText; + const isDayInPrevMonth = newDayActive.classList.contains('prev-month'); + const isDayInNextMonth = newDayActive.classList.contains('next-month'); + + if (isDayInPrevMonth) days.emit('changeToPrevMonth', day); + else if (isDayInNextMonth) days.emit('changeToNextMonth', day); + else days.emit('changeDay', day); +} + +export default function Days( + year, + month, + day, + totalDaysOfMonth, + firstDayOfMonthInWeek, +) { + Component.call(this, { html, events }); + + const $container = this.selected.get('days-container'); + + const totalDaysInCalendar = 42; + for ( + let i = -firstDayOfMonthInWeek; + i < totalDaysInCalendar - firstDayOfMonthInWeek; + i += 1 + ) { + const date = new Date(year, month, i); + const dayNumber = date.getDate(); + const firstDayOfMonth = 1; + + const dayButton = new Day(dayNumber); + + if (i < firstDayOfMonth) dayButton.setClassPrevMonth(); + if (i > totalDaysOfMonth) dayButton.setClassNextMonth(); + if (i === day) dayButton.setClassActive(); + + dayButton.mount($container); + dayButton.listen('changeDay', (newDayActive) => + changeDay(this, newDayActive), + ); + } +} + +Days.prototype = Object.assign(Days.prototype, Component.prototype, {}); diff --git a/src/components/Calendar/components/NavButton/index.js b/src/components/Calendar/components/NavButton/index.js new file mode 100644 index 00000000..bef7bfb3 --- /dev/null +++ b/src/components/Calendar/components/NavButton/index.js @@ -0,0 +1,36 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; +import navButton from '../../images/navButton.svg'; + +const events = ['prev', 'next']; + +const html = ` + +`; + +export default function NavButton(position) { + Component.call(this, { html, events }); + + this.$navButton = this.selected.get('nav-button'); + this.$navButton.classList.add(position); + const isPrev = this.$navButton.classList.contains('prev'); + this.$navButton.setAttribute( + 'aria-label', + isPrev ? 'Ir para o mês anterior' : 'Ir para o próximo mês', + ); + + const navButtonClickHandle = () => { + if (isPrev) { + this.emit('prev'); + } else { + this.emit('next'); + } + }; + this.$navButton.addEventListener('click', navButtonClickHandle); +} + +NavButton.prototype = Object.assign( + NavButton.prototype, + Component.prototype, + {}, +); diff --git a/src/components/Calendar/components/NavButton/index.scss b/src/components/Calendar/components/NavButton/index.scss new file mode 100644 index 00000000..455f811e --- /dev/null +++ b/src/components/Calendar/components/NavButton/index.scss @@ -0,0 +1,41 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.nav-button { + display: none; +} + +@include breakpoints.from667 { + .nav-button { + width: 4.6rem; + height: 4.6rem; + + display: grid; + + align-items: center; + justify-content: center; + + font-family: Nato Sans; + color: colors.$gray300; + font-size: 2rem; + + border: 0.1rem solid rgb(160, 174, 192); + + background-color: transparent; + border-radius: 1.4rem; + + cursor: pointer; + } + + .prev { + grid-area: 1; + } + + .next { + justify-self: end; + + transform: rotate(180deg); + } +} diff --git a/src/components/Calendar/images/arrows.svg b/src/components/Calendar/images/arrows.svg new file mode 100644 index 00000000..1ebda089 --- /dev/null +++ b/src/components/Calendar/images/arrows.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/Calendar/images/navButton.svg b/src/components/Calendar/images/navButton.svg new file mode 100644 index 00000000..ea74a960 --- /dev/null +++ b/src/components/Calendar/images/navButton.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js new file mode 100644 index 00000000..87b89c71 --- /dev/null +++ b/src/components/Calendar/index.js @@ -0,0 +1,200 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; +import dayjs from 'dayjs'; +import DateSelector from './components/DateSelector'; +import NavButton from './components/NavButton'; +import Days from './components/Days'; + +const events = ['changeDate', 'changeMonth', 'changeYear']; + +const monthsBR = [ + 'Janeiro', + 'Fevereiro', + 'Março', + 'Abril', + 'Maio', + 'Junho', + 'Julho', + 'Agosto', + 'Setembro', + 'Outubro', + 'Novembro', + 'Dezembro', +]; + +const currentMonth = dayjs().month(); +const months = new Array(5); +for (let i = 0; i < months.length; i += 1) { + const monthIndex = (currentMonth - (2 - i) + 12) % 12; + months[i] = monthsBR[monthIndex]; +} + +const currentYear = dayjs().year(); +const years = new Array(5); +for (let i = 0; i < years.length; i += 1) { + years[i] = currentYear - (2 - i); +} + +const html = ` +
    + +
    +
    +

    Dom

    +

    Seg

    +

    Ter

    +

    Qua

    +

    Qui

    +

    Sex

    +

    Sab

    +
    +
    +`; + +export default function Calendar() { + Component.call(this, { html, events }); + + this.setDate(); + + this.monthSelect = new DateSelector(months); + this.monthSelect.mount(this.selected.get('calendar-date')); + this.monthSelect.listen('changeMonth', (newMonth) => + this.setDate(this.day, newMonth, this.year), + ); + + this.yearSelect = new DateSelector(years); + this.yearSelect.mount(this.selected.get('calendar-date')); + this.yearSelect.listen('changeYear', (newYear) => + this.setDate(this.day, this.month, newYear), + ); + + this.navButton = new NavButton('prev'); + this.navButton.mount(this.selected.get('calendar-nav')); + this.navButton.listen('prev', () => this.goToPrevMonth()); + + this.navButton = new NavButton('next'); + this.navButton.mount(this.selected.get('calendar-nav')); + this.navButton.listen('next', () => this.goToNextMonth()); +} + +Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { + getDate() { + return { + day: this.day, + month: this.month, + year: this.year, + }; + }, + + setDate(day, month, year) { + this.day = day || dayjs().date(); + this.month = month !== undefined ? month : dayjs().month(); + this.year = year || dayjs().year(); + this.totalDaysOfMonth = dayjs( + `${this.year}-${this.month + 1}`, + ).daysInMonth(); + this.firstDayOfMonthInWeek = + dayjs(`${this.year}-${this.month + 1}-1`).day() - 1; + + this.setDays(); + + this.emit('changeDate', { + day: this.day, + month: this.month, + year: this.year, + }); + }, + + getDay() { + return this.day; + }, + + setDay(day) { + if (day < 1 || day > this.totalDaysOfMonth) { + throw new Error('Dia inválido'); + } else if (typeof day !== 'number') { + throw new Error('O valor não é um number'); + } else { + this.setDate(day, this.month, this.year); + } + }, + + setDays() { + if (this.days) this.days.unmount(); + this.days = new Days( + this.year, + this.month, + this.day, + this.totalDaysOfMonth, + this.firstDayOfMonthInWeek, + ); + this.days.mount(this.selected.get('calendar-days')); + + this.days.listen('changeDay', (newDay) => { + this.setDate(newDay, this.month, this.year); + }); + + this.days.listen('changeToPrevMonth', (newDay) => { + this.goToPrevMonth(); + this.setDay(newDay); + }); + + this.days.listen('changeToNextMonth', (newDay) => { + this.goToNextMonth(); + this.setDay(newDay); + }); + }, + + getMonth() { + return this.month; + }, + + setMonth(month) { + if (month < 0 || month > 11) { + throw new Error('Mês inválido'); + } else if (typeof month !== 'number') { + throw new Error('O valor não é um number'); + } else { + this.setDate(this.day, month, this.year); + } + }, + + getYear() { + return this.year; + }, + + setYear(year) { + if (year < 0) { + throw new Error('Ano inválido'); + } else if (typeof year !== 'number') { + throw new Error('O valor não é um number'); + } else { + this.setDate(this.day, this.month, year); + } + }, + + goToPrevMonth() { + this.month -= 1; + if (this.month < 0) { + this.month = 11; + this.year -= 1; + this.yearSelect.setYear(this.year); + } + this.monthSelect.setMonth(this.month); + this.setDate(this.day, this.month, this.year); + }, + + goToNextMonth() { + this.month += 1; + if (this.month > 11) { + this.month = 0; + this.year += 1; + this.yearSelect.setYear(this.year); + } + this.monthSelect.setMonth(this.month); + this.setDate(this.day, this.month, this.year); + }, +}); diff --git a/src/components/Calendar/index.scss b/src/components/Calendar/index.scss new file mode 100644 index 00000000..b50dcef6 --- /dev/null +++ b/src/components/Calendar/index.scss @@ -0,0 +1,77 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.calendar-container { + display: grid; + + padding: 2.4rem 0; + + background-color: rgb(250, 250, 250); + + &__date { + width: 100%; + max-width: 34rem; + + margin: 0 auto; + + &-select { + display: grid; + + justify-items: center; + } + } + + &__days { + margin: 0 auto; + padding: 0 1rem; + + div { + display: grid; + grid-template-columns: repeat(7, 1fr); + gap: 0.8rem; + + justify-items: center; + } + + p { + font-family: Noto Sans; + color: colors.$gray300; + text-align: center; + font-size: 1.2rem; + font-weight: fonts.$regular; + line-height: 2rem; + + padding-bottom: 1.2rem; + } + } +} + +@include breakpoints.from667 { + .calendar-container { + &__days { + p { + font-size: 1.6rem; + } + } + + &__date { + max-width: 42rem; + + display: grid; + grid-template-columns: 1fr 1fr 1fr; + + align-items: center; + + margin: 0 auto; + padding-bottom: 3rem; + + &-select { + display: flex; + + position: relative; + } + } + } +} diff --git a/src/stories/Calendar.stories.js b/src/stories/Calendar.stories.js new file mode 100644 index 00000000..133cf423 --- /dev/null +++ b/src/stories/Calendar.stories.js @@ -0,0 +1,14 @@ +import Calendar from '../components/Calendar'; + +export default { + title: 'Components/Calendar', + render: (args) => { + const calendar = new Calendar(args); + const $container = document.createElement('div'); + calendar.mount($container); + + return $container; + }, +}; + +export const Default = {}; From c5080a8dfd31b9c735c89c8a4723b73f3f76ff7a Mon Sep 17 00:00:00 2001 From: Gustavo Rodrigo Gularte Arend Date: Fri, 26 Apr 2024 01:26:42 -0300 Subject: [PATCH 02/20] chore: update branch --- src/components/Calendar/components/DateButton/index.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/Calendar/components/DateButton/index.js b/src/components/Calendar/components/DateButton/index.js index 0b75dc66..e2bae8a5 100644 --- a/src/components/Calendar/components/DateButton/index.js +++ b/src/components/Calendar/components/DateButton/index.js @@ -19,10 +19,5 @@ DateButton.prototype = Object.assign( active() { this.selected.get('date').classList.add('active'); }, - - setYear(year) { - const $button = this.selected.get('date').children[0]; - $button.innerText = year; - }, }, ); From 9a87cb5a0f574634615df90d4313cfc62ef5fc59 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 8 May 2024 14:55:33 -0300 Subject: [PATCH 03/20] chore: update branch --- .../Calendar/components/DateButton/index.js | 2 +- .../Calendar/components/DateButton/index.scss | 17 ++++++++--------- src/components/Calendar/components/Day/index.js | 2 +- .../Calendar/components/Day/index.scss | 14 +++++++------- .../Calendar/components/NavButton/index.scss | 4 ++-- src/components/Calendar/index.js | 2 +- src/components/Calendar/index.scss | 8 ++++---- src/styles/colors.scss | 2 ++ 8 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/components/Calendar/components/DateButton/index.js b/src/components/Calendar/components/DateButton/index.js index e2bae8a5..5f7e2c3e 100644 --- a/src/components/Calendar/components/DateButton/index.js +++ b/src/components/Calendar/components/DateButton/index.js @@ -2,7 +2,7 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; const html = ` -
  • +
  • `; export default function DateButton(date) { diff --git a/src/components/Calendar/components/DateButton/index.scss b/src/components/Calendar/components/DateButton/index.scss index 8c5a228e..c190933f 100644 --- a/src/components/Calendar/components/DateButton/index.scss +++ b/src/components/Calendar/components/DateButton/index.scss @@ -4,12 +4,12 @@ @use '~styles/breakpoints.scss' as breakpoints; .date { - button { + &__button { font-family: fonts.$primaryFont; color: colors.$gray500; font-size: 1.4rem; font-weight: fonts.$medium; - line-height: 2rem; + line-height: 2.5; border: 0; @@ -20,16 +20,15 @@ } .date.active { - button { + &__button { color: colors.$primary200; font-size: 2.6rem; font-weight: fonts.$bold; - line-height: 3.4rem; + line-height: 1.3; padding: 0.6rem 1.2rem; - border: 0.1rem solid rgb(209, 230, 255); + border: 0.1rem solid colors.$gray100; - background-color: rgba(209, 230, 255, 0.502); border-radius: 1.4rem; } } @@ -38,18 +37,18 @@ .date { display: none; - button { + &__button { width: 100%; font-size: fonts.$md; - line-height: 34px; + line-height: 1.8; } } .date.active { display: flex; - button { + &__button { color: colors.$gray800; font-size: 2.6rem; font-weight: fonts.$regular; diff --git a/src/components/Calendar/components/Day/index.js b/src/components/Calendar/components/Day/index.js index 97e08897..9de8e5e1 100644 --- a/src/components/Calendar/components/Day/index.js +++ b/src/components/Calendar/components/Day/index.js @@ -4,7 +4,7 @@ import './index.scss'; const events = ['changeDay']; const html = ` - + `; export default function Day(day, dayClass) { diff --git a/src/components/Calendar/components/Day/index.scss b/src/components/Calendar/components/Day/index.scss index 987e96fd..7d91e632 100644 --- a/src/components/Calendar/components/Day/index.scss +++ b/src/components/Calendar/components/Day/index.scss @@ -3,7 +3,7 @@ @use '~styles/fonts.scss' as fonts; @use '~styles/breakpoints.scss' as breakpoints; -.day-button { +.day__button { width: 4rem; height: 4rem; @@ -22,9 +22,9 @@ &.prev-month, &.next-month { - color: rgb(160, 174, 192); + color: colors.$gray300; - background-color: rgb(247, 250, 252); + background-color: colors.$gray150; } &:hover, @@ -32,14 +32,14 @@ color: colors.$primary200; font-weight: fonts.$semiBold; - border: 0.1rem solid rgb(209, 230, 255); + border: 0.1rem solid colors.$blue100; - background-color: rgba(209, 230, 255, 0.502); + background-color: colors.$blue150; } } @include breakpoints.from667 { - .day-button { + .day__button { width: 5.4rem; height: 5.4rem; @@ -47,7 +47,7 @@ &:hover, &.active { - border: 0.2rem solid rgb(209, 230, 255); + border: 0.2rem solid colors.$blue100; } } } diff --git a/src/components/Calendar/components/NavButton/index.scss b/src/components/Calendar/components/NavButton/index.scss index 455f811e..7e5f13f3 100644 --- a/src/components/Calendar/components/NavButton/index.scss +++ b/src/components/Calendar/components/NavButton/index.scss @@ -17,11 +17,11 @@ align-items: center; justify-content: center; - font-family: Nato Sans; + font-family: fonts.$primaryFont; color: colors.$gray300; font-size: 2rem; - border: 0.1rem solid rgb(160, 174, 192); + border: 0.1rem solid colors.$gray500; background-color: transparent; border-radius: 1.4rem; diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js index 87b89c71..da587b19 100644 --- a/src/components/Calendar/index.js +++ b/src/components/Calendar/index.js @@ -50,7 +50,7 @@ const html = `

    Sex

    Sab

    -
    `; diff --git a/src/components/Calendar/index.scss b/src/components/Calendar/index.scss index b50dcef6..15112102 100644 --- a/src/components/Calendar/index.scss +++ b/src/components/Calendar/index.scss @@ -8,7 +8,7 @@ padding: 2.4rem 0; - background-color: rgb(250, 250, 250); + background-color: colors.$shade50; &__date { width: 100%; @@ -36,12 +36,12 @@ } p { - font-family: Noto Sans; + font-family: fonts.$primaryFont; color: colors.$gray300; text-align: center; - font-size: 1.2rem; + font-size: 1.4rem; font-weight: fonts.$regular; - line-height: 2rem; + line-height: 1.4; padding-bottom: 1.2rem; } diff --git a/src/styles/colors.scss b/src/styles/colors.scss index 0dbdbfc8..a2ba03bb 100644 --- a/src/styles/colors.scss +++ b/src/styles/colors.scss @@ -45,4 +45,6 @@ $shade100: rgb(0, 0, 0); // custom +$blue100: rgb(209, 230, 255); +$blue150: rgba(209, 230, 255, 0.502); $blue600: rgb(18, 104, 204); From 070bea4507702f4e8b911c5a134d6e2b0aa1c9e3 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 8 May 2024 15:22:04 -0300 Subject: [PATCH 04/20] chore: colors adjusted --- src/components/Calendar/components/DateButton/index.scss | 2 ++ src/styles/colors.scss | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/Calendar/components/DateButton/index.scss b/src/components/Calendar/components/DateButton/index.scss index c190933f..07343804 100644 --- a/src/components/Calendar/components/DateButton/index.scss +++ b/src/components/Calendar/components/DateButton/index.scss @@ -29,6 +29,8 @@ padding: 0.6rem 1.2rem; border: 0.1rem solid colors.$gray100; + background-color: colors.$gray150; + border-radius: 1.4rem; } } diff --git a/src/styles/colors.scss b/src/styles/colors.scss index a2ba03bb..edf87064 100644 --- a/src/styles/colors.scss +++ b/src/styles/colors.scss @@ -21,16 +21,15 @@ $success200: rgb(49, 138, 94); // error $error100: rgb(179, 38, 30); -// neutrals (Gray) +// neutrals (Grey) $gray100: rgb(236, 239, 242); -$gray150: rgb(236, 239, 242); +$gray150: rgb(236, 239, 242, 0.502); $gray200: rgb(224, 224, 224); -$gray250: rgb(172, 172, 181); $gray300: rgb(179, 190, 205); $gray400: rgb(141, 141, 141); $gray500: rgb(96, 104, 115); $gray600: rgb(102, 116, 121); -$gray700: rgb(6, 8, 9); +$gray700: rgb(128, 139, 154); $gray800: rgb(57, 67, 79); $gray900: rgb(32, 35, 38); From b300c64ffdb8a7db3c3c3ea6e83a82881f9898b3 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 8 May 2024 15:42:05 -0300 Subject: [PATCH 05/20] chore: index.scss adjusted --- src/components/Button/index.scss | 72 ++--- .../app/components/SideMenu/index.scss | 294 +++++++++--------- 2 files changed, 183 insertions(+), 183 deletions(-) diff --git a/src/components/Button/index.scss b/src/components/Button/index.scss index 61d804ba..6d427cdf 100644 --- a/src/components/Button/index.scss +++ b/src/components/Button/index.scss @@ -1,36 +1,36 @@ -@use '~styles/colors.scss' as colors; - -.button { - font-family: 'Noto Sans', sans-serif; - color: rgb(255, 255, 255); - font-size: 1.6rem; - font-weight: 500; - - padding: 1.6rem; - border: unset; - - background-color: colors.$primary200; - border-radius: 1.4rem; - - transition: 0.3s ease-in-out; - - cursor: pointer; - appearance: none; - - &--block { - width: 100%; - - display: block; - } - - &:hover:not(:disabled) { - background: colors.$primary600; - transform: scale(1.02); - } - - &:disabled { - background: colors.$gray600; - - cursor: not-allowed; - } -} +@use '~styles/colors.scss' as colors; + +.button { + font-family: 'Noto Sans', sans-serif; + color: rgb(255, 255, 255); + font-size: 1.6rem; + font-weight: 500; + + padding: 1.6rem; + border: unset; + + background-color: colors.$primary200; + border-radius: 1.4rem; + + transition: 0.3s ease-in-out; + + cursor: pointer; + appearance: none; + + &--block { + width: 100%; + + display: block; + } + + &:hover:not(:disabled) { + background: colors.$primary600; + transform: scale(1.02); + } + + &:disabled { + background: colors.$gray600; + + cursor: not-allowed; + } +} diff --git a/src/layouts/app/components/SideMenu/index.scss b/src/layouts/app/components/SideMenu/index.scss index 0953bb8f..68d4cc38 100644 --- a/src/layouts/app/components/SideMenu/index.scss +++ b/src/layouts/app/components/SideMenu/index.scss @@ -1,147 +1,147 @@ -@use '~styles/colors.scss' as colors; -@use '~styles/breakpoints.scss' as breakpoints; -@use '~styles/fonts.scss' as fonts; - -.side-menu-nav { - display: flex; - - align-items: center; - justify-content: space-between; - padding-inline: 2rem; - - &__logo-container { - display: none; - padding-block: 4rem 2rem; - - text-align: center; - } - - &__logo { - max-width: 100%; - } - - &__icons { - display: flex; - gap: 2.4rem; - - align-items: center; - justify-content: center; - } - - &__notifications { - width: 1.6rem; - height: 1.95rem; - } - - &__perfil { - width: 4.3rem; - height: 4.3rem; - - border-radius: 100%; - } - - &__exit { - width: 2rem; - height: 2rem; - } - - &__exitmenu { - width: 2.9rem; - height: 2.4rem; - } -} - -.side-menu-content { - width: 28rem; - - display: flex; - flex-direction: column; - gap: 4.2rem; - - margin: 0 auto; - - &__line { - width: 100%; - - border: 0.1rem solid colors.$secondary100; - } - - &__lineinside { - width: 100%; - - margin: 4.2rem 0; - border: 0.1rem solid colors.$secondary100; - } - - &__yourpet { - font-family: fonts.$primaryFont; - } - - &__title-yourpet { - color: colors.$secondary100; - font-size: 1.6rem; - font-weight: fonts.$bold; - font-style: fonts.$normal; - } - - &__itens { - font-family: fonts.$primaryFont; - color: colors.$secondary100; - font-size: 1.6rem; - } - - &__ul { - display: flex; - flex-direction: column; - gap: 0.8rem; - - align-items: flex-start; - } - - &__menuitens { - display: flex; - gap: 1.2rem; - - align-items: center; - - color: colors.$secondary100; - text-decoration: none; - - padding: 1.2rem; - - &--active { - background-color: rgb(0, 29, 49); - border-radius: 2rem; - } - } -} - -@include breakpoints.from1024() { - .side-menu-nav { - &__logo-container { - display: block; - - margin: 0 auto; - } - - &__icons { - display: none; - } - - &__exitmenu { - display: none; - } - } - - .side-menu-content { - width: 70%; - - &__menuitens { - transition: 0.3s; - - &:hover { - opacity: 0.6; - } - } - } -} +@use '~styles/colors.scss' as colors; +@use '~styles/breakpoints.scss' as breakpoints; +@use '~styles/fonts.scss' as fonts; + +.side-menu-nav { + display: flex; + + align-items: center; + justify-content: space-between; + padding-inline: 2rem; + + &__logo-container { + display: none; + padding-block: 4rem 2rem; + + text-align: center; + } + + &__logo { + max-width: 100%; + } + + &__icons { + display: flex; + gap: 2.4rem; + + align-items: center; + justify-content: center; + } + + &__notifications { + width: 1.6rem; + height: 1.95rem; + } + + &__perfil { + width: 4.3rem; + height: 4.3rem; + + border-radius: 100%; + } + + &__exit { + width: 2rem; + height: 2rem; + } + + &__exitmenu { + width: 2.9rem; + height: 2.4rem; + } +} + +.side-menu-content { + width: 28rem; + + display: flex; + flex-direction: column; + gap: 4.2rem; + + margin: 0 auto; + + &__line { + width: 100%; + + border: 0.1rem solid colors.$secondary100; + } + + &__lineinside { + width: 100%; + + margin: 4.2rem 0; + border: 0.1rem solid colors.$secondary100; + } + + &__yourpet { + font-family: fonts.$primaryFont; + } + + &__title-yourpet { + color: colors.$secondary100; + font-size: 1.6rem; + font-weight: fonts.$bold; + font-style: fonts.$normal; + } + + &__itens { + font-family: fonts.$primaryFont; + color: colors.$secondary100; + font-size: 1.6rem; + } + + &__ul { + display: flex; + flex-direction: column; + gap: 0.8rem; + + align-items: flex-start; + } + + &__menuitens { + display: flex; + gap: 1.2rem; + + align-items: center; + + color: colors.$secondary100; + text-decoration: none; + + padding: 1.2rem; + + &--active { + background-color: rgb(0, 29, 49); + border-radius: 2rem; + } + } +} + +@include breakpoints.from1024() { + .side-menu-nav { + &__logo-container { + display: block; + + margin: 0 auto; + } + + &__icons { + display: none; + } + + &__exitmenu { + display: none; + } + } + + .side-menu-content { + width: 70%; + + &__menuitens { + transition: 0.3s; + + &:hover { + opacity: 0.6; + } + } + } +} From 4299469eaa7d47b695634e0274446a9197ade0e6 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 8 May 2024 16:39:46 -0300 Subject: [PATCH 06/20] chore: update main --- pnpm-lock.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 35c9a86b..1471d8dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3328,6 +3328,10 @@ packages: resolution: {integrity: sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==} dev: true + /@types/lodash@4.17.0: + resolution: {integrity: sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==} + dev: true + /@types/mdx@2.0.13: resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} dev: true @@ -7090,6 +7094,10 @@ packages: resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} dev: true + /known-css-properties@0.30.0: + resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} + dev: true + /language-subtag-registry@0.3.22: resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} dev: true From 0421da28f248b0a0dc8cea5a4711fa4ce7e4ea95 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Thu, 6 Jun 2024 15:20:35 -0300 Subject: [PATCH 07/20] fix: add color gray250 --- src/styles/colors.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/colors.scss b/src/styles/colors.scss index edf87064..bdad45e9 100644 --- a/src/styles/colors.scss +++ b/src/styles/colors.scss @@ -25,6 +25,7 @@ $error100: rgb(179, 38, 30); $gray100: rgb(236, 239, 242); $gray150: rgb(236, 239, 242, 0.502); $gray200: rgb(224, 224, 224); +$gray250: rgb(172, 172, 181); $gray300: rgb(179, 190, 205); $gray400: rgb(141, 141, 141); $gray500: rgb(96, 104, 115); From c490ca832a69b27826a6101be6b61690c43e400d Mon Sep 17 00:00:00 2001 From: DominMFD Date: Thu, 13 Jun 2024 09:11:00 -0300 Subject: [PATCH 08/20] chore: add lodash --- pnpm-lock.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1471d8dc..35c9a86b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3328,10 +3328,6 @@ packages: resolution: {integrity: sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==} dev: true - /@types/lodash@4.17.0: - resolution: {integrity: sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==} - dev: true - /@types/mdx@2.0.13: resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} dev: true @@ -7094,10 +7090,6 @@ packages: resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} dev: true - /known-css-properties@0.30.0: - resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} - dev: true - /language-subtag-registry@0.3.22: resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} dev: true From 00c94fd3afe435fcc4ebad388a36da1bcf49890e Mon Sep 17 00:00:00 2001 From: DominMFD Date: Sat, 20 Jul 2024 22:56:31 -0300 Subject: [PATCH 09/20] refactor: init calendar refactor --- .../Calendar/components/DateButton/index.js | 23 -- .../Calendar/components/DateButton/index.scss | 64 ----- .../Calendar/components/DateSelector/index.js | 219 ------------------ .../components/DateSelector/index.scss | 92 -------- .../Calendar/components/Day/index.js | 43 ---- .../Calendar/components/Day/index.scss | 53 ----- .../Calendar/components/Days/index.js | 54 ----- .../Calendar/components/NavButton/index.js | 36 --- .../Calendar/components/NavButton/index.scss | 41 ---- src/components/Calendar/index.js | 192 +-------------- src/components/Calendar/index.scss | 77 ------ src/components/Calendar/utils/months.js | 14 ++ 12 files changed, 17 insertions(+), 891 deletions(-) delete mode 100644 src/components/Calendar/components/DateButton/index.js delete mode 100644 src/components/Calendar/components/DateButton/index.scss delete mode 100644 src/components/Calendar/components/DateSelector/index.js delete mode 100644 src/components/Calendar/components/DateSelector/index.scss delete mode 100644 src/components/Calendar/components/Day/index.js delete mode 100644 src/components/Calendar/components/Day/index.scss delete mode 100644 src/components/Calendar/components/Days/index.js delete mode 100644 src/components/Calendar/components/NavButton/index.js delete mode 100644 src/components/Calendar/components/NavButton/index.scss create mode 100644 src/components/Calendar/utils/months.js diff --git a/src/components/Calendar/components/DateButton/index.js b/src/components/Calendar/components/DateButton/index.js deleted file mode 100644 index 5f7e2c3e..00000000 --- a/src/components/Calendar/components/DateButton/index.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Component } from 'pet-dex-utilities'; -import './index.scss'; - -const html = ` -
  • -`; - -export default function DateButton(date) { - Component.call(this, { html }); - - const $button = this.selected.get('date').children[0]; - $button.innerText = date; -} - -DateButton.prototype = Object.assign( - DateButton.prototype, - Component.prototype, - { - active() { - this.selected.get('date').classList.add('active'); - }, - }, -); diff --git a/src/components/Calendar/components/DateButton/index.scss b/src/components/Calendar/components/DateButton/index.scss deleted file mode 100644 index 07343804..00000000 --- a/src/components/Calendar/components/DateButton/index.scss +++ /dev/null @@ -1,64 +0,0 @@ -@use '~styles/base.scss'; -@use '~styles/colors.scss' as colors; -@use '~styles/fonts.scss' as fonts; -@use '~styles/breakpoints.scss' as breakpoints; - -.date { - &__button { - font-family: fonts.$primaryFont; - color: colors.$gray500; - font-size: 1.4rem; - font-weight: fonts.$medium; - line-height: 2.5; - - border: 0; - - background-color: transparent; - - cursor: pointer; - } -} - -.date.active { - &__button { - color: colors.$primary200; - font-size: 2.6rem; - font-weight: fonts.$bold; - line-height: 1.3; - - padding: 0.6rem 1.2rem; - border: 0.1rem solid colors.$gray100; - - background-color: colors.$gray150; - - border-radius: 1.4rem; - } -} - -@include breakpoints.from667 { - .date { - display: none; - - &__button { - width: 100%; - - font-size: fonts.$md; - line-height: 1.8; - } - } - - .date.active { - display: flex; - - &__button { - color: colors.$gray800; - font-size: 2.6rem; - font-weight: fonts.$regular; - - padding: 0.6rem; - border: 0; - - background-color: transparent; - } - } -} diff --git a/src/components/Calendar/components/DateSelector/index.js b/src/components/Calendar/components/DateSelector/index.js deleted file mode 100644 index ad50af7f..00000000 --- a/src/components/Calendar/components/DateSelector/index.js +++ /dev/null @@ -1,219 +0,0 @@ -import { Component } from 'pet-dex-utilities'; -import './index.scss'; -import { listenBreakpoint } from '../../../../utils/breakpoints/breakpoints'; -import DateButton from '../DateButton'; - -const events = ['changeMonth', 'changeYear']; - -const html = ` -
      -`; - -const monthsBR = [ - 'Janeiro', - 'Fevereiro', - 'Março', - 'Abril', - 'Maio', - 'Junho', - 'Julho', - 'Agosto', - 'Setembro', - 'Outubro', - 'Novembro', - 'Dezembro', -]; - -let handleTouchStart; -let handleTouchMove; -function addTouchEvents(selector) { - let startTouch; - - handleTouchStart = (event) => { - startTouch = selector.isDesktop - ? event.touches[0].clientY - : event.touches[0].clientX; - }; - - handleTouchMove = (event) => { - event.preventDefault(); - const currentTouch = selector.isDesktop - ? event.touches[0].clientY - : event.touches[0].clientX; - let move = 0; - const moveRange = 20; - move = currentTouch - startTouch; - - if (Math.abs(move) > moveRange) { - const isSlideNext = move < 0; - const nextYear = +selector.dates[3].children[0].innerText; - const prevYear = +selector.dates[1].children[0].innerText; - const nextMonth = monthsBR.indexOf( - selector.dates[3].children[0].innerText, - ); - const prevMonth = monthsBR.indexOf( - selector.dates[1].children[0].innerText, - ); - if (isSlideNext && selector.isYear) selector.setYear(nextYear); - if (!isSlideNext && selector.isYear) selector.setYear(prevYear); - if (isSlideNext && !selector.isYear) selector.setMonth(nextMonth); - if (!isSlideNext && !selector.isYear) selector.setMonth(prevMonth); - startTouch = currentTouch; - } - }; - selector.dateSelector.addEventListener('touchstart', handleTouchStart); - selector.dateSelector.addEventListener('touchmove', handleTouchMove); -} - -let handleScroll; -function scrollModal(selector) { - const $dateSelector = selector.dateSelector; - - handleScroll = (event) => { - event.preventDefault(); - const isScrollNext = event.deltaY > 0; - - if (selector.isYear) { - const nextYear = +selector.dates[3].children[0].innerText; - const prevYear = +selector.dates[1].children[0].innerText; - const newYear = isScrollNext ? nextYear : prevYear; - selector.setYear(newYear); - } else { - const nextMonth = monthsBR.indexOf( - selector.dates[3].children[0].innerText, - ); - const prevMonth = monthsBR.indexOf( - selector.dates[1].children[0].innerText, - ); - const newMonth = isScrollNext ? nextMonth : prevMonth; - selector.setMonth(newMonth); - } - }; - - $dateSelector.addEventListener('wheel', handleScroll); - addTouchEvents(selector); -} - -function openModal(selector) { - const $dateSelector = selector.dateSelector; - $dateSelector.classList.add('active'); - const $activeDate = selector.date; - $activeDate.scrollIntoView({ - behavior: 'instant', - block: 'center', - inline: 'center', - }); -} - -function closeModal(selector, event) { - const $dateSelector = selector.dateSelector; - if ( - $dateSelector.classList.contains('active') && - !$dateSelector.contains(event.target) - ) { - $dateSelector.classList.remove('active'); - } -} - -export default function DateSelector(dateArray) { - Component.call(this, { html, events }); - - this.dateSelector = this.selected.get('date-selector'); - this.dateArray = dateArray; - - this.dateArray.forEach((item, index) => { - const dateButton = new DateButton(item); - dateButton.mount(this.dateSelector); - if (index === 2) { - dateButton.active(); - } - }); - - this.dates = this.dateSelector.querySelectorAll('li'); - this.date = this.dateSelector.querySelector('li.active'); - this.isYear = !Number.isNaN(+this.date.innerText); - listenBreakpoint('from667', (matches) => { - this.isDesktop = matches; - }); - - this.dateClickHandle = (index) => () => { - if (this.isYear) { - this.setYear(this.dateArray[index]); - } else { - this.setMonth(monthsBR.indexOf(this.dateArray[index])); - } - }; - - this.dates.forEach(($date, index) => { - $date.addEventListener('click', this.dateClickHandle(index)); - }); - this.openModalHandle = () => openModal(this); - this.dateSelector.addEventListener('click', this.openModalHandle); - - this.closeModalHandle = (event) => closeModal(this, event); - window.addEventListener('click', this.closeModalHandle); - - scrollModal(this); - - setTimeout(() => { - this.date.scrollIntoView({ - behavior: 'instant', - block: 'center', - inline: 'center', - }); - }); - - this.unmount(() => { - this.dateSelector.removeEventListener('click', this.openModalHandle); - window.removeEventListener('click', this.closeModalHandle); - this.dates.forEach(($date, index) => { - $date.removeEventListener('click', this.dateClickHandle(index)); - }); - this.dateSelector.removeEventListener('wheel', handleScroll); - this.dateSelector.removeEventListener('touchstart', handleTouchStart); - this.dateSelector.removeEventListener('touchmove', handleTouchMove); - }); -} - -DateSelector.prototype = Object.assign( - DateSelector.prototype, - Component.prototype, - { - setMonth(newMonth) { - for (let i = 0; i < this.dateArray.length; i += 1) { - const index = (newMonth - (2 - i) + 12) % 12; - this.dateArray[i] = monthsBR[index]; - } - - this.dateArray.forEach((item, index) => { - this.dates[index].children[0].innerText = item; - }); - - this.date.scrollIntoView({ - behavior: 'instant', - block: 'center', - inline: 'center', - }); - - this.emit('changeMonth', newMonth); - }, - - setYear(newYear) { - for (let i = 0; i < this.dateArray.length; i += 1) { - this.dateArray[i] = newYear - (2 - i); - } - - this.dateArray.forEach((item, index) => { - this.dates[index].children[0].innerText = item; - }); - - this.date.scrollIntoView({ - behavior: 'instant', - block: 'center', - inline: 'center', - }); - - this.emit('changeYear', newYear); - }, - }, -); diff --git a/src/components/Calendar/components/DateSelector/index.scss b/src/components/Calendar/components/DateSelector/index.scss deleted file mode 100644 index 5ab3b7d2..00000000 --- a/src/components/Calendar/components/DateSelector/index.scss +++ /dev/null @@ -1,92 +0,0 @@ -@use '~styles/base.scss'; -@use '~styles/colors.scss' as colors; -@use '~styles/fonts.scss' as fonts; -@use '~styles/breakpoints.scss' as breakpoints; - -.date-selector { - max-width: 33rem; - overflow-x: hidden; - - display: flex; - gap: 0.8rem; - - align-items: center; - - margin-bottom: 2.4rem; - padding-bottom: 2.4rem; - border-bottom: 0.1rem solid colors.$gray100; - - &:first-child { - order: 2; - } -} - -@include breakpoints.from667 { - .date-selector { - margin-bottom: 0; - padding: 0; - border-bottom: 0; - - &:last-child { - display: flex; - - align-items: center; - - order: 2; - - &::after { - width: 1.6rem; - height: 2.3rem; - - display: inline; - - background-image: url('../../images/arrows.svg'); - - content: ''; - } - } - } - - .date-selector.active { - width: 23.1rem; - max-height: 22.8rem; - overflow-y: hidden; - - display: grid; - gap: 0.6rem; - - position: absolute; - left: -4rem; - - background-color: colors.$secondary100; - - .date { - display: block; - } - - .date.active { - &::after { - width: 1.6rem; - height: 2.3rem; - - display: inline-block; - - margin-top: 1.4rem; - - position: absolute; - right: 2rem; - - background-image: url('../../images/arrows.svg'); - - content: ''; - } - - button { - font-weight: fonts.$bold; - - border-top: 0.1rem solid colors.$gray100; - border-bottom: 0.1rem solid colors.$gray100; - } - } - } -} diff --git a/src/components/Calendar/components/Day/index.js b/src/components/Calendar/components/Day/index.js deleted file mode 100644 index 9de8e5e1..00000000 --- a/src/components/Calendar/components/Day/index.js +++ /dev/null @@ -1,43 +0,0 @@ -import { Component } from 'pet-dex-utilities'; -import './index.scss'; - -const events = ['changeDay']; - -const html = ` - -`; - -export default function Day(day, dayClass) { - Component.call(this, { html, events }); - - this.$day = this.selected.get('day-button'); - this.$day.innerText = day; - this.$day.setAttribute('aria-label', `Dia ${day}`); - if (dayClass) this.setClass(dayClass); - - const setActiveDayHandle = (event) => this.setClassActive(event); - this.$day.addEventListener('click', setActiveDayHandle); - - this.unmount(() => { - this.$day.removeEventListener('click', setActiveDayHandle); - }); -} - -Day.prototype = Object.assign(Day.prototype, Component.prototype, { - setClass(dayClass) { - this.$day.classList.add(dayClass); - }, - - setClassPrevMonth() { - this.$day.classList.add('prev-month'); - }, - - setClassActive() { - this.$day.classList.add('active'); - this.emit('changeDay', this.$day); - }, - - setClassNextMonth() { - this.$day.classList.add('next-month'); - }, -}); diff --git a/src/components/Calendar/components/Day/index.scss b/src/components/Calendar/components/Day/index.scss deleted file mode 100644 index 7d91e632..00000000 --- a/src/components/Calendar/components/Day/index.scss +++ /dev/null @@ -1,53 +0,0 @@ -@use '~styles/base.scss'; -@use '~styles/colors.scss' as colors; -@use '~styles/fonts.scss' as fonts; -@use '~styles/breakpoints.scss' as breakpoints; - -.day__button { - width: 4rem; - height: 4rem; - - font-family: fonts.$primaryFont; - color: colors.$gray500; - font-size: 1.6rem; - font-weight: fonts.$medium; - - padding: 0; - border: 0.1rem solid colors.$gray100; - - background-color: colors.$secondary100; - border-radius: 1rem; - - cursor: pointer; - - &.prev-month, - &.next-month { - color: colors.$gray300; - - background-color: colors.$gray150; - } - - &:hover, - &.active { - color: colors.$primary200; - font-weight: fonts.$semiBold; - - border: 0.1rem solid colors.$blue100; - - background-color: colors.$blue150; - } -} - -@include breakpoints.from667 { - .day__button { - width: 5.4rem; - height: 5.4rem; - - font-size: 1.8rem; - - &:hover, - &.active { - border: 0.2rem solid colors.$blue100; - } - } -} diff --git a/src/components/Calendar/components/Days/index.js b/src/components/Calendar/components/Days/index.js deleted file mode 100644 index 6eda5ae1..00000000 --- a/src/components/Calendar/components/Days/index.js +++ /dev/null @@ -1,54 +0,0 @@ -import { Component } from 'pet-dex-utilities'; -import Day from '../Day'; - -const events = ['changeDay', 'changeToPrevMonth', 'changeToNextMonth']; - -const html = ` -
      -`; - -function changeDay(days, newDayActive) { - const day = +newDayActive.innerText; - const isDayInPrevMonth = newDayActive.classList.contains('prev-month'); - const isDayInNextMonth = newDayActive.classList.contains('next-month'); - - if (isDayInPrevMonth) days.emit('changeToPrevMonth', day); - else if (isDayInNextMonth) days.emit('changeToNextMonth', day); - else days.emit('changeDay', day); -} - -export default function Days( - year, - month, - day, - totalDaysOfMonth, - firstDayOfMonthInWeek, -) { - Component.call(this, { html, events }); - - const $container = this.selected.get('days-container'); - - const totalDaysInCalendar = 42; - for ( - let i = -firstDayOfMonthInWeek; - i < totalDaysInCalendar - firstDayOfMonthInWeek; - i += 1 - ) { - const date = new Date(year, month, i); - const dayNumber = date.getDate(); - const firstDayOfMonth = 1; - - const dayButton = new Day(dayNumber); - - if (i < firstDayOfMonth) dayButton.setClassPrevMonth(); - if (i > totalDaysOfMonth) dayButton.setClassNextMonth(); - if (i === day) dayButton.setClassActive(); - - dayButton.mount($container); - dayButton.listen('changeDay', (newDayActive) => - changeDay(this, newDayActive), - ); - } -} - -Days.prototype = Object.assign(Days.prototype, Component.prototype, {}); diff --git a/src/components/Calendar/components/NavButton/index.js b/src/components/Calendar/components/NavButton/index.js deleted file mode 100644 index bef7bfb3..00000000 --- a/src/components/Calendar/components/NavButton/index.js +++ /dev/null @@ -1,36 +0,0 @@ -import { Component } from 'pet-dex-utilities'; -import './index.scss'; -import navButton from '../../images/navButton.svg'; - -const events = ['prev', 'next']; - -const html = ` - -`; - -export default function NavButton(position) { - Component.call(this, { html, events }); - - this.$navButton = this.selected.get('nav-button'); - this.$navButton.classList.add(position); - const isPrev = this.$navButton.classList.contains('prev'); - this.$navButton.setAttribute( - 'aria-label', - isPrev ? 'Ir para o mês anterior' : 'Ir para o próximo mês', - ); - - const navButtonClickHandle = () => { - if (isPrev) { - this.emit('prev'); - } else { - this.emit('next'); - } - }; - this.$navButton.addEventListener('click', navButtonClickHandle); -} - -NavButton.prototype = Object.assign( - NavButton.prototype, - Component.prototype, - {}, -); diff --git a/src/components/Calendar/components/NavButton/index.scss b/src/components/Calendar/components/NavButton/index.scss deleted file mode 100644 index 7e5f13f3..00000000 --- a/src/components/Calendar/components/NavButton/index.scss +++ /dev/null @@ -1,41 +0,0 @@ -@use '~styles/base.scss'; -@use '~styles/colors.scss' as colors; -@use '~styles/fonts.scss' as fonts; -@use '~styles/breakpoints.scss' as breakpoints; - -.nav-button { - display: none; -} - -@include breakpoints.from667 { - .nav-button { - width: 4.6rem; - height: 4.6rem; - - display: grid; - - align-items: center; - justify-content: center; - - font-family: fonts.$primaryFont; - color: colors.$gray300; - font-size: 2rem; - - border: 0.1rem solid colors.$gray500; - - background-color: transparent; - border-radius: 1.4rem; - - cursor: pointer; - } - - .prev { - grid-area: 1; - } - - .next { - justify-self: end; - - transform: rotate(180deg); - } -} diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js index da587b19..8bed6d21 100644 --- a/src/components/Calendar/index.js +++ b/src/components/Calendar/index.js @@ -1,200 +1,14 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; -import dayjs from 'dayjs'; -import DateSelector from './components/DateSelector'; -import NavButton from './components/NavButton'; -import Days from './components/Days'; -const events = ['changeDate', 'changeMonth', 'changeYear']; - -const monthsBR = [ - 'Janeiro', - 'Fevereiro', - 'Março', - 'Abril', - 'Maio', - 'Junho', - 'Julho', - 'Agosto', - 'Setembro', - 'Outubro', - 'Novembro', - 'Dezembro', -]; - -const currentMonth = dayjs().month(); -const months = new Array(5); -for (let i = 0; i < months.length; i += 1) { - const monthIndex = (currentMonth - (2 - i) + 12) % 12; - months[i] = monthsBR[monthIndex]; -} - -const currentYear = dayjs().year(); -const years = new Array(5); -for (let i = 0; i < years.length; i += 1) { - years[i] = currentYear - (2 - i); -} +const events = []; const html = ` -
      - -
      -
      -

      Dom

      -

      Seg

      -

      Ter

      -

      Qua

      -

      Qui

      -

      Sex

      -

      Sab

      -
      -
      -
      + `; export default function Calendar() { Component.call(this, { html, events }); - - this.setDate(); - - this.monthSelect = new DateSelector(months); - this.monthSelect.mount(this.selected.get('calendar-date')); - this.monthSelect.listen('changeMonth', (newMonth) => - this.setDate(this.day, newMonth, this.year), - ); - - this.yearSelect = new DateSelector(years); - this.yearSelect.mount(this.selected.get('calendar-date')); - this.yearSelect.listen('changeYear', (newYear) => - this.setDate(this.day, this.month, newYear), - ); - - this.navButton = new NavButton('prev'); - this.navButton.mount(this.selected.get('calendar-nav')); - this.navButton.listen('prev', () => this.goToPrevMonth()); - - this.navButton = new NavButton('next'); - this.navButton.mount(this.selected.get('calendar-nav')); - this.navButton.listen('next', () => this.goToNextMonth()); } -Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { - getDate() { - return { - day: this.day, - month: this.month, - year: this.year, - }; - }, - - setDate(day, month, year) { - this.day = day || dayjs().date(); - this.month = month !== undefined ? month : dayjs().month(); - this.year = year || dayjs().year(); - this.totalDaysOfMonth = dayjs( - `${this.year}-${this.month + 1}`, - ).daysInMonth(); - this.firstDayOfMonthInWeek = - dayjs(`${this.year}-${this.month + 1}-1`).day() - 1; - - this.setDays(); - - this.emit('changeDate', { - day: this.day, - month: this.month, - year: this.year, - }); - }, - - getDay() { - return this.day; - }, - - setDay(day) { - if (day < 1 || day > this.totalDaysOfMonth) { - throw new Error('Dia inválido'); - } else if (typeof day !== 'number') { - throw new Error('O valor não é um number'); - } else { - this.setDate(day, this.month, this.year); - } - }, - - setDays() { - if (this.days) this.days.unmount(); - this.days = new Days( - this.year, - this.month, - this.day, - this.totalDaysOfMonth, - this.firstDayOfMonthInWeek, - ); - this.days.mount(this.selected.get('calendar-days')); - - this.days.listen('changeDay', (newDay) => { - this.setDate(newDay, this.month, this.year); - }); - - this.days.listen('changeToPrevMonth', (newDay) => { - this.goToPrevMonth(); - this.setDay(newDay); - }); - - this.days.listen('changeToNextMonth', (newDay) => { - this.goToNextMonth(); - this.setDay(newDay); - }); - }, - - getMonth() { - return this.month; - }, - - setMonth(month) { - if (month < 0 || month > 11) { - throw new Error('Mês inválido'); - } else if (typeof month !== 'number') { - throw new Error('O valor não é um number'); - } else { - this.setDate(this.day, month, this.year); - } - }, - - getYear() { - return this.year; - }, - - setYear(year) { - if (year < 0) { - throw new Error('Ano inválido'); - } else if (typeof year !== 'number') { - throw new Error('O valor não é um number'); - } else { - this.setDate(this.day, this.month, year); - } - }, - - goToPrevMonth() { - this.month -= 1; - if (this.month < 0) { - this.month = 11; - this.year -= 1; - this.yearSelect.setYear(this.year); - } - this.monthSelect.setMonth(this.month); - this.setDate(this.day, this.month, this.year); - }, - - goToNextMonth() { - this.month += 1; - if (this.month > 11) { - this.month = 0; - this.year += 1; - this.yearSelect.setYear(this.year); - } - this.monthSelect.setMonth(this.month); - this.setDate(this.day, this.month, this.year); - }, -}); +Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, {}); diff --git a/src/components/Calendar/index.scss b/src/components/Calendar/index.scss index 15112102..e69de29b 100644 --- a/src/components/Calendar/index.scss +++ b/src/components/Calendar/index.scss @@ -1,77 +0,0 @@ -@use '~styles/base.scss'; -@use '~styles/colors.scss' as colors; -@use '~styles/fonts.scss' as fonts; -@use '~styles/breakpoints.scss' as breakpoints; - -.calendar-container { - display: grid; - - padding: 2.4rem 0; - - background-color: colors.$shade50; - - &__date { - width: 100%; - max-width: 34rem; - - margin: 0 auto; - - &-select { - display: grid; - - justify-items: center; - } - } - - &__days { - margin: 0 auto; - padding: 0 1rem; - - div { - display: grid; - grid-template-columns: repeat(7, 1fr); - gap: 0.8rem; - - justify-items: center; - } - - p { - font-family: fonts.$primaryFont; - color: colors.$gray300; - text-align: center; - font-size: 1.4rem; - font-weight: fonts.$regular; - line-height: 1.4; - - padding-bottom: 1.2rem; - } - } -} - -@include breakpoints.from667 { - .calendar-container { - &__days { - p { - font-size: 1.6rem; - } - } - - &__date { - max-width: 42rem; - - display: grid; - grid-template-columns: 1fr 1fr 1fr; - - align-items: center; - - margin: 0 auto; - padding-bottom: 3rem; - - &-select { - display: flex; - - position: relative; - } - } - } -} diff --git a/src/components/Calendar/utils/months.js b/src/components/Calendar/utils/months.js new file mode 100644 index 00000000..759537b3 --- /dev/null +++ b/src/components/Calendar/utils/months.js @@ -0,0 +1,14 @@ +export const MONTNHS = [ + 'Janeiro', + 'Fevereiro', + 'Março', + 'Abril', + 'Maio', + 'Junho', + 'Julho', + 'Agosto', + 'Setembro', + 'Outubro', + 'Novembro', + 'Dezembro', +]; From a7f7afa81bcd6fda23aaf7d1ff465ba47b9609de Mon Sep 17 00:00:00 2001 From: DominMFD Date: Sun, 21 Jul 2024 18:51:31 -0300 Subject: [PATCH 10/20] feat: calendar content done --- .../DayComposer/components/DayButton/index.js | 39 +++++++ .../components/DayButton/index.scss | 60 ++++++++++ .../Calendar/components/DayComposer/index.js | 78 +++++++++++++ .../components/DayComposer/index.scss | 7 ++ .../components/NavigationButton/index.js | 41 +++++++ .../components/NavigationButton/index.scss | 38 ++++++ .../components/WeekDay/index.js | 19 +++ .../components/WeekDay/index.scss | 23 ++++ .../components/WeekDayComposer/index.js | 38 ++++++ .../components/WeekDayComposer/index.scss | 7 ++ .../WeekDayComposer/utils/weekDays.js | 36 ++++++ src/components/Calendar/index.js | 108 +++++++++++++++++- src/components/Calendar/index.scss | 12 ++ src/styles/colors.scss | 6 +- 14 files changed, 506 insertions(+), 6 deletions(-) create mode 100644 src/components/Calendar/components/DayComposer/components/DayButton/index.js create mode 100644 src/components/Calendar/components/DayComposer/components/DayButton/index.scss create mode 100644 src/components/Calendar/components/DayComposer/index.js create mode 100644 src/components/Calendar/components/DayComposer/index.scss create mode 100644 src/components/Calendar/components/NavigationButton/index.js create mode 100644 src/components/Calendar/components/NavigationButton/index.scss create mode 100644 src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.js create mode 100644 src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.scss create mode 100644 src/components/Calendar/components/WeekDayComposer/index.js create mode 100644 src/components/Calendar/components/WeekDayComposer/index.scss create mode 100644 src/components/Calendar/components/WeekDayComposer/utils/weekDays.js diff --git a/src/components/Calendar/components/DayComposer/components/DayButton/index.js b/src/components/Calendar/components/DayComposer/components/DayButton/index.js new file mode 100644 index 00000000..41f4e7ca --- /dev/null +++ b/src/components/Calendar/components/DayComposer/components/DayButton/index.js @@ -0,0 +1,39 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; + +const events = ['day:active', 'day:previousMonth', 'day:nextMonth']; + +const html = ` +
    • + +
    • + +`; + +export default function DayButton(day) { + Component.call(this, { html, events }); + + this.day = day; + this.$day = this.selected.get('day'); + this.$dayButton = this.selected.get('day-button'); + + this.$dayButton.innerText = day; + this.$dayButton.setAttribute('aria-label', `Dia ${this.day}`); + + this.$day.addEventListener('click', () => this.active()); +} + +DayButton.prototype = Object.assign(DayButton.prototype, Component.prototype, { + setState(state) { + this.$dayButton.classList.add(`day__button--${state}`); + }, + + active() { + this.$dayButton.classList.add('day__button--active'); + this.emit('day:active', this.day); + }, + + desactive() { + this.$dayButton.classList.remove('day__button--active'); + }, +}); diff --git a/src/components/Calendar/components/DayComposer/components/DayButton/index.scss b/src/components/Calendar/components/DayComposer/components/DayButton/index.scss new file mode 100644 index 00000000..26e153e3 --- /dev/null +++ b/src/components/Calendar/components/DayComposer/components/DayButton/index.scss @@ -0,0 +1,60 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.day { + width: 4rem; + height: 4rem; + + justify-self: center; + + &__button { + width: 100%; + height: 100%; + + font-family: fonts.$primaryFont; + color: colors.$gray500; + text-align: center; + font-size: fonts.$sm; + font-weight: fonts.$medium; + + border: 0.1rem solid colors.$gray150; + + background-color: colors.$secondary100; + + border-radius: 10px; + + cursor: pointer; + + &:hover, + &--active { + color: colors.$primary200; + font-weight: fonts.$semiBold; + + border: 0.1rem solid colors.$blue100; + + background-color: colors.$blue150; + } + + &--previousMonth, + &--nextMonth { + color: rgba(160, 174, 192, 1); + + border: 0.1rem solid colors.$gray150; + + background-color: colors.$gray100; + } + } +} + +@include breakpoints.from667 { + .day { + width: 5.4rem; + height: 5.4rem; + + &__button { + font-size: fonts.$md; + } + } +} diff --git a/src/components/Calendar/components/DayComposer/index.js b/src/components/Calendar/components/DayComposer/index.js new file mode 100644 index 00000000..1cb61727 --- /dev/null +++ b/src/components/Calendar/components/DayComposer/index.js @@ -0,0 +1,78 @@ +import { Component } from 'pet-dex-utilities'; +import dayjs from 'dayjs'; +import DayButton from './components/DayButton'; + +import './index.scss'; + +const events = ['day:change', 'month:next', 'month:previous']; + +const html = ` +
      +`; + +export default function DayComposer(day, month, year) { + Component.call(this, { html, events }); + + this.day = day; + this.month = month; + this.year = year; + this.$dayComposer = this.selected.get('day-composer'); + this.activeDayButton = null; + + this.totalDaysInCalendar = 42; + this.totalDaysInMonth = dayjs(`${this.year}-${this.month}-1`).daysInMonth(); + this.firstDayInWeek = dayjs(`${this.year}-${this.month}-1`).day(); + this.totalDaysInPreviousMonth = dayjs( + `${this.year}-${this.month - 1}-1`, + ).daysInMonth(); + this.nextMonthDay = 1; + this.actualMonthDay = 1; + + for (let i = 1; i <= this.totalDaysInCalendar; i += 1) { + if (i <= this.firstDayInWeek) { + const previousMonthDay = + this.totalDaysInPreviousMonth - this.firstDayInWeek + i; + this.mountDay(previousMonthDay, 'previousMonth'); + } else if (this.actualMonthDay > this.totalDaysInMonth) { + this.mountDay(this.nextMonthDay, 'nextMonth'); + this.nextMonthDay += 1; + } else { + this.mountDay( + this.actualMonthDay, + this.actualMonthDay === this.day && 'active', + ); + this.actualMonthDay += 1; + } + } +} + +DayComposer.prototype = Object.assign( + DayComposer.prototype, + Component.prototype, + { + mountDay(day, state) { + const dayButton = new DayButton(day); + + if (state === 'active') this.activeDayButton = dayButton; + + dayButton.mount(this.$dayComposer); + dayButton.setState(state); + dayButton.listen('day:active', (activeDay) => { + if (state === 'previousMonth') { + this.emit('month:previous', activeDay); + } else if (state === 'nextMonth') { + this.emit('month:next', activeDay); + } else { + this.handleDayActive(dayButton, activeDay); + } + }); + }, + + handleDayActive(dayButton, activeDay) { + if (this.activeDayButton) this.activeDayButton.desactive(); + + this.activeDayButton = dayButton; + this.emit('day:change', activeDay); + }, + }, +); diff --git a/src/components/Calendar/components/DayComposer/index.scss b/src/components/Calendar/components/DayComposer/index.scss new file mode 100644 index 00000000..dcb6072c --- /dev/null +++ b/src/components/Calendar/components/DayComposer/index.scss @@ -0,0 +1,7 @@ +.day-composer { + display: grid; + grid-template-columns: repeat(7, 1fr); + gap: 0.8rem; + + list-style: none; +} diff --git a/src/components/Calendar/components/NavigationButton/index.js b/src/components/Calendar/components/NavigationButton/index.js new file mode 100644 index 00000000..ae5ab19a --- /dev/null +++ b/src/components/Calendar/components/NavigationButton/index.js @@ -0,0 +1,41 @@ +import { Component } from 'pet-dex-utilities'; +import arrow from '../../images/navButton.svg'; + +import './index.scss'; + +const events = ['button:click']; + +const html = ` + +`; + +export default function NavigationButton(state) { + Component.call(this, { html, events }); + + this.state = state; + this.$navigationButton = this.selected.get('navigation-button'); + this.$buttonIcon = this.selected.get('button-icon'); + + this.$buttonIcon.classList.toggle( + 'navigation-button__icon--next', + this.state === 'next', + ); + this.$navigationButton.setAttribute( + 'aria-label', + this.state === 'next' ? 'Ir para o próximo mês' : 'Ir para o mês anterior', + ); + + this.emitEvent = () => { + this.emit('button:click'); + }; + + this.$navigationButton.addEventListener('click', this.emitEvent); +} + +NavigationButton.prototype = Object.assign( + NavigationButton.prototype, + Component.prototype, + {}, +); diff --git a/src/components/Calendar/components/NavigationButton/index.scss b/src/components/Calendar/components/NavigationButton/index.scss new file mode 100644 index 00000000..f0bb58dc --- /dev/null +++ b/src/components/Calendar/components/NavigationButton/index.scss @@ -0,0 +1,38 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.navigation-button { + width: 4.6rem; + height: 4.6rem; + + display: none; + + align-items: center; + justify-content: center; + + margin-bottom: 2.4rem; + + border: 0.1rem solid rgb(160, 174, 192); + + background-color: colors.$secondary100; + + border-radius: 14px; + + cursor: pointer; + + &__icon { + color: rgb(160, 174, 192); + + &--next { + transform: rotate(180deg); + } + } +} + +@include breakpoints.from667 { + .navigation-button { + display: flex; + } +} diff --git a/src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.js b/src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.js new file mode 100644 index 00000000..fe9879f8 --- /dev/null +++ b/src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.js @@ -0,0 +1,19 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; + +const events = []; + +const html = ` + +`; + +export default function WeekDay(weekDay) { + Component.call(this, { events, html }); + + this.weekDay = weekDay; + this.$weekDay = this.selected.get('week-day'); + this.$weekDay.innerText = weekDay.abbreviation; + this.$weekDay.setAttribute('aria-label', `${weekDay.name}`); +} + +WeekDay.prototype = Object.assign(WeekDay.prototype, Component.prototype, {}); diff --git a/src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.scss b/src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.scss new file mode 100644 index 00000000..0cf72fef --- /dev/null +++ b/src/components/Calendar/components/WeekDayComposer/components/WeekDay/index.scss @@ -0,0 +1,23 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.week-days__day { + font-family: fonts.$fourthFont; + color: rgb(160, 174, 192); + text-align: center; + font-size: 1.2rem; + font-weight: fonts.$regular; + + &--active { + color: colors.$primary200; + font-weight: fonts.$semiBold; + } +} + +@include breakpoints.from667 { + .week-days__day { + font-size: fonts.$xs; + } +} diff --git a/src/components/Calendar/components/WeekDayComposer/index.js b/src/components/Calendar/components/WeekDayComposer/index.js new file mode 100644 index 00000000..b782347a --- /dev/null +++ b/src/components/Calendar/components/WeekDayComposer/index.js @@ -0,0 +1,38 @@ +import { Component } from 'pet-dex-utilities'; +import WeekDay from './components/WeekDay'; +import { WEEK_DAYS } from './utils/weekDays'; + +import './index.scss'; + +const events = []; + +const html = ` +
      +`; + +export default function WeekDayComposer() { + Component.call(this, { html, events }); + + this.$weekDays = this.selected.get('week-days'); + this.totalWeekDays = 7; + + for (let i = 0; i < this.totalWeekDays; i += 1) { + const weekDay = new WeekDay(WEEK_DAYS[i]); + weekDay.mount(this.$weekDays); + } +} + +WeekDayComposer.prototype = Object.assign( + WeekDayComposer.prototype, + Component.prototype, + { + activeWeekDay(currentWeekDay) { + Array.from(this.$weekDays.children).forEach((weekDay, index) => { + weekDay.classList.toggle( + 'week-days__day--active', + index === currentWeekDay, + ); + }); + }, + }, +); diff --git a/src/components/Calendar/components/WeekDayComposer/index.scss b/src/components/Calendar/components/WeekDayComposer/index.scss new file mode 100644 index 00000000..25986ce9 --- /dev/null +++ b/src/components/Calendar/components/WeekDayComposer/index.scss @@ -0,0 +1,7 @@ +.week-days { + display: grid; + grid-template-columns: repeat(7, 1fr); + gap: 0.8rem; + + margin-bottom: 1.6rem; +} diff --git a/src/components/Calendar/components/WeekDayComposer/utils/weekDays.js b/src/components/Calendar/components/WeekDayComposer/utils/weekDays.js new file mode 100644 index 00000000..658de79c --- /dev/null +++ b/src/components/Calendar/components/WeekDayComposer/utils/weekDays.js @@ -0,0 +1,36 @@ +export const WEEK_DAYS = [ + { + name: 'Domingo', + abbreviation: 'Dom', + }, + + { + name: 'Segunda-Feira', + abbreviation: 'Seg', + }, + + { + name: 'Terça-Feira', + abbreviation: 'Ter', + }, + + { + name: 'Quarta-Feira', + abbreviation: 'Qua', + }, + + { + name: 'Quinta-Feira', + abbreviation: 'Qui', + }, + + { + name: 'Sexta-Feira', + abbreviation: 'Sex', + }, + + { + name: 'Sábado', + abbreviation: 'Seg', + }, +]; diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js index 8bed6d21..8cb1cd2b 100644 --- a/src/components/Calendar/index.js +++ b/src/components/Calendar/index.js @@ -1,14 +1,116 @@ import { Component } from 'pet-dex-utilities'; +import dayjs from 'dayjs'; +import DayComposer from './components/DayComposer'; +import WeekDayComposer from './components/WeekDayComposer'; +import NavigationButton from './components/NavigationButton'; + import './index.scss'; const events = []; const html = ` - +
      +
      +
      +
      `; -export default function Calendar() { +export default function Calendar({ day, month, year }) { Component.call(this, { html, events }); + + this.day = day || dayjs().date(); + this.month = month || dayjs().month() + 1; + this.year = year || dayjs().year(); + + this.$calendar = this.selected.get('calendar'); + this.$calendarControls = this.selected.get('calendar-controls'); + this.$calendarContent = this.selected.get('calendar-content'); + + this.weekDayComposer = new WeekDayComposer(); + this.weekDayComposer.mount(this.$calendarContent); + + this.mountDays = () => { + if (this.dayComposer) this.dayComposer.unmount(); + + this.dayComposer = new DayComposer(this.day, this.month, this.year); + this.dayComposer.mount(this.$calendarContent); + this.dayComposer.listen('day:change', (newDay) => this.setDay(newDay)); + this.dayComposer.listen('month:previous', (newDay) => + this.previousMonth(newDay), + ); + this.dayComposer.listen('month:next', (newDay) => this.nextMonth(newDay)); + }; + + this.setDate(this.day, this.month, this.year); + + this.previousButton = new NavigationButton('previous'); + this.previousButton.mount(this.$calendarControls); + this.previousButton.listen('button:click', () => this.previousMonth()); + this.nextButton = new NavigationButton('next'); + this.nextButton.mount(this.$calendarControls); + this.nextButton.listen('button:click', () => this.nextMonth()); } -Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, {}); +Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { + setDate(day, month, year) { + this.day = day; + this.month = month; + this.year = year; + + this.firstDayInWeek = dayjs(`${this.year}-${this.month}-${this.day}`).day(); + this.weekDayComposer.activeWeekDay(this.firstDayInWeek); + + this.mountDays(); + }, + + getDate() { + return { + day: this.day, + month: this.month, + year: this.year, + }; + }, + + setDay(day) { + this.day = day; + this.setDate(this.day, this.month, this.year); + }, + + getDay() { + return this.day; + }, + + nextMonth(day) { + this.day = day || this.day; + this.month += 1; + + if (this.month > 12) { + this.month = 1; + this.year += 1; + } + + const totalDaysInMonth = dayjs( + `${this.year}-${this.month}-1`, + ).daysInMonth(); + if (this.day > totalDaysInMonth) this.day = totalDaysInMonth; + + this.setDate(this.day, this.month, this.year); + }, + + previousMonth(day) { + this.day = day || this.day; + this.month -= 1; + + if (this.month < 1) { + this.month = 12; + this.year -= 1; + } + + const totalDaysInMonth = dayjs( + `${this.year}-${this.month}-1`, + ).daysInMonth(); + if (this.day > totalDaysInMonth) this.day = totalDaysInMonth; + + this.setDate(this.day, this.month, this.year); + }, +}); diff --git a/src/components/Calendar/index.scss b/src/components/Calendar/index.scss index e69de29b..d39438ff 100644 --- a/src/components/Calendar/index.scss +++ b/src/components/Calendar/index.scss @@ -0,0 +1,12 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.calendar { + &__controls { + display: flex; + + justify-content: space-between; + } +} diff --git a/src/styles/colors.scss b/src/styles/colors.scss index bdad45e9..623d7abc 100644 --- a/src/styles/colors.scss +++ b/src/styles/colors.scss @@ -22,8 +22,8 @@ $success200: rgb(49, 138, 94); $error100: rgb(179, 38, 30); // neutrals (Grey) -$gray100: rgb(236, 239, 242); -$gray150: rgb(236, 239, 242, 0.502); +$gray100: rgb(247, 250, 252); +$gray150: rgb(236, 239, 242); $gray200: rgb(224, 224, 224); $gray250: rgb(172, 172, 181); $gray300: rgb(179, 190, 205); @@ -46,5 +46,5 @@ $shade100: rgb(0, 0, 0); // custom $blue100: rgb(209, 230, 255); -$blue150: rgba(209, 230, 255, 0.502); +$blue150: rgba(209, 230, 255, 0.5); $blue600: rgb(18, 104, 204); From 88eba6f6a559640da367b24b3d4378593dc26ff0 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Mon, 22 Jul 2024 08:05:09 -0300 Subject: [PATCH 11/20] feat: implements month selector --- .../DayComposer/components/DayButton/index.js | 0 .../components/DayButton/index.scss | 0 .../components}/DayComposer/index.js | 16 ++--- .../components}/DayComposer/index.scss | 0 .../components/CalendarSliding/index.js | 52 ++++++++++++++ .../components/CalendarSliding/index.scss | 0 .../components/MonthSelector/index.js | 43 +++++++++++ .../components/MonthSelector/index.scss | 71 +++++++++++++++++++ .../components/SelectorItem/index.js | 25 +++++++ .../components/SelectorItem/index.scss | 11 +++ .../components/ModalItem/index.js | 22 ++++++ .../components/ModalItem/index.scss | 0 .../components/SelectorModal/index.js | 27 +++++++ .../components/SelectorModal/index.scss | 28 ++++++++ .../components/YearSelector/index.js | 27 +++++++ .../components/YearSelector/index.scss | 0 .../components/DateSelectorComposer/index.js | 32 +++++++++ .../DateSelectorComposer/index.scss | 16 +++++ .../DateSelectorComposer/utils/monthArray.js | 10 +++ .../components/NavigationButton/index.scss | 2 - src/components/Calendar/index.js | 55 +++++++++----- src/components/Calendar/index.scss | 4 ++ src/components/Calendar/utils/months.js | 2 +- src/stories/Calendar.stories.js | 8 ++- 24 files changed, 417 insertions(+), 34 deletions(-) rename src/components/Calendar/components/{ => CalendarSliding/components}/DayComposer/components/DayButton/index.js (100%) rename src/components/Calendar/components/{ => CalendarSliding/components}/DayComposer/components/DayButton/index.scss (100%) rename src/components/Calendar/components/{ => CalendarSliding/components}/DayComposer/index.js (77%) rename src/components/Calendar/components/{ => CalendarSliding/components}/DayComposer/index.scss (100%) create mode 100644 src/components/Calendar/components/CalendarSliding/index.js create mode 100644 src/components/Calendar/components/CalendarSliding/index.scss create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.js create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.scss create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.scss create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss create mode 100644 src/components/Calendar/components/DateSelectorComposer/index.js create mode 100644 src/components/Calendar/components/DateSelectorComposer/index.scss create mode 100644 src/components/Calendar/components/DateSelectorComposer/utils/monthArray.js diff --git a/src/components/Calendar/components/DayComposer/components/DayButton/index.js b/src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.js similarity index 100% rename from src/components/Calendar/components/DayComposer/components/DayButton/index.js rename to src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.js diff --git a/src/components/Calendar/components/DayComposer/components/DayButton/index.scss b/src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.scss similarity index 100% rename from src/components/Calendar/components/DayComposer/components/DayButton/index.scss rename to src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.scss diff --git a/src/components/Calendar/components/DayComposer/index.js b/src/components/Calendar/components/CalendarSliding/components/DayComposer/index.js similarity index 77% rename from src/components/Calendar/components/DayComposer/index.js rename to src/components/Calendar/components/CalendarSliding/components/DayComposer/index.js index 1cb61727..f41b5c90 100644 --- a/src/components/Calendar/components/DayComposer/index.js +++ b/src/components/Calendar/components/CalendarSliding/components/DayComposer/index.js @@ -4,13 +4,13 @@ import DayButton from './components/DayButton'; import './index.scss'; -const events = ['day:change', 'month:next', 'month:previous']; +const events = ['day:change']; const html = `
      `; -export default function DayComposer(day, month, year) { +export default function DayComposer({ day, month, year }) { Component.call(this, { html, events }); this.day = day; @@ -57,15 +57,9 @@ DayComposer.prototype = Object.assign( dayButton.mount(this.$dayComposer); dayButton.setState(state); - dayButton.listen('day:active', (activeDay) => { - if (state === 'previousMonth') { - this.emit('month:previous', activeDay); - } else if (state === 'nextMonth') { - this.emit('month:next', activeDay); - } else { - this.handleDayActive(dayButton, activeDay); - } - }); + dayButton.listen('day:active', (activeDay) => + this.handleDayActive(dayButton, activeDay), + ); }, handleDayActive(dayButton, activeDay) { diff --git a/src/components/Calendar/components/DayComposer/index.scss b/src/components/Calendar/components/CalendarSliding/components/DayComposer/index.scss similarity index 100% rename from src/components/Calendar/components/DayComposer/index.scss rename to src/components/Calendar/components/CalendarSliding/components/DayComposer/index.scss diff --git a/src/components/Calendar/components/CalendarSliding/index.js b/src/components/Calendar/components/CalendarSliding/index.js new file mode 100644 index 00000000..d04168e9 --- /dev/null +++ b/src/components/Calendar/components/CalendarSliding/index.js @@ -0,0 +1,52 @@ +import { Component } from 'pet-dex-utilities'; +import { MONTHS } from '../../utils/months'; +import Sliding from '../../../Sliding/index'; + +import './index.scss'; +import DayComposer from './components/DayComposer'; + +const events = ['day:change']; + +const html = ` +
      +`; + +export default function CalendarSliding({ day, month, year }) { + Component.call(this, { html, events }); + + this.day = day; + this.month = month; + this.year = year; + this.$calendarSliding = this.selected.get('calendar-sliding'); + this.sliding = new Sliding({ slides: [] }); + + for (let i = 0; i < MONTHS.length; i += 1) { + const $slide = document.createElement('div'); + const dayComposer = new DayComposer({ + day: this.day, + month: i + 1, + year: this.year, + }); + dayComposer.mount($slide); + dayComposer.listen('day:change', (newDay) => + this.emit('day:change', newDay), + ); + this.sliding.add($slide); + } + + this.sliding.mount(this.$calendarSliding); +} + +CalendarSliding.prototype = Object.assign( + CalendarSliding.prototype, + Component.prototype, + { + next() { + this.sliding.next(); + }, + + previous() { + this.sliding.previous(); + }, + }, +); diff --git a/src/components/Calendar/components/CalendarSliding/index.scss b/src/components/Calendar/components/CalendarSliding/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js new file mode 100644 index 00000000..50ea0bcf --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js @@ -0,0 +1,43 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; +import SelectorItem from '../SelectorItem'; + +const events = []; + +const html = ` +
      +
        + +
          +
          +`; + +export default function MonthSelector(monthArray) { + Component.call(this, { html, events }); + + this.monthArray = monthArray; + this.$monthSelector = this.selected.get('month-selector'); + this.$previousMonths = this.selected.get('previous-months'); + this.$currentMonth = this.selected.get('current-month'); + this.$nextMonths = this.selected.get('next-months'); + + for (let i = 0; i < monthArray.length; i += 1) { + if (i < 3) { + const selectorItem = new SelectorItem(this.monthArray[i]); + selectorItem.mount(this.$previousMonths); + } + if (i === 3) { + this.$currentMonth.innerText = this.monthArray[i]; + } + if (i > 3) { + const selectorItem = new SelectorItem(this.monthArray[i]); + selectorItem.mount(this.$nextMonths); + } + } +} + +MonthSelector.prototype = Object.assign( + MonthSelector.prototype, + Component.prototype, + {}, +); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss new file mode 100644 index 00000000..9bdcca7b --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss @@ -0,0 +1,71 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.month-selector { + width: 100%; + + display: flex; + gap: 2.4rem; + + align-items: center; + justify-content: center; + + margin-bottom: 2.4rem; + + padding-bottom: 2.4rem; + + border-bottom: 0.1rem solid colors.$gray150; + + &__previous-months, + &__next-months { + display: flex; + gap: 1.6rem; + + align-items: center; + justify-content: center; + } + + &__current-month { + align-self: center; + + font-family: fonts.$primaryFont; + color: colors.$primary200; + font-size: fonts.$lg; + font-weight: fonts.$semiBold; + + padding: 0.6rem 1.2rem; + border: 0.1rem solid colors.$blue100; + + background-color: colors.$blue150; + border-radius: 1.4rem; + } +} + +@include breakpoints.from667 { + .month-selector { + width: max-content; + + margin-bottom: 0; + padding-bottom: 0; + border-bottom: 0; + + &__previous-months, + &__next-months { + display: none; + } + + &__current-month { + color: colors.$gray800; + font-weight: fonts.$regular; + + padding: 0; + border: 0; + + background-color: colors.$secondary100; + + cursor: pointer; + } + } +} diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.js new file mode 100644 index 00000000..f5286842 --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.js @@ -0,0 +1,25 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; + +const events = []; + +const html = ` +
        • +`; + +export default function SelectorItem(item) { + Component.call(this, { html, events }); + this.item = item; + this.$selectorItem = this.selected.get('selector-item'); + this.$selectorItem.innerText = this.item; +} + +SelectorItem.prototype = Object.assign( + SelectorItem.prototype, + Component.prototype, + { + active() { + this.$selectorItem.classList.add('selector-item--active'); + }, + }, +); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.scss new file mode 100644 index 00000000..281fa15a --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorItem/index.scss @@ -0,0 +1,11 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.selector-item { + font-family: fonts.$primaryFont; + color: colors.$gray700; + font-size: fonts.$xs; + font-weight: fonts.$medium; +} diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js new file mode 100644 index 00000000..a55d7de1 --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js @@ -0,0 +1,22 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; + +const events = []; + +const html = ` +
        • +`; + +export default function ModalItem(item) { + Component.call(this, { html, events }); + + this.item = item; + this.$modalItem = this.selected.get('modal-item'); + this.$modalItem.innerText = this.item; +} + +ModalItem.prototype = Object.assign( + ModalItem.prototype, + Component.prototype, + {}, +); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js new file mode 100644 index 00000000..f4bcfff0 --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -0,0 +1,27 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; +import ModalItem from './components/ModalItem'; + +const events = []; + +const html = ` +
            +`; + +export default function SelectorModal(dateArray) { + Component.call(this, { html, events }); + + this.dateArray = dateArray.slice(1, -1); + this.selectorModal = this.selected.get('selector-modal'); + + for (let i = 0; i < this.dateArray.length; i += 1) { + const modalItem = new ModalItem(this.dateArray[i]); + modalItem.mount(this.selectorModal); + } +} + +SelectorModal.prototype = Object.assign( + SelectorModal.prototype, + Component.prototype, + {}, +); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss new file mode 100644 index 00000000..284c6e6a --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss @@ -0,0 +1,28 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.selector-modal { + width: 100%; + + display: flex; + flex-direction: column; + + padding: 1rem 0; + + position: absolute; + z-index: 2; + + list-style: none; + + background-color: colors.$secondary100; + + border-radius: 0.1rem; +} + +@include breakpoints.from667 { + .selector-modal { + width: max-content; + } +} diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js new file mode 100644 index 00000000..4feeb1b6 --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js @@ -0,0 +1,27 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; + +const events = []; + +const html = ` +
            +`; + +export default function YearSelector(year) { + Component.call(this, { html, events }); + + this.year = year; + this.$yearSelector = this.selected.get('year-selector'); + this.setYear(year); +} + +YearSelector.prototype = Object.assign( + YearSelector.prototype, + Component.prototype, + { + setYear(year) { + this.year = year; + this.$yearSelector.innerText = this.year; + }, + }, +); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Calendar/components/DateSelectorComposer/index.js b/src/components/Calendar/components/DateSelectorComposer/index.js new file mode 100644 index 00000000..2cb956b9 --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/index.js @@ -0,0 +1,32 @@ +import { Component } from 'pet-dex-utilities'; +import './index.scss'; +import MonthSelector from './components/MonthSelector'; +import { monthArrayGenerator } from './utils/monthArray'; +import SelectorModal from './components/SelectorModal'; + +const events = []; + +const html = ` +
            +`; + +export default function DateSelectorComposer(month, year) { + Component.call(this, { html, events }); + + this.month = month; + this.year = year; + this.$dateSelector = this.selected.get('date-selector'); + + this.monthArray = monthArrayGenerator(month - 1); + this.monthSelector = new MonthSelector(this.monthArray); + this.monthSelector.mount(this.$dateSelector); + + this.modal = new SelectorModal(this.monthArray); + this.modal.mount(this.$dateSelector); +} + +DateSelectorComposer.prototype = Object.assign( + DateSelectorComposer.prototype, + Component.prototype, + {}, +); diff --git a/src/components/Calendar/components/DateSelectorComposer/index.scss b/src/components/Calendar/components/DateSelectorComposer/index.scss new file mode 100644 index 00000000..dcaf5a97 --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/index.scss @@ -0,0 +1,16 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.date-selector { + width: 100%; + + position: relative; +} + +@include breakpoints.from667 { + .date-selector { + width: max-content; + } +} diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/monthArray.js b/src/components/Calendar/components/DateSelectorComposer/utils/monthArray.js new file mode 100644 index 00000000..e5cb8796 --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/utils/monthArray.js @@ -0,0 +1,10 @@ +import { MONTHS } from '../../../utils/months'; + +export function monthArrayGenerator(month) { + const monthArray = new Array(7); + for (let i = 0; i < monthArray.length; i += 1) { + const monthIndex = (month - (3 - i) + 12) % 12; + monthArray[i] = MONTHS[monthIndex]; + } + return monthArray; +} diff --git a/src/components/Calendar/components/NavigationButton/index.scss b/src/components/Calendar/components/NavigationButton/index.scss index f0bb58dc..854e2e80 100644 --- a/src/components/Calendar/components/NavigationButton/index.scss +++ b/src/components/Calendar/components/NavigationButton/index.scss @@ -12,8 +12,6 @@ align-items: center; justify-content: center; - margin-bottom: 2.4rem; - border: 0.1rem solid rgb(160, 174, 192); background-color: colors.$secondary100; diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js index 8cb1cd2b..89e69e1c 100644 --- a/src/components/Calendar/index.js +++ b/src/components/Calendar/index.js @@ -1,10 +1,11 @@ import { Component } from 'pet-dex-utilities'; import dayjs from 'dayjs'; -import DayComposer from './components/DayComposer'; import WeekDayComposer from './components/WeekDayComposer'; import NavigationButton from './components/NavigationButton'; +import CalendarSliding from './components/CalendarSliding'; import './index.scss'; +import DateSelectorComposer from './components/DateSelectorComposer'; const events = []; @@ -26,29 +27,30 @@ export default function Calendar({ day, month, year }) { this.$calendarControls = this.selected.get('calendar-controls'); this.$calendarContent = this.selected.get('calendar-content'); + this.previousButton = new NavigationButton('previous'); + this.previousButton.mount(this.$calendarControls); + this.previousButton.listen('button:click', () => this.previousMonth()); + + this.dateSelector = new DateSelectorComposer(this.month, this.year); + this.dateSelector.mount(this.$calendarControls); + + this.nextButton = new NavigationButton('next'); + this.nextButton.mount(this.$calendarControls); + this.nextButton.listen('button:click', () => this.nextMonth()); + this.weekDayComposer = new WeekDayComposer(); this.weekDayComposer.mount(this.$calendarContent); - this.mountDays = () => { - if (this.dayComposer) this.dayComposer.unmount(); + this.mountCalendarSliding = () => { + if (this.calendarSliding) this.calendarSliding.unmount(); - this.dayComposer = new DayComposer(this.day, this.month, this.year); - this.dayComposer.mount(this.$calendarContent); - this.dayComposer.listen('day:change', (newDay) => this.setDay(newDay)); - this.dayComposer.listen('month:previous', (newDay) => - this.previousMonth(newDay), - ); - this.dayComposer.listen('month:next', (newDay) => this.nextMonth(newDay)); + this.calendarSliding = new CalendarSliding(this.getDate()); + this.calendarSliding.mount(this.$calendarContent); + this.calendarSliding.listen('day:change', (newDay) => this.setDay(newDay)); }; + this.mountCalendarSliding(); this.setDate(this.day, this.month, this.year); - - this.previousButton = new NavigationButton('previous'); - this.previousButton.mount(this.$calendarControls); - this.previousButton.listen('button:click', () => this.previousMonth()); - this.nextButton = new NavigationButton('next'); - this.nextButton.mount(this.$calendarControls); - this.nextButton.listen('button:click', () => this.nextMonth()); } Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { @@ -59,8 +61,6 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { this.firstDayInWeek = dayjs(`${this.year}-${this.month}-${this.day}`).day(); this.weekDayComposer.activeWeekDay(this.firstDayInWeek); - - this.mountDays(); }, getDate() { @@ -87,6 +87,9 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { if (this.month > 12) { this.month = 1; this.year += 1; + this.mountCalendarSliding(); + } else { + this.calendarSliding.next(); } const totalDaysInMonth = dayjs( @@ -104,6 +107,20 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { if (this.month < 1) { this.month = 12; this.year -= 1; + this.mountCalendarSliding(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + this.calendarSliding.next(); + } else { + this.calendarSliding.previous(); } const totalDaysInMonth = dayjs( diff --git a/src/components/Calendar/index.scss b/src/components/Calendar/index.scss index d39438ff..979e2c8b 100644 --- a/src/components/Calendar/index.scss +++ b/src/components/Calendar/index.scss @@ -7,6 +7,10 @@ &__controls { display: flex; + align-items: center; + justify-content: space-between; + + margin-bottom: 2.4rem; } } diff --git a/src/components/Calendar/utils/months.js b/src/components/Calendar/utils/months.js index 759537b3..956f6c9a 100644 --- a/src/components/Calendar/utils/months.js +++ b/src/components/Calendar/utils/months.js @@ -1,4 +1,4 @@ -export const MONTNHS = [ +export const MONTHS = [ 'Janeiro', 'Fevereiro', 'Março', diff --git a/src/stories/Calendar.stories.js b/src/stories/Calendar.stories.js index 133cf423..55c03cc2 100644 --- a/src/stories/Calendar.stories.js +++ b/src/stories/Calendar.stories.js @@ -11,4 +11,10 @@ export default { }, }; -export const Default = {}; +export const Default = { + args: { + day: 1, + month: 1, + year: 2024, + }, +}; From 8b3d3e6596da5403134709fdc4651bc996d6ccd2 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Mon, 22 Jul 2024 22:03:44 -0300 Subject: [PATCH 12/20] feat: implements date modal --- .../components/MonthSelector/index.js | 6 ++- .../components/ModalItem/index.js | 10 ++--- .../components/ModalItem/index.scss | 43 +++++++++++++++++++ .../components/SelectorModal/index.js | 1 + .../components/SelectorModal/index.scss | 26 +++++++++-- .../components/DateSelectorComposer/index.js | 11 +++-- .../DateSelectorComposer/index.scss | 8 +--- .../utils/ModalController.js | 30 +++++++++++++ 8 files changed, 116 insertions(+), 19 deletions(-) create mode 100644 src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js index 50ea0bcf..5497eb2d 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js @@ -2,7 +2,7 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; import SelectorItem from '../SelectorItem'; -const events = []; +const events = ['selector:click']; const html = `
            @@ -34,6 +34,10 @@ export default function MonthSelector(monthArray) { selectorItem.mount(this.$nextMonths); } } + + this.$currentMonth.addEventListener('click', () => + this.emit('selector:click'), + ); } MonthSelector.prototype = Object.assign( diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js index a55d7de1..9dd2fb07 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js @@ -15,8 +15,8 @@ export default function ModalItem(item) { this.$modalItem.innerText = this.item; } -ModalItem.prototype = Object.assign( - ModalItem.prototype, - Component.prototype, - {}, -); +ModalItem.prototype = Object.assign(ModalItem.prototype, Component.prototype, { + active() { + this.$modalItem.classList.add('selector-modal__item--active'); + }, +}); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.scss index e69de29b..7bbde514 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.scss @@ -0,0 +1,43 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.selector-modal__item { + width: 100%; + + font-family: fonts.$primaryFont; + color: colors.$gray500; + text-align: center; + font-size: fonts.$md; + font-weight: fonts.$medium; + line-height: 1.7; + + cursor: pointer; + + &--active { + color: colors.$gray800; + font-size: fonts.$lg; + font-weight: fonts.$bold; + + border-top: 1px solid colors.$gray150; + border-bottom: 1px solid colors.$gray150; + + position: relative; + + &::after { + width: 1.6rem; + height: 2.3rem; + + margin-left: 1rem; + + position: absolute; + + top: 0.9rem; + + background-image: url('../../../../../../images/arrows.svg'); + + content: ''; + } + } +} diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index f4bcfff0..c98fcc54 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -17,6 +17,7 @@ export default function SelectorModal(dateArray) { for (let i = 0; i < this.dateArray.length; i += 1) { const modalItem = new ModalItem(this.dateArray[i]); modalItem.mount(this.selectorModal); + if (i === 2) modalItem.active(); } } diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss index 284c6e6a..705f239e 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss @@ -6,23 +6,43 @@ .selector-modal { width: 100%; - display: flex; + display: none; flex-direction: column; + gap: 0.6rem; padding: 1rem 0; position: absolute; + top: 4.6rem; z-index: 2; list-style: none; background-color: colors.$secondary100; - border-radius: 0.1rem; + box-shadow: 0 4px 20px -2px rgba(50, 50, 71, 0.04); + + box-shadow: 0 0 5px 0 rgba(12, 26, 75, 0.08); + + border-radius: 1rem; + + animation: openModal 0.3s ease-out; } @include breakpoints.from667 { .selector-modal { - width: max-content; + display: flex; + } +} + +@keyframes openModal { + from { + transform: translateY(-2.5rem); + opacity: 0; + } + + to { + transform: translateY(0); + opacity: 1; } } diff --git a/src/components/Calendar/components/DateSelectorComposer/index.js b/src/components/Calendar/components/DateSelectorComposer/index.js index 2cb956b9..8aabe070 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/index.js @@ -2,7 +2,7 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; import MonthSelector from './components/MonthSelector'; import { monthArrayGenerator } from './utils/monthArray'; -import SelectorModal from './components/SelectorModal'; +import { ModalController } from './utils/ModalController'; const events = []; @@ -16,13 +16,18 @@ export default function DateSelectorComposer(month, year) { this.month = month; this.year = year; this.$dateSelector = this.selected.get('date-selector'); + this.modalControl = new ModalController(this); this.monthArray = monthArrayGenerator(month - 1); this.monthSelector = new MonthSelector(this.monthArray); this.monthSelector.mount(this.$dateSelector); + this.monthSelector.listen('selector:click', () => + this.modalControl.Open(this.monthArray), + ); - this.modal = new SelectorModal(this.monthArray); - this.modal.mount(this.$dateSelector); + window.addEventListener('click', (event) => + this.modalControl.CloseOnClickOutside(event), + ); } DateSelectorComposer.prototype = Object.assign( diff --git a/src/components/Calendar/components/DateSelectorComposer/index.scss b/src/components/Calendar/components/DateSelectorComposer/index.scss index dcaf5a97..5061d6ca 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/index.scss @@ -4,13 +4,7 @@ @use '~styles/breakpoints.scss' as breakpoints; .date-selector { - width: 100%; + width: 300px; position: relative; } - -@include breakpoints.from667 { - .date-selector { - width: max-content; - } -} diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js new file mode 100644 index 00000000..1a2b3e2b --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js @@ -0,0 +1,30 @@ +import SelectorModal from '../components/SelectorModal'; + +export class ModalController { + constructor(selector) { + this.selector = selector; + } + + Open(dateArray) { + if (this.modal) this.Close(); + + this.modal = new SelectorModal(dateArray); + this.modal.mount(this.selector.$dateSelector); + } + + CloseOnClickOutside(event) { + const isOutside = !event + .composedPath() + .includes(this.selector.$dateSelector); + + if (!isOutside) return; + + this.Close(); + } + + Close() { + if (this.modal) { + this.modal.unmount(); + } + } +} From d559395485cb7ab73b2ecc7faa058eb3a47ef5b5 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 24 Jul 2024 10:02:51 -0300 Subject: [PATCH 13/20] chore: implements year selector --- .../components/MonthSelector/index.js | 2 +- .../components/SelectorModal/index.js | 48 +++++++++++- .../SelectorModal/utils/scrollModal.js | 24 ++++++ .../components/YearSelector/index.js | 44 ++++++++--- .../components/YearSelector/index.scss | 71 ++++++++++++++++++ .../components/DateSelectorComposer/index.js | 59 ++++++++++++--- .../DateSelectorComposer/index.scss | 24 +++++- .../utils/ModalController.js | 2 + .../{monthArray.js => arraysGenerators.js} | 8 ++ src/components/Calendar/index.js | 74 +++++++++++++------ 10 files changed, 305 insertions(+), 51 deletions(-) create mode 100644 src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js rename src/components/Calendar/components/DateSelectorComposer/utils/{monthArray.js => arraysGenerators.js} (59%) diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js index 5497eb2d..2bec0d34 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js @@ -21,7 +21,7 @@ export default function MonthSelector(monthArray) { this.$currentMonth = this.selected.get('current-month'); this.$nextMonths = this.selected.get('next-months'); - for (let i = 0; i < monthArray.length; i += 1) { + for (let i = 0; i < this.monthArray.length; i += 1) { if (i < 3) { const selectorItem = new SelectorItem(this.monthArray[i]); selectorItem.mount(this.$previousMonths); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index c98fcc54..baaa27e8 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -1,8 +1,10 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; +import { MONTHS } from '../../../../utils/months'; import ModalItem from './components/ModalItem'; +import { scrollModal } from './utils/scrollModal'; -const events = []; +const events = ['month:change', 'year:change']; const html = `
              @@ -13,16 +15,58 @@ export default function SelectorModal(dateArray) { this.dateArray = dateArray.slice(1, -1); this.selectorModal = this.selected.get('selector-modal'); + this.isYear = typeof dateArray[0] === 'number'; for (let i = 0; i < this.dateArray.length; i += 1) { const modalItem = new ModalItem(this.dateArray[i]); modalItem.mount(this.selectorModal); if (i === 2) modalItem.active(); } + + this.items = this.selectorModal.children; + + scrollModal(this); } SelectorModal.prototype = Object.assign( SelectorModal.prototype, Component.prototype, - {}, + { + changeMonth(month) { + for (let i = 0; i < this.dateArray.length; i += 1) { + const index = (month - (2 - i) + 12) % 12; + this.dateArray[i] = MONTHS[index]; + } + + this.dateArray.forEach((item, index) => { + this.items[index].innerText = item; + }); + + this.items[2].scrollIntoView({ + behavior: 'instant', + block: 'center', + inline: 'center', + }); + + this.emit('month:change', month); + }, + + changeYear(year) { + for (let i = 0; i < this.dateArray.length; i += 1) { + this.dateArray[i] = year - (2 - i); + } + + this.dateArray.forEach((item, index) => { + this.items[index].innerText = item; + }); + + this.items[2].scrollIntoView({ + behavior: 'instant', + block: 'center', + inline: 'center', + }); + + this.emit('year:change', year); + }, + }, ); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js new file mode 100644 index 00000000..2863f25c --- /dev/null +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js @@ -0,0 +1,24 @@ +import { MONTHS } from '../../../../../utils/months'; + +export function scrollModal(selector) { + const { selectorModal } = selector; + + const handleScroll = (event) => { + event.preventDefault(); + const isScrollNext = event.deltaY > 0; + + if (selector.isYear) { + const nextYear = +selector.items[3].innerText; + const prevYear = +selector.items[1].innerText; + const newYear = isScrollNext ? nextYear : prevYear; + selector.changeYear(newYear); + } else { + const nextMonth = MONTHS.indexOf(selector.items[3].innerText); + const prevMonth = MONTHS.indexOf(selector.items[1].innerText); + const newMonth = isScrollNext ? nextMonth : prevMonth; + selector.changeMonth(newMonth); + } + }; + + selectorModal.addEventListener('wheel', handleScroll); +} diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js index 4feeb1b6..e36542fd 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js @@ -1,27 +1,47 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; +import SelectorItem from '../SelectorItem'; -const events = []; +const events = ['selector:click']; const html = ` -
              +
              +
                + +
                  +
                  `; -export default function YearSelector(year) { +export default function YearSelector(yearArray) { Component.call(this, { html, events }); - this.year = year; - this.$yearSelector = this.selected.get('year-selector'); - this.setYear(year); + this.yearArray = yearArray; + this.$monthSelector = this.selected.get('year-selector'); + this.$previousYears = this.selected.get('previous-years'); + this.$currentYear = this.selected.get('current-year'); + this.$nextYears = this.selected.get('next-years'); + + for (let i = 0; i < this.yearArray.length; i += 1) { + if (i < 3) { + const selectorItem = new SelectorItem(this.yearArray[i]); + selectorItem.mount(this.$previousYears); + } + if (i === 3) { + this.$currentYear.innerText = this.yearArray[i]; + } + if (i > 3) { + const selectorItem = new SelectorItem(this.yearArray[i]); + selectorItem.mount(this.$nextYears); + } + } + + this.$currentYear.addEventListener('click', () => + this.emit('selector:click'), + ); } YearSelector.prototype = Object.assign( YearSelector.prototype, Component.prototype, - { - setYear(year) { - this.year = year; - this.$yearSelector.innerText = this.year; - }, - }, + {}, ); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss index e69de29b..6cfb14ec 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss @@ -0,0 +1,71 @@ +@use '~styles/base.scss'; +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.year-selector { + width: 100%; + + display: flex; + gap: 2.4rem; + + align-items: center; + justify-content: center; + + margin-bottom: 2.4rem; + + padding-bottom: 2.4rem; + + border-bottom: 0.1rem solid colors.$gray150; + + &__previous-years, + &__next-years { + display: flex; + gap: 1.6rem; + + align-items: center; + justify-content: center; + } + + &__current-year { + align-self: center; + + font-family: fonts.$primaryFont; + color: colors.$primary200; + font-size: fonts.$lg; + font-weight: fonts.$semiBold; + + padding: 0.6rem 1.2rem; + border: 0.1rem solid colors.$blue100; + + background-color: colors.$blue150; + border-radius: 1.4rem; + } +} + +@include breakpoints.from667 { + .year-selector { + width: max-content; + + margin-bottom: 0; + padding-bottom: 0; + border-bottom: 0; + + &__previous-years, + &__next-years { + display: none; + } + + &__current-year { + color: colors.$gray800; + font-weight: fonts.$regular; + + padding: 0; + border: 0; + + background-color: colors.$secondary100; + + cursor: pointer; + } + } +} diff --git a/src/components/Calendar/components/DateSelectorComposer/index.js b/src/components/Calendar/components/DateSelectorComposer/index.js index 8aabe070..7be0e13b 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/index.js @@ -1,13 +1,20 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; import MonthSelector from './components/MonthSelector'; -import { monthArrayGenerator } from './utils/monthArray'; import { ModalController } from './utils/ModalController'; +import { + yearArrayGenerator, + monthArrayGenerator, +} from './utils/arraysGenerators'; +import YearSelector from './components/YearSelector'; -const events = []; +const events = ['month:change']; const html = ` -
                  +
                  +
                  +
                  +
                  `; export default function DateSelectorComposer(month, year) { @@ -16,14 +23,34 @@ export default function DateSelectorComposer(month, year) { this.month = month; this.year = year; this.$dateSelector = this.selected.get('date-selector'); + this.$monthSelector = this.selected.get('month-selector'); + this.$yearSelector = this.selected.get('year-selector'); this.modalControl = new ModalController(this); - this.monthArray = monthArrayGenerator(month - 1); - this.monthSelector = new MonthSelector(this.monthArray); - this.monthSelector.mount(this.$dateSelector); - this.monthSelector.listen('selector:click', () => - this.modalControl.Open(this.monthArray), - ); + this.mountYearSelector = () => { + if (this.yearSelector) this.yearSelector.unmount(); + + this.yearArray = yearArrayGenerator(this.year); + this.yearSelector = new YearSelector(this.yearArray); + this.yearSelector.mount(this.$yearSelector); + this.yearSelector.listen('selector:click', () => + this.modalControl.Open(this.yearArray), + ); + }; + + this.mountMonthSelector = () => { + if (this.monthSelector) this.monthSelector.unmount(); + + this.monthArray = monthArrayGenerator(this.month); + this.monthSelector = new MonthSelector(this.monthArray); + this.monthSelector.mount(this.$monthSelector); + this.monthSelector.listen('selector:click', () => + this.modalControl.Open(this.monthArray), + ); + }; + + this.mountYearSelector(); + this.mountMonthSelector(); window.addEventListener('click', (event) => this.modalControl.CloseOnClickOutside(event), @@ -33,5 +60,17 @@ export default function DateSelectorComposer(month, year) { DateSelectorComposer.prototype = Object.assign( DateSelectorComposer.prototype, Component.prototype, - {}, + { + setMonth(month) { + this.month = month; + this.mountMonthSelector(); + this.emit('month:change', month); + }, + + setYear(year) { + this.year = year; + this.mountYearSelector(); + this.emit('year:change', year); + }, + }, ); diff --git a/src/components/Calendar/components/DateSelectorComposer/index.scss b/src/components/Calendar/components/DateSelectorComposer/index.scss index 5061d6ca..12949afe 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/index.scss @@ -4,7 +4,27 @@ @use '~styles/breakpoints.scss' as breakpoints; .date-selector { - width: 300px; + width: 100%; +} + +@include breakpoints.from667 { + .date-selector { + width: 10%; + min-width: 23.1rem; + + display: flex; + flex-direction: row-reverse; + gap: 1rem; + + position: relative; + + &::before { + width: 1.6rem; + height: 2.3rem; + + background-image: url('../../images/arrows.svg'); - position: relative; + content: ''; + } + } } diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js index 1a2b3e2b..1f1fb75b 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js @@ -10,6 +10,8 @@ export class ModalController { this.modal = new SelectorModal(dateArray); this.modal.mount(this.selector.$dateSelector); + this.modal.listen('month:change', (month) => this.selector.setMonth(month)); + this.modal.listen('year:change', (year) => this.selector.setYear(year)); } CloseOnClickOutside(event) { diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/monthArray.js b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js similarity index 59% rename from src/components/Calendar/components/DateSelectorComposer/utils/monthArray.js rename to src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js index e5cb8796..2d5481d2 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/monthArray.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js @@ -8,3 +8,11 @@ export function monthArrayGenerator(month) { } return monthArray; } + +export function yearArrayGenerator(year) { + const yearArray = new Array(7); + for (let i = 0; i < yearArray.length; i += 1) { + yearArray[i] = year - (3 - i); + } + return yearArray; +} diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js index 89e69e1c..ba26401e 100644 --- a/src/components/Calendar/index.js +++ b/src/components/Calendar/index.js @@ -31,8 +31,12 @@ export default function Calendar({ day, month, year }) { this.previousButton.mount(this.$calendarControls); this.previousButton.listen('button:click', () => this.previousMonth()); - this.dateSelector = new DateSelectorComposer(this.month, this.year); + this.dateSelector = new DateSelectorComposer(this.month - 1, this.year); this.dateSelector.mount(this.$calendarControls); + this.dateSelector.listen('month:change', (newMonth) => + this.setMonth(newMonth + 1), + ); + this.dateSelector.listen('year:change', (newYear) => this.setYear(newYear)); this.nextButton = new NavigationButton('next'); this.nextButton.mount(this.$calendarControls); @@ -50,6 +54,22 @@ export default function Calendar({ day, month, year }) { }; this.mountCalendarSliding(); + + this.slidingMonths = (monthForSliding) => { + if (this.month < monthForSliding) { + const monthDifference = monthForSliding - this.month; + for (let i = 0; i < monthDifference; i += 1) { + this.calendarSliding.next(); + } + } + if (this.month > monthForSliding) { + const monthDifference = this.month - monthForSliding; + for (let i = 0; i < monthDifference; i += 1) { + this.calendarSliding.previous(); + } + } + }; + this.setDate(this.day, this.month, this.year); } @@ -80,16 +100,34 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { return this.day; }, + setMonth(month) { + this.slidingMonths(month); + this.month = month; + this.setDate(this.day, this.month, this.year); + }, + + getMonth() { + return this.month; + }, + + setYear(year) { + this.year = year; + this.mountCalendarSliding(); + this.dateSelector.setYear(this.year); + this.setDate(this.day, this.month, this.year); + }, + + getYear() { + return this.year; + }, + nextMonth(day) { this.day = day || this.day; - this.month += 1; + this.setMonth(this.month + 1); if (this.month > 12) { - this.month = 1; - this.year += 1; - this.mountCalendarSliding(); - } else { - this.calendarSliding.next(); + this.setMonth(1); + this.setYear(this.year + 1); } const totalDaysInMonth = dayjs( @@ -97,30 +135,17 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { ).daysInMonth(); if (this.day > totalDaysInMonth) this.day = totalDaysInMonth; + this.dateSelector.setMonth(this.month - 1); this.setDate(this.day, this.month, this.year); }, previousMonth(day) { this.day = day || this.day; - this.month -= 1; + this.setMonth(this.month - 1); if (this.month < 1) { - this.month = 12; - this.year -= 1; - this.mountCalendarSliding(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - this.calendarSliding.next(); - } else { - this.calendarSliding.previous(); + this.setMonth(12); + this.setYear(this.year - 1); } const totalDaysInMonth = dayjs( @@ -128,6 +153,7 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { ).daysInMonth(); if (this.day > totalDaysInMonth) this.day = totalDaysInMonth; + this.dateSelector.setMonth(this.month - 1); this.setDate(this.day, this.month, this.year); }, }); From df8d222e6f8ec2f603a443d58e49c09a8f5011dc Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 24 Jul 2024 21:55:58 -0300 Subject: [PATCH 14/20] chore: remove sliding --- .../components/CalendarSliding/index.js | 52 ------------------- .../components/CalendarSliding/index.scss | 0 .../components/MonthSelector/index.js | 4 -- .../components/MonthSelector/index.scss | 2 - .../components/SelectorModal/index.js | 25 +++++---- .../SelectorModal/utils/scrollModal.js | 19 +++---- .../components/YearSelector/index.js | 4 -- .../components/YearSelector/index.scss | 2 - .../components/DateSelectorComposer/index.js | 14 +++-- .../DateSelectorComposer/index.scss | 2 + .../utils/ModalController.js | 4 +- .../DayComposer/components/DayButton/index.js | 0 .../components/DayButton/index.scss | 0 .../components => }/DayComposer/index.js | 0 .../components => }/DayComposer/index.scss | 0 src/components/Calendar/index.js | 47 ++++++----------- 16 files changed, 45 insertions(+), 130 deletions(-) delete mode 100644 src/components/Calendar/components/CalendarSliding/index.js delete mode 100644 src/components/Calendar/components/CalendarSliding/index.scss rename src/components/Calendar/components/{CalendarSliding/components => }/DayComposer/components/DayButton/index.js (100%) rename src/components/Calendar/components/{CalendarSliding/components => }/DayComposer/components/DayButton/index.scss (100%) rename src/components/Calendar/components/{CalendarSliding/components => }/DayComposer/index.js (100%) rename src/components/Calendar/components/{CalendarSliding/components => }/DayComposer/index.scss (100%) diff --git a/src/components/Calendar/components/CalendarSliding/index.js b/src/components/Calendar/components/CalendarSliding/index.js deleted file mode 100644 index d04168e9..00000000 --- a/src/components/Calendar/components/CalendarSliding/index.js +++ /dev/null @@ -1,52 +0,0 @@ -import { Component } from 'pet-dex-utilities'; -import { MONTHS } from '../../utils/months'; -import Sliding from '../../../Sliding/index'; - -import './index.scss'; -import DayComposer from './components/DayComposer'; - -const events = ['day:change']; - -const html = ` -
                  -`; - -export default function CalendarSliding({ day, month, year }) { - Component.call(this, { html, events }); - - this.day = day; - this.month = month; - this.year = year; - this.$calendarSliding = this.selected.get('calendar-sliding'); - this.sliding = new Sliding({ slides: [] }); - - for (let i = 0; i < MONTHS.length; i += 1) { - const $slide = document.createElement('div'); - const dayComposer = new DayComposer({ - day: this.day, - month: i + 1, - year: this.year, - }); - dayComposer.mount($slide); - dayComposer.listen('day:change', (newDay) => - this.emit('day:change', newDay), - ); - this.sliding.add($slide); - } - - this.sliding.mount(this.$calendarSliding); -} - -CalendarSliding.prototype = Object.assign( - CalendarSliding.prototype, - Component.prototype, - { - next() { - this.sliding.next(); - }, - - previous() { - this.sliding.previous(); - }, - }, -); diff --git a/src/components/Calendar/components/CalendarSliding/index.scss b/src/components/Calendar/components/CalendarSliding/index.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js index 2bec0d34..2865a677 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js @@ -34,10 +34,6 @@ export default function MonthSelector(monthArray) { selectorItem.mount(this.$nextMonths); } } - - this.$currentMonth.addEventListener('click', () => - this.emit('selector:click'), - ); } MonthSelector.prototype = Object.assign( diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss index 9bdcca7b..28f52c96 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss @@ -64,8 +64,6 @@ border: 0; background-color: colors.$secondary100; - - cursor: pointer; } } } diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index baaa27e8..6c4ffdf5 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -2,7 +2,6 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; import { MONTHS } from '../../../../utils/months'; import ModalItem from './components/ModalItem'; -import { scrollModal } from './utils/scrollModal'; const events = ['month:change', 'year:change']; @@ -10,22 +9,22 @@ const html = `
                    `; -export default function SelectorModal(dateArray) { +export default function SelectorModal(monthArray, yearArray) { Component.call(this, { html, events }); - this.dateArray = dateArray.slice(1, -1); + this.monthArray = monthArray.slice(1, -1); + this.yearArray = yearArray.slice(1, -1); this.selectorModal = this.selected.get('selector-modal'); - this.isYear = typeof dateArray[0] === 'number'; - for (let i = 0; i < this.dateArray.length; i += 1) { - const modalItem = new ModalItem(this.dateArray[i]); + for (let i = 0; i < this.monthArray.length; i += 1) { + const modalItem = new ModalItem( + `${this.monthArray[i]} ${this.yearArray[i]}`, + ); modalItem.mount(this.selectorModal); if (i === 2) modalItem.active(); } this.items = this.selectorModal.children; - - scrollModal(this); } SelectorModal.prototype = Object.assign( @@ -33,12 +32,12 @@ SelectorModal.prototype = Object.assign( Component.prototype, { changeMonth(month) { - for (let i = 0; i < this.dateArray.length; i += 1) { + for (let i = 0; i < this.monthArray.length; i += 1) { const index = (month - (2 - i) + 12) % 12; - this.dateArray[i] = MONTHS[index]; + this.monthArray[i] = MONTHS[index]; } - this.dateArray.forEach((item, index) => { + this.monthArray.forEach((item, index) => { this.items[index].innerText = item; }); @@ -52,11 +51,11 @@ SelectorModal.prototype = Object.assign( }, changeYear(year) { - for (let i = 0; i < this.dateArray.length; i += 1) { + for (let i = 0; i < this.yearArray.length; i += 1) { this.dateArray[i] = year - (2 - i); } - this.dateArray.forEach((item, index) => { + this.yearArray.forEach((item, index) => { this.items[index].innerText = item; }); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js index 2863f25c..e22850eb 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js @@ -7,17 +7,14 @@ export function scrollModal(selector) { event.preventDefault(); const isScrollNext = event.deltaY > 0; - if (selector.isYear) { - const nextYear = +selector.items[3].innerText; - const prevYear = +selector.items[1].innerText; - const newYear = isScrollNext ? nextYear : prevYear; - selector.changeYear(newYear); - } else { - const nextMonth = MONTHS.indexOf(selector.items[3].innerText); - const prevMonth = MONTHS.indexOf(selector.items[1].innerText); - const newMonth = isScrollNext ? nextMonth : prevMonth; - selector.changeMonth(newMonth); - } + const nextYear = selector.items[3].innerText; + const prevYear = +selector.items[1].innerText; + const newYear = isScrollNext ? nextYear : prevYear; + selector.changeYear(newYear); + const nextMonth = MONTHS.indexOf(selector.items[3].innerText); + const prevMonth = MONTHS.indexOf(selector.items[1].innerText); + const newMonth = isScrollNext ? nextMonth : prevMonth; + selector.changeMonth(newMonth); }; selectorModal.addEventListener('wheel', handleScroll); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js index e36542fd..4760e062 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js @@ -34,10 +34,6 @@ export default function YearSelector(yearArray) { selectorItem.mount(this.$nextYears); } } - - this.$currentYear.addEventListener('click', () => - this.emit('selector:click'), - ); } YearSelector.prototype = Object.assign( diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss index 6cfb14ec..f4a2857f 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss @@ -64,8 +64,6 @@ border: 0; background-color: colors.$secondary100; - - cursor: pointer; } } } diff --git a/src/components/Calendar/components/DateSelectorComposer/index.js b/src/components/Calendar/components/DateSelectorComposer/index.js index 7be0e13b..0e107a3b 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/index.js @@ -27,31 +27,29 @@ export default function DateSelectorComposer(month, year) { this.$yearSelector = this.selected.get('year-selector'); this.modalControl = new ModalController(this); + this.yearArray = yearArrayGenerator(this.year); + this.monthArray = monthArrayGenerator(this.month); + this.mountYearSelector = () => { if (this.yearSelector) this.yearSelector.unmount(); - this.yearArray = yearArrayGenerator(this.year); this.yearSelector = new YearSelector(this.yearArray); this.yearSelector.mount(this.$yearSelector); - this.yearSelector.listen('selector:click', () => - this.modalControl.Open(this.yearArray), - ); }; this.mountMonthSelector = () => { if (this.monthSelector) this.monthSelector.unmount(); - this.monthArray = monthArrayGenerator(this.month); this.monthSelector = new MonthSelector(this.monthArray); this.monthSelector.mount(this.$monthSelector); - this.monthSelector.listen('selector:click', () => - this.modalControl.Open(this.monthArray), - ); }; this.mountYearSelector(); this.mountMonthSelector(); + this.$dateSelector.addEventListener('click', () => + this.modalControl.Open(this.monthArray, this.yearArray), + ); window.addEventListener('click', (event) => this.modalControl.CloseOnClickOutside(event), ); diff --git a/src/components/Calendar/components/DateSelectorComposer/index.scss b/src/components/Calendar/components/DateSelectorComposer/index.scss index 12949afe..b918fb5c 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/index.scss @@ -5,6 +5,8 @@ .date-selector { width: 100%; + + cursor: pointer; } @include breakpoints.from667 { diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js index 1f1fb75b..d6f4d71a 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js @@ -5,10 +5,10 @@ export class ModalController { this.selector = selector; } - Open(dateArray) { + Open(monthArray, yearArray) { if (this.modal) this.Close(); - this.modal = new SelectorModal(dateArray); + this.modal = new SelectorModal(monthArray, yearArray); this.modal.mount(this.selector.$dateSelector); this.modal.listen('month:change', (month) => this.selector.setMonth(month)); this.modal.listen('year:change', (year) => this.selector.setYear(year)); diff --git a/src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.js b/src/components/Calendar/components/DayComposer/components/DayButton/index.js similarity index 100% rename from src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.js rename to src/components/Calendar/components/DayComposer/components/DayButton/index.js diff --git a/src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.scss b/src/components/Calendar/components/DayComposer/components/DayButton/index.scss similarity index 100% rename from src/components/Calendar/components/CalendarSliding/components/DayComposer/components/DayButton/index.scss rename to src/components/Calendar/components/DayComposer/components/DayButton/index.scss diff --git a/src/components/Calendar/components/CalendarSliding/components/DayComposer/index.js b/src/components/Calendar/components/DayComposer/index.js similarity index 100% rename from src/components/Calendar/components/CalendarSliding/components/DayComposer/index.js rename to src/components/Calendar/components/DayComposer/index.js diff --git a/src/components/Calendar/components/CalendarSliding/components/DayComposer/index.scss b/src/components/Calendar/components/DayComposer/index.scss similarity index 100% rename from src/components/Calendar/components/CalendarSliding/components/DayComposer/index.scss rename to src/components/Calendar/components/DayComposer/index.scss diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js index ba26401e..26936c84 100644 --- a/src/components/Calendar/index.js +++ b/src/components/Calendar/index.js @@ -2,10 +2,10 @@ import { Component } from 'pet-dex-utilities'; import dayjs from 'dayjs'; import WeekDayComposer from './components/WeekDayComposer'; import NavigationButton from './components/NavigationButton'; -import CalendarSliding from './components/CalendarSliding'; import './index.scss'; import DateSelectorComposer from './components/DateSelectorComposer'; +import DayComposer from './components/DayComposer'; const events = []; @@ -45,29 +45,12 @@ export default function Calendar({ day, month, year }) { this.weekDayComposer = new WeekDayComposer(); this.weekDayComposer.mount(this.$calendarContent); - this.mountCalendarSliding = () => { - if (this.calendarSliding) this.calendarSliding.unmount(); + this.mountDayComposer = () => { + if (this.dayComposer) this.dayComposer.unmount(); - this.calendarSliding = new CalendarSliding(this.getDate()); - this.calendarSliding.mount(this.$calendarContent); - this.calendarSliding.listen('day:change', (newDay) => this.setDay(newDay)); - }; - - this.mountCalendarSliding(); - - this.slidingMonths = (monthForSliding) => { - if (this.month < monthForSliding) { - const monthDifference = monthForSliding - this.month; - for (let i = 0; i < monthDifference; i += 1) { - this.calendarSliding.next(); - } - } - if (this.month > monthForSliding) { - const monthDifference = this.month - monthForSliding; - for (let i = 0; i < monthDifference; i += 1) { - this.calendarSliding.previous(); - } - } + this.dayComposer = new DayComposer(this.getDate()); + this.dayComposer.mount(this.$calendarContent); + this.dayComposer.listen('day:change', (newDay) => this.setDay(newDay)); }; this.setDate(this.day, this.month, this.year); @@ -79,6 +62,7 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { this.month = month; this.year = year; + this.mountDayComposer(); this.firstDayInWeek = dayjs(`${this.year}-${this.month}-${this.day}`).day(); this.weekDayComposer.activeWeekDay(this.firstDayInWeek); }, @@ -101,7 +85,6 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { }, setMonth(month) { - this.slidingMonths(month); this.month = month; this.setDate(this.day, this.month, this.year); }, @@ -112,8 +95,6 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { setYear(year) { this.year = year; - this.mountCalendarSliding(); - this.dateSelector.setYear(this.year); this.setDate(this.day, this.month, this.year); }, @@ -123,11 +104,12 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { nextMonth(day) { this.day = day || this.day; - this.setMonth(this.month + 1); + this.month += 1; if (this.month > 12) { - this.setMonth(1); - this.setYear(this.year + 1); + this.month = 1; + this.year += 1; + this.dateSelector.setYear(this.year); } const totalDaysInMonth = dayjs( @@ -141,11 +123,12 @@ Calendar.prototype = Object.assign(Calendar.prototype, Component.prototype, { previousMonth(day) { this.day = day || this.day; - this.setMonth(this.month - 1); + this.month -= 1; if (this.month < 1) { - this.setMonth(12); - this.setYear(this.year - 1); + this.month = 12; + this.year -= 1; + this.dateSelector.setYear(this.year); } const totalDaysInMonth = dayjs( From f18cace3f881e3b23e4311aa808073171abacf99 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Mon, 29 Jul 2024 10:32:46 -0300 Subject: [PATCH 15/20] feat: add hover in date selector --- .../components/MonthSelector/index.js | 4 +++ .../components/MonthSelector/index.scss | 5 ++++ .../components/SelectorModal/index.js | 28 ++++++++++--------- .../SelectorModal/utils/scrollModal.js | 19 +++++++------ .../components/YearSelector/index.js | 4 +++ .../components/YearSelector/index.scss | 5 ++++ .../components/DateSelectorComposer/index.js | 16 ++++++----- .../utils/ModalController.js | 4 +-- 8 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js index 2865a677..2bec0d34 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.js @@ -34,6 +34,10 @@ export default function MonthSelector(monthArray) { selectorItem.mount(this.$nextMonths); } } + + this.$currentMonth.addEventListener('click', () => + this.emit('selector:click'), + ); } MonthSelector.prototype = Object.assign( diff --git a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss index 28f52c96..413d164c 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/MonthSelector/index.scss @@ -64,6 +64,11 @@ border: 0; background-color: colors.$secondary100; + + &:hover { + color: colors.$primary200; + font-weight: fonts.$semiBold; + } } } } diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index 6c4ffdf5..d391c1db 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -1,7 +1,9 @@ import { Component } from 'pet-dex-utilities'; -import './index.scss'; import { MONTHS } from '../../../../utils/months'; import ModalItem from './components/ModalItem'; +import { scrollModal } from './utils/scrollModal'; + +import './index.scss'; const events = ['month:change', 'year:change']; @@ -9,22 +11,22 @@ const html = `
                      `; -export default function SelectorModal(monthArray, yearArray) { +export default function SelectorModal(dateArray) { Component.call(this, { html, events }); - this.monthArray = monthArray.slice(1, -1); - this.yearArray = yearArray.slice(1, -1); + this.dateArray = dateArray.slice(1, -1); this.selectorModal = this.selected.get('selector-modal'); + this.isYear = typeof dateArray[0] === 'number'; - for (let i = 0; i < this.monthArray.length; i += 1) { - const modalItem = new ModalItem( - `${this.monthArray[i]} ${this.yearArray[i]}`, - ); + for (let i = 0; i < this.dateArray.length; i += 1) { + const modalItem = new ModalItem(this.dateArray[i]); modalItem.mount(this.selectorModal); if (i === 2) modalItem.active(); } this.items = this.selectorModal.children; + + scrollModal(this); } SelectorModal.prototype = Object.assign( @@ -32,12 +34,12 @@ SelectorModal.prototype = Object.assign( Component.prototype, { changeMonth(month) { - for (let i = 0; i < this.monthArray.length; i += 1) { + for (let i = 0; i < this.dateArray.length; i += 1) { const index = (month - (2 - i) + 12) % 12; - this.monthArray[i] = MONTHS[index]; + this.dateArray[i] = MONTHS[index]; } - this.monthArray.forEach((item, index) => { + this.dateArray.forEach((item, index) => { this.items[index].innerText = item; }); @@ -51,11 +53,11 @@ SelectorModal.prototype = Object.assign( }, changeYear(year) { - for (let i = 0; i < this.yearArray.length; i += 1) { + for (let i = 0; i < this.dateArray.length; i += 1) { this.dateArray[i] = year - (2 - i); } - this.yearArray.forEach((item, index) => { + this.dateArray.forEach((item, index) => { this.items[index].innerText = item; }); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js index e22850eb..2863f25c 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/utils/scrollModal.js @@ -7,14 +7,17 @@ export function scrollModal(selector) { event.preventDefault(); const isScrollNext = event.deltaY > 0; - const nextYear = selector.items[3].innerText; - const prevYear = +selector.items[1].innerText; - const newYear = isScrollNext ? nextYear : prevYear; - selector.changeYear(newYear); - const nextMonth = MONTHS.indexOf(selector.items[3].innerText); - const prevMonth = MONTHS.indexOf(selector.items[1].innerText); - const newMonth = isScrollNext ? nextMonth : prevMonth; - selector.changeMonth(newMonth); + if (selector.isYear) { + const nextYear = +selector.items[3].innerText; + const prevYear = +selector.items[1].innerText; + const newYear = isScrollNext ? nextYear : prevYear; + selector.changeYear(newYear); + } else { + const nextMonth = MONTHS.indexOf(selector.items[3].innerText); + const prevMonth = MONTHS.indexOf(selector.items[1].innerText); + const newMonth = isScrollNext ? nextMonth : prevMonth; + selector.changeMonth(newMonth); + } }; selectorModal.addEventListener('wheel', handleScroll); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js index 4760e062..e36542fd 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js @@ -34,6 +34,10 @@ export default function YearSelector(yearArray) { selectorItem.mount(this.$nextYears); } } + + this.$currentYear.addEventListener('click', () => + this.emit('selector:click'), + ); } YearSelector.prototype = Object.assign( diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss index f4a2857f..d473e909 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.scss @@ -64,6 +64,11 @@ border: 0; background-color: colors.$secondary100; + + &:hover { + color: colors.$primary200; + font-weight: fonts.$semiBold; + } } } } diff --git a/src/components/Calendar/components/DateSelectorComposer/index.js b/src/components/Calendar/components/DateSelectorComposer/index.js index 0e107a3b..2e5d982d 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/index.js @@ -8,7 +8,7 @@ import { } from './utils/arraysGenerators'; import YearSelector from './components/YearSelector'; -const events = ['month:change']; +const events = ['month:change', 'year:change']; const html = `
                      @@ -27,29 +27,31 @@ export default function DateSelectorComposer(month, year) { this.$yearSelector = this.selected.get('year-selector'); this.modalControl = new ModalController(this); - this.yearArray = yearArrayGenerator(this.year); - this.monthArray = monthArrayGenerator(this.month); - this.mountYearSelector = () => { if (this.yearSelector) this.yearSelector.unmount(); + this.yearArray = yearArrayGenerator(this.year); this.yearSelector = new YearSelector(this.yearArray); this.yearSelector.mount(this.$yearSelector); + this.yearSelector.listen('selector:click', () => + this.modalControl.Open(this.yearArray), + ); }; this.mountMonthSelector = () => { if (this.monthSelector) this.monthSelector.unmount(); + this.monthArray = monthArrayGenerator(this.month); this.monthSelector = new MonthSelector(this.monthArray); this.monthSelector.mount(this.$monthSelector); + this.monthSelector.listen('selector:click', () => + this.modalControl.Open(this.monthArray), + ); }; this.mountYearSelector(); this.mountMonthSelector(); - this.$dateSelector.addEventListener('click', () => - this.modalControl.Open(this.monthArray, this.yearArray), - ); window.addEventListener('click', (event) => this.modalControl.CloseOnClickOutside(event), ); diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js index d6f4d71a..1f1fb75b 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js @@ -5,10 +5,10 @@ export class ModalController { this.selector = selector; } - Open(monthArray, yearArray) { + Open(dateArray) { if (this.modal) this.Close(); - this.modal = new SelectorModal(monthArray, yearArray); + this.modal = new SelectorModal(dateArray); this.modal.mount(this.selector.$dateSelector); this.modal.listen('month:change', (month) => this.selector.setMonth(month)); this.modal.listen('year:change', (year) => this.selector.setYear(year)); From 9d6b2ad70650523b31057456d5714b418c0d8d34 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Tue, 30 Jul 2024 06:13:21 -0300 Subject: [PATCH 16/20] chore: init virtual scroll --- .../components/SelectorModal/index.js | 41 ++++++++++++++----- .../components/SelectorModal/index.scss | 2 + .../components/YearSelector/index.js | 6 +-- .../components/DateSelectorComposer/index.js | 2 +- .../utils/arraysGenerators.js | 4 +- 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index d391c1db..10a12a07 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -1,7 +1,6 @@ import { Component } from 'pet-dex-utilities'; import { MONTHS } from '../../../../utils/months'; import ModalItem from './components/ModalItem'; -import { scrollModal } from './utils/scrollModal'; import './index.scss'; @@ -14,25 +13,47 @@ const html = ` export default function SelectorModal(dateArray) { Component.call(this, { html, events }); - this.dateArray = dateArray.slice(1, -1); - this.selectorModal = this.selected.get('selector-modal'); + this.dateArray = dateArray; + this.$selectorModal = this.selected.get('selector-modal'); this.isYear = typeof dateArray[0] === 'number'; + this.itemsPerPage = 25; + this.currentPage = 0; - for (let i = 0; i < this.dateArray.length; i += 1) { - const modalItem = new ModalItem(this.dateArray[i]); - modalItem.mount(this.selectorModal); - if (i === 2) modalItem.active(); - } + this.renderItens(); - this.items = this.selectorModal.children; + this.$selectorModal.addEventListener('scroll', this.handleScroll.bind(this)); - scrollModal(this); + setTimeout(() => { + this.$selectorModal.scrollTop = this.$selectorModal.scrollHeight / 2.1121; + }, 0); } SelectorModal.prototype = Object.assign( SelectorModal.prototype, Component.prototype, { + renderItens() { + const start = this.currentPage * this.itemsPerPage; + const end = Math.min(start + this.itemsPerPage, this.dateArray.length); + + for (let i = start; i < end; i += 1) { + const modalItem = new ModalItem(this.dateArray[i]); + modalItem.mount(this.$selectorModal); + } + + this.currentPage += 1; + this.items = this.$selectorModal.children; + }, + + handleScroll() { + const { scrollTop, scrollHeight, clientHeight } = this.$selectorModal; + if ( + scrollTop + clientHeight >= scrollHeight && + this.currentPage * this.itemsPerPage < this.dateArray.length + ) + this.renderItens(); + }, + changeMonth(month) { for (let i = 0; i < this.dateArray.length; i += 1) { const index = (month - (2 - i) + 12) % 12; diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss index 705f239e..66826f80 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss @@ -5,6 +5,8 @@ .selector-modal { width: 100%; + height: 20rem; + overflow: auto; display: none; flex-direction: column; diff --git a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js index e36542fd..17e7f84c 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/YearSelector/index.js @@ -22,14 +22,14 @@ export default function YearSelector(yearArray) { this.$nextYears = this.selected.get('next-years'); for (let i = 0; i < this.yearArray.length; i += 1) { - if (i < 3) { + if (i < 50) { const selectorItem = new SelectorItem(this.yearArray[i]); selectorItem.mount(this.$previousYears); } - if (i === 3) { + if (i === 50) { this.$currentYear.innerText = this.yearArray[i]; } - if (i > 3) { + if (i > 50) { const selectorItem = new SelectorItem(this.yearArray[i]); selectorItem.mount(this.$nextYears); } diff --git a/src/components/Calendar/components/DateSelectorComposer/index.js b/src/components/Calendar/components/DateSelectorComposer/index.js index 2e5d982d..210632d9 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/index.js @@ -50,7 +50,7 @@ export default function DateSelectorComposer(month, year) { }; this.mountYearSelector(); - this.mountMonthSelector(); + // this.mountMonthSelector(); window.addEventListener('click', (event) => this.modalControl.CloseOnClickOutside(event), diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js index 2d5481d2..015f5c83 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js @@ -10,9 +10,9 @@ export function monthArrayGenerator(month) { } export function yearArrayGenerator(year) { - const yearArray = new Array(7); + const yearArray = new Array(101); for (let i = 0; i < yearArray.length; i += 1) { - yearArray[i] = year - (3 - i); + yearArray[i] = year - (50 - i); } return yearArray; } From a91d5fe4e763645030eabc7a1ddc448a493882d3 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 31 Jul 2024 17:56:31 -0300 Subject: [PATCH 17/20] chore: complete virtual scroll --- .../components/SelectorModal/index.js | 124 +++++++++--------- .../components/SelectorModal/index.scss | 7 +- 2 files changed, 62 insertions(+), 69 deletions(-) diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index 10a12a07..bf0eacd4 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -1,5 +1,4 @@ import { Component } from 'pet-dex-utilities'; -import { MONTHS } from '../../../../utils/months'; import ModalItem from './components/ModalItem'; import './index.scss'; @@ -7,7 +6,14 @@ import './index.scss'; const events = ['month:change', 'year:change']; const html = ` -
                        +
                        +
                        +
                        +
                          +
                        +
                        +
                        +
                        `; export default function SelectorModal(dateArray) { @@ -15,80 +21,70 @@ export default function SelectorModal(dateArray) { this.dateArray = dateArray; this.$selectorModal = this.selected.get('selector-modal'); - this.isYear = typeof dateArray[0] === 'number'; - this.itemsPerPage = 25; - this.currentPage = 0; + this.$modalList = this.selected.get('modal-list'); + this.$listContent = this.selected.get('list-content'); - this.renderItens(); - - this.$selectorModal.addEventListener('scroll', this.handleScroll.bind(this)); + this.itemCount = this.dateArray.length; + this.rowHeight = 33.99; + this.nodePadding = 10; + this.scrollTop = this.$selectorModal.scrollTop; setTimeout(() => { - this.$selectorModal.scrollTop = this.$selectorModal.scrollHeight / 2.1121; - }, 0); -} + this.viewportHeight = this.$selectorModal.offsetHeight; -SelectorModal.prototype = Object.assign( - SelectorModal.prototype, - Component.prototype, - { - renderItens() { - const start = this.currentPage * this.itemsPerPage; - const end = Math.min(start + this.itemsPerPage, this.dateArray.length); - - for (let i = start; i < end; i += 1) { - const modalItem = new ModalItem(this.dateArray[i]); - modalItem.mount(this.$selectorModal); - } + const renderWindow = () => { + this.totalContentHeight = this.itemCount * this.rowHeight; - this.currentPage += 1; - this.items = this.$selectorModal.children; - }, - - handleScroll() { - const { scrollTop, scrollHeight, clientHeight } = this.$selectorModal; - if ( - scrollTop + clientHeight >= scrollHeight && - this.currentPage * this.itemsPerPage < this.dateArray.length - ) - this.renderItens(); - }, - - changeMonth(month) { - for (let i = 0; i < this.dateArray.length; i += 1) { - const index = (month - (2 - i) + 12) % 12; - this.dateArray[i] = MONTHS[index]; - } + this.startNode = + Math.floor(this.scrollTop / this.rowHeight) - this.nodePadding; + this.startNode = Math.max(0, this.startNode); - this.dateArray.forEach((item, index) => { - this.items[index].innerText = item; - }); + this.visibleNodesCount = + Math.ceil(this.viewportHeight / this.rowHeight) + 2 * this.nodePadding; + this.visibleNodesCount = Math.min( + this.itemCount - this.startNode, + this.visibleNodesCount, + ); - this.items[2].scrollIntoView({ - behavior: 'instant', - block: 'center', - inline: 'center', - }); + this.offsetY = this.startNode * this.rowHeight; - this.emit('month:change', month); - }, + this.$modalList.style.height = `${this.totalContentHeight}px`; + this.$listContent.style.transform = `translateY(${this.offsetY}px)`; - changeYear(year) { - for (let i = 0; i < this.dateArray.length; i += 1) { - this.dateArray[i] = year - (2 - i); - } + this.$listContent.innerHTML = ''; + this.visibleChildren = new Array(this.visibleNodesCount) + .fill(null) + .map( + (_, index) => new ModalItem(this.dateArray[index + this.startNode]), + ); - this.dateArray.forEach((item, index) => { - this.items[index].innerText = item; + this.visibleChildren.forEach((modalItem) => { + modalItem.mount(this.$listContent); }); + }; - this.items[2].scrollIntoView({ - behavior: 'instant', - block: 'center', - inline: 'center', + this.$selectorModal.addEventListener('scroll', (e) => { + if (this.animationFrame) { + cancelAnimationFrame(this.animationFrame); + } + this.animationFrame = requestAnimationFrame(() => { + this.scrollTop = e.target.scrollTop; + renderWindow(); }); + }); + + const scrollToMiddle = () => { + this.scrollTop = this.totalContentHeight / 2 - this.viewportHeight / 2; + this.$selectorModal.scrollTop = this.scrollTop; + }; - this.emit('year:change', year); - }, - }, + renderWindow(); + scrollToMiddle(); + }, 0); +} + +SelectorModal.prototype = Object.assign( + SelectorModal.prototype, + Component.prototype, + {}, ); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss index 66826f80..4f2cc17e 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss @@ -5,21 +5,18 @@ .selector-modal { width: 100%; - height: 20rem; + height: 17rem; overflow: auto; display: none; flex-direction: column; - gap: 0.6rem; - padding: 1rem 0; + box-sizing: border-box; position: absolute; top: 4.6rem; z-index: 2; - list-style: none; - background-color: colors.$secondary100; box-shadow: 0 4px 20px -2px rgba(50, 50, 71, 0.04); From aef3db5629cc02a87ea9911f5b7565cd98ef0c86 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Thu, 1 Aug 2024 09:43:57 -0300 Subject: [PATCH 18/20] fix: month selector array --- .../Calendar/components/DateSelectorComposer/index.js | 2 +- .../components/DateSelectorComposer/utils/arraysGenerators.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Calendar/components/DateSelectorComposer/index.js b/src/components/Calendar/components/DateSelectorComposer/index.js index 210632d9..2e5d982d 100644 --- a/src/components/Calendar/components/DateSelectorComposer/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/index.js @@ -50,7 +50,7 @@ export default function DateSelectorComposer(month, year) { }; this.mountYearSelector(); - // this.mountMonthSelector(); + this.mountMonthSelector(); window.addEventListener('click', (event) => this.modalControl.CloseOnClickOutside(event), diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js index 015f5c83..cb47a1a4 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js @@ -1,7 +1,7 @@ import { MONTHS } from '../../../utils/months'; export function monthArrayGenerator(month) { - const monthArray = new Array(7); + const monthArray = new Array(103); for (let i = 0; i < monthArray.length; i += 1) { const monthIndex = (month - (3 - i) + 12) % 12; monthArray[i] = MONTHS[monthIndex]; From 7e6ec386f28a99928d3c700b695a440c73f57bc7 Mon Sep 17 00:00:00 2001 From: DominMFD Date: Fri, 16 Aug 2024 08:56:12 -0300 Subject: [PATCH 19/20] chore: trying make central scroll --- .../components/SelectorModal/index.js | 10 +++++++--- .../DateSelectorComposer/utils/arraysGenerators.js | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index bf0eacd4..130c2711 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -25,8 +25,8 @@ export default function SelectorModal(dateArray) { this.$listContent = this.selected.get('list-content'); this.itemCount = this.dateArray.length; - this.rowHeight = 33.99; - this.nodePadding = 10; + this.rowHeight = 42.8; + this.nodePadding = 5; this.scrollTop = this.$selectorModal.scrollTop; setTimeout(() => { @@ -58,8 +58,10 @@ export default function SelectorModal(dateArray) { (_, index) => new ModalItem(this.dateArray[index + this.startNode]), ); - this.visibleChildren.forEach((modalItem) => { + this.visibleChildren.forEach((modalItem, index) => { modalItem.mount(this.$listContent); + + if (index === 8) modalItem.active(); }); }; @@ -68,6 +70,8 @@ export default function SelectorModal(dateArray) { cancelAnimationFrame(this.animationFrame); } this.animationFrame = requestAnimationFrame(() => { + const nearestIndex = Math.round(this.scrollTop / this.rowHeight); + this.scrollTop = nearestIndex * this.rowHeight; this.scrollTop = e.target.scrollTop; renderWindow(); }); diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js index cb47a1a4..3fd737fd 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js @@ -10,7 +10,7 @@ export function monthArrayGenerator(month) { } export function yearArrayGenerator(year) { - const yearArray = new Array(101); + const yearArray = new Array(103); for (let i = 0; i < yearArray.length; i += 1) { yearArray[i] = year - (50 - i); } From 72d384f23c7236a81858eb58b25e0cc658484d2d Mon Sep 17 00:00:00 2001 From: DominMFD Date: Wed, 21 Aug 2024 08:16:17 -0300 Subject: [PATCH 20/20] fix: align active item in center --- .../components/ModalItem/index.js | 3 ++- .../components/SelectorModal/index.js | 19 ++++++++++++------- .../components/SelectorModal/index.scss | 2 +- .../utils/ModalController.js | 4 ++-- .../utils/arraysGenerators.js | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js index 9dd2fb07..2b0df598 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/components/ModalItem/index.js @@ -1,7 +1,7 @@ import { Component } from 'pet-dex-utilities'; import './index.scss'; -const events = []; +const events = ['item:change']; const html = `
                      • @@ -18,5 +18,6 @@ export default function ModalItem(item) { ModalItem.prototype = Object.assign(ModalItem.prototype, Component.prototype, { active() { this.$modalItem.classList.add('selector-modal__item--active'); + this.emit('item:change', this.item); }, }); diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js index 130c2711..2f98acfd 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.js @@ -3,7 +3,7 @@ import ModalItem from './components/ModalItem'; import './index.scss'; -const events = ['month:change', 'year:change']; +const events = ['date:change']; const html = `
                        @@ -25,7 +25,7 @@ export default function SelectorModal(dateArray) { this.$listContent = this.selected.get('list-content'); this.itemCount = this.dateArray.length; - this.rowHeight = 42.8; + this.rowHeight = 40; this.nodePadding = 5; this.scrollTop = this.$selectorModal.scrollTop; @@ -60,25 +60,30 @@ export default function SelectorModal(dateArray) { this.visibleChildren.forEach((modalItem, index) => { modalItem.mount(this.$listContent); + modalItem.listen('item:change', (item) => + this.emit('date:change', item), + ); - if (index === 8) modalItem.active(); + if (index === 8) { + modalItem.active(); + } }); }; - this.$selectorModal.addEventListener('scroll', (e) => { if (this.animationFrame) { cancelAnimationFrame(this.animationFrame); } this.animationFrame = requestAnimationFrame(() => { - const nearestIndex = Math.round(this.scrollTop / this.rowHeight); - this.scrollTop = nearestIndex * this.rowHeight; this.scrollTop = e.target.scrollTop; renderWindow(); }); }); + this.$listContent.scrollIntoView(true); + const scrollToMiddle = () => { - this.scrollTop = this.totalContentHeight / 2 - this.viewportHeight / 2; + this.scrollTop = + this.totalContentHeight / 2 - this.viewportHeight / 2 - 48; this.$selectorModal.scrollTop = this.scrollTop; }; diff --git a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss index 4f2cc17e..7c1bcb3f 100644 --- a/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss +++ b/src/components/Calendar/components/DateSelectorComposer/components/SelectorModal/index.scss @@ -5,7 +5,7 @@ .selector-modal { width: 100%; - height: 17rem; + height: 18rem; overflow: auto; display: none; diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js index 1f1fb75b..2fd318d2 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/ModalController.js @@ -10,8 +10,8 @@ export class ModalController { this.modal = new SelectorModal(dateArray); this.modal.mount(this.selector.$dateSelector); - this.modal.listen('month:change', (month) => this.selector.setMonth(month)); - this.modal.listen('year:change', (year) => this.selector.setYear(year)); + // this.modal.listen('month:change', (month) => this.selector.setMonth(month)); + this.modal.listen('date:change', (item) => this.selector.setYear(item)); } CloseOnClickOutside(event) { diff --git a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js index 3fd737fd..cb47a1a4 100644 --- a/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js +++ b/src/components/Calendar/components/DateSelectorComposer/utils/arraysGenerators.js @@ -10,7 +10,7 @@ export function monthArrayGenerator(month) { } export function yearArrayGenerator(year) { - const yearArray = new Array(103); + const yearArray = new Array(101); for (let i = 0; i < yearArray.length; i += 1) { yearArray[i] = year - (50 - i); }