Skip to content

Commit

Permalink
WIP: improving datepicker code and style
Browse files Browse the repository at this point in the history
feature/150167-datepicker
  • Loading branch information
liviaalmeida committed Nov 14, 2019
1 parent c79da86 commit 521c83a
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 45 deletions.
49 changes: 23 additions & 26 deletions src/components/blipDatepicker/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Component from 'nanocomponent'
import html from 'nanohtml'
import raw from 'nanohtml/raw'
import { DateHelper } from './DateHelper'
import { createHTMLElement } from './../../lib/utils'
import { DateHelper } from './../shared'
import { createHTMLElement, eventPathFindElementByTag } from './../../lib/utils'

import ArrowLeft from '../../img/arrow-ball-left-solid.svg'
import ArrowRight from '../../img/arrow-ball-right-solid.svg'
Expand Down Expand Up @@ -59,15 +59,18 @@ export class BlipDatepicker extends Component {
constructor(options) {
super()

options = options || {}

this.name = options.name
this.hasTime = options.hasTime || false

this.i18n = options.i18n || BlipDatepicker.i18nEN

this._selectedDay = options.selectedDay
this._selectedPeriod = options.selectedPeriod
this._validPeriod = options.validPeriod

this._onMonthButtonClick = options.onMonthButtonClick || this._onMonthButtonClick
this.onTimeChange = options.onTimeChange
this.onDateSelectorShow = options.onDateSelectorShow
this.onDateSelectorHide = options.onDateSelectorHide
this.onDayHovering = options.onDayHovering
Expand Down Expand Up @@ -110,13 +113,14 @@ export class BlipDatepicker extends Component {
set monthDate(newDate) {
this._monthDate = new Date(newDate)
this._renderMonth()
this._renderTime()
if (this.hasTime) {
this._renderTime()
}
}

set selectedDay(newDate) {
this._selectedDay = new Date(newDate)
this._selectedPeriod = undefined
this._clearSelection()
this._renderSelection(newDate)
}

Expand Down Expand Up @@ -216,6 +220,7 @@ export class BlipDatepicker extends Component {
this._yearInput = yearInput
this._prevButton = prevButton
this._nextButton = nextButton
this._tableHead = tableHead
this._tableBody = tableBody
this._daysRows = daysRows
this._monthDays = monthDays
Expand Down Expand Up @@ -344,25 +349,24 @@ export class BlipDatepicker extends Component {
this._monthDays.forEach(
dayCell => {
if (this._isValidDay(dayCell)) {
dayCell.classList.remove(BlipDatepicker.style.rangeLimit)
dayCell.classList.remove(BlipDatepicker.style.inRange)

const dayDate = new Date(Number(dayCell.getAttribute('time')))

if (this._selectedPeriod) {
if (DateHelper.isEqual(this._selectedPeriod.startDate, dayDate) || DateHelper.isEqual(this._selectedPeriod.endDate, dayDate)) {
if (DateHelper.isSameDay(this._selectedPeriod.startDate, dayDate) || DateHelper.isSameDay(this._selectedPeriod.endDate, dayDate)) {
dayCell.classList.add(BlipDatepicker.style.rangeLimit)
}
if (DateHelper.isBetween(this._selectedPeriod.startDate, this._selectedPeriod.endDate, dayDate)) {
dayCell.classList.add(BlipDatepicker.style.inRange)
} else {
dayCell.classList.remove(BlipDatepicker.style.inRange)
}
} else if (this._selectedDay && hoverDate) {
if (DateHelper.isEqual(this._selectedDay, dayDate)) {
if (DateHelper.isSameDay(this._selectedDay, dayDate)) {
dayCell.classList.add(BlipDatepicker.style.rangeLimit)
}
if (DateHelper.isBetween(this._selectedDay, hoverDate, dayDate)) {
dayCell.classList.add(BlipDatepicker.style.inRange)
} else {
dayCell.classList.remove(BlipDatepicker.style.inRange)
}
}
}
Expand All @@ -389,10 +393,9 @@ export class BlipDatepicker extends Component {

_renderDateSelector(options, selected = undefined) {
const addPxToValue = value => `${value}px`
const { top, left } = this._tableBody.getBoundingClientRect()
const { height: theadHeight } = this._tableHead.getBoundingClientRect()

this._dateSelector.style.top = addPxToValue(top)
this._dateSelector.style.left = addPxToValue(left)
this._dateSelector.style.top = addPxToValue(theadHeight)
this._dateSelector.style.height = addPxToValue(this._tableBody.offsetHeight)
this._dateSelector.style.width = addPxToValue(this._tableBody.offsetWidth)

Expand Down Expand Up @@ -435,14 +438,6 @@ export class BlipDatepicker extends Component {
if (this.onDateSelectorShow) this.onDateSelectorShow()
}

_clearSelection() {
this._monthDays.forEach(
dayCell => {
dayCell.classList.remove(BlipDatepicker.style.rangeLimit)
dayCell.classList.remove(BlipDatepicker.style.inRange)
})
}

_clearDateSelector() {
if (this.pickMonth) {
this.showPrev = true
Expand Down Expand Up @@ -529,7 +524,7 @@ export class BlipDatepicker extends Component {
}

_onMonthButtonClick = event => {
const button = event.composedPath().find(el => el.tagName === 'BUTTON')
const button = eventPathFindElementByTag(event, 'BUTTON')
const offset = Number(button.value)
this.monthDate = DateHelper.moveMonth(this.monthDate, offset)
}
Expand Down Expand Up @@ -557,7 +552,7 @@ export class BlipDatepicker extends Component {
}

_onYearRangeClick = event => {
const button = event.composedPath().find(el => el.tagName === 'BUTTON')
const button = eventPathFindElementByTag(event, 'BUTTON')
const optionsSize = this.i18n.months.length
const offset = Number(button.value) * optionsSize
const baseYear = Number(this._selectorInputs[0].value)
Expand All @@ -582,7 +577,7 @@ export class BlipDatepicker extends Component {
}

_onDayHover = event => {
const currentCell = event.composedPath().find(el => el.tagName === 'TD')
const currentCell = eventPathFindElementByTag(event, 'TD')

if (this._selectedDay && this._isValidDay(currentCell)) {
const cellDate = new Date(Number(currentCell.getAttribute('time')))
Expand All @@ -593,7 +588,7 @@ export class BlipDatepicker extends Component {
}

_onDayClick = event => {
const dayCell = event.composedPath().find(el => el.tagName === 'TD')
const dayCell = eventPathFindElementByTag(event, 'TD')

if (this._isValidDay(dayCell)) {
const dayDate = new Date(Number(dayCell.getAttribute('time')))
Expand All @@ -611,6 +606,8 @@ export class BlipDatepicker extends Component {
_onTimeInputChange = event => {
const [hour, minute] = event.target.value.split(':')
this._monthDate.setHours(hour, minute)

if (this.onTimeChange) this.onTimeChange()
}

_onTimeInputKeyup = event => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export class DateHelper {
return date1.getTime() === date2.getTime()
}

static isSameDay(date1, date2) {
return (date1.getFullYear() === date2.getFullYear()) &&
(date1.getMonth() === date2.getMonth()) &&
(date1.getDate() === date2.getDate())
}

static isBetween(dateLimit1, dateLimit2, compareDate) {
return (compareDate <= dateLimit1 && compareDate >= dateLimit2) ||
(compareDate >= dateLimit1 && compareDate <= dateLimit2)
Expand Down
8 changes: 8 additions & 0 deletions src/components/shared/Period.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export class Period {
constructor(date1, date2) {
const smaller = date1 < date2 ? date1 : date2
const bigger = date1 < date2 ? date2 : date1
this.startDate = new Date(smaller)
this.endDate = new Date(bigger)
}
}
4 changes: 3 additions & 1 deletion src/components/shared/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export { renderEmptyOption } from './EmptyOption'
export { compose } from './Compose'
export { DateHelper } from './DateHelper'
export { OptionItem } from './OptionItem'
export { Period } from './Period'
export { renderEmptyOption } from './EmptyOption'
16 changes: 16 additions & 0 deletions src/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,19 @@ export const createHTMLElement = (elementTag, ...classes) => {
}
return element
}

/**
* Find element with given tag in Event path
* @param {String} event
* @param {Array} elementTagName
*/
export const eventPathFindElementByTag = (event, elementTagName) => {
let node = event.target
while (node.parentNode !== document) {
if (node.tagName === elementTagName) {
return node
} else {
node = node.parentNode
}
}
}
43 changes: 25 additions & 18 deletions src/scss/components/_datepicker.scss
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
$icon-size: 1.7*$m;
$side-margin: 0 $u;

.blip-datepicker {
display: inline-block;

input {
border: none;
cursor: pointer;
.bp-datepicker input, .bp-daterange-picker input {
border: none;
cursor: pointer;
background-color: transparent;

&::-webkit-clear-button, &::-webkit-inner-spin-button {
display: none;
-webkit-appearance: none;
}
&::-webkit-clear-button, &::-webkit-inner-spin-button {
display: none;
-webkit-appearance: none;
}

&:focus {
outline: none;
}
&:focus {
outline: none;
}

&:disabled {
cursor: default;
background-color: transparent;
}
&:disabled {
cursor: default;
}
}

.bp-datepicker {
display: inline-block;
position: relative;

.month-table {
border-collapse: collapse;
margin: $side-margin;

th {
border-bottom: $u solid $bp-color-white;
Expand All @@ -43,6 +46,7 @@ $icon-size: 1.7*$m;
.year-input {
font-weight: 600;
max-width: 3*$m;
max-height: 1.2*$m;
margin-left: $m;

&:focus {
Expand Down Expand Up @@ -71,6 +75,7 @@ $icon-size: 1.7*$m;

.weekday-week {
border-top: 1.5*$m solid $bp-color-white;
text-transform: uppercase;
}

.month-week, .next-month-week {
Expand Down Expand Up @@ -102,7 +107,7 @@ $icon-size: 1.7*$m;
color: $bp-color-time;
}

&.in-range {
&.in-range, &.range-limit {
background-color: $bp-color-sky;
}

Expand Down Expand Up @@ -143,6 +148,7 @@ $icon-size: 1.7*$m;
background-color: $bp-color-whisper;
padding: $u 0;
border-radius: 8px;
margin: $side-margin;

.time-input-container {
display: flex;
Expand Down Expand Up @@ -182,6 +188,7 @@ $icon-size: 1.7*$m;
display: flex;
flex-direction: column;
justify-content: space-between;
margin: $side-margin;

> div {
display: flex;
Expand Down

0 comments on commit 521c83a

Please sign in to comment.