govuk_publishing_components 64.1.0 → 64.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/components/modal-dialogue.js +0 -2
  3. data/app/assets/javascripts/govuk_publishing_components/components/select-with-search.js +33 -0
  4. data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux-reporter.js +16 -13
  5. data/app/assets/stylesheets/govuk_publishing_components/components/_heading.scss +4 -0
  6. data/app/assets/stylesheets/govuk_publishing_components/components/_image-card.scss +2 -2
  7. data/app/assets/stylesheets/govuk_publishing_components/components/_input.scss +4 -0
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_modal-dialogue.scss +1 -13
  9. data/app/views/govuk_publishing_components/components/_checkboxes.html.erb +48 -47
  10. data/app/views/govuk_publishing_components/components/docs/heading.yml +1 -1
  11. data/app/views/govuk_publishing_components/components/docs/textarea.yml +6 -8
  12. data/lib/govuk_publishing_components/presenters/checkboxes_helper.rb +6 -3
  13. data/lib/govuk_publishing_components/version.rb +1 -1
  14. data/node_modules/sortablejs/Sortable.js +102 -117
  15. data/node_modules/sortablejs/Sortable.min.js +2 -2
  16. data/node_modules/sortablejs/modular/sortable.complete.esm.js +102 -117
  17. data/node_modules/sortablejs/modular/sortable.core.esm.js +102 -117
  18. data/node_modules/sortablejs/modular/sortable.esm.js +102 -117
  19. data/node_modules/sortablejs/package.json +1 -1
  20. data/node_modules/sortablejs/src/Sortable.js +5 -2
  21. data/node_modules/sortablejs/src/utils.js +2 -2
  22. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a36e502c34c34ff4f3d4f3c68b2bdc3c73d2e0063e0681113d6fa86419256a1
4
- data.tar.gz: e7687186a40332b5fd8466c08bc37eaf061383053d571873b32efb1b19fe2140
3
+ metadata.gz: b76aa67410518b26c0c6d78c41091e672f6e365fc88b9da459cceb52839edcbb
4
+ data.tar.gz: 4ce5beffe1d098ae456534a6bb82e414092b645e96b0b342f75700c6b237a635
5
5
  SHA512:
6
- metadata.gz: 4e0e05ae52393e75403160be9fe4243b498d47f9241ef4245d75aad760093c614a9a6c636fa7b256deb1fb785a020f020142df49a06eb79710955689a71ec981
7
- data.tar.gz: 0146075f678ac78ee120d4bc495dc7a2251f93b93fd8c0a04478654f29d185151a97fe906db961ee0e46629cd43186031a4474ab95387fe211beca4432c9d2f4
6
+ metadata.gz: e7212d1dd0e31d1a87adf5463afb9b57b0751a398adabf47357f93586499ac70b2009c6032b9a4c356f9e07f63c9ef7d968041bcabc01d784a708d7703df704d
7
+ data.tar.gz: e3793bc2726f8e95f930dabcaf0a0cd8bd8e3bf14077c105b757878986fce456a74a9e1cc492488ad7f5be0bd3bc14cd5f9bed9cc54e260e763ef2a820168764
@@ -49,7 +49,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
49
49
 
50
50
  this.$html.classList.add('gem-o-template--modal')
51
51
  this.$body.classList.add('gem-o-template__body--modal')
52
- this.$body.classList.add('gem-o-template__body--blur')
53
52
  this.$focusedElementBeforeOpen = document.activeElement
54
53
  this.$module.style.display = 'block'
55
54
  this.$dialogBox.focus()
@@ -64,7 +63,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
64
63
 
65
64
  this.$html.classList.remove('gem-o-template--modal')
66
65
  this.$body.classList.remove('gem-o-template__body--modal')
67
- this.$body.classList.remove('gem-o-template__body--blur')
68
66
  this.$module.style.display = 'none'
69
67
  this.$focusedElementBeforeOpen.focus()
70
68
 
@@ -13,6 +13,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}
13
13
  return
14
14
  }
15
15
 
16
+ const blankOptionText = 'Select none'
16
17
  const placeholderOption = this.module.querySelector(
17
18
  'option[value=""]:first-child'
18
19
  )
@@ -42,6 +43,21 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}
42
43
  const inner = this.containerInner.element
43
44
  const input = this.input.element
44
45
  inner.prepend(input)
