govuk_publishing_components 58.1.0 → 58.2.0

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 (148) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/select-with-search/cross-icon.svg +6 -0
  3. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-search-tracker.js +4 -0
  4. data/app/assets/javascripts/govuk_publishing_components/components/select-with-search.js +57 -0
  5. data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
  6. data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +7 -2
  7. data/app/assets/stylesheets/govuk_publishing_components/components/_select-with-search.scss +168 -0
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_select.scss +6 -0
  9. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_contact.scss +10 -10
  10. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_typography.scss +3 -16
  11. data/app/views/govuk_publishing_components/components/_add_another.html.erb +0 -1
  12. data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +1 -1
  13. data/app/views/govuk_publishing_components/components/_select.html.erb +22 -23
  14. data/app/views/govuk_publishing_components/components/_select_with_search.html.erb +14 -0
  15. data/app/views/govuk_publishing_components/components/docs/select.yml +11 -0
  16. data/app/views/govuk_publishing_components/components/docs/select_with_search.yml +196 -0
  17. data/lib/govuk_publishing_components/presenters/select_helper.rb +8 -5
  18. data/lib/govuk_publishing_components/presenters/select_with_search_helper.rb +92 -0
  19. data/lib/govuk_publishing_components/version.rb +1 -1
  20. data/lib/govuk_publishing_components.rb +1 -0
  21. data/node_modules/choices.js/LICENSE +21 -0
  22. data/node_modules/choices.js/README.md +1360 -0
  23. data/node_modules/choices.js/package.json +173 -0
  24. data/node_modules/choices.js/public/assets/scripts/choices.js +5230 -0
  25. data/node_modules/choices.js/public/assets/scripts/choices.min.js +2 -0
  26. data/node_modules/choices.js/public/assets/scripts/choices.mjs +5222 -0
  27. data/node_modules/choices.js/public/assets/scripts/choices.search-basic.js +4748 -0
  28. data/node_modules/choices.js/public/assets/scripts/choices.search-basic.min.js +2 -0
  29. data/node_modules/choices.js/public/assets/scripts/choices.search-basic.mjs +4740 -0
  30. data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.js +3631 -0
  31. data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.min.js +2 -0
  32. data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.mjs +3623 -0
  33. data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.js +3590 -0
  34. data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.min.js +2 -0
  35. data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.mjs +3582 -0
  36. data/node_modules/choices.js/public/assets/styles/base.css +180 -0
  37. data/node_modules/choices.js/public/assets/styles/base.css.map +1 -0
  38. data/node_modules/choices.js/public/assets/styles/base.min.css +1 -0
  39. data/node_modules/choices.js/public/assets/styles/choices.css +338 -0
  40. data/node_modules/choices.js/public/assets/styles/choices.css.map +1 -0
  41. data/node_modules/choices.js/public/assets/styles/choices.min.css +1 -0
  42. data/node_modules/choices.js/public/types/src/index.d.ts +6 -0
  43. data/node_modules/choices.js/public/types/src/scripts/actions/choices.d.ts +30 -0
  44. data/node_modules/choices.js/public/types/src/scripts/actions/groups.d.ts +8 -0
  45. data/node_modules/choices.js/public/types/src/scripts/actions/items.d.ts +17 -0
  46. data/node_modules/choices.js/public/types/src/scripts/choices.d.ts +210 -0
  47. data/node_modules/choices.js/public/types/src/scripts/components/container.d.ts +36 -0
  48. data/node_modules/choices.js/public/types/src/scripts/components/dropdown.d.ts +21 -0
  49. data/node_modules/choices.js/public/types/src/scripts/components/index.d.ts +7 -0
  50. data/node_modules/choices.js/public/types/src/scripts/components/input.d.ts +37 -0
  51. data/node_modules/choices.js/public/types/src/scripts/components/list.d.ts +14 -0
  52. data/node_modules/choices.js/public/types/src/scripts/components/wrapped-element.d.ts +21 -0
  53. data/node_modules/choices.js/public/types/src/scripts/components/wrapped-input.d.ts +3 -0
  54. data/node_modules/choices.js/public/types/src/scripts/components/wrapped-select.d.ts +20 -0
  55. data/node_modules/choices.js/public/types/src/scripts/constants.d.ts +1 -0
  56. data/node_modules/choices.js/public/types/src/scripts/defaults.d.ts +4 -0
  57. data/node_modules/choices.js/public/types/src/scripts/interfaces/action-type.d.ts +13 -0
  58. data/node_modules/choices.js/public/types/src/scripts/interfaces/build-flags.d.ts +11 -0
  59. data/node_modules/choices.js/public/types/src/scripts/interfaces/choice-full.d.ts +23 -0
  60. data/node_modules/choices.js/public/types/src/scripts/interfaces/class-names.d.ts +61 -0
  61. data/node_modules/choices.js/public/types/src/scripts/interfaces/event-choice.d.ts +7 -0
  62. data/node_modules/choices.js/public/types/src/scripts/interfaces/event-type.d.ts +14 -0
  63. data/node_modules/choices.js/public/types/src/scripts/interfaces/group-full.d.ts +10 -0
  64. data/node_modules/choices.js/public/types/src/scripts/interfaces/index.d.ts +14 -0
  65. data/node_modules/choices.js/public/types/src/scripts/interfaces/input-choice.d.ts +15 -0
  66. data/node_modules/choices.js/public/types/src/scripts/interfaces/input-group.d.ts +10 -0
  67. data/node_modules/choices.js/public/types/src/scripts/interfaces/item.d.ts +17 -0
  68. data/node_modules/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts +13 -0
  69. data/node_modules/choices.js/public/types/src/scripts/interfaces/options.d.ts +566 -0
  70. data/node_modules/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts +7 -0
  71. data/node_modules/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts +95 -0
  72. data/node_modules/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts +1 -0
  73. data/node_modules/choices.js/public/types/src/scripts/interfaces/search.d.ts +11 -0
  74. data/node_modules/choices.js/public/types/src/scripts/interfaces/state.d.ts +10 -0
  75. data/node_modules/choices.js/public/types/src/scripts/interfaces/store.d.ts +64 -0
  76. data/node_modules/choices.js/public/types/src/scripts/interfaces/string-pre-escaped.d.ts +3 -0
  77. data/node_modules/choices.js/public/types/src/scripts/interfaces/string-untrusted.d.ts +4 -0
  78. data/node_modules/choices.js/public/types/src/scripts/interfaces/templates.d.ts +29 -0
  79. data/node_modules/choices.js/public/types/src/scripts/interfaces/types.d.ts +18 -0
  80. data/node_modules/choices.js/public/types/src/scripts/lib/choice-input.d.ts +9 -0
  81. data/node_modules/choices.js/public/types/src/scripts/lib/html-guard-statements.d.ts +4 -0
  82. data/node_modules/choices.js/public/types/src/scripts/lib/utils.d.ts +31 -0
  83. data/node_modules/choices.js/public/types/src/scripts/reducers/choices.d.ts +8 -0
  84. data/node_modules/choices.js/public/types/src/scripts/reducers/groups.d.ts +8 -0
  85. data/node_modules/choices.js/public/types/src/scripts/reducers/items.d.ts +9 -0
  86. data/node_modules/choices.js/public/types/src/scripts/search/fuse.d.ts +14 -0
  87. data/node_modules/choices.js/public/types/src/scripts/search/index.d.ts +3 -0
  88. data/node_modules/choices.js/public/types/src/scripts/search/kmp.d.ts +11 -0
  89. data/node_modules/choices.js/public/types/src/scripts/search/prefix-filter.d.ts +11 -0
  90. data/node_modules/choices.js/public/types/src/scripts/store/store.d.ts +59 -0
  91. data/node_modules/choices.js/public/types/src/scripts/templates.d.ts +8 -0
  92. data/node_modules/choices.js/src/entry.js +3 -0
  93. data/node_modules/choices.js/src/icons/cross-inverse.svg +1 -0
  94. data/node_modules/choices.js/src/icons/cross.svg +1 -0
  95. data/node_modules/choices.js/src/index.ts +8 -0
  96. data/node_modules/choices.js/src/scripts/actions/choices.ts +59 -0
  97. data/node_modules/choices.js/src/scripts/actions/groups.ts +14 -0
  98. data/node_modules/choices.js/src/scripts/actions/items.ts +34 -0
  99. data/node_modules/choices.js/src/scripts/choices.ts +2364 -0
  100. data/node_modules/choices.js/src/scripts/components/container.ts +157 -0
  101. data/node_modules/choices.js/src/scripts/components/dropdown.ts +50 -0
  102. data/node_modules/choices.js/src/scripts/components/index.ts +8 -0
  103. data/node_modules/choices.js/src/scripts/components/input.ts +146 -0
  104. data/node_modules/choices.js/src/scripts/components/list.ts +89 -0
  105. data/node_modules/choices.js/src/scripts/components/wrapped-element.ts +89 -0
  106. data/node_modules/choices.js/src/scripts/components/wrapped-input.ts +3 -0
  107. data/node_modules/choices.js/src/scripts/components/wrapped-select.ts +115 -0
  108. data/node_modules/choices.js/src/scripts/constants.ts +1 -0
  109. data/node_modules/choices.js/src/scripts/defaults.ts +93 -0
  110. data/node_modules/choices.js/src/scripts/interfaces/action-type.ts +15 -0
  111. data/node_modules/choices.js/src/scripts/interfaces/build-flags.ts +17 -0
  112. data/node_modules/choices.js/src/scripts/interfaces/choice-full.ts +30 -0
  113. data/node_modules/choices.js/src/scripts/interfaces/class-names.ts +61 -0
  114. data/node_modules/choices.js/src/scripts/interfaces/event-choice.ts +9 -0
  115. data/node_modules/choices.js/src/scripts/interfaces/event-type.ts +16 -0
  116. data/node_modules/choices.js/src/scripts/interfaces/group-full.ts +12 -0
  117. data/node_modules/choices.js/src/scripts/interfaces/index.ts +14 -0
  118. data/node_modules/choices.js/src/scripts/interfaces/input-choice.ts +17 -0
  119. data/node_modules/choices.js/src/scripts/interfaces/input-group.ts +11 -0
  120. data/node_modules/choices.js/src/scripts/interfaces/item.ts +17 -0
  121. data/node_modules/choices.js/src/scripts/interfaces/keycode-map.ts +13 -0
  122. data/node_modules/choices.js/src/scripts/interfaces/options.ts +619 -0
  123. data/node_modules/choices.js/src/scripts/interfaces/passed-element-type.ts +9 -0
  124. data/node_modules/choices.js/src/scripts/interfaces/passed-element.ts +96 -0
  125. data/node_modules/choices.js/src/scripts/interfaces/position-options-type.ts +1 -0
  126. data/node_modules/choices.js/src/scripts/interfaces/search.ts +12 -0
  127. data/node_modules/choices.js/src/scripts/interfaces/state.ts +12 -0
  128. data/node_modules/choices.js/src/scripts/interfaces/store.ts +84 -0
  129. data/node_modules/choices.js/src/scripts/interfaces/string-pre-escaped.ts +3 -0
  130. data/node_modules/choices.js/src/scripts/interfaces/string-untrusted.ts +5 -0
  131. data/node_modules/choices.js/src/scripts/interfaces/templates.ts +66 -0
  132. data/node_modules/choices.js/src/scripts/interfaces/types.ts +21 -0
  133. data/node_modules/choices.js/src/scripts/lib/choice-input.ts +88 -0
  134. data/node_modules/choices.js/src/scripts/lib/html-guard-statements.ts +7 -0
  135. data/node_modules/choices.js/src/scripts/lib/utils.ts +230 -0
  136. data/node_modules/choices.js/src/scripts/reducers/choices.ts +86 -0
  137. data/node_modules/choices.js/src/scripts/reducers/groups.ts +32 -0
  138. data/node_modules/choices.js/src/scripts/reducers/items.ts +86 -0
  139. data/node_modules/choices.js/src/scripts/search/fuse.ts +59 -0
  140. data/node_modules/choices.js/src/scripts/search/index.ts +17 -0
  141. data/node_modules/choices.js/src/scripts/search/kmp.ts +87 -0
  142. data/node_modules/choices.js/src/scripts/search/prefix-filter.ts +42 -0
  143. data/node_modules/choices.js/src/scripts/store/store.ts +184 -0
  144. data/node_modules/choices.js/src/scripts/templates.ts +409 -0
  145. data/node_modules/choices.js/src/styles/base.scss +189 -0
  146. data/node_modules/choices.js/src/styles/choices.scss +414 -0
  147. data/node_modules/choices.js/src/tsconfig.json +22 -0
  148. metadata +134 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d82f0a7a1e3c345f7d84859133afe0bb1df1e6561663f4c5937b411cbede75cb
