1- import { default as InputNumber } from "antd/es/input-number" ;
1+ import React , { useState , useRef , useEffect , useCallback , useMemo , ReactNode } from "react" ;
2+ import { default as InputNumber } from "antd/es/input-number" ;
23import { NumberControl , RangeControl , StringControl } from "comps/controls/codeControl" ;
34import { BoolControl } from "comps/controls/boolControl" ;
45import { trans } from "i18n" ;
@@ -35,59 +36,123 @@ const childrenMap = {
3536 suffix : StringControl ,
3637} ;
3738
38- let float = false ;
39- let step = 1 ;
40- let precision = 0 ;
39+ const getBaseValue : ColumnTypeViewFn < typeof childrenMap , number , number > = ( props ) => props . text ;
4140
42- const getBaseValue : ColumnTypeViewFn < typeof childrenMap , number , number > = (
43- props
44- ) => {
45- return props . text
41+ type NumberViewProps = {
42+ value : number ;
43+ prefix : string ;
44+ suffix : string ;
45+ prefixIcon : ReactNode ;
46+ suffixIcon : ReactNode ;
47+ float : boolean ;
48+ precision : number ;
4649} ;
4750
51+ type NumberEditProps = {
52+ value : number ;
53+ onChange : ( value : number ) => void ;
54+ onChangeEnd : ( ) => void ;
55+ step : number ;
56+ precision : number ;
57+ float : boolean ;
58+ } ;
59+
60+ const ColumnNumberView = React . memo ( ( props : NumberViewProps ) => {
61+ const formattedValue = useMemo ( ( ) => {
62+ let result = ! props . float ? Math . floor ( props . value ) : props . value ;
63+ if ( props . float ) {
64+ result = Number ( result . toFixed ( props . precision + 1 ) ) ;
65+ }
66+ return result ;
67+ } , [ props . value , props . float , props . precision ] ) ;
68+
69+ return (
70+ < >
71+ { hasIcon ( props . prefixIcon ) && (
72+ < span > { props . prefixIcon } </ span >
73+ ) }
74+ < span > { props . prefix + formattedValue + props . suffix } </ span >
75+ { hasIcon ( props . suffixIcon ) && (
76+ < span > { props . suffixIcon } </ span >
77+ ) }
78+ </ >
79+ ) ;
80+ } ) ;
81+
82+ ColumnNumberView . displayName = 'ColumnNumberView' ;
83+
84+
85+ const ColumnNumberEdit = React . memo ( ( props : NumberEditProps ) => {
86+ const [ currentValue , setCurrentValue ] = useState ( props . value ) ;
87+ const mountedRef = useRef ( true ) ;
88+
89+ // Cleanup on unmount
90+ useEffect ( ( ) => {
91+ return ( ) => {
92+ mountedRef . current = false ;
93+ setCurrentValue ( 0 ) ;
94+ } ;
95+ } , [ ] ) ;
96+
97+ const handleChange = useCallback ( ( value : string | number | null ) => {
98+ if ( ! mountedRef . current ) return ;
99+ const newValue = typeof value === 'number' ? value : 0 ;
100+ const finalValue = ! props . float ? Math . floor ( newValue ) : newValue ;
101+ props . onChange ( finalValue ) ;
102+ setCurrentValue ( finalValue ) ;
103+ } , [ props . onChange , props . float ] ) ;
104+
105+ const handleBlur = useCallback ( ( ) => {
106+ if ( ! mountedRef . current ) return ;
107+ props . onChangeEnd ( ) ;
108+ } , [ props . onChangeEnd ] ) ;
109+
110+ const handlePressEnter = useCallback ( ( ) => {
111+ if ( ! mountedRef . current ) return ;
112+ props . onChangeEnd ( ) ;
113+ } , [ props . onChangeEnd ] ) ;
114+
115+ return (
116+ < InputNumberWrapper >
117+ < InputNumber
118+ step = { props . step }
119+ value = { currentValue }
120+ autoFocus
121+ variant = "borderless"
122+ onChange = { handleChange }
123+ precision = { props . float ? props . precision : 0 }
124+ onBlur = { handleBlur }
125+ onPressEnter = { handlePressEnter }
126+ />
127+ </ InputNumberWrapper >
128+ ) ;
129+ } ) ;
130+
131+ ColumnNumberEdit . displayName = 'NumberEdit' ;
132+
48133export const ColumnNumberComp = ( function ( ) {
49134 return new ColumnTypeCompBuilder (
50135 childrenMap ,
51136 ( props , dispatch ) => {
52- float = props . float ;
53- step = props . step ;
54- precision = props . precision ;
55137 const value = props . changeValue ?? getBaseValue ( props , dispatch ) ;
56- let formattedValue : string | number = ! float ? Math . floor ( value ) : value ;
57- if ( float ) {
58- formattedValue = formattedValue . toFixed ( precision + 1 ) ;
59- }
60- return (
61- < > { hasIcon ( props . prefixIcon ) && (
62- < span > { props . prefixIcon } </ span >
63- ) }
64- < span > { props . prefix + formattedValue + props . suffix } </ span >
65- { hasIcon ( props . suffixIcon ) && (
66- < span > { props . suffixIcon } </ span >
67- ) } </ >
68- ) ;
138+ return < ColumnNumberView value = { value } { ...props } /> ;
69139 } ,
70140 ( nodeValue ) => nodeValue . text . value ,
71- getBaseValue ,
141+ getBaseValue
72142 )
73143 . setEditViewFn ( ( props ) => {
144+ const { value, onChange, onChangeEnd, otherProps } = props ;
74145 return (
75- < InputNumberWrapper >
76- < InputNumber
77- step = { step }
78- defaultValue = { props . value }
79- autoFocus
80- variant = "borderless"
81- onChange = { ( value ) => {
82- value = value ?? 0 ;
83- props . onChange ( ! float ? Math . floor ( value ) : value ) ;
84- } }
85- precision = { float ? precision : 0 }
86- onBlur = { props . onChangeEnd }
87- onPressEnter = { props . onChangeEnd }
146+ < ColumnNumberEdit
147+ value = { value }
148+ onChange = { onChange }
149+ onChangeEnd = { onChangeEnd }
150+ step = { otherProps ?. step ?? 1 }
151+ precision = { otherProps ?. precision ?? 0 }
152+ float = { otherProps ?. float ?? false }
88153 />
89- </ InputNumberWrapper >
90- ) } )
154+ ) ;
155+ } )
91156 . setPropertyViewFn ( ( children ) => {
92157 return (
93158 < >
@@ -99,15 +164,15 @@ export const ColumnNumberComp = (function () {
99164 label : trans ( "table.numberStep" ) ,
100165 tooltip : trans ( "table.numberStepTooltip" ) ,
101166 onFocus : ( focused ) => {
102- if ( ! focused ) {
167+ if ( ! focused ) {
103168 const value = children . step . getView ( ) ;
104169 const isFloat = children . float . getView ( ) ;
105170 const newValue = ! isFloat ? Math . floor ( value ) : value ;
106171 children . step . dispatchChangeValueAction ( String ( newValue ) ) ;
107172 }
108173 }
109174 } ) }
110- { float && (
175+ { children . float . getView ( ) && (
111176 children . precision . propertyView ( {
112177 label : trans ( "table.precision" ) ,
113178 } )
0 commit comments