Skip to content

Commit

Permalink
Merge pull request #2025 from alphagov/feature/notification-banner
Browse files Browse the repository at this point in the history
Add notification banner
  • Loading branch information
36degrees committed Nov 19, 2020
2 parents 012db8d + a5da918 commit 742cfe6
Show file tree
Hide file tree
Showing 18 changed files with 1,013 additions and 12 deletions.
1 change: 1 addition & 0 deletions app/full-page-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = (app) => {
require('./views/full-page-examples/passport-details')(app)
require('./views/full-page-examples/update-your-account-details')(app)
require('./views/full-page-examples/upload-your-photo')(app)
require('./views/full-page-examples/upload-your-photo-error')(app)
require('./views/full-page-examples/what-is-your-address')(app)
require('./views/full-page-examples/what-is-your-nationality')(app)
require('./views/full-page-examples/what-is-your-postcode')(app)
Expand Down
34 changes: 34 additions & 0 deletions app/views/full-page-examples/upload-your-photo-error/confirm.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% extends "_generic.njk" %}

{% from "panel/macro.njk" import govukPanel %}

{% set pageTitle = "Photo submitted" %}
{% block pageTitle %}{{ pageTitle }} - GOV.UK{% endblock %}

{% block header %}
{% include "../../partials/banner.njk" %}
{{ govukHeader({
serviceName: "Apply for a passport",
navigation: [
{
href: "#",
text: "Home"
},
{
href: "#upload-a-photo",
text: "Upload a photo",
active: true
}
]
}) }}
{% endblock %}

