govuk_tech_docs 2.2.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of govuk_tech_docs might be problematic. Click here for more details.

Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.nvmrc +1 -1
  4. data/.travis.yml +2 -0
  5. data/CHANGELOG.md +26 -1
  6. data/govuk_tech_docs.gemspec +3 -8
  7. data/lib/assets/javascripts/_modules/collapsible-navigation.js +7 -7
  8. data/lib/assets/javascripts/_modules/in-page-navigation.js +2 -4
  9. data/lib/assets/stylesheets/_govuk_tech_docs.scss +9 -10
  10. data/lib/assets/stylesheets/modules/_search.scss +8 -25
  11. data/lib/assets/stylesheets/modules/_technical-documentation.scss +1 -1
  12. data/lib/assets/stylesheets/modules/_toc.scss +11 -11
  13. data/lib/govuk_tech_docs/api_reference/api_reference_extension.rb +0 -1
  14. data/lib/govuk_tech_docs/api_reference/api_reference_renderer.rb +70 -186
  15. data/lib/govuk_tech_docs/api_reference/templates/api_reference_full.html.erb +3 -2
  16. data/lib/govuk_tech_docs/api_reference/templates/operation.html.erb +1 -1
  17. data/lib/govuk_tech_docs/api_reference/templates/parameters.html.erb +1 -1
  18. data/lib/govuk_tech_docs/api_reference/templates/responses.html.erb +1 -1
  19. data/lib/govuk_tech_docs/api_reference/templates/schema.html.erb +12 -12
  20. data/lib/govuk_tech_docs/table_of_contents/heading.rb +5 -1
  21. data/lib/govuk_tech_docs/table_of_contents/heading_tree_renderer.rb +2 -2
  22. data/lib/govuk_tech_docs/table_of_contents/helpers.rb +6 -3
  23. data/lib/govuk_tech_docs/tech_docs_html_renderer.rb +1 -1
  24. data/lib/govuk_tech_docs/version.rb +1 -1
  25. data/lib/source/layouts/_header.erb +6 -2
  26. data/lib/source/layouts/_search.erb +1 -1
  27. data/node_modules/govuk-frontend/govuk/_base.scss +3 -0
  28. data/node_modules/govuk-frontend/govuk/all.js +306 -94
  29. data/node_modules/govuk-frontend/govuk/all.scss +1 -3
  30. data/node_modules/govuk-frontend/govuk/components/_all.scss +33 -29
  31. data/node_modules/govuk-frontend/govuk/components/accordion/_accordion.scss +2 -208
  32. data/node_modules/govuk-frontend/govuk/components/accordion/_index.scss +197 -0
  33. data/node_modules/govuk-frontend/govuk/components/accordion/accordion.js +1 -1
  34. data/node_modules/govuk-frontend/govuk/components/back-link/_back-link.scss +2 -65
  35. data/node_modules/govuk-frontend/govuk/components/back-link/_index.scss +99 -0
  36. data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_breadcrumbs.scss +2 -118
  37. data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_index.scss +138 -0
  38. data/node_modules/govuk-frontend/govuk/components/button/_button.scss +2 -284
  39. data/node_modules/govuk-frontend/govuk/components/button/_index.scss +288 -0
  40. data/node_modules/govuk-frontend/govuk/components/character-count/_character-count.scss +2 -31
  41. data/node_modules/govuk-frontend/govuk/components/character-count/_index.scss +25 -0
  42. data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js +17 -9
  43. data/node_modules/govuk-frontend/govuk/components/checkboxes/_checkboxes.scss +2 -308
  44. data/node_modules/govuk-frontend/govuk/components/checkboxes/_index.scss +320 -0
  45. data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js +129 -24
  46. data/node_modules/govuk-frontend/govuk/components/cookie-banner/_cookie-banner.scss +2 -0
  47. data/node_modules/govuk-frontend/govuk/components/cookie-banner/_index.scss +51 -0
  48. data/node_modules/govuk-frontend/govuk/components/date-input/_date-input.scss +2 -30
  49. data/node_modules/govuk-frontend/govuk/components/date-input/_index.scss +26 -0
  50. data/node_modules/govuk-frontend/govuk/components/details/_details.scss +2 -88
  51. data/node_modules/govuk-frontend/govuk/components/details/_index.scss +87 -0
  52. data/node_modules/govuk-frontend/govuk/components/error-message/_error-message.scss +2 -15
  53. data/node_modules/govuk-frontend/govuk/components/error-message/_index.scss +11 -0
  54. data/node_modules/govuk-frontend/govuk/components/error-summary/_error-summary.scss +2 -59
  55. data/node_modules/govuk-frontend/govuk/components/error-summary/_index.scss +43 -0
  56. data/node_modules/govuk-frontend/govuk/components/fieldset/_fieldset.scss +2 -68
  57. data/node_modules/govuk-frontend/govuk/components/fieldset/_index.scss +64 -0
  58. data/node_modules/govuk-frontend/govuk/components/file-upload/_file-upload.scss +2 -81
  59. data/node_modules/govuk-frontend/govuk/components/file-upload/_index.scss +49 -0
  60. data/node_modules/govuk-frontend/govuk/components/footer/_footer.scss +2 -244
  61. data/node_modules/govuk-frontend/govuk/components/footer/_index.scss +241 -0
  62. data/node_modules/govuk-frontend/govuk/components/header/_header.scss +2 -318
  63. data/node_modules/govuk-frontend/govuk/components/header/_index.scss +331 -0
  64. data/node_modules/govuk-frontend/govuk/components/header/header.js +665 -316
  65. data/node_modules/govuk-frontend/govuk/components/hint/_hint.scss +2 -50
  66. data/node_modules/govuk-frontend/govuk/components/hint/_index.scss +44 -0
  67. data/node_modules/govuk-frontend/govuk/components/input/_index.scss +191 -0
  68. data/node_modules/govuk-frontend/govuk/components/input/_input.scss +2 -103
  69. data/node_modules/govuk-frontend/govuk/components/inset-text/_index.scss +24 -0
  70. data/node_modules/govuk-frontend/govuk/components/inset-text/_inset-text.scss +2 -28
  71. data/node_modules/govuk-frontend/govuk/components/label/_index.scss +41 -0
  72. data/node_modules/govuk-frontend/govuk/components/label/_label.scss +2 -45
  73. data/node_modules/govuk-frontend/govuk/components/notification-banner/_index.scss +89 -0
  74. data/node_modules/govuk-frontend/govuk/components/notification-banner/_notification-banner.scss +2 -0
  75. data/node_modules/govuk-frontend/govuk/components/notification-banner/notification-banner.js +61 -0
  76. data/node_modules/govuk-frontend/govuk/components/panel/_index.scss +44 -0
  77. data/node_modules/govuk-frontend/govuk/components/panel/_panel.scss +2 -44
  78. data/node_modules/govuk-frontend/govuk/components/phase-banner/_index.scss +27 -0
  79. data/node_modules/govuk-frontend/govuk/components/phase-banner/_phase-banner.scss +2 -31
  80. data/node_modules/govuk-frontend/govuk/components/radios/_index.scss +342 -0
  81. data/node_modules/govuk-frontend/govuk/components/radios/_radios.scss +2 -346
  82. data/node_modules/govuk-frontend/govuk/components/radios/radios.js +76 -28
  83. data/node_modules/govuk-frontend/govuk/components/select/_index.scss +49 -0
  84. data/node_modules/govuk-frontend/govuk/components/select/_select.scss +2 -57
  85. data/node_modules/govuk-frontend/govuk/components/skip-link/_index.scss +36 -0
  86. data/node_modules/govuk-frontend/govuk/components/skip-link/_skip-link.scss +2 -37
  87. data/node_modules/govuk-frontend/govuk/components/summary-list/_index.scss +145 -0
  88. data/node_modules/govuk-frontend/govuk/components/summary-list/_summary-list.scss +2 -157
  89. data/node_modules/govuk-frontend/govuk/components/table/_index.scss +71 -0
  90. data/node_modules/govuk-frontend/govuk/components/table/_table.scss +2 -54
  91. data/node_modules/govuk-frontend/govuk/components/tabs/_index.scss +130 -0
  92. data/node_modules/govuk-frontend/govuk/components/tabs/_tabs.scss +2 -142
  93. data/node_modules/govuk-frontend/govuk/components/tag/_index.scss +86 -0
  94. data/node_modules/govuk-frontend/govuk/components/tag/_tag.scss +2 -91
  95. data/node_modules/govuk-frontend/govuk/components/textarea/_index.scss +47 -0
  96. data/node_modules/govuk-frontend/govuk/components/textarea/_textarea.scss +2 -55
  97. data/node_modules/govuk-frontend/govuk/components/warning-text/_index.scss +66 -0
  98. data/node_modules/govuk-frontend/govuk/components/warning-text/_warning-text.scss +2 -60
  99. data/node_modules/govuk-frontend/govuk/core/_global-styles.scss +5 -3
  100. data/node_modules/govuk-frontend/govuk/core/_links.scss +13 -3
  101. data/node_modules/govuk-frontend/govuk/core/_lists.scss +17 -3
  102. data/node_modules/govuk-frontend/govuk/core/_section-break.scss +5 -3
  103. data/node_modules/govuk-frontend/govuk/core/_template.scss +5 -4
  104. data/node_modules/govuk-frontend/govuk/core/_typography.scss +5 -3
  105. data/node_modules/govuk-frontend/govuk/helpers/_clearfix.scss +1 -1
  106. data/node_modules/govuk-frontend/govuk/helpers/_colour.scss +1 -1
  107. data/node_modules/govuk-frontend/govuk/helpers/_device-pixels.scss +3 -3
  108. data/node_modules/govuk-frontend/govuk/helpers/_focused.scss +1 -1
  109. data/node_modules/govuk-frontend/govuk/helpers/_font-faces.scss +9 -11
  110. data/node_modules/govuk-frontend/govuk/helpers/_grid.scss +2 -1
  111. data/node_modules/govuk-frontend/govuk/helpers/_links.scss +246 -33
  112. data/node_modules/govuk-frontend/govuk/helpers/_media-queries.scss +2 -6
  113. data/node_modules/govuk-frontend/govuk/helpers/_shape-arrow.scss +1 -1
  114. data/node_modules/govuk-frontend/govuk/helpers/_spacing.scss +3 -2
  115. data/node_modules/govuk-frontend/govuk/helpers/_typography.scss +8 -7
  116. data/node_modules/govuk-frontend/govuk/helpers/_visually-hidden.scss +1 -1
  117. data/node_modules/govuk-frontend/govuk/objects/_all.scss +1 -0
  118. data/node_modules/govuk-frontend/govuk/objects/_button-group.scss +101 -0
  119. data/node_modules/govuk-frontend/govuk/objects/_form-group.scss +1 -4
  120. data/node_modules/govuk-frontend/govuk/objects/_grid.scss +3 -6
  121. data/node_modules/govuk-frontend/govuk/objects/_main-wrapper.scss +5 -4
  122. data/node_modules/govuk-frontend/govuk/objects/_width-container.scss +6 -4
  123. data/node_modules/govuk-frontend/govuk/overrides/_display.scss +6 -4
  124. data/node_modules/govuk-frontend/govuk/overrides/_spacing.scss +5 -3
  125. data/node_modules/govuk-frontend/govuk/overrides/_typography.scss +5 -3
  126. data/node_modules/govuk-frontend/govuk/overrides/_width.scss +6 -3
  127. data/node_modules/govuk-frontend/govuk/settings/_all.scss +2 -0
  128. data/node_modules/govuk-frontend/govuk/settings/_colours-applied.scss +11 -5
  129. data/node_modules/govuk-frontend/govuk/settings/_colours-organisations.scss +3 -0
  130. data/node_modules/govuk-frontend/govuk/settings/_colours-palette.scss +42 -35
  131. data/node_modules/govuk-frontend/govuk/settings/_compatibility.scss +0 -1
  132. data/node_modules/govuk-frontend/govuk/settings/_ie8.scss +1 -1
  133. data/node_modules/govuk-frontend/govuk/settings/_links.scss +62 -0
  134. data/node_modules/govuk-frontend/govuk/settings/_measurements.scss +4 -5
  135. data/node_modules/govuk-frontend/govuk/settings/_typography-font-families.scss +2 -2
  136. data/node_modules/govuk-frontend/govuk/settings/_typography-font.scss +14 -5
  137. data/node_modules/govuk-frontend/govuk/settings/_typography-responsive.scss +6 -2
  138. data/node_modules/govuk-frontend/govuk/tools/_compatibility.scss +1 -1
  139. data/node_modules/govuk-frontend/govuk/tools/_font-url.scss +1 -4
  140. data/node_modules/govuk-frontend/govuk/tools/_ie8.scss +1 -1
  141. data/node_modules/govuk-frontend/govuk/tools/_image-url.scss +1 -4
  142. data/node_modules/govuk-frontend/govuk/tools/_px-to-em.scss +1 -1
  143. data/node_modules/govuk-frontend/govuk/tools/_px-to-rem.scss +1 -1
  144. data/node_modules/govuk-frontend/govuk/utilities/_visually-hidden.scss +0 -1
  145. data/node_modules/govuk-frontend/govuk/vendor/_sass-mq.scss +0 -4
  146. data/package-lock.json +358 -288
  147. data/package.json +2 -2
  148. metadata +48 -67
