diff --git a/docs/_includes/layouts/base.njk b/docs/_includes/layouts/base.njk index ba501f81b..b0fffab5c 100644 --- a/docs/_includes/layouts/base.njk +++ b/docs/_includes/layouts/base.njk @@ -31,6 +31,7 @@ + diff --git a/docs/_includes/layouts/component.njk b/docs/_includes/layouts/component.njk index 83e985474..de42d5893 100644 --- a/docs/_includes/layouts/component.njk +++ b/docs/_includes/layouts/component.njk @@ -6,7 +6,7 @@ {% if not isIndex %}Components{% endif %} {{ title }} - + {{ content | safe }} {% include "./partials/get-help-and-contribute.njk" %} diff --git a/docs/_includes/layouts/home.njk b/docs/_includes/layouts/home.njk index b58bf398f..c70050730 100644 --- a/docs/_includes/layouts/home.njk +++ b/docs/_includes/layouts/home.njk @@ -19,6 +19,7 @@
{% call card({title: "What's new" })%} +

10 December 2024: The interruption card component is now live. Use this component to help users understand possible errors and avoid serious mistakes.

26 November 2024: We’ve archived the password reveal component. We recommend that teams use the GOV.UK Design System password input instead.

{% endcall %} diff --git a/docs/assets/images/interruption-card-example-are-you-sure.png b/docs/assets/images/interruption-card-example-are-you-sure.png new file mode 100644 index 000000000..19d6f2cf5 Binary files /dev/null and b/docs/assets/images/interruption-card-example-are-you-sure.png differ diff --git a/docs/assets/images/interruption-card-example-important-content.png b/docs/assets/images/interruption-card-example-important-content.png new file mode 100644 index 000000000..0cbbdc7ac Binary files /dev/null and b/docs/assets/images/interruption-card-example-important-content.png differ diff --git a/docs/assets/images/interruption-card-example-non-contextual-error.png b/docs/assets/images/interruption-card-example-non-contextual-error.png new file mode 100644 index 000000000..f2b5835a9 Binary files /dev/null and b/docs/assets/images/interruption-card-example-non-contextual-error.png differ diff --git a/docs/assets/images/interruption-card-example-possible-error.png b/docs/assets/images/interruption-card-example-possible-error.png new file mode 100644 index 000000000..b38b8810e Binary files /dev/null and b/docs/assets/images/interruption-card-example-possible-error.png differ diff --git a/docs/assets/images/interruption-card-example-varied-outcome.png b/docs/assets/images/interruption-card-example-varied-outcome.png new file mode 100644 index 000000000..b4b99922f Binary files /dev/null and b/docs/assets/images/interruption-card-example-varied-outcome.png differ diff --git a/docs/components/interruption-card.md b/docs/components/interruption-card.md new file mode 100644 index 000000000..c9de0df1a --- /dev/null +++ b/docs/components/interruption-card.md @@ -0,0 +1,176 @@ +--- +layout: layouts/component.njk +title: Interruption card +type: component +githuburl: https://github.com/ministryofjustice/moj-frontend/discussions/421 +eleventyNavigation: + key: Interruption card + parent: Components + excerpt: "The interruption card component stops users in a flow with important information. +" +contributors: Anne Walker, James McKechnie, Lizzie Goddard, Jonathan Porton, Rachel Ricks, Mary Bowden, Louise Jones, Ed Marshall, Quay Pho, Sara Yassine and Deb Gilkes +basedon: interruption card discussion on the GOV.UK Design System backlog +basedonurl: https://github.com/alphagov/govuk-design-system-backlog/issues/27 +--- + +The interruption card component pauses a user’s journey with important information. + +{% example "/examples/interruption-card", 590 %} + +## Overview + +The interruption card uses visual prominence to draw a user's attention to something important. The user has to acknowledge it to continue. + +### When to use + +The interruption card helps users to understand possible errors and avoid mistakes (especially serious ones). + +This component should be used specifically and sparingly. It has 5 use cases: + +1. [Possible errors](#1.-possible-errors) +2. [‘Are you sure?’ content](#2.-%E2%80%98are-you-sure%3F%E2%80%99-content) +3. [Non-contextual errors](#3.-non-contextual-errors) +4. [More varied application outcomes](#4.-more-varied-application-outcomes) +5. [Showing important content ahead of a task](#5.-showing-important-content-ahead-of-a-task) + +#### 1. Possible errors + +A possible error is something which is quite likely to be a mistake. + +An interruption card gives the user more detailed or contextual information about why their answer is unexpected. They can continue without changing their answer, unlike with a validation error. + +Example of a possible error: + +

