Badge

Small labels which hold small amounts of information, system feedback, or states.

Props

type
information | important | emergency | success | dark | midtone | light | archived | aqua | black | blue | green | orange | pink | red | violet | white | yellow | aqua-light | black-light | blue-light | green-light | orange-light | pink-light | red-light | violet-light | yellow-light | sky | prairie | lilac | pasture | sunset | dawn | default
Defines the context and colour of the badge.
testId
string
Sets the data-testid attribute. Used with ByTestId queries in tests.
content
string
Text label of the badge.
icon
string
Use icontype instead. Includes an icon in the badge.
icontype
GoAIconType
Icon type to display in the badge.
ariaLabel
string
Accessible label for screen readers.
size
medium | large
Sets the size of the badge.
Defaults to medium.
emphasis
Sets the visual emphasis. 'subtle' for less prominent, 'strong' for more emphasis.
Defaults to strong.
version
1 | 2
The design system version for styling purposes.
Defaults to 1.
mt, mr, mb, ml
none | 3xs | 2xs | xs | s | m | l | xl | 2xl | 3xl | 4xl
Apply margin to the top, right, bottom, and/or left of the component.
Examples

Card view of case files

ReactAngularWeb Components
.case-file-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--goa-space-m);
}
<GoabContainer mt="l">
        <div className="case-file-row">
          <GoabBlock direction="column" gap="2xs">
            <GoabText size="heading-xs" mt="none" mb="2xs">Fiscal year: 2021/2022</GoabText>
            <GoabText size="body-s" mt="none" mb="none">Submitted: April 23, 2023</GoabText>
          </GoabBlock>
          <GoabBlock direction="row" gap="l" alignment="center">
            <GoabBadge type="midtone" content="Not started" />
            <GoabButton type="tertiary" size="compact">Start</GoabButton>
          </GoabBlock>
        </div>
      </GoabContainer>

      <GoabContainer>
        <div className="case-file-row">
          <GoabBlock direction="column" gap="2xs">
            <GoabText size="heading-xs" mt="none" mb="2xs">Fiscal year: 2020/2021</GoabText>
            <GoabText size="body-s" mt="none" mb="none">Submitted: April 9, 2022</GoabText>
          </GoabBlock>
          <GoabBlock direction="row" gap="l" alignment="center">
            <GoabBadge type="important" content="Information needed" />
            <GoabButton type="tertiary" size="compact">Edit</GoabButton>
          </GoabBlock>
        </div>
      </GoabContainer>

      <GoabContainer>
        <div className="case-file-row">
          <GoabBlock direction="column" gap="2xs">
            <GoabText size="heading-xs" mt="none" mb="2xs">Fiscal year: 2019/2020</GoabText>
            <GoabText size="body-s" mt="none" mb="none">Submitted: April 14, 2021</GoabText>
          </GoabBlock>
          <GoabBlock direction="row" gap="l" alignment="center">
            <GoabBadge type="success" content="Approved" />
            <GoabButton type="tertiary" size="compact">View</GoabButton>
          </GoabBlock>
        </div>
      </GoabContainer>

Expand or collapse part of a form

ReactAngularWeb Components
dl.accordion-example {
  margin: 0 0;
}
.accordion-example dt {
  color: var(--goa-color-text-default);
  font: var(--goa-typography-heading-s);
  margin-bottom: var(--goa-space-xs);
}
.accordion-example dd {
  margin: 0 0 var(--goa-space-l);
  font: var(--goa-typography-body-m);
}
.accordion-example dd:last-of-type {
  margin-bottom: 0;
}
<GoabText as="h3" mt="none" mb="m">Review your application</GoabText>

      <GoabAccordion
        heading="Referral details"
        headingContent={<GoabBadge type="important" content="Updated" />}>
        <dl className="accordion-example">
          <dt>Date of referral</dt>
          <dd>January 27, 2021</dd>
          <dt>Work safety concerns</dt>
          <dd>None</dd>
          <dt>Type of referral</dt>
          <dd>Word of mouth, internet search</dd>
          <dt>Intake received from another site</dt>
          <dd>Yes</dd>
        </dl>
      </GoabAccordion>

      <GoabAccordion heading="Contact information">
        <dl className="accordion-example">
          <dt>Name</dt>
          <dd>Joan Smith</dd>
          <dt>Contact preference</dt>
          <dd>Text message</dd>
        </dl>
      </GoabAccordion>