46
+ } else {
47
+ // Update text for blank option in the hidden select
48
+ const selectElement = this.passedElement.element
49
+ if (selectElement.id.search('blank') > 0) {
50
+ selectElement.firstChild.innerText = blankOptionText
51
+ }
52
+ // Update text for blank option in the choices dropdown
53
+ // choices.js 'lastChild' in this context is the listbox of choices:
54
+ const listbox = this.dropdown.element.lastChild
55
+ // choices.js 'firstChild' in this context is the first option.
56
+ // This always displays "Select One" for selects with a blank option:
57
+ var blankOption = listbox.firstChild
58
+ if (blankOption && blankOption.id.search('blank') > 0) {
59
+ blankOption.innerText = blankOptionText
60
+ }
45
61
  }
46
62
  // Add aria-labelledby to the listbox as well as the combobox
47
63
  const listbox = this.itemList.element
@@ -54,6 +70,23 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}
54
70
  }
55
71
  })
56
72
 
73
+ // Reset blank 'Select One' to 'Select None' on each change
74
+ // This is because choices.js rebuilds the widget on each
75
+ // change event and resets the text. We can't use the preferred
76
+ // refresh method as this loses the current state of the dropdown.
77
+ const selectElement = this.choices.passedElement.element
78
+ const listbox = this.choices.dropdown.element.lastChild
79
+ selectElement.addEventListener(
80
+ 'change',
81
+ function (event) {
82
+ var blankOption = listbox.firstChild
83
+ if (blankOption && blankOption.id.search('blank') > 0) {
84
+ blankOption.innerText = blankOptionText
85
+ }
86
+ },
87
+ false
88
+ )
89
+
57
90
  this.module.choices = this.choices
58
91
  }
59
92
 
@@ -286,7 +286,9 @@
286
286
  return sinceNavigationStart;
287
287
  }
288
288
 
289
- var version = "4.4.2";
289
+ var version = "4.4.3";
290
+ var pkg = {
291
+ version: version};
290
292
 
291
293
  function padStart(str, length$1, char) {
292
294
  while (str[length] < length$1) {
@@ -295,7 +297,8 @@
295
297
  return str;
296
298
  }
297
299
 
298
- var VERSION = version;
300
+ var pkgVersion = pkg.version;
301
+ var VERSION = pkgVersion;
299
302
  /**
300
303
  * Returns the version of the script as a float to be stored in legacy systems that do not support
301
304
  * string versions.
@@ -458,7 +461,7 @@
458
461
  emit("beacon", payload);
459
462
  }
460
463
  }
461
- catch (e) {
464
+ catch (_b) {
462
465
  // Intentionally empty; handled below
463
466
  }
464
467
  if (!this.isSent) {
@@ -636,7 +639,7 @@
636
639
  return currentSelector;
637
640
  }
638
641
  }
639
- catch (error) {
642
+ catch (_a) {
640
643
  // Do nothing.
641
644
  }
642
645
  return selector;
@@ -1461,7 +1464,7 @@
1461
1464
  // Seeing "Permission denied" errors, so do a simple try-catch.
1462
1465
  bCancelable = evt.cancelable;
1463
1466
  }
1464
- catch (e) {
1467
+ catch (_a) {
1465
1468
  // bail - no need to return anything
1466
1469
  logger.logEvent(52 /* LogEvent.InputEventPermissionError */);
1467
1470
  return;
@@ -2053,7 +2056,7 @@
2053
2056
  try {
2054
2057
  size += e.innerHTML[length];
2055
2058
  }
2056
- catch (e) {
2059
+ catch (_a) {
2057
2060
  // It seems like IE throws an error when accessing the innerHTML property
2058
2061
  logger.logEvent(53 /* LogEvent.InnerHtmlAccessError */);
2059
2062
  return -1;
@@ -2359,7 +2362,7 @@
2359
2362
  curtop += el.offsetTop;
2360
2363
  el = el.offsetParent;
2361
2364
  }
2362
- catch (e) {
2365
+ catch (_a) {
2363
2366
  // If we get an exception, just return the current values.
2364
2367
  return [curleft, curtop];
2365
2368
  }
@@ -2681,7 +2684,7 @@
2681
2684
  target = e.target;
2682
2685
  }
2683
2686
  }
2684
- catch (e) {
2687
+ catch (_a) {
2685
2688
  logger.logEvent(54 /* LogEvent.EventTargetAccessError */);
2686
2689
  }
2687
2690
  if (target) {
@@ -2827,7 +2830,7 @@
2827
2830
  }
2828
2831
  }
2829
2832
  }
2830
- catch (e) {
2833
+ catch (_a) {
2831
2834
  logger.logEvent(55 /* LogEvent.CookieReadError */);
2832
2835
  }
2833
2836
  return undefined;
@@ -2842,7 +2845,7 @@
2842
2845
  (globalConfig.cookieDomain ? "; domain=" + globalConfig.cookieDomain : "") +
2843
2846
  "; path=/; SameSite=Lax";
2844
2847
  }