A screen showing an MoJ header and footer. There's a back link above the card. The rest of the page is a blue interruption card. The card contains a heading, paragraph content, a button and a link. The interruption card is  used to question whether the user has entered the correct salary. Under the text is a white button with blue text: 'Yes, this is correct'. To the right of it is the link text 'Go back to income details'.

+ +#### 2. ‘Are you sure?’ content + +Sometimes a user needs to know something important about a task they've started, and confirm that they want to continue. This can stop them from doing something serious by accident, such as a deletion or cancellation. + +This type of interruption card is shown to everyone on a particular user journey, because it's about the task itself. + +If the outcome is less serious, and the information is just 'good to know', consider removing the content from the interruption card and using standard colour styling. + +Example of ‘Are you sure?’ content: + +

A screen showing an MoJ header and footer. There's a back link above the card. The rest of the page is a blue interruption card. The card contains a heading, paragraph content, a button and a link. The card is used to confirm whether the user wants to cancel this referral, because it'll remove the person from a waiting list. The user can proceed via a white button with blue text or cancel via a link link, with text 'Go back to application'.

+ +#### 3. Non-contextual errors + +A non-contextual error happens when there’s a conflict between 2 or more parts of a service. The error is with the application as a whole, not a specific part. This means that a message cannot be shown next to the source of the error, such as with a [GOV.UK Design System error message](https://design-system.service.gov.uk/components/error-message/). + +Service design should prevent these errors. However, they can happen if a user edits an early part of a form (via a [GOV.UK Design System Check answers pattern page](https://design-system.service.gov.uk/patterns/check-answers/)) in a way that affects later parts. For example, if a person’s income has changed since an application was started, they might need to answer different sections. + +The interruption card tells users how to resolve the error, for example by answering some sections again or agreeing to delete sections. The user may also want to copy the answers they've given before they’re deleted. + +Example of a non-contextual error: + +

A screen showing an MoJ header and footer. The rest of the page is a blue interruption card. The card contains a heading, paragraph content, a button and a link. The card is used to explain that a new answer affects other sections of the application. Under the text is a white button with blue text: 'Continue to other sections'. To the right of it is the link text 'Go back to application'.

+ +#### 4. More varied application outcomes + +The interruption card can be used for application outcomes which are different to a straightforward success, rejection or completion. + +This might be needed when the user: + +- has met all the success criteria, and can finish the rest of the application later +- needs to do something else after the application, for example contact a solicitor +- needs to go to another service for a task + +Example of a more varied application outcome: + +

A screen showing an MoJ header and footer. The rest of the page is a blue interruption card. The card contains a heading, paragraph content, a button and a link. The card is used to explain that the user is eligible for a payment, can submit their application but may need to provide more information later.' The user can submit using the button and enter more information using the link.

+ +#### 5. Showing important content ahead of a task + +It can be helpful to show a user important information before they start a task, particularly if the content has been missed elsewhere (for example, on a start page). + +To prevent the interruption card being overused, start with the [GOV.UK Design System inset text component](https://design-system.service.gov.uk/components/inset-text/) or the [GOV.UK Design System warning text component](https://design-system.service.gov.uk/components/warning-text/). If neither work (or something is very important) try the interruption card. + +The user can continue once they have acknowledged the content in the interruption card. They are not declaring anything, though. Declarations are for users to confirm that they've understood information they've been given or agree to something. This is not an interruption because it's part of the flow. + +Example of showing important content ahead of a task: + +

