add vc-calendar

pull/9/head
tjz 2018-03-11 21:28:13 +08:00
parent 09a0ba91c9
commit 2fd9588afc
14 changed files with 641 additions and 408 deletions

View File

@ -52,7 +52,7 @@ const getOptionProps = (instance) => {
const res = {} const res = {}
for (const [k, v] of Object.entries(props)) { for (const [k, v] of Object.entries(props)) {
if (v.default !== undefined) { if (v.default !== undefined) {
res[k] = v res[k] = typeof v.default === 'function' ? v.default() : v.default
} }
} }
return { ...res, ...propsData } return { ...res, ...propsData }

View File

@ -0,0 +1,236 @@
<script>
/* eslint react/no-multi-comp:0, no-console:0 */
import '../assets/index.less'
import PropTypes from '@/components/_util/vue-types'
import Calendar from '../'
import DatePicker from '../src/Picker'
import zhCN from '../src/locale/zh_CN'
import enUS from '../src/locale/en_US'
import '../../vc-time-picker/assets/index.less'
import TimePickerPanel from '../../vc-time-picker/Panel'
import BaseMixin from '@/components/_util/BaseMixin'
import moment from 'moment'
import 'moment/locale/zh-cn'
import 'moment/locale/en-gb'
const format = 'YYYY-MM-DD HH:mm:ss'
const cn = window.location.search.indexOf('cn') !== -1
const now = moment()
if (cn) {
now.locale('zh-cn').utcOffset(8)
} else {
now.locale('en-gb').utcOffset(0)
}
function getFormat (time) {
return time ? format : 'YYYY-MM-DD'
}
const defaultCalendarValue = now.clone()
defaultCalendarValue.add(-1, 'month')
const timePickerElement = (h) => <TimePickerPanel defaultValue={moment('00:00:00', 'HH:mm:ss')} />
function disabledTime (date) {
console.log('disabledTime', date)
if (date && (date.date() === 15)) {
return {
disabledHours () {
return [3, 4]
},
}
}
return {
disabledHours () {
return [1, 2]
},
}
}
function disabledDate (current) {
if (!current) {
// allow empty select
return false
}
const date = moment()
date.hour(0)
date.minute(0)
date.second(0)
return current.valueOf() < date.valueOf() // can not select days before today
}
const Demo = {
props: {
defaultValue: PropTypes.object,
defaultCalendarValue: PropTypes.object,
},
mixins: [BaseMixin],
data () {
return {
showTime: true,
showDateInput: true,
disabled: false,
value: this.defaultValue,
}
},
methods: {
onChange (value) {
console.log('DatePicker change: ', (value && value.format(format)))
this.setState({
value,
})
},
onShowTimeChange (e) {
this.setState({
showTime: e.target.checked,
})
},
onShowDateInputChange (e) {
this.setState({
showDateInput: e.target.checked,
})
},
toggleDisabled () {
this.setState({
disabled: !this.state.disabled,
})
},
},
render (h) {
const state = this.$data
const calendar = (<Calendar
locale={cn ? zhCN : enUS}
style={{ zIndex: 1000 }}
dateInputPlaceholder='please input'
formatter={getFormat(state.showTime)}
disabledTime={state.showTime ? disabledTime : null}
timePicker={state.showTime ? timePickerElement(h) : null}
defaultValue={this.defaultCalendarValue}
showDateInput={state.showDateInput}
disabledDate={disabledDate}
/>)
return (<div style={{ width: '400px', margin: '20px' }}>
<div style={{ marginBottom: '10px' }}>
<label>
<input
type='checkbox'
checked={state.showTime}
onChange={this.onShowTimeChange}
/>
showTime
</label>
&nbsp;&nbsp;&nbsp;&nbsp;
<label>
<input
type='checkbox'
checked={state.showDateInput}
onChange={this.onShowDateInputChange}
/>
showDateInput
</label>
&nbsp;&nbsp;&nbsp;&nbsp;
<label>
<input
checked={state.disabled}
onChange={this.toggleDisabled}
type='checkbox'
/>
disabled
</label>
</div>
<div style={{
boxSizing: 'border-box',
position: 'relative',
display: 'block',
lineHeight: 1.5,
marginBottom: '22px',
}}
>
<DatePicker
animation='slide-up'
disabled={state.disabled}
calendar={calendar}
value={state.value}
onChange={this.onChange}
scopedSlots={{
default: ({ value }) => {
return (
<span tabIndex='0' scope={{ value }}>
<input
placeholder='please select'
style={{ width: '250px' }}
disabled={state.disabled}
readOnly
tabIndex='-1'
class='ant-calendar-picker-input ant-input'
value={value && value.format(getFormat(state.showTime)) || ''}
/>
</span>
)
},
}}
>
</DatePicker>
</div>
</div>)
},
}
function onStandaloneSelect (value) {
console.log('onStandaloneSelect')
console.log(value && value.format(format))
}
function onStandaloneChange (value) {
console.log('onStandaloneChange')
console.log(value && value.format(format))
}
export default {
render (h) {
return (
<div
style={{
zIndex: 1000,
position: 'relative',
width: '900px',
margin: '20px auto',
}}
>
<div>
<div style={{ margin: '10px' }}>
<Calendar
showWeekNumber={false}
locale={cn ? zhCN : enUS}
defaultValue={now}
disabledTime={disabledTime}
showToday
formatter={getFormat(true)}
showOk={false}
timePicker={timePickerElement(h)}
onChange={onStandaloneChange}
disabledDate={disabledDate}
onSelect={onStandaloneSelect}
/>
</div>
<div style={{ float: 'left', width: '300px' }}>
<Demo defaultValue={now} />
</div>
<div style={{ float: 'right', width: '300px' }}>
<Demo defaultCalendarValue={defaultCalendarValue} />
</div>
<div style={{ clear: 'both' }}></div>
</div>
</div>
)
},
}
</script>

View File

@ -11,7 +11,7 @@ import CalendarMixin from './mixin/CalendarMixin'
import CommonMixin from './mixin/CommonMixin' import CommonMixin from './mixin/CommonMixin'
import DateInput from './date/DateInput' import DateInput from './date/DateInput'
import { getTimeConfig, getTodayTime, syncTime } from './util' import { getTimeConfig, getTodayTime, syncTime } from './util'
function noop () {}
function goStartMonth () { function goStartMonth () {
const next = this.sValue.clone() const next = this.sValue.clone()
next.startOf('month') next.startOf('month')
@ -48,12 +48,12 @@ function goDay (direction) {
const Calendar = { const Calendar = {
props: { props: {
prefixCls: PropTypes.string, // prefixCls: PropTypes.string,
defaultValue: PropTypes.object, defaultValue: PropTypes.object,
value: PropTypes.object, value: PropTypes.object,
selectedValue: PropTypes.object, selectedValue: PropTypes.object,
mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']), mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']),
locale: PropTypes.object, // locale: PropTypes.object,
showDateInput: PropTypes.bool.def(true), showDateInput: PropTypes.bool.def(true),
showWeekNumber: PropTypes.bool, showWeekNumber: PropTypes.bool,
showToday: PropTypes.bool.def(true), showToday: PropTypes.bool.def(true),
@ -68,8 +68,8 @@ const Calendar = {
// onPanelChange: PropTypes.func, // onPanelChange: PropTypes.func,
disabledDate: PropTypes.func, disabledDate: PropTypes.func,
disabledTime: PropTypes.any, disabledTime: PropTypes.any,
renderFooter: PropTypes.func, renderFooter: PropTypes.func.def(noop),
renderSidebar: PropTypes.func, renderSidebar: PropTypes.func.def(noop),
}, },
mixins: [BaseMixin, CommonMixin, CalendarMixin], mixins: [BaseMixin, CommonMixin, CalendarMixin],
@ -215,6 +215,7 @@ const Calendar = {
let timePickerEle = null let timePickerEle = null
if (timePicker && showTimePicker) { if (timePicker && showTimePicker) {
console.log(timePicker)
const timePickerOriginProps = getOptionProps(timePicker) const timePickerOriginProps = getOptionProps(timePicker)
const timePickerProps = { const timePickerProps = {
props: { props: {
@ -234,7 +235,7 @@ const Calendar = {
if (timePickerOriginProps.defaultValue !== undefined) { if (timePickerOriginProps.defaultValue !== undefined) {
timePickerProps.props.defaultOpenValue = timePickerOriginProps.defaultValue timePickerProps.props.defaultOpenValue = timePickerOriginProps.defaultValue
} }
console.log(timePickerProps)
timePickerEle = cloneElement(timePicker, timePickerProps) timePickerEle = cloneElement(timePicker, timePickerProps)
} }

View File

@ -78,7 +78,7 @@ const Picker = {
onCalendarKeyDown (event) { onCalendarKeyDown (event) {
if (event.keyCode === KeyCode.ESC) { if (event.keyCode === KeyCode.ESC) {
event.stopPropagation() event.stopPropagation()
this.close(this.focus) this.closeCalendar(this.focus)
} }
}, },
@ -94,7 +94,7 @@ const Picker = {
cause.source === 'keyboard' || cause.source === 'keyboard' ||
(!calendarProps.timePicker && cause.source !== 'dateInput') || (!calendarProps.timePicker && cause.source !== 'dateInput') ||
cause.source === 'todayButton') { cause.source === 'todayButton') {
this.close(this.focus) this.closeCalendar(this.focus)
} }
this.__emit('change', value) this.__emit('change', value)
}, },
@ -107,11 +107,11 @@ const Picker = {
}, },
onCalendarOk () { onCalendarOk () {
this.close(this.focus) this.closeCalendar(this.focus)
}, },
onCalendarClear () { onCalendarClear () {
this.close(this.focus) this.closeCalendar(this.focus)
}, },
onVisibleChange (open) { onVisibleChange (open) {
@ -153,11 +153,11 @@ const Picker = {
} }
}, },
open (callback) { openCalendar (callback) {
this.setOpen(true, callback) this.setOpen(true, callback)
}, },
close (callback) { closeCalendar (callback) {
this.setOpen(false, callback) this.setOpen(false, callback)
}, },
@ -183,9 +183,10 @@ const Picker = {
align, animation, align, animation,
disabled, disabled,
dropdownClassName, dropdownClassName,
transitionName, children, transitionName,
} = props } = props
const state = this.$data const state = this.$data
const children = this.$scopedSlots.default
return (<Trigger return (<Trigger
popupAlign={align} popupAlign={align}
builtinPlacements={placements} builtinPlacements={placements}

View File

@ -2,9 +2,7 @@
import PropTypes from '@/components/_util/vue-types' import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin' import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps, hasProp } from '@/components/_util/props-util' import { getOptionProps, hasProp } from '@/components/_util/props-util'
import { cloneElement } from '@/components/_util/vnode'
import moment from 'moment' import moment from 'moment'
import classnames from 'classnames'
import CalendarPart from './range-calendar/CalendarPart' import CalendarPart from './range-calendar/CalendarPart'
import TodayButton from './calendar/TodayButton' import TodayButton from './calendar/TodayButton'
import OkButton from './calendar/OkButton' import OkButton from './calendar/OkButton'
@ -61,74 +59,60 @@ function onInputSelect (direction, value) {
if (!value) { if (!value) {
return return
} }
const originalValue = this.state.selectedValue const originalValue = this.sSelectedValue
const selectedValue = originalValue.concat() const selectedValue = originalValue.concat()
const index = direction === 'left' ? 0 : 1 const index = direction === 'left' ? 0 : 1
selectedValue[index] = value selectedValue[index] = value
if (selectedValue[0] && this.compare(selectedValue[0], selectedValue[1]) > 0) { if (selectedValue[0] && this.compare(selectedValue[0], selectedValue[1]) > 0) {
selectedValue[1 - index] = this.state.showTimePicker ? selectedValue[index] : undefined selectedValue[1 - index] = this.showTimePicker ? selectedValue[index] : undefined
} }
this.props.onInputSelect(selectedValue) this.__emit('inputSelect', selectedValue)
this.fireSelectValueChange(selectedValue) this.fireSelectValueChange(selectedValue)
} }
const RangeCalendar = createReactClass({ const RangeCalendar = {
propTypes: { props: {
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
dateInputPlaceholder: PropTypes.any, dateInputPlaceholder: PropTypes.any,
defaultValue: PropTypes.any, defaultValue: PropTypes.any,
value: PropTypes.any, value: PropTypes.any,
hoverValue: PropTypes.any, hoverValue: PropTypes.any,
mode: PropTypes.arrayOf(PropTypes.oneOf(['date', 'month', 'year', 'decade'])), mode: PropTypes.arrayOf(PropTypes.oneOf(['date', 'month', 'year', 'decade'])),
showDateInput: PropTypes.bool, showDateInput: PropTypes.bool.def(true),
timePicker: PropTypes.any, timePicker: PropTypes.any,
showOk: PropTypes.bool, showOk: PropTypes.bool,
showToday: PropTypes.bool, showToday: PropTypes.bool.def(true),
defaultSelectedValue: PropTypes.array, defaultSelectedValue: PropTypes.array.def([]),
selectedValue: PropTypes.array, selectedValue: PropTypes.array,
onOk: PropTypes.func, onOk: PropTypes.func,
showClear: PropTypes.bool, showClear: PropTypes.bool,
locale: PropTypes.object, locale: PropTypes.object,
onChange: PropTypes.func, // onChange: PropTypes.func,
onSelect: PropTypes.func, // onSelect: PropTypes.func,
onValueChange: PropTypes.func, // onValueChange: PropTypes.func,
onHoverChange: PropTypes.func, // onHoverChange: PropTypes.func,
onPanelChange: PropTypes.func, // onPanelChange: PropTypes.func,
format: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), format: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
onClear: PropTypes.func, // onClear: PropTypes.func,
type: PropTypes.any, type: PropTypes.any.def('both'),
disabledDate: PropTypes.func, disabledDate: PropTypes.func,
disabledTime: PropTypes.func, disabledTime: PropTypes.func.def(noop),
}, },
mixins: [CommonMixin], mixins: [BaseMixin, CommonMixin],
getDefaultProps () { data () {
return { const props = this.$props
type: 'both',
defaultSelectedValue: [],
onValueChange: noop,
onHoverChange: noop,
onPanelChange: noop,
disabledTime: noop,
onInputSelect: noop,
showToday: true,
showDateInput: true,
}
},
getInitialState () {
const props = this.props
const selectedValue = props.selectedValue || props.defaultSelectedValue const selectedValue = props.selectedValue || props.defaultSelectedValue
const value = normalizeAnchor(props, 1) const value = normalizeAnchor(props, 1)
return { return {
selectedValue, sSelectedValue: selectedValue,
prevSelectedValue: selectedValue, prevSelectedValue: selectedValue,
firstSelectedValue: null, firstSelectedValue: null,
hoverValue: props.hoverValue || [], sHoverValue: props.hoverValue || [],
value, sValue: value,
showTimePicker: false, showTimePicker: false,
mode: props.mode || ['date', 'date'], sMode: props.mode || ['date', 'date'],
} }
}, },
@ -151,343 +135,347 @@ const RangeCalendar = createReactClass({
this.setState({ mode: nextProps.mode }) this.setState({ mode: nextProps.mode })
} }
}, },
methods: {
onDatePanelEnter () {
if (this.hasSelectedValue()) {
this.fireHoverValueChange(this.sSelectedValue.concat())
}
},
onDatePanelEnter () { onDatePanelLeave () {
if (this.hasSelectedValue()) { if (this.hasSelectedValue()) {
this.fireHoverValueChange(this.state.selectedValue.concat()) this.fireHoverValueChange([])
} }
}, },
onDatePanelLeave () { onSelect (value) {
if (this.hasSelectedValue()) { const { type, sSelectedValue, prevSelectedValue, firstSelectedValue } = this
this.fireHoverValueChange([]) let nextSelectedValue
} if (type === 'both') {
}, if (!firstSelectedValue) {
syncTime(prevSelectedValue[0], value)
onSelect (value) { nextSelectedValue = [value]
const { type } = this.props } else if (this.compare(firstSelectedValue, value) < 0) {
const { selectedValue, prevSelectedValue, firstSelectedValue } = this.state syncTime(prevSelectedValue[1], value)
let nextSelectedValue nextSelectedValue = [firstSelectedValue, value]
if (type === 'both') { } else {
if (!firstSelectedValue) { syncTime(prevSelectedValue[0], value)
syncTime(prevSelectedValue[1], firstSelectedValue)
nextSelectedValue = [value, firstSelectedValue]
}
} else if (type === 'start') {
syncTime(prevSelectedValue[0], value) syncTime(prevSelectedValue[0], value)
nextSelectedValue = [value] const endValue = sSelectedValue[1]
} else if (this.compare(firstSelectedValue, value) < 0) { nextSelectedValue = endValue && this.compare(endValue, value) > 0
syncTime(prevSelectedValue[1], value) ? [value, endValue] : [value]
nextSelectedValue = [firstSelectedValue, value] } else { // type === 'end'
const startValue = sSelectedValue[0]
if (startValue && this.compare(startValue, value) <= 0) {
syncTime(prevSelectedValue[1], value)
nextSelectedValue = [startValue, value]
} else {
syncTime(prevSelectedValue[0], value)
nextSelectedValue = [value]
}
}
this.fireSelectValueChange(nextSelectedValue)
},
onDayHover (value) {
let hoverValue = []
const { sSelectedValue, firstSelectedValue, type } = this
if (type === 'start' && sSelectedValue[1]) {
hoverValue = this.compare(value, sSelectedValue[1]) < 0
? [value, sSelectedValue[1]] : [value]
} else if (type === 'end' && sSelectedValue[0]) {
hoverValue = this.compare(value, sSelectedValue[0]) > 0
? [sSelectedValue[0], value] : []
} else { } else {
syncTime(prevSelectedValue[0], value) if (!firstSelectedValue) {
syncTime(prevSelectedValue[1], firstSelectedValue) return
nextSelectedValue = [value, firstSelectedValue] }
hoverValue = this.compare(value, firstSelectedValue) < 0
? [value, firstSelectedValue] : [firstSelectedValue, value]
} }
} else if (type === 'start') { this.fireHoverValueChange(hoverValue)
syncTime(prevSelectedValue[0], value) },
const endValue = selectedValue[1]
nextSelectedValue = endValue && this.compare(endValue, value) > 0 onToday () {
? [value, endValue] : [value] const startValue = getTodayTime(this.sValue[0])
} else { // type === 'end' const endValue = startValue.clone().add(1, 'months')
const startValue = selectedValue[0] this.setState({ sValue: [startValue, endValue] })
if (startValue && this.compare(startValue, value) <= 0) { },
syncTime(prevSelectedValue[1], value)
nextSelectedValue = [startValue, value] onOpenTimePicker () {
} else { this.setState({
syncTime(prevSelectedValue[0], value) showTimePicker: true,
nextSelectedValue = [value] })
},
onCloseTimePicker () {
this.setState({
showTimePicker: false,
})
},
onOk () {
const { sSelectedValue } = this
if (this.isAllowedDateAndTime(sSelectedValue)) {
this.__emit('ok', sSelectedValue)
} }
} },
this.fireSelectValueChange(nextSelectedValue) onStartInputSelect (...oargs) {
}, const args = ['left'].concat(oargs)
return onInputSelect.apply(this, args)
},
onDayHover (value) { onEndInputSelect (...oargs) {
let hoverValue = [] const args = ['right'].concat(oargs)
const { selectedValue, firstSelectedValue } = this.state return onInputSelect.apply(this, args)
const { type } = this.props },
if (type === 'start' && selectedValue[1]) {
hoverValue = this.compare(value, selectedValue[1]) < 0 onStartValueChange (leftValue) {
? [value, selectedValue[1]] : [value] const value = [...this.sValue]
} else if (type === 'end' && selectedValue[0]) { value[0] = leftValue
hoverValue = this.compare(value, selectedValue[0]) > 0 return this.fireValueChange(value)
? [selectedValue[0], value] : [] },
} else {
if (!firstSelectedValue) { onEndValueChange (rightValue) {
return const value = [...this.sValue]
value[1] = rightValue
return this.fireValueChange(value)
},
onStartPanelChange (value, mode) {
const { sMode, sValue } = this
const newMode = [mode, sMode[1]]
if (!hasProp(this, 'mode')) {
this.setState({
sMode: newMode,
})
} }
hoverValue = this.compare(value, firstSelectedValue) < 0 const newValue = [value || sValue[0], sValue[1]]
? [value, firstSelectedValue] : [firstSelectedValue, value] this.__emit('panelChange', newValue, newMode)
} },
this.fireHoverValueChange(hoverValue)
},
onToday () { onEndPanelChange (value, mode) {
const startValue = getTodayTime(this.state.value[0]) const { sMode, sValue } = this
const endValue = startValue.clone().add(1, 'months') const newMode = [sMode[0], mode]
this.setState({ value: [startValue, endValue] }) if (!hasProp(this, 'mode')) {
}, this.setState({
sMode: newMode,
onOpenTimePicker () { })
this.setState({
showTimePicker: true,
})
},
onCloseTimePicker () {
this.setState({
showTimePicker: false,
})
},
onOk () {
const { selectedValue } = this.state
if (this.isAllowedDateAndTime(selectedValue)) {
this.props.onOk(this.state.selectedValue)
}
},
onStartInputSelect (...oargs) {
const args = ['left'].concat(oargs)
return onInputSelect.apply(this, args)
},
onEndInputSelect (...oargs) {
const args = ['right'].concat(oargs)
return onInputSelect.apply(this, args)
},
onStartValueChange (leftValue) {
const value = [...this.state.value]
value[0] = leftValue
return this.fireValueChange(value)
},
onEndValueChange (rightValue) {
const value = [...this.state.value]
value[1] = rightValue
return this.fireValueChange(value)
},
onStartPanelChange (value, mode) {
const { props, state } = this
const newMode = [mode, state.mode[1]]
if (!('mode' in props)) {
this.setState({
mode: newMode,
})
}
const newValue = [value || state.value[0], state.value[1]]
props.onPanelChange(newValue, newMode)
},
onEndPanelChange (value, mode) {
const { props, state } = this
const newMode = [state.mode[0], mode]
if (!('mode' in props)) {
this.setState({
mode: newMode,
})
}
const newValue = [state.value[0], value || state.value[1]]
props.onPanelChange(newValue, newMode)
},
getStartValue () {
let value = this.state.value[0]
const selectedValue = this.state.selectedValue
// keep selectedTime when select date
if (selectedValue[0] && this.props.timePicker) {
value = value.clone()
syncTime(selectedValue[0], value)
}
if (this.state.showTimePicker && selectedValue[0]) {
return selectedValue[0]
}
return value
},
getEndValue () {
const { value, selectedValue, showTimePicker } = this.state
const endValue = value[1] ? value[1].clone() : value[0].clone().add(1, 'month')
// keep selectedTime when select date
if (selectedValue[1] && this.props.timePicker) {
syncTime(selectedValue[1], endValue)
}
if (showTimePicker) {
return selectedValue[1] ? selectedValue[1] : this.getStartValue()
}
return endValue
},
// get disabled hours for second picker
getEndDisableTime () {
const { selectedValue, value } = this.state
const { disabledTime } = this.props
const userSettingDisabledTime = disabledTime(selectedValue, 'end') || {}
const startValue = selectedValue && selectedValue[0] || value[0].clone()
// if startTime and endTime is same day..
// the second time picker will not able to pick time before first time picker
if (!selectedValue[1] || startValue.isSame(selectedValue[1], 'day')) {
const hours = startValue.hour()
const minutes = startValue.minute()
const second = startValue.second()
let { disabledHours, disabledMinutes, disabledSeconds } = userSettingDisabledTime
const oldDisabledMinutes = disabledMinutes ? disabledMinutes() : []
const olddisabledSeconds = disabledSeconds ? disabledSeconds() : []
disabledHours = generateOptions(hours, disabledHours)
disabledMinutes = generateOptions(minutes, disabledMinutes)
disabledSeconds = generateOptions(second, disabledSeconds)
return {
disabledHours () {
return disabledHours
},
disabledMinutes (hour) {
if (hour === hours) {
return disabledMinutes
}
return oldDisabledMinutes
},
disabledSeconds (hour, minute) {
if (hour === hours && minute === minutes) {
return disabledSeconds
}
return olddisabledSeconds
},
} }
} const newValue = [sValue[0], value || sValue[1]]
return userSettingDisabledTime this.__emit('panelChange', newValue, newMode)
}, },
isAllowedDateAndTime (selectedValue) { getStartValue () {
return isAllowedDate(selectedValue[0], this.props.disabledDate, this.disabledStartTime) && let value = this.sValue[0]
isAllowedDate(selectedValue[1], this.props.disabledDate, this.disabledEndTime) const selectedValue = this.sSelectedValue
}, // keep selectedTime when select date
if (selectedValue[0] && this.props.timePicker) {
isMonthYearPanelShow (mode) { value = value.clone()
return ['month', 'year', 'decade'].indexOf(mode) > -1 syncTime(selectedValue[0], value)
},
hasSelectedValue () {
const { selectedValue } = this.state
return !!selectedValue[1] && !!selectedValue[0]
},
compare (v1, v2) {
if (this.props.timePicker) {
return v1.diff(v2)
}
return v1.diff(v2, 'days')
},
fireSelectValueChange (selectedValue, direct) {
const { timePicker } = this.props
const { prevSelectedValue } = this.state
if (timePicker && timePicker.props.defaultValue) {
const timePickerDefaultValue = timePicker.props.defaultValue
if (!prevSelectedValue[0] && selectedValue[0]) {
syncTime(timePickerDefaultValue[0], selectedValue[0])
} }
if (!prevSelectedValue[1] && selectedValue[1]) { if (this.state.showTimePicker && selectedValue[0]) {
syncTime(timePickerDefaultValue[1], selectedValue[1]) return selectedValue[0]
} }
} return value
},
if (!('selectedValue' in this.props)) { getEndValue () {
this.setState({ const { sValue, sSelectedValue, showTimePicker } = this
selectedValue, const endValue = sValue[1] ? sValue[1].clone() : sValue[0].clone().add(1, 'month')
}) // keep selectedTime when select date
} if (sSelectedValue[1] && this.timePicker) {
syncTime(sSelectedValue[1], endValue)
}
if (showTimePicker) {
return sSelectedValue[1] ? sSelectedValue[1] : this.getStartValue()
}
return endValue
},
// get disabled hours for second picker
getEndDisableTime () {
const { sSelectedValue, sValue, disabledTime } = this
const userSettingDisabledTime = disabledTime(sSelectedValue, 'end') || {}
const startValue = sSelectedValue && sSelectedValue[0] || sValue[0].clone()
// if startTime and endTime is same day..
// the second time picker will not able to pick time before first time picker
if (!sSelectedValue[1] || startValue.isSame(sSelectedValue[1], 'day')) {
const hours = startValue.hour()
const minutes = startValue.minute()
const second = startValue.second()
let { disabledHours, disabledMinutes, disabledSeconds } = userSettingDisabledTime
const oldDisabledMinutes = disabledMinutes ? disabledMinutes() : []
const olddisabledSeconds = disabledSeconds ? disabledSeconds() : []
disabledHours = generateOptions(hours, disabledHours)
disabledMinutes = generateOptions(minutes, disabledMinutes)
disabledSeconds = generateOptions(second, disabledSeconds)
return {
disabledHours () {
return disabledHours
},
disabledMinutes (hour) {
if (hour === hours) {
return disabledMinutes
}
return oldDisabledMinutes
},
disabledSeconds (hour, minute) {
if (hour === hours && minute === minutes) {
return disabledSeconds
}
return olddisabledSeconds
},
}
}
return userSettingDisabledTime
},
// isAllowedDateAndTime (selectedValue) {
if (!this.state.selectedValue[0] || !this.state.selectedValue[1]) { return isAllowedDate(selectedValue[0], this.disabledDate, this.disabledStartTime) &&
const startValue = selectedValue[0] || moment() isAllowedDate(selectedValue[1], this.disabledDate, this.disabledEndTime)
const endValue = selectedValue[1] || startValue.clone().add(1, 'months') },
this.setState({
selectedValue,
value: getValueFromSelectedValue([startValue, endValue]),
})
}
if (selectedValue[0] && !selectedValue[1]) { isMonthYearPanelShow (mode) {
this.setState({ firstSelectedValue: selectedValue[0] }) return ['month', 'year', 'decade'].indexOf(mode) > -1
this.fireHoverValueChange(selectedValue.concat()) },
}
this.props.onChange(selectedValue)
if (direct || selectedValue[0] && selectedValue[1]) {
this.setState({
prevSelectedValue: selectedValue,
firstSelectedValue: null,
})
this.fireHoverValueChange([])
this.props.onSelect(selectedValue)
}
},
fireValueChange (value) { hasSelectedValue () {
const props = this.props const { sSelectedValue } = this
if (!('value' in props)) { return !!sSelectedValue[1] && !!sSelectedValue[0]
this.setState({ },
value,
})
}
props.onValueChange(value)
},
fireHoverValueChange (hoverValue) { compare (v1, v2) {
const props = this.props if (this.timePicker) {
if (!('hoverValue' in props)) { return v1.diff(v2)
this.setState({ hoverValue }) }
} return v1.diff(v2, 'days')
props.onHoverChange(hoverValue) },
},
clear () { fireSelectValueChange (selectedValue, direct) {
this.fireSelectValueChange([], true) const { timePicker, prevSelectedValue } = this
this.props.onClear() console.log('timePicker', timePicker)
}, if (timePicker && timePicker.props.defaultValue) {
const timePickerDefaultValue = timePicker.props.defaultValue
if (!prevSelectedValue[0] && selectedValue[0]) {
syncTime(timePickerDefaultValue[0], selectedValue[0])
}
if (!prevSelectedValue[1] && selectedValue[1]) {
syncTime(timePickerDefaultValue[1], selectedValue[1])
}
}
disabledStartTime (time) { if (!hasProp(this, 'selectedValue')) {
return this.props.disabledTime(time, 'start') this.setState({
}, sSelectedValue: selectedValue,
})
}
disabledEndTime (time) { //
return this.props.disabledTime(time, 'end') if (!this.sSelectedValue[0] || !this.sSelectedValue[1]) {
}, const startValue = selectedValue[0] || moment()
const endValue = selectedValue[1] || startValue.clone().add(1, 'months')
this.setState({
sSelectedValue: selectedValue,
sValue: getValueFromSelectedValue([startValue, endValue]),
})
}
disabledStartMonth (month) { if (selectedValue[0] && !selectedValue[1]) {
const { value } = this.state this.setState({ firstSelectedValue: selectedValue[0] })
return month.isSameOrAfter(value[1], 'month') this.fireHoverValueChange(selectedValue.concat())
}, }
this.__emit('change', selectedValue)
if (direct || selectedValue[0] && selectedValue[1]) {
this.setState({
prevSelectedValue: selectedValue,
firstSelectedValue: null,
})
this.fireHoverValueChange([])
this.__emit('select', selectedValue)
}
},
disabledEndMonth (month) { fireValueChange (value) {
const { value } = this.state if (!hasProp(this, 'value')) {
return month.isSameOrBefore(value[0], 'month') this.setState({
sValue: value,
})
}
this.__emit('valueChange', value)
},
fireHoverValueChange (hoverValue) {
if (!hasProp(this, 'hoverValue')) {
this.setState({ sHoverValue: hoverValue })
}
this.__emit('hoverChange', hoverValue)
},
clear () {
this.fireSelectValueChange([], true)
this.__emit('clear')
},
disabledStartTime (time) {
return this.disabledTime(time, 'start')
},
disabledEndTime (time) {
return this.disabledTime(time, 'end')
},
disabledStartMonth (month) {
const { sValue } = this
return month.isSameOrAfter(sValue[1], 'month')
},
disabledEndMonth (month) {
const { sValue } = this
return month.isSameOrBefore(sValue[0], 'month')
},
}, },
render () { render () {
const { props, state } = this const props = getOptionProps(this)
const { const {
prefixCls, dateInputPlaceholder, prefixCls, dateInputPlaceholder,
timePicker, showOk, locale, showClear, timePicker, showOk, locale, showClear,
showToday, type, showToday, type,
} = props } = props
const { const {
hoverValue, sHoverValue,
selectedValue, sSelectedValue,
mode, sMode,
showTimePicker, showTimePicker,
} = state sValue,
$listeners,
} = this
const className = { const className = {
[props.className]: !!props.className,
[prefixCls]: 1, [prefixCls]: 1,
[`${prefixCls}-hidden`]: !props.visible, [`${prefixCls}-hidden`]: !props.visible,
[`${prefixCls}-range`]: 1, [`${prefixCls}-range`]: 1,
[`${prefixCls}-show-time-picker`]: showTimePicker, [`${prefixCls}-show-time-picker`]: showTimePicker,
[`${prefixCls}-week-number`]: props.showWeekNumber, [`${prefixCls}-week-number`]: props.showWeekNumber,
} }
const classes = classnames(className) const baseProps = {
props,
on: $listeners,
}
const newProps = { const newProps = {
selectedValue: state.selectedValue, props: {
onSelect: this.onSelect, selectedValue: sSelectedValue,
onDayHover: type === 'start' && selectedValue[1] || },
type === 'end' && selectedValue[0] || !!hoverValue.length on: {
? this.onDayHover : undefined, select: this.onSelect,
dayHover: type === 'start' && sSelectedValue[1] ||
type === 'end' && sSelectedValue[0] || !!sHoverValue.length
? this.onDayHover : undefined,
},
} }
let placeholder1 let placeholder1
@ -501,11 +489,11 @@ const RangeCalendar = createReactClass({
} }
} }
const showOkButton = showOk === true || showOk !== false && !!timePicker const showOkButton = showOk === true || showOk !== false && !!timePicker
const cls = classnames({ const cls = {
[`${prefixCls}-footer`]: true, [`${prefixCls}-footer`]: true,
[`${prefixCls}-range-bottom`]: true, [`${prefixCls}-range-bottom`]: true,
[`${prefixCls}-footer-show-ok`]: showOkButton, [`${prefixCls}-footer-show-ok`]: showOkButton,
}) }
const startValue = this.getStartValue() const startValue = this.getStartValue()
const endValue = this.getEndValue() const endValue = this.getEndValue()
@ -521,34 +509,33 @@ const RangeCalendar = createReactClass({
return ( return (
<div <div
ref={this.saveRoot} ref={this.saveRoot}
className={classes} class={className}
style={props.style}
tabIndex='0' tabIndex='0'
> >
{props.renderSidebar()} {props.renderSidebar()}
<div className={`${prefixCls}-panel`}> <div class={`${prefixCls}-panel`}>
{showClear && selectedValue[0] && selectedValue[1] {showClear && sSelectedValue[0] && sSelectedValue[1]
? <a ? <a
className={`${prefixCls}-clear-btn`} class={`${prefixCls}-clear-btn`}
role='button' role='button'
title={locale.clear} title={locale.clear}
onClick={this.clear} onClick={this.clear}
/> : null} /> : null}
<div <div
className={`${prefixCls}-date-panel`} class={`${prefixCls}-date-panel`}
onMouseLeave={type !== 'both' ? this.onDatePanelLeave : undefined} onMouseleave={type !== 'both' ? this.onDatePanelLeave : noop}
onMouseEnter={type !== 'both' ? this.onDatePanelEnter : undefined} onMouseenter={type !== 'both' ? this.onDatePanelEnter : noop}
> >
<CalendarPart <CalendarPart
{...props} {...baseProps}
{...newProps} {...newProps}
hoverValue={hoverValue} hoverValue={sHoverValue}
direction='left' direction='left'
disabledTime={this.disabledStartTime} disabledTime={this.disabledStartTime}
disabledMonth={this.disabledStartMonth} disabledMonth={this.disabledStartMonth}
format={this.getFormat()} format={this.getFormat()}
value={startValue} value={startValue}
mode={mode[0]} mode={sMode[0]}
placeholder={placeholder1} placeholder={placeholder1}
onInputSelect={this.onStartInputSelect} onInputSelect={this.onStartInputSelect}
onValueChange={this.onStartValueChange} onValueChange={this.onStartValueChange}
@ -557,19 +544,19 @@ const RangeCalendar = createReactClass({
timePicker={timePicker} timePicker={timePicker}
showTimePicker={showTimePicker} showTimePicker={showTimePicker}
enablePrev enablePrev
enableNext={!isClosestMonths || this.isMonthYearPanelShow(mode[1])} enableNext={!isClosestMonths || this.isMonthYearPanelShow(sMode[1])}
/> />
<span className={`${prefixCls}-range-middle`}>~</span> <span class={`${prefixCls}-range-middle`}>~</span>
<CalendarPart <CalendarPart
{...props} {...baseProps}
{...newProps} {...newProps}
hoverValue={hoverValue} hoverValue={sHoverValue}
direction='right' direction='right'
format={this.getFormat()} format={this.getFormat()}
timePickerDisabledTime={this.getEndDisableTime()} timePickerDisabledTime={this.getEndDisableTime()}
placeholder={placeholder2} placeholder={placeholder2}
value={endValue} value={endValue}
mode={mode[1]} mode={sMode[1]}
onInputSelect={this.onEndInputSelect} onInputSelect={this.onEndInputSelect}
onValueChange={this.onEndValueChange} onValueChange={this.onEndValueChange}
onPanelChange={this.onEndPanelChange} onPanelChange={this.onEndPanelChange}
@ -578,37 +565,37 @@ const RangeCalendar = createReactClass({
showTimePicker={showTimePicker} showTimePicker={showTimePicker}
disabledTime={this.disabledEndTime} disabledTime={this.disabledEndTime}
disabledMonth={this.disabledEndMonth} disabledMonth={this.disabledEndMonth}
enablePrev={!isClosestMonths || this.isMonthYearPanelShow(mode[0])} enablePrev={!isClosestMonths || this.isMonthYearPanelShow(sMode[0])}
enableNext enableNext
/> />
</div> </div>
<div className={cls}> <div class={cls}>
{props.renderFooter()} {props.renderFooter()}
{showToday || props.timePicker || showOkButton ? ( {showToday || props.timePicker || showOkButton ? (
<div className={`${prefixCls}-footer-btn`}> <div class={`${prefixCls}-footer-btn`}>
{showToday ? ( {showToday ? (
<TodayButton <TodayButton
{...props} {...baseProps}
disabled={isTodayInView} disabled={isTodayInView}
value={state.value[0]} value={sValue[0]}
onToday={this.onToday} onToday={this.onToday}
text={locale.backToToday} text={locale.backToToday}
/> />
) : null} ) : null}
{props.timePicker {props.timePicker
? <TimePickerButton ? <TimePickerButton
{...props} {...baseProps}
showTimePicker={showTimePicker} showTimePicker={showTimePicker}
onOpenTimePicker={this.onOpenTimePicker} onOpenTimePicker={this.onOpenTimePicker}
onCloseTimePicker={this.onCloseTimePicker} onCloseTimePicker={this.onCloseTimePicker}
timePickerDisabled={!this.hasSelectedValue() || hoverValue.length} timePickerDisabled={!this.hasSelectedValue() || sHoverValue.length}
/> : null} /> : null}
{showOkButton {showOkButton
? <OkButton ? <OkButton
{...props} {...baseProps}
onOk={this.onOk} onOk={this.onOk}
okDisabled={!this.isAllowedDateAndTime(selectedValue) || okDisabled={!this.isAllowedDateAndTime(sSelectedValue) ||
!this.hasSelectedValue() || hoverValue.length !this.hasSelectedValue() || sHoverValue.length
} }
/> : null} /> : null}
</div> </div>
@ -618,7 +605,7 @@ const RangeCalendar = createReactClass({
</div> </div>
) )
}, },
}) }
export default RangeCalendar export default RangeCalendar
</script> </script>

View File

@ -19,6 +19,11 @@ const CalendarFooter = {
value: PropTypes.object, value: PropTypes.object,
renderFooter: PropTypes.func, renderFooter: PropTypes.func,
defaultValue: PropTypes.object, defaultValue: PropTypes.object,
locale: PropTypes.object,
showToday: PropTypes.bool.def(true),
disabledDate: PropTypes.func,
showTimePicker: PropTypes.bool,
okDisabled: PropTypes.bool,
}, },
methods: { methods: {
onSelect (value) { onSelect (value) {
@ -44,16 +49,17 @@ const CalendarFooter = {
}, },
on: $listeners, on: $listeners,
} }
let nowEl console.log(props)
let nowEl = null
if (showToday) { if (showToday) {
nowEl = <TodayButton {...btnProps} /> nowEl = <TodayButton {...btnProps} />
} }
delete btnProps.props.value delete btnProps.props.value
let okBtn let okBtn = null
if (showOk === true || showOk !== false && !!timePicker) { if (showOk === true || showOk !== false && !!timePicker) {
okBtn = <OkButton {...btnProps} /> okBtn = <OkButton {...btnProps} />
} }
let timePickerBtn let timePickerBtn = null
if (timePicker) { if (timePicker) {
timePickerBtn = <TimePickerButton {...btnProps} /> timePickerBtn = <TimePickerButton {...btnProps} />
} }
@ -61,7 +67,7 @@ const CalendarFooter = {
let footerBtn let footerBtn
if (nowEl || timePickerBtn || okBtn) { if (nowEl || timePickerBtn || okBtn) {
footerBtn = (<span class={`${prefixCls}-footer-btn`}> footerBtn = (<span class={`${prefixCls}-footer-btn`}>
{[nowEl, timePickerBtn, okBtn]} {nowEl}{timePickerBtn}{okBtn}
</span>) </span>)
} }
const cls = { const cls = {

View File

@ -5,7 +5,7 @@ import { getOptionProps } from '@/components/_util/props-util'
import MonthPanel from '../month/MonthPanel' import MonthPanel from '../month/MonthPanel'
import YearPanel from '../year/YearPanel' import YearPanel from '../year/YearPanel'
import DecadePanel from '../decade/DecadePanel' import DecadePanel from '../decade/DecadePanel'
function noop () {}
function goMonth (direction) { function goMonth (direction) {
const next = this.value.clone() const next = this.value.clone()
next.add(direction, 'months') next.add(direction, 'months')
@ -75,7 +75,7 @@ const CalendarHeader = {
const year = (<a const year = (<a
class={`${prefixCls}-year-select`} class={`${prefixCls}-year-select`}
role='button' role='button'
onClick={showTimePicker ? null : () => this.showYearPanel('date')} onClick={showTimePicker ? noop : () => this.showYearPanel('date')}
title={locale.yearSelect} title={locale.yearSelect}
> >
{value.format(locale.yearFormat)} {value.format(locale.yearFormat)}
@ -83,7 +83,7 @@ const CalendarHeader = {
const month = (<a const month = (<a
class={`${prefixCls}-month-select`} class={`${prefixCls}-month-select`}
role='button' role='button'
onClick={showTimePicker ? null : this.showMonthPanel} onClick={showTimePicker ? noop : this.showMonthPanel}
title={locale.monthSelect} title={locale.monthSelect}
> >
{locale.monthFormat ? value.format(locale.monthFormat) : localeData.monthsShort(value)} {locale.monthFormat ? value.format(locale.monthFormat) : localeData.monthsShort(value)}

View File

@ -2,11 +2,12 @@
function noop () {} function noop () {}
export default { export default {
functional: true, functional: true,
render: function (createElement, context) { render: function (h, context) {
const { data, listeners = {}} = context const { props, listeners = {}} = context
console.log(context)
const { const {
prefixCls, locale, showTimePicker, prefixCls, locale, showTimePicker,
timePickerDisabled } = data timePickerDisabled } = props
const { closeTimePicker = noop, openTimePicker = noop } = listeners const { closeTimePicker = noop, openTimePicker = noop } = listeners
const className = { const className = {
[`${prefixCls}-time-picker-btn`]: true, [`${prefixCls}-time-picker-btn`]: true,
@ -16,13 +17,11 @@ export default {
if (!timePickerDisabled) { if (!timePickerDisabled) {
onClick = showTimePicker ? closeTimePicker : openTimePicker onClick = showTimePicker ? closeTimePicker : openTimePicker
} }
return (<a return (
class={className} <a class={className} role='button' onClick={onClick}>
role='button' {showTimePicker ? locale.dateSelect : locale.timeSelect}
onClick={onClick} </a>
> )
{showTimePicker ? locale.dateSelect : locale.timeSelect}
</a>)
}, },
} }

View File

@ -4,7 +4,7 @@ function noop () {}
export default { export default {
functional: true, functional: true,
render (createElement, context) { render (createElement, context) {
const { data, listeners = {}} = context const { props, listeners = {}} = context
const { const {
prefixCls, prefixCls,
locale, locale,
@ -14,7 +14,7 @@ export default {
disabledDate, disabledDate,
// onToday, // onToday,
text, text,
} = data } = props
const { today = noop } = listeners const { today = noop } = listeners
const localeNow = (!text && timePicker ? locale.now : text) || locale.today const localeNow = (!text && timePicker ? locale.now : text) || locale.today
const disabledToday = const disabledToday =

View File

@ -4,7 +4,7 @@ import { getOptionProps } from '@/components/_util/props-util'
import cx from 'classnames' import cx from 'classnames'
import DateConstants from './DateConstants' import DateConstants from './DateConstants'
import { getTitleString, getTodayTime } from '../util/' import { getTitleString, getTodayTime } from '../util/'
function noop () {}
function isSameDay (one, two) { function isSameDay (one, two) {
return one && two && one.isSame(two, 'day') return one && two && one.isSame(two, 'day')
} }
@ -35,7 +35,7 @@ const DateTBody = {
dateRender: PropTypes.func, dateRender: PropTypes.func,
disabledDate: PropTypes.func, disabledDate: PropTypes.func,
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
selectedValue: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]), selectedValue: PropTypes.oneOfType([PropTypes.any, PropTypes.arrayOf(PropTypes.any)]),
value: PropTypes.object, value: PropTypes.object,
hoverValue: PropTypes.any.def([]), hoverValue: PropTypes.any.def([]),
showWeekNumber: PropTypes.bool, showWeekNumber: PropTypes.bool,
@ -48,6 +48,9 @@ const DateTBody = {
showWeekNumber, dateRender, disabledDate, showWeekNumber, dateRender, disabledDate,
hoverValue, hoverValue,
} = props } = props
console.log('selectedValue', selectedValue)
const { $listeners = {}} = this
const { select = noop, dayHover = noop } = $listeners
let iIndex let iIndex
let jIndex let jIndex
let current let current
@ -208,9 +211,9 @@ const DateTBody = {
dateCells.push( dateCells.push(
<td <td
key={passed} key={passed}
onClick={disabled ? undefined : props.onSelect.bind(null, current)} onClick={disabled ? noop : select.bind(null, current)}
onMouseenter={disabled onMouseenter={disabled
? undefined : props.onDayHover && props.onDayHover.bind(null, current) || undefined} ? noop : dayHover.bind(null, current)}
role='gridcell' role='gridcell'
title={getTitleString(current)} class={cls} title={getTitleString(current)} class={cls}
> >

View File

@ -5,15 +5,15 @@ import DateTBody from './DateTBody'
export default { export default {
functional: true, functional: true,
render (createElement, context) { render (createElement, context) {
const { data, listeners = {}} = context const { props, listeners = {}} = context
const prefixCls = data.prefixCls const prefixCls = props.prefixCls
const props = { const bodyProps = {
props: data, props,
on: listeners, on: listeners,
} }
return (<table class = {`${prefixCls}-table`} cellSpacing='0' role='grid'> return (<table class = {`${prefixCls}-table`} cellSpacing='0' role='grid'>
<DateTHead {...props}/> <DateTHead {...props}/>
<DateTBody {...props}/> <DateTBody {...bodyProps}/>
</table>) </table>)
}, },
} }

View File

@ -56,7 +56,7 @@ const CalendarMixin = {
}, },
renderRoot (newProps) { renderRoot (newProps) {
const props = this.props const props = this.$props
const prefixCls = props.prefixCls const prefixCls = props.prefixCls
const className = { const className = {

View File

@ -6,7 +6,7 @@ export default {
locale: PropTypes.object.def(enUs), locale: PropTypes.object.def(enUs),
visible: PropTypes.bool.def(true), visible: PropTypes.bool.def(true),
// onSelect: PropTypes.func, // onSelect: PropTypes.func,
prefixCls: PropTypes.string.def('rc-calendat'), prefixCls: PropTypes.string.def('rc-calendar'),
// onChange: PropTypes.func, // onChange: PropTypes.func,
// onOk: PropTypes.func, // onOk: PropTypes.func,
}, },

View File

@ -3,7 +3,7 @@ const AsyncComp = () => {
const hashs = window.location.hash.split('/') const hashs = window.location.hash.split('/')
const d = hashs[hashs.length - 1] const d = hashs[hashs.length - 1]
return { return {
component: import(`../components/pagination/demo/${d}`), component: import(`../components/vc-calendar/demo/${d}`),
} }
} }
export default [ export default [