From 6215b4134e67f8cef52ac3ab96286a52698159cc Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 25 Apr 2018 09:00:40 +0100 Subject: [PATCH 01/25] Move error message out of label for input --- src/error-message/template.njk | 2 +- src/input/README.md | 22 ++++++++++++------- src/input/__snapshots__/template.test.js.snap | 4 +++- src/input/_input.scss | 7 +++--- src/input/template.njk | 18 ++++++++++++++- src/input/template.test.js | 22 +++++++++++++++++++ 6 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/error-message/template.njk b/src/error-message/template.njk index de51cc1fe1..96dbdabaa3 100644 --- a/src/error-message/template.njk +++ b/src/error-message/template.njk @@ -1,3 +1,3 @@ - + {{ params.html | safe if params.html else params.text }} diff --git a/src/input/README.md b/src/input/README.md index 1ae6741603..20dc2143b1 100644 --- a/src/input/README.md +++ b/src/input/README.md @@ -20,7 +20,8 @@ Find out when to use the Input component in your service in the [GOV.UK Design S National Insurance number - + + #### Macro @@ -49,7 +50,8 @@ Find out when to use the Input component in your service in the [GOV.UK Design S - + + #### Macro @@ -78,12 +80,13 @@ Find out when to use the Input component in your service in the [GOV.UK Design S It’s on your National Insurance card, benefit letter, payslip or P60\. For example, ‘QQ 12 34 56 C’. - + + + Error message goes here - - + #### Macro @@ -116,7 +119,8 @@ Find out when to use the Input component in your service in the [GOV.UK Design S - + + #### Macro @@ -147,7 +151,8 @@ Find out when to use the Input component in your service in the [GOV.UK Design S - + + #### Macro @@ -178,7 +183,8 @@ Find out when to use the Input component in your service in the [GOV.UK Design S - + + #### Macro diff --git a/src/input/__snapshots__/template.test.js.snap b/src/input/__snapshots__/template.test.js.snap index f060b75d21..1916029e89 100644 --- a/src/input/__snapshots__/template.test.js.snap +++ b/src/input/__snapshots__/template.test.js.snap @@ -2,7 +2,9 @@ exports[`Input with dependant components renders with error message 1`] = ` - + Error message diff --git a/src/input/_input.scss b/src/input/_input.scss index 9c64e3f866..e6baf3d4f3 100644 --- a/src/input/_input.scss +++ b/src/input/_input.scss @@ -1,10 +1,9 @@ @import "../globals/tools/exports"; -@import "../fieldset/fieldset"; -@import "../label/label"; -@import "../error-message/error-message"; - @import "../globals/helpers/focusable"; +@import "../error-message/error-message"; +@import "../label/label"; + @include govuk-exports("input") { .govuk-input { @include govuk-font-regular-19; diff --git a/src/input/template.njk b/src/input/template.njk index f2e8775d11..8cdf016c21 100644 --- a/src/input/template.njk +++ b/src/input/template.njk @@ -1,5 +1,10 @@ +{% from "error-message/macro.njk" import govukErrorMessage -%} {% from "label/macro.njk" import govukLabel %} +{# a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages #} +{% set describedBy = "" %} +
{{- govukLabel({ @@ -9,11 +14,22 @@ hintHtml: params.label.hintHtml, classes: params.label.classes, attributes: params.label.attributes, - errorMessage: params.errorMessage, for: params.id }) -}} + {% if params.errorMessage %} + {% set errorId = params.id + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) -}} + {% endif %} +
diff --git a/src/input/template.test.js b/src/input/template.test.js index 3545a5ea09..95fd17b868 100644 --- a/src/input/template.test.js +++ b/src/input/template.test.js @@ -6,6 +6,8 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('input') +const WORD_BOUNDARY = '\\b' + describe('Input', () => { describe('by default', () => { it('passes accessibility tests', async () => { @@ -117,6 +119,7 @@ describe('Input', () => { it('renders with error message', () => { const $ = render('input', { + id: 'input-with-error', errorMessage: { 'text': 'Error message' } @@ -125,6 +128,25 @@ describe('Input', () => { expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() }) + it('associates the input as "described by" the error message', () => { + const $ = render('input', { + id: 'input-with-error', + errorMessage: { + 'text': 'Error message' + } + }) + + const $input = $('.govuk-input') + const $errorMessage = $('.govuk-error-message') + + const errorMessageId = new RegExp( + WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY + ) + + expect($input.attr('aria-describedby')) + .toMatch(errorMessageId) + }) + it('has error class when rendered with error message', () => { const $ = render('input', { errorMessage: { From c9c84f096fe0752965b92e76afefdc4f4183fadc Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 25 Apr 2018 09:08:02 +0100 Subject: [PATCH 02/25] Move error message out of label for file upload --- src/file-upload/README.md | 16 ++++++---- .../__snapshots__/template.test.js.snap | 4 ++- src/file-upload/_file-upload.scss | 1 + src/file-upload/template.njk | 19 ++++++++++-- src/file-upload/template.test.js | 30 ++++++++++++++++--- 5 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/file-upload/README.md b/src/file-upload/README.md index f68620fe91..63638d9690 100644 --- a/src/file-upload/README.md +++ b/src/file-upload/README.md @@ -20,7 +20,8 @@ Find out when to use the File upload component in your service in the [GOV.UK De Upload a file - + + #### Macro @@ -49,7 +50,8 @@ Find out when to use the File upload component in your service in the [GOV.UK De
- + + #### Macro @@ -78,12 +80,13 @@ Find out when to use the File upload component in your service in the [GOV.UK De Your photo may be in your Pictures, Photos, Downloads or Desktop folder. Or in an app like iPhoto. - + + + Error message goes here - - + #### Macro @@ -112,7 +115,8 @@ Find out when to use the File upload component in your service in the [GOV.UK De Upload a photo - + + #### Macro diff --git a/src/file-upload/__snapshots__/template.test.js.snap b/src/file-upload/__snapshots__/template.test.js.snap index 30711dbc96..dfda77a023 100644 --- a/src/file-upload/__snapshots__/template.test.js.snap +++ b/src/file-upload/__snapshots__/template.test.js.snap @@ -2,7 +2,9 @@ exports[`File upload with dependant components renders with error message 1`] = ` - + Error message diff --git a/src/file-upload/_file-upload.scss b/src/file-upload/_file-upload.scss index 5f3b511bc7..a0f05842f7 100644 --- a/src/file-upload/_file-upload.scss +++ b/src/file-upload/_file-upload.scss @@ -1,5 +1,6 @@ @import "../globals/tools/exports"; +@import "../error-message/error-message"; @import "../label/label"; @import "../globals/settings/spacing"; diff --git a/src/file-upload/template.njk b/src/file-upload/template.njk index 85de08eb73..72f1f7cb01 100644 --- a/src/file-upload/template.njk +++ b/src/file-upload/template.njk @@ -1,5 +1,10 @@ +{% from "error-message/macro.njk" import govukErrorMessage -%} {% from "label/macro.njk" import govukLabel %} +{# a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages #} +{% set describedBy = "" %} + {#- Include label passing all label parameters, merging in `for` and `errorMessage` #}
@@ -10,9 +15,19 @@ hintHtml: params.label.hintHtml, classes: params.label.classes, attributes: params.label.attributes, - errorMessage: params.errorMessage, for: params.id }) -}} - + {% if params.errorMessage %} + {% set errorId = params.id + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) -}} + {% endif %} + +
diff --git a/src/file-upload/template.test.js b/src/file-upload/template.test.js index 6e38084c55..dea48d6ac3 100644 --- a/src/file-upload/template.test.js +++ b/src/file-upload/template.test.js @@ -6,6 +6,8 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('file-upload') +const WORD_BOUNDARY = '\\b' + describe('File upload', () => { describe('by default', () => { it('passes accessibility tests', async () => { @@ -67,7 +69,7 @@ describe('File upload', () => { it('have correct nesting order', () => { const $ = render('file-upload', { errorMessage: { - 'text': 'Error message' + text: 'Error message' } }) @@ -79,7 +81,7 @@ describe('File upload', () => { const $ = render('file-upload', { id: 'my-file-upload', label: { - 'text': 'Full address' + text: 'Full address' } }) @@ -90,7 +92,7 @@ describe('File upload', () => { const $ = render('file-upload', { id: 'my-file-upload', label: { - 'text': 'Full address' + text: 'Full address' } }) @@ -100,14 +102,34 @@ describe('File upload', () => { it('renders with error message', () => { const $ = render('file-upload', { + id: 'file-upload-with-error', errorMessage: { - 'text': 'Error message' + text: 'Error message' } }) expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() }) + it('associates the input as "described by" the error message', () => { + const $ = render('file-upload', { + id: 'input-with-error', + errorMessage: { + 'text': 'Error message' + } + }) + + const $component = $('.govuk-file-upload') + const $errorMessage = $('.govuk-error-message') + + const errorMessageId = new RegExp( + WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY + ) + + expect($component.attr('aria-describedby')) + .toMatch(errorMessageId) + }) + it('has error class when rendered with error message', () => { const $ = render('file-upload', { errorMessage: { From f41a653e960624e7fdbad8dd3c94b937f1e2a4dd Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 25 Apr 2018 09:15:26 +0100 Subject: [PATCH 03/25] Move error message out of label for textarea --- src/textarea/README.md | 16 ++++++++----- .../__snapshots__/template.test.js.snap | 4 +++- src/textarea/_textarea.scss | 1 + src/textarea/template.njk | 18 ++++++++++++-- src/textarea/template.test.js | 24 ++++++++++++++++++- 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/textarea/README.md b/src/textarea/README.md index 6c6d8536bb..17f1b25810 100644 --- a/src/textarea/README.md +++ b/src/textarea/README.md @@ -24,7 +24,8 @@ Find out when to use the Textarea component in your service in the [GOV.UK Desig
- + + @@ -50,12 +51,13 @@ Find out when to use the Textarea component in your service in the [GOV.UK Desig
+ + You must provide an explanation - - +
@@ -84,7 +86,8 @@ Find out when to use the Textarea component in your service in the [GOV.UK Desig Full address - @@ -114,7 +117,8 @@ Find out when to use the Textarea component in your service in the [GOV.UK Desig Full address - + + diff --git a/src/textarea/__snapshots__/template.test.js.snap b/src/textarea/__snapshots__/template.test.js.snap index 5344d01742..c797c306fc 100644 --- a/src/textarea/__snapshots__/template.test.js.snap +++ b/src/textarea/__snapshots__/template.test.js.snap @@ -2,7 +2,9 @@ exports[`Textarea with dependant components renders with error message 1`] = ` - + Error message diff --git a/src/textarea/_textarea.scss b/src/textarea/_textarea.scss index 66d412ecb4..6fbe934599 100644 --- a/src/textarea/_textarea.scss +++ b/src/textarea/_textarea.scss @@ -1,6 +1,7 @@ @import "../globals/tools/exports"; @import "../globals/tools/iff"; +@import "../error-message/error-message"; @import "../label/label"; @import "../globals/settings/spacing"; diff --git a/src/textarea/template.njk b/src/textarea/template.njk index c2c00dac68..c2980ea785 100644 --- a/src/textarea/template.njk +++ b/src/textarea/template.njk @@ -1,5 +1,9 @@ +{% from "error-message/macro.njk" import govukErrorMessage -%} {% from "label/macro.njk" import govukLabel %} +{# a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages #} +{% set describedBy = "" %}
@@ -12,10 +16,20 @@ hintHtml: params.label.hintHtml, classes: params.label.classes, attributes: params.label.attributes, - errorMessage: params.errorMessage, for: params.id }) -}} - + {% if params.errorMessage %} + {% set errorId = params.id + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) -}} + {% endif %} + +
diff --git a/src/textarea/template.test.js b/src/textarea/template.test.js index 46b6c87b65..9bbe61ff51 100644 --- a/src/textarea/template.test.js +++ b/src/textarea/template.test.js @@ -6,6 +6,8 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('textarea') +const WORD_BOUNDARY = '\\b' + describe('Textarea', () => { describe('by default', () => { it('passes accessibility tests', async () => { @@ -120,14 +122,34 @@ describe('Textarea', () => { it('renders with error message', () => { const $ = render('textarea', { + id: 'textarea-with-error', errorMessage: { - 'text': 'Error message' + text: 'Error message' } }) expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() }) + it('associates the textarea as "described by" the error message', () => { + const $ = render('textarea', { + id: 'input-with-error', + errorMessage: { + 'text': 'Error message' + } + }) + + const $component = $('.govuk-textarea') + const $errorMessage = $('.govuk-error-message') + + const errorMessageId = new RegExp( + WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY + ) + + expect($component.attr('aria-describedby')) + .toMatch(errorMessageId) + }) + it('has error class when rendered with error message', () => { const $ = render('textarea', { errorMessage: { From 79fb625c6e1247a93d6106e86f468868a745d703 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 25 Apr 2018 09:20:21 +0100 Subject: [PATCH 04/25] Move error message out of label for select --- src/select/README.md | 10 ++-- .../__snapshots__/template.test.js.snap | 4 +- src/select/template.njk | 18 ++++++- src/select/template.test.js | 50 +++++++++++++------ 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/select/README.md b/src/select/README.md index c3d502631d..7d01c6675a 100644 --- a/src/select/README.md +++ b/src/select/README.md @@ -20,7 +20,8 @@ Find out when to use the Select component in your service in the [GOV.UK Design Label text goes here - @@ -72,12 +73,13 @@ Find out when to use the Select component in your service in the [GOV.UK Design Hint text goes here
- + + + Error message goes here - - diff --git a/src/select/__snapshots__/template.test.js.snap b/src/select/__snapshots__/template.test.js.snap index ae4676e8e2..61c008aade 100644 --- a/src/select/__snapshots__/template.test.js.snap +++ b/src/select/__snapshots__/template.test.js.snap @@ -2,7 +2,9 @@ exports[`Select with dependant components renders with error message 1`] = ` - + Error message diff --git a/src/select/template.njk b/src/select/template.njk index 938a35d81f..d424c8b2ab 100644 --- a/src/select/template.njk +++ b/src/select/template.njk @@ -1,5 +1,9 @@ +{% from "error-message/macro.njk" import govukErrorMessage -%} {% from "label/macro.njk" import govukLabel %} +{# a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages #} +{% set describedBy = "" %}
@@ -10,12 +14,22 @@ hintHtml: params.label.hintHtml, classes: params.label.classes, attributes: params.label.attributes, - errorMessage: params.errorMessage, for: params.id }) -}} + {% if params.errorMessage %} + {% set errorId = params.id + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) -}} + {% endif %} + @@ -53,7 +53,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des
- + + #### Macro @@ -89,7 +90,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup -
+
+
@@ -117,6 +119,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des
+
+ #### Macro {% from 'checkboxes/macro.njk' import govukCheckboxes %} @@ -146,17 +150,17 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup -
-
+
+
- -

Which types of waste do you transport regularly?

+ +

Which types of waste do you transport regularly?

- Select all that apply + Select all that apply -
+
-
+
@@ -183,7 +187,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des
-
+
+
#### Macro @@ -217,7 +222,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup -
+
+
@@ -245,6 +251,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des
+
+ #### Macro {% from 'checkboxes/macro.njk' import govukCheckboxes %} @@ -273,21 +281,21 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup -
-
+
+
- - What is your nationality? + + What is your nationality? - If you have dual nationality, select all options that are relevant to you. + If you have dual nationality, select all options that are relevant to you. - - Please select an option - + - + + Please select an option + -
+
@@ -314,7 +322,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des
-
+
+
#### Macro @@ -358,19 +367,19 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup -
-
+
+
- -

Which types of waste do you transport regularly?

+ +

Which types of waste do you transport regularly?

- - Please select an option - +
-
+ + Please select an option + -
+
@@ -397,7 +406,8 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des
-
+
+
#### Macro diff --git a/src/checkboxes/__snapshots__/template.test.js.snap b/src/checkboxes/__snapshots__/template.test.js.snap index aaced8be5d..9fb2807401 100644 --- a/src/checkboxes/__snapshots__/template.test.js.snap +++ b/src/checkboxes/__snapshots__/template.test.js.snap @@ -2,15 +2,8 @@ exports[`Checkboxes nested dependant components passes through fieldset params without breaking 1`] = ` - - Please select an option - - -`; - -exports[`Checkboxes nested dependant components passes through fieldset params without breaking 2`] = ` -
@@ -59,3 +52,13 @@ exports[`Checkboxes nested dependant components passes through label params with `; + +exports[`Checkboxes nested dependant components renders the error message 1`] = ` + + + Please select an option + + +`; diff --git a/src/checkboxes/_checkboxes.scss b/src/checkboxes/_checkboxes.scss index 28a3b38941..3594d6da3f 100644 --- a/src/checkboxes/_checkboxes.scss +++ b/src/checkboxes/_checkboxes.scss @@ -1,6 +1,7 @@ @import "../globals/tools/exports"; @import "../globals/tools/ie8"; +@import "../error-message/error-message"; @import "../fieldset/fieldset"; @import "../label/label"; diff --git a/src/checkboxes/template.njk b/src/checkboxes/template.njk index 6663517cff..fec167c201 100644 --- a/src/checkboxes/template.njk +++ b/src/checkboxes/template.njk @@ -1,6 +1,15 @@ +{% from "error-message/macro.njk" import govukErrorMessage -%} {% from "fieldset/macro.njk" import govukFieldset %} {% from "label/macro.njk" import govukLabel %} +{# If an id 'prefix' is not passed, fall back to using the name attribute + instead. We need this for error messages and hints as well #} +{% set idPrefix = params.idPrefix if params.idPrefix else params.name %} + +{# a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages #} +{% set describedBy = "" %} + {% set isConditional = false %} {% for item in params.items %} {% if item.conditional %} @@ -10,11 +19,21 @@ {#- Capture the HTML so we can optionally nest it in a fieldset -#} {% set innerHtml %} + {% if params.errorMessage %} + {% set errorId = idPrefix + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) -}} + {% endif %} +
{% for item in params.items %} - {% set idPrefix = params.idPrefix if params.idPrefix else params.name %} {% set id = item.id if item.id else idPrefix + "-" + loop.index %} {% set conditionalId = "conditional-" + id %}
@@ -39,18 +58,20 @@
{% endset %} -{%- if params.fieldset %} - {% call govukFieldset({ - classes: params.fieldset.classes, - attributes: params.fieldset.attributes, - legendText: params.fieldset.legendText, - legendHtml: params.fieldset.legendHtml, - legendHintText: params.fieldset.legendHintText, - legendHintHtml: params.fieldset.legendHintHtml, - errorMessage: params.errorMessage - }) %} - {{- innerHtml | indent(2) | trim | safe }} - {% endcall %} -{% else %} - {{ innerHtml | trim | safe }} -{% endif %} +
+ {%- if params.fieldset %} + {% call govukFieldset({ + describedBy: describedBy, + classes: params.fieldset.classes, + attributes: params.fieldset.attributes, + legendText: params.fieldset.legendText, + legendHtml: params.fieldset.legendHtml, + legendHintText: params.fieldset.legendHintText, + legendHintHtml: params.fieldset.legendHintHtml + }) %} + {{- innerHtml | indent(2) | trim | safe }} + {% endcall %} + {% else %} + {{ innerHtml | trim | safe }} + {% endif %} +
diff --git a/src/checkboxes/template.test.js b/src/checkboxes/template.test.js index 253c406de4..fcc569a8ac 100644 --- a/src/checkboxes/template.test.js +++ b/src/checkboxes/template.test.js @@ -6,6 +6,8 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('checkboxes') +const WORD_BOUNDARY = '\\b' + describe('Checkboxes', () => { it('default example passes accessibility tests', async () => { const $ = render('checkboxes', examples.default) @@ -259,10 +261,68 @@ describe('Checkboxes', () => { expect(htmlWithClassName($, '.govuk-checkboxes__label')).toMatchSnapshot() }) - it('passes through fieldset params without breaking', () => { + it('renders the error message', () => { const $ = render('checkboxes', examples['with-extreme-fieldset']) expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() + }) + + it('uses the idPrefix for the error message id if provided', () => { + const $ = render('checkboxes', { + name: 'name-of-checkboxes', + errorMessage: { + text: 'Please select an option' + }, + idPrefix: 'id-prefix', + items: [ + { + value: 'animal', + text: 'Waste from animal carcasses' + } + ] + }) + + const $errorMessage = $('.govuk-error-message') + + expect($errorMessage.attr('id')).toEqual('id-prefix-error') + }) + + it('falls back to using the name for the error message id', () => { + const $ = render('checkboxes', { + name: 'name-of-checkboxes', + errorMessage: { + text: 'Please select an option' + }, + items: [ + { + value: 'animal', + text: 'Waste from animal carcasses' + } + ] + }) + + const $errorMessage = $('.govuk-error-message') + + expect($errorMessage.attr('id')).toEqual('name-of-checkboxes-error') + }) + + it('associates the fieldset as "described by" the error message', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + + const $fieldset = $('.govuk-fieldset') + const $errorMessage = $('.govuk-error-message') + + const errorMessageId = new RegExp( + WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(errorMessageId) + }) + + it('passes through fieldset params without breaking', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + expect(htmlWithClassName($, '.govuk-fieldset')).toMatchSnapshot() }) diff --git a/src/fieldset/README.md b/src/fieldset/README.md index 59a7211c8d..ddd407be83 100644 --- a/src/fieldset/README.md +++ b/src/fieldset/README.md @@ -16,18 +16,16 @@ Find out when to use the Fieldset component in your service in the [GOV.UK Desig #### Markup -
-
+
- - What is your address? + + What is your address? - For example, 10 Downing Street + For example, 10 Downing Street - + -
-
+
#### Macro @@ -44,22 +42,16 @@ Find out when to use the Fieldset component in your service in the [GOV.UK Desig #### Markup -
-
+
- - What is your address? + + What is your address? - For example, 10 Downing Street + For example, 10 Downing Street - - Please fill in the street input - + - - -
-
+ #### Macro diff --git a/src/fieldset/template.njk b/src/fieldset/template.njk index e2fb4cda19..321bc9c244 100644 --- a/src/fieldset/template.njk +++ b/src/fieldset/template.njk @@ -1,19 +1,14 @@ -{% from "error-message/macro.njk" import govukErrorMessage -%} - -
-
- {% if params.legendHtml or params.legendText %} - - {{ params.legendHtml | safe if params.legendHtml else params.legendText }} - {% if params.legendHintText or params.legendHintHtml %} - {{ params.legendHintHtml | safe if params.legendHintHtml else params.legendHintText }} - {% endif %} - {% if params.errorMessage %} - {{ govukErrorMessage(params.errorMessage) | trim | indent(4) -}} - {% endif %} - +
+ {% if params.legendHtml or params.legendText %} + + {{ params.legendHtml | safe if params.legendHtml else params.legendText }} + {% if params.legendHintText or params.legendHintHtml %} + {{ params.legendHintHtml | safe if params.legendHintHtml else params.legendHintText }} {% endif %} - {{ caller() if caller }} {#- if statement allows usage of `call` to be optional -#} -
-
+ + {% endif %} +{{ caller() if caller }} {#- if statement allows usage of `call` to be optional -#} + From 64482a7762ea9b445cd815f6509152fc6ad0319a Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 1 May 2018 10:23:26 +0100 Subject: [PATCH 07/25] Move error message out of legend for radios --- src/radios/README.md | 96 ++++++++++--------- .../__snapshots__/template.test.js.snap | 19 ++-- src/radios/_radios.scss | 1 + src/radios/template.njk | 53 ++++++---- src/radios/template.test.js | 61 +++++++++++- 5 files changed, 161 insertions(+), 69 deletions(-) diff --git a/src/radios/README.md b/src/radios/README.md index 4d41c422b6..cbe580e85a 100644 --- a/src/radios/README.md +++ b/src/radios/README.md @@ -16,17 +16,17 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup -
-
+
+
- - Have you changed your name? + + Have you changed your name? - This includes changing your last name or spelling your name differently. + This includes changing your last name or spelling your name differently. - + -
+
@@ -45,7 +45,8 @@ Find out when to use the Radios component in your service in the [GOV.UK Design
-
+
+
#### Macro @@ -78,17 +79,17 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup -
-
+
+
- - Have you changed your name? + + Have you changed your name? - This includes changing your last name or spelling your name differently. + This includes changing your last name or spelling your name differently. - + -
+
@@ -107,7 +108,8 @@ Find out when to use the Radios component in your service in the [GOV.UK Design
-
+
+
#### Macro @@ -141,17 +143,17 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup -
-
+
+
- - Have you changed your name? + + Have you changed your name? - This includes changing your last name or spelling your name differently. + This includes changing your last name or spelling your name differently. - + -
+
@@ -170,7 +172,8 @@ Find out when to use the Radios component in your service in the [GOV.UK Design
-
+
+
#### Macro @@ -204,17 +207,17 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup -
-
+
+
- -

Which part of the Housing Act was your licence issued under?

+ +

Which part of the Housing Act was your licence issued under?

- Select one of the options below. + Select one of the options below. -
+
-
+
@@ -233,7 +236,8 @@ Find out when to use the Radios component in your service in the [GOV.UK Design
-
+
+
#### Macro @@ -265,7 +269,8 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup -
+
+
@@ -293,6 +298,8 @@ Find out when to use the Radios component in your service in the [GOV.UK Design
+
+ #### Macro {% from 'radios/macro.njk' import govukRadios %} @@ -321,21 +328,21 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup -
-
+
+
- - Have you changed your name? + + Have you changed your name? - This includes changing your last name or spelling your name differently. + This includes changing your last name or spelling your name differently. - - Please select an option - + - + + Please select an option + -
+
@@ -354,7 +361,8 @@ Find out when to use the Radios component in your service in the [GOV.UK Design
-
+
+
#### Macro diff --git a/src/radios/__snapshots__/template.test.js.snap b/src/radios/__snapshots__/template.test.js.snap index 367b122f8c..78dd12aa12 100644 --- a/src/radios/__snapshots__/template.test.js.snap +++ b/src/radios/__snapshots__/template.test.js.snap @@ -2,15 +2,8 @@ exports[`Radios nested dependant components passes through fieldset params without breaking 1`] = ` - - Please select an option - - -`; - -exports[`Radios nested dependant components passes through fieldset params without breaking 2`] = ` -
@@ -59,3 +52,13 @@ exports[`Radios nested dependant components passes through label params without `; + +exports[`Radios nested dependant components renders the error message 1`] = ` + + + Please select an option + + +`; diff --git a/src/radios/_radios.scss b/src/radios/_radios.scss index b421e8c420..75fdee749b 100644 --- a/src/radios/_radios.scss +++ b/src/radios/_radios.scss @@ -1,6 +1,7 @@ @import "../globals/tools/exports"; @import "../globals/tools/ie8"; +@import "../error-message/error-message"; @import "../fieldset/fieldset"; @import "../label/label"; diff --git a/src/radios/template.njk b/src/radios/template.njk index ca6035abb5..da409fe237 100644 --- a/src/radios/template.njk +++ b/src/radios/template.njk @@ -1,6 +1,15 @@ +{% from "error-message/macro.njk" import govukErrorMessage -%} {% from "fieldset/macro.njk" import govukFieldset %} {% from "label/macro.njk" import govukLabel %} +{# If an id 'prefix' is not passed, fall back to using the name attribute + instead. We need this for error messages and hints as well #} +{% set idPrefix = params.idPrefix if params.idPrefix else params.name %} + +{# a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages #} +{% set describedBy = "" %} + {% set isConditional = false %} {% for item in params.items %} {% if item.conditional %} @@ -10,11 +19,21 @@ {#- Capture the HTML so we can optionally nest it in a fieldset -#} {% set innerHtml %} + {% if params.errorMessage %} + {% set errorId = idPrefix + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) -}} + {% endif %} +
{% for item in params.items %} - {% set idPrefix = params.idPrefix if params.idPrefix else params.name %} {% set id = item.id if item.id else idPrefix + "-" + loop.index %} {% set conditionalId = "conditional-" + id %}
@@ -39,18 +58,20 @@
{% endset %} -{%- if params.fieldset %} - {% call govukFieldset({ - classes: params.fieldset.classes, - attributes: params.fieldset.attributes, - legendText: params.fieldset.legendText, - legendHtml: params.fieldset.legendHtml, - legendHintText: params.fieldset.legendHintText, - legendHintHtml: params.fieldset.legendHintHtml, - errorMessage: params.errorMessage - }) %} - {{- innerHtml | indent(2) | trim | safe }} - {% endcall %} -{% else %} - {{ innerHtml | trim | safe }} -{% endif %} +
+ {%- if params.fieldset %} + {% call govukFieldset({ + describedBy: describedBy, + classes: params.fieldset.classes, + attributes: params.fieldset.attributes, + legendText: params.fieldset.legendText, + legendHtml: params.fieldset.legendHtml, + legendHintText: params.fieldset.legendHintText, + legendHintHtml: params.fieldset.legendHintHtml + }) %} + {{- innerHtml | indent(2) | trim | safe }} + {% endcall %} + {% else %} + {{ innerHtml | trim | safe }} + {% endif %} +
diff --git a/src/radios/template.test.js b/src/radios/template.test.js index fb207edf03..f0e47e445b 100644 --- a/src/radios/template.test.js +++ b/src/radios/template.test.js @@ -6,6 +6,8 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('radios') +const WORD_BOUNDARY = '\\b' + describe('Radios', () => { it('default example passes accessibility tests', async () => { const $ = render('radios', examples.default) @@ -256,10 +258,67 @@ describe('Radios', () => { expect(htmlWithClassName($, '.govuk-radios__label')).toMatchSnapshot() }) + it('renders the error message', () => { + const $ = render('radios', examples['with-extreme-fieldset']) + expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() + }) + + it('uses the idPrefix for the error message id if provided', () => { + const $ = render('radios', { + name: 'name-of-radios', + errorMessage: { + text: 'Have you changed your name?' + }, + idPrefix: 'id-prefix', + items: [ + { + value: 'yes', + text: 'Yes' + } + ] + }) + + const $errorMessage = $('.govuk-error-message') + + expect($errorMessage.attr('id')).toEqual('id-prefix-error') + }) + + it('falls back to using the name for the error message id', () => { + const $ = render('radios', { + name: 'name-of-radios', + errorMessage: { + text: 'Have you changed your name?' + }, + items: [ + { + value: 'yes', + text: 'Yes' + } + ] + }) + + const $errorMessage = $('.govuk-error-message') + + expect($errorMessage.attr('id')).toEqual('name-of-radios-error') + }) + + it('associates the fieldset as "described by" the error message', () => { + const $ = render('radios', examples['with-extreme-fieldset']) + + const $fieldset = $('.govuk-fieldset') + const $errorMessage = $('.govuk-error-message') + + const errorMessageId = new RegExp( + WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(errorMessageId) + }) + it('passes through fieldset params without breaking', () => { const $ = render('radios', examples['with-extreme-fieldset']) - expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() expect(htmlWithClassName($, '.govuk-fieldset')).toMatchSnapshot() }) From 6448ff2cd04d749c0e21d21483ad29a10a58c4e9 Mon Sep 17 00:00:00 2001 From: alex-ju Date: Tue, 1 May 2018 11:32:43 +0100 Subject: [PATCH 08/25] Move error message out of legend for date-input --- src/date-input/README.md | 154 ++++++++++-------- .../__snapshots__/template.test.js.snap | 22 ++- src/date-input/_date-input.scss | 4 +- src/date-input/template.njk | 52 ++++-- src/date-input/template.test.js | 30 +++- 5 files changed, 168 insertions(+), 94 deletions(-) diff --git a/src/date-input/README.md b/src/date-input/README.md index a69c7df1c8..3044f57f22 100644 --- a/src/date-input/README.md +++ b/src/date-input/README.md @@ -16,24 +16,25 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup -
-
+
+
- - What is your date of birth? + + What is your date of birth? - For example, 31 3 1980 + For example, 31 3 1980 - + -
+
- + +
@@ -42,7 +43,8 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Month - + +
@@ -51,12 +53,14 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Year - + +
-
+ +
#### Macro @@ -89,28 +93,29 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup -
-
+
+
- - What is your date of birth? + + What is your date of birth? - For example, 31 3 1980 + For example, 31 3 1980 - - Error message goes here - + - + + Error message goes here + -
+
- + +
@@ -119,7 +124,8 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Month - + +
@@ -128,12 +134,14 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Year - + +
- + +
#### Macro @@ -171,28 +179,29 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup -
-
+
+
- - What is your date of birth? + + What is your date of birth? - For example, 31 3 1980 + For example, 31 3 1980 - - Error message goes here - + - + + Error message goes here + -
+
- + +
@@ -201,7 +210,8 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Month - + +
@@ -210,12 +220,14 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Year - + +
- + +
#### Macro @@ -252,28 +264,29 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup -
-
+
+
- - What is your date of birth? + + What is your date of birth? - For example, 31 3 1980 + For example, 31 3 1980 - - Error message goes here - + - + + Error message goes here + -
+
- + +
@@ -282,7 +295,8 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Month - + +
@@ -291,12 +305,14 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Year - + +
- + + #### Macro @@ -333,28 +349,29 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup -
-
+
+
- - What is your date of birth? + + What is your date of birth? - For example, 31 3 1980 + For example, 31 3 1980 - - Error message goes here - + - + + Error message goes here + -
+
- + +
@@ -363,7 +380,8 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Month - + +
@@ -372,12 +390,14 @@ Find out when to use the Date input component in your service in the [GOV.UK Des Year - + +
- + + #### Macro diff --git a/src/date-input/__snapshots__/template.test.js.snap b/src/date-input/__snapshots__/template.test.js.snap index 299756c33c..e9a0b7d17e 100644 --- a/src/date-input/__snapshots__/template.test.js.snap +++ b/src/date-input/__snapshots__/template.test.js.snap @@ -35,15 +35,9 @@ exports[`Date input passes through fieldset params without breaking 1`] = ` exports[`Date input passes through html fieldset params without breaking 1`] = ` - - Error message goes here - - -`; - -exports[`Date input passes through html fieldset params without breaking 2`] = ` - -
+
What is your @@ -60,3 +54,13 @@ exports[`Date input passes through html fieldset params without breaking 2`] = `
`; + +exports[`Date input renders the error message 1`] = ` + + + Error message goes here + + +`; diff --git a/src/date-input/_date-input.scss b/src/date-input/_date-input.scss index ab8b3a16e8..235ffc8786 100644 --- a/src/date-input/_date-input.scss +++ b/src/date-input/_date-input.scss @@ -1,9 +1,9 @@ @import "../globals/tools/exports"; @import "../globals/tools/iff"; -@import "../label/label"; -@import "../input/input"; @import "../error-message/error-message"; +@import "../input/input"; +@import "../label/label"; @include govuk-exports("date-input") { .govuk-date-input { diff --git a/src/date-input/template.njk b/src/date-input/template.njk index 3e12eb95dd..38078029b9 100644 --- a/src/date-input/template.njk +++ b/src/date-input/template.njk @@ -1,8 +1,28 @@ +{% from "error-message/macro.njk" import govukErrorMessage -%} {% from "fieldset/macro.njk" import govukFieldset %} {% from "input/macro.njk" import govukInput %} +{# If an id 'prefix' is not passed, fall back to using the name attribute + instead. We need this for error messages and hints as well #} +{% set idPrefix = params.idPrefix if params.idPrefix else params.name %} + +{# a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages #} +{% set describedBy = "" %} + {#- Capture the HTML so we can optionally nest it in a fieldset -#} {% set innerHtml %} + {% if params.errorMessage %} + {% set errorId = params.id + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) -}} + {% endif %} +
@@ -27,18 +47,20 @@
{% endset %} -{%- if params.fieldset %} - {% call govukFieldset({ - classes: params.fieldset.classes, - attributes: params.fieldset.attributes, - legendText: params.fieldset.legendText, - legendHtml: params.fieldset.legendHtml, - legendHintText: params.fieldset.legendHintText, - legendHintHtml: params.fieldset.legendHintHtml, - errorMessage: params.errorMessage - }) %} - {{- innerHtml | indent(2) | trim | safe }} - {% endcall %} -{% else %} - {{ innerHtml | trim | safe }} -{% endif %} +
+ {%- if params.fieldset %} + {% call govukFieldset({ + describedBy: describedBy, + classes: params.fieldset.classes, + attributes: params.fieldset.attributes, + legendText: params.fieldset.legendText, + legendHtml: params.fieldset.legendHtml, + legendHintText: params.fieldset.legendHintText, + legendHintHtml: params.fieldset.legendHintHtml + }) %} + {{- innerHtml | indent(2) | trim | safe }} + {% endcall %} + {% else %} + {{ innerHtml | trim | safe }} + {% endif %} +
diff --git a/src/date-input/template.test.js b/src/date-input/template.test.js index e0ee244323..c548e898bc 100644 --- a/src/date-input/template.test.js +++ b/src/date-input/template.test.js @@ -6,6 +6,8 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('date-input') +const WORD_BOUNDARY = '\\b' + describe('Date input', () => { it('default example passes accessibility tests', async () => { const $ = render('date-input', examples.default) @@ -202,6 +204,33 @@ describe('Date input', () => { }) }) + it('renders the error message', () => { + const $ = render('date-input', examples['with-errors']) + expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() + }) + + it('uses the id as a prefix for the error message id', () => { + const $ = render('date-input', examples['with-errors']) + + const $errorMessage = $('.govuk-error-message') + + expect($errorMessage.attr('id')).toEqual('dob-errors-error') + }) + + it('associates the fieldset as "described by" the error message', () => { + const $ = render('date-input', examples['with-errors']) + + const $fieldset = $('.govuk-fieldset') + const $errorMessage = $('.govuk-error-message') + + const errorMessageId = new RegExp( + WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(errorMessageId) + }) + it('passes through fieldset params without breaking', () => { const $ = render('date-input', examples['default']) @@ -232,7 +261,6 @@ describe('Date input', () => { ] }) - expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() expect(htmlWithClassName($, '.govuk-fieldset')).toMatchSnapshot() }) }) From f9921615947c41f3281399f99f65a7f097e28215 Mon Sep 17 00:00:00 2001 From: alex-ju Date: Tue, 1 May 2018 11:47:07 +0100 Subject: [PATCH 09/25] Remove error-message from fieldset --- src/fieldset/_fieldset.scss | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/fieldset/_fieldset.scss b/src/fieldset/_fieldset.scss index 7e8379d195..75232a819a 100644 --- a/src/fieldset/_fieldset.scss +++ b/src/fieldset/_fieldset.scss @@ -1,8 +1,6 @@ @import "../globals/tools/exports"; @import "../globals/tools/iff"; -@import "../error-message/error-message"; - @import "../globals/settings/spacing"; @import "../globals/settings/measurements"; @@ -12,10 +10,6 @@ @import "../globals/objects/form-group"; - - - - @include govuk-exports("fieldset") { .govuk-fieldset { margin: 0; From e5317eae87909b7bf7948ba396d03ea9b82f21b2 Mon Sep 17 00:00:00 2001 From: alex-ju Date: Tue, 1 May 2018 17:17:25 +0100 Subject: [PATCH 10/25] Add hint component --- src/all/_all.scss | 1 + src/hint/README.md | 183 ++++++++++++++++++++++++++++++++++++++ src/hint/_hint.scss | 19 ++++ src/hint/hint.njk | 7 ++ src/hint/hint.yaml | 9 ++ src/hint/index.njk | 112 +++++++++++++++++++++++ src/hint/macro.njk | 3 + src/hint/template.njk | 4 + src/hint/template.test.js | 65 ++++++++++++++ 9 files changed, 403 insertions(+) create mode 100644 src/hint/README.md create mode 100644 src/hint/_hint.scss create mode 100644 src/hint/hint.njk create mode 100644 src/hint/hint.yaml create mode 100644 src/hint/index.njk create mode 100644 src/hint/macro.njk create mode 100644 src/hint/template.njk create mode 100644 src/hint/template.test.js diff --git a/src/all/_all.scss b/src/all/_all.scss index bc3eb172be..a69a8c6ac4 100644 --- a/src/all/_all.scss +++ b/src/all/_all.scss @@ -13,6 +13,7 @@ @import "../fieldset/fieldset"; @import "../file-upload/file-upload"; @import "../footer/footer"; +@import "../hint/hint"; @import "../input/input"; @import "../label/label"; @import "../panel/panel"; diff --git a/src/hint/README.md b/src/hint/README.md new file mode 100644 index 0000000000..417fbdfe7f --- /dev/null +++ b/src/hint/README.md @@ -0,0 +1,183 @@ +# Hint + +## Introduction + +Use hint text for supporting contextual help + +## Quick start examples + +### Component default + +[Preview the hint component](http://govuk-frontend-review.herokuapp.com/components/hint/preview) + +#### Markup + + + It’s on your National Insurance card, benefit letter, payslip or P60\. For example, ‘QQ 12 34 56 C’. + + +#### Macro + + {% from 'hint/macro.njk' import govukHint %} + + {{ govukHint({ + "text": "It’s on your National Insurance card, benefit letter, payslip or P60\. For example, ‘QQ 12 34 56 C’." + }) }} + +### Hint--with html + +[Preview the hint--with html example](http://govuk-frontend-review.herokuapp.com/components/hint/with html/preview) + +#### Markup + + + It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’. + + +#### Macro + + {% from 'hint/macro.njk' import govukHint %} + + {{ govukHint({ + "html": "It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’." + }) }} + +## Dependencies + +To consume the hint component you must be running npm version 5 or above. + +## Installation + + npm install --save @govuk-frontend/hint + +## Requirements + +### Build tool configuration + +When compiling the Sass files you'll need to define includePaths to reference the node_modules directory. Below is a sample configuration using gulp + + .pipe(sass({ + includePaths: 'node_modules/' + })) + +### Static asset path configuration + +To show the button image you need to configure your app to show these assets. Below is a sample configuration using Express js: + + app.use('/public', express.static(path.join(__dirname, '/node_modules/@govuk-frontend/icons'))) + +## Component arguments + +If you are using Nunjucks,then macros take the following arguments + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeRequiredDescription
classesstringNoOptional additional classes
idstringYesThe id of the hint
textstringNoText to use within the hint
htmlstringNoHTML to use within the hint. If this is provided, the text argument will be ignored.
attributesobjectNoAny extra HTML attributes (for example data attributes) to add to the hint span tag.
+ +### Setting up Nunjucks views and paths + +Below is an example setup using express configure views: + + nunjucks.configure('node_modules/@govuk-frontend', { + autoescape: true, + cache: false, + express: app + }) + +## Getting updates + +To check whether you have the latest version of the button run: + + npm outdated @govuk-frontend/hint + +To update the latest version run: + + npm update @govuk-frontend/hint + +## Contribution + +Guidelines can be found at [on our Github repository.](https://github.com/alphagov/govuk-frontend/blob/master/CONTRIBUTING.md "link to contributing guidelines on our github repository") + +## License + +MIT \ No newline at end of file diff --git a/src/hint/_hint.scss b/src/hint/_hint.scss new file mode 100644 index 0000000000..35b1fe5d8b --- /dev/null +++ b/src/hint/_hint.scss @@ -0,0 +1,19 @@ +@import "../globals/helpers/typography"; +@import "../globals/helpers/media-queries"; + +@import "../globals/settings/colours-palette"; +@import "../globals/settings/colours-applied"; +@import "../globals/settings/typography-font-stacks"; +@import "../globals/settings/typography-font"; +@import "../globals/settings/typography-responsive"; + +@import "../globals/tools/exports"; + +@include govuk-exports("hint") { + .govuk-hint { + @include govuk-font-regular-19; + + display: block; + color: $govuk-secondary-text-colour; + } +} diff --git a/src/hint/hint.njk b/src/hint/hint.njk new file mode 100644 index 0000000000..13366c299e --- /dev/null +++ b/src/hint/hint.njk @@ -0,0 +1,7 @@ +{% from "hint/macro.njk" import govukHint %} + +{{ govukHint({ + text: "It’s on your National Insurance card, benefit letter, payslip or P60. + For example, ‘QQ 12 34 56 C’.", + id: "hint-id" +}) }} diff --git a/src/hint/hint.yaml b/src/hint/hint.yaml new file mode 100644 index 0000000000..e86213d2f3 --- /dev/null +++ b/src/hint/hint.yaml @@ -0,0 +1,9 @@ +examples: + - name: default + data: + text: 'It’s on your National Insurance card, benefit letter, payslip or P60. + For example, ‘QQ 12 34 56 C’.' + - name: with html + data: + html: 'It’s on your National Insurance card, benefit letter, payslip or P60. + For example, ‘QQ 12 34 56 C’.' diff --git a/src/hint/index.njk b/src/hint/index.njk new file mode 100644 index 0000000000..8448027ae1 --- /dev/null +++ b/src/hint/index.njk @@ -0,0 +1,112 @@ +{% if isReadme %} + {% set parentTemplate = "readme.njk" %} +{% else %} + {% set parentTemplate = "component.njk" %} +{% endif %} + +{% extends parentTemplate %} + +{# Commented out blocks below inherit from views/component.njk #} + +{# componentName #} + +{% block componentDescription %} + Use hint text for supporting contextual help +{% endblock %} + +{# examples #} + +{# override link to design system here if it's different to base url + componentName #} +{% set componentGuidanceLink = false %} + +{% block componentArguments %} +{{ govukTable({ + 'firstCellIsHeader': true, + 'head' : [ + { + text: 'Name' + }, + { + text: 'Type' + }, + { + text: 'Required' + }, + { + text: 'Description' + } + ], + 'rows' : [ + [ + { + text: 'classes' + }, + { + text: 'string' + }, + { + text: 'No' + }, + { + text: 'Optional additional classes' + } + ], + [ + { + text: 'id' + }, + { + text: 'string' + }, + { + text: 'Yes' + }, + { + text: 'The id of the hint' + } + ], + [ + { + text: 'text' + }, + { + text: 'string' + }, + { + text: 'No' + }, + { + text: 'Text to use within the hint' + } + ], + [ + { + text: 'html' + }, + { + text: 'string' + }, + { + text: 'No' + }, + { + text: 'HTML to use within the hint. If this is provided, the text argument will be ignored.' + } + ], + [ + { + text: 'attributes' + }, + { + text: 'object' + }, + { + text: 'No' + }, + { + text: 'Any extra HTML attributes (for example data attributes) to add to the hint span tag.' + } + ] + ] +})}} +{% endblock %} diff --git a/src/hint/macro.njk b/src/hint/macro.njk new file mode 100644 index 0000000000..e0a639d757 --- /dev/null +++ b/src/hint/macro.njk @@ -0,0 +1,3 @@ +{% macro govukHint(params) %} + {%- include "./template.njk" -%} +{% endmacro %} diff --git a/src/hint/template.njk b/src/hint/template.njk new file mode 100644 index 0000000000..58350dca06 --- /dev/null +++ b/src/hint/template.njk @@ -0,0 +1,4 @@ + + {{ params.html | safe if params.html else params.text }} + diff --git a/src/hint/template.test.js b/src/hint/template.test.js new file mode 100644 index 0000000000..75843d8b85 --- /dev/null +++ b/src/hint/template.test.js @@ -0,0 +1,65 @@ +/* eslint-env jest */ + +const { axe } = require('jest-axe') + +const { render, getExamples } = require('../../lib/jest-helpers') + +const examples = getExamples('hint') + +describe('Hint', () => { + describe('by default', () => { + it('passes accessibility tests', async () => { + const $ = render('hint', examples.default) + + const results = await axe($.html()) + expect(results).toHaveNoViolations() + }) + + it('renders with classes', () => { + const $ = render('hint', { + classes: 'app-hint--custom-modifier' + }) + + const $component = $('.govuk-hint') + expect($component.hasClass('app-hint--custom-modifier')).toBeTruthy() + }) + + it('renders with id', () => { + const $ = render('hint', { + id: 'my-hint' + }) + + const $component = $('.govuk-hint') + expect($component.attr('id')).toEqual('my-hint') + }) + + it('allows text to be passed whilst escaping HTML entities', () => { + const $ = render('hint', { + text: 'Unexpected bold text in body' + }) + + const content = $('.govuk-hint').html().trim() + expect(content).toEqual('Unexpected <strong>bold text</strong> in body') + }) + + it('allows HTML to be passed un-escaped', () => { + const $ = render('hint', { + html: 'Unexpected bold text in body copy' + }) + + const content = $('.govuk-hint').html().trim() + expect(content).toEqual('Unexpected bold text in body copy') + }) + + it('renders with attributes', () => { + const $ = render('hint', { + attributes: { + 'data-attribute': 'my data value' + } + }) + + const $component = $('.govuk-hint') + expect($component.attr('data-attribute')).toEqual('my data value') + }) + }) +}) From a87bf26bae62916bb1ac9108306a83905598c2cf Mon Sep 17 00:00:00 2001 From: alex-ju Date: Wed, 2 May 2018 10:17:37 +0100 Subject: [PATCH 11/25] Remove hint from label --- src/label/README.md | 52 ++------------------------------------ src/label/_label.scss | 17 +++++++------ src/label/index.njk | 42 ------------------------------ src/label/label.njk | 3 +-- src/label/label.yaml | 4 --- src/label/template.njk | 5 ---- src/label/template.test.js | 25 ------------------ 7 files changed, 12 insertions(+), 136 deletions(-) diff --git a/src/label/README.md b/src/label/README.md index 669a382b8f..19b2b9eb3d 100644 --- a/src/label/README.md +++ b/src/label/README.md @@ -14,11 +14,6 @@ Use labels for all form fields. #### Macro @@ -26,8 +21,7 @@ Use labels for all form fields. {% from 'label/macro.njk' import govukLabel %} {{ govukLabel({ - "text": "National Insurance number", - "hintText": "It’s on your National Insurance card, benefit letter, payslip or P60\. For example, ‘QQ 12 34 56 C’." + "text": "National Insurance number" }) }} ### Label--with bold text @@ -38,11 +32,6 @@ Use labels for all form fields. #### Macro @@ -51,8 +40,7 @@ Use labels for all form fields. {{ govukLabel({ "classes": "govuk-label--bold", - "text": "National Insurance number", - "hintText": "It’s on your National Insurance card, benefit letter, payslip or P60\. For example, ‘QQ 12 34 56 C’." + "text": "National Insurance number" }) }} ## Dependencies @@ -153,42 +141,6 @@ If you are using Nunjucks,then macros take the following arguments -hintText - -string - -No - -Optional text to use as a hint - - - - - -hintHtml - -string - -No - -Optional HTML to use as a hint. If this is provided, the hintText argument will be ignored. - - - - - -errorMessage - -object - -No - -Optional error message. See errorMessage component. - - - - - attributes object diff --git a/src/label/_label.scss b/src/label/_label.scss index 5d4ae8a9e0..3890a68d59 100644 --- a/src/label/_label.scss +++ b/src/label/_label.scss @@ -1,3 +1,12 @@ +@import "../globals/helpers/typography"; +@import "../globals/helpers/media-queries"; + +@import "../globals/settings/colours-palette"; +@import "../globals/settings/colours-applied"; +@import "../globals/settings/typography-font-stacks"; +@import "../globals/settings/typography-font"; +@import "../globals/settings/typography-responsive"; + @import "../globals/tools/exports"; @include govuk-exports("label") { @@ -11,12 +20,4 @@ .govuk-label--bold { @include govuk-typography-weight-bold; } - - // Hint text sits inside a label, to be read by AT - .govuk-label__hint { - @include govuk-typography-weight-regular; - - display: block; - color: $govuk-secondary-text-colour; - } } diff --git a/src/label/index.njk b/src/label/index.njk index b15cbdbaaa..64570a5a69 100644 --- a/src/label/index.njk +++ b/src/label/index.njk @@ -93,48 +93,6 @@ text: 'The value of the for attribute, the id of the input the label is associated with' } ], - [ - { - text: 'hintText' - }, - { - text: 'string' - }, - { - text: 'No' - }, - { - text: 'Optional text to use as a hint' - } - ], - [ - { - text: 'hintHtml' - }, - { - text: 'string' - }, - { - text: 'No' - }, - { - text: 'Optional HTML to use as a hint. If this is provided, the hintText argument will be ignored.' - } - ], - [ - { - text: 'errorMessage' - }, - { - text: 'object' - }, - { - text: 'No' - }, - { - text: 'Optional error message. See errorMessage component.' - } - ], [ { text: 'attributes' diff --git a/src/label/label.njk b/src/label/label.njk index 15b4f41886..5cd740f1a3 100644 --- a/src/label/label.njk +++ b/src/label/label.njk @@ -1,7 +1,6 @@ {% from "label/macro.njk" import govukLabel %} {{ govukLabel({ - "text": "National Insurance number", - "hintText": "It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’." + "text": "National Insurance number" } ) }} diff --git a/src/label/label.yaml b/src/label/label.yaml index 48d6a8c01b..12c6056f23 100644 --- a/src/label/label.yaml +++ b/src/label/label.yaml @@ -2,11 +2,7 @@ examples: - name: default data: text: National Insurance number - hintText: 'It’s on your National Insurance card, benefit letter, payslip or P60. - For example, ‘QQ 12 34 56 C’.' - name: with bold text data: classes: govuk-label--bold text: National Insurance number - hintText: 'It’s on your National Insurance card, benefit letter, payslip or P60. - For example, ‘QQ 12 34 56 C’.' diff --git a/src/label/template.njk b/src/label/template.njk index 7fe0612503..17b16520f7 100644 --- a/src/label/template.njk +++ b/src/label/template.njk @@ -2,9 +2,4 @@ {%- for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %} {%- if params.for %} for="{{ params.for }}"{% endif %}> {{ params.html | safe if params.html else params.text }} - {% if params.hintText or params.hintHtml %} - - {{ params.hintHtml | safe if params.hintHtml else params.hintText }} - - {% endif %} diff --git a/src/label/template.test.js b/src/label/template.test.js index a6b51947d7..adf75599b4 100644 --- a/src/label/template.test.js +++ b/src/label/template.test.js @@ -58,13 +58,6 @@ describe('Label', () => { expect(labelText).toEqual('National Insurance number NINO') }) - it('renders label hint text', () => { - const $ = render('label', examples.default) - const labelHintText = $('.govuk-label__hint').text().trim() - - expect(labelHintText).toEqual('It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’.') - }) - it('renders for attribute if specified', () => { const $ = render('label', { for: '#dummy-input' @@ -74,24 +67,6 @@ describe('Label', () => { expect(labelForAttr).toEqual('#dummy-input') }) - it('allows label hint text to be passed whilst escaping HTML entities', () => { - const $ = render('label', { - hintText: 'It’s on your National Insurance card, benefit letter, payslip or P60. For example, QQ 12 34 56 C.' - }) - - const labelHintText = $('.govuk-label__hint').html().trim() - expect(labelHintText).toEqual('It’s on your National Insurance card, benefit letter, payslip or P60. For example, <strong>QQ 12 34 56 C</strong>.') - }) - - it('allows label hint HTML to be passed un-escaped', () => { - const $ = render('label', { - hintHtml: 'It is on your National Insurance card, benefit letter, payslip or P60. For example, QQ 12 34 56 C.' - }) - - const labelHintText = $('.govuk-label__hint').html().trim() - expect(labelHintText).toEqual('It is on your National Insurance card, benefit letter, payslip or P60. For example, QQ 12 34 56 C.') - }) - it('allows additional attributes to be added to the component', () => { const $ = render('label', { attributes: { From 1eaccc5937981b51da094fc06d71886e4736cc47 Mon Sep 17 00:00:00 2001 From: alex-ju Date: Wed, 2 May 2018 11:50:11 +0100 Subject: [PATCH 12/25] Move hint out of label for input --- src/input/README.md | 118 +++++++++++------- src/input/__snapshots__/template.test.js.snap | 10 ++ src/input/_input.scss | 7 +- src/input/index.njk | 16 ++- src/input/input.yaml | 15 ++- src/input/template.njk | 46 ++++--- src/input/template.test.js | 30 +++++ 7 files changed, 167 insertions(+), 75 deletions(-) diff --git a/src/input/README.md b/src/input/README.md index 20dc2143b1..9bacb8b0bd 100644 --- a/src/input/README.md +++ b/src/input/README.md @@ -16,10 +16,10 @@ Find out when to use the Input component in your service in the [GOV.UK Design S #### Markup -
+
+
@@ -42,16 +42,16 @@ Find out when to use the Input component in your service in the [GOV.UK Design S #### Markup -
@@ -32,37 +29,7 @@ Find out when to use the Fieldset component in your service in the [GOV.UK Desig {% from 'fieldset/macro.njk' import govukFieldset %} {{ govukFieldset({ - "legendText": "What is your address?", - "legendHintText": "For example, 10 Downing Street" - }) }} - -### Fieldset--with-error-message - -[Preview the fieldset--with-error-message example](http://govuk-frontend-review.herokuapp.com/components/fieldset/with-error-message/preview) - -#### Markup - -
- - - What is your address? - - For example, 10 Downing Street - - - -
- -#### Macro - - {% from 'fieldset/macro.njk' import govukFieldset %} - - {{ govukFieldset({ - "legendText": "What is your address?", - "legendHintText": "For example, 10 Downing Street", - "errorMessage": { - "text": "Please fill in the street input" - } + "legendText": "What is your address?" }) }} ## Dependencies @@ -151,42 +118,6 @@ If you are using Nunjucks,then macros take the following arguments -legendHintText - -string - -No - -HTML to use within the legend element. If this is used, the legendText argument will be ignored. - - - - - -legendHintHtml - -string - -No - -HTML to use within the legend hint element. If this is used, the hintText argument will be ignored. - - - - - -errorMessage - -object - -No - -Provide text or html key with values. See errorMessage component for more details. - - - - - attributes object diff --git a/src/fieldset/__snapshots__/template.test.js.snap b/src/fieldset/__snapshots__/template.test.js.snap deleted file mode 100644 index 50d39f764f..0000000000 --- a/src/fieldset/__snapshots__/template.test.js.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`fieldset dependant components passes through errorMessage params without breaking 1`] = ` - - - Please fill in the street input - - -`; diff --git a/src/fieldset/_fieldset.scss b/src/fieldset/_fieldset.scss index 75232a819a..0876608413 100644 --- a/src/fieldset/_fieldset.scss +++ b/src/fieldset/_fieldset.scss @@ -1,6 +1,8 @@ @import "../globals/tools/exports"; @import "../globals/tools/iff"; +@import "../globals/settings/colours-palette"; +@import "../globals/settings/colours-applied"; @import "../globals/settings/spacing"; @import "../globals/settings/measurements"; @@ -8,6 +10,11 @@ @import "../globals/helpers/spacing"; @import "../globals/helpers/media-queries"; +@import "../globals/helpers/typography"; +@import "../globals/settings/typography-font-stacks"; +@import "../globals/settings/typography-font"; +@import "../globals/settings/typography-responsive"; + @import "../globals/objects/form-group"; @include govuk-exports("fieldset") { @@ -52,13 +59,4 @@ .govuk-fieldset__legend--bold { @include govuk-typography-weight-bold; } - - // Hint text sits inside a legend, to be read by AT - .govuk-fieldset__hint { - @include govuk-typography-weight-regular; - - display: block; - color: $govuk-secondary-text-colour; - } - } diff --git a/src/fieldset/fieldset.yaml b/src/fieldset/fieldset.yaml index d0ee0786cc..46dcd370b0 100644 --- a/src/fieldset/fieldset.yaml +++ b/src/fieldset/fieldset.yaml @@ -2,10 +2,3 @@ examples: - name: default data: legendText: What is your address? - legendHintText: For example, 10 Downing Street -- name: with-error-message - data: - legendText: What is your address? - legendHintText: For example, 10 Downing Street - errorMessage: - text: 'Please fill in the street input' diff --git a/src/fieldset/index.njk b/src/fieldset/index.njk index 095d74dc1f..7f43fee17e 100644 --- a/src/fieldset/index.njk +++ b/src/fieldset/index.njk @@ -79,48 +79,6 @@ text: 'Legend text' } ], - [ - { - text: 'legendHintText' - }, - { - text: 'string' - }, - { - text: 'No' - }, - { - text: 'HTML to use within the legend element. If this is used, the legendText argument will be ignored.' - } - ], - [ - { - text: 'legendHintHtml' - }, - { - text: 'string' - }, - { - text: 'No' - }, - { - text: 'HTML to use within the legend hint element. If this is used, the hintText argument will be ignored.' - } - ], - [ - { - text: 'errorMessage' - }, - { - text: 'object' - }, - { - text: 'No' - }, - { - text: 'Provide text or html key with values. See errorMessage component for more details.' - } - ], [ { text: 'attributes' diff --git a/src/fieldset/template.njk b/src/fieldset/template.njk index 321bc9c244..bf1b40dd33 100644 --- a/src/fieldset/template.njk +++ b/src/fieldset/template.njk @@ -5,9 +5,6 @@ {% if params.legendHtml or params.legendText %} {{ params.legendHtml | safe if params.legendHtml else params.legendText }} - {% if params.legendHintText or params.legendHintHtml %} - {{ params.legendHintHtml | safe if params.legendHintHtml else params.legendHintText }} - {% endif %} {% endif %} {{ caller() if caller }} {#- if statement allows usage of `call` to be optional -#} diff --git a/src/fieldset/template.test.js b/src/fieldset/template.test.js index 1a2335dae4..1ffada414c 100644 --- a/src/fieldset/template.test.js +++ b/src/fieldset/template.test.js @@ -2,7 +2,7 @@ const { axe } = require('jest-axe') -const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpers') +const { render, getExamples } = require('../../lib/jest-helpers') const examples = getExamples('fieldset') @@ -64,39 +64,6 @@ describe('fieldset', () => { expect($legend.html()).toContain('What is your address?') }) - it('renders legendHintText using markup that is semantic', () => { - const $ = render('fieldset', { - legendText: 'What is your address?', - legendHintText: 'For example, 10 Downing Street' - }) - - const $component = $('.govuk-fieldset') - const $hint = $component.find('.govuk-fieldset__hint') - expect($hint.html()).toEqual('For example, 10 Downing Street') - }) - - it('renders escaped legendHintText when passing html', () => { - const $ = render('fieldset', { - legendText: 'What is your address?', - legendHintText: 'For example, 10 Downing Street' - }) - - const $component = $('.govuk-fieldset') - const $hint = $component.find('.govuk-fieldset__hint') - expect($hint.html()).toEqual('For example, <b>10 Downing Street</b>') - }) - - it('renders legendHintHtml', () => { - const $ = render('fieldset', { - legendText: 'What is your address?', - legendHintHtml: 'For example, 10 Downing Street' - }) - - const $component = $('.govuk-fieldset') - const $hint = $component.find('.govuk-fieldset__hint') - expect($hint.html()).toEqual('For example, 10 Downing Street') - }) - it('renders attributes', () => { const $ = render('fieldset', { attributes: { @@ -109,19 +76,4 @@ describe('fieldset', () => { expect($component.attr('data-attribute')).toEqual('value') expect($component.attr('data-another-attribute')).toEqual('another-value') }) - - describe('dependant components', () => { - it('have correct nesting order', () => { - const $ = render('fieldset', examples['with-error-message']) - - const $component = $('.govuk-form-group > .govuk-fieldset') - expect($component.length).toBeTruthy() - }) - - it('passes through errorMessage params without breaking', () => { - const $ = render('fieldset', examples['with-error-message']) - - expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() - }) - }) }) From 57e3b00c45ea062a316d3f0facf293e4065a14ce Mon Sep 17 00:00:00 2001 From: alex-ju Date: Wed, 2 May 2018 16:40:39 +0100 Subject: [PATCH 17/25] Move hint out of legend for checkboxes --- src/checkboxes/README.md | 258 ++++++++++-------- .../__snapshots__/template.test.js.snap | 28 +- src/checkboxes/_checkboxes.scss | 2 + src/checkboxes/checkboxes.yaml | 16 +- src/checkboxes/index.njk | 30 +- src/checkboxes/template.njk | 73 ++--- src/checkboxes/template.test.js | 22 +- 7 files changed, 258 insertions(+), 171 deletions(-) diff --git a/src/checkboxes/README.md b/src/checkboxes/README.md index 41846b7f0c..d6d2efab12 100644 --- a/src/checkboxes/README.md +++ b/src/checkboxes/README.md @@ -17,43 +17,42 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup
-
+ +
What is your nationality? - - If you have dual nationality, select all options that are relevant to you. - -
+ + If you have dual nationality, select all options that are relevant to you. + -
- -
+ +
+ @@ -65,8 +64,10 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des "idPrefix": "nationality", "name": "nationality", "fieldset": { - "legendText": "What is your nationality?", - "legendHintText": "If you have dual nationality, select all options that are relevant to you." + "legendText": "What is your nationality?" + }, + "hint": { + "text": "If you have dual nationality, select all options that are relevant to you." }, "items": [ { @@ -91,30 +92,28 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup
-
+ +
+ Red +
+ Green +
+ Blue +
@@ -151,43 +150,42 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup
-
+ +

Which types of waste do you transport regularly?

- - Select all that apply -
-
+ + Select all that apply + -
- -
+ +
+
@@ -196,9 +194,12 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des {% from 'checkboxes/macro.njk' import govukCheckboxes %} {{ govukCheckboxes({ + "name": "waste", "fieldset": { - "legendHtml": "

Which types of waste do you transport regularly?

", - "legendHintText": "Select all that apply" + "legendHtml": "

Which types of waste do you transport regularly?

" + }, + "hint": { + "text": "Select all that apply" }, "items": [ { @@ -223,30 +224,28 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup
-
+ +
+ Red +
+ Green +
+ Blue +
@@ -282,47 +281,46 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup
-
+ +
What is your nationality? - - If you have dual nationality, select all options that are relevant to you. - - + + If you have dual nationality, select all options that are relevant to you. + + + Please select an option -
+
-
- -
-
- -
-
- -
-
+ +
+
@@ -333,17 +331,19 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des {{ govukCheckboxes({ "idPrefix": "example", "name": "example", - "errorMessage": { - "text": "Please select an option" - }, "fieldset": { "classes": "app-fieldset--custom-modifier", "attributes": { "data-attribute": "value", "data-second-attribute": "second-value" }, - "legendText": "What is your nationality?", - "legendHintText": "If you have dual nationality, select all options that are relevant to you." + "legendText": "What is your nationality?" + }, + "hint": { + "text": "If you have dual nationality, select all options that are relevant to you." + }, + "errorMessage": { + "text": "Please select an option" }, "items": [ { @@ -368,45 +368,42 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des #### Markup
-
+ +

Which types of waste do you transport regularly?

-
- + Please select an option -
+
-
- -
-
- -
-
- -
-
+ +
+
@@ -415,6 +412,7 @@ Find out when to use the Checkboxes component in your service in the [GOV.UK Des {% from 'checkboxes/macro.njk' import govukCheckboxes %} {{ govukCheckboxes({ + "name": "waste", "errorMessage": { "text": "Please select an option" }, @@ -493,7 +491,31 @@ If you are using Nunjucks,then macros take the following arguments No -Arguments for the fieldset component (e.g. legendText, legendHintText, errorMessage). See fieldset component. +Arguments for the fieldset component (e.g. legendText). See fieldset component. + + + + + +hint + +object + +No + +Arguments for the hint component (e.g. text). See hint component. + + + + + +errorMessage + +object + +No + +Arguments for the errorMessage component (e.g. text). See errorMessage component. diff --git a/src/checkboxes/__snapshots__/template.test.js.snap b/src/checkboxes/__snapshots__/template.test.js.snap index 9fb2807401..2aeab30f4c 100644 --- a/src/checkboxes/__snapshots__/template.test.js.snap +++ b/src/checkboxes/__snapshots__/template.test.js.snap @@ -3,15 +3,12 @@ exports[`Checkboxes nested dependant components passes through fieldset params without breaking 1`] = `
What is your nationality? - - If you have dual nationality, select all options that are relevant to you. -
@@ -21,14 +18,11 @@ exports[`Checkboxes nested dependant components passes through html fieldset par
- What is your <b>nationality</b>? - - If you have dual nationality, - - select all options - - that are relevant to you. - + What is your + + nationality + + ?
@@ -62,3 +56,13 @@ exports[`Checkboxes nested dependant components renders the error message 1`] = `; + +exports[`Checkboxes nested dependant components renders the hint 1`] = ` + + + If you have dual nationality, select all options that are relevant to you. + + +`; diff --git a/src/checkboxes/_checkboxes.scss b/src/checkboxes/_checkboxes.scss index 3594d6da3f..d78f530f05 100644 --- a/src/checkboxes/_checkboxes.scss +++ b/src/checkboxes/_checkboxes.scss @@ -1,8 +1,10 @@ @import "../globals/tools/exports"; @import "../globals/tools/ie8"; +@import "../globals/settings/measurements"; @import "../error-message/error-message"; @import "../fieldset/fieldset"; +@import "../hint/hint"; @import "../label/label"; @include govuk-exports("checkboxes") { diff --git a/src/checkboxes/checkboxes.yaml b/src/checkboxes/checkboxes.yaml index 7cc6775325..3ae6e8b29c 100644 --- a/src/checkboxes/checkboxes.yaml +++ b/src/checkboxes/checkboxes.yaml @@ -15,7 +15,8 @@ examples: name: 'nationality' fieldset: legendText: What is your nationality? - legendHintText: If you have dual nationality, select all options that are relevant to you. + hint: + text: If you have dual nationality, select all options that are relevant to you. items: - value: 'british' text: 'British' @@ -38,10 +39,12 @@ examples: - name: with-html data: + name: waste fieldset: legendHtml:

Which types of waste do you transport regularly?

- legendHintText: Select all that apply + hint: + text: Select all that apply items: - value: animal text: Waste from animal carcasses @@ -65,16 +68,16 @@ examples: data: idPrefix: 'example' name: 'example' - errorMessage: - text: 'Please select an option' fieldset: classes: 'app-fieldset--custom-modifier' attributes: 'data-attribute': 'value' 'data-second-attribute': 'second-value' legendText: What is your nationality? - legendHintText: - If you have dual nationality, select all options that are relevant to you. + hint: + text: If you have dual nationality, select all options that are relevant to you. + errorMessage: + text: 'Please select an option' items: - value: 'british' text: 'British' @@ -85,6 +88,7 @@ examples: - name: with-error data: + name: waste errorMessage: text: 'Please select an option' fieldset: diff --git a/src/checkboxes/index.njk b/src/checkboxes/index.njk index 66a902253b..1af6d9f94d 100644 --- a/src/checkboxes/index.njk +++ b/src/checkboxes/index.njk @@ -48,7 +48,35 @@ text: 'No' }, { - text: 'Arguments for the fieldset component (e.g. legendText, legendHintText, errorMessage). See fieldset component.' + text: 'Arguments for the fieldset component (e.g. legendText). See fieldset component.' + } + ], + [ + { + text: 'hint' + }, + { + text: 'object' + }, + { + text: 'No' + }, + { + text: 'Arguments for the hint component (e.g. text). See hint component.' + } + ], + [ + { + text: 'errorMessage' + }, + { + text: 'object' + }, + { + text: 'No' + }, + { + text: 'Arguments for the errorMessage component (e.g. text). See errorMessage component.' } ], [ diff --git a/src/checkboxes/template.njk b/src/checkboxes/template.njk index fec167c201..cea848efe4 100644 --- a/src/checkboxes/template.njk +++ b/src/checkboxes/template.njk @@ -1,13 +1,14 @@ {% from "error-message/macro.njk" import govukErrorMessage -%} {% from "fieldset/macro.njk" import govukFieldset %} +{% from "hint/macro.njk" import govukHint %} {% from "label/macro.njk" import govukLabel %} -{# If an id 'prefix' is not passed, fall back to using the name attribute - instead. We need this for error messages and hints as well #} +{#- If an id 'prefix' is not passed, fall back to using the name attribute + instead. We need this for error messages and hints as well -#} {% set idPrefix = params.idPrefix if params.idPrefix else params.name %} -{# a record of other elements that we need to associate with the input using - aria-describedby – for example hints or error messages #} +{#- a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages -#} {% set describedBy = "" %} {% set isConditional = false %} @@ -19,17 +20,27 @@ {#- Capture the HTML so we can optionally nest it in a fieldset -#} {% set innerHtml %} - {% if params.errorMessage %} - {% set errorId = idPrefix + '-error' %} - {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} - {{ govukErrorMessage({ - id: errorId, - classes: params.errorMessage.classes, - html: params.errorMessage.html, - text: params.errorMessage.text - }) -}} - {% endif %} - +{% if params.hint %} + {% set hintId = idPrefix + '-hint' %} + {% set describedBy = describedBy + ' ' + hintId if describedBy else hintId %} + {{ govukHint({ + id: hintId, + classes: params.hint.classes, + attributes: params.hint.attributes, + html: params.hint.html, + text: params.hint.text + }) | indent(2) | trim }} +{% endif %} +{% if params.errorMessage %} + {% set errorId = idPrefix + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) | indent(2) | trim }} +{% endif %}
@@ -47,7 +58,7 @@ classes: 'govuk-checkboxes__label', attributes: item.label.attributes, for: id - }) | indent(4) | trim }} + }) | indent(6) | trim }}
{% if item.conditional %}
@@ -56,22 +67,20 @@ {% endif %} {% endfor %}
-{% endset %} +{% endset -%}
- {%- if params.fieldset %} - {% call govukFieldset({ - describedBy: describedBy, - classes: params.fieldset.classes, - attributes: params.fieldset.attributes, - legendText: params.fieldset.legendText, - legendHtml: params.fieldset.legendHtml, - legendHintText: params.fieldset.legendHintText, - legendHintHtml: params.fieldset.legendHintHtml - }) %} - {{- innerHtml | indent(2) | trim | safe }} - {% endcall %} - {% else %} - {{ innerHtml | trim | safe }} - {% endif %} +{% if params.fieldset %} + {% call govukFieldset({ + describedBy: describedBy, + classes: params.fieldset.classes, + attributes: params.fieldset.attributes, + legendText: params.fieldset.legendText, + legendHtml: params.fieldset.legendHtml + }) %} + {{ innerHtml | trim | safe }} + {% endcall %} +{% else %} + {{ innerHtml | trim | safe }} +{% endif %}
diff --git a/src/checkboxes/template.test.js b/src/checkboxes/template.test.js index fcc569a8ac..06184d221a 100644 --- a/src/checkboxes/template.test.js +++ b/src/checkboxes/template.test.js @@ -261,6 +261,25 @@ describe('Checkboxes', () => { expect(htmlWithClassName($, '.govuk-checkboxes__label')).toMatchSnapshot() }) + it('renders the hint', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + + expect(htmlWithClassName($, '.govuk-hint')).toMatchSnapshot() + }) + + it('associates the fieldset as "described by" the hint', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + + const $fieldset = $('.govuk-fieldset') + const $hint = $('.govuk-hint') + + const hintId = new RegExp( + WORD_BOUNDARY + $hint.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')).toMatch(hintId) + }) + it('renders the error message', () => { const $ = render('checkboxes', examples['with-extreme-fieldset']) @@ -340,8 +359,7 @@ describe('Checkboxes', () => { } ], fieldset: { - legendText: 'What is your nationality?', - legendHintHtml: 'If you have dual nationality, select all options that are relevant to you.' + legendHtml: 'What is your nationality?' } }) From 928cd3dc1b12d0c130cdaf1c44c4093ccd6dda74 Mon Sep 17 00:00:00 2001 From: alex-ju Date: Wed, 2 May 2018 16:55:03 +0100 Subject: [PATCH 18/25] Move hint out of legend for radios --- src/checkboxes/_checkboxes.scss | 1 + src/radios/README.md | 246 ++++++++++-------- .../__snapshots__/template.test.js.snap | 28 +- src/radios/_radios.scss | 4 + src/radios/index.njk | 30 ++- src/radios/radios.yaml | 19 +- src/radios/template.njk | 73 +++--- src/radios/template.test.js | 22 +- 8 files changed, 260 insertions(+), 163 deletions(-) diff --git a/src/checkboxes/_checkboxes.scss b/src/checkboxes/_checkboxes.scss index d78f530f05..3328dcc716 100644 --- a/src/checkboxes/_checkboxes.scss +++ b/src/checkboxes/_checkboxes.scss @@ -1,5 +1,6 @@ @import "../globals/tools/exports"; @import "../globals/tools/ie8"; +@import "../globals/settings/spacing"; @import "../globals/settings/measurements"; @import "../error-message/error-message"; diff --git a/src/radios/README.md b/src/radios/README.md index cbe580e85a..d8a883020e 100644 --- a/src/radios/README.md +++ b/src/radios/README.md @@ -17,35 +17,35 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup
-
+ +
Have you changed your name? - - This includes changing your last name or spelling your name differently. - -
+ + This includes changing your last name or spelling your name differently. + -
- -
+ +
+
@@ -57,8 +57,10 @@ Find out when to use the Radios component in your service in the [GOV.UK Design "idPrefix": "example", "name": "example", "fieldset": { - "legendText": "Have you changed your name?", - "legendHintText": "This includes changing your last name or spelling your name differently." + "legendText": "Have you changed your name?" + }, + "hint": { + "text": "This includes changing your last name or spelling your name differently." }, "items": [ { @@ -80,35 +82,35 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup
-
+ +
Have you changed your name? - - This includes changing your last name or spelling your name differently. - -
+ + This includes changing your last name or spelling your name differently. + -
- -
+ +
+ @@ -121,8 +123,10 @@ Find out when to use the Radios component in your service in the [GOV.UK Design "classes": "govuk-radios--inline", "name": "example", "fieldset": { - "legendText": "Have you changed your name?", - "legendHintText": "This includes changing your last name or spelling your name differently." + "legendText": "Have you changed your name?" + }, + "hint": { + "text": "This includes changing your last name or spelling your name differently." }, "items": [ { @@ -144,35 +148,35 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup
-
+ +
Have you changed your name? - - This includes changing your last name or spelling your name differently. - -
+ + This includes changing your last name or spelling your name differently. + -
- -
+ +
+ @@ -184,8 +188,10 @@ Find out when to use the Radios component in your service in the [GOV.UK Design "idPrefix": "example-disabled", "name": "example-disabled", "fieldset": { - "legendText": "Have you changed your name?", - "legendHintText": "This includes changing your last name or spelling your name differently." + "legendText": "Have you changed your name?" + }, + "hint": { + "text": "This includes changing your last name or spelling your name differently." }, "items": [ { @@ -208,35 +214,35 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup
-
+ +

Which part of the Housing Act was your licence issued under?

- - Select one of the options below. -
-
+ + Select one of the options below. + + +
-
- -
-
- -
-
+ +
+ @@ -248,8 +254,10 @@ Find out when to use the Radios component in your service in the [GOV.UK Design "idPrefix": "housing-act", "name": "housing-act", "fieldset": { - "legendHtml": "

Which part of the Housing Act was your licence issued under?

", - "legendHintText": "Select one of the options below." + "legendHtml": "

Which part of the Housing Act was your licence issued under?

" + }, + "hint": { + "text": "Select one of the options below." }, "items": [ { @@ -270,30 +278,28 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup
-
+ +
+ Red +
+ Green +
+ Blue +
@@ -329,39 +335,39 @@ Find out when to use the Radios component in your service in the [GOV.UK Design #### Markup
-
+ +
Have you changed your name? - - This includes changing your last name or spelling your name differently. - - + + This includes changing your last name or spelling your name differently. + + + Please select an option -
+
-
- -
-
- -
-
+ +
+
@@ -381,8 +387,10 @@ Find out when to use the Radios component in your service in the [GOV.UK Design "data-attribute": "value", "data-second-attribute": "second-value" }, - "legendText": "Have you changed your name?", - "legendHintText": "This includes changing your last name or spelling your name differently." + "legendText": "Have you changed your name?" + }, + "hint": { + "text": "This includes changing your last name or spelling your name differently." }, "items": [ { @@ -455,7 +463,31 @@ If you are using Nunjucks,then macros take the following arguments No -Arguments for the fieldset component (e.g. legendText, legendHintText, errorMessage). See fieldset component. +Arguments for the fieldset component (e.g. legendText). See fieldset component. + + + + + +hint + +object + +No + +Arguments for the hint component (e.g. text). See hint component. + + + + + +errorMessage + +object + +No + +Arguments for the errorMessage component (e.g. text). See errorMessage component. diff --git a/src/radios/__snapshots__/template.test.js.snap b/src/radios/__snapshots__/template.test.js.snap index 78dd12aa12..1ffd8f4a86 100644 --- a/src/radios/__snapshots__/template.test.js.snap +++ b/src/radios/__snapshots__/template.test.js.snap @@ -3,15 +3,12 @@ exports[`Radios nested dependant components passes through fieldset params without breaking 1`] = `
Have you changed your name? - - This includes changing your last name or spelling your name differently. -
@@ -21,14 +18,11 @@ exports[`Radios nested dependant components passes through html fieldset params
- Have <b>you</b> changed your name? - - This - - includes - - changing your last name or spelling your name differently. - + Have + + you + + changed your name?
@@ -62,3 +56,13 @@ exports[`Radios nested dependant components renders the error message 1`] = ` `; + +exports[`Radios nested dependant components renders the hint 1`] = ` + + + This includes changing your last name or spelling your name differently. + + +`; diff --git a/src/radios/_radios.scss b/src/radios/_radios.scss index 75fdee749b..1d8ecb1b6b 100644 --- a/src/radios/_radios.scss +++ b/src/radios/_radios.scss @@ -1,8 +1,12 @@ +@import "../globals/helpers/clearfix"; @import "../globals/tools/exports"; @import "../globals/tools/ie8"; +@import "../globals/settings/spacing"; +@import "../globals/settings/measurements"; @import "../error-message/error-message"; @import "../fieldset/fieldset"; +@import "../hint/hint"; @import "../label/label"; @include govuk-exports("radios") { diff --git a/src/radios/index.njk b/src/radios/index.njk index fc8ffd0827..f90faf1936 100644 --- a/src/radios/index.njk +++ b/src/radios/index.njk @@ -51,7 +51,35 @@ Please note, this component depends on @govuk-frontend/globals, which will autom text: 'No' }, { - text: 'Arguments for the fieldset component (e.g. legendText, legendHintText, errorMessage). See fieldset component.' + text: 'Arguments for the fieldset component (e.g. legendText). See fieldset component.' + } + ], + [ + { + text: 'hint' + }, + { + text: 'object' + }, + { + text: 'No' + }, + { + text: 'Arguments for the hint component (e.g. text). See hint component.' + } + ], + [ + { + text: 'errorMessage' + }, + { + text: 'object' + }, + { + text: 'No' + }, + { + text: 'Arguments for the errorMessage component (e.g. text). See errorMessage component.' } ], [ diff --git a/src/radios/radios.yaml b/src/radios/radios.yaml index fa9231e913..d99fe0bbb0 100644 --- a/src/radios/radios.yaml +++ b/src/radios/radios.yaml @@ -15,8 +15,8 @@ examples: name: 'example' fieldset: legendText: Have you changed your name? - legendHintText: - This includes changing your last name or spelling your name differently. + hint: + text: This includes changing your last name or spelling your name differently. items: - value: yes text: Yes @@ -31,8 +31,8 @@ examples: name: 'example' fieldset: legendText: Have you changed your name? - legendHintText: - This includes changing your last name or spelling your name differently. + hint: + text: This includes changing your last name or spelling your name differently. items: - value: yes text: Yes @@ -46,8 +46,8 @@ examples: name: 'example-disabled' fieldset: legendText: Have you changed your name? - legendHintText: - This includes changing your last name or spelling your name differently. + hint: + text: This includes changing your last name or spelling your name differently. items: - value: yes text: Yes @@ -62,7 +62,8 @@ examples: name: 'housing-act' fieldset: legendHtml:

Which part of the Housing Act was your licence issued under?

- legendHintText: Select one of the options below. + hint: + text: Select one of the options below. items: - value: 'part-2' html: @@ -96,8 +97,8 @@ examples: 'data-attribute': 'value' 'data-second-attribute': 'second-value' legendText: Have you changed your name? - legendHintText: - This includes changing your last name or spelling your name differently. + hint: + text: This includes changing your last name or spelling your name differently. items: - value: yes text: Yes diff --git a/src/radios/template.njk b/src/radios/template.njk index da409fe237..e4c7583d16 100644 --- a/src/radios/template.njk +++ b/src/radios/template.njk @@ -1,13 +1,14 @@ {% from "error-message/macro.njk" import govukErrorMessage -%} {% from "fieldset/macro.njk" import govukFieldset %} +{% from "hint/macro.njk" import govukHint %} {% from "label/macro.njk" import govukLabel %} -{# If an id 'prefix' is not passed, fall back to using the name attribute - instead. We need this for error messages and hints as well #} +{#- If an id 'prefix' is not passed, fall back to using the name attribute + instead. We need this for error messages and hints as well -#} {% set idPrefix = params.idPrefix if params.idPrefix else params.name %} -{# a record of other elements that we need to associate with the input using - aria-describedby – for example hints or error messages #} +{#- a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages -#} {% set describedBy = "" %} {% set isConditional = false %} @@ -19,17 +20,27 @@ {#- Capture the HTML so we can optionally nest it in a fieldset -#} {% set innerHtml %} - {% if params.errorMessage %} - {% set errorId = idPrefix + '-error' %} - {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} - {{ govukErrorMessage({ - id: errorId, - classes: params.errorMessage.classes, - html: params.errorMessage.html, - text: params.errorMessage.text - }) -}} - {% endif %} - +{% if params.hint %} + {% set hintId = idPrefix + '-hint' %} + {% set describedBy = describedBy + ' ' + hintId if describedBy else hintId %} + {{ govukHint({ + id: hintId, + classes: params.hint.classes, + attributes: params.hint.attributes, + html: params.hint.html, + text: params.hint.text + }) | indent(2) | trim }} +{% endif %} +{% if params.errorMessage %} + {% set errorId = idPrefix + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) | indent(2) | trim }} +{% endif %}
@@ -47,7 +58,7 @@ classes: 'govuk-radios__label', attributes: item.label.attributes, for: id - }) | indent(4) | trim }} + }) | indent(6) | trim }}
{% if item.conditional %}
@@ -56,22 +67,20 @@ {% endif %} {% endfor %}
-{% endset %} +{% endset -%}
- {%- if params.fieldset %} - {% call govukFieldset({ - describedBy: describedBy, - classes: params.fieldset.classes, - attributes: params.fieldset.attributes, - legendText: params.fieldset.legendText, - legendHtml: params.fieldset.legendHtml, - legendHintText: params.fieldset.legendHintText, - legendHintHtml: params.fieldset.legendHintHtml - }) %} - {{- innerHtml | indent(2) | trim | safe }} - {% endcall %} - {% else %} - {{ innerHtml | trim | safe }} - {% endif %} +{% if params.fieldset %} + {% call govukFieldset({ + describedBy: describedBy, + classes: params.fieldset.classes, + attributes: params.fieldset.attributes, + legendText: params.fieldset.legendText, + legendHtml: params.fieldset.legendHtml + }) %} + {{ innerHtml | trim | safe }} + {% endcall %} +{% else %} + {{ innerHtml | trim | safe }} +{% endif %}
diff --git a/src/radios/template.test.js b/src/radios/template.test.js index f0e47e445b..bc02fb674b 100644 --- a/src/radios/template.test.js +++ b/src/radios/template.test.js @@ -258,6 +258,25 @@ describe('Radios', () => { expect(htmlWithClassName($, '.govuk-radios__label')).toMatchSnapshot() }) + it('renders the hint', () => { + const $ = render('radios', examples['with-extreme-fieldset']) + + expect(htmlWithClassName($, '.govuk-hint')).toMatchSnapshot() + }) + + it('associates the fieldset as "described by" the hint', () => { + const $ = render('radios', examples['with-extreme-fieldset']) + + const $fieldset = $('.govuk-fieldset') + const $hint = $('.govuk-hint') + + const hintId = new RegExp( + WORD_BOUNDARY + $hint.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')).toMatch(hintId) + }) + it('renders the error message', () => { const $ = render('radios', examples['with-extreme-fieldset']) expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() @@ -336,8 +355,7 @@ describe('Radios', () => { } ], fieldset: { - legendText: 'Have you changed your name?', - legendHintHtml: 'This includes changing your last name or spelling your name differently.' + legendHtml: 'Have you changed your name?' } }) From c417fe1590a929aa538a8778d69dc755d95043ed Mon Sep 17 00:00:00 2001 From: alex-ju Date: Wed, 2 May 2018 17:04:45 +0100 Subject: [PATCH 19/25] Move hint out of legend for date-input --- src/date-input/README.md | 296 ++++++++++-------- .../__snapshots__/template.test.js.snap | 23 +- src/date-input/_date-input.scss | 5 + src/date-input/date-input.yaml | 15 +- src/date-input/template.njk | 71 +++-- src/date-input/template.test.js | 19 ++ 6 files changed, 243 insertions(+), 186 deletions(-) diff --git a/src/date-input/README.md b/src/date-input/README.md index 3044f57f22..09c6e62874 100644 --- a/src/date-input/README.md +++ b/src/date-input/README.md @@ -17,49 +17,51 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
-
+ +
What is your date of birth? - - For example, 31 3 1980 - -
+ + For example, 31 3 1980 + -
-
+ +
+
@@ -71,8 +73,10 @@ Find out when to use the Date input component in your service in the [GOV.UK Des "id": "dob", "name": "dob", "fieldset": { - "legendText": "What is your date of birth?", - "legendHintText": "For example, 31 3 1980" + "legendText": "What is your date of birth?" + }, + "hint": { + "text": "For example, 31 3 1980" }, "items": [ { @@ -94,53 +98,55 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
-
+ +
What is your date of birth? - - For example, 31 3 1980 - - - Error message goes here + + For example, 31 3 1980 -
+ + Error message goes here + -
-
+ +
+ @@ -151,8 +157,10 @@ Find out when to use the Date input component in your service in the [GOV.UK Des {{ govukDateInput({ "id": "dob-errors", "fieldset": { - "legendText": "What is your date of birth?", - "legendHintText": "For example, 31 3 1980" + "legendText": "What is your date of birth?" + }, + "hint": { + "text": "For example, 31 3 1980" }, "errorMessage": { "text": "Error message goes here" @@ -180,53 +188,55 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
-
+ +
What is your date of birth? - - For example, 31 3 1980 - - - Error message goes here + + For example, 31 3 1980 -
+ + Error message goes here + -
-
+ +
+ @@ -238,8 +248,10 @@ Find out when to use the Date input component in your service in the [GOV.UK Des "id": "dob-day-error", "name": "dob-day-error", "fieldset": { - "legendText": "What is your date of birth?", - "legendHintText": "For example, 31 3 1980" + "legendText": "What is your date of birth?" + }, + "hint": { + "text": "For example, 31 3 1980" }, "errorMessage": { "text": "Error message goes here" @@ -265,53 +277,55 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
-
+ +
What is your date of birth? - - For example, 31 3 1980 - - - Error message goes here + + For example, 31 3 1980 -
+ + Error message goes here + -
-
+ +
+ @@ -323,8 +337,10 @@ Find out when to use the Date input component in your service in the [GOV.UK Des "id": "dob-month-error", "name": "dob-month-error", "fieldset": { - "legendText": "What is your date of birth?", - "legendHintText": "For example, 31 3 1980" + "legendText": "What is your date of birth?" + }, + "hint": { + "text": "For example, 31 3 1980" }, "errorMessage": { "text": "Error message goes here" @@ -350,53 +366,55 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
-
+ +
What is your date of birth? - - For example, 31 3 1980 - - - Error message goes here + + For example, 31 3 1980 -
+ + Error message goes here + -
-
+ +
+ @@ -408,8 +426,10 @@ Find out when to use the Date input component in your service in the [GOV.UK Des "id": "dob-year-error", "name": "dob-year-error", "fieldset": { - "legendText": "What is your date of birth?", - "legendHintText": "For example, 31 3 1980" + "legendText": "What is your date of birth?" + }, + "hint": { + "text": "For example, 31 3 1980" }, "errorMessage": { "text": "Error message goes here" diff --git a/src/date-input/__snapshots__/template.test.js.snap b/src/date-input/__snapshots__/template.test.js.snap index e9a0b7d17e..0ce4e7d2a7 100644 --- a/src/date-input/__snapshots__/template.test.js.snap +++ b/src/date-input/__snapshots__/template.test.js.snap @@ -22,12 +22,11 @@ exports[`Date input nested dependant components passes through label params with exports[`Date input passes through fieldset params without breaking 1`] = ` -
+
What is your date of birth? - - For example, 31 3 1980 -
@@ -44,12 +43,6 @@ exports[`Date input passes through html fieldset params without breaking 1`] = ` date of birth
? - - For example, - - 31 3 1980 - -
@@ -64,3 +57,13 @@ exports[`Date input renders the error message 1`] = `
`; + +exports[`Date input renders the hint 1`] = ` + + + For example, 31 3 1980 + + +`; diff --git a/src/date-input/_date-input.scss b/src/date-input/_date-input.scss index 235ffc8786..c6ec5c0dae 100644 --- a/src/date-input/_date-input.scss +++ b/src/date-input/_date-input.scss @@ -1,8 +1,13 @@ +@import "../globals/helpers/clearfix"; @import "../globals/tools/exports"; @import "../globals/tools/iff"; +@import "../globals/settings/colours-palette"; +@import "../globals/settings/colours-applied"; +@import "../globals/settings/spacing"; @import "../error-message/error-message"; @import "../input/input"; +@import "../hint/hint"; @import "../label/label"; @include govuk-exports("date-input") { diff --git a/src/date-input/date-input.yaml b/src/date-input/date-input.yaml index 6fb4eb396b..8ee17696e2 100644 --- a/src/date-input/date-input.yaml +++ b/src/date-input/date-input.yaml @@ -5,7 +5,8 @@ examples: name: 'dob' fieldset: legendText: 'What is your date of birth?' - legendHintText: 'For example, 31 3 1980' + hint: + text: 'For example, 31 3 1980' items: - name: 'day' @@ -18,7 +19,8 @@ examples: id: 'dob-errors' fieldset: legendText: 'What is your date of birth?' - legendHintText: 'For example, 31 3 1980' + hint: + text: 'For example, 31 3 1980' errorMessage: text: 'Error message goes here' items: @@ -37,7 +39,8 @@ examples: name: 'dob-day-error' fieldset: legendText: 'What is your date of birth?' - legendHintText: 'For example, 31 3 1980' + hint: + text: 'For example, 31 3 1980' errorMessage: text: 'Error message goes here' items: @@ -54,7 +57,8 @@ examples: name: 'dob-month-error' fieldset: legendText: 'What is your date of birth?' - legendHintText: 'For example, 31 3 1980' + hint: + text: 'For example, 31 3 1980' errorMessage: text: 'Error message goes here' items: @@ -71,7 +75,8 @@ examples: name: 'dob-year-error' fieldset: legendText: 'What is your date of birth?' - legendHintText: 'For example, 31 3 1980' + hint: + text: 'For example, 31 3 1980' errorMessage: text: 'Error message goes here' items: diff --git a/src/date-input/template.njk b/src/date-input/template.njk index 38078029b9..235b057e21 100644 --- a/src/date-input/template.njk +++ b/src/date-input/template.njk @@ -1,28 +1,35 @@ {% from "error-message/macro.njk" import govukErrorMessage -%} {% from "fieldset/macro.njk" import govukFieldset %} +{% from "hint/macro.njk" import govukHint %} {% from "input/macro.njk" import govukInput %} -{# If an id 'prefix' is not passed, fall back to using the name attribute - instead. We need this for error messages and hints as well #} -{% set idPrefix = params.idPrefix if params.idPrefix else params.name %} - -{# a record of other elements that we need to associate with the input using - aria-describedby – for example hints or error messages #} +{#- a record of other elements that we need to associate with the input using + aria-describedby – for example hints or error messages -#} {% set describedBy = "" %} {#- Capture the HTML so we can optionally nest it in a fieldset -#} {% set innerHtml %} - {% if params.errorMessage %} - {% set errorId = params.id + '-error' %} - {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} - {{ govukErrorMessage({ - id: errorId, - classes: params.errorMessage.classes, - html: params.errorMessage.html, - text: params.errorMessage.text - }) -}} - {% endif %} - +{% if params.hint %} + {% set hintId = params.id + '-hint' %} + {% set describedBy = describedBy + ' ' + hintId if describedBy else hintId %} + {{ govukHint({ + id: hintId, + classes: params.hint.classes, + attributes: params.hint.attributes, + html: params.hint.html, + text: params.hint.text + }) | indent(2) | trim }} +{% endif %} +{% if params.errorMessage %} + {% set errorId = params.id + '-error' %} + {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %} + {{ govukErrorMessage({ + id: errorId, + classes: params.errorMessage.classes, + html: params.errorMessage.html, + text: params.errorMessage.text + }) | indent(2) | trim }} +{% endif %}
@@ -41,26 +48,24 @@ "attributes": { "pattern": "[0-9]*" } - }) | indent(4) | trim }} + }) | indent(6) | trim }}
{% endfor %} {% endset %}
- {%- if params.fieldset %} - {% call govukFieldset({ - describedBy: describedBy, - classes: params.fieldset.classes, - attributes: params.fieldset.attributes, - legendText: params.fieldset.legendText, - legendHtml: params.fieldset.legendHtml, - legendHintText: params.fieldset.legendHintText, - legendHintHtml: params.fieldset.legendHintHtml - }) %} - {{- innerHtml | indent(2) | trim | safe }} - {% endcall %} - {% else %} - {{ innerHtml | trim | safe }} - {% endif %} +{% if params.fieldset %} + {% call govukFieldset({ + describedBy: describedBy, + classes: params.fieldset.classes, + attributes: params.fieldset.attributes, + legendText: params.fieldset.legendText, + legendHtml: params.fieldset.legendHtml + }) %} + {{ innerHtml | trim | safe }} + {% endcall %} +{% else %} + {{ innerHtml | trim | safe }} +{% endif %}
diff --git a/src/date-input/template.test.js b/src/date-input/template.test.js index c548e898bc..6bb8ef3caf 100644 --- a/src/date-input/template.test.js +++ b/src/date-input/template.test.js @@ -204,6 +204,25 @@ describe('Date input', () => { }) }) + it('renders the hint', () => { + const $ = render('date-input', examples['with-errors']) + expect(htmlWithClassName($, '.govuk-hint')).toMatchSnapshot() + }) + + it('associates the fieldset as "described by" the hint', () => { + const $ = render('date-input', examples['with-errors']) + + const $fieldset = $('.govuk-fieldset') + const $hint = $('.govuk-hint') + + const hintId = new RegExp( + WORD_BOUNDARY + $hint.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(hintId) + }) + it('renders the error message', () => { const $ = render('date-input', examples['with-errors']) expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() From 572dedc6d82039cb7aa75b636b70f108daa086c1 Mon Sep 17 00:00:00 2001 From: alex-ju Date: Thu, 3 May 2018 09:42:52 +0100 Subject: [PATCH 20/25] Fix helpers --- src/globals/helpers/_clearfix.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/globals/helpers/_clearfix.scss b/src/globals/helpers/_clearfix.scss index 3ab39a1c97..24f6342fa7 100644 --- a/src/globals/helpers/_clearfix.scss +++ b/src/globals/helpers/_clearfix.scss @@ -1,3 +1,5 @@ +@import "../tools/exports"; + // Mixin to clear floats @mixin govuk-clearfix { &:after { From 759fd5a506bda929eaf0c23a43eadac92175bf98 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 9 May 2018 13:23:19 +0100 Subject: [PATCH 21/25] Override fieldset role to group for date input We do this because otherwise JAWS does not announce the description for a fieldset comprised of text inputs, but adding the role to the fieldset always makes the output overly verbose for radio buttons or checkboxes. --- src/date-input/README.md | 15 +++++---------- .../__snapshots__/template.test.js.snap | 2 ++ src/date-input/template.njk | 8 +++++++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/date-input/README.md b/src/date-input/README.md index 09c6e62874..86d3dca3a3 100644 --- a/src/date-input/README.md +++ b/src/date-input/README.md @@ -17,8 +17,7 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
- -
+
What is your date of birth? @@ -98,8 +97,7 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
- -
+
What is your date of birth? @@ -188,8 +186,7 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
- -
+
What is your date of birth? @@ -277,8 +274,7 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
- -
+
What is your date of birth? @@ -366,8 +362,7 @@ Find out when to use the Date input component in your service in the [GOV.UK Des #### Markup
- -
+
What is your date of birth? diff --git a/src/date-input/__snapshots__/template.test.js.snap b/src/date-input/__snapshots__/template.test.js.snap index 0ce4e7d2a7..034a0043bc 100644 --- a/src/date-input/__snapshots__/template.test.js.snap +++ b/src/date-input/__snapshots__/template.test.js.snap @@ -24,6 +24,7 @@ exports[`Date input passes through fieldset params without breaking 1`] = `
What is your date of birth? @@ -36,6 +37,7 @@ exports[`Date input passes through html fieldset params without breaking 1`] = `
What is your diff --git a/src/date-input/template.njk b/src/date-input/template.njk index 235b057e21..1402b6bcfa 100644 --- a/src/date-input/template.njk +++ b/src/date-input/template.njk @@ -56,10 +56,16 @@
{% if params.fieldset %} +{#- We override the fieldset's role to 'group' because otherwise JAWS does not + announce the description for a fieldset comprised of text inputs, but + adding the role to the fieldset always makes the output overly verbose for + radio buttons or checkboxes. -#} {% call govukFieldset({ describedBy: describedBy, classes: params.fieldset.classes, - attributes: params.fieldset.attributes, + attributes: { + role: 'group' + }, legendText: params.fieldset.legendText, legendHtml: params.fieldset.legendHtml }) %} From 01bb364fa5b4a48ba3eb7c2a8f9f0bff6089115b Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 9 May 2018 13:36:29 +0100 Subject: [PATCH 22/25] Add a11y criteria for hint and error message --- src/error-message/error-message.yaml | 14 ++++++++++++++ src/hint/hint.yaml | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/error-message/error-message.yaml b/src/error-message/error-message.yaml index 5f0cc83e06..7dda63137c 100644 --- a/src/error-message/error-message.yaml +++ b/src/error-message/error-message.yaml @@ -1,3 +1,17 @@ +accessibilityCriteria: | + When used with a single input, the error message MUST: + - be announced by screen readers when the input is focussed + + When used with a group of multiple inputs (such as within a fieldset), the + error message MUST: + - be announced by screen readers when focussing the first input within the + group (first in this case refers to the focus order, not the DOM - if the + user is traversing backwards through the page then this would be the last + input within the group in the DOM) + + When used with a group of multiple inputs, the error message SHOULD NOT: + - be announced every time for each individual input + examples: - name: default data: diff --git a/src/hint/hint.yaml b/src/hint/hint.yaml index e86213d2f3..c2fc531744 100644 --- a/src/hint/hint.yaml +++ b/src/hint/hint.yaml @@ -1,3 +1,17 @@ +accessibilityCriteria: | + When used with a single input, the hint MUST: + - be announced by screen readers when the input is focussed + + When used with a group of multiple inputs (such as within a fieldset), the + hint MUST: + - be announced by screen readers when focussing the first input within the + group (first in this case refers to the focus order, not the DOM - if the + user is traversing backwards through the page then this would be the last + input within the group in the DOM) + + When used with a group of multiple inputs, the hint SHOULD NOT: + - be announced every time for each individual input + examples: - name: default data: From e45b38b3de52001f174b635f9c63920f1f80a4bb Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 9 May 2018 13:55:44 +0100 Subject: [PATCH 23/25] Add tests for hint + error for fieldset components Also reorganise tests to group tests relating to hints, error messages, and hints and error messages together. --- .../__snapshots__/template.test.js.snap | 16 +-- src/checkboxes/template.test.js | 126 ++++++++++-------- .../__snapshots__/template.test.js.snap | 16 +-- src/date-input/template.test.js | 100 ++++++++------ .../__snapshots__/template.test.js.snap | 16 +-- src/radios/template.test.js | 88 +++++++----- 6 files changed, 214 insertions(+), 148 deletions(-) diff --git a/src/checkboxes/__snapshots__/template.test.js.snap b/src/checkboxes/__snapshots__/template.test.js.snap index 2aeab30f4c..ec5e291f8a 100644 --- a/src/checkboxes/__snapshots__/template.test.js.snap +++ b/src/checkboxes/__snapshots__/template.test.js.snap @@ -47,22 +47,22 @@ exports[`Checkboxes nested dependant components passes through label params with `; -exports[`Checkboxes nested dependant components renders the error message 1`] = ` +exports[`Checkboxes when they include a hint renders the hint 1`] = ` - - Please select an option + If you have dual nationality, select all options that are relevant to you. `; -exports[`Checkboxes nested dependant components renders the hint 1`] = ` +exports[`Checkboxes when they include an error message renders the error message 1`] = ` - - If you have dual nationality, select all options that are relevant to you. + Please select an option `; diff --git a/src/checkboxes/template.test.js b/src/checkboxes/template.test.js index 06184d221a..680d2dceb3 100644 --- a/src/checkboxes/template.test.js +++ b/src/checkboxes/template.test.js @@ -7,6 +7,7 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('checkboxes') const WORD_BOUNDARY = '\\b' +const WHITESPACE = '\\s' describe('Checkboxes', () => { it('default example passes accessibility tests', async () => { @@ -228,58 +229,7 @@ describe('Checkboxes', () => { expect($lastConditional.html()).toContain('Conditional content') }) - describe('nested dependant components', () => { - it('have correct nesting order', () => { - const $ = render('checkboxes', examples['with-extreme-fieldset']) - - const $component = $('.govuk-form-group > .govuk-fieldset > .govuk-checkboxes') - expect($component.length).toBeTruthy() - }) - - it('passes through label params without breaking', () => { - const $ = render('checkboxes', { - name: 'example-name', - items: [ - { - value: '1', - html: 'Option 1', - label: { - attributes: { - 'data-attribute': 'value', - 'data-second-attribute': 'second-value' - } - } - }, - { - value: '2', - text: 'Option 2', - checked: true - } - ] - }) - - expect(htmlWithClassName($, '.govuk-checkboxes__label')).toMatchSnapshot() - }) - - it('renders the hint', () => { - const $ = render('checkboxes', examples['with-extreme-fieldset']) - - expect(htmlWithClassName($, '.govuk-hint')).toMatchSnapshot() - }) - - it('associates the fieldset as "described by" the hint', () => { - const $ = render('checkboxes', examples['with-extreme-fieldset']) - - const $fieldset = $('.govuk-fieldset') - const $hint = $('.govuk-hint') - - const hintId = new RegExp( - WORD_BOUNDARY + $hint.attr('id') + WORD_BOUNDARY - ) - - expect($fieldset.attr('aria-describedby')).toMatch(hintId) - }) - + describe('when they include an error message', () => { it('renders the error message', () => { const $ = render('checkboxes', examples['with-extreme-fieldset']) @@ -338,6 +288,78 @@ describe('Checkboxes', () => { expect($fieldset.attr('aria-describedby')) .toMatch(errorMessageId) }) + }) + + describe('when they include a hint', () => { + it('renders the hint', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + + expect(htmlWithClassName($, '.govuk-hint')).toMatchSnapshot() + }) + + it('associates the fieldset as "described by" the hint', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + + const $fieldset = $('.govuk-fieldset') + const $hint = $('.govuk-hint') + + const hintId = new RegExp( + WORD_BOUNDARY + $hint.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')).toMatch(hintId) + }) + }) + + describe('when they include both a hint and an error message', () => { + it('associates the fieldset as described by both the hint and the error message', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + + const $fieldset = $('.govuk-fieldset') + const $errorMessageId = $('.govuk-error-message').attr('id') + const $hintId = $('.govuk-hint').attr('id') + + const combinedIds = new RegExp( + WORD_BOUNDARY + $hintId + WHITESPACE + $errorMessageId + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(combinedIds) + }) + }) + + describe('nested dependant components', () => { + it('have correct nesting order', () => { + const $ = render('checkboxes', examples['with-extreme-fieldset']) + + const $component = $('.govuk-form-group > .govuk-fieldset > .govuk-checkboxes') + expect($component.length).toBeTruthy() + }) + + it('passes through label params without breaking', () => { + const $ = render('checkboxes', { + name: 'example-name', + items: [ + { + value: '1', + html: 'Option 1', + label: { + attributes: { + 'data-attribute': 'value', + 'data-second-attribute': 'second-value' + } + } + }, + { + value: '2', + text: 'Option 2', + checked: true + } + ] + }) + + expect(htmlWithClassName($, '.govuk-checkboxes__label')).toMatchSnapshot() + }) it('passes through fieldset params without breaking', () => { const $ = render('checkboxes', examples['with-extreme-fieldset']) diff --git a/src/date-input/__snapshots__/template.test.js.snap b/src/date-input/__snapshots__/template.test.js.snap index 034a0043bc..7eff055d91 100644 --- a/src/date-input/__snapshots__/template.test.js.snap +++ b/src/date-input/__snapshots__/template.test.js.snap @@ -50,22 +50,22 @@ exports[`Date input passes through html fieldset params without breaking 1`] = ` `; -exports[`Date input renders the error message 1`] = ` +exports[`Date input when it includes a hint renders the hint 1`] = ` - - Error message goes here + For example, 31 3 1980 `; -exports[`Date input renders the hint 1`] = ` +exports[`Date input when it includes an error message renders the error message 1`] = ` - - For example, 31 3 1980 + Error message goes here `; diff --git a/src/date-input/template.test.js b/src/date-input/template.test.js index 6bb8ef3caf..995ad34fd1 100644 --- a/src/date-input/template.test.js +++ b/src/date-input/template.test.js @@ -7,6 +7,7 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('date-input') const WORD_BOUNDARY = '\\b' +const WHITESPACE = '\\s' describe('Date input', () => { it('default example passes accessibility tests', async () => { @@ -189,65 +190,86 @@ describe('Date input', () => { }) }) - describe('nested dependant components', () => { - it('have correct nesting order', () => { - const $ = render('date-input', examples['default']) - - const $component = $('.govuk-form-group > .govuk-fieldset > .govuk-date-input') - expect($component.length).toBeTruthy() + describe('when it includes a hint', () => { + it('renders the hint', () => { + const $ = render('date-input', examples['with-errors']) + expect(htmlWithClassName($, '.govuk-hint')).toMatchSnapshot() }) - it('passes through label params without breaking', () => { - const $ = render('date-input', examples['default']) + it('associates the fieldset as "described by" the hint', () => { + const $ = render('date-input', examples['with-errors']) - expect(htmlWithClassName($, '.govuk-date-input__label')).toMatchSnapshot() + const $fieldset = $('.govuk-fieldset') + const $hint = $('.govuk-hint') + + const hintId = new RegExp( + WORD_BOUNDARY + $hint.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(hintId) }) }) - it('renders the hint', () => { - const $ = render('date-input', examples['with-errors']) - expect(htmlWithClassName($, '.govuk-hint')).toMatchSnapshot() - }) + describe('when it includes an error message', () => { + it('renders the error message', () => { + const $ = render('date-input', examples['with-errors']) + expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() + }) - it('associates the fieldset as "described by" the hint', () => { - const $ = render('date-input', examples['with-errors']) + it('uses the id as a prefix for the error message id', () => { + const $ = render('date-input', examples['with-errors']) - const $fieldset = $('.govuk-fieldset') - const $hint = $('.govuk-hint') + const $errorMessage = $('.govuk-error-message') - const hintId = new RegExp( - WORD_BOUNDARY + $hint.attr('id') + WORD_BOUNDARY - ) + expect($errorMessage.attr('id')).toEqual('dob-errors-error') + }) - expect($fieldset.attr('aria-describedby')) - .toMatch(hintId) - }) + it('associates the fieldset as "described by" the error message', () => { + const $ = render('date-input', examples['with-errors']) - it('renders the error message', () => { - const $ = render('date-input', examples['with-errors']) - expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() + const $fieldset = $('.govuk-fieldset') + const $errorMessage = $('.govuk-error-message') + + const errorMessageId = new RegExp( + WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(errorMessageId) + }) }) - it('uses the id as a prefix for the error message id', () => { - const $ = render('date-input', examples['with-errors']) + describe('when they include both a hint and an error message', () => { + it('associates the fieldset as described by both the hint and the error message', () => { + const $ = render('date-input', examples['with-errors']) + + const $fieldset = $('.govuk-fieldset') + const $errorMessageId = $('.govuk-error-message').attr('id') + const $hintId = $('.govuk-hint').attr('id') - const $errorMessage = $('.govuk-error-message') + const combinedIds = new RegExp( + WORD_BOUNDARY + $hintId + WHITESPACE + $errorMessageId + WORD_BOUNDARY + ) - expect($errorMessage.attr('id')).toEqual('dob-errors-error') + expect($fieldset.attr('aria-describedby')) + .toMatch(combinedIds) + }) }) - it('associates the fieldset as "described by" the error message', () => { - const $ = render('date-input', examples['with-errors']) + describe('nested dependant components', () => { + it('have correct nesting order', () => { + const $ = render('date-input', examples['default']) - const $fieldset = $('.govuk-fieldset') - const $errorMessage = $('.govuk-error-message') + const $component = $('.govuk-form-group > .govuk-fieldset > .govuk-date-input') + expect($component.length).toBeTruthy() + }) - const errorMessageId = new RegExp( - WORD_BOUNDARY + $errorMessage.attr('id') + WORD_BOUNDARY - ) + it('passes through label params without breaking', () => { + const $ = render('date-input', examples['default']) - expect($fieldset.attr('aria-describedby')) - .toMatch(errorMessageId) + expect(htmlWithClassName($, '.govuk-date-input__label')).toMatchSnapshot() + }) }) it('passes through fieldset params without breaking', () => { diff --git a/src/radios/__snapshots__/template.test.js.snap b/src/radios/__snapshots__/template.test.js.snap index 1ffd8f4a86..c644d5732d 100644 --- a/src/radios/__snapshots__/template.test.js.snap +++ b/src/radios/__snapshots__/template.test.js.snap @@ -47,22 +47,22 @@ exports[`Radios nested dependant components passes through label params without `; -exports[`Radios nested dependant components renders the error message 1`] = ` +exports[`Radios when they include a hint renders the hint 1`] = ` - - Please select an option + This includes changing your last name or spelling your name differently. `; -exports[`Radios nested dependant components renders the hint 1`] = ` +exports[`Radios when they include an error message renders the error message 1`] = ` - - This includes changing your last name or spelling your name differently. + Please select an option `; diff --git a/src/radios/template.test.js b/src/radios/template.test.js index bc02fb674b..6fefd3802f 100644 --- a/src/radios/template.test.js +++ b/src/radios/template.test.js @@ -7,6 +7,7 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('radios') const WORD_BOUNDARY = '\\b' +const WHITESPACE = '\\s' describe('Radios', () => { it('default example passes accessibility tests', async () => { @@ -225,39 +226,7 @@ describe('Radios', () => { }) }) - describe('nested dependant components', () => { - it('have correct nesting order', () => { - const $ = render('radios', examples['with-extreme-fieldset']) - - const $component = $('.govuk-form-group > .govuk-fieldset > .govuk-radios') - expect($component.length).toBeTruthy() - }) - - it('passes through label params without breaking', () => { - const $ = render('radios', { - name: 'example-name', - items: [ - { - value: 'yes', - html: 'Yes', - label: { - attributes: { - 'data-attribute': 'value', - 'data-second-attribute': 'second-value' - } - } - }, - { - value: 'no', - text: 'No', - checked: true - } - ] - }) - - expect(htmlWithClassName($, '.govuk-radios__label')).toMatchSnapshot() - }) - + describe('when they include a hint', () => { it('renders the hint', () => { const $ = render('radios', examples['with-extreme-fieldset']) @@ -276,7 +245,9 @@ describe('Radios', () => { expect($fieldset.attr('aria-describedby')).toMatch(hintId) }) + }) + describe('when they include an error message', () => { it('renders the error message', () => { const $ = render('radios', examples['with-extreme-fieldset']) expect(htmlWithClassName($, '.govuk-error-message')).toMatchSnapshot() @@ -334,6 +305,57 @@ describe('Radios', () => { expect($fieldset.attr('aria-describedby')) .toMatch(errorMessageId) }) + }) + + describe('when they include both a hint and an error message', () => { + it('associates the fieldset as described by both the hint and the error message', () => { + const $ = render('radios', examples['with-extreme-fieldset']) + + const $fieldset = $('.govuk-fieldset') + const $errorMessageId = $('.govuk-error-message').attr('id') + const $hintId = $('.govuk-hint').attr('id') + + const combinedIds = new RegExp( + WORD_BOUNDARY + $hintId + WHITESPACE + $errorMessageId + WORD_BOUNDARY + ) + + expect($fieldset.attr('aria-describedby')) + .toMatch(combinedIds) + }) + }) + + describe('nested dependant components', () => { + it('have correct nesting order', () => { + const $ = render('radios', examples['with-extreme-fieldset']) + + const $component = $('.govuk-form-group > .govuk-fieldset > .govuk-radios') + expect($component.length).toBeTruthy() + }) + + it('passes through label params without breaking', () => { + const $ = render('radios', { + name: 'example-name', + items: [ + { + value: 'yes', + html: 'Yes', + label: { + attributes: { + 'data-attribute': 'value', + 'data-second-attribute': 'second-value' + } + } + }, + { + value: 'no', + text: 'No', + checked: true + } + ] + }) + + expect(htmlWithClassName($, '.govuk-radios__label')).toMatchSnapshot() + }) it('passes through fieldset params without breaking', () => { const $ = render('radios', examples['with-extreme-fieldset']) From c0d8f6f65d06b8da6016168b2e3733e402314f07 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 9 May 2018 14:11:07 +0100 Subject: [PATCH 24/25] Add tests for hint + error for labelled components Also reorganise tests to group tests relating to hints, error messages, and hints and error messages together. --- .../__snapshots__/template.test.js.snap | 6 +- src/file-upload/template.test.js | 102 +++++++++------ src/input/__snapshots__/template.test.js.snap | 16 +-- src/input/template.test.js | 117 +++++++++++------- .../__snapshots__/template.test.js.snap | 16 +-- src/select/template.test.js | 111 +++++++++++------ .../__snapshots__/template.test.js.snap | 16 +-- src/textarea/template.test.js | 109 ++++++++++------ 8 files changed, 305 insertions(+), 188 deletions(-) diff --git a/src/file-upload/__snapshots__/template.test.js.snap b/src/file-upload/__snapshots__/template.test.js.snap index 375da774f6..16a039729e 100644 --- a/src/file-upload/__snapshots__/template.test.js.snap +++ b/src/file-upload/__snapshots__/template.test.js.snap @@ -1,6 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`File upload with dependant components renders with error message 1`] = ` +exports[`File upload when it includes a hint renders with hint 1`] = `""`; + +exports[`File upload when it includes an error message renders with error message 1`] = ` { describe('by default', () => { @@ -65,41 +66,7 @@ describe('File upload', () => { }) }) - describe('with dependant components', () => { - it('have correct nesting order', () => { - const $ = render('file-upload', { - errorMessage: { - text: 'Error message' - } - }) - - const $component = $('.govuk-form-group > .govuk-file-upload') - expect($component.length).toBeTruthy() - }) - - it('renders with label', () => { - const $ = render('file-upload', { - id: 'my-file-upload', - label: { - text: 'Full address' - } - }) - - expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() - }) - - it('renders label with "for" attribute reffering the file-upload "id"', () => { - const $ = render('file-upload', { - id: 'my-file-upload', - label: { - text: 'Full address' - } - }) - - const $label = $('.govuk-label') - expect($label.attr('for')).toEqual('my-file-upload') - }) - + describe('when it includes a hint', () => { it('renders with hint', () => { const $ = render('file-upload', { id: 'file-upload-with-hint', @@ -129,7 +96,9 @@ describe('File upload', () => { expect($component.attr('aria-describedby')) .toMatch(hintId) }) + }) + describe('when it includes an error message', () => { it('renders with error message', () => { const $ = render('file-upload', { id: 'file-upload-with-error', @@ -160,7 +129,7 @@ describe('File upload', () => { .toMatch(errorMessageId) }) - it('has error class when rendered with error message', () => { + it('includes the error class on the component', () => { const $ = render('file-upload', { errorMessage: { 'text': 'Error message' @@ -171,4 +140,65 @@ describe('File upload', () => { expect($component.hasClass('govuk-file-upload--error')).toBeTruthy() }) }) + + describe('when it includes both a hint and an error message', () => { + it('associates the input as described by both the hint and the error message', () => { + const $ = render('file-upload', { + id: 'input-with-error', + errorMessage: { + 'text': 'Error message' + }, + hint: { + 'text': 'Hint' + } + }) + + const $component = $('.govuk-file-upload') + const $errorMessageId = $('.govuk-error-message').attr('id') + const $hintId = $('.govuk-hint').attr('id') + + const combinedIds = new RegExp( + WORD_BOUNDARY + $hintId + WHITESPACE + $errorMessageId + WORD_BOUNDARY + ) + + expect($component.attr('aria-describedby')) + .toMatch(combinedIds) + }) + }) + + describe('with dependant components', () => { + it('have correct nesting order', () => { + const $ = render('file-upload', { + errorMessage: { + text: 'Error message' + } + }) + + const $component = $('.govuk-form-group > .govuk-file-upload') + expect($component.length).toBeTruthy() + }) + + it('renders with label', () => { + const $ = render('file-upload', { + id: 'my-file-upload', + label: { + text: 'Full address' + } + }) + + expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() + }) + + it('renders label with "for" attribute reffering the file-upload "id"', () => { + const $ = render('file-upload', { + id: 'my-file-upload', + label: { + text: 'Full address' + } + }) + + const $label = $('.govuk-label') + expect($label.attr('for')).toEqual('my-file-upload') + }) + }) }) diff --git a/src/input/__snapshots__/template.test.js.snap b/src/input/__snapshots__/template.test.js.snap index cd986cb72f..aef4c810b4 100644 --- a/src/input/__snapshots__/template.test.js.snap +++ b/src/input/__snapshots__/template.test.js.snap @@ -1,21 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Input with dependant components renders with error message 1`] = ` +exports[`Input when it includes a hint renders the hint 1`] = ` - - Error message + It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’. `; -exports[`Input with dependant components renders with hint 1`] = ` +exports[`Input when it includes an error message renders the error message 1`] = ` - - It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’. + Error message `; diff --git a/src/input/template.test.js b/src/input/template.test.js index af16453358..3808cd6e73 100644 --- a/src/input/template.test.js +++ b/src/input/template.test.js @@ -7,6 +7,7 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('input') const WORD_BOUNDARY = '\\b' +const WHITESPACE = '\\s' describe('Input', () => { describe('by default', () => { @@ -81,47 +82,12 @@ describe('Input', () => { }) }) - describe('with dependant components', () => { - it('have correct nesting order', () => { - const $ = render('input', { - id: 'my-input', - label: { - 'text': 'National Insurance number' - } - }) - - const $component = $('.govuk-form-group > .govuk-input') - expect($component.length).toBeTruthy() - }) - - it('renders with label', () => { - const $ = render('input', { - id: 'my-input', - label: { - 'text': 'National Insurance number' - } - }) - - expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() - }) - - it('renders label with "for" attribute reffering the input "id"', () => { - const $ = render('input', { - id: 'my-input', - label: { - 'text': 'National Insurance number' - } - }) - - const $label = $('.govuk-label') - expect($label.attr('for')).toEqual('my-input') - }) - - it('renders with hint', () => { + describe('when it includes a hint', () => { + it('renders the hint', () => { const $ = render('input', { id: 'input-with-hint', hint: { - 'text': 'It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’.' + text: 'It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’.' } }) @@ -132,7 +98,7 @@ describe('Input', () => { const $ = render('input', { id: 'input-with-hint', hint: { - 'text': 'It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’.' + text: 'It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’.' } }) @@ -146,12 +112,14 @@ describe('Input', () => { expect($input.attr('aria-describedby')) .toMatch(hintId) }) + }) - it('renders with error message', () => { + describe('when it includes an error message', () => { + it('renders the error message', () => { const $ = render('input', { id: 'input-with-error', errorMessage: { - 'text': 'Error message' + text: 'Error message' } }) @@ -162,7 +130,7 @@ describe('Input', () => { const $ = render('input', { id: 'input-with-error', errorMessage: { - 'text': 'Error message' + text: 'Error message' } }) @@ -177,10 +145,10 @@ describe('Input', () => { .toMatch(errorMessageId) }) - it('has error class when rendered with error message', () => { + it('includes the error class on the input', () => { const $ = render('input', { errorMessage: { - 'text': 'Error message' + text: 'Error message' } }) @@ -188,4 +156,65 @@ describe('Input', () => { expect($component.hasClass('govuk-input--error')).toBeTruthy() }) }) + + describe('when it includes both a hint and an error message', () => { + it('associates the input as described by both the hint and the error message', () => { + const $ = render('input', { + errorMessage: { + text: 'Error message' + }, + hint: { + text: 'Hint' + } + }) + + const $component = $('.govuk-input') + const $errorMessageId = $('.govuk-error-message').attr('id') + const $hintId = $('.govuk-hint').attr('id') + + const combinedIds = new RegExp( + WORD_BOUNDARY + $hintId + WHITESPACE + $errorMessageId + WORD_BOUNDARY + ) + + expect($component.attr('aria-describedby')) + .toMatch(combinedIds) + }) + }) + + describe('with dependant components', () => { + it('have correct nesting order', () => { + const $ = render('input', { + id: 'my-input', + label: { + 'text': 'National Insurance number' + } + }) + + const $component = $('.govuk-form-group > .govuk-input') + expect($component.length).toBeTruthy() + }) + + it('renders with label', () => { + const $ = render('input', { + id: 'my-input', + label: { + 'text': 'National Insurance number' + } + }) + + expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() + }) + + it('renders label with "for" attribute reffering the input "id"', () => { + const $ = render('input', { + id: 'my-input', + label: { + 'text': 'National Insurance number' + } + }) + + const $label = $('.govuk-label') + expect($label.attr('for')).toEqual('my-input') + }) + }) }) diff --git a/src/select/__snapshots__/template.test.js.snap b/src/select/__snapshots__/template.test.js.snap index 5b0e7cfabd..96f34e446d 100644 --- a/src/select/__snapshots__/template.test.js.snap +++ b/src/select/__snapshots__/template.test.js.snap @@ -1,21 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Select with dependant components renders with error message 1`] = ` +exports[`Select when it includes a hint renders the hint 1`] = ` - - Error message + Hint text goes here `; -exports[`Select with dependant components renders with hint 1`] = ` +exports[`Select when it includes an error message renders with error message 1`] = ` - - Hint text goes here + Error message `; diff --git a/src/select/template.test.js b/src/select/template.test.js index 6e15587180..e3dec756f8 100644 --- a/src/select/template.test.js +++ b/src/select/template.test.js @@ -7,6 +7,7 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('select') const WORD_BOUNDARY = '\\b' +const WHITESPACE = '\\s' describe('Select', () => { describe('by default', () => { @@ -143,46 +144,8 @@ describe('Select', () => { }) }) - describe('with dependant components', () => { - it('have correct nesting order', () => { - const $ = render('select', { - id: 'nesting-order', - label: { - text: 'National Insurance number' - }, - errorMessage: { - text: 'Error message' - } - }) - - const $component = $('.govuk-form-group > .govuk-select') - expect($component.length).toBeTruthy() - }) - - it('renders with label', () => { - const $ = render('select', { - id: 'my-select', - label: { - text: 'National Insurance number' - } - }) - - expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() - }) - - it('renders label with "for" attribute reffering the select "id"', () => { - const $ = render('select', { - id: 'my-select', - label: { - text: 'Label text' - } - }) - - const $label = $('.govuk-label') - expect($label.attr('for')).toEqual('my-select') - }) - - it('renders with hint', () => { + describe('when it includes a hint', () => { + it('renders the hint', () => { const $ = render('select', { id: 'select-with-hint', hint: { @@ -211,7 +174,9 @@ describe('Select', () => { expect($select.attr('aria-describedby')) .toMatch(hintId) }) + }) + describe('when it includes an error message', () => { it('renders with error message', () => { const $ = render('select', { id: 'select-with-error', @@ -242,7 +207,7 @@ describe('Select', () => { .toMatch(errorMessageId) }) - it('has error class when rendered with error message', () => { + it('adds the error class to the select', () => { const $ = render('select', { errorMessage: { text: 'Error message' @@ -253,4 +218,68 @@ describe('Select', () => { expect($component.hasClass('govuk-select--error')).toBeTruthy() }) }) + + describe('when it includes both a hint and an error message', () => { + it('associates the select as described by both the hint and the error message', () => { + const $ = render('select', { + errorMessage: { + text: 'Error message' + }, + hint: { + text: 'Hint' + } + }) + + const $component = $('.govuk-select') + const $errorMessageId = $('.govuk-error-message').attr('id') + const $hintId = $('.govuk-hint').attr('id') + + const combinedIds = new RegExp( + WORD_BOUNDARY + $hintId + WHITESPACE + $errorMessageId + WORD_BOUNDARY + ) + + expect($component.attr('aria-describedby')) + .toMatch(combinedIds) + }) + }) + + describe('with dependant components', () => { + it('have correct nesting order', () => { + const $ = render('select', { + id: 'nesting-order', + label: { + text: 'National Insurance number' + }, + errorMessage: { + text: 'Error message' + } + }) + + const $component = $('.govuk-form-group > .govuk-select') + expect($component.length).toBeTruthy() + }) + + it('renders with label', () => { + const $ = render('select', { + id: 'my-select', + label: { + text: 'National Insurance number' + } + }) + + expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() + }) + + it('renders label with "for" attribute reffering the select "id"', () => { + const $ = render('select', { + id: 'my-select', + label: { + text: 'Label text' + } + }) + + const $label = $('.govuk-label') + expect($label.attr('for')).toEqual('my-select') + }) + }) }) diff --git a/src/textarea/__snapshots__/template.test.js.snap b/src/textarea/__snapshots__/template.test.js.snap index 982ddd3622..11867051e8 100644 --- a/src/textarea/__snapshots__/template.test.js.snap +++ b/src/textarea/__snapshots__/template.test.js.snap @@ -1,21 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Textarea with dependant components renders with error message 1`] = ` +exports[`Textarea when it includes a hint renders with hint 1`] = ` - - Error message + It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’. `; -exports[`Textarea with dependant components renders with hint 1`] = ` +exports[`Textarea when it includes an error message renders with error message 1`] = ` - - It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’. + Error message `; diff --git a/src/textarea/template.test.js b/src/textarea/template.test.js index e15fca6e67..4e49cbb8a5 100644 --- a/src/textarea/template.test.js +++ b/src/textarea/template.test.js @@ -7,6 +7,7 @@ const { render, getExamples, htmlWithClassName } = require('../../lib/jest-helpe const examples = getExamples('textarea') const WORD_BOUNDARY = '\\b' +const WHITESPACE = '\\s' describe('Textarea', () => { describe('by default', () => { @@ -81,45 +82,7 @@ describe('Textarea', () => { }) }) - describe('with dependant components', () => { - it('have correct nesting order', () => { - const $ = render('textarea', { - id: 'nested-order', - label: { - 'text': 'Full address' - }, - errorMessage: { - 'text': 'Error message' - } - }) - - const $component = $('.govuk-form-group > .govuk-textarea') - expect($component.length).toBeTruthy() - }) - - it('renders with label', () => { - const $ = render('textarea', { - id: 'my-textarea', - label: { - 'text': 'Full address' - } - }) - - expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() - }) - - it('renders label with "for" attribute reffering the textarea "id"', () => { - const $ = render('textarea', { - id: 'my-textarea', - label: { - 'text': 'Full address' - } - }) - - const $label = $('.govuk-label') - expect($label.attr('for')).toEqual('my-textarea') - }) - + describe('when it includes a hint', () => { it('renders with hint', () => { const $ = render('textarea', { id: 'textarea-with-error', @@ -149,7 +112,9 @@ describe('Textarea', () => { expect($textarea.attr('aria-describedby')) .toMatch(hintId) }) + }) + describe('when it includes an error message', () => { it('renders with error message', () => { const $ = render('textarea', { id: 'textarea-with-error', @@ -180,7 +145,7 @@ describe('Textarea', () => { .toMatch(errorMessageId) }) - it('has error class when rendered with error message', () => { + it('adds the error class to the textarea', () => { const $ = render('textarea', { errorMessage: { 'text': 'Error message' @@ -191,4 +156,68 @@ describe('Textarea', () => { expect($component.hasClass('govuk-textarea--error')).toBeTruthy() }) }) + + describe('when it includes both a hint and an error message', () => { + it('associates the textarea as described by both the hint and the error message', () => { + const $ = render('textarea', { + errorMessage: { + 'text': 'Error message' + }, + hint: { + 'text': 'Hint' + } + }) + + const $component = $('.govuk-textarea') + const $errorMessageId = $('.govuk-error-message').attr('id') + const $hintId = $('.govuk-hint').attr('id') + + const combinedIds = new RegExp( + WORD_BOUNDARY + $hintId + WHITESPACE + $errorMessageId + WORD_BOUNDARY + ) + + expect($component.attr('aria-describedby')) + .toMatch(combinedIds) + }) + }) + + describe('with dependant components', () => { + it('have correct nesting order', () => { + const $ = render('textarea', { + id: 'nested-order', + label: { + 'text': 'Full address' + }, + errorMessage: { + 'text': 'Error message' + } + }) + + const $component = $('.govuk-form-group > .govuk-textarea') + expect($component.length).toBeTruthy() + }) + + it('renders with label', () => { + const $ = render('textarea', { + id: 'my-textarea', + label: { + 'text': 'Full address' + } + }) + + expect(htmlWithClassName($, '.govuk-label')).toMatchSnapshot() + }) + + it('renders label with "for" attribute reffering the textarea "id"', () => { + const $ = render('textarea', { + id: 'my-textarea', + label: { + 'text': 'Full address' + } + }) + + const $label = $('.govuk-label') + expect($label.attr('for')).toEqual('my-textarea') + }) + }) }) From 1f4bf3d2d19ecd608cf3ba33817983b7614e8521 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Thu, 10 May 2018 09:37:41 +0100 Subject: [PATCH 25/25] Add test for group role on date input fieldset --- src/date-input/template.test.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/date-input/template.test.js b/src/date-input/template.test.js index 995ad34fd1..20cd2d1687 100644 --- a/src/date-input/template.test.js +++ b/src/date-input/template.test.js @@ -188,6 +188,14 @@ describe('Date input', () => { const $firstItems = $('.govuk-date-input__item:first-child input') expect($firstItems.attr('id')).toEqual('my-date-input-day') }) + + it('sets the `group` role on the fieldset to force JAWS18 to announce the hint and error message', () => { + const $ = render('date-input', examples['with-errors']) + + const $fieldset = $('.govuk-fieldset') + + expect($fieldset.attr('role')).toEqual('group') + }) }) describe('when it includes a hint', () => {