ant-design-vue/components/vc-time-picker/TimePicker.vue

300 lines
7.5 KiB
Vue

<script>
import PropTypes from 'prop-types'
import Trigger from 'rc-trigger'
import Panel from './Panel'
import placements from './placements'
import moment from 'moment'
function noop () {
}
function refFn (field, component) {
this[field] = component
}
export default class Picker extends Component {
static propTypes = {
prefixCls: PropTypes.string,
clearText: PropTypes.string,
value: PropTypes.object,
defaultOpenValue: PropTypes.object,
inputReadOnly: PropTypes.bool,
disabled: PropTypes.bool,
allowEmpty: PropTypes.bool,
defaultValue: PropTypes.object,
open: PropTypes.bool,
defaultOpen: PropTypes.bool,
align: PropTypes.object,
placement: PropTypes.any,
transitionName: PropTypes.string,
getPopupContainer: PropTypes.func,
placeholder: PropTypes.string,
format: PropTypes.string,
showHour: PropTypes.bool,
showMinute: PropTypes.bool,
showSecond: PropTypes.bool,
style: PropTypes.object,
className: PropTypes.string,
popupClassName: PropTypes.string,
disabledHours: PropTypes.func,
disabledMinutes: PropTypes.func,
disabledSeconds: PropTypes.func,
hideDisabledOptions: PropTypes.bool,
onChange: PropTypes.func,
onOpen: PropTypes.func,
onClose: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
addon: PropTypes.func,
name: PropTypes.string,
autoComplete: PropTypes.string,
use12Hours: PropTypes.bool,
hourStep: PropTypes.number,
minuteStep: PropTypes.number,
secondStep: PropTypes.number,
focusOnOpen: PropTypes.bool,
onKeyDown: PropTypes.func,
autoFocus: PropTypes.bool,
};
static defaultProps = {
clearText: 'clear',
prefixCls: 'rc-time-picker',
defaultOpen: false,
inputReadOnly: false,
style: {},
className: '',
popupClassName: '',
align: {},
defaultOpenValue: moment(),
allowEmpty: true,
showHour: true,
showMinute: true,
showSecond: true,
disabledHours: noop,
disabledMinutes: noop,
disabledSeconds: noop,
hideDisabledOptions: false,
placement: 'bottomLeft',
onChange: noop,
onOpen: noop,
onClose: noop,
onFocus: noop,
onBlur: noop,
addon: noop,
use12Hours: false,
focusOnOpen: false,
onKeyDown: noop,
};
constructor (props) {
super(props)
this.saveInputRef = refFn.bind(this, 'picker')
this.savePanelRef = refFn.bind(this, 'panelInstance')
const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = props
this.state = {
open,
value,
}
}
componentWillReceiveProps (nextProps) {
const { value, open } = nextProps
if ('value' in nextProps) {
this.setState({
value,
})
}
if (open !== undefined) {
this.setState({ open })
}
}
onPanelChange = (value) => {
this.setValue(value)
}
onPanelClear = () => {
this.setValue(null)
this.setOpen(false)
}
onVisibleChange = (open) => {
this.setOpen(open)
}
onEsc = () => {
this.setOpen(false)
this.focus()
}
onKeyDown = (e) => {
if (e.keyCode === 40) {
this.setOpen(true)
}
}
setValue (value) {
if (!('value' in this.props)) {
this.setState({
value,
})
}
this.props.onChange(value)
}
getFormat () {
const { format, showHour, showMinute, showSecond, use12Hours } = this.props
if (format) {
return format
}
if (use12Hours) {
const fmtString = ([
showHour ? 'h' : '',
showMinute ? 'mm' : '',
showSecond ? 'ss' : '',
].filter(item => !!item).join(':'))
return fmtString.concat(' a')
}
return [
showHour ? 'HH' : '',
showMinute ? 'mm' : '',
showSecond ? 'ss' : '',
].filter(item => !!item).join(':')
}
getPanelElement () {
const {
prefixCls, placeholder, disabledHours,
disabledMinutes, disabledSeconds, hideDisabledOptions, inputReadOnly,
allowEmpty, showHour, showMinute, showSecond, defaultOpenValue, clearText,
addon, use12Hours, focusOnOpen, onKeyDown, hourStep, minuteStep, secondStep,
} = this.props
return (
<Panel
clearText={clearText}
prefixCls={`${prefixCls}-panel`}
ref={this.savePanelRef}
value={this.state.value}
inputReadOnly={inputReadOnly}
onChange={this.onPanelChange}
onClear={this.onPanelClear}
defaultOpenValue={defaultOpenValue}
showHour={showHour}
showMinute={showMinute}
showSecond={showSecond}
onEsc={this.onEsc}
allowEmpty={allowEmpty}
format={this.getFormat()}
placeholder={placeholder}
disabledHours={disabledHours}
disabledMinutes={disabledMinutes}
disabledSeconds={disabledSeconds}
hideDisabledOptions={hideDisabledOptions}
use12Hours={use12Hours}
hourStep={hourStep}
minuteStep={minuteStep}
secondStep={secondStep}
addon={addon}
focusOnOpen={focusOnOpen}
onKeyDown={onKeyDown}
/>
)
}
getPopupClassName () {
const { showHour, showMinute, showSecond, use12Hours, prefixCls } = this.props
let popupClassName = this.props.popupClassName
// Keep it for old compatibility
if ((!showHour || !showMinute || !showSecond) && !use12Hours) {
popupClassName += ` ${prefixCls}-panel-narrow`
}
let selectColumnCount = 0
if (showHour) {
selectColumnCount += 1
}
if (showMinute) {
selectColumnCount += 1
}
if (showSecond) {
selectColumnCount += 1
}
if (use12Hours) {
selectColumnCount += 1
}
popupClassName += ` ${prefixCls}-panel-column-${selectColumnCount}`
return popupClassName
}
setOpen (open) {
const { onOpen, onClose } = this.props
if (this.state.open !== open) {
if (!('open' in this.props)) {
this.setState({ open })
}
if (open) {
onOpen({ open })
} else {
onClose({ open })
}
}
}
focus () {
this.picker.focus()
}
blur () {
this.picker.blur()
}
render () {
const {
prefixCls, placeholder, placement, align,
disabled, transitionName, style, className, getPopupContainer, name, autoComplete,
onFocus, onBlur, autoFocus, inputReadOnly,
} = this.props
const { open, value } = this.state
const popupClassName = this.getPopupClassName()
return (
<Trigger
prefixCls={`${prefixCls}-panel`}
popupClassName={popupClassName}
popup={this.getPanelElement()}
popupAlign={align}
builtinPlacements={placements}
popupPlacement={placement}
action={disabled ? [] : ['click']}
destroyPopupOnHide
getPopupContainer={getPopupContainer}
popupTransitionName={transitionName}
popupVisible={open}
onPopupVisibleChange={this.onVisibleChange}
>
<span className={`${prefixCls} ${className}`} style={style}>
<input
className={`${prefixCls}-input`}
ref={this.saveInputRef}
type='text'
placeholder={placeholder}
name={name}
onKeyDown={this.onKeyDown}
disabled={disabled}
value={value && value.format(this.getFormat()) || ''}
autoComplete={autoComplete}
onFocus={onFocus}
onBlur={onBlur}
autoFocus={autoFocus}
onChange={noop}
readOnly={!!inputReadOnly}
/>
<span className={`${prefixCls}-icon`}/>
</span>
</Trigger>
)
}
}
</script>