diff --git a/src/components/Badge.test.tsx b/src/components/Badge.test.tsx
index 00fd6c7c..44d7415a 100644
--- a/src/components/Badge.test.tsx
+++ b/src/components/Badge.test.tsx
@@ -23,22 +23,18 @@ describe("Badge component", () => {
expect(badge).toHaveClass("border-rmigray-200");
});
- // Type assertions: children must be scalar (string|number)
it("disallows ReactNode children for Badge at compile-time", () => {
// @ts-expect-error - Badge children must be string | number
render(
- Not allowed
+ Not allowed
,
);
});
it("applies pathwayType styling when variant is 'pathwayType'", () => {
const { container } = render(
- ,
+ Pathway Type,
);
const badge = container.firstChild as HTMLElement;
@@ -48,12 +44,7 @@ describe("Badge component", () => {
});
it("applies temperature styling when variant is 'temperature'", () => {
- const { container } = render(
- ,
- );
+ const { container } = render(1.5°C);
const badge = container.firstChild as HTMLElement;
expect(badge).toHaveClass("bg-rmired-100");
@@ -62,12 +53,7 @@ describe("Badge component", () => {
});
it("applies year styling when variant is 'year'", () => {
- const { container } = render(
- ,
- );
+ const { container } = render(2050);
const badge = container.firstChild as HTMLElement;
expect(badge).toHaveClass("bg-rmiblue-100");
@@ -77,10 +63,7 @@ describe("Badge component", () => {
it("applies geography styling when variant is 'geographyGlobal'", () => {
const { container } = render(
- ,
+ Global,
);
const badge = container.firstChild as HTMLElement;
@@ -91,10 +74,7 @@ describe("Badge component", () => {
it("applies geography styling when variant is 'geographyRegion'", () => {
const { container } = render(
- ,
+ RegionName,
);
const badge = container.firstChild as HTMLElement;
@@ -105,10 +85,7 @@ describe("Badge component", () => {
it("applies geography styling when variant is 'geographyCountry'", () => {
const { container } = render(
- ,
+ CountryName,
);
const badge = container.firstChild as HTMLElement;
@@ -118,12 +95,7 @@ describe("Badge component", () => {
});
it("applies sector styling when variant is 'sector'", () => {
- const { container } = render(
- ,
- );
+ const { container } = render(Energy);
const badge = container.firstChild as HTMLElement;
expect(badge).toHaveClass("bg-solar-100");
@@ -140,16 +112,9 @@ describe("Badge component", () => {
});
it("always includes base badge styling", () => {
- // Testing that common styles are applied to all variants
- const { container } = render(
- ,
- );
+ const { container } = render(Test);
const badge = container.firstChild as HTMLElement;
- // Check for common styling classes that should be on all badges
expect(badge).toHaveClass("inline-flex");
expect(badge).toHaveClass("items-center");
expect(badge).toHaveClass("rounded-full");
@@ -161,18 +126,13 @@ describe("Badge component", () => {
});
it("renders as a span element", () => {
- const { container } = render();
+ const { container } = render(Test);
expect(container.firstChild?.nodeName).toBe("SPAN");
});
- // Tooltip tests
it("does not render tooltip when no tooltip is provided", () => {
render(No Tooltip);
-
- // Find the badge span
const badge = screen.getByText("No Tooltip");
-
- // Check that it's a plain span without tabindex
expect(badge).toBeInTheDocument();
expect(badge).not.toHaveAttribute("tabindex");
});
@@ -180,25 +140,16 @@ describe("Badge component", () => {
it("uses TextWithTooltip when tooltip is provided", () => {
render(With Tooltip);
- // Badge text should still be present
const badgeText = screen.getByText("With Tooltip");
expect(badgeText).toBeInTheDocument();
- // The outer span from TextWithTooltip should have tabindex attribute
- // We need to look for a parent element with tabindex since the badge text itself
- // is wrapped in its own span
const triggerElement = badgeText.closest("span")?.parentElement;
expect(triggerElement).toHaveAttribute("tabindex", "0");
-
- // The aria-describedby attribute is added when tooltip is visible
expect(triggerElement).not.toHaveAttribute("aria-describedby");
});
- // Testing tooltip visibility requires checking document.body, since tooltips are now in portals
it("doesn't show tooltip initially", () => {
render(Hover me);
-
- // Initially the tooltip shouldn't be in document.body
const tooltipElement = document.querySelector("[role='tooltip']");
expect(tooltipElement).not.toBeInTheDocument();
});
@@ -280,9 +231,11 @@ describe("Badge component", () => {
describe("BadgeMaybeAbsent", () => {
it("renders 'None' for undefined/null", () => {
- const { rerender } = render();
+ const { rerender } = render(
+ {undefined},
+ );
expect(screen.getByText("None")).toBeInTheDocument();
- rerender();
+ rerender({null});
expect(screen.getByText("None")).toBeInTheDocument();
});
@@ -301,14 +254,13 @@ describe("BadgeMaybeAbsent", () => {
it("uses toLabel only for present values", () => {
const toLabel = (v: number) => `Y${v}`;
const { rerender } = render(
- toLabel={toLabel}>2030,
+ toLabel={toLabel}>{2030},
);
expect(screen.getByText("Y2030")).toBeInTheDocument();
rerender(
-
- text={undefined}
- toLabel={toLabel}
- />,
+ toLabel={toLabel}>
+ {undefined}
+ ,
);
expect(screen.getByText("None")).toBeInTheDocument();
});
@@ -317,17 +269,14 @@ describe("BadgeMaybeAbsent", () => {
// @ts-expect-error - BadgeMaybeAbsent children must be string | number | null | undefined
render(
- Not allowed
+ Not allowed
,
);
});
it("supports noneLabel override", () => {
render(
- ,
+ {undefined},
);
expect(screen.getByText("No Value")).toBeInTheDocument();
});
diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx
index 9c312244..4dc930b4 100644
--- a/src/components/Badge.tsx
+++ b/src/components/Badge.tsx
@@ -13,7 +13,9 @@ interface BadgeProps {
| "geographyGlobal"
| "geographyRegion"
| "geographyCountry"
- | "sector";
+ | "sector"
+ | "metric"
+ | "keyFeature";
className?: string;
}
@@ -53,13 +55,10 @@ const Badge: React.FC = ({
? `${badgeStylesBase} ${className}`
: badgeStylesBase;
- // If no tooltip, just return the basic badge
- // If no tooltip, just return the basic badge
if (!tooltip) {
return {children};
}
- // With tooltip, use the TextWithTooltip component
return (
{children}}
@@ -70,7 +69,6 @@ const Badge: React.FC = ({
};
export default Badge;
-// --- value-aware helpers (schema-agnostic) --------------------
export type BadgeMaybeAbsentProps = Omit<
React.ComponentProps,
@@ -83,7 +81,7 @@ export type BadgeMaybeAbsentProps = Omit<
/** Visible text for the "None" case (default "None"). */
noneLabel?: string;
/** Optional decorator for the final label (e.g., highlight search matches). */
- renderLabel?: (label: string, isAbsent: boolean) => React.ReactNode;
+ renderLabel?: (label: string, isAbsent: boolean) => string | number;
};
export function BadgeMaybeAbsent({
@@ -104,11 +102,11 @@ export function BadgeMaybeAbsent({
} else if (typeof children === "string" || typeof children === "number") {
base = String(children);
} else {
- // Should be unreachable at runtime due to typing, but keep a safe fallback
base = String(children as unknown as string | number);
}
const content =
renderLabel && typeof base === "string" ? renderLabel(base, absent) : base;
- return {content};
+
+ return {String(content)};
}