hof 20.1.3 → 20.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1530,6 +1530,7 @@ To render a specific fields in your templates use the mixin name (matching those
1530
1530
  - `required`: Value applied to `aria-required` HTML attribute.
1531
1531
  - `hint`: This adds context to the label, which it is a part of, for input text, radio groups and textarea. It is used within the input by aria-describedby for screen readers.
1532
1532
  - `maxlength`: Applicable to text-based fields and mapped to the `maxlength` HTML attribute.
1533
+ - `maxword`: Applicable to textarea fields.
1533
1534
  - `options`: Applicable to HTML `select` and `radio` controls and used to generate the items of either HTML element.
1534
1535
  - `selected`: Applicable to `select`, `checkbox`, and `radio` controls. Will render the selected HTML option/element selected or checked.
1535
1536
  - `legend`: Applicable to `radio` button controls, which are wrapped in a HTML `fieldset` with a `legend` element.
@@ -62,6 +62,10 @@ module.exports = Validators = {
62
62
  return Validators.string(value) && (value === '' || value.length <= length);
63
63
  },
64
64
 
65
+ maxword(value, length) {
66
+ return Validators.string(value) && (value === '' || value.split(/\s+/).length <= length);
67
+ },
68
+
65
69
  exactlength(value, length) {
66
70
  return Validators.string(value) && (value === '' || value.length === length);
67
71
  },
@@ -42,6 +42,15 @@ module.exports = function (options) {
42
42
  return null;
43
43
  }
44
44
 
45
+ function maxword(field) {
46
+ const validation = field.validate || [];
47
+ const mw = _.findWhere(validation, { type: 'maxword' });
48
+ if (mw) {
49
+ return _.isArray(mw.arguments) ? mw.arguments[0] : mw.arguments;
50
+ }
51
+ return null;
52
+ }
53
+
45
54
  function type(field) {
46
55
  return field.type || 'text';
47
56
  }
@@ -208,6 +217,7 @@ module.exports = function (options) {
208
217
  hintId: extension.hintId || (hint ? key + '-hint' : null),
209
218
  error: this.errors && this.errors[key],
210
219
  maxlength: maxlength(field) || extension.maxlength,
220
+ maxword: maxword(field) || extension.maxword,
211
221
  required: required,
212
222
  pattern: extension.pattern,
213
223
  date: extension.date,
@@ -216,6 +226,7 @@ module.exports = function (options) {
216
226
  isPageHeading: field.isPageHeading,
217
227
  attributes: field.attributes,
218
228
  isPrefixOrSuffix: _.map(field.attributes, item => {if (item.prefix || item.suffix !== undefined) return true;}),
229
+ isMaxlengthOrMaxword: maxlength(field) || extension.maxlength || maxword(field) || extension.maxword,
219
230
  renderChild: renderChild.bind(this)
220
231
  });
221
232
  }