4
- data.tar.gz: 80fe207fb320c15fcb156ebebc3fa66d8c3b452b52fb5d436acec39065840d84
3
+ metadata.gz: 8766d04b5c4c4d7fab4d972b014cc0ac72f541321146789b75c64414b60aeb08
4
+ data.tar.gz: d6915e235caf1ea065a3f6f001ef34d797f76187cd58f199ba8ff20e242fb062
5
5
  SHA512:
6
- metadata.gz: 70f839bf58c4d8d06037a121875656558f9badc69a322b2886946a94f541040d7db7252904733bc852797691442c9d18fdac1d102737d5369688cbbdf248ef65
7
- data.tar.gz: c0e347b5a6d110077c68a41af3a05aef428a4329a5a6ea422ce94c7ea4d6b94fc8e0b2d59f23239608e5662db11b7d5faba456422e0c6ee4b14f9cf9d2d4e8e4
6
+ metadata.gz: 1aaa22f84475dd4bd8b5bd26d6af93a3e456c999ff9eeffd4631dac8d87b50e7dfed42db8b845cff27408812d7314d9acfb8440109887e137b9208b13ccce8c2
7
+ data.tar.gz: bb8b3b01adf12c73c771b6366abf277fb263d33149a853188785e308389b9d6c8202c6fcf3301c037a3ac602b65861a4bcdcb210646736dd9dfeb9e3109424a0
@@ -0,0 +1,6 @@
1
+ <svg width='21' height='21' viewBox='0 0 21 21' xmlns='http://www.w3.org/2000/svg'>
2
+ <g fill='#000' fill-rule='evenodd'>
3
+ <path d='M2.592.044l18.364 18.364-2.548 2.548L.044 2.592z' />
4
+ <path d='M0 18.364L18.364 0l2.548 2.548L2.548 20.912z' />
5
+ </g>
6
+ </svg>
@@ -9,6 +9,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
9
9
  this.$module = $module