A screen showing an MoJ header and footer. The rest of the page is a blue interruption card. The card contains a heading, paragraph content, a button and a link. The card is used to explain that the prison visit is closed and that there can no physical contact. The user can continue or go back.

+ +### When not to use + +Do not use the interruption card for anything outside of the 5 use cases. It should also not be used to: + +- emphasise large amounts of content on a page (as the impact will be lost) +- show form elements such as radio buttons (a red error message on the blue background is not accessible) +- make a heading more visually prominent +- display an empty state for the user to resolve (if it's within a list) – use the [GOV.UK Design System tasklist component](https://design-system.service.gov.uk/components/task-list/) instead + +### Things to consider + +The card is not announced to screen reader users when they interact with the page, so the heading needs to clearly convey that the user is being interrupted. This can be done with content such as ‘Before you continue’. + +The interruption card uses a non-standard colour palette for emphasis in a user journey. Other blue parts of a page, such as a header, person identifier or phase banner, will affect how much impact it has. + +### Similar or linked components + +There’s also the: + +- [GOV.UK Design System warning text component](https://design-system.service.gov.uk/components/warning-text/) +- [GOV.UK Design System error message](https://design-system.service.gov.uk/components/error-message/) +- [GOV.UK Design System panel](https://design-system.service.gov.uk/components/panel/) +- [GOV.UK Design System notification banner](https://design-system.service.gov.uk/components/notification-banner/) + +## How to use + +### What to add to it + +The interruption card should only contain: + +- a heading +- paragraph content (with bullets but no other styling) +- 1 button (or link) to continue +- 1 button (or link) to go back + +The only button that can be used is the [GOV.UK Design System button on a dark background](https://design-system.service.gov.uk/components/button/#buttons-on-dark-backgrounds). + +Do not add form elements (such as radio buttons). A red error message would appear on the blue background, which is not accessible. + +There’s not enough research on the use of images in interruption cards. The [GOV.UK Design System guidance on images](https://design-system.service.gov.uk/styles/images/) may help with this. + +### Colours + +The component follows the [GOV.UK Design System colour palette](https://design-system.service.gov.uk/styles/colour/): + +- the background is `govuk-colour("blue")` +- the text is `govuk-colour("white")` +- [links use the inverse modifier class](https://design-system.service.gov.uk/styles/links/#links-on-dark-backgrounds) +- [buttons use the inverse modifier class](https://design-system.service.gov.uk/components/button/#buttons-on-dark-backgrounds) + +No other button colours should be used. Do not use the [GOV.UK Design System secondary or warning buttons](https://design-system.service.gov.uk/components/button/#secondary-buttons), for example. + +### Height and width + +The interruption card has no minimum or maximum height – it resizes to the contents. It works well with fairly short, concise content. Adding a lot of content will reduce its impact. + +The component is set to full width on desktop and mobile and should not be changed. The content width will automatically adjust for readability. + +### Other parts of the page + +The interruption card should be the only body content on a page. The only other elements can be the header, footer, phase banner, person profile, breadcrumb or back link (which are all persistent). + +Do not add form elements (such as radio buttons) underneath the component. + +### How often to use it + +This interruption card works well when used sparingly. This is to keep it significant, and distinct from standard service pattern pages. + +When considering it in a specific case, think about: + +- how many other interruption cards there are in the service +- the maximum number of cards a user might view in a single journey +- whether a user would ever view 2 cards in a row (and how that could be prevented) + +If a lot of interruption cards are emerging in a service, it might be a sign that the journey needs redesigning. + +#### Repetitive journeys + +Users completing the same journey multiple times in a service will become overexposed to a particular interruption card. This could be a poor user experience if the card is used to highlight something important and the user has already seen it several times. + +Consider limiting the amount of times a particular interruption card is shown to users at the same stage of the journey. diff --git a/docs/examples/interruption-card/index.njk b/docs/examples/interruption-card/index.njk new file mode 100644 index 000000000..24ad67add --- /dev/null +++ b/docs/examples/interruption-card/index.njk @@ -0,0 +1,23 @@ +--- +layout: layouts/example.njk +title: Interruption card (example) +figma_link: https://www.figma.com/design/N2xqOFkyehXwcD9DxU1gEq/MoJ-Figma-Kit?node-id=6479-695 +--- + +{%- from "moj/components/interruption-card/macro.njk" import interruptionCard -%} +{% call interruptionCard({ + heading: "Are you sure you want to change this?", + primaryAction: { + text: "Continue", + href: "#" + }, + secondaryAction: { + text: "Go back to application", + href: "#" + } + }) -%} +

