govuk_publishing_components 25.1.0 → 25.2.3

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 +606 -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 +275 -65
  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: 74b6d888231a927108558b8a25e000da57a26baba4e11d6770b633b9a7b58ea2
4
+ data.tar.gz: 2472c91a10dc527834c77982f7ad57585a337aaffd0bc62f5e8a7cffbcb77ed9
5
5
  SHA512:
6
- metadata.gz: fcabb52ef323f944b938498968946e797e6c3b868393768fa42bd5fa350206e381d0d612bf9d158f6d6c00ed226aa7f89a4b737ba7a6acc32a390d4ef967d3a6
7
- data.tar.gz: 1c79526993a09351120f3459a5096e9e95974fc35557e031607e52babdb9099115b61462adc6e7b712d04300688a19ce35478d217323d60beae29ad839cc38a6
6
+ metadata.gz: 2ebde6b8dfca166b9185bd13c13a700e1139b819da0cd22e71fdbd856db1d9631f5faf67178a9f1a82ee30277408fc51a6226982df93a8288d3c8f193f9a808c
7
+ data.tar.gz: 5327b6f2d764d7a8231339f3912d67ba64e30243c6dde41c96b3fc455b9c7ba91032b9a0a559db24c33f981ab789bcc7c211879d7d78307a91313d0c31519723
@@ -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,183 @@
1
1
  $search-icon-size: 20px;
2
2
 