@@ -1,346 +1,2 @@
1
- @import "../../settings/all";
2
- @import "../../tools/all";
3
- @import "../../helpers/all";
4
-
5
- @import "../error-message/error-message";
6
- @import "../fieldset/fieldset";
7
- @import "../hint/hint";
8
- @import "../label/label";
9
-
10
- @include govuk-exports("govuk/component/radios") {
11
-
12
- $govuk-touch-target-size: 44px;
13
- $govuk-radios-size: 40px;
14
- $govuk-small-radios-size: 24px;
15
- $govuk-radios-label-padding-left-right: govuk-spacing(3);
16
- // When the default focus width is used on a curved edge it looks visually smaller.
17
- // So for the circular radios we bump the default to make it look visually consistent.
18
- $govuk-radios-focus-width: $govuk-focus-width + 1px;
19
-
20
- .govuk-radios__item {
21
- @include govuk-font($size: 19);
22
-
23
- display: block;
24
- position: relative;
25
-
26
- min-height: $govuk-radios-size;
27
-
28
- margin-bottom: govuk-spacing(2);
29
- padding-left: $govuk-radios-size;
30
-
31
- clear: left;
32
- }
33
-
34
- .govuk-radios__item:last-child,
35
- .govuk-radios__item:last-of-type {
36
- margin-bottom: 0;
37
- }
38
-
39
- .govuk-radios__input {
40
- $input-offset: ($govuk-touch-target-size - $govuk-radios-size) / 2;
41
-
42
- cursor: pointer;
43
-
44
- // IE8 doesn’t support pseudo-elements, so we don’t want to hide native
45
- // elements there.
46
- @include govuk-not-ie8 {
47
- position: absolute;
48
-
49
- z-index: 1;
50
- top: $input-offset * -1;
51
- left: $input-offset * -1;
52
-
53
- width: $govuk-touch-target-size;
54
- height: $govuk-touch-target-size;
55
- margin: 0;
56
-
57
- opacity: 0;
58
- }
59
-
60
- @include govuk-if-ie8 {
61
- margin-top: 10px;
62
- margin-right: $govuk-radios-size / -2;
63
- margin-left: $govuk-radios-size / -2;
64
- float: left;
65
-
66
- // add focus outline to input
67
- &:focus {
68
- outline: $govuk-focus-width solid $govuk-focus-colour;
69
- }
70
- }
71
- }
72
-
73
- .govuk-radios__label {
74
- display: inline-block;
75
- margin-bottom: 0;
76
- padding: 8px $govuk-radios-label-padding-left-right govuk-spacing(1);
77
- cursor: pointer;
78
- // remove 300ms pause on mobile
79
- -ms-touch-action: manipulation;
80
- touch-action: manipulation;
81
- }
82
-
83
- // ( ) Radio ring
84
- .govuk-radios__label::before {
85
- content: "";
86
- box-sizing: border-box;
87
- position: absolute;
88
- top: 0;
89
- left: 0;
90
-
91
- width: $govuk-radios-size;
92
- height: $govuk-radios-size;
93
-
94
- border: $govuk-border-width-form-element solid currentColor;
95
- border-radius: 50%;
96
- background: transparent;
97
- }
98
-
99
- // • Radio button
100
- //
101
- // We create the 'button' entirely out of 'border' so that they remain
102
- // 'filled' even when colours are overridden in the browser.
103
- .govuk-radios__label::after {
104
- content: "";
105
-
106
- position: absolute;
107
- top: govuk-spacing(2);
108
- left: govuk-spacing(2);
109
-
110
- width: 0;
111
- height: 0;
112
-
113
- border: govuk-spacing(2) solid currentColor;
114
- border-radius: 50%;
115
- opacity: 0;
116
- background: currentColor;
117
- }
118
-
119
- .govuk-radios__hint {
120
- display: block;
121
- padding-right: $govuk-radios-label-padding-left-right;
122
- padding-left: $govuk-radios-label-padding-left-right;
123
- }
124
-
125
- // Focused state
126
- .govuk-radios__input:focus + .govuk-radios__label::before {
127
- border-width: 4px;
128
- box-shadow: 0 0 0 $govuk-radios-focus-width $govuk-focus-colour;
129
- }
130
-
131
- // Selected state
132
- .govuk-radios__input:checked + .govuk-radios__label::after {
133
- opacity: 1;
134
- }
135
-
136
- // Disabled state
137
- .govuk-radios__input:disabled,
138
- .govuk-radios__input:disabled + .govuk-radios__label {
139
- cursor: default;
140
- }
141
-
142
- .govuk-radios__input:disabled + .govuk-radios__label {
143
- opacity: .5;
144
- }
145
-
146
- // =========================================================
147
- // Inline radios
148
- // =========================================================
149
-
150
- .govuk-radios--inline {
151
- @include govuk-media-query ($from: tablet) {
152
- @include govuk-clearfix;
153
-
154
- .govuk-radios__item {
155
- margin-right: govuk-spacing(4);
156
- float: left;
157
- clear: none;
158
- }
159
- }
160
-
161
- // Prevent inline modifier being used with conditional reveals
162
- &.govuk-radios--conditional {
163
- .govuk-radios__item {
164
- margin-right: 0;
165
- float: none;
166
- }
167
- }
168
- }
169
-
170
- // =========================================================
171
- // Dividers ('or')
172
- // =========================================================
173
-
174
- .govuk-radios__divider {
175
- $govuk-divider-size: $govuk-radios-size !default;
176
- @include govuk-font($size: 19);
177
- @include govuk-text-colour;
178
- width: $govuk-divider-size;
179
- margin-bottom: govuk-spacing(2);
180
- text-align: center;
181
- }
182
-
183
- // =========================================================
184
- // Conditional reveals
185
- // =========================================================
186
-
187
- // The narrow border is used in the conditional reveals because the border has
188
- // to be an even number in order to be centred under the 40px checkbox or radio.
189
- $conditional-border-width: $govuk-border-width-narrow;
190
- // Calculate the amount of padding needed to keep the border centered against the radios.
191
- $conditional-border-padding: ($govuk-radios-size / 2) - ($conditional-border-width / 2);
192
- // Move the border centered with the radios
193
- $conditional-margin-left: $conditional-border-padding;
194
- // Move the contents of the conditional inline with the label
195
- $conditional-padding-left: $conditional-border-padding + $govuk-radios-label-padding-left-right;
196
-
197
- .govuk-radios__conditional {
198
- @include govuk-responsive-margin(4, "bottom");
199
- margin-left: $conditional-margin-left;
200
- padding-left: $conditional-padding-left;
201
- border-left: $conditional-border-width solid $govuk-border-colour;
202
-
203
- .js-enabled &--hidden {
204
- display: none;
205
- }
206
-
207
- & > :last-child {
208
- margin-bottom: 0;
209
- }
210
- }
211
-
212
- // =========================================================
213
- // Small checkboxes
214
- // =========================================================
215
-
216
- .govuk-radios--small {
217
-
218
- $input-offset: ($govuk-touch-target-size - $govuk-small-radios-size) / 2;
219
- $label-offset: $govuk-touch-target-size - $input-offset;
220
-
221
- .govuk-radios__item {
222
- @include govuk-clearfix;
223
- min-height: 0;
224
- margin-bottom: 0;
225
- padding-left: $label-offset;
226
- float: left;
227
- }
228
-
229
- // Shift the touch target into the left margin so that the visible edge of
230
- // the control is aligned
231
- //
232
- // ┆Which colour is your favourite?
233
- // ┌┆───┐
234
- // │┆() │ Purple
235
- // └┆▲──┘
236
- // ▲┆└─ Radio pseudo element, aligned with margin
237
- // └─── Touch target (invisible input), shifted into the margin
238
- .govuk-radios__input {
239
- @include govuk-not-ie8 {
240
- left: $input-offset * -1;
241
- }
242
-
243
- @include govuk-if-ie8 {
244
- margin-left: $govuk-small-radios-size * -1;
245
- }
246
- }
247
-
248
- // Adjust the size and position of the label.
249
- //
250
- // Unlike larger radios, we also have to float the label in order to
251
- // 'shrink' it, preventing the hover state from kicking in across the full
252
- // width of the parent element.
253
- .govuk-radios__label {
254
- margin-top: -2px;
255
- padding: 13px govuk-spacing(3) 13px 1px;
256
- float: left;
257
-
258
- @include govuk-media-query($from: tablet) {
259
- padding: 11px govuk-spacing(3) 10px 1px;
260
- }
261
- }
262
-
263
- // ( ) Radio ring
264
- //
265
- // Reduce the size of the control [1], vertically centering it within the
266
- // touch target [2]
267
- .govuk-radios__label::before {
268
- top: $input-offset - $govuk-border-width-form-element; // 2
269
- width: $govuk-small-radios-size; // 1
270
- height: $govuk-small-radios-size; // 1
271
- }
272
-
273
- // • Radio button
274
- //
275
- // Reduce the size of the 'button' and center it within the ring
276
- .govuk-radios__label::after {
277
- top: 15px;
278
- left: 7px;
279
- border-width: 5px;
280
- }
281
-
282
- // Fix position of hint with small radios
283
- //
284
- // Do not use hints with small radios – because they're within the input
285
- // wrapper they trigger the hover state, but clicking them doesn't actually
286
- // activate the control.
287
- //
288
- // (If you do use them, they won't look completely broken... but seriously,
289
- // don't use them)
290
- .govuk-radios__hint {
291
- padding: 0;
292
- clear: both;
293
- pointer-events: none;
294
- }
295
-
296
- // Align conditional reveals with small radios
297
- .govuk-radios__conditional {
298
- $margin-left: ($govuk-small-radios-size / 2) - ($conditional-border-width / 2);
299
- margin-left: $margin-left;
300
- padding-left: $label-offset - ($margin-left + $conditional-border-width);
301
- clear: both;
302
- }
303
-
304
- .govuk-radios__divider {
305
- width: $govuk-small-radios-size;
306
- margin-bottom: govuk-spacing(1);
307
- }
308
-
309
- // Hover state for small radios.
310
- //
311
- // We use a hover state for small radios because the touch target size
312
- // is so much larger than their visible size, and so we need to provide
313
- // feedback to the user as to which radio they will select when their
314
- // cursor is outside of the visible area.
315
- .govuk-radios__item:hover .govuk-radios__input:not(:disabled) + .govuk-radios__label::before {
316
- box-shadow: 0 0 0 $govuk-hover-width $govuk-hover-colour;
317
- }
318
-
319
- // Because we've overridden the border-shadow provided by the focus state,
320
- // we need to redefine that too.
321
- //
322
- // We use two box shadows, one that restores the original focus state [1]
323
- // and another that then applies the hover state [2].
324
- .govuk-radios__item:hover .govuk-radios__input:focus + .govuk-radios__label::before {
325
- // sass-lint:disable indentation
326
- box-shadow: 0 0 0 $govuk-radios-focus-width $govuk-focus-colour, // 1
327
- 0 0 0 $govuk-hover-width $govuk-hover-colour; // 2
328
- }
329
-
330
- // For devices that explicitly don't support hover, don't provide a hover
331
- // state (e.g. on touch devices like iOS).
332
- //
333
- // We can't use `@media (hover: hover)` because we wouldn't get the hover
334
- // state in browsers that don't support `@media (hover)` (like Internet
335
- // Explorer) – so we have to 'undo' the hover state instead.
336
- @media (hover: none), (pointer: coarse) {
337
- .govuk-radios__item:hover .govuk-radios__input:not(:disabled) + .govuk-radios__label::before {
338
- box-shadow: initial;
339
- }
340
-
341
- .govuk-radios__item:hover .govuk-radios__input:focus + .govuk-radios__label::before {
342
- box-shadow: 0 0 0 $govuk-radios-focus-width $govuk-focus-colour;
343
- }
344
- }
345
- }
346
- }
1
+ @import "../../base";
2
+ @import "./index";
@@ -1030,67 +1030,115 @@ function nodeListForEach (nodes, callback) {
1030
1030
 
1031
1031
  function Radios ($module) {
1032
1032
  this.$module = $module;
1033
+ this.$inputs = $module.querySelectorAll('input[type="radio"]');
1033
1034
  }
1034
1035
 
1036
+ /**
1037
+ * Initialise Radios
1038
+ *
1039
+ * Radios can be associated with a 'conditionally revealed' content block – for
1040
+ * example, a radio for 'Phone' could reveal an additional form field for the
1041
+ * user to enter their phone number.
1042
+ *
1043
+ * These associations are made using a `data-aria-controls` attribute, which is
1044
+ * promoted to an aria-controls attribute during initialisation.
1045
+ *
1046
+ * We also need to restore the state of any conditional reveals on the page (for
1047
+ * example if the user has navigated back), and set up event handlers to keep
1048
+ * the reveal in sync with the radio state.
1049
+ */
1035
1050
  Radios.prototype.init = function () {
1036
1051
  var $module = this.$module;
1037
- var $inputs = $module.querySelectorAll('input[type="radio"]');
1052
+ var $inputs = this.$inputs;
1038
1053
 
1039
- /**
1040
- * Loop over all items with [data-controls]
1041
- * Check if they have a matching conditional reveal
1042
- * If they do, assign attributes.
1043
- **/
1044
1054
  nodeListForEach($inputs, function ($input) {
1045
- var controls = $input.getAttribute('data-aria-controls');
1055
+ var target = $input.getAttribute('data-aria-controls');
1046
1056
 
1047
- // Check if input controls anything
1048
- // Check if content exists, before setting attributes.
1049
- if (!controls || !$module.querySelector('#' + controls)) {
1057
+ // Skip radios without data-aria-controls attributes, or where the
1058
+ // target element does not exist.
1059
+ if (!target || !$module.querySelector('#' + target)) {
1050
1060
  return
1051
1061
  }
1052
1062
 
1053
- // If we have content that is controlled, set attributes.
1054
- $input.setAttribute('aria-controls', controls);
1063
+ // Promote the data-aria-controls attribute to a aria-controls attribute
1064
+ // so that the relationship is exposed in the AOM
1065
+ $input.setAttribute('aria-controls', target);
1055
1066
  $input.removeAttribute('data-aria-controls');
1056
- this.setAttributes($input);
1057
- }.bind(this));
1067
+ });
1068
+
1069
+ // When the page is restored after navigating 'back' in some browsers the
1070
+ // state of form controls is not restored until *after* the DOMContentLoaded
1071
+ // event is fired, so we need to sync after the pageshow event in browsers
1072
+ // that support it.
1073
+ if ('onpageshow' in window) {
1074
+ window.addEventListener('pageshow', this.syncAllConditionalReveals.bind(this));
1075
+ } else {
1076
+ window.addEventListener('DOMContentLoaded', this.syncAllConditionalReveals.bind(this));
1077
+ }
1078
+
1079
+ // Although we've set up handlers to sync state on the pageshow or
1080
+ // DOMContentLoaded event, init could be called after those events have fired,
1081
+ // for example if they are added to the page dynamically, so sync now too.
1082
+ this.syncAllConditionalReveals();
1058
1083
 
1059
1084
  // Handle events
1060
1085
  $module.addEventListener('click', this.handleClick.bind(this));
1061
1086
  };