2845
- catch (e) {
2848
+ catch (_a) {
2846
2849
  logger.logEvent(56 /* LogEvent.CookieSetError */);
2847
2850
  }
2848
2851
  }
@@ -2994,9 +2997,9 @@
2994
2997
  */
2995
2998
  function _runCommand(_a) {
2996
2999
  var fn = _a[0], args = _a.slice(1);
2997
- if (typeof globalLux[fn] === "function") {
2998
- // eslint-disable-next-line @typescript-eslint/ban-types
2999
- globalLux[fn].apply(globalLux, args);
3000
+ var method = globalLux[fn];
3001
+ if (typeof method === "function") {
3002
+ method.apply(globalLux, args);
3000
3003
  }
3001
3004
  }
3002
3005
  // Process the command queue
@@ -4,6 +4,10 @@
4
4
  // needs to be this specific to override govuk-heading
5
5
  .gem-c-heading__text {
6
6
  margin: 0;
7
+ // improve visual layout of headings
8
+ // set balance as a fallback for firefox, pretty for other browsers
9
+ text-wrap: balance;
10
+ text-wrap: pretty;
7
11
  }
8
12
  }
9
13
 
@@ -13,7 +13,7 @@
13
13
  @include govuk-text-colour;
14
14
 
15
15
  @include govuk-media-query($until: tablet) {
16
- flex-direction: row-reverse;
16
+ flex-direction: column-reverse;
17
17
  gap: govuk-spacing(3);
18
18
  }
19
19
  }
@@ -142,7 +142,7 @@
142
142
  border-top: none;
143
143
  }
144
144
 
145
- @include govuk-media-query($until: "mobile") {
145
+ @include govuk-media-query($until: mobile) {
146
146
  flex-direction: column-reverse;
147
147
  }
148
148
  }
@@ -14,3 +14,7 @@ $search-icon-size: 40px;
14
14
  height: govuk-px-to-rem($search-icon-size);
15
15
  background: url("govuk_publishing_components/icon-search.svg") no-repeat -3px center;
16
16
  }
17
+
18
+ .gem-c-input--with-search-icon {
19
+ padding-left: govuk-spacing(6);
20
+ }
@@ -71,10 +71,9 @@ $govuk-modal-wide-breakpoint: $govuk-page-width + $govuk-modal-margin * 2 + $gov
71
71
  left: 0;
72
72
  width: 100%;
73
73
  height: 100%;
74
- opacity: .8;
75
- background: govuk-colour("black");
76
74
  pointer-events: none;
77
75
  touch-action: none;
76
+ backdrop-filter: blur(2px) brightness(0.4);
78
77
  }
79
78
 
80
79
  .gem-o-template--modal {
@@ -87,17 +86,6 @@ $govuk-modal-wide-breakpoint: $govuk-page-width + $govuk-modal-margin * 2 + $gov
87
86
  overflow: hidden;
88
87
  }
89
88
 
90
- .gem-o-template__body--blur {
91
- .govuk-skip-link,
92
- .govuk-header,
93
- .govuk-phase-banner,
94
- .govuk-width-container .govuk-back-link,
95
- .govuk-footer,
96
- .govuk-main-wrapper {
97
- filter: blur(2px);
98
- }
99
- }
100
-
101
89
  .gem-c-modal-dialogue__header {
102
90
  padding: 9px govuk-spacing(3) 10px;
103
91
  color: govuk-colour("white");
@@ -1,65 +1,66 @@
1
- <%
2
- cb_helper = GovukPublishingComponents::Presenters::CheckboxesHelper.new(local_assigns)
3
- id = cb_helper.id
4
- component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns)
5
- component_helper.set_id(id)
6
- component_helper.add_class(cb_helper.css_classes.join(" ")) # cb_helper.css_classes generates "gem-c-checkboxes"
7
- component_helper.add_data_attribute({ module: "gem-checkboxes govuk-checkboxes" })
8
- %>
1
+ <% cb_helper = GovukPublishingComponents::Presenters::CheckboxesHelper.new(local_assigns) %>
2
+ <% if cb_helper.items.any? %>
3
+ <%
4
+ id = cb_helper.id
5
+ component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns)
6
+ component_helper.set_id(id)
7
+ component_helper.add_class(cb_helper.css_classes.join(" ")) # cb_helper.css_classes generates "gem-c-checkboxes"
8
+ component_helper.add_data_attribute({ module: "gem-checkboxes govuk-checkboxes" })
9
+ %>
10
+ <%= tag.div(**component_helper.all_attributes) do %>
11
+ <% if cb_helper.should_have_fieldset %>
12
+ <% if cb_helper.heading_markup %>
13
+ <%= tag.fieldset class: "govuk-fieldset", "aria-describedby": cb_helper.fieldset_describedby do %>
14
+ <%= cb_helper.heading_markup %>
9
15
 
