Skip to content

Commit fa698c9

Browse files
twjefferychrisolsen
authored andcommitted
feat(#1613):additional badge types and custom icon
1 parent 0b5fdc1 commit fa698c9

File tree

8 files changed

+469
-21
lines changed

8 files changed

+469
-21
lines changed

libs/angular-components/src/lib/components/badge/badge.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GoabBadgeType } from "@abgov/ui-components-common";
1+
import { GoabBadgeType, GoabIconType } from "@abgov/ui-components-common";
22
import {
33
CUSTOM_ELEMENTS_SCHEMA,
44
Component,
@@ -14,6 +14,7 @@ import { GoabBaseComponent } from "../base.component";
1414
<goa-badge
1515
[attr.type]="type"
1616
[attr.icon]="icon"
17+
[attr.icontype]="iconType"
1718
[attr.arialabel]="ariaLabel"
1819
[attr.content]="content"
1920
[attr.testid]="testId"
@@ -37,5 +38,6 @@ export class GoabBadge extends GoabBaseComponent {
3738
@Input() type?: GoabBadgeType;
3839
@Input() content?: string;
3940
@Input({ transform: booleanAttribute }) icon?: boolean;
41+
@Input() iconType?: GoabIconType;
4042
@Input() ariaLabel?: string;
4143
}

libs/common/src/lib/common.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,27 @@ export type GoabBadgeType =
8989
| "emergency"
9090
| "dark"
9191
| "midtone"
92-
| "light";
92+
| "light"
93+
| "archived"
94+
| "aqua"
95+
| "black"
96+
| "blue"
97+
| "green"
98+
| "orange"
99+
| "pink"
100+
| "red"
101+
| "violet"
102+
| "white"
103+
| "yellow"
104+
| "aqua-light"
105+
| "black-light"
106+
| "blue-light"
107+
| "green-light"
108+
| "orange-light"
109+
| "pink-light"
110+
| "red-light"
111+
| "violet-light"
112+
| "yellow-light";
93113

94114
export type GoabPaginationVariant = "all" | "links-only";
95115

libs/react-components/src/lib/badge/badge.spec.tsx

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { GoabBadge } from "./badge";
44
configure({ testIdAttribute: "testId" });
55

66
describe("GoabBadge", () => {
7-
it("should render", () => {
7+
it("should render with default behavior (no icon)", () => {
88
const { container } = render(<GoabBadge type="information" content="Text Content" />);
99

1010
const el = container.querySelector("goa-badge");
11-
expect(el?.getAttribute("icon")).toBeNull();
11+
expect(el?.getAttribute("icon")).toBe("false");
1212
});
1313

1414
it("should render the properties", () => {
@@ -35,4 +35,103 @@ describe("GoabBadge", () => {
3535
expect(el?.getAttribute("ml")).toBe("xl");
3636
expect(el?.getAttribute("arialabel")).toBe("text");
3737
});
38+
39+
it("should render custom icon type when icontype is provided", () => {
40+
const { container } = render(
41+
<GoabBadge
42+
type="information"
43+
content="Custom Icon"
44+
iconType="home"
45+
/>,
46+
);
47+
const el = container.querySelector("goa-badge");
48+
49+
expect(el?.getAttribute("icontype")).toBe("home");
50+
expect(el?.getAttribute("icon")).toBe("true");
51+
});
52+
53+
it("should not render icontype when not provided", () => {
54+
const { container } = render(
55+
<GoabBadge
56+
type="success"
57+
content="Default Icon"
58+
icon
59+
/>,
60+
);
61+
const el = container.querySelector("goa-badge");
62+
63+
expect(el?.getAttribute("icontype")).toBeNull();
64+
expect(el?.getAttribute("icon")).toBe("true");
65+
});
66+
67+
it("should pass icon=false correctly to web component", () => {
68+
const { container } = render(
69+
<GoabBadge
70+
type="success"
71+
content="No Icon"
72+
icon={false}
73+
iconType="star"
74+
/>,
75+
);
76+
const el = container.querySelector("goa-badge");
77+
78+
expect(el?.getAttribute("icon")).toBe("false");
79+
expect(el?.getAttribute("icontype")).toBe("star");
80+
});
81+
82+
it("should pass icon='true' when icon={true} explicitly", () => {
83+
const { container } = render(
84+
<GoabBadge
85+
type="information"
86+
content="Show Icon"
87+
icon={true}
88+
/>,
89+
);
90+
const el = container.querySelector("goa-badge");
91+
92+
expect(el?.getAttribute("icon")).toBe("true");
93+
expect(el?.getAttribute("icontype")).toBeNull();
94+
});
95+
96+
it("should pass icon='false' when icon={false} without iconType", () => {
97+
const { container } = render(
98+
<GoabBadge
99+
type="success"
100+
content="No Icon"
101+
icon={false}
102+
/>,
103+
);
104+
const el = container.querySelector("goa-badge");
105+
106+
expect(el?.getAttribute("icon")).toBe("false");
107+
expect(el?.getAttribute("icontype")).toBeNull();
108+
});
109+
110+
it("should pass icon='false' when icon={undefined}", () => {
111+
const { container } = render(
112+
<GoabBadge
113+
type="important"
114+
content="Undefined Icon"
115+
icon={undefined}
116+
/>,
117+
);
118+
const el = container.querySelector("goa-badge");
119+
120+
expect(el?.getAttribute("icon")).toBe("false");
121+
});
122+
123+
it("should pass icon='true' when iconType and icon={true} both provided", () => {
124+
const { container } = render(
125+
<GoabBadge
126+
type="success"
127+
content="Custom Star"
128+
icon={true}
129+
iconType="star"
130+
/>,
131+
);
132+
const el = container.querySelector("goa-badge");
133+
134+
expect(el?.getAttribute("icon")).toBe("true");
135+
expect(el?.getAttribute("icontype")).toBe("star");
136+
});
38137
});

libs/react-components/src/lib/badge/badge.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GoabBadgeType, Margins } from "@abgov/ui-components-common";
1+
import { GoabBadgeType, Margins, GoabIconType } from "@abgov/ui-components-common";
22
import type { JSX } from "react";
33

44
interface WCProps extends Margins {
@@ -7,6 +7,7 @@ interface WCProps extends Margins {
77
content?: string;
88
arialabel?: string;
99
testid?: string;
10+
icontype?: GoabIconType;
1011
}
1112

1213
declare module "react" {
@@ -24,6 +25,25 @@ export interface GoabBadgeProps extends Margins {
2425
content?: string;
2526
testId?: string;
2627
ariaLabel?: string;
28+
iconType?: GoabIconType;
29+
}
30+
31+
/**
32+
* Determines the icon display logic for the badge component.
33+
* Priority order:
34+
* 1. icon={true} - always show icon, starting with default
35+
* 2. icon={false} - always hide icon (overrides iconType)
36+
* 3. iconType provided - show custom icon
37+
* 4. default/no icon or iconType set - hide icon
38+
*/
39+
function getIconValue(icon?: boolean, iconType?: GoabIconType): "true" | "false" {
40+
// Explicit icon prop takes precedence
41+
if (icon !== undefined) {
42+
return icon ? "true" : "false";
43+
}
44+
45+
// Show custom icon if iconType is provided
46+
return iconType ? "true" : "false";
2747
}
2848

2949
export function GoabBadge({
@@ -36,14 +56,17 @@ export function GoabBadge({
3656
mb,
3757
ml,
3858
ariaLabel,
59+
iconType,
3960
}: GoabBadgeProps): JSX.Element {
4061
return (
4162
<goa-badge
4263
type={type}
4364
content={content}
44-
icon={icon ? "true" : undefined}
65+
// Handle icon display priority: explicit icon prop takes precedence over iconType
66+
icon={getIconValue(icon, iconType)}
4567
testid={testId}
4668
arialabel={ariaLabel}
69+
icontype={iconType}
4770
mt={mt}
4871
mr={mr}
4972
mb={mb}

libs/web-components/src/components/badge/Badge.html-data.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,66 @@
2727
},
2828
{
2929
"name": "light"
30+
},
31+
{
32+
"name": "archived"
33+
},
34+
{
35+
"name": "aqua"
36+
},
37+
{
38+
"name": "black"
39+
},
40+
{
41+
"name": "blue"
42+
},
43+
{
44+
"name": "green"
45+
},
46+
{
47+
"name": "orange"
48+
},
49+
{
50+
"name": "pink"
51+
},
52+
{
53+
"name": "red"
54+
},
55+
{
56+
"name": "violet"
57+
},
58+
{
59+
"name": "white"
60+
},
61+
{
62+
"name": "yellow"
63+
},
64+
{
65+
"name": "aqua-light"
66+
},
67+
{
68+
"name": "black-light"
69+
},
70+
{
71+
"name": "blue-light"
72+
},
73+
{
74+
"name": "green-light"
75+
},
76+
{
77+
"name": "orange-light"
78+
},
79+
{
80+
"name": "pink-light"
81+
},
82+
{
83+
"name": "red-light"
84+
},
85+
{
86+
"name": "violet-light"
87+
},
88+
{
89+
"name": "yellow-light"
3090
}
3191
]
3292
},
@@ -37,6 +97,11 @@
3797
"default": "false",
3898
"valueSet": "boolean"
3999
},
100+
{
101+
"name": "icontype",
102+
"description": "Custom icon type to override the default icon for the badge type",
103+
"type": "string"
104+
},
40105
{
41106
"name": "content",
42107
"description": "Text label of the badge",

0 commit comments

Comments
 (0)