@madgex/design-system 3.6.2 → 3.7.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 (57) hide show
  1. package/coverage/cobertura-coverage.xml +208 -130
  2. package/coverage/components/accordion/accordion.js.html +1 -1
  3. package/coverage/components/accordion/index.html +1 -1
  4. package/coverage/components/button/button.js.html +1 -1
  5. package/coverage/components/button/index.html +1 -1
  6. package/coverage/components/inputs/combobox/combobox.js.html +1 -1
  7. package/coverage/components/inputs/combobox/index.html +1 -1
  8. package/coverage/components/inputs/combobox/vue-components/Combobox.vue.html +57 -9
  9. package/coverage/components/inputs/combobox/vue-components/ComboboxInput.vue.html +215 -0
  10. package/coverage/components/inputs/combobox/vue-components/ListBoxOption.vue.html +1 -1
  11. package/coverage/components/inputs/combobox/vue-components/index.html +32 -17
  12. package/coverage/components/inputs/file-upload/file-upload.js.html +1 -1
  13. package/coverage/components/inputs/file-upload/index.html +1 -1
  14. package/coverage/components/inputs/textarea/character-count.js.html +1 -1
  15. package/coverage/components/inputs/textarea/index.html +1 -1
  16. package/coverage/components/modal/index.html +1 -1
  17. package/coverage/components/modal/modal.js.html +1 -1
  18. package/coverage/components/notification/index.html +1 -1
  19. package/coverage/components/notification/notification.js.html +1 -1
  20. package/coverage/components/popover/index.html +1 -1
  21. package/coverage/components/popover/popover.js.html +1 -1
  22. package/coverage/components/switch-state/index.html +1 -1
  23. package/coverage/components/switch-state/switch-state.js.html +1 -1
  24. package/coverage/components/tabs/index.html +1 -1
  25. package/coverage/components/tabs/tabs.js.html +1 -1
  26. package/coverage/index.html +22 -22
  27. package/coverage/js/common.js.html +1 -1
  28. package/coverage/js/fractal-scripts/combobox.js.html +99 -15
  29. package/coverage/js/fractal-scripts/index.html +9 -9
  30. package/coverage/js/fractal-scripts/notification.js.html +1 -1
  31. package/coverage/js/fractal-scripts/switch-state.js.html +1 -1
  32. package/coverage/js/index-fractal.js.html +1 -1
  33. package/coverage/js/index-polyfills.js.html +1 -1
  34. package/coverage/js/index-vue.js.html +1 -1
  35. package/coverage/js/index.html +1 -1
  36. package/coverage/js/index.js.html +1 -1
  37. package/coverage/js/polyfills/arrayPrototypeFind.js.html +1 -1
  38. package/coverage/js/polyfills/closest.js.html +1 -1
  39. package/coverage/js/polyfills/index.html +1 -1
  40. package/coverage/js/polyfills/objectAssign.js.html +1 -1
  41. package/coverage/js/polyfills/remove.js.html +1 -1
  42. package/coverage/tokens/_config.js.html +1 -1
  43. package/coverage/tokens/index.html +1 -1
  44. package/dist/_tokens/css/_tokens.css +1 -1
  45. package/dist/_tokens/js/_tokens-module.js +1 -1
  46. package/dist/_tokens/scss/_tokens.scss +1 -1
  47. package/dist/css/index.css +1 -1
  48. package/dist/js/index.js +1 -1
  49. package/package.json +4 -4
  50. package/src/components/inputs/combobox/README.md +7 -0
  51. package/src/components/inputs/combobox/combobox.config.js +14 -0
  52. package/src/components/inputs/combobox/combobox.njk +10 -1
  53. package/src/components/inputs/combobox/combobox.scss +12 -0
  54. package/src/components/inputs/combobox/vue-components/Combobox.vue +16 -0
  55. package/src/components/inputs/combobox/vue-components/ComboboxClear.vue +21 -0
  56. package/src/components/inputs/combobox/vue-components/ComboboxInput.vue +6 -0
  57. package/src/js/fractal-scripts/combobox.js +37 -9
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@madgex/design-system",
3
3
  "author": "Madgex",
