Skip to content

Commit 8410f0c

Browse files
committed
UIEXT-2930: Handle stepSize setting for number inputs
UIEXT-2930 (Add configurable step size to NumberInputWidget)
1 parent ac3c502 commit 8410f0c

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

packages/components/src/components/forms/NumberInput/NumberInput.vue

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export default {
4242
default: Number.MAX_SAFE_INTEGER,
4343
type: Number,
4444
},
45+
step: {
46+
default: null,
47+
type: [Number, null] as PropType<number | null>,
48+
},
4549
/**
4650
* Validity controlled by the parent component to be flexible.
4751
*/
@@ -87,6 +91,10 @@ export default {
8791
return this.type === "integer";
8892
},
8993
stepSize() {
94+
if (this.step !== null) {
95+
return this.step;
96+
}
97+
9098
return this.isInteger
9199
? DEFAULT_STEP_SIZE_INTEGER
92100
: DEFAULT_STEP_SIZE_DOUBLE;
@@ -204,7 +212,12 @@ export default {
204212
205213
/** Mimic stepping to nearest step with safe value rounding */
206214
let parsedVal = value + increment;
207-
parsedVal = Math.round(parsedVal * 10) / 10; // eslint-disable-line no-magic-numbers
215+
let scaleFactor = 1 / Math.abs(increment); // eslint-disable-line no-magic-numbers
216+
if (Math.abs(increment) < 1) {
217+
// Avoid rounding errors induced by fractional increments
218+
scaleFactor = Math.round(scaleFactor);
219+
}
220+
parsedVal = Math.round(parsedVal * scaleFactor) / scaleFactor;
208221
209222
/**
210223
* All measures have been taken to ensure a valid value at this point, so if the last

packages/jsonforms/src/uiComponents/NumberControlBase.vue

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ const props = defineProps<
1515
1616
const DEFAULT_STEP_SIZE_INTEGER = 1;
1717
const DEFAULT_STEP_SIZE_DOUBLE = 0.1;
18-
const stepSize =
19-
props.type === "integer"
20-
? DEFAULT_STEP_SIZE_INTEGER
21-
: DEFAULT_STEP_SIZE_DOUBLE;
18+
19+
const stepSize = computed(
20+
() =>
21+
props.control.uischema.options?.stepSize ??
22+
(props.type === "integer"
23+
? DEFAULT_STEP_SIZE_INTEGER
24+
: DEFAULT_STEP_SIZE_DOUBLE),
25+
);
2226
2327
type BoundValidationParameters = {
2428
isExclusive: boolean;
@@ -57,14 +61,14 @@ const onFocusOut = () => {
5761
if (minParams.value && !respectsMin(minParams.value)(num)) {
5862
const { min, isExclusive } = minParams.value;
5963
if (isExclusive) {
60-
props.changeValue(min + stepSize);
64+
props.changeValue(min + stepSize.value);
6165
} else {
6266
props.changeValue(min);
6367
}
6468
} else if (maxParams.value && !respectsMax(maxParams.value)(num)) {
6569
const { max, isExclusive } = maxParams.value;
6670
if (isExclusive) {
67-
props.changeValue(max - stepSize);
71+
props.changeValue(max - stepSize.value);
6872
} else {
6973
props.changeValue(max);
7074
}
@@ -81,6 +85,7 @@ const onFocusOut = () => {
8185
:type="type"
8286
:min="minParams?.min"
8387
:max="maxParams?.max"
88+
:step="stepSize"
8489
:is-valid
8590
compact
8691
@update:model-value="changeValue"

0 commit comments

Comments
 (0)