@@ -1,32 +1,35 @@
1
- {{#maxlength}}
2
- <div class="govuk-character-count" data-module="govuk-character-count" data-maxlength="{{maxlength}}">
3
- {{/maxlength}}
4
- <div id="{{id}}-group" class="{{#compound}}form-group-compound {{/compound}}{{#formGroupClassName}}{{formGroupClassName}}{{/formGroupClassName}}{{#error}} govuk-form-group--error{{/error}}">
5
- {{#isPageHeading}}<h1 class="govuk-label-wrapper">{{/isPageHeading}}<label for="{{id}}" class="{{labelClassName}}{{#isPageHeading}}govuk-label--l{{/isPageHeading}}">
6
- {{{label}}}
7
- {{#error}}
8
- <p id="{{id}}-error" class="govuk-error-message">
9
- <span id="{{id}}-error" class="govuk-visually-hidden">Error:</span>{{error.message}}
10
- </p>
11
- {{/error}}
12
- </label>
13
- {{#isPageHeading}}</h1>{{/isPageHeading}}
14
- {{#hint}}<div {{$hintId}}id="{{hintId}}" {{/hintId}}class="govuk-hint">{{hint}}</div>{{/hint}}
15
- {{#renderChild}}{{/renderChild}}
16
- <textarea
17
- name="{{id}}"
18
- id="{{id}}"
19
- class="govuk-textarea{{#className}} {{className}}{{/className}} {{#maxlength}}maxlength{{/maxlength}}{{#error}} govuk-input--error{{/error}}"
20
- aria-required="{{required}}"
21
- {{#maxlength}} maxlength="{{maxlength}}"{{/maxlength}}
22
- {{#attributes}}
23
- {{attribute}}="{{value}}"
24
- {{/attributes}}
25
- {{^error}}{{#hintId}}{{#maxlength}} aria-describedby="{{id}}-maxlength-hint {{hintId}}"{{/maxlength}}{{/hintId}}{{/error}}
26
- {{^error}}{{#hintId}}{{^maxlength}} aria-describedby="{{hintId}}"{{/maxlength}}{{/hintId}}{{/error}}
27
- {{^error}}{{^hintId}}{{#maxlength}} aria-describedby="{{id}}-maxlength-hint"{{/maxlength}}{{/hintId}}{{/error}}
28
- {{#error}} aria-invalid="true" aria-describedby="{{id}}-error"{{/error}}
29
- >{{value}}</textarea>
30
- {{#maxlength}}<div id="{{id}}-maxlength-hint" class="govuk-character-count__message" aria-live="polite">You have {{maxlength}} characters remaining</div>{{/maxlength}}
31
- </div>
32
- {{#maxlength}}</div>{{/maxlength}}
1
+ {{#isMaxlengthOrMaxword}}<div class="govuk-character-count" data-module="govuk-character-count"
2
+ {{#maxlength}}data-maxlength="{{maxlength}}" {{/maxlength}} {{#maxword}}data-maxwords="{{maxword}}" {{/maxword}}>
3
+ {{/isMaxlengthOrMaxword}}
4
+ <div id="{{id}}-group" class="govuk-form-group {{#formGroupClassName}}{{formGroupClassName}}{{/formGroupClassName}}{{#error}} govuk-form-group--error{{/error}}">
5
+ {{#isPageHeading}}<h1 class="govuk-label-wrapper">{{/isPageHeading}}
6
+ <label for="{{id}}"
7
+ class="{{labelClassName}}{{#isPageHeading}}govuk-label--l{{/isPageHeading}}">
8
+ {{{label}}}
9
+ {{#error}}
10
+ <p id="{{id}}-error" class="govuk-error-message">
11
+ <span id="{{id}}-error" class="govuk-visually-hidden">Error:</span>{{error.message}}
12
+ </p>
13
+ {{/error}}
14
+ </label>
15
+ {{#isPageHeading}}</h1>{{/isPageHeading}}
16
+ {{#hint}}<div {{$hintId}}id="{{hintId}}" {{/hintId}}class="govuk-hint">{{hint}}</div>{{/hint}}
17
+ {{#renderChild}}{{/renderChild}}
18
+ <textarea name="{{id}}" id="{{id}}"
19
+ class="govuk-textarea {{#isMaxlengthOrMaxword}}govuk-js-character-count{{/isMaxlengthOrMaxword}} {{#className}}{{className}}{{/className}} {{#error}}govuk-input--error{{/error}}"
20
+ aria-describedby="{{id}}-info"
21
+ {{#attributes}}
22
+ {{attribute}}="{{value}}"
23
+ {{/attributes}}
24
+ {{^error}}{{#hintId}}{{#maxlength}} aria-describedby="{{id}}-maxlength-hint {{hintId}}"{{/maxlength}}{{/hintId}}{{/error}}
25
+ {{^error}}{{#hintId}}{{^maxlength}} aria-describedby="{{hintId}}"{{/maxlength}}{{/hintId}}{{/error}}
26
+ {{^error}}{{^hintId}}{{#maxlength}}aria-describedby="{{id}}-maxlength-hint" {{/maxlength}}{{/hintId}}{{/error}}
27
+ {{#error}} aria-invalid="true" aria-describedby="{{id}}-error" {{/error}}
28
+ >{{value}}</textarea>
29
+ {{#isMaxlengthOrMaxword}}
30
+ <div id="{{id}}-info" class=" govuk-hint govuk-character-count__message" aria-live="polite">You have {{#maxlength}}{{maxlength}} characters{{/maxlength}}{{#maxword}}{{maxword}}
31
+ words{{/maxword}} remaining
32
+ </div>
33
+ {{/isMaxlengthOrMaxword}}
34
+ </div>
35
+ {{#isMaxlengthOrMaxword}}</div>{{/isMaxlengthOrMaxword}}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hof",
3
3
  "description": "A bootstrap for HOF projects",
4
- "version": "20.1.3",
4
+ "version": "20.1.4",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
7
7
  "author": "HomeOffice",
@@ -135,7 +135,7 @@
135
135
  "reporter": "spec",
136
136
  "require": "test/common.js",
137
137
  "recursive": "true",
138
- "timeout": "6000",
138
+ "timeout": "7000",
139
139
  "exit": "true"
140
140
  },
141
141
  "resolutions": {
@@ -16,9 +16,6 @@ module.exports = {
16
16
  },
17
17
  name: {
18
18
  validate: ['required', 'notUrl', { type: 'maxlength', arguments: 200 }],
19
- // need to remove this for the heading to go
20
- labelClassName: ['govuk-label--l'],
21
- isPageHeading: 'true'
22
19
  },
23
20
  'dateOfBirth': dateComponent('dateOfBirth', {
24
21
  mixin: 'input-date',
@@ -70,8 +67,6 @@ module.exports = {
70
67
  ]
71
68
  },
72
69
  email: {
73
- isPageHeading: 'true',
74
- labelClassName: ['govuk-label--l'],
75
70
  validate: ['required', 'email']
76
71
  },
77
72
  phone: {
@@ -95,11 +90,10 @@ module.exports = {
95
90
  mixin: 'textarea',
96
91
  // we want to ignore default formatters as we want
97
92
  // to preserve white space
98
- isPageHeading: 'true',
99
93
  'ignore-defaults': true,
100
94
  // apply the other default formatters
101
95
  formatter: ['trim', 'hyphens'],
102
- labelClassName: ['govuk-label--l'],
96
+ isPageHeading: 'true',
103
97
  // attributes here are passed to the field element
104
98
  validate: ['required', { type: 'maxlength', arguments: 10 }],
105
99
  attributes: [{
@@ -107,6 +101,21 @@ module.exports = {
107
101
  value: 8
108
102
  }]
109
103
  },
104
+ whatHappened: {
105
+ mixin: 'textarea',
106
+ // we want to ignore default formatters as we want
107
+ // to preserve white space
108
+ 'ignore-defaults': true,
109
+ // apply the other default formatters
110
+ formatter: ['trim', 'hyphens'],
111
+ isPageHeading: 'true',
112
+ // attributes here are passed to the field element
113
+ validate: ['required', { type: 'maxword', arguments: 10 }],
114
+ attributes: [{
115
+ attribute: 'rows',
116
+ value: 8
117
+ }]
118
+ },
110
119
  appealStages: {
111
120
  mixin: 'select',
112
121
  isPageHeading: 'true',
@@ -66,6 +66,10 @@ module.exports = {
66
66
  },
67
67
  '/text-input-area': {
68
68
  fields: ['complaintDetails'],
69
+ next: '/word-count'
70
+ },
71
+ '/word-count': {
72
+ fields: ['whatHappened'],
69
73
  next: '/select'
70
74
  },
71
75
  '/select':{
@@ -36,5 +36,8 @@ module.exports = {
36
36
  ],
37
37
  complaintDetails: [
38
38
  'complaintDetails'
39
+ ],
40
+ whatHappened: [
41
+ 'whatHappened'
39
42
  ]
40
43
  };
@@ -15,7 +15,7 @@
15
15
  }
16
16
  },
17
17
  "name": {
18
- "label": "What is your full name?"
18
+ "label": "Full name"
19
19
  },
20
20
  "dateOfBirth": {
21
21
  "legend": "What is your date of birth?",
@@ -70,7 +70,7 @@
70
70
  }
71
71
  },
72
72
  "email" : {
73
- "label": "Enter your email address"
73
+ "label": "Email address"
74
74
  },
75
75
  "phone": {
76
76
  "label": "Phone number",
@@ -83,6 +83,10 @@
83
83
  "label": "Complaint details",
84
84
  "hint": "Briefly summarise your complaint. Include anything that can help our investigation."
85
85
  },
86
+ "whatHappened": {
87
+ "label": "What happened",
88
+ "hint": "Briefly summarise what happened."
89
+ },
86
90
  "countrySelect": {
87
91
  "label": "Which country are you based in?",
88
92
  "hint": "Start to type the country name and options will appear"
@@ -10,6 +10,12 @@
10
10
  "header": "What is your address in the UK?",
11
11
  "intro": "If you have no fixed address, enter an address where we can contact you."
12
12
  },
13
+ "name": {
14
+ "header": "What is your full name?"
15
+ },
16
+ "email": {
17
+ "header": "Enter your email address"
18
+ },
13
19
  "phone-number": {
14
20
  "header": "Enter your phone number"
15
21
  },
@@ -36,6 +42,9 @@
36
42
  },
37
43
  "complaintDetails": {
38
44
  "header": "Complaint details"
45
+ },
46
+ "whatHappened": {
47
+ "header": "What happened"
39
48
  }
40
49
  }
41
50
  },
@@ -44,6 +44,10 @@
44
44
  "default": "Enter details about why you are making a complaint",
45
45
  "maxlength": "Keep to the {{maxlength}} character limit"
46
46
  },
47
+ "whatHappened": {
48
+ "default": "Enter details about what happened",
49
+ "maxword": "Keep to the {{maxword}} word limit"
50
+ },
47
51
  "appealStages": {
48
52
  "required": "Select an appeal stage from the list"
49
53
  }