diff --git a/packages/ui/src/base/badge/badge.stories.tsx b/packages/ui/src/base/badge/badge.stories.tsx
index 4a01bb1..934f4cb 100644
--- a/packages/ui/src/base/badge/badge.stories.tsx
+++ b/packages/ui/src/base/badge/badge.stories.tsx
@@ -209,6 +209,44 @@ export const IconOnly: Story = {
},
};
+export const IconOpticallyAlignedIconOnly: Story = {
+ argTypes: {
+ children: {
+ control: false,
+ },
+ icon: {
+ control: false,
+ },
+ },
+ args: {
+ children: undefined,
+ },
+ render: (args) => (
+
+
+
+
+
+
+
+ ),
+ play: async ({ canvas }) => {
+ for(const [icon, label] of [
+ ["issue-open-m", "Open"],
+ ["issue-close", "Closed"],
+ ["status_failed", "Failed"],
+ ["status_success", "Passed"],
+ ["status_pending", "Pending"],
+ ]) {
+ const badge = canvas.getByRole("img", { name: label });
+
+ await expect(canvas.getByTestId(`${icon}-icon`)).not.toHaveClass("-gl-ml-2");
+ await expect(badge).toHaveClass("!gl-px-2");
+ await expect(badge.querySelector(".gl-badge-content")).toBeNull();
+ }
+ },
+};
+
export const Truncated: Story = {
argTypes: {
children: {
diff --git a/packages/ui/src/base/badge/badge.test.tsx b/packages/ui/src/base/badge/badge.test.tsx
index e8ff243..0e5a9ed 100644
--- a/packages/ui/src/base/badge/badge.test.tsx
+++ b/packages/ui/src/base/badge/badge.test.tsx
@@ -73,6 +73,7 @@ describe("GlBadge", () => {
it.each([
[{ icon: "issue-open-m" }, true],
[{ icon: "issue-close" }, true],
+ [{ icon: "status_failed", iconOpticallyAligned: true }, true],
[{ icon: "license", iconOpticallyAligned: true }, true],
[{ icon: "license" }, false],
] as const)("aligns circular icons for %s", (props, expected) => {
@@ -81,6 +82,22 @@ describe("GlBadge", () => {
expect(markup.includes("-gl-ml-2")).toBe(expected);
});
+ it.each([
+ ["issue-open-m", false],
+ ["issue-close", false],
+ ["status_failed", true],
+ ] as const)("keeps the icon-only %s badge centered", (icon, iconOpticallyAligned) => {
+ const markup = renderToStaticMarkup(
+ ,
+ );
+
+ expect(markup).not.toContain("-gl-ml-2");
+ expect(markup).toContain("role=\"img\"");
+ expect(markup).toContain("aria-label=\"Status\"");
+ expect(markup).toContain("!gl-px-2");
+ expect(markup).not.toContain("gl-badge-content");
+ });
+
it("warns when an icon-only badge has no aria-label", () => {
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
@@ -132,11 +149,12 @@ describe("GlBadge", () => {
it("keeps the img role for icon-only link badges", () => {
const markup = renderBadge(
- { "aria-label": "Scheduled", href: "https://www.gitlab.com", icon: "calendar" },
+ { "aria-label": "Closed", href: "https://www.gitlab.com", icon: "issue-close" },
null,
);
expect(markup).toContain("role=\"img\"");
+ expect(markup).not.toContain("-gl-ml-2");
});
});
});
diff --git a/packages/ui/src/base/badge/badge.tsx b/packages/ui/src/base/badge/badge.tsx
index f4e036b..5c39907 100644
--- a/packages/ui/src/base/badge/badge.tsx
+++ b/packages/ui/src/base/badge/badge.tsx
@@ -45,7 +45,7 @@ export type GlBadgeProps = BaseBadgeProps & {
href?: string;
/** Name of an icon from `@gitlab/svgs` shown before the text. */
icon?: string;
- /** Optically aligns circular icons with the badge. */
+ /** Optically aligns circular icons when the badge also has content. */
iconOpticallyAligned?: boolean;
/** Icon size: `sm` (12px) or `md` (16px). */
iconSize?: GlBadgeIconSize;
@@ -147,7 +147,7 @@ const GlBadge = forwardRef(function GlBadge({
{icon ? (