TimePicker.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. import _defineProperty from 'babel-runtime/helpers/defineProperty';
  2. import moment from 'moment';
  3. import classNames from 'classnames';
  4. import PropTypes from '../_util/vue-types';
  5. import BaseMixin from '../_util/BaseMixin';
  6. import { initDefaultProps, hasProp, getComponentFromProp, isValidElement, getEvents } from '../_util/props-util';
  7. import { cloneElement } from '../_util/vnode';
  8. import Trigger from '../vc-trigger';
  9. import Panel from './Panel';
  10. import placements from './placements';
  11. function noop() {}
  12. export default {
  13. name: 'VcTimePicker',
  14. mixins: [BaseMixin],
  15. props: initDefaultProps({
  16. prefixCls: PropTypes.string,
  17. clearText: PropTypes.string,
  18. value: PropTypes.any,
  19. defaultOpenValue: {
  20. type: Object,
  21. 'default': function _default() {
  22. return moment();
  23. }
  24. },
  25. inputReadOnly: PropTypes.bool,
  26. disabled: PropTypes.bool,
  27. allowEmpty: PropTypes.bool,
  28. defaultValue: PropTypes.any,
  29. open: PropTypes.bool,
  30. defaultOpen: PropTypes.bool,
  31. align: PropTypes.object,
  32. placement: PropTypes.any,
  33. transitionName: PropTypes.string,
  34. getPopupContainer: PropTypes.func,
  35. placeholder: PropTypes.string,
  36. format: PropTypes.string,
  37. showHour: PropTypes.bool,
  38. showMinute: PropTypes.bool,
  39. showSecond: PropTypes.bool,
  40. popupClassName: PropTypes.string,
  41. popupStyle: PropTypes.object,
  42. disabledHours: PropTypes.func,
  43. disabledMinutes: PropTypes.func,
  44. disabledSeconds: PropTypes.func,
  45. hideDisabledOptions: PropTypes.bool,
  46. // onChange: PropTypes.func,
  47. // onAmPmChange: PropTypes.func,
  48. // onOpen: PropTypes.func,
  49. // onClose: PropTypes.func,
  50. // onFocus: PropTypes.func,
  51. // onBlur: PropTypes.func,
  52. name: PropTypes.string,
  53. autoComplete: PropTypes.string,
  54. use12Hours: PropTypes.bool,
  55. hourStep: PropTypes.number,
  56. minuteStep: PropTypes.number,
  57. secondStep: PropTypes.number,
  58. focusOnOpen: PropTypes.bool,
  59. // onKeyDown: PropTypes.func,
  60. autoFocus: PropTypes.bool,
  61. id: PropTypes.string,
  62. inputIcon: PropTypes.any,
  63. clearIcon: PropTypes.any,
  64. addon: PropTypes.func
  65. }, {
  66. clearText: 'clear',
  67. prefixCls: 'rc-time-picker',
  68. defaultOpen: false,
  69. inputReadOnly: false,
  70. popupClassName: '',
  71. popupStyle: {},
  72. align: {},
  73. allowEmpty: true,
  74. showHour: true,
  75. showMinute: true,
  76. showSecond: true,
  77. disabledHours: noop,
  78. disabledMinutes: noop,
  79. disabledSeconds: noop,
  80. hideDisabledOptions: false,
  81. placement: 'bottomLeft',
  82. use12Hours: false,
  83. focusOnOpen: false
  84. }),
  85. data: function data() {
  86. var defaultOpen = this.defaultOpen,
  87. defaultValue = this.defaultValue,
  88. _open = this.open,
  89. open = _open === undefined ? defaultOpen : _open,
  90. _value = this.value,
  91. value = _value === undefined ? defaultValue : _value;
  92. return {
  93. sOpen: open,
  94. sValue: value
  95. };
  96. },
  97. watch: {
  98. value: function value(val) {
  99. this.setState({
  100. sValue: val
  101. });
  102. },
  103. open: function open(val) {
  104. if (val !== undefined) {
  105. this.setState({
  106. sOpen: val
  107. });
  108. }
  109. }
  110. },
  111. mounted: function mounted() {
  112. var _this = this;
  113. this.$nextTick(function () {
  114. if (_this.autoFocus) {
  115. _this.focus();
  116. }
  117. });
  118. },
  119. methods: {
  120. onPanelChange: function onPanelChange(value) {
  121. this.setValue(value);
  122. },
  123. onAmPmChange: function onAmPmChange(ampm) {
  124. this.__emit('amPmChange', ampm);
  125. },
  126. onClear: function onClear(event) {
  127. event.stopPropagation();
  128. this.setValue(null);
  129. this.setOpen(false);
  130. },
  131. onVisibleChange: function onVisibleChange(open) {
  132. this.setOpen(open);
  133. },
  134. onEsc: function onEsc() {
  135. this.setOpen(false);
  136. this.focus();
  137. },
  138. onKeyDown: function onKeyDown(e) {
  139. if (e.keyCode === 40) {
  140. this.setOpen(true);
  141. }
  142. },
  143. onKeyDown2: function onKeyDown2(e) {
  144. this.__emit('keydown', e);
  145. },
  146. setValue: function setValue(value) {
  147. if (!hasProp(this, 'value')) {
  148. this.setState({
  149. sValue: value
  150. });
  151. }
  152. this.__emit('change', value);
  153. },
  154. getFormat: function getFormat() {
  155. var format = this.format,
  156. showHour = this.showHour,
  157. showMinute = this.showMinute,
  158. showSecond = this.showSecond,
  159. use12Hours = this.use12Hours;
  160. if (format) {
  161. return format;
  162. }
  163. if (use12Hours) {
  164. var fmtString = [showHour ? 'h' : '', showMinute ? 'mm' : '', showSecond ? 'ss' : ''].filter(function (item) {
  165. return !!item;
  166. }).join(':');
  167. return fmtString.concat(' a');
  168. }
  169. return [showHour ? 'HH' : '', showMinute ? 'mm' : '', showSecond ? 'ss' : ''].filter(function (item) {
  170. return !!item;
  171. }).join(':');
  172. },
  173. getPanelElement: function getPanelElement() {
  174. var h = this.$createElement;
  175. var prefixCls = this.prefixCls,
  176. placeholder = this.placeholder,
  177. disabledHours = this.disabledHours,
  178. addon = this.addon,
  179. disabledMinutes = this.disabledMinutes,
  180. disabledSeconds = this.disabledSeconds,
  181. hideDisabledOptions = this.hideDisabledOptions,
  182. inputReadOnly = this.inputReadOnly,
  183. showHour = this.showHour,
  184. showMinute = this.showMinute,
  185. showSecond = this.showSecond,
  186. defaultOpenValue = this.defaultOpenValue,
  187. clearText = this.clearText,
  188. use12Hours = this.use12Hours,
  189. focusOnOpen = this.focusOnOpen,
  190. onKeyDown2 = this.onKeyDown2,
  191. hourStep = this.hourStep,
  192. minuteStep = this.minuteStep,
  193. secondStep = this.secondStep,
  194. sValue = this.sValue;
  195. var clearIcon = getComponentFromProp(this, 'clearIcon');
  196. return h(Panel, {
  197. attrs: {
  198. clearText: clearText,
  199. prefixCls: prefixCls + '-panel',
  200. value: sValue,
  201. inputReadOnly: inputReadOnly,
  202. defaultOpenValue: defaultOpenValue,
  203. showHour: showHour,
  204. showMinute: showMinute,
  205. showSecond: showSecond,
  206. format: this.getFormat(),
  207. placeholder: placeholder,
  208. disabledHours: disabledHours,
  209. disabledMinutes: disabledMinutes,
  210. disabledSeconds: disabledSeconds,
  211. hideDisabledOptions: hideDisabledOptions,
  212. use12Hours: use12Hours,
  213. hourStep: hourStep,
  214. minuteStep: minuteStep,
  215. secondStep: secondStep,
  216. focusOnOpen: focusOnOpen,
  217. clearIcon: clearIcon,
  218. addon: addon
  219. },
  220. ref: 'panel', on: {
  221. 'change': this.onPanelChange,
  222. 'amPmChange': this.onAmPmChange,
  223. 'esc': this.onEsc,
  224. 'keydown': onKeyDown2
  225. }
  226. });
  227. },
  228. getPopupClassName: function getPopupClassName() {
  229. var showHour = this.showHour,
  230. showMinute = this.showMinute,
  231. showSecond = this.showSecond,
  232. use12Hours = this.use12Hours,
  233. prefixCls = this.prefixCls,
  234. popupClassName = this.popupClassName;
  235. var selectColumnCount = 0;
  236. if (showHour) {
  237. selectColumnCount += 1;
  238. }
  239. if (showMinute) {
  240. selectColumnCount += 1;
  241. }
  242. if (showSecond) {
  243. selectColumnCount += 1;
  244. }
  245. if (use12Hours) {
  246. selectColumnCount += 1;
  247. }
  248. // Keep it for old compatibility
  249. return classNames(popupClassName, _defineProperty({}, prefixCls + '-panel-narrow', (!showHour || !showMinute || !showSecond) && !use12Hours), prefixCls + '-panel-column-' + selectColumnCount);
  250. },
  251. setOpen: function setOpen(open) {
  252. if (this.sOpen !== open) {
  253. if (!hasProp(this, 'open')) {
  254. this.setState({ sOpen: open });
  255. }
  256. if (open) {
  257. this.__emit('open', { open: open });
  258. } else {
  259. this.__emit('close', { open: open });
  260. }
  261. }
  262. },
  263. focus: function focus() {
  264. this.$refs.picker.focus();
  265. },
  266. blur: function blur() {
  267. this.$refs.picker.blur();
  268. },
  269. onFocus: function onFocus(e) {
  270. this.__emit('focus', e);
  271. },
  272. onBlur: function onBlur(e) {
  273. this.__emit('blur', e);
  274. },
  275. renderClearButton: function renderClearButton() {
  276. var _this2 = this;
  277. var h = this.$createElement;
  278. var sValue = this.sValue;
  279. var _$props = this.$props,
  280. prefixCls = _$props.prefixCls,
  281. allowEmpty = _$props.allowEmpty,
  282. clearText = _$props.clearText,
  283. disabled = _$props.disabled;
  284. if (!allowEmpty || !sValue || disabled) {
  285. return null;
  286. }
  287. var clearIcon = getComponentFromProp(this, 'clearIcon');
  288. if (isValidElement(clearIcon)) {
  289. var _ref = getEvents(clearIcon) || {},
  290. _click = _ref.click;
  291. return cloneElement(clearIcon, {
  292. on: {
  293. click: function click() {
  294. if (_click) _click.apply(undefined, arguments);
  295. _this2.onClear.apply(_this2, arguments);
  296. }
  297. }
  298. });
  299. }
  300. return h(
  301. 'a',
  302. {
  303. attrs: {
  304. role: 'button',
  305. title: clearText,
  306. tabIndex: 0
  307. },
  308. 'class': prefixCls + '-clear', on: {
  309. 'click': this.onClear
  310. }
  311. },
  312. [clearIcon || h('i', { 'class': prefixCls + '-clear-icon' })]
  313. );
  314. }
  315. },
  316. render: function render() {
  317. var h = arguments[0];
  318. var prefixCls = this.prefixCls,
  319. placeholder = this.placeholder,
  320. placement = this.placement,
  321. align = this.align,
  322. id = this.id,
  323. disabled = this.disabled,
  324. transitionName = this.transitionName,
  325. getPopupContainer = this.getPopupContainer,
  326. name = this.name,
  327. autoComplete = this.autoComplete,
  328. autoFocus = this.autoFocus,
  329. sOpen = this.sOpen,
  330. sValue = this.sValue,
  331. onFocus = this.onFocus,
  332. onBlur = this.onBlur,
  333. popupStyle = this.popupStyle;
  334. var popupClassName = this.getPopupClassName();
  335. var inputIcon = getComponentFromProp(this, 'inputIcon');
  336. return h(
  337. Trigger,
  338. {
  339. attrs: {
  340. prefixCls: prefixCls + '-panel',
  341. popupClassName: popupClassName,
  342. popupStyle: popupStyle,
  343. popupAlign: align,
  344. builtinPlacements: placements,
  345. popupPlacement: placement,
  346. action: disabled ? [] : ['click'],
  347. destroyPopupOnHide: true,
  348. getPopupContainer: getPopupContainer,
  349. popupTransitionName: transitionName,
  350. popupVisible: sOpen
  351. },
  352. on: {
  353. 'popupVisibleChange': this.onVisibleChange
  354. }
  355. },
  356. [h(
  357. 'template',
  358. { slot: 'popup' },
  359. [this.getPanelElement()]
  360. ), h(
  361. 'span',
  362. { 'class': '' + prefixCls },
  363. [h('input', {
  364. 'class': prefixCls + '-input',
  365. ref: 'picker',
  366. attrs: { type: 'text',
  367. placeholder: placeholder,
  368. name: name,
  369. disabled: disabled,
  370. autoComplete: autoComplete,
  371. autoFocus: autoFocus,
  372. readOnly: true,
  373. id: id
  374. },
  375. on: {
  376. 'keydown': this.onKeyDown,
  377. 'focus': onFocus,
  378. 'blur': onBlur
  379. },
  380. domProps: {
  381. 'value': sValue && sValue.format(this.getFormat()) || ''
  382. }
  383. }), inputIcon || h('span', { 'class': prefixCls + '-icon' }), this.renderClearButton()]
  384. )]
  385. );
  386. }
  387. };