import React, { useRef, useState } from 'react'; // import { withKnobs, text, boolean } from '@storybook/addon-knobs'; import './inputNumber.scss'; import InputNumber from '../index'; import Button from '../../button/index'; import { withField, Form } from '../../index'; import { useFormApi } from '../../form'; import { Space } from '../../index'; export default { title: 'InputNumber', } function log(v, e) { const type = typeof v; console.log(type, v); } const createOnChange = changeFn => { return (...args) => { log(...args); if (typeof changeFn === 'function') { changeFn(...args); } }; }; export const _InputNumber = () => { const Demo = () => { const [controlledValue, setControlledValue] = useState(10.1); const controlledOnChange = createOnChange(setControlledValue); const [controlledValue2, setControlledValue2] = useState(9); const controlledOnChange2 = createOnChange(setControlledValue2); const [decimal, setDecimal] = useState(10.01); const decimalOnChange = createOnChange(setDecimal); const [formattedVal, setFormattedVal] = useState(10.02); const formattedValOnChange = createOnChange(setFormattedVal); const [formattedDecimal, setFormattedDecimal] = useState(10.03); const formattedDecimalOnChange = createOnChange(setFormattedDecimal); return (



`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />


`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />



`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} onChange={formattedValOnChange} value={formattedVal} />
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} onChange={formattedDecimalOnChange} value={formattedDecimal} />
); }; return ; }; _InputNumber.story = { name: 'Input number', }; export const InputnumberUseRefCallFocus = () => { const Demo = () => { const ref = useRef(); const focus = () => { ref.current && ref.current.focus(); }; const blur = () => ref.current && ref.current.blur(); return ( <> ); }; return ; }; InputnumberUseRefCallFocus.story = { name: 'inputnumber use ref call focus', }; export const UncontrolledInputNumber = () => { const Demo = function Demo(props = {}) { return (
defaultValue

defaultValue + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
defaultValue + precision + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
defaultValue + precision + max + min + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
); }; return ; }; UncontrolledInputNumber.story = { name: 'uncontrolled InputNumber', }; export const ControlledInputNumber = () => { const ControlledDemo = function ControlledDemo(props = {}) { const [value, setValue] = useState(0); const _setValue = createOnChange(setValue); const [value1, setValue1] = useState(0.234); const _setValue1 = createOnChange(setValue1); const [value2, setValue2] = useState(1000); const _setValue2 = createOnChange(setValue2); const [value3, setValue3] = useState(0.21); const _setValue3 = createOnChange(setValue3); const [value4, setValue4] = useState(3); const randomSetValue4 = createOnChange(v => { setValue4(Math.random() * 3 + 1); }); const [value5, setValue5] = useState(5); const randomSetValue5 = createOnChange(v => { setValue5(Math.random() * 5 + 1); }); const [value6, setValue6] = useState(6); const randomSetValue6 = createOnChange(v => { const num = Math.random() * 10 + 9; console.log('random set: ', num); setValue6(num); }); const _setValue6 = createOnChange(setValue6); return (
defaultValue

value

value + onChange
console.log('blur')} />
value + precision + onChange

value + step + precision + onChange

value + precision + onChange + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
random set value + precision

random set value + precision + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
random set value + max + min + precision + onChange

); }; return ; }; ControlledInputNumber.story = { name: 'controlled InputNumber', }; export const InnnerButtons = () => { const Demo = () => { return (

); }; return ; }; InnnerButtons.story = { name: 'innnerButtons', }; export const ShiftStep = () => { const Demo = () => { return (
); }; return ; }; ShiftStep.story = { name: 'shiftStep', }; export const OnChangeLimit = () => { const Demo = () => { const [disabled, setDisabled] = useState(true); const [disabled2, setDisabled2] = useState(false); const [val, setVal] = useState(2); return ( <>

数值没有持续变化说明正常,v1.10.0修复



点击2后点击输入框,然后点击按钮会触发
{disabled ? (
{ setDisabled(false); }} > {val}
) : ( setVal(res)} /> )}

点击按钮后切换 disabled 状态
disablde: {String(disabled2)}
setDisabled2(true)} />
); }; return ; }; OnChangeLimit.story = { name: 'onChange无限触发问题', }; export const ClearIconPosition = () => { const Demo = () => { return ; }; return ; }; ClearIconPosition.story = { name: 'clear icon 位置', }; export const UncontrolledKeepFocus = () => { const Demo = () => { const [val, setVal] = useState(2); const [val2, setVal2] = useState(2); return (
defaultValue

defaultValue + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
defaultValue + precision + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
defaultValue + precision + max + min + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
); }; return ; }; UncontrolledKeepFocus.story = { name: 'uncontrolled keepFocus', }; export const ControlledKeepFocus = () => { const Demo = () => { const [value, setValue] = useState(0); const _setValue = createOnChange(setValue); const [value1, setValue1] = useState(0.234); const _setValue1 = createOnChange(setValue1); const [value2, setValue2] = useState(1000); const _setValue2 = createOnChange(setValue2); const [value3, setValue3] = useState(0.21); const _setValue3 = createOnChange(setValue3); const [value4, setValue4] = useState(3); const randomSetValue4 = createOnChange(v => { setValue4(Math.random() * 3 + 1); }); const [value5, setValue5] = useState(5); const randomSetValue5 = createOnChange(v => { setValue5(Math.random() * 5 + 1); }); const [value6, setValue6] = useState(6); const randomSetValue6 = createOnChange(v => { const num = Math.random() * 10 + 9; console.log('random set: ', num); setValue6(num); }); const _setValue6 = createOnChange(setValue6); return (
defaultValue

value

value + onChange
console.log('blur')} />
value + precision + onChange

value + step + precision + onChange

value + precision + onChange + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
random set value + precision

random set value + precision + formatter + parser
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\$\s?|(,*)/g, '')} />
random set value + max + min + precision + onChange

); }; return ; }; ControlledKeepFocus.story = { name: 'controlled keepFocus', }; export const DisabledStyle = () => { const Demo = () => { return ( <>





); }; return ; }; DisabledStyle.story = { name: 'disabled style', }; export const FormCustomInput = () => { const Demo = () => { const CustomInput = withField(InputNumber, { onKeyChangeFnName: 'onNumberChange' }); return ( <>

not controlled + without formatter

console.log('inputNumber change', ...args)} onNumberChange={(...args) => console.log('inputNumber number change', ...args)} />

not controlled + formatter(onChange会包括英文字符,onNumberChange不包括)

`${value}`.replace(/\D/g, '')} onChange={(...args) => console.log('inputNumber change', ...args)} onNumberChange={(...args) => console.log('inputNumber number change', ...args)} />
console.log(v)}>

Form + Form.InputNumber + formatter + onChange(onChange包括英文字符,显示没有英文字符)

`${value}`.replace(/\D/g, '')} onChange={(...args) => console.log('form inputNumber change', ...args)} />

Form + withField InputNumber + formatter + onNumberChange(onNumberChange不包括英文字符,显示也不包括英文字符)

`${value}`.replace(/\D/g, '')} />

type=number (TODO:需要关注内置的按钮+不同浏览器对type=number的支持情况,比如 safari 貌似就不支持)

console.log('inputNumber change', ...args)} onNumberChange={(...args) => console.log('inputNumber number change', ...args)} />

测试 formatter + parser 是否正常

console.log(`Changed to: [${typeof v}] ${v}`)} defaultValue={1000} min={0} formatter={value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={value => value.replace(/\¥\s?|(,*)/g, '')} /> ); }; return ; }; FormCustomInput.story = { name: 'Form.CustomInput', }; export const FixPrecision = () => { const [value, setValue] = useState(5.12); const [value2, setValue2] = useState(5.12); return (
setValue(v)} value={value} style={{ width: 190 }} precision={2} /> console.log('blur')} onChange={v => setValue2(v)} value={value2} style={{ width: 190 }} precision={2} />
); } /** * 受控传超出 min value 的值,需要触发 onChange * 不然在 Form 中使用可能会导致 Form State 与 InputNumber 展示的值不同问题 */ export const FixMinValue = () => { const [value, setValue] = useState(); const formRef = useFormApi(); return (
{ console.log('inputNumber1 change', `'${v}'`, e); setValue(v); }} /> { console.log('inputNumber2 change', v, e); }} />
{ console.log('form inputNumber change', v, e); }} />
); } FixMinValue.storyName = 'fix min value'; /** * fix InputNumber precision 删除后,输入非法字符显示 0.00 * https://github.com/DouyinFE/semi-design/issues/786 */ export const FixPrecision786 = () => { return (
); } FixPrecision786.storyName = 'fix precision 删除后输入非法值会显示 0.00'; export const FixFormValidate = () => { return (
); } FixFormValidate.storyName = 'fix form validate'; export const InputNumberA11y = () => { return (
); } InputNumberA11y.storyName = "inputNumber a11y";