]> git.immae.eu Git - github/fretlink/time-picker.git/blobdiff - src/TimePicker.jsx
fix 0.15 warning
[github/fretlink/time-picker.git] / src / TimePicker.jsx
index e82b46fe0480174daac66eb8de49b01689d607d0..350eeb2e223fe39def3236dc524c1d0c3e40b89f 100644 (file)
@@ -1,10 +1,9 @@
-import React, {PropTypes} from 'react';
-import ReactDOM from 'react-dom';
+import React, { PropTypes } from 'react';
 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 { getFormatter } from './util/index';
 
 function noop() {
 }
@@ -16,21 +15,27 @@ function refFn(field, component) {
 const Picker = React.createClass({
   propTypes: {
     prefixCls: PropTypes.string,
-    inputClassName: PropTypes.string,
     locale: PropTypes.object,
     value: PropTypes.object,
-    children: PropTypes.func,
     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,
+    formatter: PropTypes.any,
+    showHour: PropTypes.bool,
+    style: PropTypes.object,
+    className: PropTypes.string,
+    showSecond: PropTypes.bool,
+    disabledHours: PropTypes.func,
+    disabledMinutes: PropTypes.func,
+    disabledSeconds: PropTypes.func,
+    hideDisabledOptions: PropTypes.bool,
     onChange: PropTypes.func,
     onOpen: PropTypes.func,
     onClose: PropTypes.func,
@@ -40,8 +45,17 @@ const Picker = React.createClass({
 
   getDefaultProps() {
     return {
-      open: false,
+      defaultOpen: false,
+      style: {},
+      className: '',
       align: {},
+      allowEmpty: true,
+      showHour: true,
+      showSecond: true,
+      disabledHours: noop,
+      disabledMinutes: noop,
+      disabledSeconds: noop,
+      hideDisabledOptions: false,
       placement: 'bottomLeft',
       onChange: noop,
       onOpen: noop,
@@ -51,22 +65,22 @@ const Picker = React.createClass({
 
   getInitialState() {
     this.savePanelRef = refFn.bind(this, 'panelInstance');
-    const { open, defaultValue, value } = this.props;
+    const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = this.props;
     return {
-      open: open,
-      value: value || defaultValue,
+      open,
+      value,
     };
   },
 
   componentWillReceiveProps(nextProps) {
     const { value, open } = nextProps;
-    if (value !== undefined) {
+    if ('value' in nextProps) {
       this.setState({
         value,
       });
     }
     if (open !== undefined) {
-      this.setState({open});
+      this.setState({ open });
     }
   },
 
@@ -80,12 +94,18 @@ const Picker = React.createClass({
   },
 
   onVisibleChange(open) {
-    this.setOpen(open, () => {
-      if (open) {
-        ReactDOM.findDOMNode(this.refs.picker).blur();
-        ReactDOM.findDOMNode(this.panelInstance).focus();
-      }
-    });
+    this.setOpen(open);
+  },
+
+  onEsc() {
+    this.setOpen(false);
+    this.refs.picker.focus();
+  },
+
+  onKeyDown(e) {
+    if (e.keyCode === 40) {
+      this.setOpen(true);
+    }
   },
 
   setValue(value) {
@@ -97,42 +117,73 @@ const Picker = React.createClass({
     this.props.onChange(value);
   },
 
-  getPanel() {
-    const { prefixCls, defaultValue, locale, formatter, placeholder, hourOptions, minuteOptions, secondOptions } = this.props;
+  getFormatter() {
+    const formatter = this.props.formatter;
+    const locale = this.props.locale;
+    if (formatter) {
+      if (formatter === this.lastFormatter) {
+        return this.normalFormatter;
+      }
+      this.normalFormatter = getFormatter(formatter, locale);
+      this.lastFormatter = formatter;
+      return this.normalFormatter;
+    }
+    if (!this.props.showSecond) {
+      if (!this.notShowSecondFormatter) {
+        this.notShowSecondFormatter = getFormatter('HH:mm', locale);
+      }
+      return this.notShowSecondFormatter;
+    }
+    if (!this.props.showHour) {
+      if (!this.notShowHourFormatter) {
+        this.notShowHourFormatter = getFormatter('mm:ss', locale);
+      }
+      return this.notShowHourFormatter;
+    }
+    if (!this.normalFormatter) {
+      this.normalFormatter = getFormatter('HH:mm:ss', locale);
+    }
+    return this.normalFormatter;
+  },
+
+  getPanelElement() {
+    const {
+      prefixCls, defaultValue, locale, placeholder, disabledHours,
+      disabledMinutes, disabledSeconds, hideDisabledOptions,
+      allowEmpty, showHour, showSecond,
+    } = this.props;
     return (
       <Panel
-        prefixCls={prefixCls}
+        prefixCls={`${prefixCls}-panel`}
+        ref={this.savePanelRef}
+        value={this.state.value}
+        onChange={this.onPanelChange}
+        gregorianCalendarLocale={locale.calendar}
+        onClear={this.onPanelClear}
         defaultValue={defaultValue}
+        showHour={showHour}
+        onEsc={this.onEsc}
+        showSecond={showSecond}
         locale={locale}
-        formatter={formatter}
+        allowEmpty={allowEmpty}
+        formatter={this.getFormatter()}
         placeholder={placeholder}
-        hourOptions={hourOptions}
-        minuteOptions={minuteOptions}
-        secondOptions={secondOptions}
+        disabledHours={disabledHours}
+        disabledMinutes={disabledMinutes}
+        disabledSeconds={disabledSeconds}
+        hideDisabledOptions={hideDisabledOptions}
       />
     );
   },
 
-  getPanelElement() {
-    const panel = this.getPanel();
-    const extraProps = {
-      ref: this.savePanelRef,
-      value: this.state.value,
-      onChange: createChainedFunction(panel.props.onChange, this.onPanelChange),
-      onClear: createChainedFunction(panel.props.onClear, this.onPanelClear),
-    };
-
-    return React.cloneElement(panel, extraProps);
-  },
-
   setOpen(open, callback) {
-    const {onOpen, onClose} = this.props;
+    const { onOpen, onClose } = this.props;
     if (this.state.open !== open) {
       this.setState({
-        open: open,
+        open,
       }, callback);
       const event = {
-        open: open,
+        open,
       };
       if (open) {
         onOpen(event);
@@ -143,25 +194,35 @@ const Picker = React.createClass({
   },
 
   render() {
-    const { prefixCls, placeholder, placement, align, disabled, transitionName, formatter, inputClassName } = this.props;
+    const { prefixCls, placeholder, placement, align, disabled, transitionName, style, className, showHour, showSecond, getPopupContainer } = this.props;
     const { open, value } = this.state;
-
+    let popupClassName;
+    if (!showHour || !showSecond) {
+      popupClassName = `${prefixCls}-panel-narrow`;
+    }
     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}`}>
-          <input className={inputClassName} ref="picker" type="text" placeholder={placeholder} readOnly
-                 disabled={disabled} value={value && formatter.format(value)}/>
+        <span className={`${prefixCls} ${className}`} style={style}>
+          <input
+            className={`${prefixCls}-input`}
+            ref="picker" type="text" placeholder={placeholder}
+            readOnly
+            onKeyDown={this.onKeyDown}
+            disabled={disabled} value={value && this.getFormatter().format(value) || ''}
+          />
           <span className={`${prefixCls}-icon`}/>
         </span>
       </Trigger>