diff --git a/components/vc-time-picker/Combobox.jsx b/components/vc-time-picker/Combobox.jsx index 543324a0b..35a622d72 100644 --- a/components/vc-time-picker/Combobox.jsx +++ b/components/vc-time-picker/Combobox.jsx @@ -28,6 +28,7 @@ const Combobox = { prefixCls: PropTypes.string, value: PropTypes.object, // onChange: PropTypes.func, + // onAmPmChange: PropTypes.func, showHour: PropTypes.bool, showMinute: PropTypes.bool, showSecond: PropTypes.bool, @@ -71,6 +72,7 @@ const Combobox = { } } } + this.__emit('amPmChange', ampm); } else { value.second(+itemValue); } diff --git a/components/vc-time-picker/Header.jsx b/components/vc-time-picker/Header.jsx index c9afa561e..4eda403ba 100644 --- a/components/vc-time-picker/Header.jsx +++ b/components/vc-time-picker/Header.jsx @@ -158,29 +158,6 @@ const Header = { this.__emit('keydown', e); }, - onClear() { - this.__emit('clear'); - this.setState({ str: '' }); - }, - - getClearButton() { - const { prefixCls, allowEmpty, clearText } = this; - const clearIcon = getComponentFromProp(this, 'clearIcon'); - if (!allowEmpty) { - return null; - } - return ( - - {clearIcon || } - - ); - }, - getProtoValue() { return this.value || this.defaultOpenValue; }, @@ -207,7 +184,6 @@ const Header = { return (
{this.getInput()} - {this.getClearButton()}
); }, diff --git a/components/vc-time-picker/Panel.jsx b/components/vc-time-picker/Panel.jsx index 116379501..58d2b811e 100644 --- a/components/vc-time-picker/Panel.jsx +++ b/components/vc-time-picker/Panel.jsx @@ -1,8 +1,8 @@ +import moment from 'moment'; import PropTypes from '../_util/vue-types'; import BaseMixin from '../_util/BaseMixin'; import Header from './Header'; import Combobox from './Combobox'; -import moment from 'moment'; import { getComponentFromProp } from '../_util/props-util'; function noop() {} @@ -16,6 +16,20 @@ function generateOptions(length, disabledOptions, hideDisabledOptions, step = 1) } return arr; } + +function toNearestValidTime(time, hourOptions, minuteOptions, secondOptions) { + const hour = hourOptions + .slice() + .sort((a, b) => Math.abs(time.hour() - a) - Math.abs(time.hour() - b))[0]; + const minute = minuteOptions + .slice() + .sort((a, b) => Math.abs(time.minute() - a) - Math.abs(time.minute() - b))[0]; + const second = secondOptions + .slice() + .sort((a, b) => Math.abs(time.second() - a) - Math.abs(time.second() - b))[0]; + return moment(`${hour}:${minute}:${second}`, 'HH:mm:ss'); +} + const Panel = { mixins: [BaseMixin], props: { @@ -81,6 +95,10 @@ const Panel = { this.__emit('change', newValue); }, + onAmPmChange(ampm) { + this.__emit('amPmChange', ampm); + }, + onCurrentSelectPanelChange(currentSelectPanel) { this.setState({ currentSelectPanel }); }, @@ -157,13 +175,18 @@ const Panel = { hideDisabledOptions, secondStep, ); - + const validDefaultOpenValue = toNearestValidTime( + defaultOpenValue, + hourOptions, + minuteOptions, + secondOptions, + ); return (
{ const perTick = (difference / duration) * 10; requestAnimationFrame(() => { - element.scrollTop = element.scrollTop + perTick; + element.scrollTop += perTick; if (element.scrollTop === to) return; scrollTo(element, to, duration - 10); }); @@ -66,18 +66,28 @@ const Select = { [`${prefixCls}-select-option-selected`]: selectedIndex === index, [`${prefixCls}-select-option-disabled`]: item.disabled, }); - let onClick = noop; - if (!item.disabled) { - onClick = this.onSelect.bind(this, item.value); - } + const onClick = item.disabled + ? undefined + : () => { + this.onSelect(item.value); + }; return ( -
  • +
  • {item.value}
  • ); }); }, + handleMouseEnter(e) { + this.setState({ active: true }); + this.__emit('mouseenter', e); + }, + + handleMouseLeave() { + this.setState({ active: false }); + }, + scrollToSelected(duration) { // move to selected item const select = this.$el; @@ -93,15 +103,6 @@ const Select = { const to = topOption.offsetTop; scrollTo(select, to, duration); }, - - handleMouseEnter(e) { - this.setState({ active: true }); - this.__emit('mouseenter', e); - }, - - handleMouseLeave() { - this.setState({ active: false }); - }, }, render() { diff --git a/components/vc-time-picker/TimePicker.jsx b/components/vc-time-picker/TimePicker.jsx index d5b88b10f..14cc9734a 100644 --- a/components/vc-time-picker/TimePicker.jsx +++ b/components/vc-time-picker/TimePicker.jsx @@ -1,10 +1,11 @@ +import moment from 'moment'; import PropTypes from '../_util/vue-types'; import BaseMixin from '../_util/BaseMixin'; +import { initDefaultProps, hasProp, getComponentFromProp,isValidElement, getEvents } from '../_util/props-util'; +import { cloneElement } from '../_util/vnode'; import Trigger from '../vc-trigger'; import Panel from './Panel'; import placements from './placements'; -import moment from 'moment'; -import { initDefaultProps, hasProp, getComponentFromProp } from '../_util/props-util'; function noop() {} @@ -38,11 +39,13 @@ export default { showMinute: PropTypes.bool, showSecond: PropTypes.bool, popupClassName: PropTypes.string, + popupStyle: PropTypes.object, disabledHours: PropTypes.func, disabledMinutes: PropTypes.func, disabledSeconds: PropTypes.func, hideDisabledOptions: PropTypes.bool, // onChange: PropTypes.func, + // onAmPmChange: PropTypes.func, // onOpen: PropTypes.func, // onClose: PropTypes.func, // onFocus: PropTypes.func, @@ -67,6 +70,7 @@ export default { defaultOpen: false, inputReadOnly: false, popupClassName: '', + popupStyle: {}, align: {}, id: '', allowEmpty: true, @@ -116,7 +120,12 @@ export default { this.setValue(value); }, - onPanelClear() { + onAmPmChange(ampm) { + this.__emit('amPmChange', ampm); + }, + + onClear(event) { + event.stopPropagation(); this.setValue(null); this.setOpen(false); }, @@ -200,7 +209,7 @@ export default { value={sValue} inputReadOnly={inputReadOnly} onChange={this.onPanelChange} - onClear={this.onPanelClear} + onAmPmChange={this.onAmPmChange} defaultOpenValue={defaultOpenValue} showHour={showHour} showMinute={showMinute} @@ -275,6 +284,37 @@ export default { onBlur(e) { this.__emit('blur', e); }, + renderClearButton() { + const { sValue } = this; + const { prefixCls, allowEmpty, clearText } = this.$props; + if (!allowEmpty || !sValue) { + return null; + } + const clearIcon = getComponentFromProp(this, 'clearIcon'); + if (isValidElement(clearIcon)) { + const { click } = getEvents(clearIcon) || {}; + return cloneElement(clearIcon, { + on: { + click: (...args) => { + if (click) click(...args); + this.onClear(...args); + }, + }, + }); + } + + return ( + + {clearIcon || } + + ); + }, }, render() { @@ -295,6 +335,7 @@ export default { sValue, onFocus, onBlur, + popupStyle, } = this; const popupClassName = this.getPopupClassName(); const inputIcon = getComponentFromProp(this, 'inputIcon'); @@ -302,6 +343,7 @@ export default { {inputIcon || } + {this.renderClearButton()} ); diff --git a/components/vc-time-picker/assets/index.less b/components/vc-time-picker/assets/index.less index 426ce3a46..1582de656 100644 --- a/components/vc-time-picker/assets/index.less +++ b/components/vc-time-picker/assets/index.less @@ -2,10 +2,40 @@ .@{prefixClass} { display: inline-block; + position: relative; box-sizing: border-box; * { box-sizing: border-box; } + + &-clear { + position: absolute; + right: 6px; + cursor: pointer; + overflow: hidden; + width: 20px; + height: 20px; + text-align: center; + line-height: 20px; + top: 3px; + margin: 0; + + &-icon:after { + content: "x"; + font-size: 12px; + font-style: normal; + color: #aaa; + display: inline-block; + line-height: 1; + height: 20px; + width: 20px; + transition: color 0.3s ease; + } + + &-icon:hover:after { + color: #666; + } + } } @import './index/Picker'; diff --git a/components/vc-time-picker/assets/index/Header.less b/components/vc-time-picker/assets/index/Header.less index 1215451ba..b107436ac 100644 --- a/components/vc-time-picker/assets/index/Header.less +++ b/components/vc-time-picker/assets/index/Header.less @@ -19,32 +19,4 @@ border-color: red; } } - - &-clear-btn { - position: absolute; - right: 6px; - cursor: pointer; - overflow: hidden; - width: 20px; - height: 20px; - text-align: center; - line-height: 20px; - top: 6px; - margin: 0; - } - - &-clear-btn-icon:after { - content: 'x'; - font-size: 12px; - font-style: normal; - color: #aaa; - display: inline-block; - line-height: 1; - width: 20px; - transition: color 0.3s ease; - } - - &-clear-btn-icon:hover:after { - color: #666; - } } diff --git a/components/vc-time-picker/assets/index/Select.less b/components/vc-time-picker/assets/index/Select.less index 86c73c109..f11d1e9bd 100644 --- a/components/vc-time-picker/assets/index/Select.less +++ b/components/vc-time-picker/assets/index/Select.less @@ -33,7 +33,6 @@ li { list-style: none; - box-sizing: content-box; margin: 0; padding: 0 0 0 16px; width: 100%; diff --git a/components/vc-time-picker/index.js b/components/vc-time-picker/index.js index b20fc70cf..7e491f7b5 100644 --- a/components/vc-time-picker/index.js +++ b/components/vc-time-picker/index.js @@ -1,2 +1,2 @@ -// based on rc-time-picker 3.4.0 +// based on rc-time-picker 3.6.2 export { default } from './TimePicker'; diff --git a/components/vc-tree-select/src/Select.jsx b/components/vc-tree-select/src/Select.jsx index 5bccd3590..ee247ddf6 100644 --- a/components/vc-tree-select/src/Select.jsx +++ b/components/vc-tree-select/src/Select.jsx @@ -104,7 +104,8 @@ const Select = { treeDataSimpleMode: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), treeNodeFilterProp: PropTypes.string, treeNodeLabelProp: PropTypes.string, - treeCheckable: PropTypes.oneOfType([PropTypes.bool, PropTypes.any]), + treeCheckable: PropTypes.oneOfType([PropTypes.any, PropTypes.bool]), + // treeCheckable: PropTypes.any, treeCheckStrictly: PropTypes.bool, treeIcon: PropTypes.bool, treeLine: PropTypes.bool, @@ -594,6 +595,7 @@ const Select = { disabled, inputValue, treeNodeLabelProp, + multiple, treeCheckable, treeCheckStrictly, autoClearSearchValue, diff --git a/components/vc-tree-select/src/Selector/MultipleSelector/index.jsx b/components/vc-tree-select/src/Selector/MultipleSelector/index.jsx index 0b5c52a13..1a8ce163c 100644 --- a/components/vc-tree-select/src/Selector/MultipleSelector/index.jsx +++ b/components/vc-tree-select/src/Selector/MultipleSelector/index.jsx @@ -24,7 +24,7 @@ const MultipleSelector = { searchValue: PropTypes.string, labelInValue: PropTypes.bool, maxTagCount: PropTypes.number, - maxTagPlaceholder: PropTypes.any, + maxTagPlaceholder: PropTypes.oneOfType([PropTypes.any, PropTypes.func]), // onChoiceAnimationLeave: PropTypes.func, },