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" ;
2
3
import { NumberControl , RangeControl , StringControl } from "comps/controls/codeControl" ;
3
4
import { BoolControl } from "comps/controls/boolControl" ;
4
5
import { trans } from "i18n" ;
@@ -35,59 +36,123 @@ const childrenMap = {
35
36
suffix : StringControl ,
36
37
} ;
37
38
38
- let float = false ;
39
- let step = 1 ;
40
- let precision = 0 ;
39
+ const getBaseValue : ColumnTypeViewFn < typeof childrenMap , number , number > = ( props ) => props . text ;
41
40
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 ;
46
49
} ;
47
50
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
+
48
133
export const ColumnNumberComp = ( function ( ) {
49
134
return new ColumnTypeCompBuilder (
50
135
childrenMap ,
51
136
( props , dispatch ) => {
52
- float = props . float ;
53
- step = props . step ;
54
- precision = props . precision ;
55
137
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 } /> ;
69
139
} ,
70
140
( nodeValue ) => nodeValue . text . value ,
71
- getBaseValue ,
141
+ getBaseValue
72
142
)
73
143
. setEditViewFn ( ( props ) => {
144
+ const { value, onChange, onChangeEnd, otherProps } = props ;
74
145
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 }
88
153
/>
89
- </ InputNumberWrapper >
90
- ) } )
154
+ ) ;
155
+ } )
91
156
. setPropertyViewFn ( ( children ) => {
92
157
return (
93
158
< >
@@ -99,15 +164,15 @@ export const ColumnNumberComp = (function () {
99
164
label : trans ( "table.numberStep" ) ,
100
165
tooltip : trans ( "table.numberStepTooltip" ) ,
101
166
onFocus : ( focused ) => {
102
- if ( ! focused ) {
167
+ if ( ! focused ) {
103
168
const value = children . step . getView ( ) ;
104
169
const isFloat = children . float . getView ( ) ;
105
170
const newValue = ! isFloat ? Math . floor ( value ) : value ;
106
171
children . step . dispatchChangeValueAction ( String ( newValue ) ) ;
107
172
}
108
173
}
109
174
} ) }
110
- { float && (
175
+ { children . float . getView ( ) && (
111
176
children . precision . propertyView ( {
112
177
label : trans ( "table.precision" ) ,
113
178
} )
0 commit comments