227 lines
5.9 KiB
Vue
227 lines
5.9 KiB
Vue
|
|
import * as moment from 'moment'
|
|
import VcTimePicker from '../vc-time-picker'
|
|
import LocaleReceiver from '../locale-provider/LocaleReceiver'
|
|
import defaultLocale from './locale/en_US'
|
|
import BaseMixin from '../_util/BaseMixin'
|
|
import PropTypes from '../_util/vue-types'
|
|
import Icon from '../icon'
|
|
import interopDefault from '../_util/interopDefault'
|
|
import { initDefaultProps, hasProp, getOptionProps, getComponentFromProp, isValidElement } from '../_util/props-util'
|
|
import { cloneElement } from '../_util/vnode'
|
|
|
|
export function generateShowHourMinuteSecond (format) {
|
|
// Ref: http://momentjs.com/docs/#/parsing/string-format/
|
|
return {
|
|
showHour: (
|
|
format.indexOf('H') > -1 ||
|
|
format.indexOf('h') > -1 ||
|
|
format.indexOf('k') > -1
|
|
),
|
|
showMinute: format.indexOf('m') > -1,
|
|
showSecond: format.indexOf('s') > -1,
|
|
}
|
|
}
|
|
function isMoment (value) {
|
|
if (Array.isArray(value)) {
|
|
return value.length === 0 || value.findIndex((val) => val === undefined || moment.isMoment(val)) !== -1
|
|
} else {
|
|
return value === undefined || moment.isMoment(value)
|
|
}
|
|
}
|
|
const MomentType = PropTypes.custom(isMoment)
|
|
export const TimePickerProps = () => ({
|
|
size: PropTypes.oneOf(['large', 'default', 'small']),
|
|
value: MomentType,
|
|
defaultValue: MomentType,
|
|
open: PropTypes.bool,
|
|
format: PropTypes.string,
|
|
disabled: PropTypes.bool,
|
|
placeholder: PropTypes.string,
|
|
prefixCls: PropTypes.string,
|
|
hideDisabledOptions: PropTypes.bool,
|
|
disabledHours: PropTypes.func,
|
|
disabledMinutes: PropTypes.func,
|
|
disabledSeconds: PropTypes.func,
|
|
getPopupContainer: PropTypes.func,
|
|
use12Hours: PropTypes.bool,
|
|
focusOnOpen: PropTypes.bool,
|
|
hourStep: PropTypes.number,
|
|
minuteStep: PropTypes.number,
|
|
secondStep: PropTypes.number,
|
|
allowEmpty: PropTypes.bool,
|
|
inputReadOnly: PropTypes.bool,
|
|
clearText: PropTypes.string,
|
|
defaultOpenValue: PropTypes.object,
|
|
popupClassName: PropTypes.string,
|
|
suffixIcon: PropTypes.any,
|
|
align: PropTypes.object,
|
|
placement: PropTypes.any,
|
|
transitionName: PropTypes.string,
|
|
autoFocus: PropTypes.bool,
|
|
addon: PropTypes.any,
|
|
})
|
|
|
|
const TimePicker = {
|
|
name: 'ATimePicker',
|
|
mixins: [BaseMixin],
|
|
props: initDefaultProps(TimePickerProps(), {
|
|
prefixCls: 'ant-time-picker',
|
|
align: {
|
|
offset: [0, -2],
|
|
},
|
|
disabled: false,
|
|
disabledHours: undefined,
|
|
disabledMinutes: undefined,
|
|
disabledSeconds: undefined,
|
|
hideDisabledOptions: false,
|
|
placement: 'bottomLeft',
|
|
transitionName: 'slide-up',
|
|
focusOnOpen: true,
|
|
}),
|
|
model: {
|
|
prop: 'value',
|
|
event: 'change',
|
|
},
|
|
data () {
|
|
const value = this.value || this.defaultValue
|
|
if (value && !interopDefault(moment).isMoment(value)) {
|
|
throw new Error(
|
|
'The value/defaultValue of TimePicker must be a moment object, ',
|
|
)
|
|
}
|
|
return {
|
|
sValue: value,
|
|
}
|
|
},
|
|
watch: {
|
|
value (val) {
|
|
this.setState({ sValue: val })
|
|
},
|
|
},
|
|
methods: {
|
|
handleChange (value) {
|
|
if (!hasProp(this, 'value')) {
|
|
this.setState({ sValue: value })
|
|
}
|
|
const { format = 'HH:mm:ss' } = this
|
|
this.$emit('change', value, (value && value.format(format)) || '')
|
|
},
|
|
|
|
handleOpenClose ({ open }) {
|
|
this.$emit('openChange', open)
|
|
this.$emit('update:open', open)
|
|
},
|
|
|
|
focus () {
|
|
this.$refs.timePicker.focus()
|
|
},
|
|
|
|
blur () {
|
|
this.$refs.timePicker.blur()
|
|
},
|
|
|
|
getDefaultFormat () {
|
|
const { format, use12Hours } = this
|
|
if (format) {
|
|
return format
|
|
} else if (use12Hours) {
|
|
return 'h:mm:ss a'
|
|
}
|
|
return 'HH:mm:ss'
|
|
},
|
|
|
|
renderTimePicker (locale) {
|
|
const props = getOptionProps(this)
|
|
delete props.defaultValue
|
|
|
|
const format = this.getDefaultFormat()
|
|
const className = {
|
|
[`${props.prefixCls}-${props.size}`]: !!props.size,
|
|
}
|
|
const tempAddon = getComponentFromProp(this, 'addon', {}, false)
|
|
const addon = (panel) => {
|
|
return tempAddon ? (
|
|
<div class={`${props.prefixCls}-panel-addon`}>
|
|
{typeof tempAddon === 'function' ? tempAddon(panel) : tempAddon}
|
|
</div>
|
|
) : null
|
|
}
|
|
const { prefixCls } = props
|
|
let suffixIcon = getComponentFromProp(this, 'suffixIcon')
|
|
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon
|
|
const clockIcon = suffixIcon && (
|
|
isValidElement(suffixIcon)
|
|
? cloneElement(
|
|
suffixIcon,
|
|
{
|
|
class: `${prefixCls}-clock-icon`,
|
|
},
|
|
) : <span class={`${prefixCls}-clock-icon`}>{suffixIcon}</span>) || (
|
|
<Icon
|
|
type='clock-circle'
|
|
class={`${prefixCls}-clock-icon`}
|
|
theme='outlined'
|
|
/>
|
|
)
|
|
|
|
const inputIcon = (
|
|
<span class={`${prefixCls}-icon`}>
|
|
{clockIcon}
|
|
</span>
|
|
)
|
|
|
|
const clearIcon = (
|
|
<Icon
|
|
type='close-circle'
|
|
class={`${prefixCls}-panel-clear-btn-icon`}
|
|
theme='filled'
|
|
/>
|
|
)
|
|
const timeProps = {
|
|
props: {
|
|
...generateShowHourMinuteSecond(format),
|
|
...props,
|
|
format,
|
|
value: this.sValue,
|
|
placeholder: props.placeholder === undefined ? locale.placeholder : props.placeholder,
|
|
addon,
|
|
inputIcon,
|
|
clearIcon,
|
|
},
|
|
class: className,
|
|
ref: 'timePicker',
|
|
on: {
|
|
...this.$listeners,
|
|
change: this.handleChange,
|
|
open: this.handleOpenClose,
|
|
close: this.handleOpenClose,
|
|
},
|
|
}
|
|
return (
|
|
<VcTimePicker {...timeProps}/>
|
|
)
|
|
},
|
|
},
|
|
|
|
render () {
|
|
return (
|
|
<LocaleReceiver
|
|
componentName='TimePicker'
|
|
defaultLocale={defaultLocale}
|
|
scopedSlots={
|
|
{ default: this.renderTimePicker }
|
|
}
|
|
/>
|
|
)
|
|
},
|
|
}
|
|
|
|
/* istanbul ignore next */
|
|
TimePicker.install = function (Vue) {
|
|
Vue.component(TimePicker.name, TimePicker)
|
|
}
|
|
|
|
export default TimePicker
|
|
|