Filter data in a table

ReactAngularWeb Components
const [typedChips, setTypedChips] = useState<string[]>([]);
  const [inputValue, setInputValue] = useState("");
  const [inputError, setInputError] = useState("");
  const errorEmpty = "Empty filter";
  const errorDuplicate = "Enter a unique filter";

  const data = useMemo(
    () => [
      {
        status: { type: "information" as GoabBadgeType, text: "In progress" },
        name: "Ivan Schmidt",
        id: "7838576954",
      },
      {
        status: { type: "success" as GoabBadgeType, text: "Completed" },
        name: "Luz Lakin",
        id: "8576953364",
      },
      {
        status: { type: "information" as GoabBadgeType, text: "In progress" },
        name: "Keith McGlynn",
        id: "9846041345",
      },
      {
        status: { type: "success" as GoabBadgeType, text: "Completed" },
        name: "Melody Frami",
        id: "7385256175",
      },
      {
        status: { type: "important" as GoabBadgeType, text: "Updated" },
        name: "Frederick Skiles",
        id: "5807570418",
      },
      {
        status: { type: "success" as GoabBadgeType, text: "Completed" },
        name: "Dana Pfannerstill",
        id: "5736306857",
      },
    ],
    []
  );

  const [dataFiltered, setDataFiltered] = useState(data);

  const handleInputChange = (detail: GoabInputOnChangeDetail) => {
    const newValue = detail.value.trim();
    setInputValue(newValue);
  };

  const handleInputKeyPress = (detail: GoabInputOnKeyPressDetail) => {
    if (detail.key === "Enter") {
      applyFilter();
    }
  };

  const applyFilter = () => {
    if (inputValue === "") {
      setInputError(errorEmpty);
      return;
    }
    if (typedChips.length > 0 && typedChips.includes(inputValue)) {
      setInputError(errorDuplicate);
      return;
    }
    setTypedChips([...typedChips, inputValue]);
    setTimeout(() => {
      setInputValue("");
    }, 0);
    setInputError("");
  };

  const removeTypedChip = (chip: string) => {
    setTypedChips(typedChips.filter(c => c !== chip));
    setInputError("");
  };

  const checkNested = useCallback((obj: object, chip: string): boolean => {
    return Object.values(obj).some(value =>
      typeof value === "object" && value !== null
        ? checkNested(value, chip)
        : typeof value === "string" && value.toLowerCase().includes(chip.toLowerCase())
    );
  }, []);

  const getFilteredData = useCallback(
    (typedChips: string[]) => {
      if (typedChips.length === 0) {
        return data;
      }
      return data.filter((item: object) =>
        typedChips.every(chip => checkNested(item, chip))
      );
    },
    [checkNested, data]
  );

  useEffect(() => {
    setDataFiltered(getFilteredData(typedChips));
  }, [getFilteredData, typedChips]);
<GoabFormItem id="filterChipInput" error={inputError} mb="m">
        <GoabBlock gap="xs" direction="row" alignment="start" width="100%">
          <div style={{ flex: 1 }}>
            <GoabInput
              name="filterChipInput"
              aria-labelledby="filterChipInput"
              value={inputValue}
              leadingIcon="search"
              width="100%"
              onChange={handleInputChange}
              onKeyPress={handleInputKeyPress}
            />
          </div>
          <GoabButton type="secondary" onClick={applyFilter} leadingIcon="filter">
            Filter
          </GoabButton>
        </GoabBlock>
      </GoabFormItem>

      {typedChips.length > 0 && (
        <div>
          <GoabText tag="span" color="secondary" mb="xs" mr="xs">
            Filter:
          </GoabText>
          {typedChips.map((typedChip, index) => (
            <GoabFilterChip
              key={index}
              content={typedChip}
              mb="xs"
              mr="xs"
              onClick={() => removeTypedChip(typedChip)}
            />
          ))}
          <GoabButton type="tertiary" size="compact" mb="xs" onClick={() => setTypedChips([])}>
            Clear all
          </GoabButton>
        </div>
      )}

      <GoabTable width="full">
        <thead>
          <tr>
            <th>Status</th>
            <th>Name</th>
            <th className="goa-table-number-header">ID Number</th>
          </tr>
        </thead>
        <tbody>
          {dataFiltered.map(item => (
            <tr key={item.id}>
              <td>
                <GoabBadge type={item.status.type} content={item.status.text} icon={false} />
              </td>
              <td>{item.name}</td>
              <td className="goa-table-number-column">{item.id}</td>
            </tr>
          ))}
        </tbody>
      </GoabTable>

      {dataFiltered.length === 0 && data.length > 0 && (
        <GoabBlock mt="l" mb="l">
          No results found
        </GoabBlock>
      )}

