add vc-input-number
parent
94e76c2226
commit
460fa4b642
|
@ -0,0 +1,56 @@
|
|||
import InputNumber from '../src/index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
disabled: false,
|
||||
readOnly: false,
|
||||
value: 50000,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange:', value)
|
||||
this.value = value
|
||||
},
|
||||
toggleDisabled () {
|
||||
this.disabled = !this.disabled
|
||||
},
|
||||
toggleReadOnly () {
|
||||
this.readOnly = !this.readOnly
|
||||
},
|
||||
numberWithCommas (x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
},
|
||||
format (num) {
|
||||
return `$ ${this.numberWithCommas(num)} boeing737`
|
||||
},
|
||||
parser (num) {
|
||||
return num.toString().split(' ')[1].replace(/,*/g, '')
|
||||
},
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<div style='margin: 10px;'>
|
||||
<InputNumber
|
||||
min={-8000}
|
||||
max={10000000}
|
||||
value={this.value}
|
||||
onChange={this.onChange}
|
||||
style='width: 200px'
|
||||
readOnly={this.readOnly}
|
||||
disabled={this.disabled}
|
||||
autoFocus={false}
|
||||
step={100}
|
||||
formatter={this.format}
|
||||
parser={this.parser}
|
||||
/>
|
||||
<p style='padding:10px 0'>
|
||||
<button onClick={this.toggleDisabled}>toggle Disabled</button>
|
||||
<button onClick={this.toggleReadOnly}>toggle readOnly</button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import InputNumber from '../src/index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
disabled: false,
|
||||
readOnly: false,
|
||||
value: 5,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange:', value)
|
||||
this.value = value
|
||||
},
|
||||
toggleDisabled () {
|
||||
this.disabled = !this.disabled
|
||||
},
|
||||
toggleReadOnly () {
|
||||
this.readOnly = !this.readOnly
|
||||
},
|
||||
},
|
||||
render () {
|
||||
const upHandler = (<div style={{ color: 'blue' }}>x</div>)
|
||||
const downHandler = (<div style={{ color: 'red' }}>V</div>)
|
||||
return (
|
||||
<div style='margin: 10px;'>
|
||||
<InputNumber
|
||||
min={-8}
|
||||
max={10}
|
||||
value={this.value}
|
||||
onChange={this.onChange}
|
||||
style='width: 100px'
|
||||
readOnly={this.readOnly}
|
||||
disabled={this.disabled}
|
||||
upHandler={upHandler}
|
||||
downHandler={downHandler}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
import InputNumber from '../src/index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
precision: 2,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange:', value)
|
||||
this.value = value
|
||||
},
|
||||
changeprecision (e) {
|
||||
this.precision = parseInt(e.target.value, 10)
|
||||
},
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<div style='margin: 10px;'>
|
||||
<InputNumber
|
||||
defaultValue={1}
|
||||
onChange={this.onChange}
|
||||
precision={this.precision}
|
||||
/>
|
||||
<p style='padding:10px 0'>
|
||||
precision:
|
||||
<input
|
||||
type='number'
|
||||
onInput={this.changeprecision}
|
||||
value={this.precision}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import InputNumber from '../src/index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
disabled: false,
|
||||
readOnly: false,
|
||||
value: 5,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange:', value)
|
||||
this.value = value
|
||||
},
|
||||
toggleDisabled () {
|
||||
this.disabled = !this.disabled
|
||||
},
|
||||
toggleReadOnly () {
|
||||
this.readOnly = !this.readOnly
|
||||
},
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<div style='margin: 10px;'>
|
||||
<InputNumber
|
||||
min={-8}
|
||||
max={10}
|
||||
value={this.value}
|
||||
style='width: 100px'
|
||||
onChange={this.onChange}
|
||||
readOnly={this.readOnly}
|
||||
disabled={this.disabled}
|
||||
useTouch
|
||||
/>
|
||||
<p style='padding:10px 0'>
|
||||
<button onClick={this.toggleDisabled}>toggle Disabled</button>
|
||||
<button onClick={this.toggleReadOnly}>toggle readOnly</button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import InputNumber from '../src/index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
disabled: false,
|
||||
readOnly: false,
|
||||
value: 5,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange:', value)
|
||||
this.value = value
|
||||
},
|
||||
toggleDisabled () {
|
||||
this.disabled = !this.disabled
|
||||
},
|
||||
toggleReadOnly () {
|
||||
this.readOnly = !this.readOnly
|
||||
},
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<div style='margin: 10px;'>
|
||||
<InputNumber
|
||||
min={-8}
|
||||
max={10}
|
||||
value={this.value}
|
||||
onChange={this.onChange}
|
||||
style='width: 100px'
|
||||
readOnly={this.readOnly}
|
||||
disabled={this.disabled}
|
||||
/>
|
||||
<p style='padding:10px 0'>
|
||||
<button onClick={this.toggleDisabled}>toggle Disabled</button>
|
||||
<button onClick={this.toggleReadOnly}>toggle readOnly</button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import InputNumber from '../src/index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
value: 0.000000001,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange:', value)
|
||||
this.value = value
|
||||
},
|
||||
toggleDisabled () {
|
||||
this.disabled = !this.disabled
|
||||
},
|
||||
toggleReadOnly () {
|
||||
this.readOnly = !this.readOnly
|
||||
},
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<div style='margin: 10px;'>
|
||||
<InputNumber
|
||||
min={-10}
|
||||
max={10}
|
||||
step={0.000000001}
|
||||
style='width: 100px'
|
||||
value={this.value}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
|
@ -1,37 +1,33 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Touchable from 'rmc-feedback';
|
||||
import PropTypes from '../../_util/vue-types'
|
||||
import Touchable from '../../vc-m-feedback'
|
||||
|
||||
class InputHandler extends Component {
|
||||
render() {
|
||||
const {
|
||||
prefixCls, disabled, onTouchStart, onTouchEnd,
|
||||
onMouseDown, onMouseUp, onMouseLeave, ...otherProps,
|
||||
} = this.props;
|
||||
return (
|
||||
<Touchable
|
||||
disabled={disabled}
|
||||
onTouchStart={onTouchStart}
|
||||
onTouchEnd={onTouchEnd}
|
||||
onMouseDown={onMouseDown}
|
||||
onMouseUp={onMouseUp}
|
||||
onMouseLeave={onMouseLeave}
|
||||
activeClassName={`${prefixCls}-handler-active`}
|
||||
>
|
||||
<span {...otherProps} />
|
||||
</Touchable>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InputHandler.propTypes = {
|
||||
const InputHandler = {
|
||||
props: {
|
||||
prefixCls: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
onTouchStart: PropTypes.func,
|
||||
onTouchEnd: PropTypes.func,
|
||||
onMouseDown: PropTypes.func,
|
||||
onMouseUp: PropTypes.func,
|
||||
onMouseLeave: PropTypes.func,
|
||||
};
|
||||
},
|
||||
render () {
|
||||
const { prefixCls, disabled } = this.$props
|
||||
const touchableProps = {
|
||||
props: {
|
||||
disabled,
|
||||
activeClassName: `${prefixCls}-handler-active`,
|
||||
},
|
||||
on: this.$listeners,
|
||||
}
|
||||
const spanProps = {
|
||||
attrs: this.$attrs,
|
||||
}
|
||||
return (
|
||||
<Touchable
|
||||
{...touchableProps}
|
||||
>
|
||||
<span {...spanProps}>
|
||||
{this.$slots.default}
|
||||
</span>
|
||||
</Touchable>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default InputHandler;
|
||||
export default InputHandler
|
||||
|
|
|
@ -1,38 +1,37 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import isNegativeZero from 'is-negative-zero';
|
||||
import InputHandler from './InputHandler';
|
||||
import PropTypes from '../../_util/vue-types'
|
||||
import BaseMixin from '../../_util/BaseMixin'
|
||||
import { initDefaultProps, hasProp } from '../../_util/props-util'
|
||||
import classNames from 'classnames'
|
||||
import isNegativeZero from 'is-negative-zero'
|
||||
import InputHandler from './InputHandler'
|
||||
|
||||
function noop() {
|
||||
function noop () {
|
||||
}
|
||||
|
||||
function preventDefault(e) {
|
||||
e.preventDefault();
|
||||
function preventDefault (e) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
function defaultParser(input) {
|
||||
return input.replace(/[^\w\.-]+/g, '');
|
||||
function defaultParser (input) {
|
||||
return input.replace(/[^\w\.-]+/g, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* When click and hold on a button - the speed of auto changin the value.
|
||||
*/
|
||||
const SPEED = 200;
|
||||
const SPEED = 200
|
||||
|
||||
/**
|
||||
* When click and hold on a button - the delay before auto changin the value.
|
||||
*/
|
||||
const DELAY = 600;
|
||||
const DELAY = 600
|
||||
|
||||
/**
|
||||
* Max Safe Integer -- on IE this is not available, so manually set the number in that case.
|
||||
* The reason this is used, instead of Infinity is because numbers above the MSI are unstable
|
||||
*/
|
||||
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1;
|
||||
|
||||
export default class InputNumber extends React.Component {
|
||||
static propTypes = {
|
||||
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1
|
||||
const inputNumberProps = {
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.number,
|
||||
PropTypes.string,
|
||||
|
@ -43,14 +42,14 @@ export default class InputNumber extends React.Component {
|
|||
]),
|
||||
focusOnUpDown: PropTypes.bool,
|
||||
autoFocus: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
onKeyDown: PropTypes.func,
|
||||
onKeyUp: PropTypes.func,
|
||||
// onChange: PropTypes.func,
|
||||
// onKeyDown: PropTypes.func,
|
||||
// onKeyUp: PropTypes.func,
|
||||
prefixCls: PropTypes.string,
|
||||
tabIndex: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
onFocus: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
// onFocus: PropTypes.func,
|
||||
// onBlur: PropTypes.func,
|
||||
readOnly: PropTypes.bool,
|
||||
max: PropTypes.number,
|
||||
min: PropTypes.number,
|
||||
|
@ -58,553 +57,534 @@ export default class InputNumber extends React.Component {
|
|||
PropTypes.number,
|
||||
PropTypes.string,
|
||||
]),
|
||||
upHandler: PropTypes.node,
|
||||
downHandler: PropTypes.node,
|
||||
upHandler: PropTypes.any,
|
||||
downHandler: PropTypes.any,
|
||||
useTouch: PropTypes.bool,
|
||||
formatter: PropTypes.func,
|
||||
parser: PropTypes.func,
|
||||
onMouseEnter: PropTypes.func,
|
||||
onMouseLeave: PropTypes.func,
|
||||
onMouseOver: PropTypes.func,
|
||||
onMouseOut: PropTypes.func,
|
||||
// onMouseEnter: PropTypes.func,
|
||||
// onMouseLeave: PropTypes.func,
|
||||
// onMouseOver: PropTypes.func,
|
||||
// onMouseOut: PropTypes.func,
|
||||
precision: PropTypes.number,
|
||||
required: PropTypes.bool,
|
||||
pattern: PropTypes.string,
|
||||
}
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
export default {
|
||||
name: 'InputNumber',
|
||||
mixins: [BaseMixin],
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
props: initDefaultProps(inputNumberProps, {
|
||||
focusOnUpDown: true,
|
||||
useTouch: false,
|
||||
prefixCls: 'rc-input-number',
|
||||
min: -MAX_SAFE_INTEGER,
|
||||
step: 1,
|
||||
style: {},
|
||||
onChange: noop,
|
||||
onKeyDown: noop,
|
||||
onFocus: noop,
|
||||
onBlur: noop,
|
||||
parser: defaultParser,
|
||||
required: false,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
let value;
|
||||
if ('value' in props) {
|
||||
value = props.value;
|
||||
}),
|
||||
data () {
|
||||
let value
|
||||
if (hasProp(this, 'value')) {
|
||||
value = this.value
|
||||
} else {
|
||||
value = props.defaultValue;
|
||||
value = this.defaultValue
|
||||
}
|
||||
value = this.toNumber(value);
|
||||
value = this.toNumber(value)
|
||||
|
||||
this.state = {
|
||||
return {
|
||||
inputValue: this.toPrecisionAsStep(value),
|
||||
value,
|
||||
focused: props.autoFocus,
|
||||
};
|
||||
sValue: value,
|
||||
focused: this.autoFocus,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.componentDidUpdate();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('value' in nextProps) {
|
||||
const value = this.state.focused
|
||||
? nextProps.value : this.getValidValue(nextProps.value, nextProps.min, nextProps.max);
|
||||
this.setState({
|
||||
value,
|
||||
inputValue: this.inputting ? value : this.toPrecisionAsStep(value),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUpdate() {
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
this.updatedFunc()
|
||||
})
|
||||
},
|
||||
beforeUpdate () {
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
this.start = this.input.selectionStart;
|
||||
this.end = this.input.selectionEnd;
|
||||
this.start = this.$refs.inputRef.selectionStart
|
||||
this.end = this.$refs.inputRef.selectionEnd
|
||||
} catch (e) {
|
||||
// Fix error in Chrome:
|
||||
// Failed to read the 'selectionStart' property from 'HTMLInputElement'
|
||||
// http://stackoverflow.com/q/21177489/3040605
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// pressingUpOrDown is true means that someone just click up or down button
|
||||
// https://github.com/ant-design/ant-design/issues/9204
|
||||
})
|
||||
},
|
||||
updated () {
|
||||
this.$nextTick(() => {
|
||||
this.updatedFunc()
|
||||
})
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.stop()
|
||||
},
|
||||
watch: {
|
||||
value (val) {
|
||||
const value = this.focused
|
||||
? val : this.getValidValue(val, this.min, this.max)
|
||||
this.setState({
|
||||
sValue: val,
|
||||
inputValue: this.inputting ? value : this.toPrecisionAsStep(value),
|
||||
})
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updatedFunc () {
|
||||
if (!this.pressingUpOrDown) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (this.props.focusOnUpDown && this.state.focused) {
|
||||
const selectionRange = this.input.setSelectionRange;
|
||||
if (this.focusOnUpDown && this.focused) {
|
||||
const selectionRange = this.$refs.inputRef.setSelectionRange
|
||||
if (selectionRange &&
|
||||
typeof selectionRange === 'function' &&
|
||||
this.start !== undefined &&
|
||||
this.end !== undefined) {
|
||||
this.input.setSelectionRange(this.start, this.end);
|
||||
this.$refs.inputRef.setSelectionRange(this.start, this.end)
|
||||
} else {
|
||||
this.focus();
|
||||
this.focus()
|
||||
}
|
||||
this.pressingUpOrDown = false;
|
||||
this.pressingUpOrDown = false
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.stop();
|
||||
}
|
||||
|
||||
onKeyDown = (e, ...args) => {
|
||||
},
|
||||
onKeyDown (e, ...args) {
|
||||
if (e.keyCode === 38) {
|
||||
const ratio = this.getRatio(e);
|
||||
this.up(e, ratio);
|
||||
this.stop();
|
||||
const ratio = this.getRatio(e)
|
||||
this.up(e, ratio)
|
||||
this.stop()
|
||||
} else if (e.keyCode === 40) {
|
||||
const ratio = this.getRatio(e);
|
||||
this.down(e, ratio);
|
||||
this.stop();
|
||||
const ratio = this.getRatio(e)
|
||||
this.down(e, ratio)
|
||||
this.stop()
|
||||
}
|
||||
const { onKeyDown } = this.props;
|
||||
if (onKeyDown) {
|
||||
onKeyDown(e, ...args);
|
||||
this.$emit('keydown', e, ...args)
|
||||
},
|
||||
onKeyUp (e, ...args) {
|
||||
this.stop()
|
||||
this.$emit('keyup', e, ...args)
|
||||
},
|
||||
onChange (e) {
|
||||
if (this.focused) {
|
||||
this.inputting = true
|
||||
}
|
||||
}
|
||||
|
||||
onKeyUp = (e, ...args) => {
|
||||
this.stop();
|
||||
const { onKeyUp } = this.props;
|
||||
if (onKeyUp) {
|
||||
onKeyUp(e, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
onChange = (e) => {
|
||||
if (this.state.focused) {
|
||||
this.inputting = true;
|
||||
}
|
||||
const input = this.props.parser(this.getValueFromEvent(e));
|
||||
this.setState({ inputValue: input });
|
||||
this.props.onChange(this.toNumberWhenUserInput(input)); // valid number or invalid string
|
||||
}
|
||||
|
||||
onFocus = (...args) => {
|
||||
const input = this.parser(this.getValueFromEvent(e))
|
||||
this.setState({ inputValue: input })
|
||||
this.$emit('change', this.toNumberWhenUserInput(input)) // valid number or invalid string
|
||||
},
|
||||
onFocus (...args) {
|
||||
this.setState({
|
||||
focused: true,
|
||||
});
|
||||
this.props.onFocus(...args);
|
||||
}
|
||||
|
||||
onBlur = (e, ...args) => {
|
||||
this.inputting = false;
|
||||
})
|
||||
this.$emit('focus', ...args)
|
||||
},
|
||||
onBlur (e, ...args) {
|
||||
this.inputting = false
|
||||
this.setState({
|
||||
focused: false,
|
||||
});
|
||||
const value = this.getCurrentValidValue(this.state.inputValue);
|
||||
e.persist(); // fix https://github.com/react-component/input-number/issues/51
|
||||
})
|
||||
const value = this.getCurrentValidValue(this.inputValue)
|
||||
// todo
|
||||
// e.persist() // fix https://github.com/react-component/input-number/issues/51
|
||||
this.setValue(value, () => {
|
||||
this.props.onBlur(e, ...args);
|
||||
});
|
||||
}
|
||||
|
||||
getCurrentValidValue(value) {
|
||||
let val = value;
|
||||
this.$emit('blur', e, ...args)
|
||||
})
|
||||
},
|
||||
getCurrentValidValue (value) {
|
||||
let val = value
|
||||
if (val === '') {
|
||||
val = '';
|
||||
val = ''
|
||||
} else if (!this.isNotCompleteNumber(val)) {
|
||||
val = this.getValidValue(val);
|
||||
val = this.getValidValue(val)
|
||||
} else {
|
||||
val = this.state.value;
|
||||
val = this.sValue
|
||||
}
|
||||
return this.toNumber(val);
|
||||
}
|
||||
|
||||
getRatio(e) {
|
||||
let ratio = 1;
|
||||
return this.toNumber(val)
|
||||
},
|
||||
getRatio (e) {
|
||||
let ratio = 1
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
ratio = 0.1;
|
||||
ratio = 0.1
|
||||
} else if (e.shiftKey) {
|
||||
ratio = 10;
|
||||
ratio = 10
|
||||
}
|
||||
return ratio;
|
||||
}
|
||||
|
||||
getValueFromEvent(e) {
|
||||
return ratio
|
||||
},
|
||||
getValueFromEvent (e) {
|
||||
// optimize for chinese input expierence
|
||||
// https://github.com/ant-design/ant-design/issues/8196
|
||||
return e.target.value.trim().replace(/。/g, '.');
|
||||
}
|
||||
|
||||
getValidValue(value, min = this.props.min, max = this.props.max) {
|
||||
let val = parseFloat(value, 10);
|
||||
return e.target.value.trim().replace(/。/g, '.')
|
||||
},
|
||||
getValidValue (value, min = this.min, max = this.max) {
|
||||
let val = parseFloat(value, 10)
|
||||
// https://github.com/ant-design/ant-design/issues/7358
|
||||
if (isNaN(val)) {
|
||||
return value;
|
||||
return value
|
||||
}
|
||||
if (val < min) {
|
||||
val = min;
|
||||
val = min
|
||||
}
|
||||
if (val > max) {
|
||||
val = max;
|
||||
val = max
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
setValue(v, callback) {
|
||||
return val
|
||||
},
|
||||
setValue (v, callback) {
|
||||
// trigger onChange
|
||||
const newValue = this.isNotCompleteNumber(parseFloat(v, 10)) ? undefined : parseFloat(v, 10);
|
||||
const changed = newValue !== this.state.value ||
|
||||
`${newValue}` !== `${this.state.inputValue}`; // https://github.com/ant-design/ant-design/issues/7363
|
||||
if (!('value' in this.props)) {
|
||||
const newValue = this.isNotCompleteNumber(parseFloat(v, 10)) ? undefined : parseFloat(v, 10)
|
||||
const changed = newValue !== this.sValue ||
|
||||
`${newValue}` !== `${this.inputValue}` // https://github.com/ant-design/ant-design/issues/7363
|
||||
if (!hasProp(this, 'value')) {
|
||||
this.setState({
|
||||
value: newValue,
|
||||
sValue: newValue,
|
||||
inputValue: this.toPrecisionAsStep(v),
|
||||
}, callback);
|
||||
}, callback)
|
||||
} else {
|
||||
// always set input value same as value
|
||||
this.setState({
|
||||
inputValue: this.toPrecisionAsStep(this.state.value),
|
||||
}, callback);
|
||||
inputValue: this.toPrecisionAsStep(this.sValue),
|
||||
}, callback)
|
||||
}
|
||||
if (changed) {
|
||||
this.props.onChange(newValue);
|
||||
this.$emit('change', newValue)
|
||||
}
|
||||
},
|
||||
getPrecision (value) {
|
||||
if (hasProp(this, 'precision')) {
|
||||
return this.precision
|
||||
}
|
||||
|
||||
getPrecision(value) {
|
||||
if ('precision' in this.props) {
|
||||
return this.props.precision;
|
||||
}
|
||||
const valueString = value.toString();
|
||||
const valueString = value.toString()
|
||||
if (valueString.indexOf('e-') >= 0) {
|
||||
return parseInt(valueString.slice(valueString.indexOf('e-') + 2), 10);
|
||||
return parseInt(valueString.slice(valueString.indexOf('e-') + 2), 10)
|
||||
}
|
||||
let precision = 0;
|
||||
let precision = 0
|
||||
if (valueString.indexOf('.') >= 0) {
|
||||
precision = valueString.length - valueString.indexOf('.') - 1;
|
||||
precision = valueString.length - valueString.indexOf('.') - 1
|
||||
}
|
||||
return precision;
|
||||
}
|
||||
|
||||
return precision
|
||||
},
|
||||
// step={1.0} value={1.51}
|
||||
// press +
|
||||
// then value should be 2.51, rather than 2.5
|
||||
// if this.props.precision is undefined
|
||||
// https://github.com/react-component/input-number/issues/39
|
||||
getMaxPrecision(currentValue, ratio = 1) {
|
||||
if ('precision' in this.props) {
|
||||
return this.props.precision;
|
||||
getMaxPrecision (currentValue, ratio = 1) {
|
||||
if (hasProp(this, 'precision')) {
|
||||
return this.precision
|
||||
}
|
||||
const { step } = this.props;
|
||||
const ratioPrecision = this.getPrecision(ratio);
|
||||
const stepPrecision = this.getPrecision(step);
|
||||
const currentValuePrecision = this.getPrecision(currentValue);
|
||||
const { step } = this
|
||||
const ratioPrecision = this.getPrecision(ratio)
|
||||
const stepPrecision = this.getPrecision(step)
|
||||
const currentValuePrecision = this.getPrecision(currentValue)
|
||||
if (!currentValue) {
|
||||
return ratioPrecision + stepPrecision;
|
||||
return ratioPrecision + stepPrecision
|
||||
}
|
||||
return Math.max(currentValuePrecision, ratioPrecision + stepPrecision);
|
||||
}
|
||||
|
||||
getPrecisionFactor(currentValue, ratio = 1) {
|
||||
const precision = this.getMaxPrecision(currentValue, ratio);
|
||||
return Math.pow(10, precision);
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.input.focus();
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.input.blur();
|
||||
}
|
||||
|
||||
formatWrapper(num) {
|
||||
return Math.max(currentValuePrecision, ratioPrecision + stepPrecision)
|
||||
},
|
||||
getPrecisionFactor (currentValue, ratio = 1) {
|
||||
const precision = this.getMaxPrecision(currentValue, ratio)
|
||||
return Math.pow(10, precision)
|
||||
},
|
||||
focus () {
|
||||
this.$refs.inputRef.focus()
|
||||
},
|
||||
blur () {
|
||||
this.$refs.inputRef.blur()
|
||||
},
|
||||
formatWrapper (num) {
|
||||
// http://2ality.com/2012/03/signedzero.html
|
||||
// https://github.com/ant-design/ant-design/issues/9439
|
||||
if (isNegativeZero(num)) {
|
||||
return '-0';
|
||||
return '-0'
|
||||
}
|
||||
if (this.props.formatter) {
|
||||
return this.props.formatter(num);
|
||||
if (this.formatter) {
|
||||
return this.formatter(num)
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
toPrecisionAsStep(num) {
|
||||
return num
|
||||
},
|
||||
toPrecisionAsStep (num) {
|
||||
if (this.isNotCompleteNumber(num) || num === '') {
|
||||
return num;
|
||||
return num
|
||||
}
|
||||
const precision = Math.abs(this.getMaxPrecision(num));
|
||||
const precision = Math.abs(this.getMaxPrecision(num))
|
||||
if (precision === 0) {
|
||||
return num.toString();
|
||||
return num.toString()
|
||||
}
|
||||
if (!isNaN(precision)) {
|
||||
return Number(num).toFixed(precision);
|
||||
return Number(num).toFixed(precision)
|
||||
}
|
||||
return num.toString();
|
||||
}
|
||||
|
||||
return num.toString()
|
||||
},
|
||||
// '1.' '1x' 'xx' '' => are not complete numbers
|
||||
isNotCompleteNumber(num) {
|
||||
isNotCompleteNumber (num) {
|
||||
return (
|
||||
isNaN(num) ||
|
||||
num === '' ||
|
||||
num === null ||
|
||||
(num && num.toString().indexOf('.') === num.toString().length - 1)
|
||||
);
|
||||
}
|
||||
|
||||
toNumber(num) {
|
||||
)
|
||||
},
|
||||
toNumber (num) {
|
||||
if (this.isNotCompleteNumber(num)) {
|
||||
return num;
|
||||
return num
|
||||
}
|
||||
if ('precision' in this.props) {
|
||||
return Number(Number(num).toFixed(this.props.precision));
|
||||
if (hasProp(this, 'precision')) {
|
||||
return Number(Number(num).toFixed(this.precision))
|
||||
}
|
||||
return Number(num);
|
||||
}
|
||||
|
||||
return Number(num)
|
||||
},
|
||||
// '1.0' '1.00' => may be a inputing number
|
||||
toNumberWhenUserInput(num) {
|
||||
toNumberWhenUserInput (num) {
|
||||
// num.length > 16 => prevent input large number will became Infinity
|
||||
if ((/\.\d*0$/.test(num) || num.length > 16) && this.state.focused) {
|
||||
return num;
|
||||
if ((/\.\d*0$/.test(num) || num.length > 16) && this.focused) {
|
||||
return num
|
||||
}
|
||||
return this.toNumber(num);
|
||||
}
|
||||
|
||||
upStep(val, rat) {
|
||||
const { step, min } = this.props;
|
||||
const precisionFactor = this.getPrecisionFactor(val, rat);
|
||||
const precision = Math.abs(this.getMaxPrecision(val, rat));
|
||||
let result;
|
||||
return this.toNumber(num)
|
||||
},
|
||||
upStep (val, rat) {
|
||||
const { step, min } = this
|
||||
const precisionFactor = this.getPrecisionFactor(val, rat)
|
||||
const precision = Math.abs(this.getMaxPrecision(val, rat))
|
||||
let result
|
||||
if (typeof val === 'number') {
|
||||
result =
|
||||
((precisionFactor * val + precisionFactor * step * rat) /
|
||||
precisionFactor).toFixed(precision);
|
||||
precisionFactor).toFixed(precision)
|
||||
} else {
|
||||
result = min === -Infinity ? step : min;
|
||||
result = min === -Infinity ? step : min
|
||||
}
|
||||
return this.toNumber(result);
|
||||
}
|
||||
|
||||
downStep(val, rat) {
|
||||
const { step, min } = this.props;
|
||||
const precisionFactor = this.getPrecisionFactor(val, rat);
|
||||
const precision = Math.abs(this.getMaxPrecision(val, rat));
|
||||
let result;
|
||||
return this.toNumber(result)
|
||||
},
|
||||
downStep (val, rat) {
|
||||
const { step, min } = this
|
||||
const precisionFactor = this.getPrecisionFactor(val, rat)
|
||||
const precision = Math.abs(this.getMaxPrecision(val, rat))
|
||||
let result
|
||||
if (typeof val === 'number') {
|
||||
result =
|
||||
((precisionFactor * val - precisionFactor * step * rat) /
|
||||
precisionFactor).toFixed(precision);
|
||||
precisionFactor).toFixed(precision)
|
||||
} else {
|
||||
result = min === -Infinity ? -step : min;
|
||||
result = min === -Infinity ? -step : min
|
||||
}
|
||||
return this.toNumber(result);
|
||||
}
|
||||
|
||||
step(type, e, ratio = 1, recursive) {
|
||||
this.stop();
|
||||
return this.toNumber(result)
|
||||
},
|
||||
stepFn (type, e, ratio = 1, recursive) {
|
||||
this.stop()
|
||||
if (e) {
|
||||
e.persist();
|
||||
e.preventDefault();
|
||||
// e.persist()
|
||||
e.preventDefault()
|
||||
}
|
||||
const props = this.props;
|
||||
if (props.disabled) {
|
||||
return;
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
const value = this.getCurrentValidValue(this.state.inputValue) || 0;
|
||||
const { max, min } = this
|
||||
const value = this.getCurrentValidValue(this.inputValue) || 0
|
||||
if (this.isNotCompleteNumber(value)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
let val = this[`${type}Step`](value, ratio);
|
||||
const outOfRange = val > props.max || val < props.min;
|
||||
if (val > props.max) {
|
||||
val = props.max;
|
||||
} else if (val < props.min) {
|
||||
val = props.min;
|
||||
let val = this[`${type}Step`](value, ratio)
|
||||
const outOfRange = val > max || val < min
|
||||
if (val > max) {
|
||||
val = max
|
||||
} else if (val < min) {
|
||||
val = min
|
||||
}
|
||||
this.setValue(val);
|
||||
this.setValue(val)
|
||||
this.setState({
|
||||
focused: true,
|
||||
});
|
||||
})
|
||||
if (outOfRange) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
this.autoStepTimer = setTimeout(() => {
|
||||
this[type](e, ratio, true);
|
||||
}, recursive ? SPEED : DELAY);
|
||||
}
|
||||
|
||||
stop = () => {
|
||||
this[type](e, ratio, true)
|
||||
}, recursive ? SPEED : DELAY)
|
||||
},
|
||||
stop () {
|
||||
if (this.autoStepTimer) {
|
||||
clearTimeout(this.autoStepTimer);
|
||||
clearTimeout(this.autoStepTimer)
|
||||
}
|
||||
}
|
||||
|
||||
down = (e, ratio, recursive) => {
|
||||
this.pressingUpOrDown = true;
|
||||
this.step('down', e, ratio, recursive);
|
||||
}
|
||||
|
||||
up = (e, ratio, recursive) => {
|
||||
this.pressingUpOrDown = true;
|
||||
this.step('up', e, ratio, recursive);
|
||||
}
|
||||
|
||||
saveInput = (node) => {
|
||||
this.input = node;
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = { ...this.props };
|
||||
const { prefixCls, disabled, readOnly, useTouch } = props;
|
||||
},
|
||||
down (e, ratio, recursive) {
|
||||
this.pressingUpOrDown = true
|
||||
this.stepFn('down', e, ratio, recursive)
|
||||
},
|
||||
up (e, ratio, recursive) {
|
||||
this.pressingUpOrDown = true
|
||||
this.stepFn('up', e, ratio, recursive)
|
||||
},
|
||||
handleInputClick () {
|
||||
this.$emit('click')
|
||||
},
|
||||
},
|
||||
render () {
|
||||
const { prefixCls, disabled, readOnly, useTouch } = this.$props
|
||||
const classes = classNames({
|
||||
[prefixCls]: true,
|
||||
[props.className]: !!props.className,
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
[`${prefixCls}-focused`]: this.state.focused,
|
||||
});
|
||||
let upDisabledClass = '';
|
||||
let downDisabledClass = '';
|
||||
const { value } = this.state;
|
||||
if (value || value === 0) {
|
||||
if (!isNaN(value)) {
|
||||
const val = Number(value);
|
||||
if (val >= props.max) {
|
||||
upDisabledClass = `${prefixCls}-handler-up-disabled`;
|
||||
[`${prefixCls}-focused`]: this.focused,
|
||||
})
|
||||
let upDisabledClass = ''
|
||||
let downDisabledClass = ''
|
||||
const { sValue } = this
|
||||
if (sValue || sValue === 0) {
|
||||
if (!isNaN(sValue)) {
|
||||
const val = Number(sValue)
|
||||
if (val >= this.max) {
|
||||
upDisabledClass = `${prefixCls}-handler-up-disabled`
|
||||
}
|
||||
if (val <= props.min) {
|
||||
downDisabledClass = `${prefixCls}-handler-down-disabled`;
|
||||
if (val <= this.min) {
|
||||
downDisabledClass = `${prefixCls}-handler-down-disabled`
|
||||
}
|
||||
} else {
|
||||
upDisabledClass = `${prefixCls}-handler-up-disabled`;
|
||||
downDisabledClass = `${prefixCls}-handler-down-disabled`;
|
||||
upDisabledClass = `${prefixCls}-handler-up-disabled`
|
||||
downDisabledClass = `${prefixCls}-handler-down-disabled`
|
||||
}
|
||||
}
|
||||
|
||||
const editable = !props.readOnly && !props.disabled;
|
||||
const editable = !this.readOnly && !this.disabled
|
||||
|
||||
// focus state, show input value
|
||||
// unfocus state, show valid value
|
||||
let inputDisplayValue;
|
||||
if (this.state.focused) {
|
||||
inputDisplayValue = this.state.inputValue;
|
||||
let inputDisplayValue
|
||||
if (this.focused) {
|
||||
inputDisplayValue = this.inputValue
|
||||
} else {
|
||||
inputDisplayValue = this.toPrecisionAsStep(this.state.value);
|
||||
inputDisplayValue = this.toPrecisionAsStep(this.sValue)
|
||||
}
|
||||
|
||||
if (inputDisplayValue === undefined || inputDisplayValue === null) {
|
||||
inputDisplayValue = '';
|
||||
inputDisplayValue = ''
|
||||
}
|
||||
|
||||
let upEvents;
|
||||
let downEvents;
|
||||
let upEvents
|
||||
let downEvents
|
||||
if (useTouch) {
|
||||
upEvents = {
|
||||
onTouchStart: (editable && !upDisabledClass) ? this.up : noop,
|
||||
onTouchEnd: this.stop,
|
||||
};
|
||||
touchstart: (editable && !upDisabledClass) ? this.up : noop,
|
||||
touchend: this.stop,
|
||||
}
|
||||
downEvents = {
|
||||
onTouchStart: (editable && !downDisabledClass) ? this.down : noop,
|
||||
onTouchEnd: this.stop,
|
||||
};
|
||||
touchstart: (editable && !downDisabledClass) ? this.down : noop,
|
||||
touchend: this.stop,
|
||||
}
|
||||
} else {
|
||||
upEvents = {
|
||||
onMouseDown: (editable && !upDisabledClass) ? this.up : noop,
|
||||
onMouseUp: this.stop,
|
||||
onMouseLeave: this.stop,
|
||||
};
|
||||
downEvents = {
|
||||
onMouseDown: (editable && !downDisabledClass) ? this.down : noop,
|
||||
onMouseUp: this.stop,
|
||||
onMouseLeave: this.stop,
|
||||
};
|
||||
mousedown: (editable && !upDisabledClass) ? this.up : noop,
|
||||
mouseup: this.stop,
|
||||
mouseleave: this.stop,
|
||||
}
|
||||
downEvents = {
|
||||
mousedown: (editable && !downDisabledClass) ? this.down : noop,
|
||||
mouseup: this.stop,
|
||||
mouseleave: this.stop,
|
||||
}
|
||||
}
|
||||
const inputDisplayValueFormat = this.formatWrapper(inputDisplayValue)
|
||||
const isUpDisabled = !!upDisabledClass || disabled || readOnly
|
||||
const isDownDisabled = !!downDisabledClass || disabled || readOnly
|
||||
const contentProps = {
|
||||
on: this.$listeners,
|
||||
class: classes,
|
||||
}
|
||||
const upHandlerProps = {
|
||||
props: {
|
||||
disabled: isUpDisabled,
|
||||
prefixCls,
|
||||
},
|
||||
attrs: {
|
||||
unselectable: 'unselectable',
|
||||
role: 'button',
|
||||
'aria-label': 'Increase Value',
|
||||
'aria-disabled': !!isUpDisabled,
|
||||
},
|
||||
class: `${prefixCls}-handler ${prefixCls}-handler-up ${upDisabledClass}`,
|
||||
on: upEvents,
|
||||
ref: 'up',
|
||||
}
|
||||
const downHandlerProps = {
|
||||
props: {
|
||||
disabled: isDownDisabled,
|
||||
prefixCls,
|
||||
},
|
||||
attrs: {
|
||||
unselectable: 'unselectable',
|
||||
role: 'button',
|
||||
'aria-label': 'Decrease Value',
|
||||
'aria-disabled': !!isDownDisabled,
|
||||
},
|
||||
class: `${prefixCls}-handler ${prefixCls}-handler-down ${downDisabledClass}`,
|
||||
on: downEvents,
|
||||
ref: 'down',
|
||||
}
|
||||
const inputDisplayValueFormat = this.formatWrapper(inputDisplayValue);
|
||||
const isUpDisabled = !!upDisabledClass || disabled || readOnly;
|
||||
const isDownDisabled = !!downDisabledClass || disabled || readOnly;
|
||||
// ref for test
|
||||
return (
|
||||
<div
|
||||
className={classes}
|
||||
style={props.style}
|
||||
onMouseEnter={props.onMouseEnter}
|
||||
onMouseLeave={props.onMouseLeave}
|
||||
onMouseOver={props.onMouseOver}
|
||||
onMouseOut={props.onMouseOut}
|
||||
{...contentProps}
|
||||
>
|
||||
<div className={`${prefixCls}-handler-wrap`}>
|
||||
<div class={`${prefixCls}-handler-wrap`}>
|
||||
<InputHandler
|
||||
ref="up"
|
||||
disabled={isUpDisabled}
|
||||
prefixCls={prefixCls}
|
||||
unselectable="unselectable"
|
||||
{...upEvents}
|
||||
role="button"
|
||||
aria-label="Increase Value"
|
||||
aria-disabled={!!isUpDisabled}
|
||||
className={`${prefixCls}-handler ${prefixCls}-handler-up ${upDisabledClass}`}
|
||||
{...upHandlerProps}
|
||||
>
|
||||
{this.props.upHandler || <span
|
||||
unselectable="unselectable"
|
||||
className={`${prefixCls}-handler-up-inner`}
|
||||
{this.upHandler || <span
|
||||
unselectable='unselectable'
|
||||
class={`${prefixCls}-handler-up-inner`}
|
||||
onClick={preventDefault}
|
||||
/>}
|
||||
</InputHandler>
|
||||
<InputHandler
|
||||
ref="down"
|
||||
disabled={isDownDisabled}
|
||||
prefixCls={prefixCls}
|
||||
unselectable="unselectable"
|
||||
{...downEvents}
|
||||
role="button"
|
||||
aria-label="Decrease Value"
|
||||
aria-disabled={!!isDownDisabled}
|
||||
className={`${prefixCls}-handler ${prefixCls}-handler-down ${downDisabledClass}`}
|
||||
{...downHandlerProps}
|
||||
>
|
||||
{this.props.downHandler || <span
|
||||
unselectable="unselectable"
|
||||
className={`${prefixCls}-handler-down-inner`}
|
||||
{this.downHandler || <span
|
||||
unselectable='unselectable'
|
||||
class={`${prefixCls}-handler-down-inner`}
|
||||
onClick={preventDefault}
|
||||
/>}
|
||||
</InputHandler>
|
||||
</div>
|
||||
<div
|
||||
className={`${prefixCls}-input-wrap`}
|
||||
role="spinbutton"
|
||||
aria-valuemin={props.min}
|
||||
aria-valuemax={props.max}
|
||||
aria-valuenow={value}
|
||||
class={`${prefixCls}-input-wrap`}
|
||||
role='spinbutton'
|
||||
aria-valuemin={this.min}
|
||||
aria-valuemax={this.max}
|
||||
aria-valuenow={sValue}
|
||||
>
|
||||
<input
|
||||
required={props.required}
|
||||
type={props.type}
|
||||
placeholder={props.placeholder}
|
||||
onClick={props.onClick}
|
||||
className={`${prefixCls}-input`}
|
||||
tabIndex={props.tabIndex}
|
||||
autoComplete="off"
|
||||
required={this.required}
|
||||
type={this.type}
|
||||
placeholder={this.placeholder}
|
||||
onClick={this.handleInputClick}
|
||||
class={`${prefixCls}-input`}
|
||||
tabIndex={this.tabIndex}
|
||||
autoComplete='off'
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onKeyDown={editable ? this.onKeyDown : noop}
|
||||
onKeyUp={editable ? this.onKeyUp : noop}
|
||||
autoFocus={props.autoFocus}
|
||||
maxLength={props.maxLength}
|
||||
readOnly={props.readOnly}
|
||||
disabled={props.disabled}
|
||||
max={props.max}
|
||||
min={props.min}
|
||||
step={props.step}
|
||||
name={props.name}
|
||||
id={props.id}
|
||||
onKeydown={editable ? this.onKeyDown : noop}
|
||||
onKeyup={editable ? this.onKeyUp : noop}
|
||||
autoFocus={this.autoFocus}
|
||||
maxLength={this.maxLength}
|
||||
readOnly={this.readOnly}
|
||||
disabled={this.disabled}
|
||||
max={this.max}
|
||||
min={this.min}
|
||||
step={this.step}
|
||||
name={this.name}
|
||||
id={this.id}
|
||||
onChange={this.onChange}
|
||||
ref={this.saveInput}
|
||||
ref='inputRef'
|
||||
value={inputDisplayValueFormat}
|
||||
pattern={props.pattern}
|
||||
pattern={this.pattern}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -3,11 +3,7 @@ const AsyncComp = () => {
|
|||
const hashs = window.location.hash.split('/')
|
||||
const d = hashs[hashs.length - 1]
|
||||
return {
|
||||
<<<<<<< HEAD
|
||||
component: import(`../components/vc-m-feedback/demo/${d}`),
|
||||
=======
|
||||
component: import(`../components/table/demo/${d}`),
|
||||
>>>>>>> 5d2271a131c74d672cc0cfada07e256752160b41
|
||||
component: import(`../components/vc-input-number/demo/${d}`),
|
||||
}
|
||||
}
|
||||
export default [
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
"dom-scroll-into-view": "^1.2.1",
|
||||
"enquire.js": "^2.1.6",
|
||||
"eslint-plugin-vue": "^3.13.0",
|
||||
"is-negative-zero": "^2.0.0",
|
||||
"lodash": "^4.17.5",
|
||||
"moment": "^2.21.0",
|
||||
"omit.js": "^1.0.0",
|
||||
|
|
Loading…
Reference in New Issue