govuk_publishing_components 25.1.0 → 25.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/components/layout-super-navigation-header.js +234 -40
  3. data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js +6 -0
  4. data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +580 -41
  5. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_charts.scss +5 -0
  6. data/app/views/govuk_publishing_components/components/_layout_for_public.html.erb +1 -1
  7. data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +244 -63
  8. data/config/locales/ar.yml +5 -3
  9. data/config/locales/az.yml +5 -3
  10. data/config/locales/be.yml +5 -3
  11. data/config/locales/bg.yml +5 -3
  12. data/config/locales/bn.yml +5 -3
  13. data/config/locales/cs.yml +5 -3
  14. data/config/locales/cy.yml +8 -6
  15. data/config/locales/da.yml +5 -3
  16. data/config/locales/de.yml +5 -3
  17. data/config/locales/dr.yml +5 -3
  18. data/config/locales/el.yml +5 -3
  19. data/config/locales/en.yml +87 -83
  20. data/config/locales/es-419.yml +5 -3
  21. data/config/locales/es.yml +5 -3
  22. data/config/locales/et.yml +5 -3
  23. data/config/locales/fa.yml +5 -3
  24. data/config/locales/fi.yml +5 -3
  25. data/config/locales/fr.yml +5 -3
  26. data/config/locales/gd.yml +5 -3
  27. data/config/locales/gu.yml +5 -3
  28. data/config/locales/he.yml +5 -3
  29. data/config/locales/hi.yml +5 -3
  30. data/config/locales/hr.yml +5 -3
  31. data/config/locales/hu.yml +5 -3
  32. data/config/locales/hy.yml +5 -3
  33. data/config/locales/id.yml +5 -3
  34. data/config/locales/is.yml +5 -3
  35. data/config/locales/it.yml +5 -3
  36. data/config/locales/ja.yml +5 -3
  37. data/config/locales/ka.yml +5 -3
  38. data/config/locales/kk.yml +5 -3
  39. data/config/locales/ko.yml +5 -3
  40. data/config/locales/lt.yml +5 -3
  41. data/config/locales/lv.yml +5 -3
  42. data/config/locales/ms.yml +5 -3
  43. data/config/locales/mt.yml +5 -3
  44. data/config/locales/nl.yml +5 -3
  45. data/config/locales/no.yml +5 -3
  46. data/config/locales/pa-pk.yml +5 -3
  47. data/config/locales/pa.yml +5 -3
  48. data/config/locales/pl.yml +5 -3
  49. data/config/locales/ps.yml +5 -3
  50. data/config/locales/pt.yml +5 -3
  51. data/config/locales/ro.yml +5 -3
  52. data/config/locales/ru.yml +5 -3
  53. data/config/locales/si.yml +5 -3
  54. data/config/locales/sk.yml +5 -3
  55. data/config/locales/sl.yml +5 -3
  56. data/config/locales/so.yml +5 -3
  57. data/config/locales/sq.yml +5 -3
  58. data/config/locales/sr.yml +5 -3
  59. data/config/locales/sv.yml +5 -3
  60. data/config/locales/sw.yml +5 -3
  61. data/config/locales/ta.yml +5 -3
  62. data/config/locales/th.yml +5 -3
  63. data/config/locales/tk.yml +5 -3
  64. data/config/locales/tr.yml +5 -3
  65. data/config/locales/uk.yml +5 -3
  66. data/config/locales/ur.yml +5 -3
  67. data/config/locales/uz.yml +5 -3
  68. data/config/locales/vi.yml +5 -3
  69. data/config/locales/zh-hk.yml +5 -3
  70. data/config/locales/zh-tw.yml +5 -3
  71. data/config/locales/zh.yml +5 -3
  72. data/lib/govuk_publishing_components/version.rb +1 -1
  73. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83542c59d80d443eb01ea0451640ef185c26104d231d603a9842fb05b55bb26c
4
- data.tar.gz: e9cd38b7ca3a3430c63c212a12b1a9444579175d6c9ef55693d5b0c373c8108b
3
+ metadata.gz: 30b1c979671a113e33ce87e4db1b19cbd0b26d2c64a6f1f4a98da31c24ac6294
4
+ data.tar.gz: 8c1a5fa5e9d9fa2f78adb033a0409deb8a6da43f6149b8b6f2f041b4cc859809
5
5
  SHA512:
6
- metadata.gz: fcabb52ef323f944b938498968946e797e6c3b868393768fa42bd5fa350206e381d0d612bf9d158f6d6c00ed226aa7f89a4b737ba7a6acc32a390d4ef967d3a6
7
- data.tar.gz: 1c79526993a09351120f3459a5096e9e95974fc35557e031607e52babdb9099115b61462adc6e7b712d04300688a19ce35478d217323d60beae29ad839cc38a6
6
+ metadata.gz: 591e1edddd512c62aa2c7948b7e901c23842f06fc518ef1e2b24277af9ac933044d274f353d1e0d1ad8bb5e8b0ce92fe33989e059cf77288c9aaec86f7d19e47
7
+ data.tar.gz: 891a548c447d50c57b464ff8244b75f8f069655555f45b71568708350b608dc606f1956de61fc67542856c6e1087e1eb5dcd66dacb60179350f9483efc6c52c2
@@ -4,68 +4,262 @@ window.GOVUK = window.GOVUK || {}
4
4
  window.GOVUK.Modules = window.GOVUK.Modules || {};
5
5
 