{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
{{ govukPanel({
titleText: pageTitle
}) }}
</div>
</div>
{% endblock %}
10 changes: 10 additions & 0 deletions app/views/full-page-examples/upload-your-photo-error/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = (app) => {
app.post(
'/full-page-examples/upload-your-photo-error',
(request, response) => {
return response.render('./full-page-examples/upload-your-photo-error/index', {
isError: true
})
}
)
}
93 changes: 93 additions & 0 deletions app/views/full-page-examples/upload-your-photo-error/index.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
scenario: >-
As part of an online service, you are asked to upload your photo.

The upload will always fail with an error that uses the notification banner.
---

{# This example is based of the live "Passport" service: https://www.passport.service.gov.uk/photo/upload #}
{% extends "_generic.njk" %}

{% from "back-link/macro.njk" import govukBackLink %}
{% from "button/macro.njk" import govukButton %}
{% from "checkboxes/macro.njk" import govukCheckboxes %}
{% from "file-upload/macro.njk" import govukFileUpload %}
{% from "notification-banner/macro.njk" import govukNotificationBanner %}
{% from "phase-banner/macro.njk" import govukPhaseBanner %}
{% from "radios/macro.njk" import govukRadios %}

{% block pageTitle %}Upload your photo - GOV.UK{% endblock %}

{% block header %}
{% include "../../partials/banner.njk" %}
{{ govukHeader({
serviceName: "Apply for a passport"
}) }}
{% endblock %}

{% block beforeContent %}
{{ govukPhaseBanner({
tag: {
text: "beta"
},
html: 'This is a new service – your <a class="govuk-link" href="#">feedback</a> will help us to improve it.'
}) }}
{{ govukBackLink({
text: "Back",
href: "#"
}) }}
{% endblock %}

{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<form method="post" novalidate>
{% if isError %}
{{ govukNotificationBanner({
"type": "error",
"html": "<p class=\"govuk-notification-banner__heading\">There was a problem uploading your file. <a href=\"#\" class=\"govuk-notification-banner__link\">Please try again.</a></p>\n"
}) }}
{% endif %}

<h1 class="govuk-heading-xl">Upload your photo</h1>

<p class="govuk-body">
Your photo will now go through an automated check.
</p>

<p class="govuk-body">
You’ll need to review it before you add the photo to your application.
</p>

{{ govukFileUpload({
id: "photo",
name: "photo",
label: {
text: "Upload your photo"
},
hint: {
text: "Your photo must be at least 50KB and no more than 10MB"
},
errorMessage: errors["photo"]
}) }}

{{ govukCheckboxes({
idPrefix: "terms-and-conditions",
name: "terms-and-conditions",
items: [
{
value: "true",
html: 'I accept the <a class="govuk-link" href="#">terms and conditions</a>',
checked: values["terms-and-conditions"]
}
],
errorMessage: errors["terms-and-conditions"]
}) }}

{{ govukButton({
text: "Submit your photo"
}) }}
</form>
</div>
</div>
{% endblock %}
6 changes: 6 additions & 0 deletions src/govuk/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Details from './components/details/details'
import CharacterCount from './components/character-count/character-count'
import Checkboxes from './components/checkboxes/checkboxes'
import ErrorSummary from './components/error-summary/error-summary'
import NotificationBanner from './components/notification-banner/notification-banner'
import Header from './components/header/header'
import Radios from './components/radios/radios'
import Tabs from './components/tabs/tabs'
Expand Down Expand Up @@ -50,6 +51,11 @@ function initAll (options) {
var $toggleButton = scope.querySelector('[data-module="govuk-header"]')
new Header($toggleButton).init()

var $notificationBanners = scope.querySelectorAll('[data-module="govuk-notification-banner"]')
nodeListForEach($notificationBanners, function ($notificationBanner) {
new NotificationBanner($notificationBanner).init()
})

var $radios = scope.querySelectorAll('[data-module="govuk-radios"]')
nodeListForEach($radios, function ($radio) {
new Radios($radio).init()
Expand Down
1 change: 1 addition & 0 deletions src/govuk/components/_all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@import "input/index";
@import "inset-text/index";
@import "label/index";
@import "notification-banner/index";
@import "panel/index";
@import "phase-banner/index";
@import "tabs/index";
Expand Down
14 changes: 2 additions & 12 deletions src/govuk/components/error-summary/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,7 @@

.govuk-error-summary__list a {
@include govuk-typography-weight-bold;

// Override default link styling to use error colour
&:link,
&:visited,
&:hover,
&:active {
color: $govuk-error-colour;
}

&:focus {
@include govuk-focused-text;
}
@include govuk-link-common;
@include govuk-link-style-error;
}
}
15 changes: 15 additions & 0 deletions src/govuk/components/notification-banner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Notification banner

## Installation

See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.

## Guidance and Examples

Find out when to use the notification banner component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/notification-banner).

## Component options

Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.

See [options table](https://design-system.service.gov.uk/components/notification-banner/#options-notification-banner-example) for details.
80 changes: 80 additions & 0 deletions src/govuk/components/notification-banner/_index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
@include govuk-exports("govuk/component/notification-banner") {
.govuk-notification-banner {
@include govuk-font($size: 19);
@include govuk-responsive-margin(8, "bottom");

border: $govuk-border-width solid $govuk-brand-colour;

&:focus {
outline: $govuk-focus-width solid $govuk-focus-colour;
}
}

.govuk-notification-banner__header {
padding: 2px govuk-spacing(3) govuk-spacing(1);

// Ensures the notification header appears separate to the notification body text in high contrast mode
border-bottom: 1px solid transparent;

background-color: $govuk-brand-colour;

@include govuk-media-query($from: tablet) {
padding: 2px govuk-spacing(4) govuk-spacing(1);
}
}

.govuk-notification-banner__title {
@include govuk-font($size: 19, $weight: bold);

margin: 0;

padding: 0;

color: govuk-colour("white");
}

.govuk-notification-banner__content {
margin: govuk-spacing(3);

@include govuk-media-query($from: tablet) {
margin: govuk-spacing(4);
}
}

.govuk-notification-banner__heading {
@include govuk-font($size: 24, $weight: bold);

margin: 0 0 govuk-spacing(3) 0;

padding: 0;
}

.govuk-notification-banner__link {
@include govuk-link-common;
@include govuk-link-style-default;
}

.govuk-notification-banner--success {
border-color: $govuk-success-colour;

.govuk-notification-banner__header {
background-color: $govuk-success-colour;
}

.govuk-notification-banner__link {
@include govuk-link-style-success;
}
}

.govuk-notification-banner--error {
border-color: $govuk-error-colour;

.govuk-notification-banner__header {
background-color: $govuk-error-colour;
}

.govuk-notification-banner__link {
@include govuk-link-style-error;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import "../../base";
@import "./index";
3 changes: 3 additions & 0 deletions src/govuk/components/notification-banner/macro.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% macro govukNotificationBanner(params) %}
{%- include "./template.njk" -%}
{% endmacro %}
53 changes: 53 additions & 0 deletions src/govuk/components/notification-banner/notification-banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function NotificationBanner ($module) {
this.$module = $module
}

/**
* Initialise the component
*/
NotificationBanner.prototype.init = function () {
var $module = this.$module
// Check for module
if (!$module) {
return
}

this.setFocus()
}

/**
* Focus the element
*
* If `role="alert"` is set, focus the element to help some assistive technologies
* prioritise announcing it.
*
* You can turn off the auto-focus functionality by setting `data-disable-auto-focus="true"` in the
* component HTML. You might wish to do this based on user research findings, or to avoid a clash
* with another element which should be focused when the page loads.
*/
NotificationBanner.prototype.setFocus = function () {
var $module = this.$module

if ($module.getAttribute('data-disable-auto-focus') === 'true') {
return
}

if ($module.getAttribute('role') !== 'alert') {
return
}

// Set tabindex to -1 to make the element focusable with JavaScript.
// Remove the tabindex on blur as the component doesn't need to be focusable after the page has
// loaded.
if (!$module.getAttribute('tabindex')) {
$module.setAttribute('tabindex', '-1')

$module.addEventListener('blur', function () {
$module.removeAttribute('tabindex')
})
}

$module.focus()
}

export default NotificationBanner
Loading

0 comments on commit 742cfe6

Please sign in to comment.