diff --git a/README.md b/README.md
index e307c1f9..a970986a 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@ API
| showHour | Boolean | true | whether show hour | |
| showMinute | Boolean | true | whether show minute |
| showSecond | Boolean | true | whether show second |
-| format | String | - | moment format |
+| format | String or String[] | - | moment format |
| disabledHours | Function | - | disabled hour options |
| disabledMinutes | Function | - | disabled minute options |
| disabledSeconds | Function | - | disabled second options |
diff --git a/examples/multiFormat.html b/examples/multiFormat.html
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/multiFormat.js b/examples/multiFormat.js
new file mode 100644
index 00000000..3d1eab2a
--- /dev/null
+++ b/examples/multiFormat.js
@@ -0,0 +1,22 @@
+/* eslint no-console:0 */
+
+import 'rc-time-picker/assets/index.less';
+
+import React from 'react';
+import ReactDom from 'react-dom';
+
+import moment from 'moment';
+
+import TimePicker from 'rc-time-picker';
+
+const format = ['h:mm a', 'h:mm a', 'HH:mm a', 'h:mm', 'HH:mm', 'hhmm', 'HHmm'];
+
+const now = moment().hour(3).minute(0);
+
+ReactDom.render(
+ ,
+ document.getElementById('__react-content')
+);
diff --git a/rc-time-picker.d.ts b/rc-time-picker.d.ts
index c94a516b..33d10a39 100644
--- a/rc-time-picker.d.ts
+++ b/rc-time-picker.d.ts
@@ -1,43 +1,43 @@
-declare module "rc-time-picker" {
- import { Moment } from "moment";
- import * as React from "react";
+declare module 'rc-time-picker' {
+ import { Moment } from 'moment';
+ import * as React from 'react';
- type TimePickerProps = {
- prefixCls?: String;
- clearText?: String;
- disabled?: Boolean;
- allowEmpty?: Boolean;
- open?: Boolean;
- defaultValue?: Moment;
- defaultOpenValue?: Moment;
- value?: Moment;
- placeholder?: String;
- className?: String;
- id?: String;
- popupClassName?: String;
- showHour?: Boolean;
- showMinute?: Boolean;
- showSecond?: Boolean;
- format?: String;
- disabledHours?: Function;
- disabledMinutes?: Function;
- disabledSeconds?: Function;
- use12Hours?: Boolean;
- hideDisabledOptions?: Boolean;
- onChange?: Function;
- addon?: Function;
- placement?: String;
- transitionName?: String;
- name?: String;
- onOpen?: Function;
- onClose?: Function;
- hourStep?: Number;
- minuteStep?: Number;
- secondStep?: Number;
- focusOnOpen?: Boolean;
- inputReadOnly?: Boolean;
+ interface ITimePickerProps {
+ prefixCls?: string;
+ clearText?: string;
+ disabled?: boolean;
+ allowEmpty?: boolean;
+ open?: boolean;
+ defaultValue?: moment;
+ defaultOpenValue?: moment;
+ value?: moment;
+ placeholder?: string;
+ className?: string;
+ id?: string;
+ popupClassName?: string;
+ showHour?: boolean;
+ showMinute?: boolean;
+ showSecond?: boolean;
+ format?: string;
+ disabledHours?: function;
+ disabledMinutes?: function;
+ disabledSeconds?: function;
+ use12Hours?: boolean;
+ hideDisabledOptions?: boolean;
+ onChange?: function;
+ addon?: function;
+ placement?: string;
+ transitionName?: string;
+ name?: string;
+ onOpen?: function;
+ onClose?: function;
+ hourStep?: number;
+ minuteStep?: number;
+ secondStep?: number;
+ focusOnOpen?: boolean;
+ inputReadOnly?: noolean;
inputIcon?: React.ReactNode;
clearIcon?: React.ReactNode;
- };
+ }
export default class TimePicker extends React.Component {}
}
diff --git a/src/Combobox.jsx b/src/Combobox.jsx
index cb29161d..7979eb0b 100644
--- a/src/Combobox.jsx
+++ b/src/Combobox.jsx
@@ -1,6 +1,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Select from './Select';
+import { getTimeFormat } from './util';
const formatOption = (option, disabledOptions) => {
let value = `${option}`;
@@ -21,7 +22,7 @@ const formatOption = (option, disabledOptions) => {
class Combobox extends Component {
static propTypes = {
- format: PropTypes.string,
+ format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
defaultOpenValue: PropTypes.object,
prefixCls: PropTypes.string,
value: PropTypes.object,
@@ -172,13 +173,14 @@ class Combobox extends Component {
}
getAMPMSelect() {
- const { prefixCls, use12Hours, format, isAM } = this.props;
+ const { prefixCls, use12Hours, isAM, format } = this.props;
+ const timeFormat = getTimeFormat(format);
if (!use12Hours) {
return null;
}
const AMPMOptions = ['am', 'pm'] // If format has A char, then we should uppercase AM/PM
- .map(c => (format.match(/\sA/) ? c.toUpperCase() : c))
+ .map(c => (timeFormat.match(/\sA/) ? c.toUpperCase() : c))
.map(c => ({ value: c }));
const selected = isAM ? 0 : 1;
diff --git a/src/Header.jsx b/src/Header.jsx
index 03916bdf..f1fe051d 100644
--- a/src/Header.jsx
+++ b/src/Header.jsx
@@ -1,10 +1,11 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
+import { formatTime } from './util';
class Header extends Component {
static propTypes = {
- format: PropTypes.string,
+ format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
prefixCls: PropTypes.string,
disabledDate: PropTypes.func,
placeholder: PropTypes.string,
@@ -36,7 +37,7 @@ class Header extends Component {
super(props);
const { value, format } = props;
this.state = {
- str: (value && value.format(format)) || '',
+ str: formatTime(value, format),
invalid: false,
};
}
@@ -56,7 +57,7 @@ class Header extends Component {
componentWillReceiveProps(nextProps) {
const { value, format } = nextProps;
this.setState({
- str: (value && value.format(format)) || '',
+ str: formatTime(value, format),
invalid: false,
});
}
diff --git a/src/Panel.jsx b/src/Panel.jsx
index d57ee999..a27c453f 100644
--- a/src/Panel.jsx
+++ b/src/Panel.jsx
@@ -38,7 +38,7 @@ class Panel extends Component {
defaultOpenValue: PropTypes.object,
value: PropTypes.object,
placeholder: PropTypes.string,
- format: PropTypes.string,
+ format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
inputReadOnly: PropTypes.bool,
disabledHours: PropTypes.func,
disabledMinutes: PropTypes.func,
diff --git a/src/TimePicker.jsx b/src/TimePicker.jsx
index 47daa1f3..a60af3cc 100644
--- a/src/TimePicker.jsx
+++ b/src/TimePicker.jsx
@@ -5,6 +5,7 @@ import Trigger from 'rc-trigger';
import moment from 'moment';
import Panel from './Panel';
import placements from './placements';
+import { formatTime } from './util';
function noop() {}
@@ -29,7 +30,7 @@ export default class Picker extends Component {
transitionName: PropTypes.string,
getPopupContainer: PropTypes.func,
placeholder: PropTypes.string,
- format: PropTypes.string,
+ format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
showHour: PropTypes.bool,
showMinute: PropTypes.bool,
showSecond: PropTypes.bool,
@@ -330,7 +331,7 @@ export default class Picker extends Component {
name={name}
onKeyDown={this.onKeyDown}
disabled={disabled}
- value={(value && value.format(this.getFormat())) || ''}
+ value={formatTime(value, this.getFormat())}
autoComplete={autoComplete}
onFocus={onFocus}
onBlur={onBlur}
diff --git a/src/util/index.js b/src/util/index.js
new file mode 100644
index 00000000..0fc3d00a
--- /dev/null
+++ b/src/util/index.js
@@ -0,0 +1,13 @@
+export function getTimeFormat(format) {
+ if (Array.isArray(format)) {
+ return format.length ? format[0] : undefined;
+ }
+ return format;
+}
+
+export function formatTime(value, format) {
+ if (!value) {
+ return '';
+ }
+ return value.format(getTimeFormat(format));
+}
diff --git a/tests/TimePicker.spec.jsx b/tests/TimePicker.spec.jsx
index c269278a..d42ce118 100644
--- a/tests/TimePicker.spec.jsx
+++ b/tests/TimePicker.spec.jsx
@@ -3,7 +3,7 @@ import React from 'react';
import { mount } from 'enzyme';
import moment from 'moment';
import TimePicker from '../src/TimePicker';
-import { clickInput, clickSelectItem, matchValue } from './util';
+import { clickInput, clickSelectItem, matchValue, findHeader } from './util';
describe('TimePicker', () => {
let container;
@@ -180,4 +180,33 @@ describe('TimePicker', () => {
expect(blur).toBeTruthy();
});
});
+
+ describe('time formats', () => {
+ it('supports single format', async () => {
+ const picker = renderPickerWithoutSeconds({
+ format: 'h:mm a',
+ });
+
+ clickInput(picker);
+ setTimeout(100);
+ findHeader(picker).simulate('change', { target: { value: '8:34 am' } });
+ setTimeout(100);
+ matchValue(picker, '8:34 am');
+ });
+
+ it('supports an array of formats', async () => {
+ const picker = renderPickerWithoutSeconds({
+ format: ['h:mm', 'h:mm a'],
+ });
+
+ clickInput(picker);
+ setTimeout(100);
+ findHeader(picker).simulate('change', { target: { value: '8:34' } });
+ setTimeout(100);
+ matchValue(picker, '8:34');
+ findHeader(picker).simulate('change', { target: { value: '8:34 pm' } });
+ setTimeout(100);
+ matchValue(picker, '8:34');
+ });
+ });
});