govuk_publishing_components 25.3.0 → 25.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/analytics/track-click.js +15 -7
  3. data/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js +10 -6
  4. data/app/assets/javascripts/govuk_publishing_components/components/layout-super-navigation-header.js +3 -7
  5. data/app/assets/javascripts/govuk_publishing_components/modules.js +1 -1
  6. data/app/assets/stylesheets/component_guide/application.scss +0 -6
  7. data/app/assets/stylesheets/govuk_publishing_components/components/_cookie-banner.scss +4 -9
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +22 -24
  9. data/app/assets/stylesheets/govuk_publishing_components/components/_step-by-step-nav-header.scss +2 -4
  10. data/app/views/govuk_publishing_components/components/_cookie_banner.html.erb +1 -1
  11. data/app/views/govuk_publishing_components/components/_image_card.html.erb +0 -1
  12. data/app/views/govuk_publishing_components/components/_layout_for_public.html.erb +5 -2
  13. data/app/views/govuk_publishing_components/components/docs/image_card.yml +9 -0
  14. data/lib/govuk_publishing_components/presenters/image_card_helper.rb +3 -2
  15. data/lib/govuk_publishing_components/presenters/public_layout_helper.rb +3 -0
  16. data/lib/govuk_publishing_components/version.rb +1 -1
  17. data/node_modules/govuk-frontend/govuk/all.js +61 -3
  18. data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_index.scss +1 -0
  19. data/node_modules/govuk-frontend/govuk/components/button/_index.scss +10 -4
  20. data/node_modules/govuk-frontend/govuk/components/checkboxes/_index.scss +49 -34
  21. data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js +61 -3
  22. data/node_modules/govuk-frontend/govuk/components/checkboxes/fixtures.json +122 -41
  23. data/node_modules/govuk-frontend/govuk/components/checkboxes/macro-options.json +12 -0
  24. data/node_modules/govuk-frontend/govuk/components/checkboxes/template.njk +37 -39
  25. data/node_modules/govuk-frontend/govuk/components/footer/_index.scss +22 -10
  26. data/node_modules/govuk-frontend/govuk/components/header/_index.scss +11 -7
  27. data/node_modules/govuk-frontend/govuk/components/header/fixtures.json +18 -18
  28. data/node_modules/govuk-frontend/govuk/components/header/template.njk +5 -11
  29. data/node_modules/govuk-frontend/govuk/components/input/_index.scss +4 -0
  30. data/node_modules/govuk-frontend/govuk/components/skip-link/_index.scss +2 -0
  31. data/node_modules/govuk-frontend/govuk/components/warning-text/_index.scss +0 -1
  32. data/node_modules/govuk-frontend/govuk/core/_template.scss +0 -1
  33. data/node_modules/govuk-frontend/govuk/helpers/_links.scss +6 -0
  34. data/node_modules/govuk-frontend/govuk/objects/_button-group.scss +9 -2
  35. data/node_modules/govuk-frontend/govuk/objects/_width-container.scss +4 -0
  36. data/node_modules/govuk-frontend/govuk/template.njk +1 -1
  37. data/node_modules/govuk-frontend/package.json +1 -1
  38. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41273e4fba800fd43e808314fc1888f6dcfec744c7df9a6cfea11443d37d9493
4
- data.tar.gz: 87fc6df908f19e12cc2bba6aafaf3e8eff479e33cfc59dcac05ffdb1639c9223
3
+ metadata.gz: b1b20d5bd22562106adb11d4dae477700ae7cf87c10e8113615ddccc43a57eee
4
+ data.tar.gz: 6c8cbab6a211c1d7192af9128ea910b9394702a7d369e1b48e29d74f541ce4a4
5
5
  SHA512:
