Migrate calendar to ES6

old
Javi Velasco 2015-09-07 01:41:59 +02:00
parent 489b996653
commit a5586f4b7d
7 changed files with 207 additions and 149 deletions

View File

@ -1,29 +0,0 @@
css = require './style'
time = require '../utils/time'
module.exports = React.createClass
displayName: 'Day',
propTypes:
day : React.PropTypes.number
onClick : React.PropTypes.func
selectedDate : React.PropTypes.object
viewDate : React.PropTypes.object
_dayStyle: ->
marginLeft: "#{time.getFirstWeekDay(@props.viewDate) * 100/7}%"
_isSelected: () ->
isSameYear = @props.viewDate.getFullYear() == @props.selectedDate.getFullYear()
isSameMonth = @props.viewDate.getMonth() == @props.selectedDate.getMonth()
isSameDay = @props.day == @props.selectedDate.getDate()
isSameYear && isSameMonth && isSameDay
render: ->
className = " #{css.day}"
className += " active" if @_isSelected()
dayStyle = @_dayStyle() if @props.day == 1
<div className={className} style={dayStyle}>
<span onClick={@props.onClick}>{ @props.day }</span>
</div>

View File

@ -0,0 +1,39 @@
const React = window.React;
const css = require('./style');
const time = require('../utils/time');
module.exports = React.createClass({
displayName: 'Day',
propTypes: {
day: React.PropTypes.number,
onClick: React.PropTypes.func,
selectedDate: React.PropTypes.object,
viewDate: React.PropTypes.object
},
_dayStyle () {
if (this.props.day === 1) {
return {
marginLeft: `${time.getFirstWeekDay(this.props.viewDate) * 100 / 7}%`
};
}
},
_isSelected () {
const sameYear = this.props.viewDate.getFullYear() === this.props.selectedDate.getFullYear();
const sameMonth = this.props.viewDate.getMonth() === this.props.selectedDate.getMonth();
const sameDay = this.props.day === this.props.selectedDate.getDate();
return sameYear && sameMonth && sameDay;
},
render () {
return (
<div
className={this._isSelected() ? `${css.day} active` : css.day}
style={this._dayStyle()}>
<span onClick={this.props.onClick}>{this.props.day}</span>
</div>
);
}
});

View File

@ -1,91 +0,0 @@
CTG = React.addons.CSSTransitionGroup
css = require './style'
time = require '../utils/time'
FontIcon = require '../font_icon'
Month = require './month'
module.exports = React.createClass
displayName: 'Calendar',
# -- States & Properties
propTypes:
display : React.PropTypes.oneOf(['months', 'years'])
onChange : React.PropTypes.func
selectedDate : React.PropTypes.object
viewDate : React.PropTypes.object
getDefaultProps: ->
display : 'months'
selectedDate : new Date()
getInitialState: ->
selectedDate : @props.selectedDate
viewDate : @props.selectedDate
# -- Lifecycle
componentDidUpdate: (prevProps, prevState) ->
@_scrollToActive() if @refs.activeYear
if prevState.selectedDate.getTime() != @state.selectedDate.getTime() && @props.onChange
@props.onChange? @
# -- Events
onDayClick: (event) ->
@setState
selectedDate: time.setDay(@state.viewDate, parseInt(event.target.textContent))
onYearClick: (event) ->
newDate = time.setYear(@state.selectedDate, parseInt(event.target.textContent))
@setState
selectedDate: newDate
viewDate: newDate
# -- Private methods
_scrollToActive: ->
@refs.years.getDOMNode().scrollTop =
@refs.activeYear.getDOMNode().offsetTop -
@refs.years.getDOMNode().offsetHeight/2 +
@refs.activeYear.getDOMNode().offsetHeight/2
# -- Public methods
getValue: ->
@state.selectedDate
incrementViewMonth: ->
@setState
direction: 'right'
viewDate: time.addMonths(@state.viewDate, 1)
decrementViewMonth: ->
@setState
direction: 'left'
viewDate: time.addMonths(@state.viewDate, -1)
# -- Render
renderYear: (year) ->
props =
className : if year == @state.viewDate.getFullYear() then 'active' else ''
key : "year-#{year}"
onClick : @onYearClick
props.ref = 'activeYear' if year == @state.viewDate.getFullYear()
return <li {...props}>{ year }</li>
render: ->
<div className={css.root}>
{ if @props.display == 'months'
<div className={@state.direction}>
<FontIcon className={css.prev} value='chevron_left' onClick={@decrementViewMonth} />
<FontIcon className={css.next} value='chevron_right' onClick={@incrementViewMonth} />
<CTG transitionName='slide-horizontal'>
<Month
key={@state.viewDate.getMonth()}
viewDate={@state.viewDate}
selectedDate={@state.selectedDate}
onDayClick={@onDayClick} />
</CTG>
</div>
else if @props.display == 'years'
<ul ref="years" className={css.years}>
{ @renderYear(i) for i in [1900..2100] }
</ul>
}
</div>

View File

