Migrate calendar to ES6
parent
489b996653
commit
a5586f4b7d
|
@ -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>
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -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>
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -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>
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -24,5 +24,6 @@ module.exports = {
|
|||
|
||||
events: require('./events'),
|
||||
prefixer: require('./prefixer'),
|
||||
time: require('./time'),
|
||||
testing: require('./testing')
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue