Skip to content

Commit

Permalink
Merge pull request #85 from nhsuk/badge
Browse files Browse the repository at this point in the history
Add badge component
  • Loading branch information
davidhunter08 authored Jun 12, 2024
2 parents a2627b1 + cde6b55 commit aecd897
Show file tree
Hide file tree
Showing 14 changed files with 232 additions and 2 deletions.
60 changes: 60 additions & 0 deletions docs/components/badge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
layout: layouts/component.njk
title: Badge
description: Use badges to alert users to unread information. Badges can include a number count.
backlogID: 0
tags:
- component
---

## When to use

Badges can be placed:

- on the edge of an icon
- on a card

Badges help to notify users about unread information that needs their attention. This could include new messages or new documents.

## How to use

Badges should be dynamic and temporary. After users have viewed the relevant information, badges should either:

- disappear
- remain if there are still unread items (but with an adjusted number count, if one is used)

There are different size and colour variations of badges.

### Large badges

{% example "badges/badge-large.njk" %}

Large badges always include a number count. This tells users how many items need their attention.

Above the count of 9, large badges always display 9+. This allows the width of the badge to be restricted to two characters.

### Small badges

Small badges are simple circles. They can be placed:

- on the edge of icons, such as on the bottom navigation
- on cards, alongside text, such as “Document attached” on appointment cards

{% example "badges/badge-small.njk" %}

The colour of small badges can be:

- red for important notifications that needs to stand out on a page
- blue for secondary notifications that can afford to be less prominent

{% example "badges/badge-small-red.njk" %}

For example, users will see a red badge on the bottom navigation to indicate unread messages. When they then navigate to their messages inbox to view those messages, unread message headings are indicated by blue badges.

## Accessibility

Badges are designed to stand out when placed over icons and cards. The contrast ratio is 3:1, meeting [WCAG 2.2. Contrast (Minimum) (Level AA)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum).

We use visually hidden text to convey badges to screen reader users. Large badges announce the number count up to 9. They announce "nine plus" after that to match the visual display of 9+.

Small badges could announce "New notification", "Important" or "You have unread messages" depending on the context.
2 changes: 1 addition & 1 deletion docs/components/card-links.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ If you are using icons, they should have [aria labels/hidden text?] so that scre

Use badges to alert users to new, important information that sits beyond a card link. This could include unread messages or new appointment details.

[embed badge example]
{% example "cards/card-link-with-badge.njk" %}

## Content guidance

Expand Down
13 changes: 13 additions & 0 deletions docs/examples/badges/badge-large.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
layout: layouts/example.njk
title: Badge Large
figmaLink: "https://www.figma.com/design/6f2CbcZ7cnpNrtKEcfQp8X/NHS-App-Design-System?node-id=128-7303&t=UdzCaY5YPtBypveQ-0"
vueLink: "https://nhsappvuecomponentlibraryv1.nonlive.nhsapp.service.nhs.uk/?path=/docs/components-nhsbadge-large--docs"
---

{% from "badge/large/macro.njk" import badgeLarge %}

{{ badgeLarge({
count: 3,
label: 'notifications'
}) }}
15 changes: 15 additions & 0 deletions docs/examples/badges/badge-small-red.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
layout: layouts/example.njk
title: Badge Small
figmaLink: "https://www.figma.com/design/6f2CbcZ7cnpNrtKEcfQp8X/NHS-App-Design-System?node-id=128-7303&t=UdzCaY5YPtBypveQ-0"
vueLink: "https://nhsappvuecomponentlibraryv1.nonlive.nhsapp.service.nhs.uk/?path=/docs/components-nhsbadge-small--docs"
---

{% from "badge/small/macro.njk" import badgeSmall %}

{{ badgeSmall({
label: 'New',
color: 'red',
text: 'Document attached',
classes: 'nhsuk-body-m'
}) }}
14 changes: 14 additions & 0 deletions docs/examples/badges/badge-small.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
layout: layouts/example.njk
title: Badge Small
figmaLink: "https://www.figma.com/design/6f2CbcZ7cnpNrtKEcfQp8X/NHS-App-Design-System?node-id=128-7303&t=UdzCaY5YPtBypveQ-0"
vueLink: "https://nhsappvuecomponentlibraryv1.nonlive.nhsapp.service.nhs.uk/?path=/docs/components-nhsbadge-small--docs"
---

{% from "badge/small/macro.njk" import badgeSmall %}

{{ badgeSmall({
label: 'New',
text: 'Document attached',
classes: 'nhsuk-body-m'
}) }}
17 changes: 17 additions & 0 deletions docs/examples/cards/card-link-with-badge.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
layout: layouts/example.njk
title: Card link with description
figmaLink: "https://www.figma.com/file/6f2CbcZ7cnpNrtKEcfQp8X/NHS-App-Design-System?type=design&node-id=128%3A7303&mode=design&t=DLiyCHcTTAYkEDa0-1"
vueLink: "https://nhsappvuecomponentlibraryv1.nonlive.nhsapp.service.nhs.uk/?path=/docs/components-nhscardlink--docs"
---

{% from "card/macro.njk" import card %}