Set a specific tab to be active

ReactAngularWeb Components
const review = [0, 1, 2, 3];
  const complete = [0, 1];
<GoabTabs initialTab={2}>
      <GoabTab heading="All">
        <GoabTable width="100%">
          <thead>
            <tr>
              <th>Status</th>
              <th>Text</th>
              <th className="goa-table-number-header">Number</th>
              <th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
            </tr>
          </thead>
          <tbody>
            {review.map((i) => (
              <tr key={`review-${i}`}>
                <td>
                  <GoabBadge type="important" content="Review pending" />
                </td>
                <td>Lorem Ipsum</td>
                <td className="goa-table-number-column">1234567890</td>
                <td>
                  <GoabButton type="tertiary" size="compact">Action</GoabButton>
                </td>
              </tr>
            ))}
            {complete.map((i) => (
              <tr key={`complete-${i}`}>
                <td>
                  <GoabBadge type="information" content="Complete" />
                </td>
                <td>Lorem Ipsum</td>
                <td className="goa-table-number-column">1234567890</td>
                <td>
                  <GoabButton type="tertiary" size="compact">Action</GoabButton>
                </td>
              </tr>
            ))}
          </tbody>
        </GoabTable>
      </GoabTab>
      <GoabTab heading={<>Review pending<GoabBadge type="important" content="4" icon={false} /></>}>
        <GoabTable width="100%">
          <thead>
            <tr>
              <th>Status</th>
              <th>Text</th>
              <th className="goa-table-number-header">Number</th>
              <th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
            </tr>
          </thead>
          <tbody>
            {review.map((i) => (
              <tr key={i}>
                <td>
                  <GoabBadge type="important" content="Review pending" />
                </td>
                <td>Lorem Ipsum</td>
                <td className="goa-table-number-column">1234567890</td>
                <td>
                  <GoabButton type="tertiary" size="compact">Action</GoabButton>
                </td>
              </tr>
            ))}
          </tbody>
        </GoabTable>
      </GoabTab>
      <GoabTab heading={<>Complete<GoabBadge type="information" content="338" icon={false} /></>}>
        <GoabTable width="100%">
          <thead>
            <tr>
              <th>Status</th>
              <th>Text</th>
              <th className="goa-table-number-header">Number</th>
              <th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
            </tr>
          </thead>
          <tbody>
            {complete.map((i) => (
              <tr key={i}>
                <td>
                  <GoabBadge type="information" content="Complete" />
                </td>
                <td>Lorem Ipsum</td>
                <td className="goa-table-number-column">1234567890</td>
                <td>
                  <GoabButton type="tertiary" size="compact">Action</GoabButton>
                </td>
              </tr>
            ))}
          </tbody>
        </GoabTable>
      </GoabTab>
    </GoabTabs>

Show different views of data in a table

ReactAngularWeb Components
const review = [0, 1, 2, 3];
  const complete = [0, 1];