You've changed the person's address from Wales to England. This means that the referral needs to be cancelled.

+

Previous home address: 1 Willow Lane, Newchurch, Kington, HR5 3QF

+

New home address: 9 Elm Street, Whitney-on-Wye, Hereford, HR3 6EH

+

You can go back to undo this change.

+{%- endcall %} diff --git a/docs/examples/multi-select/index.njk b/docs/examples/multi-select/index.njk index 4ca8a2231..ffbe218a8 100644 --- a/docs/examples/multi-select/index.njk +++ b/docs/examples/multi-select/index.njk @@ -4,7 +4,7 @@ title: Multi select (example) figma_link: https://www.figma.com/file/N2xqOFkyehXwcD9DxU1gEq/MoJ-Figma-Kit?type=design&node-id=841-220&mode=design --- - +
diff --git a/docs/examples/pagination/index.njk b/docs/examples/pagination/index.njk index 114a3377c..8356da773 100644 --- a/docs/examples/pagination/index.njk +++ b/docs/examples/pagination/index.njk @@ -25,7 +25,7 @@ arguments: pagination }], results: { count: 30, - from: 10, + from: 11, to: 20, text: 'results' }, diff --git a/src/moj/all.js b/src/moj/all.js index c2584069a..73ae94cc3 100644 --- a/src/moj/all.js +++ b/src/moj/all.js @@ -15,7 +15,8 @@ MOJFrontend.initAll = function (options) { MOJFrontend.nodeListForEach($multiSelects, function ($multiSelect) { new MOJFrontend.MultiSelect({ container: $multiSelect.querySelector($multiSelect.getAttribute('data-multi-select-checkbox')), - checkboxes: $multiSelect.querySelectorAll('tbody .govuk-checkboxes__input') + checkboxes: $multiSelect.querySelectorAll('tbody .govuk-checkboxes__input'), + id_prefix: $multiSelect.getAttribute('data-multi-select-idprefix'), }); }); diff --git a/src/moj/components/_all.scss b/src/moj/components/_all.scss index 19812f8e0..398bfa11d 100755 --- a/src/moj/components/_all.scss +++ b/src/moj/components/_all.scss @@ -9,6 +9,7 @@ @import "filter/filter"; @import "header/header"; @import "identity-bar/identity-bar"; +@import "interruption-card/interruption-card"; @import "messages/messages"; @import "multi-file-upload/multi-file-upload"; @import "multi-select/multi-select"; diff --git a/src/moj/components/interruption-card/_interruption-card.scss b/src/moj/components/interruption-card/_interruption-card.scss new file mode 100644 index 000000000..4eedccbd5 --- /dev/null +++ b/src/moj/components/interruption-card/_interruption-card.scss @@ -0,0 +1,35 @@ +.moj-interruption-card { + background-color: govuk-colour("blue"); + margin-bottom: govuk-spacing(3); + @include govuk-responsive-padding(7, $adjustment: $govuk-border-width*-1); + border: $govuk-border-width solid transparent; +} + +.moj-interruption-card__content { + max-width: 960px; +} + +.moj-interruption-card__heading, +.moj-interruption-card__body { + color: govuk-colour("white"); +} + +.moj-interruption-card__body:last-child { + margin-bottom: 0; +} + +.moj-interruption-card__actions:last-child { + margin-bottom: 0; + + .govuk-button:last-child, + .govuk-link:last-child { + margin-bottom: 0; + } + + @include govuk-media-query($from: tablet) { + .govuk-button, + .govuk-link { + margin-bottom: 0; + } + } +} diff --git a/src/moj/components/interruption-card/macro.njk b/src/moj/components/interruption-card/macro.njk new file mode 100644 index 000000000..488400436 --- /dev/null +++ b/src/moj/components/interruption-card/macro.njk @@ -0,0 +1,3 @@ +{% macro interruptionCard(params) %} + {%- include "./template.njk" %} +{% endmacro %} diff --git a/src/moj/components/interruption-card/template.njk b/src/moj/components/interruption-card/template.njk new file mode 100644 index 000000000..85d6715b6 --- /dev/null +++ b/src/moj/components/interruption-card/template.njk @@ -0,0 +1,35 @@ +{% from "govuk/components/button/macro.njk" import govukButton %} +
+
+

{{- params.heading -}}

+
{{ caller() }}
+
+ {% if params.primaryAction.style == "link" %} + {{- params.primaryAction.text -}} + {% else %} + {{ govukButton({ + text: params.primaryAction.text, + classes: "govuk-button--inverse", + href: params.primaryAction.href, + preventDoubleClick: true, + attributes: params.primaryAction.attributes + }) }} + {% endif %} + {% if params.secondaryAction %} + {% if params.secondaryAction.style == "button" %} + {{ govukButton({ + text: params.secondaryAction.text, + classes: "govuk-button--inverse", + href: params.secondaryAction.href, + preventDoubleClick: true, + attributes: params.secondaryAction.attributes + }) }} + {% else %} + {{- params.secondaryAction.text -}} + {% endif %} + {% endif %} +
+
+
diff --git a/src/moj/components/multi-select/README.md b/src/moj/components/multi-select/README.md index 633141df4..3e6d6755e 100644 --- a/src/moj/components/multi-select/README.md +++ b/src/moj/components/multi-select/README.md @@ -1,3 +1,3 @@ # Table multi-select -- [Guidance](https://design-patterns.service.justice.gov.uk/components/table-multi-select) +- [Guidance](https://design-patterns.service.justice.gov.uk/components/multi-select/) diff --git a/src/moj/components/multi-select/multi-select.js b/src/moj/components/multi-select/multi-select.js index b6e541c9f..646db19ff 100644 --- a/src/moj/components/multi-select/multi-select.js +++ b/src/moj/components/multi-select/multi-select.js @@ -7,7 +7,13 @@ MOJFrontend.MultiSelect = function(options) { this.container.data('moj-multi-select-initialised', true); - this.toggle = $(this.getToggleHtml()); + const idPrefix = options.id_prefix; + let allId = 'checkboxes-all'; + if (typeof idPrefix !== 'undefined') { + allId = idPrefix + 'checkboxes-all'; + } + + this.toggle = $(this.getToggleHtml(allId)); this.toggleButton = this.toggle.find('input'); this.toggleButton.on('click', $.proxy(this, 'onButtonClick')); this.container.append(this.toggle); @@ -16,11 +22,11 @@ MOJFrontend.MultiSelect = function(options) { this.checked = options.checked || false; }; -MOJFrontend.MultiSelect.prototype.getToggleHtml = function() { - var html = ''; +MOJFrontend.MultiSelect.prototype.getToggleHtml = function (allId) { + let html = ''; html += '
'; - html += ' '; - html += '
'; diff --git a/src/moj/components/pagination/template.njk b/src/moj/components/pagination/template.njk index b6fc2a21b..ad0e98441 100755 --- a/src/moj/components/pagination/template.njk +++ b/src/moj/components/pagination/template.njk @@ -12,9 +12,9 @@
  • {% else %} {%- if item.selected %} -
  • {{ item.text }}
  • +
  • {{ item.text }}
  • {% else %} -
  • {{ item.text }}
  • +
  • {{ item.text }}
  • {% endif -%} {% endif -%} {% endfor -%}