3
+ @mixin chevron($colour) {
4
+ border-bottom: 3px solid govuk-colour($colour);
5
+ border-right: 3px solid govuk-colour($colour);
6
+ content: " ";
7
+ display: inline-block;
8
+ height: 8px;
9
+ margin: 0 8px 0 2px;
10
+ transform: translateY(-35%) rotate(45deg);
11
+ vertical-align: middle;
12
+ width: 8px;
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
+ &:link,
28
+ &:visited {
29
+ color: $govuk-link-colour;
30
+ }
31
+
32
+ &:focus {
33
+ background: $govuk-focus-colour;
34
+ border-color: $govuk-focus-text-colour;
35
+ border-top-color: $govuk-focus-colour;
36
+ color: $govuk-focus-text-colour;
37
+ outline: 3px solid transparent;
38
+ box-shadow: none;
39
+ z-index: 1;
40
+ }
41
+
42
+ @include govuk-media-query($from: "tablet") {
43
+ padding: govuk-spacing(6);
44
+ }
45
+
46
+ @include govuk-media-query($from: "desktop") {
47
+ @include govuk-font($size: 16, $weight: false, $line-height: 20px);
48
+ color: govuk-colour("white");
49
+ display: inherit;
50
+ height: govuk-spacing(9);
51
+ padding: govuk-spacing(4);
52
+
53
+ &:after {
54
+ background: govuk-colour("black");
55
+ bottom: 0;
56
+ content: " ";
57
+ display: block;
58
+ height: govuk-spacing(1);
59
+ left: govuk-spacing(4);
60
+ position: absolute;
61
+ right: govuk-spacing(4);
62
+ }
63
+
64
+ &:hover {
65
+ background: govuk-colour("black");
66
+ color: govuk-colour("mid-grey");
67
+
68
+ &:after {
69
+ background-color: govuk-colour("mid-grey");
70
+ }
71
+ }
72
+
73
+ &:focus {
74
+ @include govuk-focused-text;
75
+ box-shadow: none;
76
+
77
+ &:after {
78
+ background-color: $govuk-focus-text-colour;
79
+ }
80
+ }
81
+
82
+ &,
83
+ &:visited {
84
+ color: govuk-colour("white");
85
+ }
86
+ }
87
+ }
88
+
89
+ %toggle-base {
90
+ @extend %top-level-navigation-link-base;
91
+ @include govuk-font($size: 16, $weight: false, $line-height: 20px);
92
+ border-radius: 0;
93
+ cursor: pointer;
94
+ padding: govuk-spacing(4);
95
+ right: 0;
96
+ top: 0;
97
+
98
+ @include govuk-media-query($from: "desktop") {
99
+ border: none;
100
+ }
101
+ }
102
+
103
+ %top-level-navigation-toggle-base {
104
+ @extend %toggle-base;
105
+ border-top: 1px solid govuk-colour("black");
106
+ height: govuk-spacing(9);
107
+
108
+ &:focus {
109
+ border-color: $govuk-focus-colour;
110
+ }
111
+
112
+ &.gem-c-layout-super-navigation-header__open-button {
113
+ border-left-color: govuk-colour("black");
114
+ border-right-color: govuk-colour("black");
115
+
116
+ &,
117
+ &:hover {
118
+ background: govuk-colour("light-grey");
119
+ color: govuk-colour("light-grey");
120
+ }
121
+
122
+ &:focus {
123
+ color: $govuk-focus-colour;
124
+ background: $govuk-focus-colour;
125
+ }
126
+
127
+ &:before,
128
+ &:after {
129
+ $width: govuk-spacing(4);
130
+ $height: 4px;
131
+
132
+ border: none;
133
+ content: " ";
134
+ display: block;
135
+ margin: 0;
136
+ width: $width;
137
+ height: $height;
138
+ background: govuk-colour("black");
139
+ transform-origin: center;
140
+ position: absolute;
141
+ top: calc(50% - #{$height / 2});
142
+ left: calc(50% - #{$width / 2});
143
+ }
144
+
145
+ &:before {
146
+ transform: rotate(45deg);
147
+ }
148
+
149
+ &:after {
150
+ transform: rotate(-45deg);
151
+ }
152
+ }
153
+ }
154
+
155
+ %search-icon {
156
+ height: $search-icon-size;
157
+ pointer-events: none;
158
+ width: $search-icon-size;
159
+ }
160
+
161
+ // Header layout - black bar and logo.
3
162
  .gem-c-layout-super-navigation-header {
4
163
  background: govuk-colour("black");
5
164
  position: relative;
165
+
166
+ .lte-ie8 & {
167
+ height: govuk-spacing(9);
168
+ }
169
+
170
+ [hidden] {
171
+ display: none;
172
+ }
173
+ }
174
+
175
+ .gem-c-layout-super-navigation-header__container {
176
+ position: relative;
177
+
178
+ @include govuk-media-query($from: "desktop") {
179
+ position: static;
180
+ }
6
181
  }
7
182
 
8
183
  .gem-c-layout-super-navigation-header__header-logo {
@@ -23,103 +198,493 @@ $search-icon-size: 20px;
23
198
  }
24
199
  }
25
200
 
26
- .gem-c-layout-super-navigation-header__items {
201
+ // Top level navigation and search.
202
+ .gem-c-layout-super-navigation-header__navigation-items,
203
+ .gem-c-layout-super-navigation-header__search-items {
204
+ background: govuk-colour("light-grey");
205
+ display: block;
27
206
  list-style: none;
28
- margin: 0;
29
- padding: 0 0 govuk-spacing(1) 0;
207
+ margin: 0 (0 - govuk-spacing(3));
208
+ padding: 0;
209
+
210
+ @include govuk-media-query($from: "tablet") {
211
+ margin: 0 (0 - govuk-spacing(6));
212
+ }
30
213
 
31
214
  @include govuk-media-query($from: "desktop") {
215
+ background: none;
216
+ float: left;
32
217
  padding: 0;
218
+ margin: 0;
219
+ }
220
+ }
221
+
222
+ .gem-c-layout-super-navigation-header__navigation-items {
223
+ .js-enabled & {
224
+ padding: 0 0 govuk-spacing(9) 0;
225
+
226
+ @include govuk-media-query($from: "desktop") {
227
+ padding: 0;
228
+ }
33
229
  }
34
230
  }
35
231
 
36
- .gem-c-layout-super-navigation-header__item {
232
+ .gem-c-layout-super-navigation-header__navigation-item,
233
+ .gem-c-layout-super-navigation-header__search-item {
37
234
  margin-right: 0;
38
- padding: govuk-spacing(1) 0;
235
+ padding: 0;
39
236
 
40
237
  @include govuk-media-query($from: "desktop") {
238
+ border-bottom: none;
41
239
  float: left;
42
240
  padding: 0;
43
241
  }
44
242
  }
45
243
 
46
- .gem-c-layout-super-navigation-header__item-link {
47
- display: block;
48
- padding: govuk-spacing(3) 0;
49
- position: relative;
244
+ .gem-c-layout-super-navigation-header__navigation-item {
245
+ &:after {
246
+ background-color: $govuk-border-colour;
247
+ content: " ";
248
+ display: block;
249
+ height: 1px;
250
+ left: 0;
251
+ right: 0;
252
+ position: absolute;
253
+ }
50
254
 
51
255
  @include govuk-media-query($from: "desktop") {
52
- padding: govuk-spacing(4);
53
- width: auto;
256
+ &:after {
257
+ content: none;
258
+ }
54
259
  }
260
+ }
55
261
 
56
- &:focus {
57
- z-index: 1;
262
+ // Top level navigation links.
263
+ .gem-c-layout-super-navigation-header__navigation-item-link {
264
+ @extend %top-level-navigation-link-base;
265
+
266
+ &,
267
+ &:link, // 👈 required to override govuk-template
268
+ &:visited {
269
+ color: $govuk-link-colour;
270
+
271
+ &:hover {
272
+ color: govuk-colour("mid-grey");
273
+ }
274
+
275
+ &:focus {
276
+ color: $govuk-focus-text-colour;
277
+ }
278
+
279
+ @include govuk-media-query($from: "desktop") {
280
+ color: govuk-colour("white");
281
+ }
58
282
  }
59
- }
60
283
 
61
- // Special search link
62
- .gem-c-layout-super-navigation-header__item--search {
63
- border-bottom: 0;
284
+ // This :link:focus selector is required to override the `govuk-template`
285
+ // defaults.
286
+ &:link:focus {
287
+ color: $govuk-focus-text-colour;
288
+ }
289
+
290
+ .js-enabled & {
291
+ @include govuk-media-query($until: "desktop") {
292
+ padding: govuk-spacing(6) govuk-spacing(3) govuk-spacing(6) govuk-spacing(9);
293
+ }
294
+
295
+ @include govuk-media-query($until: "tablet") {
296
+ padding-left: govuk-spacing(7);
297
+ }
298
+ }
64
299
  }
65
300
 
66
- .gem-c-layout-super-navigation-header__item-link--search {
301
+ // Search link and dropdown.
302
+ .gem-c-layout-super-navigation-header__search-item-link {
303
+ @extend %top-level-navigation-link-base;
304
+
67
305
  @include govuk-media-query($from: "desktop") {
68
- background-color: $govuk-link-colour;
69
- display: inherit;
70
- width: govuk-spacing(4);
306
+ background: $govuk-link-colour;
307
+ margin-left: 0;
71
308
 
72
- &:hover {
73
- background-color: $govuk-link-hover-colour;
309
+ &:focus:hover:after,
310
+ &:after {
311
+ content: none;
74
312
  }
75
313
 
76
- &:focus {
77
- background-color: $govuk-focus-colour;
314
+ &:hover:after {
315
+ content: " ";
316
+ left: 0;
317
+ right: 0;
78
318
  }
79
319
  }
80
320
  }
81
321
 
82
- .gem-c-layout-super-navigation-header__item-link-text--search {
322
+ .gem-c-layout-super-navigation-header__search-item-link-text {
83
323
  @include govuk-media-query($from: "desktop") {
84
324
  @include govuk-visually-hidden;
85
325
  }
86
326
  }
87
327
 
88
- .gem-c-layout-super-navigation-header__item-link-icon--search {
328
+ .gem-c-layout-super-navigation-header__search-item-link-icon {
329
+ @extend %search-icon;
89
330
  display: none;
90
331
 
91
332
  @include govuk-media-query($from: "desktop") {
92
333
  display: block;
93
- height: $search-icon-size;
94
- width: $search-icon-size;
95
334
  }
96
335
  }
97
336
 
98
- .gem-c-layout-super-navigation-header__menu-button {
99
- @include govuk-font($size: 19, $weight: bold, $line-height: 20px);
337
+ .gem-c-layout-super-navigation-header__search-toggle-button-link-icon {
338
+ @extend %search-icon;
339
+ display: block;
340
+ }
341
+
342
+ // Search and popular content dropdown.
343
+ .gem-c-layout-super-navigation-header__search-and-popular {
344
+ display: none;
345
+ padding-bottom: govuk-spacing(4);
346
+ padding-top: govuk-spacing(4);
347
+
348
+ .js-enabled & {
349
+ display: block;
350
+ }
351
+ }
352
+
353
+ // Styles for top level navigation toggle button.
354
+ .gem-c-layout-super-navigation-header__navigation-top-toggle-button {
355
+ @extend %top-level-navigation-toggle-base;
100
356
  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;
357
+ color: govuk-colour("white");
358
+ position: absolute;
359
+ right: 45px;
360
+
361
+ @include govuk-media-query($from: 360px) {
362
+ &:before {
363
+ @include chevron("white");
364
+ }
365
+ }
104
366
 
105
367
  &:focus {
106
- border-left-color: $govuk-focus-colour;
107
- border-right-color: $govuk-focus-colour;
368
+ &:before {
369
+ border-color: $govuk-focus-text-colour;
370
+ }
371
+ }
372
+
373
+ @include govuk-media-query(360px) {
374
+ right: 60px;
375
+ }
376
+
377
+ @include govuk-media-query($from: "desktop") {
378
+ display: none;
379
+ }
380
+ }
381
+
382
+ // styles for search toggle button
383
+ .gem-c-layout-super-navigation-header__search-toggle-button {
384
+ @extend %top-level-navigation-toggle-base;
385
+ border-top: 1px solid transparent;
386
+ border-left: 1px solid govuk-colour("mid-grey");
387
+ color: govuk-colour("white");
388
+ position: absolute;
389
+ right: (0 - govuk-spacing(3));
390
+
391
+ &:hover {
392
+ border-color: govuk-colour("black");
393
+ }
394
+
395
+ @include govuk-media-query($from: 360px) {
396
+ right: 0;
397
+ }
398
+
399
+ @include govuk-media-query($from: "desktop") {
400
+ background-color: $govuk-link-colour;
401
+ border-left: 0;
402
+ height: govuk-spacing(9);
403
+ margin-left: govuk-spacing(3);
404
+ padding: govuk-spacing(4);
405
+ position: relative;
406
+ float: right;
407
+
408
+ &:not(.gem-c-layout-super-navigation-header__open-button):hover {
409
+ background: none;
410
+ color: govuk-colour("light-grey");
411
+
412
+ &:after {
413
+ content: " ";
414
+ left: 0;
415
+ right: 0;
416
+ }
417
+ }
418
+
419
+ &:focus:hover:after,
420
+ &:after {
421
+ content: none;
422
+ }
423
+
424
+ &.gem-c-layout-super-navigation-header__open-button {
425
+ border-top-color: govuk-colour("black");
426
+
427
+ &:hover:after {
428
+ content: " ";
429
+ }
430
+ }
108
431
  }
109
432
  }
110
433
 
111
- .js-enabled .gem-c-layout-super-navigation-header__items {
434
+ // styles for second level navigation toggle buttons
435
+ .gem-c-layout-super-navigation-header__navigation-second-toggle-button {
436
+ @extend %toggle-base;
437
+ @include govuk-font($size: 24, $weight: false, $line-height: 20px);
438
+ border: 0;
439
+ margin: 0;
440
+ padding: govuk-spacing(6) govuk-spacing(3);
441
+ position: relative;
442
+ text-align: left;
443
+ text-decoration: none;
444
+ width: 100%;
445
+
446
+ &:before {
447
+ @include chevron("black");
448
+ }
449
+
450
+ &,
451
+ &:visited {
452
+ color: $govuk-link-colour;// FIXME: contrast against govuk-colour("light-grey") not high enough
453
+
454
+ @include govuk-media-query($from: "desktop") {
455
+ color: govuk-colour("white");
456
+ }
457
+ }
458
+
459
+ @include govuk-media-query($from: "tablet") {
460
+ padding: govuk-spacing(6);
461
+ }
462
+
463
+ @include govuk-media-query($from: "desktop") {
464
+ @include govuk-font($size: 16, $weight: false, $line-height: 20px);
465
+ border-top: 1px solid transparent;
466
+ color: govuk-colour("white");
467
+ height: govuk-spacing(9);
468
+ padding: govuk-spacing(4);
469
+ position: relative;
470
+
471
+ &:before {
472
+ border-color: govuk-colour("white");
473
+ }
474
+
475
+ &:hover {
476
+ color: govuk-colour("mid-grey");
477
+
478
+ &:after {
479
+ background-color: govuk-colour("mid-grey");
480
+ }
481
+
482
+ &:before {
483
+ border-color: govuk-colour("mid-grey");
484
+ }
485
+ }
486
+
487
+ &:focus {
488
+ color: $govuk-focus-text-colour;
489
+ // border-color: $govuk-focus-text-colour;
490
+
491
+ &:after {
492
+ background-color: $govuk-focus-text-colour;
493
+ }
494
+
495
+ &:before {
496
+ border-color: $govuk-focus-text-colour;
497
+ }
498
+ }
499
+ }
500
+
501
+ &.gem-c-layout-super-navigation-header__open-button {
502
+ border-top-color: govuk-colour("black");
503
+
504
+ &:focus {
505
+ border-top-color: $govuk-focus-colour;
506
+ }
507
+
508
+ &:before {
509
+ transform: translateY(20%) rotate(225deg);
510
+ }
511
+
512
+ @include govuk-media-query($from: "desktop") {
513
+ background-color: govuk-colour("light-grey");
514
+ color: $govuk-link-colour;
515
+
516
+ &:after {
517
+ background: $govuk-link-colour;
518
+ }
519
+
520
+ &:before {
521
+ border-color: $govuk-link-colour;
522
+ }
523
+
524
+ &:focus {
525
+ background-color: $govuk-focus-colour;
526
+ color: $govuk-focus-text-colour;
527
+
528
+ &:after {
529
+ background-color: $govuk-focus-text-colour;
530
+ }
531
+
532
+ &:before {
533
+ border-color: $govuk-focus-text-colour;
534
+ }
535
+ }
536
+
537
+ &:active {
538
+ background-color: govuk-colour("light-grey");
539
+ color: $govuk-link-colour;
540
+
541
+ &:before {
542
+ border-color: $govuk-link-colour;
543
+ }
544
+ }
545
+ }
546
+ }
547
+ }
548
+
549
+ // Dropdown menu.
550
+ .gem-c-layout-super-navigation-header__navigation-dropdown-menu {
551
+ background: govuk-colour("white");
552
+
553
+ @include govuk-media-query($from: "desktop") {
554
+ background: govuk-colour("light-grey");
555
+ left: 0;
556
+ position: absolute;
557
+ right: 0;
558
+ }
559
+ }
560
+
561
+ // Dropdown menu description.
562
+ .gem-c-layout-super-navigation-header__menu-description {
112
563
  display: none;
113
564
 
114
565
  @include govuk-media-query($from: "desktop") {
115
566
  display: block;
567
+ padding: govuk-spacing(7) 0 govuk-spacing(7) 0;
116
568
  }
117
569
  }
118
570
 
119
- .js-enabled .gem-c-layout-super-navigation-header__items--open {
120
- display: block;
571
+ // Dropdown menu items.
572
+ .gem-c-layout-super-navigation-header__dropdown-list-item {
573
+ @include govuk-media-query($from: "desktop") {
574
+ padding: govuk-spacing(2) 0;
575
+ }
121
576
  }
122
577
 
123
- .gem-c-layout-super-navigation-header__dropdown-menu {
124
- display: none;
578
+ // Navigation menu items.
579
+ .gem-c-layout-super-navigation-header__navigation-second-items {
580
+ margin: 0 auto;
581
+ padding: govuk-spacing(2) 0 govuk-spacing(6) 0;
582
+
583
+ @include govuk-media-query($from: "desktop") {
584
+ display: flex;
585
+ flex-wrap: wrap;
586
+ margin-left: (0 - govuk-spacing(3));
587
+ margin-right: (0 - govuk-spacing(3));
588
+ padding: govuk-spacing(6) 0 govuk-spacing(8) 0;
589
+
590
+ & > li {
591
+ box-sizing: border-box;
592
+ margin-bottom: 0;
593
+ padding-left: govuk-spacing(3);
594
+ padding-right: govuk-spacing(3);
595
+ width: 50%;
596
+ }
597
+ }
598
+ }
599
+
600
+ .gem-c-layout-super-navigation-header__navigation-second-item-link {
601
+ display: inline-block;
602
+ padding: govuk-spacing(2) 0;
603
+
604
+ @include govuk-media-query($from: "desktop") {
605
+ display: inline;
606
+ font-weight: bold;
607
+ padding: 0;
608
+ }
609
+ }
610
+
611
+ .gem-c-layout-super-navigation-header__navigation-second-item-link--with-description {
612
+ @include govuk-font($size: 19, $weight: bold);
613
+ margin-bottom: 0;
614
+ padding-bottom: govuk-spacing(1);
615
+ }
616
+
617
+ // Dropdown menu footer links.
618
+ .gem-c-layout-super-navigation-header__navigation-second-footer {
619
+ border-top: 1px solid govuk-colour("mid-grey");
620
+ }
621
+
622
+ .gem-c-layout-super-navigation-header__navigation-second-footer-list {
623
+ list-style: none;
624
+ padding-bottom: govuk-spacing(8);
625
+ padding-top: govuk-spacing(4);
626
+
627
+ @include govuk-grid-column($width: "two-thirds", $float: right, $at: "desktop");
628
+
629
+ @include govuk-media-query($from: "desktop") {
630
+ padding: govuk-spacing(7) 0 govuk-spacing(8) 0;
631
+ }
632
+ }
633
+
634
+ .gem-c-layout-super-navigation-header__navigation-second-footer-item {
635
+ @include govuk-media-query($from: "desktop") {
636
+ box-sizing: border-box;
637
+ float: left;
638
+ width: 50%;
639
+ padding: 0 govuk-spacing(3);
640
+ }
641
+ }
642
+
643
+ .gem-c-layout-super-navigation-header__navigation-second-footer-link {
644
+ @include govuk-font($size: 19, $weight: bold);
645
+ display: inline-block;
646
+ margin: govuk-spacing(1) 0;
647
+ padding: govuk-spacing(2) 0;
648
+
649
+ @include govuk-media-query($from: "desktop") {
650
+ display: inline;
651
+ font-weight: bold;
652
+ padding: 0;
653
+ }
654
+ }
655
+
656
+ // Search dropdown.
657
+ .gem-c-layout-super-navigation-header__search-items {
658
+ background: govuk-colour("light-grey");
659
+ margin: 0 (0 - govuk-spacing(3));
660
+
661
+ @include govuk-media-query($from: "tablet") {
662
+ margin: 0 (0 - govuk-spacing(6));
663
+ }
664
+
665
+ @include govuk-media-query($from: "desktop") {
666
+ margin: 0;
667
+
668
+ .js-enabled & {
669
+ left: 0;
670
+ position: absolute;
671
+ right: 0;
672
+ top: 60px;
673
+ }
674
+ }
675
+ }
676
+
677
+ .gem-c-layout-super-navigation-header__search-form {
678
+ padding: govuk-spacing(3) 0 govuk-spacing(6) 0;
679
+ }
680
+
681
+ // Popular links.
682
+ .gem-c-layout-super-navigation-header__popular-link {
683
+ padding: govuk-spacing(2) 0;
684
+ display: inline-block;
685
+
686
+ @include govuk-media-query($from: "desktop") {
687
+ margin: govuk-spacing(1) 0;
688
+ padding: 0;
689
+ }
125
690
  }