Skip to content

Commit

Permalink
feat(OnyxStepper): implement strip step and precision (#1976)
Browse files Browse the repository at this point in the history
- added strip step Mode (values that do not fit the step size, a
stepMismatch error is shown)
- added precision (always display the given number of decimals places)
- applied the spin button aria pattern

---------

Co-authored-by: Jonathan Carle <jonathan_leo.carle@mail.schwarz>
  • Loading branch information
ChristianBusshoff and JoCa96 authored Oct 29, 2024
1 parent 7183695 commit 3bc1d58
Show file tree
Hide file tree
Showing 9 changed files with 391 additions and 54 deletions.
8 changes: 8 additions & 0 deletions .changeset/olive-jobs-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"sit-onyx": minor
---

feat(OnyxStepper):

- Implemented `stripStep` and `precision`.
- Deprecated `step`, replacing it with `stepSize` and `precision`.
26 changes: 26 additions & 0 deletions apps/demo-app/src/components/form-demo/FormDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
OnyxInput,
OnyxRadioGroup,
OnyxSelect,
OnyxStepper,
OnyxSwitch,
OnyxTextarea,
type CheckboxGroupOption,
Expand All @@ -22,6 +23,10 @@ export type FormData = Partial<{
minlengthTextarea: string;
typeInput: string;
patternInput: string;
defaultStepper: number;
requiredStepper: number;
areaStepper: number;
stripStepStepper: number;
switch: boolean;
checkboxGroup: number[];
requiredSelect: string[];
Expand Down Expand Up @@ -127,6 +132,27 @@ const radioOptions: RadioButtonOption[] = [
:minlength="5"
required
/>
<OnyxStepper v-model="formState.defaultStepper" class="onyx-grid-span-4" label="Delault" />
<OnyxStepper
v-model="formState.requiredStepper"
class="onyx-grid-span-4"
label="Requires a value"
required
/>
<OnyxStepper
v-model="formState.areaStepper"
class="onyx-grid-span-4"
label="Only allows Numbers inside an area"
:min="5"
:max="20"
/>

<OnyxStepper
v-model="formState.stripStepStepper"
class="onyx-grid-span-4"
label="Strip Step"
strip-step
/>

<OnyxSwitch v-model="formState.switch" class="onyx-grid-span-4" label="Switch" required />

Expand Down
132 changes: 126 additions & 6 deletions packages/sit-onyx/src/components/OnyxStepper/OnyxStepper.ct.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ test("should emit events", async ({ mount, makeAxeBuilder }) => {
await inputElement.blur();
// ASSERT
expect(events).toMatchObject({
updateModelValue: [1, 10],
updateModelValue: [10],
});
});

Expand Down Expand Up @@ -357,7 +357,7 @@ test("should increment/decrement value by step on counter button click", async (
props: {
label: "Test label",
style: "width: 12rem;",
step: 2,
stepSize: 2,
},
on,
});
Expand Down Expand Up @@ -453,6 +453,7 @@ test("should not allow entering value lower the min value that has been set", as
label: "Test label",
style: "width: 12rem;",
min: 2,
modelValue: 4,
},
on,
});
Expand All @@ -467,10 +468,6 @@ test("should not allow entering value lower the min value that has been set", as
expect(accessibilityScanResults.violations).toEqual([]);
await expect(component.getByLabel("Test label")).toBeAttached();

await input.click();
await input.fill("4");
await expect(input).toHaveValue("4");

await substractButton.click();
await expect(input).toHaveValue("3");

Expand All @@ -479,3 +476,126 @@ test("should not allow entering value lower the min value that has been set", as

await expect(substractButton).toBeDisabled();
});

test("Should display the same number of decimal places as the smallest possible step", async ({
mount,
makeAxeBuilder,
}) => {
// ARRANGE
const on = {
"update:modelValue": (newValue) => {
component.update({
props: {
modelValue: newValue,
},
on,
});
},
};

const component = await mount(OnyxStepper, {
props: {
label: "Test label",
style: "width: 12rem;",
precision: 0.01,
},
on,
});

const input = component.locator("input");

// ACT
const accessibilityScanResults = await makeAxeBuilder().analyze();

// ASSERT
expect(accessibilityScanResults.violations).toEqual([]);

await input.fill("1");
await input.dispatchEvent("change");
await expect(input).toHaveValue("1.00");
});

test("Should display an error if the value is not a multiple of the precision", async ({
page,
mount,
makeAxeBuilder,
}) => {
// ARRANGE
const on = {
"update:modelValue": (newValue: number) => {
component.update({
props: {
modelValue: newValue,
},
on,
});
},
};

const component = await mount(OnyxStepper, {
props: {
label: "Test label",
style: "width: 12rem;",
modelValue: 1,
precision: 0.5,
},
on,
});

const input = component.getByLabel("Test label");
const errorMessage = component.locator(".onyx-form-element__error-message");

// ACT
const accessibilityScanResults = await makeAxeBuilder().analyze();

// ASSERT
expect(accessibilityScanResults.violations).toEqual([]);

await input.fill("1");
await page.keyboard.press("Enter");

await expect(errorMessage).toBeHidden();
await page.keyboard.press("Enter");

await input.fill("3.6");
await page.keyboard.press("Enter");

await expect(errorMessage).toBeVisible();
});

test("Should revert to the last valid input if the current input is invalid in stripStep mode", async ({
page,
mount,
}) => {
// ARRANGE
const on = {
"update:modelValue": (newValue: number) => {
component.update({
props: {
modelValue: newValue,
},
on,
});
},
};

const component = await mount(OnyxStepper, {
props: {
label: "Test label",
style: "width: 12rem;",
precision: 0.5,
stripStep: true,
},
on,
});

const input = component.locator("input");

await input.fill("1");
await page.keyboard.press("Enter");
await expect(input).toHaveValue("1.0");
await page.keyboard.press("Enter");
await input.fill("1.6");
await page.keyboard.press("Enter");
await expect(input).toHaveValue("1.0");
});
Loading

0 comments on commit 3bc1d58

Please sign in to comment.