Skip to content

Commit

Permalink
Merge pull request #5 from harel/momentjs
Browse files Browse the repository at this point in the history
Decoupling of dates handling into Date handlers
  • Loading branch information
harel authored May 18, 2017
2 parents f4d8fcb + 3167d58 commit 0282145
Show file tree
Hide file tree
Showing 14 changed files with 781 additions and 157 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { Datetime } from 'semantic-ui-react'
import {Datetime} from 'semantic-ui-react'

const DateRangeExample = () => (
<Datetime.Range
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react'
import { Datetime } from 'semantic-ui-react'

const DateTimeExampleDateOnly = () => (
<Datetime time={false} placeholder='Select Date' />
<Datetime
time={false}
placeholder='Select Date' />
)

export default DateTimeExampleDateOnly
13 changes: 13 additions & 0 deletions docs/app/Examples/modules/Datetime/Types/DateTimeExampleMoment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import { Datetime } from 'semantic-ui-react'
import moment from 'moment-timezone';
import 'moment/locale/en-gb';

const DateTimeExampleMoment = () => (
<Datetime
time
dateHandler='moment'
defaultValue={moment.tz('2017-04-24T12:35', 'Europe/London')} />
)

export default DateTimeExampleMoment
5 changes: 5 additions & 0 deletions docs/app/Examples/modules/Datetime/Types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ const DatetimeTypesExamples = () => (
description='A full Date and Time selector, with initial value of the current date and time'
examplePath='modules/Datetime/Types/DateTimeExampleFull'
/>
<ComponentExample
title='Date and Time using Moment-Timezone dates'
description=''
examplePath='modules/Datetime/Types/DateTimeExampleMoment'
/>
<ComponentExample
title='Date'
description='A date only Date selector'
Expand Down
2 changes: 1 addition & 1 deletion src/lib/customPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ export const DateValue = (props, propName, componentName) => {
return new Date(value) != 'Invalid Date' && !isNaN(new Date(value)) ? null :
new Error(propName + ' in ' + componentName + ' cannot be parsed as a date')
} else if (typeof value === 'object') {
return value.getDate != undefined ? null :
return value.getDate != undefined || value._isAMomentObject != undefined ? null :
new Error(propName + ' in ' + componentName + ' is not a Date or a string parsable date')
}
}
Expand Down
154 changes: 76 additions & 78 deletions src/modules/Datetime/Calendar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { PropTypes } from 'react'
import React, { PropTypes, Component } from 'react'
import CalendarMenu from './CalendarMenu'
import Month from './Month'
import Months from './Months'
Expand All @@ -7,7 +7,7 @@ import Hours from './Hours'
import Minutes from './Minutes'

import {
AutoControlledComponent as Component,
//AutoControlledComponent as Component,
customPropTypes,
META,
} from '../../lib'
Expand Down Expand Up @@ -83,6 +83,7 @@ export default class Calendar extends Component {

/** Current value as a Date object or a string that can be parsed into one. */
value: customPropTypes.DateValue,
dateHandler: PropTypes.func
}

static defaultProps = {
Expand All @@ -91,117 +92,106 @@ export default class Calendar extends Component {
date: true,
time: true,
range: false,
mode: 'day',
selectionStart: null,
selectionEnd: null
}

static autoControlledProps = [
'value',
'mode',
'selectionStart',
'selectionEnd',
]
// static autoControlledProps = [
// 'value',
// 'mode',
// 'selectionStart',
// 'selectionEnd',
// ]

constructor(props) {
super(props)
this.state = {
value: new Date(),
mode: this.getInitialMode(props),
}
}
const {dateHandler} = props
this.Date = dateHandler
// const initialValue = new this.Date(new Date()).getDate()
// this.state = {
// value: initialValue,
// mode: this.getInitialMode(props),
// }

getInitialMode(props) {
const { date, time } = props
return !date && time ? 'hour' : 'day'
}

getYear = () => this.state.value.getFullYear()
getMonth = () => this.state.value.getMonth()
getHour = () => this.state.value.getHours()
// getInitialMode(props) {
// const { date, time } = props
// return !date && time ? 'hour' : 'day'
// }

getYear = () => new this.Date(this.props.value).year()
getMonth = () => new this.Date(this.props.value).month()
getHour = () => new this.Date(this.props.value).hours()
getDate = () => new this.Date(this.props.value).day()

getMonthName() {
const { content } = this.props
return content.months[this.getMonth()]
}

setMonth = (e, props) => {
console.log("Calendar setMonth()", props)
e.stopPropagation()
const { value, page } = props
const { onDateSelect } = this.props
const nextMode = 'day'
const date = new Date(this.state.value)
const date = new this.Date(this.props.value)
const month = !value && page
? date.getMonth() + page
? date.month() + page
: value

date.setMonth(month)
this.trySetState({
value: date,
mode: nextMode,
})
if (this.props.onChangeMonth) {
this.props.onChangeMonth(date)
}
date.month(month)
onDateSelect(e, date.getDate(), nextMode)
// this.trySetState({
// value: date.getDate(),
// mode: nextMode,
// })
// if (this.props.onChangeMonth) {
// this.props.onChangeMonth(date.day())
// }
}

setYear = (e, year, nextMode = 'day') => {
e.stopPropagation()
const date = new Date(this.state.value)
date.setYear(year)
this.trySetState({
value: date,
mode: nextMode,
})
const {value, onDateSelect} = this.props
const date = new this.Date(value)
date.year(year)
onDateSelect(e, date.getDate(), nextMode)
}

setHour = (e, hour, nextMode = 'minute') => {
e.stopPropagation()
const date = new Date(this.state.value)
date.setHours(hour)
this.trySetState({
value: date,
mode: nextMode,
})
const {value, onDateSelect} = this.props
const date = new this.Date(value)
date.hours(hour)
onDateSelect(e, date.getDate(), nextMode)
}

setMinute = (e, minute) => {
e.stopPropagation()
const { onDateSelect } = this.props
const date = new Date(this.state.value)
date.setMinutes(minute)
const extraState = {}
if (this.props.range) {
extraState.mode = 'day'
}
this.trySetState({
value: date,
...extraState,
})
if (onDateSelect) {
onDateSelect(e, new Date(date))
}
const { onDateSelect, value } = this.props
const date = new this.Date(value)
date.minutes(minute)
const nextMode = this.props.range ? ' day' : null
onDateSelect(e, date.getDate(), nextMode)
}

setDay = (e, day) => {
e.stopPropagation()
const date = new Date(this.state.value)
date.setDate(day)
const { onDateSelect, time } = this.props
const nextMode = time ? 'hour' : this.state.mode
const rangeState = {}
if (this.props.range) {
rangeState.selectionStart = date
}
this.trySetState({
value: date,
mode: nextMode,
...rangeState,
})
if (!time && onDateSelect) {
onDateSelect(e, new Date(date))
}
const { onDateSelect, time, range, value, mode } = this.props
const date = new this.Date(value)
date.day(day)

const selectedDate = date.getDate()
const nextMode = time ? 'hour' : null
onDateSelect(e, selectedDate, nextMode, range ? date : null)
}

page = (direction, e) => {
e.stopPropagation()
const { mode } = this.state
const { mode } = this.props
switch (mode) {
case 'day':
this.setMonth(e, { page: direction })
Expand All @@ -228,20 +218,28 @@ export default class Calendar extends Component {
*/
changeMode = (mode, e) => {
e.stopPropagation()
this.trySetState({ mode })
const {value, onDateSelect} = this.props
onDateSelect(e, value, mode)
}

/**
* Returns the calendar body content
*/
getBodyContent() {
const { content, firstDayOfWeek, disabledDates } = this.props
const { mode, value, selectionStart, selectionEnd } = this.state
const {
content,
firstDayOfWeek,
disabledDates,
mode,
value,
selectionStart,
selectionEnd } = this.props
switch (mode) {
case 'day':
return (
<Month
firstDayOfWeek={firstDayOfWeek}
dateHandler={this.Date}
content={content}
onClick={this.setDay}
date={value}
Expand Down Expand Up @@ -269,13 +267,13 @@ export default class Calendar extends Component {
}

render() {
const { date } = this.props
const { mode, value } = this.state
const { date, mode, value } = this.props
const calendarDay = this.getDate()
return (
<div style={style}>
{date && (
<CalendarMenu
date={value}
value={calendarDay}
monthName={this.getMonthName()}
year={this.getYear()}
mode={mode}
Expand Down
13 changes: 6 additions & 7 deletions src/modules/Datetime/CalendarMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ export default class CalendarMenu extends Component {
/** Year **/
year: PropTypes.number,

// TODO consider using `value` instead
/** Current date **/
date: PropTypes.any,
/** Current day of the month **/
value: PropTypes.number,

/** Current calendar mode **/
mode: PropTypes.oneOf(['minute', 'hour', 'day', 'month', 'year']),
Expand All @@ -42,18 +41,18 @@ export default class CalendarMenu extends Component {
onPrevious: PropTypes.func,

/** Called when paginating to the next month. */
onNext: PropTypes.func,
onNext: PropTypes.func
}

static _meta = {
name: 'CalendarMenu',
parent: 'Datetime',
type: META.TYPES.MODULE,
}

render() {
const {
date,
value,
mode,
monthName,
onChangeMode,
Expand All @@ -75,7 +74,7 @@ export default class CalendarMenu extends Component {
),
_.includes(mode, ['hour', 'minute']) && (
<Menu.Item key='hour-minute' onClick={onChangeMode.bind(null, 'month')}>
{monthName}&nbsp;{date.getDate()}
{monthName}&nbsp;{value}
</Menu.Item>
),
_.includes(mode, ['day', 'month', 'hour', 'minute']) && (
Expand Down
Loading

0 comments on commit 0282145

Please sign in to comment.