6
- metadata.gz: f9c9af6f11ff227c238b3e5256ee85f460f628f7ae8923835a56e33be33e87659f0ccf94d272ff559717bc7cd0179378a5141f9f76e406ea846249d56c5ae9f3
7
- data.tar.gz: 165440177ebe3c307decae4789c93d6858c0925c26898c1c68901d72dc437448aed6b7e50a76123b4a17fea577f261262ae80fa245bb437b67b3dd72e139117e
6
+ metadata.gz: 298e4ac11183bbd0dc6dd364c9d831143c5b94e92b65e3afccad59269c1515e683834db2e3af528f7c2416c78a644cbd61aba803b66e65335195f8bc1e4dfd76
7
+ data.tar.gz: 71429d6099fcc7465c2fef3092fb9b586f385c399e1f90a71470a433d91d2f25314ed53e10b543a683cb3c94c7b8bcb44a272c5a3e479faab9a8f581e9405902
@@ -10,38 +10,46 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
10
10
  this.$module = $module[0]
11
11
  this.$module.handleClick = this.handleClick.bind(this)
12
12
  var trackLinksOnly = this.$module.hasAttribute('data-track-links-only')
13
+ var limitToElementClass = this.$module.getAttribute('data-limit-to-element-class')
13
14
 
14
15
  var that = this
15
16
  // add a listener to the whole element
16
17
  this.$module.addEventListener('click', function (e) {
18
+ var target = e.target
17
19
  if (!trackLinksOnly) {
18
- that.$module.handleClick(e.target)
19
- } else if (trackLinksOnly && e.target.tagName === 'A') {
20
- that.$module.handleClick(e.target)
20
+ that.$module.handleClick(target)
21
+ } else if (trackLinksOnly && target.tagName === 'A') {
22
+ if (!limitToElementClass) {
23
+ that.$module.handleClick(target)
24
+ } else if (limitToElementClass && target.closest('.' + limitToElementClass)) {
25
+ that.$module.handleClick(target)
26
+ }
21
27
  }
22
28
  })
23
29
  }
24
30
 
25
31
  GemTrackClick.prototype.handleClick = function (target) {
26
32
  var options = { transport: 'beacon' }
27
- var linkText
33
+ var linkUrl
28
34
 
29
35
  // if clicked element hasn't got the right attributes, look for a parent that matches
30
36
  if (!target.hasAttribute('data-track-category') && !target.hasAttribute('data-track-action')) {
31
- linkText = target.textContent || target.innerText
37
+ linkUrl = target.getAttribute('href')
32
38
  target = target.closest('[data-track-category][data-track-action]')
33
39
  }
34
40
 
35
41
  if (target) {
36
42
  var category = target.getAttribute('data-track-category')
37
43
  var action = target.getAttribute('data-track-action')
38
- var label = target.getAttribute('data-track-label')
44
+ var label = target.getAttribute('data-track-label') || linkUrl
39
45
  var value = target.getAttribute('data-track-value')
40
46
  var dimension = target.getAttribute('data-track-dimension')
41
47
  var dimensionIndex = target.getAttribute('data-track-dimension-index')
42
48
  var extraOptions = target.getAttribute('data-track-options')
43
49
 
44
- options.label = label || linkText
50
+ if (label) {
51
+ options.label = label
52
+ }
45
53
 
46
54
  if (value) {
47
55
  options.value = value
@@ -27,11 +27,13 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
27
27
 
28
28
  this.$acceptCookiesButton = this.$module.querySelector('button[data-accept-cookies]')
29
29
  if (this.$acceptCookiesButton) {
30
+ this.$acceptCookiesButton.style.display = 'block'
30
31
  this.$acceptCookiesButton.addEventListener('click', this.$module.setCookieConsent)
31
32
  }
32
33
 
33
34
  this.$rejectCookiesButton = this.$module.querySelector('button[data-reject-cookies]')
34
35
  if (this.$rejectCookiesButton) {
36
+ this.$rejectCookiesButton.style.display = 'block'
35
37
  this.$rejectCookiesButton.addEventListener('click', this.$module.rejectCookieConsent)
36
38
  }
37
39
 
@@ -44,7 +46,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
44
46
  var shouldHaveCookieMessage = (this.$module && window.GOVUK.cookie('cookies_preferences_set') !== 'true')
45
47
 
46
48
  if (shouldHaveCookieMessage) {
47
- this.$module.removeAttribute('hidden')
49
+ this.$module.style.display = 'block'
48
50
 
49
51
  // Set the default consent cookie if it isn't already present
50
52
  if (!window.GOVUK.cookie('cookies_policy')) {
@@ -53,16 +55,17 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
53
55
 
54
56
  window.GOVUK.deleteUnconsentedCookies()
55
57
  } else {
56
- this.$module.setAttribute('hidden', '')
58
+ this.$module.style.display = 'none'
57
59
  }
58
60
  } else {
59
- this.$module.setAttribute('hidden', '')
61
+ this.$module.style.display = 'none'
60
62
  }
61
63
  }
62
64
 
63
65
  CookieBanner.prototype.hideCookieMessage = function (event) {
64
66
  if (this.$module) {
65
- this.$module.setAttribute('hidden', '')
67
+ this.$module.hidden = true
68
+ this.$module.style.display = 'none'
66
69
  window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 })
67
70
  }
68
71
 
@@ -98,8 +101,9 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
98
101
  CookieBanner.prototype.showConfirmationMessage = function () {
99
102
  this.$cookieBannerMainContent = document.querySelector('.js-banner-wrapper')
100
103
 
101
- this.$cookieBannerMainContent.setAttribute('hidden', '')
102
- this.$module.cookieBannerConfirmationMessage.removeAttribute('hidden')
104
+ this.$cookieBannerMainContent.hidden = true
105
+ this.$module.cookieBannerConfirmationMessage.style.display = 'block'
106
+ this.$module.cookieBannerConfirmationMessage.hidden = false
103
107
  }
104
108
 
105
109
  CookieBanner.prototype.isInCookiesPage = function () {
@@ -155,10 +155,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
155
155
  }
156
156
 
157
157
  this.$module.style.marginBottom = '0'
158
-
159
- window.removeEventListener('resize', this.resizeHandler, { passive: true })
160
-
161
- this.lastWindowSize = this.windowSize()
162
158
  }