10
- <%= tag.div(**component_helper.all_attributes) do %>
11
- <% if cb_helper.should_have_fieldset %>
12
- <% if cb_helper.heading_markup %>
13
- <%= tag.fieldset class: "govuk-fieldset", "aria-describedby": cb_helper.fieldset_describedby do %>
14
- <%= cb_helper.heading_markup %>
15
-
16
- <% if cb_helper.description %>
17
- <%= tag.div cb_helper.description, class: "govuk-body" %>
18
- <% end %>
16
+ <% if cb_helper.description %>
17
+ <%= tag.div cb_helper.description, class: "govuk-body" %>
18
+ <% end %>
19
19
 
20
- <% if cb_helper.hint_text %>
21
- <%= tag.div cb_helper.hint_text, id: "#{id}-hint", class: "govuk-hint" %>
22
- <% end %>
20
+ <% if cb_helper.hint_text %>
21
+ <%= tag.div cb_helper.hint_text, id: "#{id}-hint", class: "govuk-hint" %>
22
+ <% end %>
23
23
 
24
- <% if cb_helper.error %>
25
- <%= tag.p error, id: "#{id}-error", class: "govuk-error-message" %>
26
- <% end %>
24
+ <% if cb_helper.error %>
25
+ <%= tag.p error, id: "#{id}-error", class: "govuk-error-message" %>
26
+ <% end %>
27
27
 
28
- <%= tag.div class: "govuk-checkboxes", data: {
29
- module: ("govuk-checkboxes" if cb_helper.has_conditional),
30
- nested: ("true" if cb_helper.has_nested),
31
- } do %>
32
- <% cb_helper.items.each_with_index do |item, index| %>
33
- <% if item === :or %>
34
- <%= tag.div t("components.checkboxes.or"), class: "govuk-checkboxes__divider" %>
35
- <% else %>
36
- <%= tag.div class: "govuk-checkboxes__item" do %>
37
- <%= cb_helper.checkbox_markup(item, index) %>
28
+ <%= tag.div class: "govuk-checkboxes", data: {
29
+ module: ("govuk-checkboxes" if cb_helper.has_conditional),
30
+ nested: ("true" if cb_helper.has_nested),
31
+ } do %>
32
+ <% cb_helper.items.each_with_index do |item, index| %>
33
+ <% if item === :or %>
34
+ <%= tag.div t("components.checkboxes.or"), class: "govuk-checkboxes__divider" %>
35
+ <% else %>
36
+ <%= tag.div class: "govuk-checkboxes__item" do %>
37
+ <%= cb_helper.checkbox_markup(item, index) %>
38
38
 
39
- <% if item[:items].present? %>
40
- <%= tag.div id: "#{id}-nested-#{index}", class: "govuk-checkboxes--nested", data: { parent: "#{id}-#{index}" } do %>
41
- <% item[:items].each_with_index do |nested_item, nested_index| %>
42
- <%= tag.div class: "govuk-checkboxes__item" do %>
43
- <%= cb_helper.checkbox_markup(nested_item, "#{index}-#{nested_index}") %>
39
+ <% if item[:items].present? %>
40
+ <%= tag.div id: "#{id}-nested-#{index}", class: "govuk-checkboxes--nested", data: { parent: "#{id}-#{index}" } do %>
41
+ <% item[:items].each_with_index do |nested_item, nested_index| %>
42
+ <%= tag.div class: "govuk-checkboxes__item" do %>
43
+ <%= cb_helper.checkbox_markup(nested_item, "#{index}-#{nested_index}") %>
44
+ <% end %>
44
45
  <% end %>
45
46
  <% end %>
46
47
  <% end %>
47
48
  <% end %>
48
- <% end %>
49
49
 
50
- <% if item[:conditional] %>
51
- <%= tag.div item[:conditional], id: "#{id}-#{index}-conditional-#{index}", class: "govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden" %>
52
- <% end %>
50
+ <% if item[:conditional] %>
51
+ <%= tag.div item[:conditional], id: "#{id}-#{index}-conditional-#{index}", class: "govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden" %>
52
+ <% end %>
53
53
 
54
+ <% end %>
54
55
  <% end %>