{{ card({
title: 'Messages',
href: '#',
badgeLarge: {
count: 4,
label: 'unread messages'
}
}) }}
1 change: 1 addition & 0 deletions docs/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

{%- from 'hero/macro.njk' import hero -%}
{%- from 'card/macro.njk' import card -%}
{%- from 'badge/large/macro.njk' import badgeLarge -%}

{% block header %}
{{ super() }}
Expand Down
3 changes: 2 additions & 1 deletion src/all.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import "node_modules/nhsuk-frontend/packages/core/tools/all.scss";
@import "node_modules/nhsuk-frontend/packages/core/settings/all.scss";

@import "./components/card/card.scss";
@import "./components/card/card";
@import "./components/badge/badge";
73 changes: 73 additions & 0 deletions src/components/badge/_badge.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// ==========================================================================
// COMPONENTS / #BADGE
// ==========================================================================

@use "sass:math";

.nhsapp-badge {
@include nhsuk-typography-responsive(19);

display: inline-block;

background-color: $nhsuk-error-color;
border-radius: nhsuk-spacing(1);
color: $color_nhsuk-white;
font-weight: bold;
padding: 0 nhsuk-spacing(2);

@include mq($from: tablet) {
padding: 0 12px;
}
}

.nhsapp-badge-small {
position: relative;

display: inline-flex;
align-items: baseline;
}

/**
* Mixin to position the small badge
* @param {number} $size - The size of the badge
*/
@mixin small-badge-position($size: 8px) {
position: relative;
width: $size;
height: $size;
margin-right: $size;
border-radius: math.div($size, 2);

$font-height: 0.7em; // The height of a capital letter in the specific font we use (Frutiger)
bottom: calc(0.5 * ($font-height - $size));
}

$nhsapp-badge-size-mobile: 8px;
$nhsapp-badge-size-tablet: 12px;

.nhsapp-badge-small__indicator {
@include small-badge-position($nhsapp-badge-size-mobile);

@include mq($from: tablet) {
@include small-badge-position($nhsapp-badge-size-tablet);
}

background-color: $color_nhsuk-blue;
}

.nhsapp-badge-small--red {
.nhsapp-badge-small__indicator {
background-color: $nhsuk-error-color;
}
}

.nhsapp-badge-small--absolute {
.nhsapp-badge-small__indicator {
position: absolute;

left: -2 * $nhsapp-badge-size-mobile;
@include mq($from: tablet) {
left: -2 * $nhsapp-badge-size-tablet;
}
}
}
11 changes: 11 additions & 0 deletions src/components/badge/large/badge-large.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{%- if params.count -%}
<span class="nhsapp-badge">
<span class="nhsuk-u-visually-hidden">You have</span>
{% if params.count > 9 %}
+9
{% else %}
{{ params.count }}
{% endif %}
<span class="nhsuk-u-visually-hidden">{{ params.label }}</span>
</span>
{%- endif -%}
3 changes: 3 additions & 0 deletions src/components/badge/large/macro.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% macro badgeLarge(params) %}
{%- include "./badge-large.njk" -%}
{% endmacro %}
9 changes: 9 additions & 0 deletions src/components/badge/small/badge-small.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<span class="
nhsapp-badge-small
{{ 'nhsapp-badge-small--red' if params.color === 'red' }}
{{ 'nhsapp-badge-small--absolute' if params.positionAbsolute }}
{{ params.classes if params.classes }}">
<span class="nhsapp-badge-small__indicator" aria-hidden="true"></span>
<span class="nhsuk-u-visually-hidden">{{ params.label }}</span>
<span>{{ params.text }}</span>
</span>
3 changes: 3 additions & 0 deletions src/components/badge/small/macro.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% macro badgeSmall(params) %}
{%- include "./badge-small.njk" -%}
{% endmacro %}
10 changes: 10 additions & 0 deletions src/components/card/card.njk
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{% from "badge/large/macro.njk" import badgeLarge %}

{% set hasBadgeLarge = true if params.badgeLarge.count > 1 %}

<div class="nhsapp-card">
<div class="nhsapp-card__container">
<div class="nhsapp-card__content">
Expand All @@ -10,6 +14,12 @@
</div>
{%- endif -%}
</div>
{% if hasBadgeLarge %}
{{ badgeLarge({
count: params.badgeLarge.count,
label: params.badgeLarge.label
}) }}
{% endif %}
<svg class="nhsapp-icon app-icon--chevron" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="25" height="24" viewBox="0 0 25 24" fill="none">
<path d="M8.82264 19.11C8.56264 19.11 8.29264 19.01 8.10264 18.8C7.72264 18.4 7.73264 17.77 8.13264 17.39L13.7426 12.01L8.14264 6.75999C7.74264 6.37999 7.72264 5.74999 8.09264 5.34999C8.47264 4.94999 9.10264 4.92999 9.50264 5.29999L15.8726 11.27C16.0726 11.46 16.1826 11.72 16.1926 11.99C16.2026 12.26 16.0826 12.53 15.8826 12.72L9.51264 18.83C9.32264 19.02 9.07264 19.11 8.82264 19.11Z"></path>
</svg>
Expand Down

0 comments on commit aecd897

Please sign in to comment.