2018-03-19 02:16:27 +00:00
|
|
|
|
2018-03-19 02:25:42 +00:00
|
|
|
import PropTypes from '../../_util/vue-types'
|
|
|
|
import BaseMixin from '../../_util/BaseMixin'
|
|
|
|
import { getOptionProps, hasProp } from '../../_util/props-util'
|
|
|
|
import { cloneElement } from '../../_util/vnode'
|
|
|
|
import KeyCode from '../../_util/KeyCode'
|
2018-03-17 13:38:29 +00:00
|
|
|
import * as moment from 'moment'
|
2018-03-10 14:10:13 +00:00
|
|
|
import DateTable from './date/DateTable'
|
|
|
|
import CalendarHeader from './calendar/CalendarHeader'
|
|
|
|
import CalendarFooter from './calendar/CalendarFooter'
|
|
|
|
import CalendarMixin from './mixin/CalendarMixin'
|
|
|
|
import CommonMixin from './mixin/CommonMixin'
|
|
|
|
import DateInput from './date/DateInput'
|
2018-03-12 14:13:59 +00:00
|
|
|
import enUs from './locale/en_US'
|
2018-03-10 14:10:13 +00:00
|
|
|
import { getTimeConfig, getTodayTime, syncTime } from './util'
|
|
|
|
function goStartMonth () {
|
|
|
|
const next = this.sValue.clone()
|
|
|
|
next.startOf('month')
|
|
|
|
this.setValue(next)
|
|
|
|
}
|
|
|
|
|
|
|
|
function goEndMonth () {
|
|
|
|
const next = this.sValue.clone()
|
|
|
|
next.endOf('month')
|
|
|
|
this.setValue(next)
|
|
|
|
}
|
|
|
|
|
|
|
|
function goTime (direction, unit) {
|
|
|
|
const next = this.sValue.clone()
|
|
|
|
next.add(direction, unit)
|
|
|
|
this.setValue(next)
|
|
|
|
}
|
|
|
|
|
|
|
|
function goMonth (direction) {
|
|
|
|
return goTime.call(this, direction, 'months')
|
|
|
|
}
|
|
|
|
|
|
|
|
function goYear (direction) {
|
|
|
|
return goTime.call(this, direction, 'years')
|
|
|
|
}
|
|
|
|
|
|
|
|
function goWeek (direction) {
|
|
|
|
return goTime.call(this, direction, 'weeks')
|
|
|
|
}
|
|
|
|
|
|
|
|
function goDay (direction) {
|
|
|
|
return goTime.call(this, direction, 'days')
|
|
|
|
}
|
|
|
|
|
2018-03-17 13:38:29 +00:00
|
|
|
function isMoment (value) {
|
|
|
|
if (Array.isArray(value)) {
|
|
|
|
return value.length === 0 || !!value.find((val) => val === undefined || moment.isMoment(val))
|
|
|
|
} else {
|
|
|
|
return value === undefined || moment.isMoment(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const MomentType = PropTypes.custom(isMoment)
|
2018-03-10 14:10:13 +00:00
|
|
|
const Calendar = {
|
|
|
|
props: {
|
2018-03-12 14:13:59 +00:00
|
|
|
locale: PropTypes.object.def(enUs),
|
2018-03-17 13:38:29 +00:00
|
|
|
format: PropTypes.string,
|
2018-03-12 14:13:59 +00:00
|
|
|
visible: PropTypes.bool.def(true),
|
|
|
|
prefixCls: PropTypes.string.def('rc-calendar'),
|
2018-03-11 13:28:13 +00:00
|
|
|
// prefixCls: PropTypes.string,
|
2018-03-17 13:38:29 +00:00
|
|
|
defaultValue: MomentType,
|
|
|
|
value: MomentType,
|
|
|
|
selectedValue: MomentType,
|
2018-03-10 14:10:13 +00:00
|
|
|
mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']),
|
2018-03-11 13:28:13 +00:00
|
|
|
// locale: PropTypes.object,
|
2018-03-10 14:10:13 +00:00
|
|
|
showDateInput: PropTypes.bool.def(true),
|
|
|
|
showWeekNumber: PropTypes.bool,
|
|
|
|
showToday: PropTypes.bool.def(true),
|
|
|
|
showOk: PropTypes.bool,
|
|
|
|
// onSelect: PropTypes.func,
|
|
|
|
// onOk: PropTypes.func,
|
|
|
|
// onKeyDown: PropTypes.func,
|
|
|
|
timePicker: PropTypes.any,
|
|
|
|
dateInputPlaceholder: PropTypes.any,
|
|
|
|
// onClear: PropTypes.func,
|
|
|
|
// onChange: PropTypes.func,
|
|
|
|
// onPanelChange: PropTypes.func,
|
|
|
|
disabledDate: PropTypes.func,
|
|
|
|
disabledTime: PropTypes.any,
|
2018-03-12 14:13:59 +00:00
|
|
|
renderFooter: PropTypes.func.def(() => null),
|
|
|
|
renderSidebar: PropTypes.func.def(() => null),
|
2018-03-17 13:38:29 +00:00
|
|
|
dateRender: PropTypes.func,
|
2018-03-10 14:10:13 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
mixins: [BaseMixin, CommonMixin, CalendarMixin],
|
|
|
|
|
|
|
|
data () {
|
|
|
|
return {
|
|
|
|
sMode: this.mode || 'date',
|
|
|
|
}
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
mode (val) {
|
|
|
|
this.setState({ sMode: val })
|
|
|
|
},
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
onKeyDown (event) {
|
|
|
|
if (event.target.nodeName.toLowerCase() === 'input') {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
const keyCode = event.keyCode
|
|
|
|
// mac
|
|
|
|
const ctrlKey = event.ctrlKey || event.metaKey
|
|
|
|
const { disabledDate, sValue: value } = this
|
|
|
|
switch (keyCode) {
|
|
|
|
case KeyCode.DOWN:
|
|
|
|
goWeek.call(this, 1)
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.UP:
|
|
|
|
goWeek.call(this, -1)
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.LEFT:
|
|
|
|
if (ctrlKey) {
|
|
|
|
goYear.call(this, -1)
|
|
|
|
} else {
|
|
|
|
goDay.call(this, -1)
|
|
|
|
}
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.RIGHT:
|
|
|
|
if (ctrlKey) {
|
|
|
|
goYear.call(this, 1)
|
|
|
|
} else {
|
|
|
|
goDay.call(this, 1)
|
|
|
|
}
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.HOME:
|
|
|
|
goStartMonth.call(this)
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.END:
|
|
|
|
goEndMonth.call(this)
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.PAGE_DOWN:
|
|
|
|
goMonth.call(this, 1)
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.PAGE_UP:
|
|
|
|
goMonth.call(this, -1)
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
case KeyCode.ENTER:
|
|
|
|
if (!disabledDate || !disabledDate(value)) {
|
|
|
|
this.onSelect(value, {
|
|
|
|
source: 'keyboard',
|
|
|
|
})
|
|
|
|
}
|
|
|
|
event.preventDefault()
|
|
|
|
return 1
|
|
|
|
default:
|
|
|
|
this.__emit('keydown', event)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onClear () {
|
|
|
|
this.onSelect(null)
|
|
|
|
this.__emit('clear')
|
|
|
|
},
|
|
|
|
|
|
|
|
onOk () {
|
|
|
|
const { sSelectedValue } = this
|
|
|
|
if (this.isAllowedDate(sSelectedValue)) {
|
|
|
|
this.__emit('ok', sSelectedValue)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onDateInputChange (value) {
|
|
|
|
this.onSelect(value, {
|
|
|
|
source: 'dateInput',
|
|
|
|
})
|
|
|
|
},
|
|
|
|
onDateTableSelect (value) {
|
|
|
|
const { timePicker, sSelectedValue } = this
|
|
|
|
if (!sSelectedValue && timePicker) {
|
2018-03-12 14:13:59 +00:00
|
|
|
const timePickerProps = getOptionProps(timePicker)
|
|
|
|
const timePickerDefaultValue = timePickerProps.defaultValue
|
2018-03-10 14:10:13 +00:00
|
|
|
if (timePickerDefaultValue) {
|
|
|
|
syncTime(timePickerDefaultValue, value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.onSelect(value)
|
|
|
|
},
|
|
|
|
onToday () {
|
|
|
|
const { sValue } = this
|
|
|
|
const now = getTodayTime(sValue)
|
|
|
|
this.onSelect(now, {
|
|
|
|
source: 'todayButton',
|
|
|
|
})
|
|
|
|
},
|
|
|
|
onPanelChange (value, mode) {
|
|
|
|
const { sValue } = this
|
|
|
|
if (!hasProp(this, 'mode')) {
|
|
|
|
this.setState({ sMode: mode })
|
|
|
|
}
|
|
|
|
this.__emit('panelChange', value || sValue, mode)
|
|
|
|
},
|
|
|
|
getRootDOMNode () {
|
|
|
|
return this.$el
|
|
|
|
},
|
|
|
|
openTimePicker () {
|
|
|
|
this.onPanelChange(null, 'time')
|
|
|
|
},
|
|
|
|
closeTimePicker () {
|
|
|
|
this.onPanelChange(null, 'date')
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
render () {
|
|
|
|
const {
|
|
|
|
locale, prefixCls, disabledDate,
|
|
|
|
dateInputPlaceholder, timePicker,
|
|
|
|
disabledTime, showDateInput, renderSidebar,
|
|
|
|
sValue, sSelectedValue, sMode,
|
|
|
|
$props: props,
|
|
|
|
} = this
|
|
|
|
const showTimePicker = sMode === 'time'
|
|
|
|
const disabledTimeConfig = showTimePicker && disabledTime && timePicker
|
|
|
|
? getTimeConfig(sSelectedValue, disabledTime) : null
|
|
|
|
|
|
|
|
let timePickerEle = null
|
|
|
|
|
|
|
|
if (timePicker && showTimePicker) {
|
|
|
|
const timePickerOriginProps = getOptionProps(timePicker)
|
|
|
|
const timePickerProps = {
|
|
|
|
props: {
|
|
|
|
showHour: true,
|
|
|
|
showSecond: true,
|
|
|
|
showMinute: true,
|
|
|
|
...timePickerOriginProps,
|
|
|
|
...disabledTimeConfig,
|
|
|
|
value: sSelectedValue,
|
|
|
|
disabledTime,
|
|
|
|
},
|
|
|
|
on: {
|
|
|
|
change: this.onDateInputChange,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timePickerOriginProps.defaultValue !== undefined) {
|
|
|
|
timePickerProps.props.defaultOpenValue = timePickerOriginProps.defaultValue
|
|
|
|
}
|
|
|
|
timePickerEle = cloneElement(timePicker, timePickerProps)
|
|
|
|
}
|
|
|
|
|
|
|
|
const dateInputElement = showDateInput ? (
|
|
|
|
<DateInput
|
|
|
|
format={this.getFormat()}
|
|
|
|
key='date-input'
|
|
|
|
value={sValue}
|
|
|
|
locale={locale}
|
|
|
|
placeholder={dateInputPlaceholder}
|
|
|
|
showClear
|
|
|
|
disabledTime={disabledTime}
|
|
|
|
disabledDate={disabledDate}
|
|
|
|
onClear={this.onClear}
|
|
|
|
prefixCls={prefixCls}
|
|
|
|
selectedValue={sSelectedValue}
|
|
|
|
onChange={this.onDateInputChange}
|
|
|
|
/>
|
|
|
|
) : null
|
|
|
|
const children = [
|
|
|
|
renderSidebar(),
|
|
|
|
(<div class={`${prefixCls}-panel`} key='panel'>
|
|
|
|
{dateInputElement}
|
|
|
|
<div class={`${prefixCls}-date-panel`}>
|
|
|
|
<CalendarHeader
|
|
|
|
locale={locale}
|
|
|
|
mode={sMode}
|
|
|
|
value={sValue}
|
|
|
|
onValueChange={this.setValue}
|
|
|
|
onPanelChange={this.onPanelChange}
|
|
|
|
showTimePicker={showTimePicker}
|
|
|
|
prefixCls={prefixCls}
|
|
|
|
/>
|
|
|
|
{timePicker && showTimePicker
|
|
|
|
? (<div class={`${prefixCls}-time-picker`}>
|
|
|
|
<div class={`${prefixCls}-time-picker-panel`}>
|
|
|
|
{timePickerEle }
|
|
|
|
</div>
|
|
|
|
</div>)
|
|
|
|
: null}
|
|
|
|
<div class={`${prefixCls}-body`}>
|
|
|
|
<DateTable
|
|
|
|
locale={locale}
|
|
|
|
value={sValue}
|
|
|
|
selectedValue={sSelectedValue}
|
|
|
|
prefixCls={prefixCls}
|
|
|
|
dateRender={props.dateRender}
|
|
|
|
onSelect={this.onDateTableSelect}
|
|
|
|
disabledDate={disabledDate}
|
|
|
|
showWeekNumber={props.showWeekNumber}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<CalendarFooter
|
|
|
|
showOk={props.showOk}
|
|
|
|
renderFooter={props.renderFooter}
|
|
|
|
locale={locale}
|
|
|
|
prefixCls={prefixCls}
|
|
|
|
showToday={props.showToday}
|
|
|
|
disabledTime={disabledTime}
|
|
|
|
showTimePicker={showTimePicker}
|
|
|
|
showDateInput={props.showDateInput}
|
|
|
|
timePicker={timePicker}
|
|
|
|
selectedValue={sSelectedValue}
|
|
|
|
value={sValue}
|
|
|
|
disabledDate={disabledDate}
|
|
|
|
okDisabled={!this.isAllowedDate(sSelectedValue)}
|
|
|
|
onOk={this.onOk}
|
|
|
|
onSelect={this.onSelect}
|
|
|
|
onToday={this.onToday}
|
|
|
|
onOpenTimePicker={this.openTimePicker}
|
|
|
|
onCloseTimePicker={this.closeTimePicker}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>),
|
|
|
|
]
|
|
|
|
|
|
|
|
return this.renderRoot({
|
|
|
|
children,
|
|
|
|
class: props.showWeekNumber ? `${prefixCls}-week-number` : '',
|
|
|
|
})
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Calendar
|
2018-03-19 02:16:27 +00:00
|
|
|
|