X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=src%2FTimePicker.jsx;h=271515da4af3973ac5ed0486c3bbc1f1e8948a6d;hb=2fb27d673619b7bdd70178e617965a009fa72874;hp=98a175480feb2c4850eeeb3f22329185a5a32fcc;hpb=e75ed0c6b89282cf475e94d6d5ad0fb35803f974;p=github%2Ffretlink%2Ftime-picker.git diff --git a/src/TimePicker.jsx b/src/TimePicker.jsx index 98a1754..271515d 100644 --- a/src/TimePicker.jsx +++ b/src/TimePicker.jsx @@ -1,10 +1,9 @@ -import React, {PropTypes} from 'react'; -import ReactDOM from 'react-dom'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import Trigger from 'rc-trigger'; -import {createChainedFunction} from 'rc-util'; -import Panel from './module/Panel'; -import placements from './util/placements'; -import CommonMixin from './mixin/CommonMixin'; +import Panel from './Panel'; +import placements from './placements'; +import moment from 'moment'; function noop() { } @@ -13,152 +12,268 @@ function refFn(field, component) { this[field] = component; } -const Picker = React.createClass({ - propTypes: { +export default class Picker extends Component { + static propTypes = { prefixCls: PropTypes.string, - inputClassName: PropTypes.string, - locale: PropTypes.object, - children: PropTypes.func, + clearText: PropTypes.string, + value: PropTypes.object, + defaultOpenValue: PropTypes.object, 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, - formatter: PropTypes.object, - hourOptions: PropTypes.array, - minuteOptions: PropTypes.array, - secondOptions: PropTypes.array, + 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, - }, - - mixins: [CommonMixin], - - getDefaultProps() { - return { - open: false, - align: {}, - placement: 'bottomLeft', - onChange: noop, - onOpen: noop, - onClose: noop, - }; - }, + onFocus: PropTypes.func, + onBlur: PropTypes.func, + addon: PropTypes.func, + name: PropTypes.string, + autoComplete: PropTypes.string, + use12Hours: PropTypes.bool, + onKeyDown: PropTypes.func, + }; + + static defaultProps = { + clearText: 'clear', + prefixCls: 'rc-time-picker', + defaultOpen: 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, + onKeyDown: noop, + }; - getInitialState() { + constructor(props) { + super(props); + this.saveInputRef = refFn.bind(this, 'picker'); this.savePanelRef = refFn.bind(this, 'panelInstance'); - const { open, defaultValue } = this.props; - return { - open: open, - value: defaultValue, + const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = props; + this.state = { + open, + value, }; - }, + } componentWillReceiveProps(nextProps) { - const { defaultValue, open } = nextProps; - if (defaultValue !== undefined) { - this.setState({value: defaultValue}); + const { value, open } = nextProps; + if ('value' in nextProps) { + this.setState({ + value, + }); } if (open !== undefined) { - this.setState({open}); + this.setState({ open }); } - }, + } - onPanelChange(value) { - this.setState({ - value: value, - }); - this.props.onChange(value); - }, + onPanelChange = (value) => { + this.setValue(value); + } - onPanelClear() { - this.setState({ - value: '', - }); + onPanelClear = () => { + this.setValue(null); this.setOpen(false); - }, + } - onVisibleChange(open) { - this.setOpen(open, () => { - if (open) { - ReactDOM.findDOMNode(this.refs.picker).blur(); - ReactDOM.findDOMNode(this.panelInstance).focus(); - } - }); - }, + 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); + } - getPanel() { - const { prefixCls, defaultValue, locale, formatter, placeholder, hourOptions, minuteOptions, secondOptions } = this.props; + 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, + allowEmpty, showHour, showMinute, showSecond, defaultOpenValue, clearText, + addon, use12Hours, onKeyDown, + } = this.props; return ( ); - }, + } - getPanelElement() { - const panel = this.getPanel(); - const extraProps = { - ref: this.savePanelRef, - defaultValue: this.state.value || panel.props.defaultValue, - onChange: createChainedFunction(panel.props.onChange, this.onPanelChange), - onClear: createChainedFunction(panel.props.onClear, this.onPanelClear), - }; - - return React.cloneElement(panel, extraProps); - }, + 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, callback) { - const {onOpen, onClose} = this.props; + setOpen(open) { + const { onOpen, onClose } = this.props; if (this.state.open !== open) { - this.setState({ - open: open, - }, callback); - const event = { - open: open, - }; + if (!('open' in this.props)) { + this.setState({ open }); + } if (open) { - onOpen(event); + onOpen({ open }); } else { - onClose(event); + onClose({ open }); } } - }, + } + + focus() { + this.picker.focus(); + } render() { - const { prefixCls, placeholder, placement, align, disabled, transitionName, children, formatter, inputClassName } = this.props; + const { + prefixCls, placeholder, placement, align, + disabled, transitionName, style, className, getPopupContainer, name, autoComplete, + onFocus, onBlur, + } = this.props; const { open, value } = this.state; - + const popupClassName = this.getPopupClassName(); return ( - - - + + + ); - }, -}); - -export default Picker; + } +}