<GoabTabs initialTab={1}>
          <GoabTab heading="All">
            <GoabTable width="100%">
              <thead>
                <tr>
                  <th>Status</th>
                  <th>Text</th>
                  <th className="goa-table-number-header">Number</th>
                  <th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
                </tr>
              </thead>
              <tbody>
                {review.map((i) => (
                  <tr key={`review-${i}`}>
                    <td>
                      <GoabBadge type="important" content="Review pending" />
                    </td>
                    <td>Lorem Ipsum</td>
                    <td className="goa-table-number-column">1234567890</td>
                    <td>
                      <GoabButton type="tertiary" size="compact">Action</GoabButton>
                    </td>
                  </tr>
                ))}
                {complete.map((i) => (
                  <tr key={`complete-${i}`}>
                    <td>
                      <GoabBadge type="information" content="Complete" />
                    </td>
                    <td>Lorem Ipsum</td>
                    <td className="goa-table-number-column">1234567890</td>
                    <td>
                      <GoabButton type="tertiary" size="compact">Action</GoabButton>
                    </td>
                  </tr>
                ))}
              </tbody>
            </GoabTable>
          </GoabTab>
          <GoabTab
            heading={
                Review pending
                <GoabBadge type="important" content="4" icon={false} />
            }
          >
            <GoabTable width="100%">
              <thead>
                <tr>
                  <th>Status</th>
                  <th>Text</th>
                  <th className="goa-table-number-header">Number</th>
                  <th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
                </tr>
              </thead>
              <tbody>
                {review.map((i) => (
                  <tr key={i}>
                    <td>
                      <GoabBadge type="important" content="Review pending" />
                    </td>
                    <td>Lorem Ipsum</td>
                    <td className="goa-table-number-column">1234567890</td>
                    <td>
                      <GoabButton type="tertiary" size="compact">Action</GoabButton>
                    </td>
                  </tr>
                ))}
              </tbody>
            </GoabTable>
          </GoabTab>
          <GoabTab
            heading={
              <>
                Complete
                <GoabBadge type="information" content="338" icon={false} />
              </>
            }
          >
            <GoabTable width="100%">
              <thead>
                <tr>
                  <th>Status</th>
                  <th>Text</th>
                  <th className="goa-table-number-header">Number</th>
                  <th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
                </tr>
              </thead>
              <tbody>
                {complete.map((i) => (
                  <tr key={i}>
                    <td>
                      <GoabBadge type="information" content="Complete" />
                    </td>
                    <td>Lorem Ipsum</td>
                    <td className="goa-table-number-column">1234567890</td>
                    <td>
                      <GoabButton type="tertiary" size="compact">Action</GoabButton>
                    </td>
                  </tr>
                ))}
              </tbody>
            </GoabTable>
          </GoabTab>
    </GoabTabs>

Show multiple actions in a compact table

ReactAngularWeb Components
const rows = [
    { status: "information", statusText: "In progress", name: "Darlene Robertson", id: 45904 },
    { status: "dark", statusText: "Inactive", name: "Floyd Miles", id: 47838 },
    { status: "success", statusText: "Active", name: "Kathryn Murphy", id: 34343 },
    { status: "important", statusText: "Recent", name: "Annette Black", id: 89897 },
    { status: "success", statusText: "Active", name: "Esther Howard", id: 12323 },
    { status: "success", statusText: "Active", name: "Jane Cooper", id: 56565 },
  ];
<GoabTable width="100%">
      <thead>
        <tr>
          <th>Status</th>
          <th>Name</th>
          <th style={{ textAlign: "right" }}>Id Number</th>
          <th style={{ width: "1%", whiteSpace: "nowrap" }}>Edit | Flag | Send</th>
        </tr>
      </thead>
      <tbody>
        {rows.map((row) => (
          <tr key={row.id}>
            <td>
              <GoabBadge
                type={row.status as "information" | "dark" | "success" | "important"}
                content={row.statusText}
                icon={false}
              />
            </td>
            <td>{row.name}</td>
            <td className="goa-table-number-column">{row.id}</td>
            <td>
              <GoabBlock>
                <GoabIconButton size="small" icon="pencil" ariaLabel="Edit" />
                <GoabIconButton size="small" icon="flag" ariaLabel="Flag" />
                <GoabIconButton size="small" icon="mail" ariaLabel="Send" />
              </GoabBlock>
            </td>
          </tr>
        ))}
      </tbody>
    </GoabTable>

Show multiple tags together

ReactAngularWeb Components
<GoabBlock gap="xs">
      <GoabBadge type="information" content="In progress" />
      <GoabBadge type="important" content="Priority" />
      <GoabBadge type="emergency" content="Past deadline" />
    </GoabBlock>

Show status in a table

ReactAngularWeb Components
interface BadgeValue {
  key: number;
  type: GoabBadgeType;
  content: string;
}

const badgeValues: BadgeValue[] = [
    { key: 1, type: "important", content: "Pending" },
    { key: 2, type: "emergency", content: "Failed" },
    { key: 3, type: "success", content: "Complete" },
    { key: 4, type: "information", content: "In progress" },
    { key: 5, type: "midtone", content: "Closed" },
    { key: 6, type: "success", content: "Complete" },
  ];

  const handleClick = () => {
    console.log("clicked");
  };
