From 93bde3fb67b427ef986a336f7afdc2783c336216 Mon Sep 17 00:00:00 2001
From: tangjinzhou <415800467@qq.com>
Date: Sat, 27 Jun 2020 22:17:48 +0800
Subject: [PATCH] feat: update inputnumber
---
antdv-demo | 2 +-
components/input-number/index.jsx | 57 +++---
.../vc-input-number/src/InputHandler.js | 12 +-
components/vc-input-number/src/index.js | 163 ++++++++++--------
.../vc-m-feedback/src/TouchFeedback.jsx | 77 +++++----
examples/App.vue | 2 +-
examples/index.js | 2 +
7 files changed, 174 insertions(+), 141 deletions(-)
diff --git a/antdv-demo b/antdv-demo
index 6cde2f94c..d68062568 160000
--- a/antdv-demo
+++ b/antdv-demo
@@ -1 +1 @@
-Subproject commit 6cde2f94ca4a1dbbb260a4436369e2084ff467ed
+Subproject commit d680625687a695a9b9a06a131e12f9611a480d5b
diff --git a/components/input-number/index.jsx b/components/input-number/index.jsx
index 93a4d9a1c..e530697c7 100644
--- a/components/input-number/index.jsx
+++ b/components/input-number/index.jsx
@@ -1,11 +1,11 @@
+import { inject } from 'vue';
import PropTypes from '../_util/vue-types';
-import { initDefaultProps, getOptionProps, getListeners } from '../_util/props-util';
+import { initDefaultProps, getOptionProps } from '../_util/props-util';
import classNames from 'classnames';
import UpOutlined from '@ant-design/icons-vue/UpOutlined';
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
import VcInputNumber from '../vc-input-number/src';
import { ConfigConsumerProps } from '../config-provider';
-import Base from '../base';
export const InputNumberProps = {
prefixCls: PropTypes.string,
@@ -29,56 +29,59 @@ export const InputNumberProps = {
const InputNumber = {
name: 'AInputNumber',
- model: {
- prop: 'value',
- event: 'change',
- },
+ inheritAttrs: false,
props: initDefaultProps(InputNumberProps, {
step: 1,
}),
- inject: {
- configProvider: { default: () => ConfigConsumerProps },
+ setup() {
+ return {
+ configProvider: inject('configProvider', ConfigConsumerProps),
+ };
},
methods: {
+ saveInputNumber(inputNumberRef) {
+ this.inputNumberRef = inputNumberRef;
+ },
focus() {
- this.$refs.inputNumberRef.focus();
+ this.inputNumberRef.focus();
},
blur() {
- this.$refs.inputNumberRef.blur();
+ this.inputNumberRef.blur();
},
},
render() {
- const { prefixCls: customizePrefixCls, size, ...others } = getOptionProps(this);
+ const { prefixCls: customizePrefixCls, size, class: className, ...others } = {
+ ...getOptionProps(this),
+ ...this.$attrs,
+ };
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('input-number', customizePrefixCls);
- const inputNumberClass = classNames({
- [`${prefixCls}-lg`]: size === 'large',
- [`${prefixCls}-sm`]: size === 'small',
- });
+ const inputNumberClass = classNames(
+ {
+ [`${prefixCls}-lg`]: size === 'large',
+ [`${prefixCls}-sm`]: size === 'small',
+ },
+ className,
+ );
const upIcon = ;
const downIcon = ;
const vcInputNumberprops = {
- props: {
- prefixCls,
- upHandler: upIcon,
- downHandler: downIcon,
- ...others,
- },
+ prefixCls,
+ upHandler: upIcon,
+ downHandler: downIcon,
+ ...others,
class: inputNumberClass,
- ref: 'inputNumberRef',
- on: getListeners(this),
};
- return ;
+ return ;
},
};
/* istanbul ignore next */
-InputNumber.install = function(Vue) {
- Vue.use(Base);
- Vue.component(InputNumber.name, InputNumber);
+InputNumber.install = function(app) {
+ app.component(InputNumber.name, InputNumber);
};
export default InputNumber;
diff --git a/components/vc-input-number/src/InputHandler.js b/components/vc-input-number/src/InputHandler.js
index 75c866752..42b929f5c 100755
--- a/components/vc-input-number/src/InputHandler.js
+++ b/components/vc-input-number/src/InputHandler.js
@@ -1,9 +1,10 @@
import PropTypes from '../../_util/vue-types';
import Touchable from '../../vc-m-feedback';
-import { getListeners } from '../../_util/props-util';
+import { getSlot } from '../../_util/props-util';
const InputHandler = {
name: 'InputHandler',
+ inheritAttrs: false,
props: {
prefixCls: PropTypes.string,
disabled: PropTypes.bool,
@@ -11,15 +12,12 @@ const InputHandler = {
render() {
const { prefixCls, disabled } = this.$props;
const touchableProps = {
- props: {
- disabled,
- activeClassName: `${prefixCls}-handler-active`,
- },
- on: getListeners(this),
+ disabled,
+ activeClassName: `${prefixCls}-handler-active`,
};
return (
- {this.$slots.default}
+ {getSlot(this)}
);
},
diff --git a/components/vc-input-number/src/index.js b/components/vc-input-number/src/index.js
index 3a15712d9..02955018f 100755
--- a/components/vc-input-number/src/index.js
+++ b/components/vc-input-number/src/index.js
@@ -1,7 +1,7 @@
// based on rc-input-number 4.5.5
import PropTypes from '../../_util/vue-types';
import BaseMixin from '../../_util/BaseMixin';
-import { initDefaultProps, hasProp, getOptionProps, getListeners } from '../../_util/props-util';
+import { initDefaultProps, hasProp, getOptionProps } from '../../_util/props-util';
import classNames from 'classnames';
import KeyCode from '../../_util/KeyCode';
import InputHandler from './InputHandler';
@@ -76,15 +76,17 @@ const inputNumberProps = {
title: PropTypes.string,
name: PropTypes.string,
id: PropTypes.string,
+ type: PropTypes.string,
};
export default {
name: 'VCInputNumber',
mixins: [BaseMixin],
- model: {
- prop: 'value',
- event: 'change',
- },
+ inheritAttrs: false,
+ // model: {
+ // prop: 'value',
+ // event: 'change',
+ // },
props: initDefaultProps(inputNumberProps, {
focusOnUpDown: true,
useTouch: false,
@@ -158,6 +160,7 @@ export default {
typeof nextValue === 'number' &&
nextValue > max
) {
+ this.$emit('update:value', max);
this.$emit('change', max);
}
if (
@@ -166,6 +169,7 @@ export default {
typeof nextValue === 'number' &&
nextValue < min
) {
+ this.$emit('update:value', min);
this.$emit('change', min);
}
}
@@ -179,7 +183,7 @@ export default {
},
methods: {
updatedFunc() {
- const inputElem = this.$refs.inputRef;
+ const inputElem = this.inputRef;
// Restore cursor
try {
// Firefox set the input cursor after it get focused.
@@ -270,7 +274,9 @@ export default {
}
this.rawInput = this.parser(this.getValueFromEvent(e));
this.setState({ inputValue: this.rawInput });
- this.$emit('change', this.toNumber(this.rawInput)); // valid number or invalid string
+ const num = this.toNumber(this.rawInput); // valid number or invalid string
+ this.$emit('update:value', num);
+ this.$emit('change', num);
},
onFocus(...args) {
this.setState({
@@ -285,12 +291,12 @@ export default {
});
const value = this.getCurrentValidValue(this.inputValue);
const newValue = this.setValue(value);
- if (this.$listeners.blur) {
- const originValue = this.$refs.inputRef.value;
+ if (this.$attrs.onBlur) {
+ const originValue = this.inputRef.value;
const inputValue = this.getInputDisplayValue({ focused: false, sValue: newValue });
- this.$refs.inputRef.value = inputValue;
+ this.inputRef.value = inputValue;
this.$emit('blur', ...args);
- this.$refs.inputRef.value = originValue;
+ this.inputRef.value = originValue;
}
},
getCurrentValidValue(value) {
@@ -366,6 +372,7 @@ export default {
);
}
if (changed) {
+ this.$emit('update:value', newValue);
this.$emit('change', newValue);
}
return newValue;
@@ -431,7 +438,7 @@ export default {
recordCursorPosition() {
// Record position
try {
- const inputElem = this.$refs.inputRef;
+ const inputElem = this.inputRef;
this.cursorStart = inputElem.selectionStart;
this.cursorEnd = inputElem.selectionEnd;
this.currentValue = inputElem.value;
@@ -444,17 +451,12 @@ export default {
}
},
fixCaret(start, end) {
- if (
- start === undefined ||
- end === undefined ||
- !this.$refs.inputRef ||
- !this.$refs.inputRef.value
- ) {
+ if (start === undefined || end === undefined || !this.inputRef || !this.inputRef.value) {
return;
}
try {
- const inputElem = this.$refs.inputRef;
+ const inputElem = this.inputRef;
const currentStart = inputElem.selectionStart;
const currentEnd = inputElem.selectionEnd;
@@ -470,7 +472,7 @@ export default {
restoreByAfter(str) {
if (str === undefined) return false;
- const fullStr = this.$refs.inputRef.value;
+ const fullStr = this.inputRef.value;
const index = fullStr.lastIndexOf(str);
if (index === -1) return false;
@@ -504,11 +506,11 @@ export default {
});
},
focus() {
- this.$refs.inputRef.focus();
+ this.inputRef.focus();
this.recordCursorPosition();
},
blur() {
- this.$refs.inputRef.blur();
+ this.inputRef.blur();
},
formatWrapper(num) {
// http://2ality.com/2012/03/signedzero.html
@@ -621,8 +623,20 @@ export default {
handleInputClick() {
this.$emit('click');
},
+ saveUp(node) {
+ this.upHandlerRef = node;
+ },
+
+ saveDown(node) {
+ this.downHandlerRef = node;
+ },
+
+ saveInput(node) {
+ this.inputRef = node;
+ },
},
render() {
+ const props = { ...this.$props, ...this.$attrs };
const {
prefixCls,
disabled,
@@ -631,8 +645,10 @@ export default {
autoComplete,
upHandler,
downHandler,
- } = this.$props;
+ class: className,
+ } = props;
const classes = classNames({
+ [className]: className,
[prefixCls]: true,
[`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-focused`]: this.focused,
@@ -655,6 +671,16 @@ export default {
}
}
+ const dataOrAriaAttributeProps = {};
+ for (const key in props) {
+ if (
+ props.hasOwnProperty(key) &&
+ (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-' || key === 'role')
+ ) {
+ dataOrAriaAttributeProps[key] = props[key];
+ }
+ }
+
const editable = !this.readOnly && !this.disabled;
// focus state, show input value
@@ -665,71 +691,61 @@ export default {
let downEvents;
if (useTouch) {
upEvents = {
- touchstart: editable && !upDisabledClass ? this.up : noop,
- touchend: this.stop,
+ onTouchstart: editable && !upDisabledClass ? this.up : noop,
+ onTouchend: this.stop,
};
downEvents = {
- touchstart: editable && !downDisabledClass ? this.down : noop,
- touchend: this.stop,
+ onTouchstart: editable && !downDisabledClass ? this.down : noop,
+ onTouchend: this.stop,
};
} else {
upEvents = {
- mousedown: editable && !upDisabledClass ? this.up : noop,
- mouseup: this.stop,
- mouseleave: this.stop,
+ onMousedown: editable && !upDisabledClass ? this.up : noop,
+ onMouseup: this.stop,
+ onMouseleave: this.stop,
};
downEvents = {
- mousedown: editable && !downDisabledClass ? this.down : noop,
- mouseup: this.stop,
- mouseleave: this.stop,
+ onMousedown: editable && !downDisabledClass ? this.down : noop,
+ onMouseup: this.stop,
+ onMouseleave: this.stop,
};
}
const isUpDisabled = !!upDisabledClass || disabled || readOnly;
const isDownDisabled = !!downDisabledClass || disabled || readOnly;
- const {
- mouseenter = noop,
- mouseleave = noop,
- mouseover = noop,
- mouseout = noop,
- } = getListeners(this);
- const contentProps = {
- on: { mouseenter, mouseleave, mouseover, mouseout },
- class: classes,
- attrs: { title: this.$props.title },
- };
+
const upHandlerProps = {
- props: {
- disabled: isUpDisabled,
- prefixCls,
- },
- attrs: {
- unselectable: 'unselectable',
- role: 'button',
- 'aria-label': 'Increase Value',
- 'aria-disabled': !!isUpDisabled,
- },
+ disabled: isUpDisabled,
+ prefixCls,
+ unselectable: 'unselectable',
+ role: 'button',
+ 'aria-label': 'Increase Value',
+ 'aria-disabled': !!isUpDisabled,
class: `${prefixCls}-handler ${prefixCls}-handler-up ${upDisabledClass}`,
- on: upEvents,
- ref: 'up',
+ ...upEvents,
+ ref: this.saveUp,
};
const downHandlerProps = {
- props: {
- disabled: isDownDisabled,
- prefixCls,
- },
- attrs: {
- unselectable: 'unselectable',
- role: 'button',
- 'aria-label': 'Decrease Value',
- 'aria-disabled': !!isDownDisabled,
- },
+ disabled: isDownDisabled,
+ prefixCls,
+ unselectable: 'unselectable',
+ role: 'button',
+ 'aria-label': 'Decrease Value',
+ 'aria-disabled': !!isDownDisabled,
class: `${prefixCls}-handler ${prefixCls}-handler-down ${downDisabledClass}`,
- on: downEvents,
- ref: 'down',
+ ...downEvents,
+ ref: this.saveDown,
};
- // ref for test
+
return (
-
+
{upHandler || (
@@ -757,7 +773,7 @@ export default {
aria-valuemax={this.max}
aria-valuenow={sValue}
required={this.required}
- type={this.type}
+ type={props.type}
placeholder={this.placeholder}
onClick={this.handleInputClick}
class={`${prefixCls}-input`}
@@ -767,7 +783,7 @@ export default {
onBlur={this.onBlur}
onKeydown={editable ? this.onKeyDown : noop}
onKeyup={editable ? this.onKeyUp : noop}
- maxLength={this.maxLength}
+ maxlength={props.maxLength}
readOnly={this.readOnly}
disabled={this.disabled}
max={this.max}
@@ -777,9 +793,10 @@ export default {
title={this.title}
id={this.id}
onInput={this.onChange}
- ref="inputRef"
+ ref={this.saveInput}
value={inputDisplayValue}
pattern={this.pattern}
+ {...dataOrAriaAttributeProps}
/>
diff --git a/components/vc-m-feedback/src/TouchFeedback.jsx b/components/vc-m-feedback/src/TouchFeedback.jsx
index cb7f3f2c0..89c388911 100755
--- a/components/vc-m-feedback/src/TouchFeedback.jsx
+++ b/components/vc-m-feedback/src/TouchFeedback.jsx
@@ -1,4 +1,5 @@
-import { initDefaultProps } from '../../_util/props-util';
+import classNames from 'classnames';
+import { initDefaultProps, getSlot } from '../../_util/props-util';
import { cloneElement } from '../../_util/vnode';
import warning from '../../_util/warning';
import BaseMixin from '../../_util/BaseMixin';
@@ -7,10 +8,12 @@ import { ITouchProps } from './PropTypes';
export default {
name: 'TouchFeedback',
mixins: [BaseMixin],
+ inheritAttrs: false,
props: initDefaultProps(ITouchProps, {
disabled: false,
}),
data() {
+ this.child = null;
return {
active: false,
};
@@ -26,8 +29,12 @@ export default {
},
methods: {
triggerEvent(type, isActive, ev) {
- // 暂时仅有input-number用到,事件直接到挂载到Touchable上,不需要像antd那样从子组件触发
- this.$emit(type, ev);
+ const eventType = `on${type}`;
+ const { child } = this;
+
+ if (child.props[eventType]) {
+ child.props[eventType](ev);
+ }
if (isActive !== this.active) {
this.setState({
active: isActive,
@@ -35,60 +42,66 @@ export default {
}
},
onTouchStart(e) {
- this.triggerEvent('touchstart', true, e);
+ this.triggerEvent('Touchstart', true, e);
},
onTouchMove(e) {
- this.triggerEvent('touchmove', false, e);
+ this.triggerEvent('Touchmove', false, e);
},
onTouchEnd(e) {
- this.triggerEvent('touchend', false, e);
+ this.triggerEvent('Touchend', false, e);
},
onTouchCancel(e) {
- this.triggerEvent('touchcancel', false, e);
+ this.triggerEvent('Touchcancel', false, e);
},
onMouseDown(e) {
// pc simulate mobile
- this.triggerEvent('mousedown', true, e);
+ this.triggerEvent('Mousedown', true, e);
},
onMouseUp(e) {
- this.triggerEvent('mouseup', false, e);
+ this.triggerEvent('Mouseup', false, e);
},
onMouseLeave(e) {
- this.triggerEvent('mouseleave', false, e);
+ this.triggerEvent('Mouseleave', false, e);
},
},
render() {
const { disabled, activeClassName = '', activeStyle = {} } = this.$props;
- const child = this.$slots.default;
+ let child = getSlot(this);
if (child.length !== 1) {
warning(false, 'm-feedback组件只能包含一个子元素');
return null;
}
- let childProps = {
- on: disabled
- ? {}
- : {
- touchstart: this.onTouchStart,
- touchmove: this.onTouchMove,
- touchend: this.onTouchEnd,
- touchcancel: this.onTouchCancel,
- mousedown: this.onMouseDown,
- mouseup: this.onMouseUp,
- mouseleave: this.onMouseLeave,
- },
- };
+ const events = disabled
+ ? undefined
+ : {
+ onTouchstart: this.onTouchStart,
+ onTouchmove: this.onTouchMove,
+ onTouchend: this.onTouchEnd,
+ onTouchcancel: this.onTouchCancel,
+ onMousedown: this.onMouseDown,
+ onMouseup: this.onMouseUp,
+ onMouseleave: this.onMouseLeave,
+ };
+ child = child[0];
+ this.child = child;
if (!disabled && this.active) {
- childProps = {
- ...childProps,
- ...{
- style: activeStyle,
- class: activeClassName,
- },
- };
+ let { style, class: className } = child.props;
+
+ if (activeStyle !== false) {
+ if (activeStyle) {
+ style = { ...style, ...activeStyle };
+ }
+ className = classNames(className, activeClassName);
+ }
+ return cloneElement(child, {
+ class: className,
+ style,
+ ...events,
+ });
}
- return cloneElement(child, childProps);
+ return cloneElement(child, events);
},
};
diff --git a/examples/App.vue b/examples/App.vue
index 708299153..dc52a4f82 100644
--- a/examples/App.vue
+++ b/examples/App.vue
@@ -4,7 +4,7 @@