6
6
  (function (Modules) {
7
- function SuperNavigationToggle ($module) {
8
- this.$module = $module
7
+ var SETTINGS = {
8
+ breakpoint: {
9
+ desktop: 769
10
+ },
11
+ label: {
12
+ hide: 'data-text-for-hide',
13
+ show: 'data-text-for-show'
14
+ }
15
+ }
9
16
 
10
- this.showMenuText = $module.getAttribute('data-text-for-show-menu')
11
- this.hideMenuText = $module.getAttribute('data-text-for-hide-menu')
12
- this.buttonText = $module.getAttribute('data-text-for-button')
17
+ // Small helpers that update the label when the state of the button has
18
+ // changed:
19
+ var setLabel = function ($button, showOrHide) {
20
+ var newLabel = $button.getAttribute(SETTINGS.label[showOrHide])
13
21
 
14
- this.$button = this.setupButton($module)
22
+ if (newLabel) {
23
+ $button.setAttribute('aria-label', newLabel)
24
+ }
25
+ }
15
26
 
16
- this.$menu = document.getElementById(this.$button.getAttribute('aria-controls'))
27
+ // Wrapper functions to contain all of the mechanisms needed for hiding and
28
+ // toggling the menus.
29
+ var hide = function ($button, $menu) {
30
+ $button.setAttribute('aria-expanded', false)
31
+ $button.classList.remove('gem-c-layout-super-navigation-header__open-button')
32
+ $menu.setAttribute('hidden', 'hidden')
33
+ setLabel($button, 'show')
34
+ }
35
+ var show = function ($button, $menu) {
36
+ $button.setAttribute('aria-expanded', true)
37
+ $button.classList.add('gem-c-layout-super-navigation-header__open-button')
38
+ $menu.removeAttribute('hidden')
39
+ setLabel($button, 'hide')
40
+ }
17
41
 
18
- this.syncStatus()
42
+ var toggle = function ($button, $menu) {
43
+ var isOpen = $button.getAttribute('aria-expanded') === 'true'
44
+ var trackingLabel = $button.getAttribute('data-tracking-key')
45
+ if (isOpen) {
46
+ hide($button, $menu)
47
+ } else {
48
+ show($button, $menu)
49
+ }
50
+
51
+ // Fire analytics if analytics are available
52
+ if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent && trackingLabel) {
53
+ window.GOVUK.analytics.trackEvent('headerClicked', trackingLabel + (isOpen ? 'Closed' : 'Opened'), { label: 'none' })
54
+ }
55
+ }
56
+
57
+ // Clicking an element inside a `button` element causes the `event.target` to
58
+ // be the inside element, not the button. This can be taken care of by setting
59
+ // the CSS pointer-events to be none, but that doesn't work for older
60
+ // browsers, won't work for people with CSS turned off, or for people who are
61
+ // using CSS overrides.
62
+ // This checks if the $element is the `elementType`; if it is, it gets
63
+ // returned; if not it recursively checks to see if the parent element is a
64
+ // `elementType`. This means that it can be used with `pointer-events: none`.
65
+ var closestParentIncluding = function ($element, elementType) {
66
+ if ($element.tagName.toLowerCase() === elementType.toLowerCase()) {
67
+ return $element
68
+ }
69
+ return closestParentIncluding($element.parentNode, elementType)
19
70
  }
20
71
 
21
- SuperNavigationToggle.prototype.setupButton = function (target) {
22
- var menuHeading = target.getAttribute('aria-labelledby')
23
- var adjacentTo = target.querySelector('#' + menuHeading)
24
- var buttonText = document.createTextNode(this.buttonText)
72
+ // Searched the previous elements to find one with the same tag as set in
73
+ // `elementType` . If it's found the element is returned; if not, it returns
74
+ // null.
75
+ var closestPrevious = function ($element, elementType) {
76
+ if ($element === null) {
77
+ return null
78
+ }
25
79
 
26
- var button = document.createElement('button')
27
- button.type = 'button'
28
- button.className = 'govuk-header__menu-button gem-c-layout-super-navigation-header__menu-button'
29
- button.setAttribute('aria-controls', 'super-navigation-menu')
30
- button.setAttribute('aria-label', this.showMenuText)
31
- button.setAttribute('aria-expanded', false)
80
+ // Using `previousSibling` means that there is a possibility that the
81
+ // $element could be a text node or a comment node - checking the `nodeType`
82
+ // of the element will ensure that it's a real element.
83
+ if ($element.nodeType === 1 && $element.tagName.toLowerCase() === elementType.toLowerCase()) {
84
+ return $element
85
+ }
32
86
 
33
- button.appendChild(buttonText)
34
- adjacentTo.insertAdjacentElement('beforebegin', button)
87
+ // If `previousElementSibling` can be used then let's use it as it'll be
88
+ // slightly faster since it skips things that aren't elements. If not,
89
+ // `previousSibling` can still be used as there's a `nodeType` check.
90
+ var previousElement = $element.previousElementSibling || $element.previousSibling
35
91
 
36
- return button
92
+ return closestPrevious(previousElement, elementType)
37
93
  }
38
94
 
39
- SuperNavigationToggle.prototype.syncStatus = function () {
40
- this.status = this.$button.getAttribute('aria-expanded') === 'true' ? 'open' : 'closed'
95
+ // When moving from one screen size to another (eg mobile to desktop) we need
96
+ // to find out whether a submenu is open so the parent menu can be kept open.
97
+ var hasSubMenusOpen = function ($menu) {
98
+ return $menu.querySelectorAll('button[aria-expanded="true"]').length > 0
41
99
  }
42
100
 
43
- SuperNavigationToggle.prototype.closeMenu = function () {
44
- this.$menu.classList.remove('gem-c-layout-super-navigation-header__items--open')
101
+ // Returns what screen size the window is currently. Returns a string of
102
+ // either `desktop` or `mobile` so it can be interpolated to access the
103
+ // `data-toggle-{desktop|mobile}-group` attribute.
104
+ var windowSize = function () {
105
+ return window.innerWidth >= SETTINGS.breakpoint.desktop ? 'desktop' : 'mobile'
106
+ }
45
107
 
46
- this.$button.classList.remove('govuk-header__menu-button--open')
47
- this.$button.setAttribute('aria-expanded', false)
48
- this.$button.setAttribute('aria-label', this.showMenuText)
108
+ function SuperNavigationMegaMenu ($module) {
109
+ this.$module = $module
110
+ this.$navigationToggle = this.$module.querySelector('#super-navigation-menu-toggle')
111
+ this.$navigationMenu = this.$module.querySelector('#super-navigation-menu')
112
+ this.$searchToggle = this.$module.querySelector('#super-search-menu-toggle')
113
+ this.$searchMenu = this.$module.querySelector('#super-search-menu')
114
+
115
+ // The menu toggler buttons need three attributes for this to work:
116
+ // - `aria-controls` contains the id of the menu to be toggled
117
+ // - `data-toggle-mobile-group` is the group that the menu belongs to on
118
+ // smaller screens
119
+ // - `data-toggle-desktop-group` is the group that the menu belongs to on
120
+ // larger screens
121
+ this.$buttons = this.$module.querySelectorAll(
122
+ 'button[aria-controls][data-toggle-mobile-group][data-toggle-desktop-group]'
123
+ )
124
+
125
+ this.hiddenButtons = this.$module.querySelectorAll('button[hidden]')
126
+
127
+ this.lastWindowSize = undefined
49
128
  }
50
129
 
51
- SuperNavigationToggle.prototype.openMenu = function () {
52
- this.$menu.classList.add('gem-c-layout-super-navigation-header__items--open')
130
+ SuperNavigationMegaMenu.prototype.windowSize = windowSize
53
131
 
54
- this.$button.classList.add('govuk-header__menu-button--open')
55
- this.$button.setAttribute('aria-expanded', true)
56
- this.$button.setAttribute('aria-label', this.hideMenuText)
132
+ // Resizes the space needed for the dropdown menu so that it doesn't overlap
133
+ // with the page content. As this is an event that needs to be added and
134
+ // removed it can't be be bound to `this` because that changes the fingerprint
135
+ // of the function, and makes it unable to be removed with
136
+ // `removeEventListener`.
137
+ SuperNavigationMegaMenu.prototype.resizeHandler = function () {
138
+ var $module = document.querySelector('[data-module="super-navigation-mega-menu"]')
139
+ var $openButton = $module.querySelector('[aria-expanded="true"][data-toggle-desktop-group="top"]')
140
+ var $openMenu = $openButton ? $module.querySelector('#' + $openButton.getAttribute('aria-controls')) : null
141
+ var margin = $openMenu && windowSize() === 'desktop' ? $openMenu.offsetHeight : 0
142
+
143
+ $module.style.marginBottom = margin + 'px'
57
144
  }
58
145
 
59
- SuperNavigationToggle.prototype.handleToggle = function () {
60
- if (this.status === 'open') this.closeMenu()
61
- if (this.status === 'closed') this.openMenu()
146
+ SuperNavigationMegaMenu.prototype.updateStates = function () {
147
+ if (this.windowSize() === 'mobile' && this.lastWindowSize !== 'mobile') {
148
+ this.$navigationToggle.removeAttribute('hidden')
149
+
150
+ // Hides navigation menu unless a submenu is open - this could be common
151
+ // as the desktop view has the navigation submenu as top level in the
152
+ // menu.
153
+ if (!hasSubMenusOpen(this.$navigationMenu)) {
154
+ hide(this.$navigationToggle, this.$navigationMenu)
155
+ }
156
+
157
+ this.$module.style.marginBottom = '0'
158
+
159
+ window.removeEventListener('resize', this.resizeHandler, { passive: true })
62
160
 
63
- this.syncStatus()
161
+ this.lastWindowSize = this.windowSize()
162
+ }
163
+
164
+ // Hide the navigation toggle button and show the navigation submenu:
165
+ if (this.windowSize() === 'desktop' && this.lastWindowSize !== 'desktop') {
166
+ this.$navigationToggle.setAttribute('hidden', 'hidden')
167
+ this.$navigationMenu.removeAttribute('hidden')
168
+
169
+ window.addEventListener('resize', this.resizeHandler, { passive: true })
170
+
171
+ this.lastWindowSize = this.windowSize()
172
+ }
173
+ }
174
+
175
+ SuperNavigationMegaMenu.prototype.buttonHandler = function (event) {
176
+ var $target = closestParentIncluding(event.target, 'button')
177
+ var $targetMenu = this.$module.querySelector('#' + $target.getAttribute('aria-controls'))
178
+
179
+ var toggleGroupAttribute = 'data-toggle-' + this.windowSize() + '-group'
180
+ var toggleGroupName = $target.getAttribute(toggleGroupAttribute)
181
+ var toggleGroupList = this.$module.querySelectorAll('[' + toggleGroupAttribute + '="' + toggleGroupName + '"]')
182
+
183
+ for (var k = 0; k < toggleGroupList.length; k++) {
184
+ var $element = toggleGroupList[k]
185
+ if ($element !== $target) {
186
+ var $menu = this.$module.querySelector('#' + $element.getAttribute('aria-controls'))
187
+ hide($element, $menu)
188
+ }
189
+ }
190
+
191
+ toggle($target, $targetMenu)
192
+
193
+ if (this.windowSize() === 'desktop') {
194
+ this.$module.style.marginBottom = $targetMenu.offsetHeight + 'px'
195
+ }
64
196
  }
65
197
 
66
- SuperNavigationToggle.prototype.init = function () {
67
- this.$button.addEventListener('click', this.handleToggle.bind(this))
198
+ SuperNavigationMegaMenu.prototype.init = function () {
199
+ for (var j = 0; j < this.$buttons.length; j++) {
200
+ var $button = this.$buttons[j]
201
+ $button.addEventListener('click', this.buttonHandler.bind(this), true)
202
+ }
203
+
204
+ // The toggle buttons are hardcoded to be hidden in the markup - this means
205
+ // that people without JavaScript turned on won't have buttons present that
206
+ // don't do anything.
207
+ // Since JavaScript is enabled we can remove the hidden attribute from
208
+ // the buttons so that they're perceivable by users.
209
+ // As the toggle buttons are now selectable, we should prevent the links
210
+ // from being selectable to avoid confusion.
211
+ for (var i = 0; i < this.hiddenButtons.length; i++) {
212
+ var $element = this.hiddenButtons[i]
213
+ $element.removeAttribute('hidden')
214
+
215
+ var closestSiblingLink = closestPrevious($element, 'a')
216
+ if (closestSiblingLink) {
217
+ closestSiblingLink.setAttribute('hidden', 'hidden')
218
+ }
219
+ }
220
+
221
+ this.$module.querySelector('.gem-c-layout-super-navigation-header__search-item-link')
222
+ .setAttribute('hidden', 'hidden')
223
+
224
+ // Navigation menu and search menu are hardcoded to be open in the markup -
225
+ // this means that the menu still makes sense with CSS and JavaScript turned
226
+ // off.
227
+ // The menus now need to be hidden as part of the JavaScript
228
+ // initialisation.
229
+ // - On both mobile and desktop, this means hiding the search menu
230
+ // - On mobile, this means hiding the navigation
231
+ // - On desktop, this means hiding the navigation button, showing the
232
+ // second level navigation menu
233
+ hide(this.$searchToggle, this.$searchMenu)
234
+ this.updateStates()
235
+
236
+ this.lastWindowSize = this.windowSize()
237
+
238
+ // The menu needs to be updated when the window is resized - specifically,
239
+ // the top level navigation toggle needs to be shown or hidden.
240
+ // Using `matchMedia` to listen for both resize events means that this
241
+ // will only fire when the media query is matched so is more efficient. The
242
+ // fallback is the `window.resize` event with a check to make sure that it
243
+ // only does things when moving from mobile to desktop view.
244
+ var setupResizeListener = function () {
245
+ window.addEventListener('resize', this.updateStates.bind(this), { passive: true })
246
+ }.bind(this)
247
+
248
+ if (typeof window.matchMedia === 'function') {
249
+ // Internet Explorer 11 supports `matchMedia`, but doesn't support
250
+ // the `change` event[1] - so we try it, and then fail back to using
251
+ // `window.resize`.
252
+ // [1]: https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/onchange
253
+ try {
254
+ window.matchMedia('screen and (min-width:' + SETTINGS.breakpoint.desktop + 'px)')
255
+ .addEventListener('change', this.updateStates.bind(this))
256
+ } catch (error) {
257
+ setupResizeListener()
258
+ }
259
+ } else {
260
+ setupResizeListener()
261
+ }
68
262
  }
69
263
 
70
- Modules.SuperNavigationToggle = SuperNavigationToggle
264
+ Modules.SuperNavigationMegaMenu = SuperNavigationMegaMenu
71
265
  })(window.GOVUK.Modules)
@@ -9,9 +9,15 @@
9
9
 
10
10
  YoutubeLinkEnhancement.prototype.init = function () {
11
11
  if (!this.campaignCookiesAllowed()) {
12
+ this.startModule = this.startModule.bind(this)
13
+ window.addEventListener('cookie-consent', this.startModule)
12
14
  return
13
15
  }
16
+ this.startModule()
17
+ }
14
18
 
19
+ YoutubeLinkEnhancement.prototype.startModule = function () {
20
+ window.removeEventListener('cookie-consent', this.startModule)
15
21
  var $youtubeLinks = this.$element.querySelectorAll('a[href*="youtube.com"], a[href*="youtu.be"]')
16
22
 
17
23
  if ($youtubeLinks.length > 0) {
@@ -1,8 +1,185 @@
1
1
  $search-icon-size: 20px;
2
2
 
3
+ @mixin chevron($colour) {
4
+ border-bottom: .2rem solid govuk-colour($colour);
5
+ border-right: .2rem solid govuk-colour($colour);
6
+ content: " ";
7
+ display: inline-block;
8
+ height: .5rem;
9
+ margin: 0 .5em 0 .15em;
10
+ transform: translateY(-35%) rotate(45deg);
11
+ vertical-align: middle;
12
+ width: .5rem;
13
+ }
14
+
15
+ %top-level-navigation-link-base {
16
+ background: none;
17
+ @include govuk-font($size: 24, $weight: bold, $line-height: 20px);
18
+ border: 0;
19
+ box-sizing: border-box;
20
+ display: block;
21
+ margin: 0;
22
+ padding: govuk-spacing(6) govuk-spacing(3);
23
+ position: relative;
24
+ text-decoration: none;
25
+
26
+ &,
27
+ &:visited {
28
+ color: govuk-colour("blue"); // FIXME: contrast against govuk-colour("light-grey") not high enough
29
+ }
30
+
31
+ &:focus {
32
+ background: $govuk-focus-colour;
33
+ border-color: $govuk-focus-text-colour;
34
+ border-top-color: $govuk-focus-colour;
35
+ color: $govuk-focus-text-colour;
36
+ outline: 3px solid transparent;
37
+ box-shadow: none;
38
+ z-index: 1;
39
+ }
40
+
41
+ @include govuk-media-query($from: "tablet") {
42
+ padding: govuk-spacing(6);
43
+ }
44
+
45
+ @include govuk-media-query($from: "desktop") {
46
+ @include govuk-font($size: 16, $weight: false, $line-height: 20px);
47
+ display: inherit;
48
+ height: govuk-spacing(9);
49
+ padding: govuk-spacing(4);
50
+
51
+ &:after {
52
+ background: govuk-colour("black");
53
+ bottom: 0;
54
+ content: " ";
55
+ display: block;
56
+ height: govuk-spacing(1);
57
+ left: govuk-spacing(4);
58
+ position: absolute;
59
+ right: govuk-spacing(4);
60
+ }
61
+
62
+ &:hover {
63
+ background: govuk-colour("black");
64
+ color: govuk-colour("mid-grey");
65
+
66
+ &:after {
67
+ background-color: govuk-colour("mid-grey");
68
+ }
69
+ }
70
+
71
+ &:focus {
72
+ @include govuk-focused-text;
73
+ box-shadow: none;
74
+
75
+ &:after {
76
+ background-color: $govuk-focus-text-colour;
77
+ }
78
+ }
79
+
80
+ &,
81
+ &:visited {
82
+ color: govuk-colour("white");
83
+ }
84
+ }
85
+ }
86
+
87
+ %toggle-base {
88
+ @extend %top-level-navigation-link-base;
89
+ @include govuk-font($size: 16, $weight: false, $line-height: 20px);
90
+ border-radius: 0;
91
+ cursor: pointer;
92
+ padding: govuk-spacing(4);
93
+ right: 0;
94
+ top: 0;
95
+
96
+ @include govuk-media-query($from: "desktop") {
97
+ border: none;
98
+ }
99
+ }
100
+
101
+ %top-level-navigation-toggle-base {
102
+ @extend %toggle-base;
103
+ border-top: 1px solid govuk-colour("black");
104
+ height: govuk-spacing(9);
105
+
106
+ &:focus {
107
+ border-color: $govuk-focus-colour;
108
+ }
109
+
110
+ &:hover {
111
+ border-color: govuk-colour("black");
112
+ }
113
+
114
+ &.gem-c-layout-super-navigation-header__open-button {
115
+ border-left-color: govuk-colour("black");
116
+ border-right-color: govuk-colour("black");
117
+
118
+ &,
119
+ &:hover {
120
+ background: govuk-colour("light-grey");
121
+ color: govuk-colour("light-grey");
122
+ }
123
+
124
+ &:focus {
125
+ color: $govuk-focus-colour;
126
+ background: $govuk-focus-colour;
127
+ }
128
+
129
+ &:before,
130
+ &:after {
131
+ $width: 1.2rem;
132
+ $height: .2rem;
133
+
134
+ border: none;
135
+ content: " ";
136
+ display: block;
137
+ margin: 0;
138
+ width: $width;
139
+ height: $height;
140
+ background: govuk-colour("black");
141
+ transform-origin: center;
142
+ position: absolute;
143
+ top: calc(50% - #{$height / 2});
144
+ left: calc(50% - #{$width / 2});
145
+ }
146
+
147
+ &:before {
148
+ transform: rotate(45deg);
149
+ }
150
+
151
+ &:after {
152
+ transform: rotate(-45deg);
153
+ }
154
+ }
155
+ }
156
+
157
+ %search-icon {
158
+ height: $search-icon-size;
159
+ pointer-events: none;
160
+ width: $search-icon-size;
161
+ }
162
+
163
+ // Header layout - black bar and logo.
3
164
  .gem-c-layout-super-navigation-header {
4
165
  background: govuk-colour("black");
5
166
  position: relative;
167
+
168
+ .lte-ie8 & {
169
+ height: govuk-spacing(9);
170
+ }
171
+
172
+ [hidden] {
173
+ display: none;
174
+ }
175
+ }
176
+
177
+ .gem-c-layout-super-navigation-header__container {
178
+ position: relative;
179
+
180
+ @include govuk-media-query($from: "desktop") {
181
+ position: static;
182
+ }
6
183
  }
7
184
 
8
185
  .gem-c-layout-super-navigation-header__header-logo {
@@ -23,103 +200,465 @@ $search-icon-size: 20px;
23
200
  }
24
201
  }
25
202
 
26
- .gem-c-layout-super-navigation-header__items {
203
+ // Top level navigation and search.
204
+ .gem-c-layout-super-navigation-header__navigation-items,
205
+ .gem-c-layout-super-navigation-header__search-items {
206
+ background: govuk-colour("light-grey");
207
+ display: block;
27
208
  list-style: none;
28
- margin: 0;
29
- padding: 0 0 govuk-spacing(1) 0;
209
+ margin: 0 (0 - govuk-spacing(3));
210
+ padding: 0;
211
+
212
+ @include govuk-media-query($from: "tablet") {
213
+ margin: 0 (0 - govuk-spacing(6));
214
+ }
30
215
 
31
216
  @include govuk-media-query($from: "desktop") {
217
+ background: none;
218
+ float: left;
32
219
  padding: 0;
220
+ margin: 0;
221
+ }
222
+ }
223
+
224
+ .gem-c-layout-super-navigation-header__navigation-items {
225
+ .js-enabled & {
226
+ padding: 0 0 govuk-spacing(9) 0;
227
+
228
+ @include govuk-media-query($from: "desktop") {
229
+ padding: 0;
230
+ }
33
231
  }
34
232
  }
35
233
 
36
- .gem-c-layout-super-navigation-header__item {
234
+ .gem-c-layout-super-navigation-header__navigation-item,
235
+ .gem-c-layout-super-navigation-header__search-item {
37
236
  margin-right: 0;
38
- padding: govuk-spacing(1) 0;
237
+ padding: 0;
39
238
 
40
239
  @include govuk-media-query($from: "desktop") {
240
+ border-bottom: none;
41
241
  float: left;
42
242
  padding: 0;
43
243
  }
44
244
  }
45
245
 
46
- .gem-c-layout-super-navigation-header__item-link {
47
- display: block;
48
- padding: govuk-spacing(3) 0;
49
- position: relative;
246
+ .gem-c-layout-super-navigation-header__navigation-item {
247
+ &:after {
248
+ background-color: $govuk-border-colour;
249
+ content: " ";
250
+ display: block;
251
+ height: 1px;
252
+ left: 0;
253
+ right: 0;
254
+ position: absolute;
255
+ }
50
256
 
51
257
  @include govuk-media-query($from: "desktop") {
52
- padding: govuk-spacing(4);
53
- width: auto;
258
+ &:after {
259
+ content: none;
260
+ }
54
261
  }
262
+ }
55
263
 
56
- &:focus {
57
- z-index: 1;
264
+ // Top level navigation links.
265
+ .gem-c-layout-super-navigation-header__navigation-item-link {
266
+ @extend %top-level-navigation-link-base;
267
+
268
+ .js-enabled & {
269
+ @include govuk-media-query($until: "desktop") {
270
+ padding: govuk-spacing(6) govuk-spacing(3) govuk-spacing(6) govuk-spacing(9);
271
+ }
272
+
273
+ @include govuk-media-query($until: "tablet") {
274
+ padding-left: govuk-spacing(7);
275
+ }
58
276
  }
59
277
  }
60
278
 
61
- // Special search link
62
- .gem-c-layout-super-navigation-header__item--search {
63
- border-bottom: 0;
64
- }
279
+ // Search link and dropdown.
280
+ .gem-c-layout-super-navigation-header__search-item-link {
281
+ @extend %top-level-navigation-link-base;
65
282
 
66
- .gem-c-layout-super-navigation-header__item-link--search {
67
283
  @include govuk-media-query($from: "desktop") {
68
- background-color: $govuk-link-colour;
69
- display: inherit;
70
- width: govuk-spacing(4);
284
+ background: $govuk-link-colour;
285
+ margin-left: 0;
71
286
 
72
- &:hover {
73
- background-color: $govuk-link-hover-colour;
287
+ &:focus:hover:after,
288
+ &:after {
289
+ content: none;
74
290
  }
75
291
 
76
- &:focus {
77
- background-color: $govuk-focus-colour;
292
+ &:hover:after {
293
+ content: " ";
294
+ left: 0;
295
+ right: 0;
78
296
  }
79
297
  }
80
298
  }
81
299
 
82
- .gem-c-layout-super-navigation-header__item-link-text--search {
300
+ .gem-c-layout-super-navigation-header__search-item-link-text {
83
301
  @include govuk-media-query($from: "desktop") {
84
302
  @include govuk-visually-hidden;
85
303
  }
86
304
  }
87
305
 
88
- .gem-c-layout-super-navigation-header__item-link-icon--search {
306
+ .gem-c-layout-super-navigation-header__search-item-link-icon {
307
+ @extend %search-icon;
89
308
  display: none;
90
309
 
91
310
  @include govuk-media-query($from: "desktop") {
92
311
  display: block;
93
- height: $search-icon-size;
94
- width: $search-icon-size;
95
312
  }
96
313
  }
97
314
 
98
- .gem-c-layout-super-navigation-header__menu-button {
99
- @include govuk-font($size: 19, $weight: bold, $line-height: 20px);
315
+ .gem-c-layout-super-navigation-header__search-toggle-button-link-icon {
316
+ @extend %search-icon;
317
+ display: block;
318
+ }
319
+
320
+ // Search and popular content dropdown.
321
+ .gem-c-layout-super-navigation-header__search-and-popular {
322
+ display: none;
323
+ padding-bottom: govuk-spacing(4);
324
+ padding-top: govuk-spacing(4);
325
+
326
+ .js-enabled & {
327
+ display: block;
328
+ }
329
+ }
330
+
331
+ // Styles for top level navigation toggle button.
332
+ .gem-c-layout-super-navigation-header__navigation-top-toggle-button {
333
+ @extend %top-level-navigation-toggle-base;
100
334
  border-left: 1px solid govuk-colour("mid-grey");
101
- border-right: 1px solid govuk-colour("mid-grey");
102
- padding: govuk-spacing(4);
103
- top: 0;
335
+ color: govuk-colour("white");
336
+ position: absolute;
337
+ right: 45px;
338
+
339
+ @include govuk-media-query($from: 360px) {
340
+ &:before {
341
+ @include chevron("white");
342
+ }
343
+ }
104
344
 
105
345
  &:focus {
106
- border-left-color: $govuk-focus-colour;
107
- border-right-color: $govuk-focus-colour;
346
+ &:before {
347
+ border-color: $govuk-focus-text-colour;
348
+ }
349
+ }
350
+
351
+ @include govuk-media-query(360px) {
352
+ right: 60px;
353
+ }
354
+
355
+ @include govuk-media-query($from: "desktop") {
356
+ display: none;
108
357
  }
109
358
  }
110
359
 
111
- .js-enabled .gem-c-layout-super-navigation-header__items {
360
+ // styles for search toggle button
361
+ .gem-c-layout-super-navigation-header__search-toggle-button {
362
+ @extend %top-level-navigation-toggle-base;
363
+ border-top: 1px solid transparent;
364
+ border-left: 1px solid govuk-colour("mid-grey");
365
+ color: govuk-colour("white");
366
+ position: absolute;
367
+ right: (0 - govuk-spacing(3));
368
+
369
+ @include govuk-media-query($from: 360px) {
370
+ right: 0;
371
+ }
372
+
373
+ @include govuk-media-query($from: "desktop") {
374
+ background-color: $govuk-link-colour;
375
+ border-left: 0;
376
+ height: govuk-spacing(9);
377
+ margin-left: govuk-spacing(3);
378
+ padding: govuk-spacing(4);
379
+ position: relative;
380
+ float: right;
381
+
382
+ &:not(.gem-c-layout-super-navigation-header__open-button):hover {
383
+ background: none;
384
+ color: govuk-colour("light-grey");
385
+
386
+ &:after {
387
+ content: " ";
388
+ left: 0;
389
+ right: 0;
390
+ }
391
+ }
392
+
393
+ &:focus:hover:after,
394
+ &:after {
395
+ content: none;
396
+ }
397
+
398
+ &.gem-c-layout-super-navigation-header__open-button {
399
+ border-top-color: govuk-colour("black");
400
+
401
+ &:hover:after {
402
+ content: " ";
403
+ }
404
+ }
405
+ }
406
+ }
407
+
408
+ // styles for second level navigation toggle buttons
409
+ .gem-c-layout-super-navigation-header__navigation-second-toggle-button {
410
+ @extend %toggle-base;
411
+ @include govuk-font($size: 24, $weight: false, $line-height: 20px);
412
+ border: 0;
413
+ margin: 0;
414
+ padding: govuk-spacing(6) govuk-spacing(3);
415
+ position: relative;
416
+ text-align: left;
417
+ text-decoration: none;
418
+ width: 100%;
419
+
420
+ &:before {
421
+ @include chevron("black");
422
+ }
423
+
424
+ &,
425
+ &:visited {
426
+ color: $govuk-link-colour;// FIXME: contrast against govuk-colour("light-grey") not high enough
427
+
428
+ @include govuk-media-query($from: "desktop") {
429
+ color: govuk-colour("white");
430
+ }
431
+ }
432
+
433
+ @include govuk-media-query($from: "tablet") {
434
+ padding: govuk-spacing(6);
435
+ }
436
+
437
+ @include govuk-media-query($from: "desktop") {
438
+ @include govuk-font($size: 16, $weight: false, $line-height: 20px);
439
+ border-top: 1px solid transparent;
440
+ color: govuk-colour("white");
441
+ height: govuk-spacing(9);
442
+ padding: govuk-spacing(4);
443
+ position: relative;
444
+
445
+ &:before {
446
+ border-color: govuk-colour("white");
447
+ }
448
+
449
+ &:hover {
450
+ color: govuk-colour("mid-grey");
451
+
452
+ &:after {
453
+ background-color: govuk-colour("mid-grey");
454
+ }
455
+
456
+ &:before {
457
+ border-color: govuk-colour("mid-grey");
458
+ }
459
+ }
460
+
461
+ &:focus {
462
+ color: $govuk-focus-text-colour;
463
+ // border-color: $govuk-focus-text-colour;
464
+
465
+ &:after {
466
+ background-color: $govuk-focus-text-colour;
467
+ }
468
+
469
+ &:before {
470
+ border-color: $govuk-focus-text-colour;
471
+ }
472
+ }
473
+ }
474
+
475
+ &.gem-c-layout-super-navigation-header__open-button {
476
+ border-top-color: govuk-colour("black");
477
+
478
+ &:focus {
479
+ border-top-color: $govuk-focus-colour;
480
+ }
481
+
482
+ &:before {
483
+ transform: translateY(20%) rotate(225deg);
484
+ }
485
+
486
+ @include govuk-media-query($from: "desktop") {
487
+ background-color: govuk-colour("light-grey");
488
+ color: $govuk-link-colour;
489
+
490
+ &:after {
491
+ background: $govuk-link-colour;
492
+ }
493
+
494
+ &:before {
495
+ border-color: $govuk-link-colour;
496
+ }
497
+
498
+ &:focus {
499
+ background-color: $govuk-focus-colour;
500
+ color: $govuk-focus-text-colour;
501
+
502
+ &:after {
503
+ background-color: $govuk-focus-text-colour;
504
+ }
505
+
506
+ &:before {
507
+ border-color: $govuk-focus-text-colour;
508
+ }
509
+ }
510
+
511
+ &:active {
512
+ background-color: govuk-colour("light-grey");
513
+ color: $govuk-link-colour;
514
+
515
+ &:before {
516
+ border-color: $govuk-link-colour;
517
+ }
518
+ }
519
+ }
520
+ }
521
+ }
522
+
523
+ // Dropdown menu.
524
+ .gem-c-layout-super-navigation-header__navigation-dropdown-menu {
525
+ background: govuk-colour("white");
526
+
527
+ @include govuk-media-query($from: "desktop") {
528
+ background: govuk-colour("light-grey");
529
+ left: 0;
530
+ position: absolute;
531
+ right: 0;
532
+ }
533
+ }
534
+
535
+ // Dropdown menu description.
536
+ .gem-c-layout-super-navigation-header__menu-description {
112
537
  display: none;
113
538
 
114
539
  @include govuk-media-query($from: "desktop") {
115
540
  display: block;
541
+ padding: govuk-spacing(7) 0 govuk-spacing(7) 0;
116
542
  }
117
543
  }
118
544
 
119
- .js-enabled .gem-c-layout-super-navigation-header__items--open {
120
- display: block;
545
+ // Dropdown menu items.
546
+ .gem-c-layout-super-navigation-header__dropdown-list-item {
547
+ @include govuk-media-query($from: "desktop") {
548
+ padding: govuk-spacing(2) 0;
549
+ }
121
550
  }
122
551
 
123
- .gem-c-layout-super-navigation-header__dropdown-menu {
124
- display: none;
552
+ // Navigation menu items.
553
+ .gem-c-layout-super-navigation-header__navigation-second-items {
554
+ margin: 0 auto;
555
+ padding: govuk-spacing(2) 0 govuk-spacing(6) 0;
556
+
557
+ @include govuk-media-query($from: "desktop") {
558
+ display: flex;
559
+ flex-wrap: wrap;
560
+ margin-left: (0 - govuk-spacing(3));
561
+ margin-right: (0 - govuk-spacing(3));
562
+ padding: govuk-spacing(6) 0 govuk-spacing(8) 0;
563
+
564
+ & > li {
565
+ box-sizing: border-box;
566
+ margin-bottom: 0;
567
+ padding-left: govuk-spacing(3);
568
+ padding-right: govuk-spacing(3);
569
+ width: 50%;
570
+ }
571
+ }
572
+ }
573
+
574
+ .gem-c-layout-super-navigation-header__navigation-second-item-link {
575
+ display: inline-block;
576
+ padding: govuk-spacing(2) 0;
577
+
578
+ @include govuk-media-query($from: "desktop") {
579
+ display: inline;
580
+ font-weight: bold;
581
+ padding: 0;
582
+ }
583
+ }
584
+
585
+ .gem-c-layout-super-navigation-header__navigation-second-item-link--with-description {
586
+ @include govuk-font($size: 19, $weight: bold);
587
+ margin-bottom: 0;
588
+ padding-bottom: govuk-spacing(1);
589
+ }
590
+
591
+ // Dropdown menu footer links.
592
+ .gem-c-layout-super-navigation-header__navigation-second-footer {
593
+ border-top: 1px solid govuk-colour("mid-grey");
594
+ }
595
+
596
+ .gem-c-layout-super-navigation-header__navigation-second-footer-list {
597
+ list-style: none;
598
+ padding-bottom: govuk-spacing(8);
599
+ padding-top: govuk-spacing(4);
600
+
601
+ @include govuk-grid-column($width: "two-thirds", $float: right, $at: "desktop");
602
+
603
+ @include govuk-media-query($from: "desktop") {
604
+ padding: govuk-spacing(7) 0 govuk-spacing(8) 0;
605
+ }
606
+ }
607
+
608
+ .gem-c-layout-super-navigation-header__navigation-second-footer-item {
609
+ @include govuk-media-query($from: "desktop") {
610
+ box-sizing: border-box;
611
+ float: left;
612
+ width: 50%;
613
+ padding: 0 govuk-spacing(3);
614
+ }
615
+ }
616
+
617
+ .gem-c-layout-super-navigation-header__navigation-second-footer-link {
618
+ @include govuk-font($size: 19, $weight: bold);
619
+ display: inline-block;
620
+ margin: govuk-spacing(1) 0;
621
+ padding: govuk-spacing(2) 0;
622
+
623
+ @include govuk-media-query($from: "desktop") {
624
+ display: inline;
625
+ font-weight: bold;
626
+ padding: 0;
627
+ }
628
+ }
629
+
630
+ // Search dropdown.
631
+ .gem-c-layout-super-navigation-header__search-items {
632
+ background: govuk-colour("light-grey");
633
+ margin: 0 (0 - govuk-spacing(3));
634
+
635
+ @include govuk-media-query($from: "tablet") {
636
+ margin: 0 (0 - govuk-spacing(6));
637
+ }
638
+
639
+ @include govuk-media-query($from: "desktop") {
640
+ margin: 0;
641
+
642
+ .js-enabled & {
643
+ left: 0;
644
+ position: absolute;
645
+ right: 0;
646
+ top: 60px;
647
+ }
648
+ }
649
+ }
650
+
651
+ .gem-c-layout-super-navigation-header__search-form {
652
+ padding: govuk-spacing(3) 0 govuk-spacing(6) 0;
653
+ }
654
+
655
+ // Popular links.
656
+ .gem-c-layout-super-navigation-header__popular-link {
657
+ padding: govuk-spacing(2) 0;
658
+ display: inline-block;
659
+
660
+ @include govuk-media-query($from: "desktop") {
661
+ margin: govuk-spacing(1) 0;
662
+ padding: 0;
663
+ }
125
664
  }