import React, { useEffect, useState, useRef, useCallback } from 'react'; import { Input, Balloon, Icon } from '@alife/cn-ui'; import classnames from 'classnames'; import { volumeInputProps, valueProps, currentEnum, } from 'src/types/op-volume-input'; import OPLayout from '../op-layout'; import event from '../event'; import './index.scss'; const { Tooltip } = Balloon; const { Content } = OPLayout; export default function OPVolumeInput(props: volumeInputProps) { const { value: propValue = { length: '', width: '', height: '', }, autoFocus = true, state = '', unit = 'cm', current: propCurrent = 'length', locale = { length: '长', width: '宽', height: '高', tooltip: '按回车确认', }, onChange, onEnter, size = 'large', } = props; const [focus, setFocus] = useState({ length: false, width: false, height: false, }); const [value, setValue] = useState(propValue); const [current, setCurrent] = useState(propCurrent); const lengthRef = useRef(null); const widthRef = useRef(null); const heightRef = useRef(null); const isFocus = focus.length || focus.width || focus.height; const handleChangeInput = useCallback( (type: string) => { let newCurrent = '' as currentEnum; switch (current) { case 'length': if (type === 'left') { newCurrent = 'height'; } else { newCurrent = 'width'; } break; case 'width': if (type === 'left') { newCurrent = 'length'; } else { newCurrent = 'height'; } break; case 'height': if (type === 'left') { newCurrent = 'width'; } else { newCurrent = 'length'; } break; default: break; } setCurrent(newCurrent); }, [current], ); const handleLeft = useCallback(() => { handleChangeInput('left'); }, [handleChangeInput]); const handleRight = useCallback(() => { handleChangeInput('right'); }, [handleChangeInput]); const handleEnter = useCallback(() => { let newCurrent = '' as currentEnum; const currentValue = value?.[current] as currentEnum; if (!currentValue) { return; } switch (current) { case 'length': newCurrent = 'width'; break; case 'width': newCurrent = 'height'; break; case 'height': newCurrent = 'height'; onEnter?.(value); break; default: break; } setCurrent(newCurrent); }, [current, onEnter, value]); const onInputFocus = (type: currentEnum) => { setFocus({ length: false, width: false, height: false, [type]: true, }); }; const onInputBlur = (type: currentEnum) => { setFocus({ ...focus, [type]: false, }); }; const handleChange = (type: currentEnum, v: string) => { if (/^\d+\.*\d*$/.test(v) || !v) { const newValue = { ...value, [type]: v.trim(), } as valueProps; setValue(newValue); onChange && onChange({ current, value: { ...value, [type]: v.trim(), }, }); } }; const renderText = (text: string, unit: string) => ( <> {text} ({unit}) ); useEffect(() => { const { length, width, height } = value as valueProps; if (autoFocus) { switch (current) { case 'length': { const cur = lengthRef.current; if (cur) { cur.focus(); cur.getInputNode().setSelectionRange(length.length, length.length); } break; } case 'width': { const cur = widthRef.current; if (cur) { cur.focus(); cur.getInputNode().setSelectionRange(width.length, width.length); } break; } case 'height': { const cur = heightRef.current; if (cur) { cur.focus(); cur.getInputNode().setSelectionRange(height.length, height.length); } break; } default: break; } } event.bind('enter', handleEnter); event.bind('left', handleLeft); event.bind('right', handleRight); return () => { event.unbind('enter', handleEnter); event.unbind('left', handleLeft); event.unbind('right', handleRight); }; }, [autoFocus, current, value, handleEnter, handleLeft, handleRight]); return (
onInputFocus('length')} onBlur={() => onInputBlur('length')} trim onChange={(val) => handleChange('length', val)} /> {locale.tooltip} onInputFocus('width')} onBlur={() => onInputBlur('width')} value={value?.width} size='large' className={`op-volume-input-width ${ focus.width ? 'op-volume-input-focus' : '' }`} trim onChange={(val) => handleChange('width', val)} /> {locale.tooltip} onInputFocus('height')} onBlur={() => onInputBlur('height')} value={value?.height} size='large' className={`op-volume-input-height ${ focus.height ? 'op-volume-input-focus' : '' }`} trim onChange={(val) => handleChange('height', val)} /> {locale.tooltip}
); }