From b57728edf441688061e4d781a2973f82d03b525c Mon Sep 17 00:00:00 2001 From: Thomas Jeffery Date: Fri, 10 Apr 2026 14:30:22 -0600 Subject: [PATCH] fix(#3648): remove edge treatment from high emphasis badges Remove box-shadow inner border from strong emphasis badges in V2. Subtle emphasis badges retain their individual box-shadow tokens. --- .../routes/bugs/3648/bug3648.component.html | 60 ++++++++++ .../src/routes/bugs/3648/bug3648.component.ts | 10 ++ .../src/routes/bugs/3648/bug3648.route.json | 6 + .../src/app/routes/bugs/bug3648.route.ts | 9 ++ apps/prs/react/src/routes/bugs/bug3648.tsx | 106 ++++++++++++++++++ .../specs/badge.browser.spec.tsx | 56 +++++++++ .../src/components/badge/Badge.spec.ts | 32 +++++- .../src/components/badge/Badge.svelte | 10 +- 8 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 apps/prs/angular/src/routes/bugs/3648/bug3648.component.html create mode 100644 apps/prs/angular/src/routes/bugs/3648/bug3648.component.ts create mode 100644 apps/prs/angular/src/routes/bugs/3648/bug3648.route.json create mode 100644 apps/prs/react/src/app/routes/bugs/bug3648.route.ts create mode 100644 apps/prs/react/src/routes/bugs/bug3648.tsx create mode 100644 libs/react-components/specs/badge.browser.spec.tsx diff --git a/apps/prs/angular/src/routes/bugs/3648/bug3648.component.html b/apps/prs/angular/src/routes/bugs/3648/bug3648.component.html new file mode 100644 index 0000000000..29a3a4a470 --- /dev/null +++ b/apps/prs/angular/src/routes/bugs/3648/bug3648.component.html @@ -0,0 +1,60 @@ +
+

3648 - Badge refinements

+

+ + View on GitHub + +

+ +

Strong emphasis badges (edge treatment should be removed)

+
+ + + + + + + + + + + + +
+ +

Strong emphasis, large size

+
+ + + + + + + + + + + + +
+ +

Subtle emphasis badges (reference, no changes needed)

+
+ + + + + + + + + + + + +
+
diff --git a/apps/prs/angular/src/routes/bugs/3648/bug3648.component.ts b/apps/prs/angular/src/routes/bugs/3648/bug3648.component.ts new file mode 100644 index 0000000000..d072bd3691 --- /dev/null +++ b/apps/prs/angular/src/routes/bugs/3648/bug3648.component.ts @@ -0,0 +1,10 @@ +import { Component } from "@angular/core"; +import { GoabBadge } from "@abgov/angular-components"; + +@Component({ + standalone: true, + selector: "abgov-bug3648", + templateUrl: "./bug3648.component.html", + imports: [GoabBadge], +}) +export class Bug3648Component {} diff --git a/apps/prs/angular/src/routes/bugs/3648/bug3648.route.json b/apps/prs/angular/src/routes/bugs/3648/bug3648.route.json new file mode 100644 index 0000000000..b5937d264b --- /dev/null +++ b/apps/prs/angular/src/routes/bugs/3648/bug3648.route.json @@ -0,0 +1,6 @@ +{ + "title": "Badge edge treatment", + "path": "bugs/3648", + "id": "3648", + "type": "bug" +} diff --git a/apps/prs/react/src/app/routes/bugs/bug3648.route.ts b/apps/prs/react/src/app/routes/bugs/bug3648.route.ts new file mode 100644 index 0000000000..3f56e33311 --- /dev/null +++ b/apps/prs/react/src/app/routes/bugs/bug3648.route.ts @@ -0,0 +1,9 @@ +import { Bug3648Route } from "../../../routes/bugs/bug3648"; +import type { PrRouteDefinition } from "../../route-manifest"; +export default { + type: "bug", + id: "3648", + path: "bugs/3648", + title: "Badge edge treatment", + component: Bug3648Route, +} satisfies PrRouteDefinition; diff --git a/apps/prs/react/src/routes/bugs/bug3648.tsx b/apps/prs/react/src/routes/bugs/bug3648.tsx new file mode 100644 index 0000000000..856ecc883f --- /dev/null +++ b/apps/prs/react/src/routes/bugs/bug3648.tsx @@ -0,0 +1,106 @@ +import { + GoabBlock, + GoabText, + GoabDivider, + GoabDetails, + GoabLink, + GoabBadge, +} from "@abgov/react-components"; + +export function Bug3648Route() { + return ( +
+ + Bug #3648: Badge refinements + + + + + + View on GitHub + + + + + + High emphasis badges have a visible edge treatment that contrasts with the + badge background. This is likely an inner shadow or similar, not an actual CSS + border. Figma has no such treatment. Remove it from high emphasis badges. + + + + + + + Test Cases + + + High emphasis (strong) badges - inspect for edge treatment + + + Each of these should have NO visible edge/border/shadow. Inspect to see what CSS + creates the visible edge (box-shadow on line 224 of Badge.svelte uses + --goa-badge-border token). + +
+ + + + + + + + + + + + +
+ + + + Strong emphasis, large size +
+ + + + + + + + + + + + +
+ + + + Subtle emphasis badges (reference, no changes needed) + + These use their own box-shadow tokens for the edge and should remain unchanged. + +
+ + + + + + + + + + + + +
+
+ ); +} + +export default Bug3648Route; diff --git a/libs/react-components/specs/badge.browser.spec.tsx b/libs/react-components/specs/badge.browser.spec.tsx new file mode 100644 index 0000000000..a6de182bed --- /dev/null +++ b/libs/react-components/specs/badge.browser.spec.tsx @@ -0,0 +1,56 @@ +import { render } from "vitest-browser-react"; +import { GoabBadge } from "../src"; +import { expect, describe, it, vi } from "vitest"; + +describe("Badge V2 Emphasis", () => { + it("should have an explicit box-shadow none rule on strong emphasis", async () => { + const result = render( + , + ); + + const badge = result.getByTestId("badge-strong"); + + await vi.waitFor(() => { + const el = badge.element(); + expect(el).toBeTruthy(); + expect(el.classList.contains("v2")).toBe(true); + expect(el.classList.contains("badge-strong")).toBe(true); + + // Verify the shadow DOM stylesheet has an explicit box-shadow: none rule for strong + const root = el.getRootNode() as ShadowRoot; + const sheet = root.adoptedStyleSheets?.[0] ?? root.querySelector("style")?.sheet; + const rules = Array.from(sheet?.cssRules ?? []); + const strongRule = rules.find( + (r) => r instanceof CSSStyleRule && r.selectorText?.includes("badge-strong"), + ) as CSSStyleRule | undefined; + expect(strongRule).toBeTruthy(); + expect(strongRule!.style.boxShadow).toBe("none"); + }); + }); + + it("should render subtle emphasis with correct classes and shadow rule", async () => { + const result = render( + , + ); + + const badge = result.getByTestId("badge-subtle"); + + await vi.waitFor(() => { + const el = badge.element(); + expect(el).toBeTruthy(); + expect(el.classList.contains("v2")).toBe(true); + expect(el.classList.contains("badge-subtle")).toBe(true); + expect(el.classList.contains("badge-information")).toBe(true); + + // Verify the shadow DOM stylesheet contains the box-shadow rule for subtle badges + const root = el.getRootNode() as ShadowRoot; + const sheet = root.adoptedStyleSheets?.[0] ?? root.querySelector("style")?.sheet; + const rules = Array.from(sheet?.cssRules ?? []); + const subtleRule = rules.find( + (r) => r instanceof CSSStyleRule && r.selectorText?.includes("badge-subtle") && r.selectorText?.includes("badge-information"), + ) as CSSStyleRule | undefined; + expect(subtleRule).toBeTruthy(); + expect(subtleRule!.style.boxShadow).toContain("--goa-badge-info-subtle-border"); + }); + }); +}); diff --git a/libs/web-components/src/components/badge/Badge.spec.ts b/libs/web-components/src/components/badge/Badge.spec.ts index cc3ee1a7eb..dfee02d1df 100644 --- a/libs/web-components/src/components/badge/Badge.spec.ts +++ b/libs/web-components/src/components/badge/Badge.spec.ts @@ -115,6 +115,36 @@ describe("GoABadgeComponent", () => { }); }); + describe("V2 Emphasis", () => { + it(`should apply strong emphasis class in v2`, async () => { + const baseElement = render(GoABadge, { + testid: "badge-test", + type: "information", + content: "Strong", + version: "2", + emphasis: "strong", + }); + const badge = await baseElement.findByTestId("badge-test"); + + expect(badge).toHaveClass("v2"); + expect(badge).toHaveClass("badge-strong"); + }); + + it(`should apply subtle emphasis class in v2`, async () => { + const baseElement = render(GoABadge, { + testid: "badge-test", + type: "information", + content: "Subtle", + version: "2", + emphasis: "subtle", + }); + const badge = await baseElement.findByTestId("badge-test"); + + expect(badge).toHaveClass("v2"); + expect(badge).toHaveClass("badge-subtle"); + }); + }); + describe("Custom Icon Type", () => { it(`should render custom icon type when icontype is provided`, async () => { const result = render(GoABadge, { @@ -159,7 +189,7 @@ describe("GoABadgeComponent", () => { }); const badge = await result.findByTestId("badge-test"); const goaIcon = result.container.querySelector("goa-icon"); - + expect(goaIcon).toBeNull(); // No icon should be rendered expect(badge).toContainHTML("No Icon"); expect(badge).toHaveClass("badge-success"); diff --git a/libs/web-components/src/components/badge/Badge.svelte b/libs/web-components/src/components/badge/Badge.svelte index d01fb33658..4a4517bc4e 100644 --- a/libs/web-components/src/components/badge/Badge.svelte +++ b/libs/web-components/src/components/badge/Badge.svelte @@ -77,7 +77,11 @@ type BadgeType = (typeof Types)[number]; type BadgeSize = (typeof badgeSizes)[number]; type BadgeVersion = (typeof versions)[number]; - type BadgeJustifyContent = "center" | "flex-start" | "flex-end" | "space-between"; + type BadgeJustifyContent = + | "center" + | "flex-start" + | "flex-end" + | "space-between"; /** Defines the context and colour of the badge. */ export let type: BadgeType; @@ -384,6 +388,10 @@ padding-bottom: 0; } + .v2.badge-strong { + box-shadow: none; + } + /* Version 2: Default Colours */ .v2.badge-default { background-color: var(--goa-badge-default-color-bg);