Skip to content

Commit cc8a56e

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

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;
@@ -61,7 +65,7 @@ const onFocusOut = () => {
6165
if (minParams.value && !respectsMin(minParams.value)(comparisonValue)) {
6266
const { min, isExclusive } = minParams.value;
6367
if (isExclusive) {
64-
updatedValue = min + stepSize;
68+
updatedValue = min + stepSize.value;
6569
} else {
6670
updatedValue = min;
6771
}
@@ -71,7 +75,7 @@ const onFocusOut = () => {
7175
) {
7276
const { max, isExclusive } = maxParams.value;
7377
if (isExclusive) {
74-
updatedValue = max - stepSize;
78+
updatedValue = max - stepSize.value;
7579
} else {
7680
updatedValue = max;
7781
}
@@ -91,6 +95,7 @@ const onFocusOut = () => {
9195
:type="type"
9296
:min="minParams?.min"
9397
:max="maxParams?.max"
98+
:step="stepSize"
9499
:is-valid
95100
compact
96101
@update:model-value="changeValue"

0 commit comments

Comments
 (0)