@ -0,0 +1,118 @@
const React = window.React;
const css = require('./style');
const utils = require('../utils');
const FontIcon = require('../font_icon');
const Month = require('./month');
const CTG = React.addons.CSSTransitionGroup;
module.exports = React.createClass({
displayName: 'Calendar',
propTypes: {
display: React.PropTypes.oneOf(['months', 'years']),
onChange: React.PropTypes.func,
selectedDate: React.PropTypes.object,
viewDate: React.PropTypes.object
},
getDefaultProps () {
return {
display: 'months',
selectedDate: new Date()
};
},
getInitialState () {
return {
selectedDate: this.props.selectedDate,
viewDate: this.props.selectedDate
};
},
componentDidUpdate (props, state) {
if (this.refs.activeYear) this._scrollToActive();
if (state.selectedDate.getTime() !== this.state.selectedDate.getTime() && this.props.onChange) {
this.props.onChange(this.state.selectedDate);
}
},
onDayClick (event) {
this.setState({
selectedDate: utils.time.setDay(this.state.viewDate, parseInt(event.target.textContent))
});
},
onYearClick (event) {
const date = utils.time.setYear(this.state.selectedDate, parseInt(event.target.textContent));
this.setState({selectedDate: date, viewDate: date});
},
_scrollToActive () {
this.refs.years.getDOMNode().scrollTop =
this.refs.activeYear.getDOMNode().offsetTop -
this.refs.years.getDOMNode().offsetHeight / 2 +
this.refs.activeYear.getDOMNode().offsetHeight / 2;
},
incrementViewMonth () {
this.setState({
direction: 'right',
viewDate: utils.time.addMonths(this.state.viewDate, 1)
});
},
decrementViewMonth () {
this.setState({
direction: 'left',
viewDate: utils.time.addMonths(this.state.viewDate, -1)
});
},
renderYear (year) {
let props = {
className: year === this.state.viewDate.getFullYear() ? 'active' : '',
key: `year-${year}`,
onClick: this.onYearClick
};
if (year === this.state.viewDate.getFullYear()) {
props.ref = 'activeYear';
}
return (<li {...props}>{ year }</li>);
},
renderYears () {
return (
<ul ref="years" className={css.years}>
{ utils.range(1900, 2100).map(i => { return this.renderYear(i); })}
</ul>
);
},
renderMonths () {
return (
<div className={this.state.direction}>
<FontIcon className={css.prev} value='chevron_left' onClick={this.decrementViewMonth}/>
<FontIcon className={css.next} value='chevron_right' onClick={this.incrementViewMonth}/>
<CTG transitionName='slide-horizontal'>
<Month
key={this.state.viewDate.getMonth()}
viewDate={this.state.viewDate}
selectedDate={this.state.selectedDate}
onDayClick={this.onDayClick} />
</CTG>
</div>
);
},
render () {
return (
<div className={css.root}>
{ this.props.display === 'months' ? this.renderMonths() : this.renderYears() }
</div>
);
}
});

View File

@ -1,29 +0,0 @@
css = require './style'
Day = require './day'
time = require '../utils/time'
module.exports = React.createClass
displayName: 'Month',
propTypes:
onDayClick : React.PropTypes.func
selectedDate : React.PropTypes.object
viewDate : React.PropTypes.object
render: ->
<div>
<span className={css.title}>
{ time.getFullMonth(@props.viewDate)} {@props.viewDate.getFullYear() }
</span>
<div className={css.week}>
{ <span key={"dw#{i}"}>{ time.getFullDayOfWeek(i).charAt(0) }</span> for i in [0..6] }
</div>
<div className={css.days}>
{ for i in [1..time.getDaysInMonth(@props.viewDate)]
<Day key={"d#{i}"}
day={i}
onClick={@props.onDayClick}
selectedDate={@props.selectedDate}
viewDate={@props.viewDate} /> }
</div>
</div>

View File

@ -0,0 +1,49 @@
const React = window.React;
const css = require('./style');
const utils = require('../utils');
const Day = require('./day');
module.exports = React.createClass({
displayName: 'Month',
propTypes: {
onDayClick: React.PropTypes.func,
selectedDate: React.PropTypes.object,
viewDate: React.PropTypes.object
},
renderWeeks () {
return utils.range(0, 7).map(i => {
return (
<span key={`dw${i}`}>
{ utils.time.getFullDayOfWeek(i).charAt(0) }
</span>
);
});
},
renderDays () {
return utils.range(1, utils.time.getDaysInMonth(this.props.viewDate) + 1).map(i => {
return (
<Day key={`d${i}`}
day={i}
onClick={this.props.onDayClick}
selectedDate={this.props.selectedDate}
viewDate={this.props.viewDate} />
);
});
},
render () {
return (
<div>
<span className={css.title}>
{ utils.time.getFullMonth(this.props.viewDate)} {this.props.viewDate.getFullYear() }
</span>
<div className={css.week}>{ this.renderWeeks() }</div>
<div className={css.days}>{ this.renderDays() }</div>
</div>
);
}
});

View File

@ -24,5 +24,6 @@ module.exports = {
events: require('./events'),
prefixer: require('./prefixer'),
time: require('./time'),
testing: require('./testing')
};