diff --git a/.env b/.env new file mode 100644 index 0000000..0c2ce26 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +REACT_APP_TRANSLATIONS_URL=https://client.optios.net/api/translations/export/domain diff --git a/package-lock.json b/package-lock.json index 07c2e9e..a46cfc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33196,4 +33196,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/src/DateTimeRangePicker/DatePicker/DatePicker.scss b/src/DateTimeRangePicker/DatePicker/DatePicker.scss index f2ab0a7..3fdd030 100644 --- a/src/DateTimeRangePicker/DatePicker/DatePicker.scss +++ b/src/DateTimeRangePicker/DatePicker/DatePicker.scss @@ -1,30 +1,42 @@ $color-highlight: #428be3; $color-background-day: rgba(black, .1); $color-other-month: rgba(black, .4); -$color-disabled: rgba(black, .4); +$color-disabled: rgba(16, 16, 16, 0.3); +$color-disabled-background: #e6e6e6; .date-time-range-picker .date-time-range-picker-dates{ position: relative; .date-time-range-picker-header { display: flex; - justify-content: space-between; + justify-content: center; .date-time-range-picker-header-month { - width: 19.3em; line-height: 2em; margin: .3em 0; text-align: center; - + padding: 0 .5em; + { .date-time-range-picker-header-month { margin-left: 1em; } } } + .date-time-range-picker-header-month:hover{ + background-color: $color-highlight; + color: white; + cursor: pointer; + } + .date-time-range-picker-header-month.year{ + background-color: $color-disabled-background; + color: $color-disabled; + pointer: none; + } .date-time-range-picker-header-prev, - .date-time-range-picker-header-next { + .date-time-range-picker-header-next, + .date-time-range-picker-header-prev-year, + .date-time-range-picker-header-next-year{ position: absolute; margin: .3em; border-radius: 2em; @@ -45,6 +57,34 @@ $color-disabled: rgba(black, .4); .date-time-range-picker-header-next { right: 0; } + .date-time-range-picker-header-prev-year { + left: 45px; + font-size: 12px; + margin-top: 10px; + } + + .date-time-range-picker-header-next-year { + right: 45px; + font-size: 12px; + margin-top: 10px; + } + } + + .date-time-range-picker-year-mode { + position: absolute; + width: 100%; + height: 100%; + display: flex; + flex-wrap: wrap; + button.monthButton{ + background-color: white; + flex: 0 0 33.3333%; + overflow: hidden; + } + button.monthButton:hover{ + cursor: pointer; + background-color: $color-disabled-background; + } } .date-time-range-picker-months { diff --git a/src/DateTimeRangePicker/DatePicker/DatePicker.tsx b/src/DateTimeRangePicker/DatePicker/DatePicker.tsx index a140ffc..3f9efb3 100644 --- a/src/DateTimeRangePicker/DatePicker/DatePicker.tsx +++ b/src/DateTimeRangePicker/DatePicker/DatePicker.tsx @@ -1,23 +1,29 @@ -import React from 'react' +import React, {useState} from 'react' import moment, {Moment} from 'moment' import './DatePicker.scss' import IProps from './IProps' import Month from './Month/Month' import Header from './Header/Header' +import {TCalendarMode} from './TCalendarMode' +import {YearView} from './YearView/YearView' const DatePicker: React.FunctionComponent = ( { range = false, fromDate, untilDate, + initialDate, months = 1, onFromDateChanged, onUntilDateChanged } ) => { - const [currentDate, setCurrentDate] = React.useState(fromDate ? fromDate.clone() : moment()) - const [hoverDate, setHoverDate] = React.useState() + const [calendarMode, setCalendarMode] = useState('normal') + const [currentDate, setCurrentDate] = useState(fromDate + ? fromDate.clone() + : initialDate ? initialDate : moment()) + const [hoverDate, setHoverDate] = useState(initialDate || undefined) const monthsArray = [] for (let monthIndex = 0; monthIndex < months; monthIndex++) { @@ -31,6 +37,16 @@ const DatePicker: React.FunctionComponent = ( months={months} onPrevMonth={() => setCurrentDate(currentDate.clone().subtract(1, 'month'))} onNextMonth={() => setCurrentDate(currentDate.clone().add(1, 'month'))} + onPrevYear={() => setCurrentDate(currentDate.clone().subtract(1, 'year'))} + onNextYear={() => setCurrentDate(currentDate.clone().add(1, 'year'))} + calendarMode={calendarMode} + setCalendarMode={setCalendarMode} + /> +
{monthsArray.map( diff --git a/src/DateTimeRangePicker/DatePicker/Header/Header.tsx b/src/DateTimeRangePicker/DatePicker/Header/Header.tsx index b5397c0..78732f0 100644 --- a/src/DateTimeRangePicker/DatePicker/Header/Header.tsx +++ b/src/DateTimeRangePicker/DatePicker/Header/Header.tsx @@ -2,7 +2,16 @@ import React from 'react' import IProps from './IProps' -const Header: React.FunctionComponent = ({date, months, onPrevMonth, onNextMonth}) => { +const Header: React.FunctionComponent = ({ + date, + months, + onPrevMonth, + onNextMonth, + calendarMode, + setCalendarMode, + onPrevYear, + onNextYear +}) => { const monthsArray = [] for (let monthIndex = 0; monthIndex < months; monthIndex++) { monthsArray.push(monthIndex) @@ -10,14 +19,21 @@ const Header: React.FunctionComponent = ({date, months, onPrevMonth, onN return
+ {calendarMode === 'normal' ? null : } {monthsArray.map( (monthIndex: number) => { - return
- {date.clone().add(monthIndex, 'months').format('MMMM YYYY')} + return
setCalendarMode('year')}> + {date.clone().add(monthIndex, 'months').format(calendarMode === 'normal' ? 'MMMM YYYY' : 'YYYY')}
} )} - + { calendarMode === 'normal' + ? null + : }
} diff --git a/src/DateTimeRangePicker/DatePicker/Header/IProps.ts b/src/DateTimeRangePicker/DatePicker/Header/IProps.ts index 0ca36ad..9c89f9f 100644 --- a/src/DateTimeRangePicker/DatePicker/Header/IProps.ts +++ b/src/DateTimeRangePicker/DatePicker/Header/IProps.ts @@ -1,10 +1,15 @@ import moment from 'moment' +import {TCalendarMode} from '../TCalendarMode' interface IProps { date: moment.Moment, months: number, onNextMonth: () => void, onPrevMonth: () => void + onNextYear: () => void + onPrevYear: () => void + calendarMode: TCalendarMode + setCalendarMode: (mode: TCalendarMode) => void } export default IProps diff --git a/src/DateTimeRangePicker/DatePicker/Header/__tests__/Header.test.tsx b/src/DateTimeRangePicker/DatePicker/Header/__tests__/Header.test.tsx index 5a39f4b..5fa604b 100644 --- a/src/DateTimeRangePicker/DatePicker/Header/__tests__/Header.test.tsx +++ b/src/DateTimeRangePicker/DatePicker/Header/__tests__/Header.test.tsx @@ -11,6 +11,10 @@ describe('Date/time range picker header', () => { months={1} onPrevMonth={() => { return }} onNextMonth={() => { return }} + onNextYear={() => { return }} + onPrevYear={() => { return }} + calendarMode={'normal'} + setCalendarMode={() => { return }} /> ) @@ -26,6 +30,10 @@ describe('Date/time range picker header', () => { months={1} onPrevMonth={onPrevMonthHandler} onNextMonth={onNextMonthHandler} + onNextYear={() => { return }} + onPrevYear={() => { return }} + calendarMode={'normal'} + setCalendarMode={() => { return }} /> ) component.find('.date-time-range-picker-header-prev').simulate('click') diff --git a/src/DateTimeRangePicker/DatePicker/Header/__tests__/__snapshots__/Header.test.tsx.snap b/src/DateTimeRangePicker/DatePicker/Header/__tests__/__snapshots__/Header.test.tsx.snap index 8fb7065..456caa4 100644 --- a/src/DateTimeRangePicker/DatePicker/Header/__tests__/__snapshots__/Header.test.tsx.snap +++ b/src/DateTimeRangePicker/DatePicker/Header/__tests__/__snapshots__/Header.test.tsx.snap @@ -12,8 +12,9 @@ exports[`Date/time range picker header should render correctly 1`] = ` «
October 2019
diff --git a/src/DateTimeRangePicker/DatePicker/IProps.ts b/src/DateTimeRangePicker/DatePicker/IProps.ts index 54c5e2d..80dad79 100644 --- a/src/DateTimeRangePicker/DatePicker/IProps.ts +++ b/src/DateTimeRangePicker/DatePicker/IProps.ts @@ -1,9 +1,10 @@ -import moment, {Moment} from 'moment' +import {Moment} from 'moment' interface IProps { range: boolean, - fromDate?: moment.Moment, - untilDate?: moment.Moment, + fromDate?: Moment, + untilDate?: Moment, + initialDate?: Moment months: number, onFromDateChanged: (date: Moment | undefined) => void onUntilDateChanged: (date: Moment | undefined) => void diff --git a/src/DateTimeRangePicker/DatePicker/TCalendarMode.ts b/src/DateTimeRangePicker/DatePicker/TCalendarMode.ts new file mode 100644 index 0000000..23fd943 --- /dev/null +++ b/src/DateTimeRangePicker/DatePicker/TCalendarMode.ts @@ -0,0 +1 @@ +export type TCalendarMode = 'normal' | 'year' diff --git a/src/DateTimeRangePicker/DatePicker/YearView/IProps.ts b/src/DateTimeRangePicker/DatePicker/YearView/IProps.ts new file mode 100644 index 0000000..7fed99c --- /dev/null +++ b/src/DateTimeRangePicker/DatePicker/YearView/IProps.ts @@ -0,0 +1,9 @@ +import {TCalendarMode} from '../TCalendarMode' +import {Moment} from 'moment' + +export interface IProps { + isRender: boolean + currentDate: Moment + setCurrentDate: (date: Moment) => void + setCalendarMode: (mode: TCalendarMode) => void +} diff --git a/src/DateTimeRangePicker/DatePicker/YearView/YearView.tsx b/src/DateTimeRangePicker/DatePicker/YearView/YearView.tsx new file mode 100644 index 0000000..9cb193c --- /dev/null +++ b/src/DateTimeRangePicker/DatePicker/YearView/YearView.tsx @@ -0,0 +1,24 @@ +import React, {FunctionComponent} from 'react' +import {IProps} from './IProps' +import moment from 'moment/moment' + +export const YearView: FunctionComponent = ({isRender, currentDate, setCurrentDate, setCalendarMode}) => { + if (!isRender) { + return null + } + + const setMonth = (monthNumber: number) => { + setCalendarMode('normal') + setCurrentDate(currentDate.set('month', monthNumber)) + } + + return ( +
+ {moment.months().map((month, i) => + )} +
+ ) +} diff --git a/src/DateTimeRangePicker/DateTimeRangePicker.stories.tsx b/src/DateTimeRangePicker/DateTimeRangePicker.stories.tsx index e96c626..4082dd4 100644 --- a/src/DateTimeRangePicker/DateTimeRangePicker.stories.tsx +++ b/src/DateTimeRangePicker/DateTimeRangePicker.stories.tsx @@ -1,12 +1,18 @@ import React from 'react' import DateTimeRangePicker from './DateTimeRangePicker' +import moment from 'moment' export default { title: 'DateTimeRangePicker', component: DateTimeRangePicker } +const someDate = moment('2021/06/15') -export const basic = () => console.log(date, date2)}/> +export const basic = () => console.log(date, date2)} +/> export const dateTime = () => console.log(date, date2)}/> export const range = () => console.log(date, date2)} /> export const rangeWithMultipleMonths = () => { diff --git a/src/DateTimeRangePicker/DateTimeRangePicker.tsx b/src/DateTimeRangePicker/DateTimeRangePicker.tsx index 8677036..a1c463e 100644 --- a/src/DateTimeRangePicker/DateTimeRangePicker.tsx +++ b/src/DateTimeRangePicker/DateTimeRangePicker.tsx @@ -1,5 +1,8 @@ import React, {useEffect, useState} from 'react' import moment, {Moment} from 'moment' +import 'moment/locale/nl' +import 'moment/locale/fr' +import 'moment/locale/de' import './DateTimeRangePicker.scss' import IProps from './IProps' @@ -15,8 +18,10 @@ const DateTimeRangePicker: React.FunctionComponent = ( inline = true, fromDate, untilDate, + initialDate, months = 1, - onChange + onChange, + calendarLocale = 'en' } ) => { const [currentFromDate, setCurrentFromDate] = useState(fromDate ? fromDate.clone() : undefined) @@ -28,6 +33,7 @@ const DateTimeRangePicker: React.FunctionComponent = ( (untilDate ? untilDate.clone() : undefined ) const [isMounted, setIsMounted] = useState(false) + moment.locale(calendarLocale) useEffect( () => { @@ -63,6 +69,7 @@ const DateTimeRangePicker: React.FunctionComponent = ( months={months} fromDate={currentFromDate} untilDate={currentUntilDate} + initialDate={initialDate} onFromDateChanged={ (changedDate: Moment | undefined) => { setCurrentFromDate(changedDate) diff --git a/src/DateTimeRangePicker/IProps.ts b/src/DateTimeRangePicker/IProps.ts index 2dbd86e..1137d2f 100644 --- a/src/DateTimeRangePicker/IProps.ts +++ b/src/DateTimeRangePicker/IProps.ts @@ -1,4 +1,5 @@ import {Moment} from 'moment' +import {TCalendarLocaleSupport} from './TCalendarLocaleSupport' interface IProps { date?: boolean, @@ -7,8 +8,10 @@ interface IProps { inline?: boolean, fromDate?: Moment, untilDate?: Moment, + initialDate?: Moment months?: number, onChange?: (fromDateTime: Moment, untilDateTime?: Moment) => void + calendarLocale?: TCalendarLocaleSupport } export default IProps diff --git a/src/DateTimeRangePicker/TCalendarLocaleSupport.ts b/src/DateTimeRangePicker/TCalendarLocaleSupport.ts new file mode 100644 index 0000000..8ee807f --- /dev/null +++ b/src/DateTimeRangePicker/TCalendarLocaleSupport.ts @@ -0,0 +1 @@ +export type TCalendarLocaleSupport = 'nl' | 'en' | 'de' | 'fr'