163
159
 
164
160
  // Hide the navigation toggle button and show the navigation submenu:
@@ -166,10 +162,10 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
166
162
  this.$navigationToggle.setAttribute('hidden', 'hidden')
167
163
  this.$navigationMenu.removeAttribute('hidden')
168
164
 
169
- window.addEventListener('resize', this.resizeHandler, { passive: true })
170
-
171
- this.lastWindowSize = this.windowSize()
165
+ this.resizeHandler()
172
166
  }
167
+
168
+ this.lastWindowSize = this.windowSize()
173
169
  }
174
170
 
175
171
  SuperNavigationMegaMenu.prototype.buttonHandler = function (event) {
@@ -7,7 +7,7 @@
7
7
 
8
8
  GOVUK.modules = {
9
9
  find: function (container) {
10
- container = container || $(document)
10
+ container = $(container || document)
11
11
 
12
12
  var modules
13
13
  var moduleSelector = '[data-module]'
@@ -499,9 +499,3 @@ $code-delete-bg: #fadddd;
499
499
  top: 0;
500
500
  background: govuk-colour("white");
501
501
  }
502
-
503
- .gem-c-cookie-banner[hidden] {
504
- .js-enabled & {
505
- display: block;
506
- }
507
- }
@@ -1,10 +1,9 @@
1
1
  @import "govuk/components/cookie-banner/cookie-banner";
2
2
  $govuk-cookie-banner-background: govuk-colour("light-grey", "grey-4");
3
3
 
4
- .gem-c-cookie-banner[hidden] {
5
- display: block; // shown with JS, always on for non-JS
6
- .js-enabled & {
7
- display: none;
4
+ .js-enabled {
5
+ .gem-c-cookie-banner {
6
+ display: none; // shown with JS, always on for non-JS
8
7
  }
9
8
  }
10
9
 
@@ -15,13 +14,9 @@ $govuk-cookie-banner-background: govuk-colour("light-grey", "grey-4");
15
14
  // can't be used without js so implement there
16
15
  .gem-c-cookie-banner .gem-c-button {
17
16
  display: none;
18
-
19
- .js-enabled & {
20
- display: block;
21
- }
22
17
  }
23
18
 
24
- .gem-c-cookie-banner__confirmation[hidden] {
19
+ .gem-c-cookie-banner__confirmation {
25
20
  display: none;
26
21
  position: relative;
27
22
  padding: govuk-spacing(1);
@@ -269,7 +269,11 @@ $search-icon-size: 20px;
269
269
  color: $govuk-link-colour;
270
270
 
271
271
  &:hover {
272
- color: govuk-colour("mid-grey");
272
+ color: $govuk-link-hover-colour;
273
+
274
+ @include govuk-media-query($from: "desktop") {
275
+ color: govuk-colour("mid-grey");
276
+ }
273
277
  }
274
278
 
275
279
  &:focus {
@@ -358,6 +362,10 @@ $search-icon-size: 20px;
358
362
  position: absolute;
359
363
  right: 45px;
360
364
 
365
+ &.gem-c-layout-super-navigation-header__open-button {
366
+ border-top-color: govuk-colour("black");
367
+ }
368
+
361
369
  @include govuk-media-query($from: 360px) {
362
370
  &:before {
363
371
  @include chevron("white");
@@ -388,8 +396,19 @@ $search-icon-size: 20px;
388
396
  position: absolute;
389
397
  right: (0 - govuk-spacing(3));
390
398
 
391
- &:hover {
392
- border-color: govuk-colour("black");
399
+ &:after {
400
+ background-color: $govuk-link-colour;
401
+ content: " ";
402
+ left: 0;
403
+ right: 0;
404
+ }
405
+
406
+ &:not(.gem-c-layout-super-navigation-header__open-button):focus {
407
+ &:hover,
408
+ &:after {
409
+ background-color: $govuk-focus-colour;
410
+ border-top-color: $govuk-focus-colour;
411
+ }
393
412
  }
394
413
 
395
414
  @include govuk-media-query($from: 360px) {
@@ -405,22 +424,6 @@ $search-icon-size: 20px;
405
424
  position: relative;
406
425
  float: right;
407
426
 
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
427
  &.gem-c-layout-super-navigation-header__open-button {
425
428
  border-top-color: govuk-colour("black");
426
429
 
@@ -486,7 +489,6 @@ $search-icon-size: 20px;
486
489
 
487
490
  &:focus {
488
491
  color: $govuk-focus-text-colour;
489
- // border-color: $govuk-focus-text-colour;
490
492
 
491
493
  &:after {
492
494
  background-color: $govuk-focus-text-colour;
@@ -501,10 +503,6 @@ $search-icon-size: 20px;
501
503
  &.gem-c-layout-super-navigation-header__open-button {
502
504
  border-top-color: govuk-colour("black");
503
505
 
504
- &:focus {
505
- border-top-color: $govuk-focus-colour;
506
- }
507
-
508
506
  &:before {
509
507
  transform: translateY(20%) rotate(225deg);
510
508
  }
@@ -1,5 +1,7 @@
1
1
  .gem-c-step-nav-header {
2
+ @include govuk-font(24, $weight: bold);
2
3
  @include govuk-text-colour;
4
+
3
5
  position: relative;
4
6
  padding: 10px;
5
7
  background: govuk-colour("light-grey", $legacy: "grey-4");
@@ -15,7 +17,3 @@
15
17
  @include govuk-font(19, $weight: bold);
16
18
  display: block;
17
19
  }
18
-
19
- .gem-c-step-nav-header__title {
20
- @include govuk-font(24, $weight: bold, $line-height: 1);
21
- }
@@ -29,7 +29,7 @@
29
29
  css_classes = %w(gem-c-cookie-banner govuk-clearfix)
30
30
  css_classes << "gem-c-cookie-banner--services" if services_cookies
31
31
  %>
32
- <div id="<%= id %>" class="<%= css_classes.join(' ') %>" data-module="cookie-banner" role="region" aria-label="cookie banner" data-nosnippet hidden>
32
+ <div id="<%= id %>" class="<%= css_classes.join(' ') %>" data-module="cookie-banner" role="region" aria-label="cookie banner" data-nosnippet>
33
33
  <div class="govuk-cookie-banner js-banner-wrapper" role="region" aria-label="<%= title %>">
34
34
  <div class="gem-c-cookie-banner__message govuk-cookie-banner__message govuk-width-container">
35
35
  <div class="govuk-grid-row">
@@ -14,7 +14,6 @@
14
14
  heading_link_classes = %w[
15
15
  gem-c-image-card__title-link
16
16
  govuk-link
17
- govuk-link--no-underline
18
17
  ]
19
18
  heading_link_classes << brand_helper.color_class
20
19
  extra_link_classes = %w[
@@ -11,6 +11,7 @@
11
11
  omit_header ||= false
12
12
  product_name ||= nil
13
13
  show_explore_header ||= false
14
+ draft_watermark ||= false
14
15
  show_search = local_assigns.include?(:show_search) ? local_assigns[:show_search] : true
15
16
  title ||= "GOV.UK - The best place to find government services and information"
16
17
 
@@ -39,6 +40,8 @@
39
40
  # when a) there's content for the emergency or global banner *and* b) when using
40
41
  # the contrained width layout.
41
42
  blue_bar_dedupe = !full_width && global_bar.present?
43
+ body_css_classes = %w(gem-c-layout-for-public govuk-template__body)
44
+ body_css_classes << "draft" if draft_watermark
42
45
  -%>
43
46
  <!DOCTYPE html>
44
47
  <!--[if lt IE 9]><html class="lte-ie8" lang="<%= html_lang %>"><![endif]-->
@@ -72,7 +75,7 @@
72
75
 
73
76
  <%= yield :head %>
74
77
  </head>
75
- <body class="gem-c-layout-for-public govuk-template__body">
78
+ <%= tag.body class: body_css_classes do %>
76
79
  <script>
77
80
  document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');
78
81
  </script>
@@ -147,5 +150,5 @@
147
150
  } %>
148
151
  <% end %>
149
152
  <%= javascript_include_tag 'application' %>
150
- </body>
153
+ <% end %>
151
154
  </html>
@@ -35,6 +35,15 @@ examples:
35
35
  image_alt: "some meaningful alt text please"
36
36
  heading_text: "I am not a heading"
37
37
  heading_level: 0
38
+ with_lazy_loading:
39
+ description: The image can have an attribute of lazy loading. Defaults to auto if not passed.
40
+ data:
41
+ href: "/really-not-a-page"
42
+ image_src: "https://assets.publishing.service.gov.uk/government/uploads/system/uploads/feature/image/62756/s300_courts-of-justice.JPG"
43
+ image_alt: "some meaningful alt text please"
44
+ image_loading: "lazy"
45
+ heading_text: "I am not a heading"
46
+ heading_level: 0
38
47
  with_different_link_size:
39
48
  description: |
40
49
  Set a different font size for the link. Uses the [GOV.UK Frontend heading sizes](https://design-system.service.gov.uk/styles/typography/#headings) but defaults to 19px for legacy reasons. Valid options are `xl`, `l`, `m` and `s`.
@@ -4,7 +4,7 @@ module GovukPublishingComponents
4
4
  include ActionView::Helpers
5
5
  include ActionView::Context
6
6
 
7
- attr_reader :href, :href_data_attributes, :extra_links, :large, :extra_links_no_indent, :heading_text, :metadata, :lang
7
+ attr_reader :href, :href_data_attributes, :extra_links, :large, :extra_links_no_indent, :heading_text, :metadata, :lang, :image_loading
8
8
 
9
9
  def initialize(local_assigns)
10
10
  @href = local_assigns[:href]
@@ -12,6 +12,7 @@ module GovukPublishingComponents
12
12
  @extra_links = local_assigns[:extra_links] || []
13
13
  @image_src = local_assigns[:image_src]
14
14
  @image_alt = local_assigns[:image_alt] || ""
15
+ @image_loading = local_assigns[:image_loading] || "auto"
15
16
  @context = local_assigns[:context]
16
17
  @description = local_assigns[:description]
17
18
  @large = local_assigns[:large]
@@ -35,7 +36,7 @@ module GovukPublishingComponents
35
36
  def image
36
37
  if @image_src
37
38
  content_tag(:figure, class: "gem-c-image-card__image-wrapper") do
38
- image_tag(@image_src, class: "gem-c-image-card__image", alt: @image_alt)
39
+ image_tag(@image_src, class: "gem-c-image-card__image", alt: @image_alt, loading: @image_loading)
39
40
  end
40
41
  end
41
42
  end
@@ -353,6 +353,9 @@ module GovukPublishingComponents
353
353
  {
354
354
  href: "/cymraeg",
355
355
  text: "Rhestr o Wasanaethau Cymraeg",
356
+ attributes: {
357
+ lang: "cy",
358
+ },
356
359
  },
357
360
  {
358
361
  href: "/government/organisations/government-digital-service",
@@ -1,3 +1,3 @@
1
1
  module GovukPublishingComponents
2
- VERSION = "25.3.0".freeze
2
+ VERSION = "25.6.0".freeze
3
3
  end
@@ -1751,6 +1751,47 @@ Checkboxes.prototype.syncConditionalRevealWithInputState = function ($input) {
1751
1751
  }
1752
1752
  };
1753
1753
 
1754
+ /**
1755
+ * Uncheck other checkboxes
1756
+ *
1757
+ * Find any other checkbox inputs with the same name value, and uncheck them.
1758
+ * This is useful for when a “None of these" checkbox is checked.
1759
+ */
1760
+ Checkboxes.prototype.unCheckAllInputsExcept = function ($input) {
1761
+ var allInputsWithSameName = document.querySelectorAll('input[type="checkbox"][name="' + $input.name + '"]');
1762
+
1763
+ nodeListForEach(allInputsWithSameName, function ($inputWithSameName) {
1764
+ var hasSameFormOwner = ($input.form === $inputWithSameName.form);
1765
+ if (hasSameFormOwner && $inputWithSameName !== $input) {
1766
+ $inputWithSameName.checked = false;
1767
+ }
1768
+ });
1769
+
1770
+ this.syncAllConditionalReveals();
1771
+ };
1772
+
1773
+ /**
1774
+ * Uncheck exclusive inputs
1775
+ *
1776
+ * Find any checkbox inputs with the same name value and the 'exclusive' behaviour,
1777
+ * and uncheck them. This helps prevent someone checking both a regular checkbox and a
1778
+ * "None of these" checkbox in the same fieldset.
1779
+ */
1780
+ Checkboxes.prototype.unCheckExclusiveInputs = function ($input) {
1781
+ var allInputsWithSameNameAndExclusiveBehaviour = document.querySelectorAll(
1782
+ 'input[data-behaviour="exclusive"][type="checkbox"][name="' + $input.name + '"]'
1783
+ );
1784
+
1785
+ nodeListForEach(allInputsWithSameNameAndExclusiveBehaviour, function ($exclusiveInput) {
1786
+ var hasSameFormOwner = ($input.form === $exclusiveInput.form);
1787
+ if (hasSameFormOwner) {
1788
+ $exclusiveInput.checked = false;
1789
+ }
1790
+ });
1791
+
1792
+ this.syncAllConditionalReveals();
1793
+ };
1794
+
1754
1795
  /**
1755
1796
  * Click event handler
1756
1797
  *
@@ -1762,12 +1803,29 @@ Checkboxes.prototype.syncConditionalRevealWithInputState = function ($input) {
1762
1803
  Checkboxes.prototype.handleClick = function (event) {
1763
1804
  var $target = event.target;
1764
1805
 
1765
- // If a checkbox with aria-controls, handle click
1766
- var isCheckbox = $target.getAttribute('type') === 'checkbox';
1806
+ // Ignore clicks on things that aren't checkbox inputs
1807
+ if ($target.type !== 'checkbox') {
1808
+ return
1809
+ }
1810
+
1811
+ // If the checkbox conditionally-reveals some content, sync the state
1767
1812
  var hasAriaControls = $target.getAttribute('aria-controls');
1768
- if (isCheckbox && hasAriaControls) {
1813
+ if (hasAriaControls) {
1769
1814
  this.syncConditionalRevealWithInputState($target);
1770
1815
  }
1816
+
1817
+ // No further behaviour needed for unchecking
1818
+ if (!$target.checked) {
1819
+ return
1820
+ }
1821
+
1822
+ // Handle 'exclusive' checkbox behaviour (ie "None of these")
1823
+ var hasBehaviourExclusive = ($target.getAttribute('data-behaviour') === 'exclusive');
1824
+ if (hasBehaviourExclusive) {
1825
+ this.unCheckAllInputsExcept($target);
1826
+ } else {
1827
+ this.unCheckExclusiveInputs($target);
1828
+ }
1771
1829
  };
1772
1830
 
1773
1831
  (function(undefined) {