<GoabTable width="100%">
      <thead>
        <tr>
          <th>Status</th>
          <th>Name</th>
          <th className="goa-table-number-header">File number</th>
          <th style={{ width: "1%", whiteSpace: "nowrap" }}></th>
        </tr>
      </thead>
      <tbody>
        {badgeValues.map((badge) => (
          <tr key={badge.key}>
            <td>
              <GoabBadge type={badge.type} content={badge.content} icon={false} />
            </td>
            <td>Lorem ipsum dolor sit amet consectetur</td>
            <td className="goa-table-number-column">1234567890</td>
            <td>
              <GoabButton size="compact" type="tertiary" onClick={handleClick}>
                Assign
              </GoabButton>
            </td>
          </tr>
        ))}
      </tbody>
    </GoabTable>

Show status on a card

ReactAngularWeb Components
<GoabContainer
      type="non-interactive"
      accent="thick"
      heading="Heading"
      actions={<GoabBadge type="important" content="Priority" />}
    >
      Content
    </GoabContainer>

Task list page

ReactAngularWeb Components
<GoabText as="h1" mt="none">Apply for a service</GoabText>
      <GoabCallout
        type="important"
        emphasis="low"
        size="medium"
        heading="Application incomplete"
        mb="2xl"
        mt="xl"
        maxWidth="360px"
      >
        You have completed 1 of 3 sections.
      </GoabCallout>

      <GoabText as="h2">1. Before you start</GoabText>
      <GoabTable width="100%" mb="2xl" mt="l">
        <tbody>
          <tr>
            <td>
              <a href="#">Read terms of use</a>
            </td>
            <td className="goa-table-number-column">
              <GoabBadge type="success" content="Completed" ariaLabel="completed" icon={false} />
            </td>
          </tr>
        </tbody>
      </GoabTable>

      <GoabText as="h2">2. Prepare application</GoabText>
      <GoabTable width="100%" mb="2xl" mt="l">
        <tbody>
          <tr>
            <td>
              <a href="#">Your contact details</a>
            </td>
            <td className="goa-table-number-column">
              <GoabBadge type="information" content="Not started" ariaLabel="not started" icon={false} />
            </td>
          </tr>
          <tr>
            <td>
              <a href="#">Your family</a>
            </td>
            <td className="goa-table-number-column">
              <GoabBadge type="information" content="Not started" ariaLabel="not started" icon={false} />
            </td>
          </tr>
          <tr>
            <td>
              <a href="#">Verify your identity</a>
            </td>
            <td className="goa-table-number-column">
              <GoabBadge type="information" content="Not started" ariaLabel="not started" icon={false} />
            </td>
          </tr>
        </tbody>
      </GoabTable>

      <GoabText as="h2" mb="s">3. Schedule service</GoabText>
      <GoabText size="body-s" color="secondary" mt="2xs">
        You need to complete the previous section before you can start this task.
      </GoabText>
      <GoabTable width="100%" mt="l" mb="3xl">
        <tbody>
          <tr>
            <td>Receive email confirmation</td>
            <td className="goa-table-number-column">
              <GoabBadge type="light" content="Cannot start yet" ariaLabel="cannot start yet" icon={false} />
            </td>
          </tr>
          <tr>
            <td>Pay service fee</td>
            <td className="goa-table-number-column">
              <GoabBadge type="light" content="Cannot start yet" ariaLabel="cannot start yet" icon={false} />
            </td>
          </tr>
        </tbody>
      </GoabTable>

Other

Edit
Don't use a primary button to edit a badge.
Use badges for information and organization, not interactivity.
Edit
Use a tertiary button next to a badge if it needs to be manually updated.

Types

Don't style badges to look like buttons.
Don't use interactive colours. These are reserved for links, buttons, and other interactive elements.
Match badge type to the status it represents

Content

Use sentence case for badge text. Capitalize the first word only.
Use short, concise text in badges.
All GoA Design System components are built to meet WCAG 2.2 AA standards. The following guidelines provide additional context for accessible implementation.

Screen Readers

Icon-only interactive elements must have an accessible label so screen reader users understand their purpose.

For IconButton: The ariaLabel prop is required.

// Good - describes the action
<GoabIconButton icon="trash" ariaLabel="Delete item" />

// Bad - no label for screen readers
<GoabIconButton icon="trash" />

For Badge with icon only: Provide ariaLabel when there’s no visible text.

<GoabBadge icon="warning" ariaLabel="Warning" type="important" />

For Icon: Use ariaLabel when the icon conveys meaning, not just decoration.

The label should describe:

  • What action happens (for buttons): “Delete”, “Edit”, “Close”
  • What the icon represents (for informational icons): “Warning”, “Success”
Don't use icon-only elements without an accessible label