10
10
  this.$searchInput = this.$module.querySelector('input[type="search"]')
11
11
 
12
+ this.searchInputName = this.$module.dataset.ga4SearchInputName
12
13
  this.type = this.$module.dataset.ga4SearchType
13
14
  this.url = this.$module.dataset.ga4SearchUrl
14
15
  this.section = this.$module.dataset.ga4SearchSection
@@ -44,6 +45,9 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
44
45
 
45
46
  setTriggeredAction (event) {
46
47
  if (event.target.type === 'search') {
48
+ // if `searchInputName` set then only set `triggeredAction` to `search`
49
+ // if changed `input[type=search]` matches `input[name=searchInputName]`
50
+ if (this.searchInputName && event.target.name !== this.searchInputName) return
47
51
  this.triggeredAction = 'search'
48
52
  } else if (this.triggeredAction !== 'search') {
49
53
  // The 'search' action always takes precedence over the 'filter' action, so only set the
@@ -0,0 +1,57 @@
1
+ //= require choices.js/public/assets/scripts/choices.min.js
2
+ 'use strict'
3
+ window.GOVUK = window.GOVUK || {}
4
+ window.GOVUK.Modules = window.GOVUK.Modules || {}
5
+ ;(function (Modules) {
6
+ function SelectWithSearch (module) {
7
+ this.module = module
8
+ }
9
+
10
+ SelectWithSearch.prototype.init = function () {
11
+ if (!this.module.matches('select')) {
12
+ console.error('Module is not a select element')
13
+ return
14
+ }
15
+
16
+ const placeholderOption = this.module.querySelector(
17
+ 'option[value=""]:first-child'
18
+ )
19
+
20
+ if (placeholderOption && placeholderOption.textContent === '') {
21
+ placeholderOption.textContent = this.module.multiple
22
+ ? 'Select all that apply'
23
+ : 'Select one'
24
+ }
25
+
26
+ const ariaDescribedBy = this.module.getAttribute('aria-describedby') || ''
27
+
28
+ this.choices = new window.Choices(this.module, {
29
+ allowHTML: true,
30
+ searchPlaceholderValue: 'Search in list',
31
+ shouldSort: false, // show options and groups in the order they were given
32
+ itemSelectText: '',
33
+ searchResultLimit: 100,
34
+ removeItemButton: this.module.multiple,
35
+ labelId: this.module.id + '-label ' + ariaDescribedBy,
36
+ callbackOnInit: function () {
37
+ // For the multiple select, move the input field to
38
+ // the top of the feedback area, so that the selected
39
+ // 'lozenges' appear afterwards in a more natural flow
40
+ if (this.dropdown.type === 'select-multiple') {
41
+ const inner = this.containerInner.element
42
+ const input = this.input.element
43
+ inner.prepend(input)
44
+ }
45
+ },
46
+ // https://fusejs.io/api/options.html
47
+ fuseOptions: {
48
+ ignoreLocation: true, // matches any part of the string
49
+ threshold: 0 // only matches when characters are sequential
50
+ }
51
+ })
52
+
53
+ this.module.choices = this.choices
54
+ }
55
+
56
+ Modules.SelectWithSearch = SelectWithSearch
57
+ })(window.GOVUK.Modules)
@@ -75,6 +75,7 @@
75
75
  @import "components/search";
76
76
  @import "components/secondary-navigation";
77
77
  @import "components/select";
78
+ @import "components/select-with-search";
78
79
  @import "components/service-navigation";
79
80
  @import "components/share-links";
80
81
  @import "components/signup-link";
@@ -8,7 +8,7 @@ $chevron-indent-spacing: 7px;
8
8
 
9
9
  $pseudo-underline-height: 3px;
10
10
 
11
- $navbar-height: 60px;
11
+ $navbar-height: 61px;
12
12
 
13
13
  $button-pipe-colour: $govuk-blue-tint-95;
14
14
 
@@ -98,7 +98,6 @@ $search-icon-height: 20px;
98
98
  background: $govuk-brand-colour;
99
99
  border-top: 1px solid $govuk-brand-colour;
100
100
  margin-top: -1px;
101
- border-bottom: 1px solid transparent;
102
101
  position: relative;
103
102
 
104
103
  [hidden] {
@@ -694,4 +693,10 @@ $search-icon-height: 20px;
694
693
  padding: 10px 0 !important; // stylelint-disable-line declaration-no-important
695
694
  }
696
695
  }
696
+
697
+ // Used to add a transparent bottom border for forced-colour modes
698
+ .transparent-bottom-border {
699
+ border-bottom: 1px solid transparent;
700
+ }
701
+
697
702
  // stylelint-enable max-nesting-depth
@@ -0,0 +1,168 @@
1
+ // overload the choices.js variables
2
+
3
+ $font-size: 19px;
4
+
5
+ $choices-bg-color: govuk-colour("white") !default;
6
+ $choices-font-size-lg: $font-size !default;
7
+ $choices-font-size-md: $font-size !default;
8
+ $choices-font-size-sm: $font-size !default;
9
+ $choices-primary-color: #ffffff !default; // can't use mixin here because of Choices.js Sass functions
10
+ $choices-text-color: govuk-colour("black");
11
+ $choices-icon-cross: url("select-with-search/cross-icon.svg");
12
+ $choices-border-radius: 0 !default;
13
+ $choices-border-radius-item: 0 !default;
14
+ $choices-z-index: 2 !default;
15
+ $choices-button-dimension: 12px !default;
16
+
17
+ @import "govuk_publishing_components/individual_component_support";
18
+ @import "mixins/prefixed-transform";
19
+ @import "govuk/components/label/label";
20
+ @import "choices.js/src/styles/choices";
21
+
22
+ .gem-c-select-with-search {
23
+ .choices * {
24
+ // Something inside .choices needs this – I'm not sure what yet
25
+ box-sizing: border-box;
26
+ font-family: $govuk-font-family;
27
+ }
28
+
29
+ .choices[data-type*="select-one"]::after {
30
+ @include govuk-shape-arrow($direction: down, $base: 10px, $display: inline-block);
31
+ @include prefixed-transform($translateY: -50%);
32
+ margin: 0;
33
+ }
34
+
35
+ .choices.is-open[data-type*="select-one"]::after {
36
+ margin: 0;
37
+ bottom: govuk-em(1px, $font-size);
38
+ @include prefixed-transform($translateY: -50%, $rotate: 180deg);
39
+ }
40
+
41
+ .choices[data-type*="select-multiple"] .choices__button,
42
+ .choices[data-type*="text"] .choices__button {
43
+ border-color: govuk-colour("mid-grey");
44
+ border-right: 1px solid govuk-colour("mid-grey");
45
+ padding: govuk-spacing(2) govuk-spacing(4) govuk-spacing(2) govuk-spacing(2);
46
+ margin-right: 0;
47
+
48
+ &:hover {
49
+ background-color: govuk-colour("mid-grey");
50
+ border-color: govuk-colour("dark-grey");
51
+ box-shadow: 0 $govuk-border-width-form-element 0 govuk-colour("dark-grey");
52
+ }
53
+
54
+ &:focus {
55
+ background-color: $govuk-focus-colour;
56
+ box-shadow: 0 $govuk-border-width-form-element 0 $govuk-focus-text-colour;
57
+ }
58
+ }
59
+
60
+ .choices.is-disabled {
61
+ .choices__item[data-deletable] {
62
+ background-color: govuk-colour("white");
63
+ }
64
+
65
+ .choices__button {
66
+ display: none;
67
+ }
68
+ }
69
+
70
+ .choices__input {
71
+ display: block;
72
+ margin-bottom: 0;
73
+ }
74
+
75
+ .choices__inner {
76
+ padding: govuk-spacing(1);
77
+ border: $govuk-border-width-form-element solid govuk-colour("black");
78
+ }
79
+
80
+ &.govuk-form-group--error .choices:not(.is-active):not(.is-focused):not(.is-open) .choices__inner {
81
+ border-color: $govuk-error-colour;
82
+ }
83
+
84
+ .choices.is-focused,
85
+ .choices.is-open {
86
+ overflow: visible;
87
+ }
88
+
89
+ .choices.is-flipped .choices__list {
90
+ border-radius: 0; // this isn't set by a variable unlike all other border radius :(
91
+ border-width: $govuk-border-width-form-element;
92
+ }
93
+
94
+ .choices.is-focused .choices__inner,
95
+ .choices.is-open .choices__inner {
96
+ outline: $govuk-focus-width solid $govuk-focus-colour;
97
+ // Ensure outline appears outside of the element
98
+ outline-offset: 0;
99
+ // Double the border by adding its width again. Use `box-shadow` to do
100
+ // this instead of changing `border-width` (which changes element size)
101
+ // and since `outline` is already used for the yellow focus state.
102
+ box-shadow: inset 0 0 0 $govuk-border-width-form-element;
103
+ }
104
+
105
+ .choices__list--multiple {
106
+ display: block;
107
+
108
+ &:not(:empty) {
109
+ margin-block-start: 6px;
110
+ border-block-start: 1px solid $govuk-border-colour;
111
+ padding-block-end: 5px;
112
+ }
113
+ }
114
+
115
+ .choices__list--multiple .choices__item {
116
+ display: inline-flex;
117
+ align-items: center;
118
+ border: 0;
119
+ padding: 0 0 0 govuk-spacing(2);
120
+ margin: govuk-spacing(2) govuk-spacing(2) 0 0;
121
+ background-color: govuk-colour("light-grey");
122
+ box-shadow: 0 $govuk-border-width-form-element 0 govuk-colour("mid-grey");
123
+ line-height: 1;
124
+ color: $govuk-text-colour;
125
+
126
+ .is-disabled & {
127
+ opacity: 0.5;
128
+ }
129
+ }
130
+
131
+ // Dropdown
132
+ .choices__list--dropdown,
133
+ .choices__list[aria-expanded] {
134
+ border: $govuk-border-width-form-element solid govuk-colour("black");
135
+ border-top-width: 0;
136
+
137
+ .is-flipped & {
138
+ border-top-width: $govuk-border-width-form-element;
139
+ border-bottom-width: 0;
140
+ }
141
+ }
142
+
143
+ .choices__list--dropdown .choices__item,
144
+ .choices__list[aria-expanded] .choices__item {
145
+ position: relative;
146
+ border-bottom: 1px solid govuk-colour("mid-grey");
147
+
148
+ &:last-child {
149
+ border-bottom: 0;
150
+ }
151
+ }
152
+
153
+ .choices__list--dropdown .choices__item--selectable.is-highlighted,
154
+ .choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
155
+ background-color: govuk-colour("blue");
156
+ border-color: govuk-colour("blue");
157
+ color: govuk-colour("white");
158
+ outline: none;
159
+ }
160
+
161
+ .choices__heading {
162
+ @include govuk-typography-weight-bold;
163
+ color: govuk-colour("black"); // Choices.js doesn't use a variable for this color for some reason :(
164
+ padding: govuk-spacing(6) govuk-spacing(2) govuk-spacing(2);
165
+ border-bottom: 1px solid govuk-colour("mid-grey");
166
+ cursor: default;
167
+ }
168
+ }
@@ -1,6 +1,12 @@
1
1
  @import "govuk_publishing_components/individual_component_support";
