@@ -35,7 +35,7 @@ export function format<BaseType = InputAttributes>(
3535 fixedDecimalScale,
3636 prefix = '' ,
3737 suffix = '' ,
38- allowNegative = true ,
38+ allowNegative,
3939 thousandsGroupStyle = 'thousand' ,
4040 } = props ;
4141
@@ -123,13 +123,25 @@ export function removeFormatting<BaseType = InputAttributes>(
123123 changeMeta : ChangeMeta = getDefaultChangeMeta ( value ) ,
124124 props : NumericFormatProps < BaseType > ,
125125) {
126- const { allowNegative = true , prefix = '' , suffix = '' , decimalScale } = props ;
126+ const { allowNegative, prefix = '' , suffix = '' , decimalScale } = props ;
127127 const { from, to } = changeMeta ;
128128 let { start, end } = to ;
129129 const { allowedDecimalSeparators, decimalSeparator } = getSeparators ( props ) ;
130130
131131 const isBeforeDecimalSeparator = value [ end ] === decimalSeparator ;
132132
133+ /**
134+ * If only a number is added on empty input which matches with the prefix or suffix,
135+ * then don't remove it, just return the same
136+ */
137+ if (
138+ charIsNumber ( value ) &&
139+ ( value === prefix || value === suffix ) &&
140+ changeMeta . lastValue === ''
141+ ) {
142+ return value ;
143+ }
144+
133145 /** Check for any allowed decimal separator is added in the numeric format and replace it with decimal separator */
134146 if ( end - start === 1 && allowedDecimalSeparators . indexOf ( value [ start ] ) !== - 1 ) {
135147 const separator = decimalScale === 0 ? '' : decimalSeparator ;
@@ -138,18 +150,23 @@ export function removeFormatting<BaseType = InputAttributes>(
138150
139151 const stripNegation = ( value : string , start : number , end : number ) => {
140152 /**
141- * if prefix starts with - the number hast to have two - at the start
153+ * if prefix starts with - we don't allow negative number to avoid confusion
142154 * if suffix starts with - and the value length is same as suffix length, then the - sign is from the suffix
143155 * In other cases, if the value starts with - then it is a negation
144156 */
145157 let hasNegation = false ;
146158 let hasDoubleNegation = false ;
147- if ( prefix . startsWith ( '-' ) ) hasNegation = ! value . startsWith ( '--' ) ;
148- else if ( value . startsWith ( '--' ) ) {
159+
160+ if ( prefix . startsWith ( '-' ) ) {
161+ hasNegation = false ;
162+ } else if ( value . startsWith ( '--' ) ) {
149163 hasNegation = false ;
150164 hasDoubleNegation = true ;
151- } else if ( suffix . startsWith ( '-' ) && value . length === suffix . length ) hasNegation = false ;
152- else if ( value [ 0 ] === '-' ) hasNegation = true ;
165+ } else if ( suffix . startsWith ( '-' ) && value . length === suffix . length ) {
166+ hasNegation = false ;
167+ } else if ( value [ 0 ] === '-' ) {
168+ hasNegation = true ;
169+ }
153170
154171 let charsToRemove = hasNegation ? 1 : 0 ;
155172 if ( hasDoubleNegation ) charsToRemove = 2 ;
@@ -267,8 +284,10 @@ export function getCaretBoundary<BaseType = InputAttributes>(
267284 return boundaryAry ;
268285}
269286
270- function validateProps < BaseType = InputAttributes > ( props : NumericFormatProps < BaseType > ) {
287+ function validateAndUpdateProps < BaseType = InputAttributes > ( props : NumericFormatProps < BaseType > ) {
271288 const { thousandSeparator, decimalSeparator } = getSeparators ( props ) ;
289+ // eslint-disable-next-line prefer-const
290+ let { prefix = '' , allowNegative = true } = props ;
272291
273292 if ( thousandSeparator === decimalSeparator ) {
274293 throw new Error ( `
@@ -277,11 +296,30 @@ function validateProps<BaseType = InputAttributes>(props: NumericFormatProps<Bas
277296 decimalSeparator: ${ decimalSeparator } (default value for decimalSeparator is .)
278297 ` ) ;
279298 }
299+
300+ if ( prefix . startsWith ( '-' ) && allowNegative ) {
301+ // TODO: throw error in next major version
302+ console . error ( `
303+ Prefix can't start with '-' when allowNegative is true.
304+ prefix: ${ prefix }
305+ allowNegative: ${ allowNegative }
306+ ` ) ;
307+
308+ allowNegative = false ;
309+ }
310+
311+ return {
312+ ...props ,
313+ allowNegative,
314+ } ;
280315}
281316
282317export function useNumericFormat < BaseType = InputAttributes > (
283318 props : NumericFormatProps < BaseType > ,
284319) : NumberFormatBaseProps < BaseType > {
320+ // validate props
321+ props = validateAndUpdateProps ( props ) ;
322+
285323 const {
286324 decimalSeparator = '.' ,
287325 /* eslint-disable no-unused-vars */
@@ -304,9 +342,6 @@ export function useNumericFormat<BaseType = InputAttributes>(
304342 ...restProps
305343 } = props ;
306344
307- // validate props
308- validateProps ( props ) ;
309-
310345 const _format : FormatInputValueFunction = ( numStr ) => format ( numStr , props ) ;
311346
312347 const _removeFormatting : RemoveFormattingFunction = ( inputValue , changeMeta ) =>
@@ -359,7 +394,12 @@ export function useNumericFormat<BaseType = InputAttributes>(
359394 }
360395
361396 // if user hits backspace, while the cursor is before prefix, and the input has negation, remove the negation
362- if ( key === 'Backspace' && value [ 0 ] === '-' && selectionStart === prefix . length + 1 ) {
397+ if (
398+ key === 'Backspace' &&
399+ value [ 0 ] === '-' &&
400+ selectionStart === prefix . length + 1 &&
401+ allowNegative
402+ ) {
363403 // bring the cursor to after negation
364404 setCaretPosition ( el , 1 ) ;
365405 }
0 commit comments