@madgex/design-system 3.0.8 → 3.0.9
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.
- package/coverage/cobertura-coverage.xml +126 -96
- package/coverage/components/accordion/accordion.js.html +1 -1
- package/coverage/components/accordion/index.html +1 -1
- package/coverage/components/button/button.js.html +1 -1
- package/coverage/components/button/index.html +1 -1
- package/coverage/components/inputs/combobox/combobox.js.html +1 -1
- package/coverage/components/inputs/combobox/index.html +1 -1
- package/coverage/components/inputs/combobox/vue-components/Combobox.vue.html +120 -36
- package/coverage/components/inputs/combobox/vue-components/ListBoxOption.vue.html +1 -1
- package/coverage/components/inputs/combobox/vue-components/index.html +19 -19
- package/coverage/components/inputs/file-upload/file-upload.js.html +1 -1
- package/coverage/components/inputs/file-upload/index.html +1 -1
- package/coverage/components/inputs/textarea/character-count.js.html +1 -1
- package/coverage/components/inputs/textarea/index.html +1 -1
- package/coverage/components/modal/index.html +1 -1
- package/coverage/components/modal/modal.js.html +1 -1
- package/coverage/components/notification/index.html +1 -1
- package/coverage/components/notification/notification.js.html +1 -1
- package/coverage/components/popover/index.html +1 -1
- package/coverage/components/popover/popover.js.html +1 -1
- package/coverage/components/switch-state/index.html +1 -1
- package/coverage/components/switch-state/switch-state.js.html +1 -1
- package/coverage/components/tabs/index.html +1 -1
- package/coverage/components/tabs/tabs.js.html +1 -1
- package/coverage/index.html +19 -19
- package/coverage/js/common.js.html +1 -1
- package/coverage/js/fractal-scripts/combobox.js.html +1 -1
- package/coverage/js/fractal-scripts/index.html +1 -1
- package/coverage/js/fractal-scripts/notification.js.html +1 -1
- package/coverage/js/fractal-scripts/switch-state.js.html +1 -1
- package/coverage/js/index-fractal.js.html +1 -1
- package/coverage/js/index-polyfills.js.html +1 -1
- package/coverage/js/index-vue.js.html +1 -1
- package/coverage/js/index.html +1 -1
- package/coverage/js/index.js.html +1 -1
- package/coverage/js/polyfills/arrayPrototypeFind.js.html +1 -1
- package/coverage/js/polyfills/closest.js.html +1 -1
- package/coverage/js/polyfills/index.html +1 -1
- package/coverage/js/polyfills/objectAssign.js.html +1 -1
- package/coverage/js/polyfills/remove.js.html +1 -1
- package/coverage/tokens/_config.js.html +1 -1
- package/coverage/tokens/index.html +1 -1
- package/dist/_tokens/css/_tokens.css +1 -1
- package/dist/_tokens/js/_tokens-module.js +1 -1
- package/dist/_tokens/scss/_tokens.scss +1 -1
- package/dist/js/index.js +1 -1
- package/package.json +1 -1
- package/src/components/inputs/_form-elements.scss +1 -1
- package/src/components/inputs/combobox/README.md +2 -2
- package/src/components/inputs/combobox/_template.njk +2 -10
- package/src/components/inputs/combobox/combobox.config.js +12 -2
- package/src/components/inputs/combobox/combobox.njk +0 -1
- package/src/components/inputs/combobox/vue-components/Combobox.vue +42 -14
- package/src/scss/core/_containers.scss +1 -1
- package/src/scss/functions/_px2rem.scss +1 -1
- package/src/scss/import.scss +1 -0
- package/src/scss/vendor/_sass-mq.scss +1 -1
package/package.json
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
- `id`: the id of your combobox
|
|
4
4
|
- `name`: the name of the input for form submission. Uses ID unless specified - _optional_
|
|
5
|
-
- `resultMessage`: to be used as a prop for the Vue component below, will not be used if Javascript is not available
|
|
6
5
|
- `labelText`: the text used in the label
|
|
7
6
|
- `options`: a json object of key, value pairs e.g { 45: 'Orange' }. To be used when falling back to a native select if Javascript is not available
|
|
8
7
|
- `value`: a default selected value for the input - _optional_
|
|
@@ -20,7 +19,6 @@
|
|
|
20
19
|
- `comboboxid`: the id of your combobox. Populated automatically from Nunjucks parameters
|
|
21
20
|
- `labeltext`: the text used in the label. Populated automatically from Nunjucks parameters
|
|
22
21
|
- `placeholder`: the placeholder for your input. Populated automatically from Nunjucks parameters
|
|
23
|
-
- `resultmessage`: the visually hidden message to inform screenreader users when the options in the listbox have changed. Can either be a string which will be prefixed with the number of options, or a function which takes the number of options as its parameter and which should return a string. Defaults to 'options available', populated automatically from Nunjucks parameters if passed in
|
|
24
22
|
- `name`: the name of the input for form submission. Will only be populated automatically if fallbackTo is 'input'
|
|
25
23
|
- `value`: a default value for the combobox input. Populated automatically from Nunjucks parameters
|
|
26
24
|
- `options`: an array of options, which should be objects with a `label` and a `value`. The array should be provided externally by selecting the custom `<mds-combobox>` element and setting it as an attribute
|
|
@@ -33,3 +31,5 @@ The Vue component is a [WAI-ARIA 1.0 combobox](https://www.w3.org/TR/wai-aria-pr
|
|
|
33
31
|
NB. The AJAX demo above currently only works in browsers, not <= IE11. Fetch will be polyfilled or replaced in due course.
|
|
34
32
|
|
|
35
33
|
When Javascript is not available, either a native combobox or native input will be available as a fallback.
|
|
34
|
+
|
|
35
|
+
aria-describedBy has been added to notify screen reader users how to interact with the autocomplete suggestions.
|
|
@@ -20,14 +20,6 @@
|
|
|
20
20
|
{% set comboboxName = comboboxId %}
|
|
21
21
|
{% endif %}
|
|
22
22
|
|
|
23
|
-
{%- set placeholder %}
|
|
24
|
-
{%- if params.placeholder -%}
|
|
25
|
-
{{ params.placeholder }}
|
|
26
|
-
{%- else -%}
|
|
27
|
-
Please select
|
|
28
|
-
{%- endif -%}
|
|
29
|
-
{% endset -%}
|
|
30
|
-
|
|
31
23
|
{%- set labelId %}{{comboboxId}}-label{% endset -%}
|
|
32
24
|
|
|
33
25
|
{%- if comboboxId -%}
|
|
@@ -60,8 +52,8 @@
|
|
|
60
52
|
{% endif %}
|
|
61
53
|
</div>
|
|
62
54
|
{# Leave the custom element at the bottom so it has access to the above elements on render #}
|
|
63
|
-
<mds-combobox comboboxid="{{ comboboxId }}" placeholder="{{ placeholder }}" iconpath="{{ defaultIconPath }}" data-aria-invalid="{{ params.validationError }}"
|
|
64
|
-
{% if params.fallbackTo === 'input' %}name="{{ comboboxName }}"{% endif %}
|
|
55
|
+
<mds-combobox comboboxid="{{ comboboxId }}" placeholder="{{ params.placeholder }}" iconpath="{{ defaultIconPath }}" data-aria-invalid="{{ params.validationError }}"
|
|
56
|
+
{% if params.fallbackTo === 'input' %}name="{{ comboboxName }}"{% endif %}
|
|
65
57
|
{% if params.value %}value="{{ params.value }}"{% endif %}
|
|
66
58
|
></mds-combobox>
|
|
67
59
|
</div>
|
|
@@ -22,12 +22,22 @@ module.exports = {
|
|
|
22
22
|
variantTitle: 'AJAX autocomplete',
|
|
23
23
|
name: 'keywords',
|
|
24
24
|
id: 'keywords-lookup',
|
|
25
|
-
resultMessage: 'suggestions',
|
|
26
25
|
labelText: 'Keywords:',
|
|
27
|
-
value: 'Initial value',
|
|
28
26
|
placeholder: 'eg. Web developer',
|
|
29
27
|
fallbackTo: 'input',
|
|
30
28
|
},
|
|
31
29
|
},
|
|
30
|
+
{
|
|
31
|
+
name: 'AJAX autocomplete prefilled',
|
|
32
|
+
context: {
|
|
33
|
+
variantTitle: 'AJAX autocomplete prefilled',
|
|
34
|
+
name: 'keywords',
|
|
35
|
+
id: 'keywords-lookup',
|
|
36
|
+
labelText: 'Keywords:',
|
|
37
|
+
placeholder: 'eg. Testimonials',
|
|
38
|
+
value: 'Initial Value',
|
|
39
|
+
fallbackTo: 'input',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
32
42
|
],
|
|
33
43
|
};
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
<ComboboxInput
|
|
13
13
|
@change="handleChange"
|
|
14
14
|
@blur="onInputBlur"
|
|
15
|
+
@focus="handleFocus"
|
|
15
16
|
:id="comboboxid"
|
|
16
17
|
:name="name"
|
|
17
18
|
:placeholder="placeholder"
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
:aria-expanded="ariaExpanded"
|
|
20
21
|
:activeDescendent="selectedOptionId"
|
|
21
22
|
:ariaInvalid="ariaInvalid"
|
|
23
|
+
:aria-describedby="describedBy"
|
|
22
24
|
v-model="inputValue"
|
|
23
25
|
/>
|
|
24
26
|
<ListBox :id="listBoxId" :hidden="listBoxHidden" :isLoading="isLoading" :comboboxid="comboboxid">
|
|
@@ -34,7 +36,10 @@
|
|
|
34
36
|
/>
|
|
35
37
|
</template>
|
|
36
38
|
</ListBox>
|
|
37
|
-
<div aria-live="polite" role="status" class="mds-visually-hidden">{{
|
|
39
|
+
<div aria-live="polite" role="status" class="mds-visually-hidden">{{ resultCountMessage }}</div>
|
|
40
|
+
<span :id="describedBy" style="display: none">
|
|
41
|
+
When autocomplete results are available use up and down arrows to review and enter to select.
|
|
42
|
+
</span>
|
|
38
43
|
</div>
|
|
39
44
|
</template>
|
|
40
45
|
|
|
@@ -57,11 +62,7 @@ export default {
|
|
|
57
62
|
},
|
|
58
63
|
placeholder: {
|
|
59
64
|
type: String,
|
|
60
|
-
default: '
|
|
61
|
-
},
|
|
62
|
-
resultmessage: {
|
|
63
|
-
type: [String, Function],
|
|
64
|
-
default: 'options available',
|
|
65
|
+
default: '',
|
|
65
66
|
},
|
|
66
67
|
name: {
|
|
67
68
|
type: [String, Boolean],
|
|
@@ -94,6 +95,9 @@ export default {
|
|
|
94
95
|
selected: null,
|
|
95
96
|
chosen: null,
|
|
96
97
|
searchValue: this.$props.value,
|
|
98
|
+
resultCountMessage: null,
|
|
99
|
+
resultMessage: 'result available',
|
|
100
|
+
resultMessage_plural: 'results available',
|
|
97
101
|
};
|
|
98
102
|
},
|
|
99
103
|
provide() {
|
|
@@ -107,6 +111,7 @@ export default {
|
|
|
107
111
|
if (this.chosenOption) {
|
|
108
112
|
return this.chosenOption.label;
|
|
109
113
|
}
|
|
114
|
+
|
|
110
115
|
return this.searchValue;
|
|
111
116
|
},
|
|
112
117
|
set(event) {
|
|
@@ -115,6 +120,9 @@ export default {
|
|
|
115
120
|
this.searchValue = event.target ? event.target.value : '';
|
|
116
121
|
this.handleChange();
|
|
117
122
|
this.$emit('search', this.searchValue);
|
|
123
|
+
if (this.visibleOptions.length > 0) {
|
|
124
|
+
this.updateCount();
|
|
125
|
+
}
|
|
118
126
|
},
|
|
119
127
|
},
|
|
120
128
|
selectedOption: {
|
|
@@ -139,6 +147,7 @@ export default {
|
|
|
139
147
|
if (this.filterOptions) {
|
|
140
148
|
return this.options.filter((opt) => opt.label.toLowerCase().includes(this.searchValue.toLowerCase()));
|
|
141
149
|
}
|
|
150
|
+
|
|
142
151
|
return this.options;
|
|
143
152
|
},
|
|
144
153
|
listBoxId() {
|
|
@@ -147,14 +156,19 @@ export default {
|
|
|
147
156
|
optionId() {
|
|
148
157
|
return `${this.comboboxid}-option`;
|
|
149
158
|
},
|
|
159
|
+
describedBy() {
|
|
160
|
+
return `${this.comboboxid}-assistiveHint`;
|
|
161
|
+
},
|
|
150
162
|
isLoading() {
|
|
151
163
|
return this.options.length === 0 && this.expanded;
|
|
152
164
|
},
|
|
153
165
|
selectedOptionId() {
|
|
154
166
|
const index = this.visibleOptions.indexOf(this.selectedOption);
|
|
167
|
+
|
|
155
168
|
if (index > -1) {
|
|
156
169
|
return `${this.optionId}-${index}`;
|
|
157
170
|
}
|
|
171
|
+
|
|
158
172
|
return false;
|
|
159
173
|
},
|
|
160
174
|
listBoxHidden() {
|
|
@@ -163,12 +177,6 @@ export default {
|
|
|
163
177
|
lastOptionIndex() {
|
|
164
178
|
return this.visibleOptions.length - 1;
|
|
165
179
|
},
|
|
166
|
-
resultCount() {
|
|
167
|
-
if (typeof this.resultmessage === 'function') {
|
|
168
|
-
return this.resultmessage(this.visibleOptions.length);
|
|
169
|
-
}
|
|
170
|
-
return `${this.visibleOptions.length} ${this.resultmessage}`;
|
|
171
|
-
},
|
|
172
180
|
ariaExpanded() {
|
|
173
181
|
// These must be strings to apply as an aria attribute of the same name
|
|
174
182
|
return this.expanded ? 'true' : 'false';
|
|
@@ -191,6 +199,12 @@ export default {
|
|
|
191
199
|
this.makeInactive();
|
|
192
200
|
}
|
|
193
201
|
},
|
|
202
|
+
handleFocus() {
|
|
203
|
+
this.handleChange();
|
|
204
|
+
if (this.visibleOptions.length > 1) {
|
|
205
|
+
this.updateCount();
|
|
206
|
+
}
|
|
207
|
+
},
|
|
194
208
|
clickOption(option = this.selectedOption) {
|
|
195
209
|
this.chosenOption = option;
|
|
196
210
|
this.makeInactive();
|
|
@@ -198,6 +212,7 @@ export default {
|
|
|
198
212
|
chooseOption() {
|
|
199
213
|
this.chosenOption = this.selectedOption;
|
|
200
214
|
this.makeInactive();
|
|
215
|
+
this.clearCount();
|
|
201
216
|
},
|
|
202
217
|
hiddenGuard(fn) {
|
|
203
218
|
if (this.listBoxHidden) return;
|
|
@@ -205,11 +220,13 @@ export default {
|
|
|
205
220
|
},
|
|
206
221
|
onInputBlur() {
|
|
207
222
|
this.makeInactive();
|
|
223
|
+
this.clearCount();
|
|
208
224
|
},
|
|
209
225
|
onKeyDown() {
|
|
210
226
|
if (this.selectedOption) {
|
|
211
227
|
const currentIndex = this.visibleOptions.indexOf(this.selectedOption);
|
|
212
|
-
const nextIndex = currentIndex === this.lastOptionIndex ?
|
|
228
|
+
const nextIndex = currentIndex === this.lastOptionIndex ? currentIndex : currentIndex + 1;
|
|
229
|
+
|
|
213
230
|
this.selectedOption = this.visibleOptions[nextIndex];
|
|
214
231
|
} else {
|
|
215
232
|
[this.selectedOption] = this.visibleOptions;
|
|
@@ -218,7 +235,8 @@ export default {
|
|
|
218
235
|
onKeyUp() {
|
|
219
236
|
if (this.selectedOption) {
|
|
220
237
|
const currentIndex = this.visibleOptions.indexOf(this.selectedOption);
|
|
221
|
-
const nextIndex = currentIndex === 0 ?
|
|
238
|
+
const nextIndex = currentIndex === 0 ? currentIndex : currentIndex - 1;
|
|
239
|
+
|
|
222
240
|
this.selectedOption = this.visibleOptions[nextIndex];
|
|
223
241
|
} else {
|
|
224
242
|
this.selectedOption = this.visibleOptions[this.lastOptionIndex];
|
|
@@ -230,6 +248,16 @@ export default {
|
|
|
230
248
|
onKeyEnd() {
|
|
231
249
|
this.selectedOption = this.visibleOptions[this.lastOptionIndex];
|
|
232
250
|
},
|
|
251
|
+
updateCount() {
|
|
252
|
+
setTimeout(() => {
|
|
253
|
+
const message = this.visibleOptions.length === 1 ? this.resultMessage_plural : this.resultMessage;
|
|
254
|
+
|
|
255
|
+
this.resultCountMessage = `${this.visibleOptions.length} ${message}`;
|
|
256
|
+
}, 1400);
|
|
257
|
+
},
|
|
258
|
+
clearCount() {
|
|
259
|
+
this.resultCountMessage = null;
|
|
260
|
+
},
|
|
233
261
|
},
|
|
234
262
|
};
|
|
235
263
|
</script>
|
|
@@ -92,7 +92,7 @@ $mds-half-gutter-width: $mds-size-gutter-width * 0.5;
|
|
|
92
92
|
// Calculate space left between the wrapper and the edge of the screen on each side
|
|
93
93
|
// so we can stretch the sticky container to make it appear full screen
|
|
94
94
|
// I added 0.01 to stretch the container slightly more to avoid a tiny gap between the edge of the screen and the container
|
|
95
|
-
$space-between-wrapper-and-edge: (100% - $mds-size-wrapper-width
|
|
95
|
+
$space-between-wrapper-and-edge: math.div(100% - $mds-size-wrapper-width, 2) + 0.01;
|
|
96
96
|
|
|
97
97
|
.mds-fixed-container--sticky {
|
|
98
98
|
position: sticky;
|
package/src/scss/import.scss
CHANGED