@@ -68,6 +68,14 @@ const makeVNumberInputProps = propsFactory({
6868 type : String ,
6969 validator : ( v : any ) => ! v || v . length === 1 ,
7070 } ,
71+ grouping : {
72+ type : [ Boolean , String ] as PropType < 'always' | 'auto' | 'min2' | boolean > ,
73+ default : false ,
74+ } ,
75+ groupSeparator : {
76+ type : String ,
77+ validator : ( v : any ) => ! v || v . length === 1 ,
78+ } ,
7179
7280 ...omit ( makeVTextFieldProps ( ) , [ 'modelValue' , 'validationValue' ] ) ,
7381} , 'VNumberInput' )
@@ -95,32 +103,21 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
95103
96104 const isFocused = shallowRef ( props . focused )
97105
98- const { decimalSeparator : decimalSeparatorFromLocale } = useLocale ( )
106+ const {
107+ current : locale ,
108+ decimalSeparator : decimalSeparatorFromLocale ,
109+ numericGroupSeparator : numericGroupSeparatorFromLocale ,
110+ } = useLocale ( )
99111 const decimalSeparator = computed ( ( ) => props . decimalSeparator ?. [ 0 ] || decimalSeparatorFromLocale . value )
100-
101- function correctPrecision ( val : number , precision = props . precision , trim = true ) {
102- const fixed = precision == null
103- ? String ( val )
104- : val . toFixed ( precision )
105-
106- if ( isFocused . value && trim ) {
107- return Number ( fixed ) . toString ( ) // trim zeros
108- . replace ( '.' , decimalSeparator . value )
109- }
110-
111- if ( props . minFractionDigits === null || ( precision !== null && precision < props . minFractionDigits ) ) {
112- return fixed . replace ( '.' , decimalSeparator . value )
113- }
114-
115- let [ baseDigits , fractionDigits ] = fixed . split ( '.' )
116-
117- fractionDigits = ( fractionDigits ?? '' ) . padEnd ( props . minFractionDigits , '0' )
118- . replace ( new RegExp ( `(?<=\\d{${ props . minFractionDigits } })0+$` , 'g' ) , '' )
119-
120- return [
121- baseDigits ,
122- fractionDigits ,
123- ] . filter ( Boolean ) . join ( decimalSeparator . value )
112+ const groupSeparator = computed ( ( ) => props . groupSeparator ?. [ 0 ] || numericGroupSeparatorFromLocale . value )
113+
114+ function correctPrecision ( val : number , precision ?: number | null , trim = true ) {
115+ precision ??= isFocused . value && trim ? undefined : props . precision ?? undefined
116+ return new Intl . NumberFormat ( locale . value , {
117+ minimumFractionDigits : props . minFractionDigits ?? precision ,
118+ maximumFractionDigits : precision ,
119+ useGrouping : props . grouping ,
120+ } ) . format ( val )
124121 }
125122
126123 const model = useProxiedModel ( props , 'modelValue' , null ,
@@ -154,7 +151,10 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
154151 _inputText . value = null
155152 return
156153 }
157- const parsedValue = Number ( val . replace ( decimalSeparator . value , '.' ) )
154+ const parsedValue = Number ( val
155+ . replaceAll ( groupSeparator . value , '' )
156+ . replace ( decimalSeparator . value , '.' )
157+ )
158158 if ( ! isNaN ( parsedValue ) && parsedValue <= props . max && parsedValue >= props . min ) {
159159 model . value = parsedValue
160160 _inputText . value = val
@@ -315,7 +315,10 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
315315 if ( controlsDisabled . value ) return
316316 if ( ! vTextFieldRef . value ) return
317317 const actualText = vTextFieldRef . value . value
318- const parsedValue = Number ( actualText . replace ( decimalSeparator . value , '.' ) )
318+ const parsedValue = Number ( actualText
319+ . replaceAll ( groupSeparator . value , '' )
320+ . replace ( decimalSeparator . value , '.' )
321+ )
319322 if ( actualText && ! isNaN ( parsedValue ) ) {
320323 inputText . value = correctPrecision ( clamp ( parsedValue , props . min , props . max ) )
321324 } else {
0 commit comments