govuk_publishing_components 58.1.1 → 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.
- checksums.yaml +4 -4
- data/app/assets/images/select-with-search/cross-icon.svg +6 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-search-tracker.js +4 -0
- data/app/assets/javascripts/govuk_publishing_components/components/select-with-search.js +57 -0
- data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_select-with-search.scss +168 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_select.scss +6 -0
- data/app/views/govuk_publishing_components/components/_select.html.erb +22 -23
- data/app/views/govuk_publishing_components/components/_select_with_search.html.erb +14 -0
- data/app/views/govuk_publishing_components/components/docs/select.yml +11 -0
- data/app/views/govuk_publishing_components/components/docs/select_with_search.yml +196 -0
- data/lib/govuk_publishing_components/presenters/select_helper.rb +8 -5
- data/lib/govuk_publishing_components/presenters/select_with_search_helper.rb +92 -0
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/lib/govuk_publishing_components.rb +1 -0
- data/node_modules/choices.js/LICENSE +21 -0
- data/node_modules/choices.js/README.md +1360 -0
- data/node_modules/choices.js/package.json +173 -0
- data/node_modules/choices.js/public/assets/scripts/choices.js +5230 -0
- data/node_modules/choices.js/public/assets/scripts/choices.min.js +2 -0
- data/node_modules/choices.js/public/assets/scripts/choices.mjs +5222 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-basic.js +4748 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-basic.min.js +2 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-basic.mjs +4740 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.js +3631 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.min.js +2 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.mjs +3623 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.js +3590 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.min.js +2 -0
- data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.mjs +3582 -0
- data/node_modules/choices.js/public/assets/styles/base.css +180 -0
- data/node_modules/choices.js/public/assets/styles/base.css.map +1 -0
- data/node_modules/choices.js/public/assets/styles/base.min.css +1 -0
- data/node_modules/choices.js/public/assets/styles/choices.css +338 -0
- data/node_modules/choices.js/public/assets/styles/choices.css.map +1 -0
- data/node_modules/choices.js/public/assets/styles/choices.min.css +1 -0
- data/node_modules/choices.js/public/types/src/index.d.ts +6 -0
- data/node_modules/choices.js/public/types/src/scripts/actions/choices.d.ts +30 -0
- data/node_modules/choices.js/public/types/src/scripts/actions/groups.d.ts +8 -0
- data/node_modules/choices.js/public/types/src/scripts/actions/items.d.ts +17 -0
- data/node_modules/choices.js/public/types/src/scripts/choices.d.ts +210 -0
- data/node_modules/choices.js/public/types/src/scripts/components/container.d.ts +36 -0
- data/node_modules/choices.js/public/types/src/scripts/components/dropdown.d.ts +21 -0
- data/node_modules/choices.js/public/types/src/scripts/components/index.d.ts +7 -0
- data/node_modules/choices.js/public/types/src/scripts/components/input.d.ts +37 -0
- data/node_modules/choices.js/public/types/src/scripts/components/list.d.ts +14 -0
- data/node_modules/choices.js/public/types/src/scripts/components/wrapped-element.d.ts +21 -0
- data/node_modules/choices.js/public/types/src/scripts/components/wrapped-input.d.ts +3 -0
- data/node_modules/choices.js/public/types/src/scripts/components/wrapped-select.d.ts +20 -0
- data/node_modules/choices.js/public/types/src/scripts/constants.d.ts +1 -0
- data/node_modules/choices.js/public/types/src/scripts/defaults.d.ts +4 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/action-type.d.ts +13 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/build-flags.d.ts +11 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/choice-full.d.ts +23 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/class-names.d.ts +61 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/event-choice.d.ts +7 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/event-type.d.ts +14 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/group-full.d.ts +10 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/index.d.ts +14 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/input-choice.d.ts +15 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/input-group.d.ts +10 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/item.d.ts +17 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts +13 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/options.d.ts +566 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts +7 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts +95 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts +1 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/search.d.ts +11 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/state.d.ts +10 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/store.d.ts +64 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/string-pre-escaped.d.ts +3 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/string-untrusted.d.ts +4 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/templates.d.ts +29 -0
- data/node_modules/choices.js/public/types/src/scripts/interfaces/types.d.ts +18 -0
- data/node_modules/choices.js/public/types/src/scripts/lib/choice-input.d.ts +9 -0
- data/node_modules/choices.js/public/types/src/scripts/lib/html-guard-statements.d.ts +4 -0
- data/node_modules/choices.js/public/types/src/scripts/lib/utils.d.ts +31 -0
- data/node_modules/choices.js/public/types/src/scripts/reducers/choices.d.ts +8 -0
- data/node_modules/choices.js/public/types/src/scripts/reducers/groups.d.ts +8 -0
- data/node_modules/choices.js/public/types/src/scripts/reducers/items.d.ts +9 -0
- data/node_modules/choices.js/public/types/src/scripts/search/fuse.d.ts +14 -0
- data/node_modules/choices.js/public/types/src/scripts/search/index.d.ts +3 -0
- data/node_modules/choices.js/public/types/src/scripts/search/kmp.d.ts +11 -0
- data/node_modules/choices.js/public/types/src/scripts/search/prefix-filter.d.ts +11 -0
- data/node_modules/choices.js/public/types/src/scripts/store/store.d.ts +59 -0
- data/node_modules/choices.js/public/types/src/scripts/templates.d.ts +8 -0
- data/node_modules/choices.js/src/entry.js +3 -0
- data/node_modules/choices.js/src/icons/cross-inverse.svg +1 -0
- data/node_modules/choices.js/src/icons/cross.svg +1 -0
- data/node_modules/choices.js/src/index.ts +8 -0
- data/node_modules/choices.js/src/scripts/actions/choices.ts +59 -0
- data/node_modules/choices.js/src/scripts/actions/groups.ts +14 -0
- data/node_modules/choices.js/src/scripts/actions/items.ts +34 -0
- data/node_modules/choices.js/src/scripts/choices.ts +2364 -0
- data/node_modules/choices.js/src/scripts/components/container.ts +157 -0
- data/node_modules/choices.js/src/scripts/components/dropdown.ts +50 -0
- data/node_modules/choices.js/src/scripts/components/index.ts +8 -0
- data/node_modules/choices.js/src/scripts/components/input.ts +146 -0
- data/node_modules/choices.js/src/scripts/components/list.ts +89 -0
- data/node_modules/choices.js/src/scripts/components/wrapped-element.ts +89 -0
- data/node_modules/choices.js/src/scripts/components/wrapped-input.ts +3 -0
- data/node_modules/choices.js/src/scripts/components/wrapped-select.ts +115 -0
- data/node_modules/choices.js/src/scripts/constants.ts +1 -0
- data/node_modules/choices.js/src/scripts/defaults.ts +93 -0
- data/node_modules/choices.js/src/scripts/interfaces/action-type.ts +15 -0
- data/node_modules/choices.js/src/scripts/interfaces/build-flags.ts +17 -0
- data/node_modules/choices.js/src/scripts/interfaces/choice-full.ts +30 -0
- data/node_modules/choices.js/src/scripts/interfaces/class-names.ts +61 -0
- data/node_modules/choices.js/src/scripts/interfaces/event-choice.ts +9 -0
- data/node_modules/choices.js/src/scripts/interfaces/event-type.ts +16 -0
- data/node_modules/choices.js/src/scripts/interfaces/group-full.ts +12 -0
- data/node_modules/choices.js/src/scripts/interfaces/index.ts +14 -0
- data/node_modules/choices.js/src/scripts/interfaces/input-choice.ts +17 -0
- data/node_modules/choices.js/src/scripts/interfaces/input-group.ts +11 -0
- data/node_modules/choices.js/src/scripts/interfaces/item.ts +17 -0
- data/node_modules/choices.js/src/scripts/interfaces/keycode-map.ts +13 -0
- data/node_modules/choices.js/src/scripts/interfaces/options.ts +619 -0
- data/node_modules/choices.js/src/scripts/interfaces/passed-element-type.ts +9 -0
- data/node_modules/choices.js/src/scripts/interfaces/passed-element.ts +96 -0
- data/node_modules/choices.js/src/scripts/interfaces/position-options-type.ts +1 -0
- data/node_modules/choices.js/src/scripts/interfaces/search.ts +12 -0
- data/node_modules/choices.js/src/scripts/interfaces/state.ts +12 -0
- data/node_modules/choices.js/src/scripts/interfaces/store.ts +84 -0
- data/node_modules/choices.js/src/scripts/interfaces/string-pre-escaped.ts +3 -0
- data/node_modules/choices.js/src/scripts/interfaces/string-untrusted.ts +5 -0
- data/node_modules/choices.js/src/scripts/interfaces/templates.ts +66 -0
- data/node_modules/choices.js/src/scripts/interfaces/types.ts +21 -0
- data/node_modules/choices.js/src/scripts/lib/choice-input.ts +88 -0
- data/node_modules/choices.js/src/scripts/lib/html-guard-statements.ts +7 -0
- data/node_modules/choices.js/src/scripts/lib/utils.ts +230 -0
- data/node_modules/choices.js/src/scripts/reducers/choices.ts +86 -0
- data/node_modules/choices.js/src/scripts/reducers/groups.ts +32 -0
- data/node_modules/choices.js/src/scripts/reducers/items.ts +86 -0
- data/node_modules/choices.js/src/scripts/search/fuse.ts +59 -0
- data/node_modules/choices.js/src/scripts/search/index.ts +17 -0
- data/node_modules/choices.js/src/scripts/search/kmp.ts +87 -0
- data/node_modules/choices.js/src/scripts/search/prefix-filter.ts +42 -0
- data/node_modules/choices.js/src/scripts/store/store.ts +184 -0
- data/node_modules/choices.js/src/scripts/templates.ts +409 -0
- data/node_modules/choices.js/src/styles/base.scss +189 -0
- data/node_modules/choices.js/src/styles/choices.scss +414 -0
- data/node_modules/choices.js/src/tsconfig.json +22 -0
- metadata +134 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8766d04b5c4c4d7fab4d972b014cc0ac72f541321146789b75c64414b60aeb08
|
4
|
+
data.tar.gz: d6915e235caf1ea065a3f6f001ef34d797f76187cd58f199ba8ff20e242fb062
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1aaa22f84475dd4bd8b5bd26d6af93a3e456c999ff9eeffd4631dac8d87b50e7dfed42db8b845cff27408812d7314d9acfb8440109887e137b9208b13ccce8c2
|
7
|
+
data.tar.gz: bb8b3b01adf12c73c771b6366abf277fb263d33149a853188785e308389b9d6c8202c6fcf3301c037a3ac602b65861a4bcdcb210646736dd9dfeb9e3109424a0
|
@@ -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";
|
@@ -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%;
|
@@ -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
|
-
|
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.
|
22
|
+
<% if select_helper.options_markup.present? && id && label %>
|
22
23
|
<%= content_tag :div, class: select_helper.css_classes do %>
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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.
|
34
|
+
<% if select_helper.error_items.any? %>
|
41
35
|
<%= render "govuk_publishing_components/components/error_message", {
|
42
36
|
id: select_helper.error_id,
|
43
|
-
|
37
|
+
items: select_helper.error_items,
|
44
38
|
} %>
|
45
39
|
<% end %>
|
46
40
|
|
47
|
-
|
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
|
@@ -0,0 +1,196 @@
|
|
1
|
+
name: Select with search (experimental)
|
2
|
+
description: A dropdown select with search
|
3
|
+
body: |
|
4
|
+
A Javascript enhanced dropdown select. This component is progressively enhanced, if
|
5
|
+
Javascript is unavailable then it will use the select component.
|
6
|
+
|
7
|
+
This is an experimental component as it currently fails WCAG compliance for keyboard navigation. The total number of options are not
|
8
|
+
announced when using Voice Over.
|
9
|
+
accessibility_criteria: |
|
10
|
+
- accept focus
|
11
|
+
- be focusable with a keyboard
|
12
|
+
- be usable with a keyboard
|
13
|
+
- indicate when it has focus
|
14
|
+
examples:
|
15
|
+
default:
|
16
|
+
data:
|
17
|
+
id: dropdown-default
|
18
|
+
label: My Dropdown
|
19
|
+
options:
|
20
|
+
- text: Option one
|
21
|
+
value: option1
|
22
|
+
- text: Option two
|
23
|
+
value: option2
|
24
|
+
- text: Option three
|
25
|
+
value: option3
|
26
|
+
with_blank_option:
|
27
|
+
description: Include a blank option
|
28
|
+
data:
|
29
|
+
id: dropdown-with-blank
|
30
|
+
label: With blank option
|
31
|
+
include_blank: true
|
32
|
+
options:
|
33
|
+
- text: Option one
|
34
|
+
value: option1
|
35
|
+
- text: Option two
|
36
|
+
value: option2
|
37
|
+
- text: Option three
|
38
|
+
value: option3
|
39
|
+
with_grouped_options:
|
40
|
+
description: Options can be grouped
|
41
|
+
data:
|
42
|
+
id: dropdown-with-grouped-options
|
43
|
+
label: Select a city
|
44
|
+
grouped_options:
|
45
|
+
- - England
|
46
|
+
- - text: Bath
|
47
|
+
value: bath
|
48
|
+
- text: Bristol
|
49
|
+
value: bristol
|
50
|
+
- text: London
|
51
|
+
value: london
|
52
|
+
- text: Manchester
|
53
|
+
value: manchester
|
54
|
+
- - Northern Ireland
|
55
|
+
- - text: Bangor
|
56
|
+
value: bangor
|
57
|
+
- text: Belfast
|
58
|
+
value: belfast
|
59
|
+
- - Scotland
|
60
|
+
- - text: Dundee
|
61
|
+
value: dundee
|
62
|
+
- text: Edinburgh
|
63
|
+
value: edinburgh
|
64
|
+
- text: Glasgow
|
65
|
+
value: glasgow
|
66
|
+
- - Wales
|
67
|
+
- - text: Cardiff
|
68
|
+
value: cardiff
|
69
|
+
- text: Swansea
|
70
|
+
value: swansea
|
71
|
+
with_grouped_options_and_blank_option:
|
72
|
+
description: Options can be grouped and include a blank option
|
73
|
+
data:
|
74
|
+
id: dropdown-with-grouped-options-and-blank
|
75
|
+
label: Select a city
|
76
|
+
include_blank: true
|
77
|
+
grouped_options:
|
78
|
+
- - England
|
79
|
+
- - text: Bath
|
80
|
+
value: bath
|
81
|
+
- text: Bristol
|
82
|
+
value: bristol
|
83
|
+
- text: London
|
84
|
+
value: london
|
85
|
+
- text: Manchester
|
86
|
+
value: manchester
|
87
|
+
- - Northern Ireland
|
88
|
+
- - text: Bangor
|
89
|
+
value: bangor
|
90
|
+
- text: Belfast
|
91
|
+
value: belfast
|
92
|
+
- - Scotland
|
93
|
+
- - text: Dundee
|
94
|
+
value: dundee
|
95
|
+
- text: Edinburgh
|
96
|
+
value: edinburgh
|
97
|
+
- text: Glasgow
|
98
|
+
value: glasgow
|
99
|
+
- - Wales
|
100
|
+
- - text: Cardiff
|
101
|
+
value: cardiff
|
102
|
+
- text: Swansea
|
103
|
+
value: swansea
|
104
|
+
with_different_id_and_name:
|
105
|
+
description: If no name is provided, name defaults to the (required) value of id.
|
106
|
+
data:
|
107
|
+
id: dropdown-with-different-id-and-name
|
108
|
+
label: My Dropdown
|
109
|
+
name: dropdown[1]
|
110
|
+
options:
|
111
|
+
- text: Option one
|
112
|
+
value: option1
|
113
|
+
- text: Option two
|
114
|
+
value: option2
|
115
|
+
with_data_attributes:
|
116
|
+
data:
|
117
|
+
id: dropdown-with-data-attributes
|
118
|
+
data_attributes:
|
119
|
+
module: not-a-module
|
120
|
+
loose: moose
|
121
|
+
label: Select your country
|
122
|
+
options:
|
123
|
+
- text: France
|
124
|
+
value: fr
|
125
|
+
- text: Germany
|
126
|
+
value: de
|
127
|
+
- text: United Kingdom
|
128
|
+
value: uk
|
129
|
+
with_preselect:
|
130
|
+
data:
|
131
|
+
id: dropdown-with-preselect
|
132
|
+
label: Option 2 preselected
|
133
|
+
options:
|
134
|
+
- text: Option one
|
135
|
+
value: option1
|
136
|
+
- text: Option two
|
137
|
+
value: option2
|
138
|
+
selected: true
|
139
|
+
- text: Option three
|
140
|
+
value: option3
|
141
|
+
with_hint:
|
142
|
+
description: When a hint is included the `aria-describedby` attribute of the select is included to point to the hint. When an error and a hint are present, that attribute includes the IDs of both the hint and the error.
|
143
|
+
data:
|
144
|
+
id: dropdown-with-hint
|
145
|
+
label: Choose your preferred thing
|
146
|
+
hint: You might need some more information here
|
147
|
+
hint_id: optional-hint-id
|
148
|
+
options:
|
149
|
+
- text: Something
|
150
|
+
value: option1
|
151
|
+
- text: Something else
|
152
|
+
value: option2
|
153
|
+
with_error:
|
154
|
+
description: An arbitrary number of separate error items can be passed to the component.
|
155
|
+
data:
|
156
|
+
id: dropdown-with-error
|
157
|
+
label: How will you be travelling to the conference?
|
158
|
+
error_items:
|
159
|
+
- text: Please choose an option
|
160
|
+
include_blank: true
|
161
|
+
options:
|
162
|
+
- text: Public transport
|
163
|
+
value: option1
|
164
|
+
- text: Will make own arrangements
|
165
|
+
value: option2
|
166
|
+
with_custom_label_size:
|
167
|
+
description: Make the label different sizes. Valid options are `s`, `m`, `l` and `xl`.
|
168
|
+
data:
|
169
|
+
id: dropdown-with-custom-label-size
|
170
|
+
label: Bigger!
|
171
|
+
heading_size: xl
|
172
|
+
options:
|
173
|
+
- text: Option one
|
174
|
+
value: option1
|
175
|
+
- text: Option two
|
176
|
+
value: option2
|
177
|
+
- text: Option three
|
178
|
+
value: option3
|
179
|
+
with_multiple_select_enabled:
|
180
|
+
description: Allow multiple items to be selected and de-selected.
|
181
|
+
data:
|
182
|
+
id: dropdown-with-multiple
|
183
|
+
label: Select your country
|
184
|
+
include_blank: true
|
185
|
+
multiple: true
|
186
|
+
options:
|
187
|
+
- text: France
|
188
|
+
value: fr
|
189
|
+
selected: false
|
190
|
+
- text: Germany
|
191
|
+
value: de
|
192
|
+
selected: false
|
193
|
+
- text: The United Kingdom of Great Britain and Northern Ireland
|
194
|
+
value: uk
|
195
|
+
- text: Democratic Republic of the Congo
|
196
|
+
value: cg
|
@@ -1,23 +1,26 @@
|
|
1
1
|
module GovukPublishingComponents
|
2
2
|
module Presenters
|
3
3
|
class SelectHelper
|
4
|
-
|
4
|
+
include ActionView::Helpers::FormOptionsHelper
|
5
|
+
|
6
|
+
attr_reader :options, :options_markup, :error_items, :error_id, :hint, :hint_id, :describedby
|
5
7
|
|
6
8
|
def initialize(local_assigns)
|
7
9
|
@options = local_assigns[:options] || []
|
8
|
-
@
|
10
|
+
@error_items = local_assigns[:error_items] || []
|
11
|
+
@error_items << { text: local_assigns[:error_message] } if local_assigns[:error_message]
|
9
12
|
@error_id = local_assigns[:error_id] || nil
|
10
13
|
@hint = local_assigns[:hint] || nil
|
11
14
|
@hint_id = local_assigns[:hint_id] || nil
|
12
15
|
@heading_size = local_assigns[:heading_size]
|
13
16
|
@full_width = local_assigns[:full_width] || false
|
14
|
-
@
|
17
|
+
@options_markup = options_for_select(get_options, @selected_option)
|
15
18
|
@describedby = get_describedby
|
16
19
|
end
|
17
20
|
|
18
21
|
def css_classes
|
19
22
|
classes = %w[govuk-form-group gem-c-select]
|
20
|
-
classes << "govuk-form-group--error" if @
|
23
|
+
classes << "govuk-form-group--error" if @error_items.present?
|
21
24
|
classes
|
22
25
|
end
|
23
26
|
|
@@ -66,7 +69,7 @@ module GovukPublishingComponents
|
|
66
69
|
def get_describedby
|
67
70
|
describedby = %w[]
|
68
71
|
|
69
|
-
if @
|
72
|
+
if @error_items.present? || @error_id
|
70
73
|
@error_id ||= "error-#{SecureRandom.hex(4)}"
|
71
74
|
describedby << @error_id
|
72
75
|
end
|