2
2
  @import "govuk/components/select/select";
3
3
 
4
+ // Increase height of selects that have a `multiple`
5
+ // attribute otherwise they are too small to be useful.
6
+ .govuk-select[multiple] {
7
+ height: auto;
8
+ }
9
+
4
10
  .gem-c-select__select--full-width {
5
11
  min-width: 100%;
6
12
  max-width: 100%;
@@ -31,20 +31,20 @@
31
31
  }
32
32
  }
33
33
 
34
+ .email-url-number {
35
+ .email {
36
+ word-wrap: break-word;
37
+ }
38
+
39
+ span {
40
+ display: block;
41
+ }
42
+ }
43
+
34
44
  .content {
35
45
  float: none;
36
46
  width: 100%;
37
47
 
38
- .email-url-number {
39
- .email {
40
- word-wrap: break-word;
41
- }
42
-
43
- span {
44
- display: block;
45
- }
46
- }
47
-
48
48
  .comments {
49
49
  @include govuk-font($size: 16);
50
50
  @include govuk-media-query($from: tablet) {
@@ -53,26 +53,13 @@
53
53
  }
54
54
 
55
55
  &.gem-c-govspeak--direction-rtl blockquote {
56
- padding: 0 govuk-spacing(4) 0 0;
57
-
58
- @include govuk-media-query($from: desktop) {
59
- margin: 0 (- govuk-spacing(6)) 0 0;
60
- }
56
+ padding: 0 govuk-spacing(6) 0 0;
61
57
 
62
58
  p {
63
- padding-right: govuk-spacing(3);
64
- padding-left: 0;
65
-
66
- @include govuk-media-query($from: tablet) {
67
- padding-right: govuk-spacing(6);
68
- padding-left: 0;
69
- }
70
-
71
59
  &::before {
72
60
  content: "\201D";
73
- float: right;
74
- margin-right: (- govuk-spacing(3));
75
- margin-left: 0;
61
+ right: auto;
62
+ left: 100%;
76
63
  }
77
64
 
78
65
  &:last-child::after {
@@ -11,7 +11,6 @@
11
11
  component_helper.add_class("gem-c-add-another")
12
12
  component_helper.add_data_attribute({
13
13
  module: "add-another",
14
- ga4_start_index: 3,
15
14
  add_button_text:,
16
15
  fieldset_legend:,
17
16
  empty_fields:,
@@ -43,7 +43,7 @@
43
43
  %>
44
44
  <%= tag.header(**component_helper.all_attributes) do %>
45
45
  <div class="gem-c-layout-super-navigation-header__container govuk-clearfix">
46
- <div class="govuk-width-container">
46
+ <div class="govuk-width-container transparent-bottom-border">
47
47
  <%= content_tag(:div, {
48
48
  class: header_logo_classes
49
49
  }) do %>
@@ -8,42 +8,41 @@
8
8
  is_page_heading ||= false
9
9
  data_attributes ||= {}
10
10
  aria_controls ||= nil
11
+ heading_size ||= false
12
+ multiple ||= false
13
+ include_blank ||= false
11
14
 
12
- shared_helper = GovukPublishingComponents::Presenters::SharedHelper.new(local_assigns)
13
- heading_size = false unless shared_helper.valid_heading_size?(heading_size)
14
- select_helper = GovukPublishingComponents::Presenters::SelectHelper.new(local_assigns)
15
+ select_helper ||= GovukPublishingComponents::Presenters::SelectHelper.new(local_assigns)
15
16
 
16
17
  aria_attributes = {
17
18
  controls: aria_controls,
18
19
  describedby: select_helper.describedby
19
20
  }
20
21
  %>
21
- <% if select_helper.options.any? && id && label %>
22
+ <% if select_helper.options_markup.present? && id && label %>
22
23
  <%= content_tag :div, class: select_helper.css_classes do %>
23
- <% if is_page_heading %>
24
- <% add_gem_component_stylesheet("heading") %>
25
- <%= render "govuk_publishing_components/components/heading", {
26
- text: label_tag(id, label, class: select_helper.label_classes),
27
- heading_level: 1
28
- } %>
29
- <% else %>
30
- <%= label_tag(id, label, class: select_helper.label_classes) %>
31
- <% end %>
32
-
33
- <% if select_helper.hint %>
34
- <%= render "govuk_publishing_components/components/hint", {
35
- id: select_helper.hint_id,
36
- text: hint
37
- } %>
38
- <% end %>
24
+ <%= render "govuk_publishing_components/components/label", {
25
+ id: "#{id}-label",
26
+ html_for: id,
27
+ text: label,
28
+ heading_size:,
29
+ is_page_heading:,
30
+ hint_text: select_helper.hint,
31
+ hint_id: select_helper.hint_id,
32
+ } %>
39
33
 
40
- <% if select_helper.error_message %>
34
+ <% if select_helper.error_items.any? %>
41
35
  <%= render "govuk_publishing_components/components/error_message", {
42
36
  id: select_helper.error_id,
43
- text: select_helper.error_message
37
+ items: select_helper.error_items,
44
38
  } %>
45
39
  <% end %>
46
40
 
47
- <%= select_tag name, options_for_select(select_helper.option_markup, select_helper.selected_option), id: id, class: select_helper.select_classes, aria: aria_attributes, data: data_attributes %>
41
+ <%# Create null input so that the value is cleared if no options are selected %>
42
+ <%# https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select-label-Gotcha %>
43
+ <% if multiple %>
44
+ <%= hidden_field_tag name, nil %>
45
+ <% end %>
46
+ <%= select_tag name, select_helper.options_markup, id: id, class: select_helper.select_classes, aria: aria_attributes, data: data_attributes, multiple: %>
48
47
  <% end %>
49
48
  <% end %>
@@ -0,0 +1,14 @@
1
+ <%
2
+ add_gem_component_stylesheet("select-with-search")
3
+
4
+ # select_helper.select_classes generates "gem-c-select-with-search"
5
+ select_helper = GovukPublishingComponents::Presenters::SelectWithSearchHelper.new(local_assigns)
6
+
7
+ component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns)
8
+ component_helper.add_data_attribute({ module: "select-with-search" })
9
+ %>
10
+ <%= render "govuk_publishing_components/components/select", {
11
+ **local_assigns,
12
+ **component_helper.all_attributes,
13
+ select_helper:
14
+ }.with_indifferent_access %>
@@ -174,3 +174,14 @@ examples:
174
174
  value: option1
175
175
  - text: Option two
176
176
  value: option2
177
+ with_multiple:
178
+ data:
179
+ id: dropdown-multiple-id
180
+ id: dropdown-multiple
181
+ label: My Dropdown
182
+ multiple: true
183
+ options:
184
+ - text: Option one
185
+ value: option1
186
+ - text: Option two
187
+ value: option2