@@ -9,7 +9,10 @@ import TextField, { type TextFieldProps } from '@mui/material/TextField';
99 * Extends Material UI's TextFieldProps, excluding 'onChange' and 'defaultValue'.
1010 */
1111interface CurrencyTextFieldProps
12- extends Omit < TextFieldProps , 'onBlur' | 'onChange' | 'defaultValue' > {
12+ extends Omit <
13+ TextFieldProps ,
14+ 'onBlur' | 'onChange' | 'defaultValue' | 'type'
15+ > {
1316 /**
1417 * The character used as the decimal separator.
1518 * Defaults to '.'.
@@ -102,32 +105,28 @@ export const CurrencyTextField: React.FC<CurrencyTextFieldProps> = ({
102105 ...props
103106} ) => {
104107 // Internal state to manage the input value.
105- const [ internalValue , setInternalValue ] = useState < Dinero . Dinero > (
106- ( value || defaultValue ) ??
107- Dinero ( {
108- amount : 0 ,
109- currency : currency ,
110- precision : precision ,
111- } ) ,
108+ const [ internalValue , setInternalValue ] = useState < Dinero . Dinero | undefined > (
109+ value ?? defaultValue ?? undefined ,
112110 ) ;
113111
114- /**
115- * TODO: fix loop when precision changes
116- */
117112 useEffect ( ( ) => {
118- setInternalValue ( ( prevState ) => ( {
119- ...prevState ,
120- currency : currency ,
121- precision : precision ,
122- } ) ) ;
123- } , [ currency , precision ] ) ;
113+ if ( internalValue ) {
114+ const updatedValue = Dinero ( {
115+ amount : internalValue . getAmount ( ) ,
116+ currency,
117+ precision,
118+ } ) ;
119+
120+ // Update only if there's a real change to avoid unnecessary re-renders
121+ if ( ! updatedValue . equalsTo ( internalValue ) ) {
122+ setInternalValue ( updatedValue ) ;
123+ }
124+ }
125+ } , [ currency , internalValue , precision ] ) ;
124126
125- /**
126- * Update the internal value when the value prop changes.
127- * This is necessary to keep the input value in sync with the value prop.
128- */
127+ // Update internal value only if `value` prop changes and is defined
129128 useEffect ( ( ) => {
130- if ( value ) {
129+ if ( value !== undefined ) {
131130 setInternalValue ( value ) ;
132131 }
133132 } , [ value ] ) ;
@@ -149,9 +148,8 @@ export const CurrencyTextField: React.FC<CurrencyTextFieldProps> = ({
149148 precision : precision ,
150149 } ) ;
151150
152- if ( ! dineroValue . equalsTo ( internalValue ) ) {
151+ if ( ! internalValue || ! dineroValue . equalsTo ( internalValue ) ) {
153152 onChange ?.( dineroValue , values . formattedValue ) ;
154-
155153 setInternalValue ( dineroValue ) ;
156154 }
157155 } ;
@@ -165,7 +163,7 @@ export const CurrencyTextField: React.FC<CurrencyTextFieldProps> = ({
165163 event : React . FocusEvent < HTMLInputElement | HTMLTextAreaElement > ,
166164 ) => {
167165 if ( onBlur ) {
168- onBlur ( event , internalValue ) ;
166+ onBlur ( event , internalValue as Dinero . Dinero ) ;
169167 }
170168 } ;
171169
@@ -181,18 +179,20 @@ export const CurrencyTextField: React.FC<CurrencyTextFieldProps> = ({
181179 * Formats the dinero value to a matching number that can be use in NumericFormat
182180 */
183181 const formattedValue = useMemo ( ( ) => {
184- const amount = internalValue ?. getAmount ( ) ?? 0 ;
185- const precision = internalValue ?. getPrecision ( ) ?? 2 ;
186- const factor = Math . pow ( 10 , precision ) ;
182+ if ( ! internalValue ) return '' ; // Return empty string if no value
183+ const amount = internalValue . getAmount ( ) ;
184+ const factor = Math . pow ( 10 , internalValue . getPrecision ( ) ) ;
187185 return ( amount / factor ) . toFixed ( precision ) ;
188- } , [ internalValue ] ) ;
186+ } , [ internalValue , precision ] ) ;
189187
190188 /**
191189 * Formats the dinero value to a matching number that can be use in NumericFormat
192190 */
193191 const formattedDefaultValue = useMemo ( ( ) => {
194- const amount = defaultValue ?. getAmount ( ) ?? 0 ;
195- const precision = defaultValue ?. getPrecision ( ) ?? 2 ;
192+ if ( ! defaultValue ) return '' ;
193+
194+ const amount = defaultValue . getAmount ( ) ?? 0 ;
195+ const precision = defaultValue . getPrecision ( ) ?? 2 ;
196196 const factor = Math . pow ( 10 , precision ) ;
197197 return ( amount / factor ) . toFixed ( precision ) ;
198198 } , [ defaultValue ] ) ;
@@ -215,7 +215,7 @@ export const CurrencyTextField: React.FC<CurrencyTextFieldProps> = ({
215215 onFocus = { handleFocus }
216216 onValueChange = { handleValueChange }
217217 { ...props }
218- type = { ' text' }
218+ type = " text"
219219 />
220220 ) ;
221221} ;
0 commit comments