55
56
  <% end %>
56
57
  <% end %>
57
58
  <% end %>
58
- <% end %>
59
59
 
60
- <% else %>
61
- <div class="govuk-checkboxes__item">
62
- <%= cb_helper.checkbox_markup(cb_helper.items[0], 0) %>
63
- </div>
60
+ <% else %>
61
+ <div class="govuk-checkboxes__item">
62
+ <%= cb_helper.checkbox_markup(cb_helper.items[0], 0) %>
63
+ </div>
64
+ <% end %>
64
65
  <% end %>
65
66
  <% end %>
@@ -30,7 +30,7 @@ examples:
30
30
 
31
31
  This option is not tied to the `heading_level` option in order to give flexibility.
32
32
  data:
33
- text: 'One big heading'
33
+ text: 'One big heading containing a number of words'
34
34
  font_size: "xl"
35
35
  right_to_left:
36
36
  data:
@@ -28,13 +28,6 @@ examples:
28
28
  text: "What is the nature of your medical emergency?"
29
29
  name: "emergency-name"
30
30
  textarea_id: "emergency-id"
31
- with_margin_bottom:
32
- description: The component accepts a number for margin bottom from `0` to `9` (`0px` to `60px`) using the [GOV.UK Frontend spacing scale](https://design-system.service.gov.uk/styles/spacing/#the-responsive-spacing-scale). It defaults to a margin bottom of 6 (30px).
33
- data:
34
- margin_bottom: 9
35
- label:
36
- text: "Can you provide more detail?"
37
- name: "more-detail"
38
31
  specific_rows:
39
32
  description: Textarea with 10 rows
40
33
  data:
@@ -64,6 +57,12 @@ examples:
64
57
  href: '#example-error-1'
65
58
  - text: Descriptive link to the question with an error 2
66
59
  href: '#example-error-2'
60
+ with bold_label:
61
+ data:
62
+ label:
63
+ text: "Can you provide more detail?"
64
+ bold: true
65
+ name: "more-detail"
67
66
  with_label_as_page_heading:
68
67
  data:
69
68
  label:
@@ -106,7 +105,6 @@ examples:
106
105
  textarea_id: "contextual-guidance-id"
107
106
  label:
108
107
  text: "Title"
109
- bold: true
110
108
  name: "described"
111
109
  rows: 2
112
110
  describedby: "contextual-guidance"
@@ -17,6 +17,8 @@ module GovukPublishingComponents
17
17
 
18
18
  def initialize(options)
19
19
  @items = options[:items] || []
20
+ return unless @items.any?
21
+
20
22
  @name = options[:name]
21
23
  @css_classes = %w[gem-c-checkboxes govuk-form-group]
22
24
  @css_classes << "govuk-form-group--error" if options[:error]
@@ -24,8 +26,8 @@ module GovukPublishingComponents
24
26
  @error = true if options[:error]
25
27
 
26
28
  # check if any item is set as being conditional
27
- @has_conditional = options[:items].any? { |item| item.is_a?(Hash) && item[:conditional] }
28
- @has_nested = options[:items].any? { |item| item.is_a?(Hash) && item[:items] }
29
+ @has_conditional = @items.any? { |item| item.is_a?(Hash) && item[:conditional] }
30
+ @has_nested = @items.any? { |item| item.is_a?(Hash) && item[:items] }
29
31
 
30
32
  @id = options[:id] || "checkboxes-#{SecureRandom.hex(4)}"
31
33
  @heading = options[:heading] || nil
@@ -41,7 +43,7 @@ module GovukPublishingComponents
41
43
  # should have a fieldset if there's a heading, or if more than one checkbox
42
44
  # separate check is in the view for if more than one checkbox and no heading, in which case fail
43
45
  def should_have_fieldset
44
- @items.length > 1 || @heading
46
+ @items.length > 1 || !@heading.blank? # rubocop:disable Rails/Present
45
47
  end
46
48
 
47
49
  def fieldset_describedby
@@ -91,6 +93,7 @@ module GovukPublishingComponents
91
93
  checked = true if checkbox[:checked].present?
92
94
  data = checkbox[:data_attributes] || {}
93
95
  data[:controls] = controls
96
+ # aria-controls is set as a data attribute then applied properly using JS
94
97
  data["aria-controls"] = aria_controls
95
98
  data[:behaviour] = "exclusive" if checkbox[:exclusive]
96
99
 
@@ -1,3 +1,3 @@
1
1
  module GovukPublishingComponents
2
- VERSION = "64.1.0".freeze
2
+ VERSION = "64.1.2".freeze
3
3
  end