Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions packages/react/src/component-tests/IcStepper/IcStepper.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import React from "react";
import { mount } from "cypress/react";
import { IcStep, IcStepper } from "../../components";
import {
FullWidth,
Compact,
Expand Down Expand Up @@ -319,3 +320,48 @@ describe("IcStepper visual regression tests in high contrast mode", () => {
});
});
});

describe("IcStepper text resize accessibility regression", () => {
afterEach(() => {
cy.document().then((doc) => {
doc.documentElement.style.fontSize = "";
});
cy.task("generateReport");
});

it("switches to compact mode at 200% text size without horizontal overflow", () => {
cy.viewport(800, 600);
cy.injectAxe();
mount(
<div
id="text-resize-stepper-container"
style={{ width: "700px", maxWidth: "100%" }}
>
<IcStepper>
<IcStep heading="First step" />
<IcStep heading="Second step with a longer heading" type="current" />
<IcStep heading="Third step" />
<IcStep heading="Fourth step" />
</IcStepper>
</div>
);
cy.checkHydrated(STEPPER_SELECTOR);

cy.document().then((doc) => {
doc.documentElement.style.fontSize = "32px";
});

cy.get(STEPPER_SELECTOR).should("have.class", "ic-stepper-compact");

cy.get("#text-resize-stepper-container").then(($container) => {
const container = $container[0];
expect(container.scrollWidth).to.be.at.most(container.clientWidth);
});

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/text-resize-200-percent",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.015),
});
});
});
29 changes: 20 additions & 9 deletions packages/web-components/src/components/ic-stepper/ic-stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,17 +320,22 @@ export class Stepper {
});
};

private getMinimumDefaultStepperWidth = (): number => {
const rootFontSize =
parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
const baseStepWidth =
this.aligned === "left" &&
this.connectorWidth &&
this.connectorWidth > 100
? this.connectorWidth + 48
: 148;

return (baseStepWidth / 16) * rootFontSize * this.steps.length;
};

private overrideVariant = () => {
if (this.variantOverride) {
let minDefaultStepperWidth = 148 * this.steps.length;

if (
this.aligned === "left" &&
this.connectorWidth &&
this.connectorWidth > 100
) {
minDefaultStepperWidth = (this.connectorWidth + 48) * this.steps.length;
}
const minDefaultStepperWidth = this.getMinimumDefaultStepperWidth();
if (this.el.clientWidth < minDefaultStepperWidth) {
this.variant = "compact";
} else {
Expand All @@ -339,8 +344,13 @@ export class Stepper {
}
};

private observeSteps = () => {
this.steps.forEach((step) => this.resizeObserver?.observe(step));
};

private resizeObserverCallback = () => {
this.getChildren();
this.observeSteps();
this.checkStepTitles();
this.overrideVariant();
this.setStepperWidth();
Expand All @@ -353,6 +363,7 @@ export class Stepper {
this.resizeObserverCallback();
});
this.resizeObserver.observe(this.el);
this.observeSteps();
};

render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1034,3 +1034,61 @@ describe("switch between the compact and default stepper depending on whether th
});
});
});

const textResizeStepperMarkup = `
<ic-stepper>
<ic-step heading="First"></ic-step>
<ic-step heading="Second" type="current"></ic-step>
<ic-step heading="Third"></ic-step>
<ic-step heading="Fourth"></ic-step>
</ic-stepper>`;

describe("ic-stepper text resize", () => {
const mockRootFontSize = (fontSize: string) => {
jest
.spyOn(globalThis, "getComputedStyle")
.mockReturnValue({ fontSize } as CSSStyleDeclaration);
};

afterEach(() => {
jest.restoreAllMocks();
});

it("scales the automatic compact breakpoint with the root font size", async () => {
const page = await newSpecPage({
components: [Stepper, Step],
html: textResizeStepperMarkup,
});

mockRootFontSize("32px");

Object.defineProperty(page.root, "clientWidth", {
configurable: true,
value: 700,
});

page.rootInstance.getChildren();
page.rootInstance.overrideVariant();

expect(page.rootInstance.variant).toBe("compact");
});

it("keeps the default variant at the same width with the normal root font size", async () => {
const page = await newSpecPage({
components: [Stepper, Step],
html: textResizeStepperMarkup,
});

mockRootFontSize("16px");

Object.defineProperty(page.root, "clientWidth", {
configurable: true,
value: 700,
});

page.rootInstance.getChildren();
page.rootInstance.overrideVariant();

expect(page.rootInstance.variant).toBe("default");
});
});