4
4
  "license": "UNLICENSED",
5
- "version": "3.6.2",
5
+ "version": "3.7.0",
6
6
  "scripts": {
7
7
  "clean": "rimraf dist public tokens/build",
8
8
  "commit": "commit",
@@ -49,9 +49,9 @@
49
49
  "@commitlint/cli": "^12.1.4",
50
50
  "@commitlint/config-conventional": "^12.1.4",
51
51
  "@commitlint/prompt-cli": "^12.1.4",
52
- "@frctl/fractal": "^1.5.8",
53
- "@frctl/mandelbrot": "^1.9.2",
54
- "@frctl/nunjucks": "^2.0.11",
52
+ "@frctl/fractal": "^1.5.13",
53
+ "@frctl/mandelbrot": "^1.10.1",
54
+ "@frctl/nunjucks": "^2.0.14",
55
55
  "@madgex/eslint-config-madgex": "^1.4.1",
56
56
  "@vue/eslint-config-prettier": "^6.0.0",
57
57
  "@vue/test-utils": "^1.2.1",
@@ -22,6 +22,7 @@ i18n: {
22
22
  'When autocomplete results are available, use up and down arrows to review and enter to select.', // help text for screen readers users to explain how to use the combobox
23
23
  resultsMessage: '{count} result available.', // announce number of results - note the use of `{count}` to get the number of results
24
24
  resultsMessage_plural: '{count} results available.', // announce number of results (plural) - note the use of `{count}` to get the number of results
25
+ clearInput: 'clear input', // text for screen readers explaining what the clear control in combobox does
25
26
  }
26
27
  ```
27
28
 
@@ -36,6 +37,12 @@ i18n: {
36
37
  - `filterOptions`: whether or not the Vue component should internally filter the options array according to the search input (defaults to true)
37
38
  - `i18n`: Text to translate/customise. Populated automatically from Nunjucks parameters
38
39
 
40
+ ## Events
41
+ The following events are emiited.
42
+ - `select-option`
43
+ - `search`
44
+ - `clear-all`
45
+
39
46
  ## Accessibility
40
47
 
41
48
  The Vue component is a [WAI-ARIA 1.0 combobox](https://www.w3.org/TR/wai-aria-practices/#combobox).
@@ -15,6 +15,19 @@ module.exports = {
15
15
  classes: 'im-a-custom-class',
16
16
  },
17
17
  },
18
+ {
19
+ name: 'Clears hidden field(s)',
20
+ context: {
21
+ variantTitle: 'Clear hidden',
22
+ name: 'Salary',
23
+ id: 'salary-selection',
24
+ optional: 'true',
25
+ labelText: 'Salary expectations?',
26
+ options: { 1: 'Up to £20k', 2: 'Up to £30k', 3: 'Up to £40k', 4: 'Up to £50k' },
27
+ value: 'Up to',
28
+ fallbackTo: 'select',
29
+ },
30
+ },
18
31
  {
19
32
  name: 'AJAX autocomplete',
20
33
  context: {
@@ -31,6 +44,7 @@ module.exports = {
31
44
  'When autocomplete results are available, use up and down arrows to review and enter to select. (test i18n)',
32
45
  resultsMessage: '{count} result available (test i18n)',
33
46
  resultsMessage_plural: '{count} results available (test i18n)',
47
+ clearInput: 'clear input (test i18n)',
34
48
  },
35
49
  },
36
50
  },
@@ -16,6 +16,15 @@
16
16
  type: type,
17
17
  i18n: i18n
18
18
  }) }}
19
+ {#
20
+ The below only applies to one combobox example.
21
+ Demonstrates how the clear-all event (fired when combobox is cleared),
22
+ can be used to clear hidden form fields.
23
+ #}
24
+ {% if id === 'salary-selection' %}
25
+ <p class="mds-margin-top-b3">A hidden input is cleared when clear-all event fires. Check <em>#salary-selection-hidden-input</em> in dev tools.</p>
26
+ <input type="hidden" id="salary-selection-hidden-input" />
27
+ {% endif %}
19
28
  <br><br>
20
29
  </div>
21
- </div>
30
+ </div>
@@ -2,6 +2,18 @@
2
2
  display: block;
3
3
  position: relative;
4
4
  }
5
+ .mds-combobox__clear {
6
+ position: absolute;
7
+ top: 0;
8
+ right: 0;
9
+ cursor: pointer;
10
+ &:focus {
11
+ @include inputFocusStyle();
12
+ }
13
+ & .mds-icon {
14
+ color: $mds-color-neutral-base;
15
+ }
16
+ }
5
17
  .mds-combobox__listbox {
6
18
  border: $mds-size-border-width-base solid $mds-color-input-border;
7
19
  border-top: none;
@@ -10,6 +10,7 @@
10
10
  @keydown.enter.stop.prevent="chooseOption"
11
11
  >
12
12
  <ComboboxInput
13
+ ref="comboInput"
13
14
  @change="handleChange"
14
15
  @blur="onInputBlur"
15
16
  @focus="handleFocus"
@@ -23,6 +24,7 @@
23
24
  :aria-describedby="describedBy"
24
25
  v-model="inputValue"
25
26
  />
27
+ <ComboboxClear v-if="searchValue.length > 0" @clear="handleClear" />
26
28
  <ListBox :id="listBoxId" :hidden="listBoxHidden" :isLoading="isLoading" :comboboxid="comboboxid">
27
29
  <template>
28
30
  <ListBoxOption
@@ -43,6 +45,7 @@
43
45
 
44
46
  <script>
45
47
  import ComboboxInput from './ComboboxInput.vue';
48
+ import ComboboxClear from './ComboboxClear.vue';
46
49
  import ListBox from './ListBox.vue';
47
50
  import ListBoxOption from './ListBoxOption.vue';
48
51
 
@@ -50,6 +53,7 @@ export default {
50
53
  name: 'Combobox',
51
54
  components: {
52
55
  ComboboxInput,
56
+ ComboboxClear,
53
57
  ListBox,
54
58
  ListBoxOption,
55
59
  },
@@ -104,6 +108,7 @@ export default {
104
108
  return {
105
109
  iconPath: this.iconpath,
106
110
  loadingText: this.i18nText.loadingText,
111
+ clearInput: this.i18nText.clearInput,
107
112
  };
108
113
  },
109
114
  computed: {
@@ -194,6 +199,7 @@ export default {
194
199
  'When autocomplete results are available, use up and down arrows to review and enter to select.',
195
200
  resultsMessage: '{count} result available',
196
201
  resultsMessage_plural: '{count} results available',
202
+ clearInput: 'clear input',
197
203
  };
198
204
  },
199
205
  },
@@ -205,6 +211,7 @@ export default {
205
211
  this.expanded = false;
206
212
  },
207
213
  handleChange() {
214
+ if (this.searchValue.length === 0) this.clearField();
208
215
  if (this.searchValue.length > 1) {
209
216
  this.makeActive();
210
217
  this.updateCount();
@@ -218,6 +225,15 @@ export default {
218
225
  this.updateCount();
219
226
  }
220
227
  },
228
+ handleClear() {
229
+ this.clearField();
230
+ this.$refs.comboInput.focusInput();
231
+ },
232
+ clearField() {
233
+ this.searchValue = '';
234
+ this.chosenOption = null;
235
+ this.$emit('clear-all');
236
+ },
221
237
  clickOption(option = this.selectedOption) {
222
238
  this.chosenOption = option;
223
239
  this.makeInactive();
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <button
3
+ class="mds-combobox__clear mds-button mds-button--plain"
4
+ type="button"
5
+ @click="$emit('clear', $event)"
6
+ @keydown.enter="$emit('clear', $event)"
7
+ :aria-label="clearInput"
8
+ :title="clearInput"
9
+ >
10
+ <svg aria-hidden="true" focusable="false" class="mds-icon mds-icon--close mds-icon--sm">
11
+ <use href="/assets/icons.svg#icon-close" />
12
+ </svg>
13
+ </button>
14
+ </template>
15
+
16
+ <script>
17
+ export default {
18
+ name: 'ComboboxClear',
19
+ inject: ['clearInput'],
20
+ };
21
+ </script>
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div role="presentation">
3
3
  <input
4
+ ref="inputEl"
4
5
  v-bind="$attrs"
5
6
  class="mds-form-control"
6
7
  autocomplete="off"
@@ -34,6 +35,11 @@ export default {
34
35
  default: 'false',
35
36
  },
36
37
  },
38
+ methods: {
39
+ focusInput() {
40
+ this.$refs.inputEl.focus();
41
+ },
42
+ },
37
43
  inheritAttrs: false,
38
44
  };
39
45
  </script>
@@ -1,6 +1,6 @@
1
1
  const elementName = 'mds-combobox';
2
2
 
3
- function bindToSelect() {
3
+ function bindToLocationSelect() {
4
4
  const el = document.querySelector(`[data-combobox-id="distance-selection"]`);
5
5
 
6
6
  if (el) {
@@ -9,16 +9,41 @@ function bindToSelect() {
9
9
  const vueSelect = el.querySelector(elementName);
10
10
 
11
11
  vueSelect.options = options.slice(1).map((opt) => ({ value: opt.value, label: opt.textContent }));
12
- // not sure it's needed ?
13
- // vueSelect.addEventListener('select-option', (event) => {
14
- // const [option] = event.detail;
15
- // if (!option) return;
16
- // selectInput.value = option.value;
17
- // selectInput.querySelector(`option[value="${option.value}"]`).setAttribute('selected', true);
18
- // });
19
12
  }
20
13
  }
21
14
 
15
+ function bindToSalarySelect() {
16
+ const el = document.querySelector(`[data-combobox-id="salary-selection"]`);
17
+
18
+ if (el) {
19
+ const selectInput = el.querySelector('select');
20
+ const options = Array.from(selectInput.querySelectorAll('option'));
21
+ const vueSelect = el.querySelector(elementName);
22
+
23
+ vueSelect.options = options.slice(1).map((opt) => ({ value: opt.value, label: opt.textContent }));
24
+ }
25
+ }
26
+
27
+ function setSalaryHiddenField() {
28
+ const comboBoxEl = document.querySelector(`[data-combobox-id="salary-selection"] mds-combobox`);
29
+ const hiddenInputEl = document.querySelector('#salary-selection-hidden-input');
30
+
31
+ comboBoxEl.addEventListener('select-option', () => {
32
+ console.log('Setting #salary-selection-hidden-input..');
33
+ hiddenInputEl.value = hiddenInputEl.value === 'flip' ? 'flop' : 'flip';
34
+ });
35
+ }
36
+
37
+ function clearSalaryHiddenField() {
38
+ const comboBoxEl = document.querySelector(`[data-combobox-id="salary-selection"] mds-combobox`);
39
+ const hiddenInputEl = document.querySelector('#salary-selection-hidden-input');
40
+
41
+ comboBoxEl.addEventListener('clear-all', () => {
42
+ console.log('Clearing #salary-selection-hidden-input..');
43
+ hiddenInputEl.value = '';
44
+ });
45
+ }
46
+
22
47
  function bindToApi() {
23
48
  const el = document.querySelector(`[data-combobox-id="keywords-lookup"]`);
24
49
 
@@ -48,7 +73,10 @@ function bindToApi() {
48
73
 
49
74
  const combobox = {
50
75
  init: () => {
51
- bindToSelect();
76
+ bindToLocationSelect();
77
+ bindToSalarySelect();
78
+ setSalaryHiddenField();
79
+ clearSalaryHiddenField()
52
80
  bindToApi();
53
81
  },
54
82
  };