1062
1087
 
1063
- Radios.prototype.setAttributes = function ($input) {
1064
- var $content = document.querySelector('#' + $input.getAttribute('aria-controls'));
1088
+ /**
1089
+ * Sync the conditional reveal states for all inputs in this $module.
1090
+ */
1091
+ Radios.prototype.syncAllConditionalReveals = function () {
1092
+ nodeListForEach(this.$inputs, this.syncConditionalRevealWithInputState.bind(this));
1093
+ };
1065
1094
 
1066
- if ($content && $content.classList.contains('govuk-radios__conditional')) {
1095
+ /**
1096
+ * Sync conditional reveal with the input state
1097
+ *
1098
+ * Synchronise the visibility of the conditional reveal, and its accessible
1099
+ * state, with the input's checked state.
1100
+ *
1101
+ * @param {HTMLInputElement} $input Radio input
1102
+ */
1103
+ Radios.prototype.syncConditionalRevealWithInputState = function ($input) {
1104
+ var $target = document.querySelector('#' + $input.getAttribute('aria-controls'));
1105
+
1106
+ if ($target && $target.classList.contains('govuk-radios__conditional')) {
1067
1107
  var inputIsChecked = $input.checked;
1068
1108
 
1069
1109
  $input.setAttribute('aria-expanded', inputIsChecked);
1070
-
1071
- $content.classList.toggle('govuk-radios__conditional--hidden', !inputIsChecked);
1110
+ $target.classList.toggle('govuk-radios__conditional--hidden', !inputIsChecked);
1072
1111
  }
1073
1112
  };
1074
1113
 
1114
+ /**
1115
+ * Click event handler
1116
+ *
1117
+ * Handle a click within the $module – if the click occurred on a radio, sync
1118
+ * the state of the conditional reveal for all radio buttons in the same form
1119
+ * with the same name (because checking one radio could have un-checked a radio
1120
+ * in another $module)
1121
+ *
1122
+ * @param {MouseEvent} event Click event
1123
+ */
1075
1124
  Radios.prototype.handleClick = function (event) {
1076
1125
  var $clickedInput = event.target;
1077
- // We only want to handle clicks for radio inputs
1126
+
1127
+ // Ignore clicks on things that aren't radio buttons
1078
1128
  if ($clickedInput.type !== 'radio') {
1079
1129
  return
1080
1130
  }
1081
- // Because checking one radio can uncheck a radio in another $module,
1082
- // we need to call set attributes on all radios in the same form, or document if they're not in a form.
1083
- //
1084
- // We also only want radios which have aria-controls, as they support conditional reveals.
1131
+
1132
+ // We only need to consider radios with conditional reveals, which will have
1133
+ // aria-controls attributes.
1085
1134
  var $allInputs = document.querySelectorAll('input[type="radio"][aria-controls]');
1135
+
1086
1136
  nodeListForEach($allInputs, function ($input) {
1087
- // Only inputs with the same form owner should change.
1088
1137
  var hasSameFormOwner = ($input.form === $clickedInput.form);
1089
-
1090
- // In radios, only radios with the same name will affect each other.
1091
1138
  var hasSameName = ($input.name === $clickedInput.name);
1139
+
1092
1140
  if (hasSameName && hasSameFormOwner) {
1093
- this.setAttributes($input);
1141
+ this.syncConditionalRevealWithInputState($input);
1094
1142
  }
1095
1143
  }.bind(this));
1096
1144
  };