Skip to content

Commit d5779cd

Browse files
authored
feat(VNumberInput): more flexible precision display (#21315)
1 parent 0953ed2 commit d5779cd

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

packages/api-generator/src/locale/en/VNumberInput.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"inset": "Applies an indentation to the dividers used in the stepper buttons.",
66
"max": "Specifies the maximum allowable value for the input.",
77
"min": "Specifies the minimum allowable value for the input.",
8+
"minFractionDigits": "Specifies the minimum fraction digits to be displayed (capped to `precision`). Defaults to `precision` when not explicitly set.",
89
"precision": "Enforces strict precision. It is expected to be an integer value in range between `0` and `15`, or null for unrestricted.",
910
"step": "Defines the interval between allowed values when the user increments or decrements the input"
1011
},

packages/vuetify/src/components/VNumberInput/VNumberInput.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ const makeVNumberInputProps = propsFactory({
6060
type: Number as PropType<number | null>,
6161
default: 0,
6262
},
63+
minFractionDigits: {
64+
type: Number as PropType<number | null>,
65+
default: null,
66+
},
6367

6468
...omit(makeVTextFieldProps(), ['modelValue', 'validationValue']),
6569
}, 'VNumberInput')
@@ -87,12 +91,26 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
8791
const { isFocused, focus, blur } = useFocus(props)
8892

8993
function correctPrecision (val: number, precision = props.precision) {
90-
const fixed = precision == null
91-
? String(val)
92-
: val.toFixed(precision)
93-
return isFocused.value
94-
? Number(fixed).toString() // trim zeros
95-
: fixed
94+
if (precision == null) {
95+
return String(val)
96+
}
97+
98+
let fixed = val.toFixed(precision)
99+
100+
if (isFocused.value) {
101+
return Number(fixed).toString() // trim zeros
102+
}
103+
104+
if ((props.minFractionDigits ?? precision) < precision) {
105+
const trimLimit = precision - props.minFractionDigits!
106+
const [baseDigits, fractionDigits] = fixed.split('.')
107+
fixed = [
108+
baseDigits,
109+
fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), ''),
110+
].filter(Boolean).join('.')
111+
}
112+
113+
return fixed
96114
}
97115

98116
const model = useProxiedModel(props, 'modelValue', null,
@@ -159,6 +177,7 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
159177
}
160178

161179
watch(() => props.precision, () => formatInputValue())
180+
watch(() => props.minFractionDigits, () => formatInputValue())
162181

163182
onMounted(() => {
164183
clampModel()
@@ -279,9 +298,7 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
279298
inputText.value = null
280299
return
281300
}
282-
inputText.value = props.precision == null
283-
? String(model.value)
284-
: model.value.toFixed(props.precision)
301+
inputText.value = correctPrecision(model.value)
285302
}
286303

287304
function trimDecimalZeros () {

0 commit comments

Comments
 (0)