@madgex/design-system 13.8.0 → 14.0.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.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@madgex/design-system",
3
3
  "author": "Madgex",
4
4
  "license": "UNLICENSED",
5
- "version": "13.8.0",
5
+ "version": "14.0.0",
6
6
  "main": "dist/js/index.js",
7
7
  "exports": {
8
8
  ".": "./dist/js/index.js",
@@ -37,5 +37,17 @@ module.exports = {
37
37
  },
38
38
  },
39
39
  },
40
+ {
41
+ name: 'No Description',
42
+ context: {
43
+ name: 'no-description',
44
+ value: 'no-description',
45
+ i18n: {
46
+ title: 'No Description',
47
+ description: '',
48
+ price: '£7',
49
+ },
50
+ },
51
+ },
40
52
  ],
41
53
  };
@@ -6,7 +6,7 @@
6
6
  cursor: pointer;
7
7
  border: #{$regular-border};
8
8
  border-radius: $border-radius;
9
- justify-content: space-around;
9
+ justify-content: space-evenly;
10
10
  padding-left: ($constant-size-baseline * 4);
11
11
 
12
12
  & > * {
@@ -33,6 +33,7 @@
33
33
  width: 100px;
34
34
  max-width: 30%;
35
35
  white-space: nowrap;
36
+ margin-left: auto;
36
37
  }
37
38
 
38
39
  // Selected (checked) state
@@ -1,23 +1,34 @@
1
+ # MdsCombobox
2
+
3
+ This component provides autocomplete search functionality to select an option from a list of options.
4
+
5
+ Options can be provided via the `options` parameter, or obtained from an API using the `apiUrl` parameter.
6
+
7
+ `value` is an Object or Array of Objects representing the selected option or options.
8
+
1
9
  ## Parameters - Nunjucks
2
10
 
3
- - `id`: the id of your combobox
4
- - `name`: the name of the input for form submission. Uses ID unless specified - _optional_
5
- - `labelText`: the text used in the label
6
- - `options`: a JSON array, e.g `[{ label: 'Orange', value: 45 }]`. Populates both mds-combobox, and fallback select options
7
- - `apiUrl`: when populated, `options` is ignored and data is fetching from an API URL instead
8
- - `apiQueryKey`: the query paramter name added to `apiUrl` - _optional_ (defaults to 'searchText')
9
- - `apiOptionsPath`: where to grab an array of options on api response, e.g. `data.options` would be an array of options. _optional_ . leave undefined to use root api response as array
10
- - `optionLabelPath`: where to grab the visual label propertly from the option object e.g. 'label' or 'title' or 'nested.object.label' _optional_ (defaults to `label`)
11
- - `value`: a default selected value for the input - _optional_
12
- - `fallbackTo`: the form element to use as a fallback. Should be either 'select' or 'input'
13
- - `placeholder`: the placeholder for your input (defaults to 'Please select')
14
- - `classes`: add extra classes to the trigger - _optional_
15
- - `helpText`: Helper text to display under the label _optional_,
16
- - `tooltipMessage`: Toggles a tooltip with this message to appear on the input _optional_
17
- - `validationError`: The error message provided by validation _optional_,
18
- - `state`: The current state of the input, currently the only allowed value is `error` _optional_
19
- - `type`: name of the options api e.g "location-lookup"
20
- - `i18n`: Text to translate/customise (object) **optional**
11
+ - `id`: the id of your combobox **required**
12
+ - `name`: the name of the input for form submission. Uses ID unless specified - **recommended**
13
+ - `labelText`: the text used in the label **required**
14
+ - `value`: the populated option `object` ( `{ label: 'Orange', value: 45 }`) or `array` of option `objects` ( `[{ label: 'Orange', value: 45 }, { label: 'Green', value: 33 }]`)
15
+ - `searchText`: _Not_ the value, but the current text inside the search input.
16
+ - `options`: an `array`, e.g `[{ label: 'Orange', value: 45 }]`. Populates both mds-combobox, and fallback select options
17
+ - `apiUrl`: when populated, `options` is ignored and data is fetched from an API URL instead
18
+ - `apiQueryKey`: the query parameter name added to `apiUrl` - (defaults to 'searchText')
19
+ - `apiOptionsPath`: where to grab an array of options on api response, e.g. `data.options` would be an array of options. leave undefined to use root api response as array
20
+ - `optionLabelPath`: where to grab the visual label from the option object e.g. 'label' or 'title' or 'nested.object.label' (defaults to `label`)
21
+ - `optionValuePath`: where to grab the value from the option object e.g. `value` or `nested.object.value` (defaults to `value`)
22
+ - `multiple`: Boolean, whether to treat `value` input and output as an Array, or a singular. Also to display pills. default `false`
23
+ - `fallbackTo`: the form element to use as a fallback. Should be either 'select' or 'input' **recommended**
24
+ - `placeholder`: the placeholder for your input (defaults to 'Please select') **recommended**
25
+ - `classes`: add extra classes to the trigger
26
+ - `helpText`: Helper text to display under the label
27
+ - `tooltipMessage`: Toggles a tooltip with this message to appear on the input
28
+ - `validationError`: The error message provided by validation
29
+ - `state`: The current state of the input, currently the only allowed value is `error`
30
+ - `type`: applied as data-type` attribute, the name of the options api e.g "location-lookup"
31
+ - `i18n`: an `object`, Text to translate/customise
21
32
  - `minSearchCharacters`: The minimum number of characters inside the input before a search is performed to avoid low specificity searches. This should be matched by your implementation's search handler.
22
33
 
23
34
  ```
@@ -30,41 +41,158 @@ i18n: {
30
41
  resultsMessage: '{count} result available.', // announce number of results - note the use of `{count}` to get the number of results
31
42
  resultsMessage_plural: '{count} results available.', // announce number of results (plural) - note the use of `{count}` to get the number of results
32
43
  clearInput: 'clear input', // text for screen readers explaining what the clear control in combobox does
44
+ removePill: 'Remove {label}', // remove button aria label for pill, if using `multiple:true`
45
+ selectedOptionsLabel: 'Selected options:' // visually hidden text introducing the list of selected options, if using `multiple:true`
33
46
  }
34
47
  ```
35
48
 
36
- ## Updating hidden input values
49
+ ## Usage
37
50
 
38
- When a user selects an option, any inputs passed inside MdsCombobox with the data attribute `data-key` will be populated with values from that chosen option.
51
+ MdsCombobox usage revolves around either options provided by `params.options` or an API (`apiUrl` in use), and being in `multiple` mode via `params.multiple`.
52
+ If `multiple` mode is true,`params.value` must be undefined or an `array`, otherwise undefined or an `object`.
39
53
 
40
- ### Example 1
54
+ The params `value`, `options`, `optionLabelPath` and `optionValuePath` are tightly coupled and must be compatible with each other:
41
55
 
42
- Populate the hidden input with the `value` property from the selected option `{label:"my label", value: 56}`.
56
+ - `options`: an array of objects, each object has the property stated by `optionLabelPath` and `optionValuePath`
57
+ - `value`: an object ( or array of objects if `multiple:true`), object is the same shape as the ones in `options`, each object has the property stated by `optionLabelPath` and `optionValuePath`
58
+
59
+ ### Example - Single mode - no API - default option object shape
60
+
61
+ As our options object uses the default property names, we don't need to specify them.
43
62
 
44
63
  ```njk
45
- {\% call MdsCombobox({...}) \%}
46
- <input type="hidden" data-key="value" /> <!-- value will be 56 -->
64
+ {\% call MdsCombobox({
65
+ id:'my-id',
66
+ name: 'my-combo',
67
+ labelText:'My Combo',
68
+ options: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ]
69
+ }) \%}
47
70
  {\% endcall \%}
71
+
48
72
  ```
49
73
 
50
- ### Example 2
74
+ #### with prefilled value
51
75
 
52
- Populate the hidden input with the `nested.thing` property from the selected option `{label:"my label", nested: {thing: 989 }, lat: "56.202", lon: '0.142'}`.
76
+ ```njk
77
+ {\% call MdsCombobox({
78
+ id:'my-id',
79
+ name: 'my-combo',
80
+ labelText:'My Combo',
81
+ value: {value: 'value-2', label: 'my-label-2'},
82
+ options: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ]
83
+ }) \%}
84
+ {\% endcall \%}
85
+
86
+ ```
87
+
88
+ ### Example - Multiple mode - no API - default option object shape
53
89
 
54
90
  ```njk
55
- {\% call MdsCombobox({...}) \%}
56
- <input type="hidden" data-key="nested.thing" /> <!-- value will be 989 -->
57
- <input type="hidden" data-key="lat" /> <!-- value will be 56.202 -->
58
- <input type="hidden" data-key="lon" /> <!-- value will be 0.142 -->
91
+ {\% call MdsCombobox({
92
+ id:'my-id',
93
+ name: 'my-combo',
94
+ labelText:'My Combo',
95
+ options: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ],
96
+ multiple: true
97
+ }) \%}
59
98
  {\% endcall \%}
99
+
100
+ ```
101
+
102
+ #### with prefilled value
103
+
104
+ Note the value should be an array when using multiple mode.
105
+
106
+ ```njk
107
+ {\% call MdsCombobox({
108
+ id:'my-id',
109
+ name: 'my-combo',
110
+ labelText:'My Combo',
111
+ value: [{value: 'value-2', label: 'my-label-2'}],
112
+ options: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ],
113
+ multiple: true
114
+ }) \%}
115
+ {\% endcall \%}
116
+
117
+ ```
118
+
119
+ ### Example - Single mode - API usage - custom option object shape
120
+
121
+ API response options have a custom shape with `word` and `score` properties,
122
+ like so `[{word: 'something', score: 12},...]`. It also used `?keyword` for the query param on the request.
123
+
124
+ ```njk
125
+ {\% call MdsCombobox({
126
+ id:'my-id',
127
+ name: 'my-combo',
128
+ labelText:'My Combo',
129
+ apiUrl: '/api/location-lookup',
130
+ apiQueryKey: 'keyword',
131
+ optionLabelPath: 'word',
132
+ optionValuePath: 'score'
133
+ }) \%}
134
+ {\% endcall \%}
135
+
136
+ ```
137
+
138
+ #### with prefilled value
139
+
140
+ ```njk
141
+ {\% call MdsCombobox({
142
+ id:'my-id',
143
+ name: 'my-combo',
144
+ labelText:'My Combo',
145
+ value: {word: 'my-label-2', score: 'value-2'},
146
+ apiUrl: '/api/location-lookup',
147
+ apiQueryKey: 'keyword',
148
+ optionLabelPath: 'word',
149
+ optionValuePath: 'score'
150
+ }) \%}
151
+ {\% endcall \%}
152
+
153
+ ```
154
+
155
+ ### Example - Multiple mode - API usage - default option object shape
156
+
157
+ API response had a root object property called `data`, like so `{data:[{label: 'something', value: 12},...]}`.
158
+
159
+ ```njk
160
+ {\% call MdsCombobox({
161
+ id:'my-id',
162
+ name: 'my-combo',
163
+ labelText:'My Combo',
164
+ apiUrl: '/api/location-lookup',
165
+ apiOptionsPath: 'data',
166
+ multiple: true
167
+ }) \%}
168
+ {\% endcall \%}
169
+
170
+ ```
171
+
172
+ options:
173
+
174
+ #### with prefilled value
175
+
176
+ Note the value is an array for multiple mode.
177
+
178
+ ```njk
179
+ {\% call MdsCombobox({
180
+ id:'my-id',
181
+ name: 'my-combo',
182
+ labelText:'My Combo',
183
+ value: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ],
184
+ apiUrl: '/api/location-lookup',
185
+ apiOptionsPath: 'data',
186
+ multiple: true
187
+ }) \%}
188
+ {\% endcall \%}
189
+
60
190
  ```
61
191
 
62
192
  ## Accessibility
63
193
 
64
194
  The Vue component is a [WAI-ARIA 1.0 combobox](https://www.w3.org/TR/wai-aria-practices/#combobox).
65
195
 
66
- NB. The AJAX demo above currently only works in browsers, not <= IE11. Fetch will be polyfilled or replaced in due course.
67
-
68
196
  When Javascript is not available, either a native combobox or native input will be available as a fallback.
69
197
 
70
198
  aria-describedBy has been added to notify screen reader users how to interact with the autocomplete suggestions.
@@ -55,57 +55,80 @@
55
55
  }) }}
56
56
  {# Leave the custom element at the bottom so it has access to the above elements on render #}
57
57
  <mds-combobox
58
- comboboxid="{{ comboboxId }}"
58
+ combobox-id="{{ comboboxId }}"
59
+ name="{{ comboboxName }}"
59
60
  placeholder="{{ params.placeholder }}"
60
61
  iconpath="{{ defaultIconPath }}"
61
- {% if params.options.length %}options="{{params.options | dump}}"{% endif %}
62
+ {% if params.options and params.options.length %}options="{{params.options | dump }}"{% endif %}
62
63
  {% if params.apiUrl %}api-url="{{params.apiUrl}}"{% endif%}
63
64
  {% if params.apiQueryKey %}api-query-key="{{params.apiQueryKey}}"{% endif%}
64
65
  {% if params.apiOptionsPath %}api-options-path="{{params.apiOptionsPath}}"{% endif%}
65
66
  {% if params.optionLabelPath %}option-label-path="{{params.optionLabelPath}}"{% endif%}
67
+ {% if params.optionValuePath %}option-value-path="{{params.optionValuePath}}"{% endif%}
66
68
  i18n="{{ params.i18n | dump }}"
67
69
  data-aria-invalid="{{ params.validationError }}"
68
70
  {% if params.minSearchCharacters %}min-search-characters="{{ params.minSearchCharacters }}"{% endif %}
69
- {% if params.fallbackTo === 'input' %}name="{{ comboboxName }}"{% endif %}
70
- {% if params.value %}value="{{ params.value }}"{% endif %}
71
+ {% if params.value %}value="{{ params.value | dump }}"{% endif %}
72
+ {% if params.searchText %}search-text="{{ params.searchText }}"{% endif %}
73
+ {% if params.multiple %}multiple{% endif %}
71
74
  {% if ariaDescribedBy %} describedby-id="{{ariaDescribedBy}}"{% endif -%}
72
75
  {{- MdsAttributes(params.attributes) -}}
73
76
  >
77
+ {# all 'default slot' fallback content is removed from DOM when vue component loads #}
74
78
  <div class="mds-form-element__fallback">
75
- {% if params.fallbackTo === 'select' and params.options %}
79
+ {# matches Combobox Vue component #}
80
+ {% set _optionValuePath = params.optionValuePath or "value" %}
81
+ {% set _optionLabelPath = params.optionLabelPath or "label" %}
82
+ {# if no provided options, at least try to render select input with value's options #}
83
+ {% set _options = params.options or (params.multiple and params.value) %}
84
+
85
+ {% if params.fallbackTo === 'select' and _options %}
76
86
  <select
77
87
  class="mds-form-control"
78
88
  id="{{ comboboxId }}"
79
89
  name="{{ comboboxName }}"
80
- value="{{ params.defaultValue|default('') }}"
90
+ {% if params.multiple %}multiple{% endif %}
81
91
  {% if ariaDescribedBy %}aria-describedby="{{ariaDescribedBy}}"{% endif %}
82
92
  >
83
93
  <option>{{ placeholder }}</option>
84
- {%- if params.options -%}
85
- {%- for option in params.options -%}
86
- <option value="{{ option.value }}">{{ option.label }}</option>
94
+ {%- if _options -%}
95
+ {%- for option in _options -%}
96
+ <option
97
+ value="{{ option[_optionValuePath] }}"
98
+ {% if not params.multiple and params.value %}
99
+ {# not multiple mode, see if value #}
100
+ {% if params.value[_optionValuePath] === option[_optionValuePath] %}selected{% endif %}
101
+ {% elseif params.value %}
102
+ {# multiple mode, so we assume params.value is an array #}
103
+ {% for valOpt in params.value %}
104
+ {%if valOpt[_optionValuePath] === option[_optionValuePath] %} selected {% endif %}
105
+ {% endfor %}
106
+ {% endif %}
107
+ >{{ option[_optionLabelPath] }}</option>
87
108
  {%- endfor -%}
88
109
  {%- endif -%}
89
110
  </select>
90
- {% elseif params.fallbackTo === 'input' %}
111
+ {# we cant have multiple mode and use input #}
112
+ {% elseif not params.multiple and params.fallbackTo === 'input' %}
91
113
  <input
92
114
  class="mds-form-control"
93
115
  type="text"
94
116
  name="{{ comboboxName }}"
95
117
  autocomplete="off"
96
118
  id="{{ comboboxId }}"
97
- value="{{ params.value|default('') }}"
119
+ {% if params.value %} value="{{params.value[_optionValuePath]}}"{% endif %}
98
120
  placeholder="{{ placeholder }}"
99
121
  {% if params.validationError %}aria-invalid="true"{% endif %}
100
122
  {% if ariaDescribedBy %}aria-describedby="{{ariaDescribedBy}}"{% endif %}
101
123
  />
124
+ {% elseif params.multiple and params.fallbackTo === 'input' %}
125
+ <strong>YOU MUST USE `select` AS `fallbackTo` WHEN USING `multiple` MODE</strong>
102
126
  {% endif %}
103
127
  </div>
104
128
  {% if caller %}
105
- <span slot="target-inputs">
106
- {{- caller() -}}
107
- </span>
129
+ {{- caller() -}}
108
130
  {% endif %}
109
131
  </mds-combobox>
132
+ <br><br>
110
133
  </div>
111
134
  {%- endif -%}
@@ -23,31 +23,16 @@ module.exports = {
23
23
  classes: 'im-a-custom-class',
24
24
  },
25
25
  },
26
-
27
- {
28
- name: 'default',
29
- context: {
30
- variantTitle: 'Multi select',
31
- name: 'multi',
32
- id: 'multiselect',
33
- optional: 'true',
34
- labelText: 'How far are you willing to travel?',
35
- options: optionsDistance,
36
- fallbackTo: 'select',
37
- multiple: true,
38
- placeholder: 'eg. Within 5 miles',
39
- },
40
- },
41
26
  {
42
- name: 'Clears hidden field(s)',
27
+ name: 'Search text pre-populated, option *not* selected',
43
28
  context: {
44
- variantTitle: 'Clear hidden',
29
+ variantTitle: 'Search text pre-populated, option *not* selected',
45
30
  name: 'Salary',
46
31
  id: 'salary-selection',
47
32
  optional: 'true',
48
33
  labelText: 'Salary expectations?',
49
34
  options: optionsSalary,
50
- value: 'Up to',
35
+ searchText: 'Up to',
51
36
  fallbackTo: 'select',
52
37
  },
53
38
  },
@@ -66,6 +51,7 @@ module.exports = {
66
51
  apiQueryKey: 's',
67
52
  apiOptionsPath: undefined,
68
53
  optionLabelPath: 'word',
54
+ optionValuePath: 'score',
69
55
  i18n: {
70
56
  requiredIcon: 'Required (test i18n)',
71
57
  loadingText: 'Loading (test i18n)',
@@ -82,18 +68,18 @@ module.exports = {
82
68
  context: {
83
69
  useAutocomplete: true,
84
70
  variantTitle: 'AJAX autocomplete prefilled',
85
- name: 'keywords',
71
+ name: 'keywords-prefilled',
86
72
  id: 'keywords-lookup-prefilled',
87
73
  labelText: 'Keywords:',
88
74
  placeholder: 'eg. Testimonials',
89
- value: 'Initial Value',
90
- vModel: 'Initial Value',
75
+ value: { word: 'Initial Value', score: 'the-value' },
91
76
  fallbackTo: 'input',
92
77
  minSearchCharacters: 3,
93
78
  apiUrl: 'https://api.datamuse.com/sug',
94
79
  apiQueryKey: 's',
95
80
  apiOptionsPath: undefined,
96
81
  optionLabelPath: 'word',
82
+ optionValuePath: 'score',
97
83
  },
98
84
  },
99
85
  {
@@ -101,14 +87,78 @@ module.exports = {
101
87
  context: {
102
88
  useAutocomplete: true,
103
89
  variantTitle: 'AJAX autocomplete prefilled with validation error',
104
- name: 'keywords',
90
+ name: 'keywordsprefilled-error',
105
91
  id: 'keywords-lookup-prefilled-validation-error',
106
92
  labelText: 'Keywords:',
107
93
  placeholder: 'eg. Testimonials',
108
- value: 'Initial Value',
109
- vModel: 'Initial Value',
94
+ value: { word: 'Initial Value', score: 'the-value' },
110
95
  fallbackTo: 'input',
111
96
  validationError: 'There was an error',
97
+ apiQueryKey: 's',
98
+ apiOptionsPath: undefined,
99
+ optionLabelPath: 'word',
100
+ optionValuePath: 'score',
101
+ },
102
+ },
103
+ {
104
+ name: 'AJAX multiselect - multiple attr',
105
+ context: {
106
+ useAutocomplete: true,
107
+ variantTitle: 'AJAX multiselect',
108
+ name: 'keywords-multiple',
109
+ id: 'keywords-lookup-multiselect-preselected',
110
+ labelText: 'Keywords:',
111
+ placeholder: 'eg. Web developer',
112
+ fallbackTo: 'select',
113
+ minSearchCharacters: 3,
114
+ apiUrl: 'https://api.datamuse.com/sug',
115
+ apiQueryKey: 's',
116
+ apiOptionsPath: undefined,
117
+ optionLabelPath: 'word',
118
+ optionValuePath: 'score',
119
+ multiple: true,
120
+ i18n: {
121
+ requiredIcon: 'Required (test i18n)',
122
+ loadingText: 'Loading (test i18n)',
123
+ describedByText:
124
+ 'When autocomplete results are available, use up and down arrows to review and enter to select. (test i18n)',
125
+ resultsMessage: '{count} result available (test i18n)',
126
+ resultsMessage_plural: '{count} results available (test i18n)',
127
+ clearInput: 'clear input (test i18n)',
128
+ },
129
+ },
130
+ },
131
+ {
132
+ name: 'AJAX multiselect - prefilled',
133
+ context: {
134
+ useAutocomplete: true,
135
+ variantTitle: 'AJAX multiselect-prefilled',
136
+ name: 'keywords-multiple-prefilled',
137
+ id: 'keywords-lookup-multiselect-prefilled',
138
+ labelText: 'Keywords:',
139
+ placeholder: 'eg. Web developer',
140
+ value: [
141
+ { word: 'Initial Value 1', score: 'the-value-1' },
142
+ { word: 'Initial Value 2', score: 'the-value-2' },
143
+ ],
144
+ fallbackTo: 'select',
145
+ minSearchCharacters: 3,
146
+ apiUrl: 'https://api.datamuse.com/sug',
147
+ apiQueryKey: 's',
148
+ apiOptionsPath: undefined,
149
+ optionLabelPath: 'word',
150
+ optionValuePath: 'score',
151
+ multiple: true,
152
+ i18n: {
153
+ requiredIcon: 'Required (test i18n)',
154
+ loadingText: 'Loading (test i18n)',
155
+ describedByText:
156
+ 'When autocomplete results are available, use up and down arrows to review and enter to select. (test i18n)',
157
+ resultsMessage: '{count} result available (test i18n)',
158
+ resultsMessage_plural: '{count} results available (test i18n)',
159
+ clearInput: 'clear input (test i18n)',
160
+ selectedOptionsLabel: 'Selected options: (test i18n)',
161
+ },
112
162
  },
113
163
  },
114
164
  ],
@@ -1,7 +1,6 @@
1
1
  {% from "./inputs/combobox/_macro.njk" import MdsCombobox %}
2
2
 
3
- {% if not multiple %}
4
- <div class="mds-grid-row">
3
+ <form class="mds-grid-row">
5
4
  <div class="mds-grid-col-6">
6
5
  <h3>{{ variantTitle }}</h3>
7
6
 
@@ -12,6 +11,7 @@
12
11
  options: options,
13
12
  optional: optional,
14
13
  value: value,
14
+ searchText: searchText,
15
15
  fallbackTo: fallbackTo,
16
16
  classes: classes,
17
17
  placeholder: placeholder,
@@ -24,25 +24,11 @@
24
24
  apiQueryKey: apiQueryKey,
25
25
  apiOptionsPath: apiOptionsPath,
26
26
  optionLabelPath: optionLabelPath,
27
+ optionValuePath: optionValuePath,
28
+ multiple: multiple
27
29
  attributes: attributes
28
30
  }) %}
29
- {#
30
- The below demonstrates how a target input value can be set on option selection, or on clear of combobox
31
- #}
32
- {% if id === 'salary-selection' %}
33
- <input disabled data-key="value" placeholder="normally hidden target" style="position:absolute; left: 100%; top: 0;" />
34
- {% endif %}
35
- {% if id === 'keywords-lookup' or id === 'keywords-lookup-prefilled' %}
36
- <input disabled data-key="word" placeholder="normally hidden target" style="position:absolute; left: 100%; top: 0;" />
37
- {% endif %}
38
31
  {% endcall %}
39
-
40
- {% if id === 'salary-selection' %}
41
- <p class="mds-margin-top-b3">A hidden input is cleared when combobox is cleared.
42
- {% endif %}
43
-
44
- <br><br>
45
32
  </div>
46
- </div>
47
- {% endif %}
33
+ </form>
48
34
 
@@ -1,39 +1,29 @@
1
1
  .mds-combobox {
2
2
  display: block;
3
3
  position: relative;
4
-
5
- /* .mds-combobox--multiple has checkbox inputs too, so we need to target type="text" only */
6
- & input[type='text'] {
7
- padding-right: $constant-size-baseline * 14;
8
- }
9
- }
10
- .mds-combobox--multiple {
11
- background-color: #fff;
12
- @extend .mds-form-control;
13
- padding: 0;
14
- & input[type='text'] {
15
- width: 100%;
16
- border: 0;
17
- padding: $constant-size-baseline * 3; // match .mds-form-control
18
- font-size: inherit;
19
- line-height: inherit;
20
- padding-right: $constant-size-baseline * 14;
21
- appearance: none;
22
- &:focus {
23
- outline: 0;
24
- }
4
+ .mds-form-control {
5
+ display: flex;
6
+ flex-wrap: wrap;
7
+ cursor: text;
8
+ gap: $constant-size-baseline;
25
9
  }
26
10
  }
27
- .mds-combobox__input {
28
- position: relative;
29
- }
30
- .mds-combobox__pills {
31
- padding: $constant-size-baseline;
32
- padding-bottom: 0;
11
+ .mds-combobox__search-input {
12
+ flex: 1;
13
+ min-width: 180px;
14
+ border: 0;
15
+ outline: 0;
16
+ font-size: inherit;
17
+ line-height: inherit;
18
+ background: transparent;
19
+ appearance: none;
20
+ padding-right: $constant-size-baseline * 10;
33
21
  }
22
+
34
23
  .mds-combobox__clear {
35
24
  position: absolute;
36
25
  top: 0;
26
+ bottom: 0;
37
27
  right: 0;
38
28
  cursor: pointer;
39
29
  &:focus {
@@ -88,3 +78,45 @@
88
78
  }
89
79
  }
90
80
  }
81
+ .mds-combobox__pills {
82
+ display: inline-flex;
83
+ flex-wrap: wrap;
84
+ gap: $constant-size-baseline;
85
+ margin-bottom: 0;
86
+ }
87
+ .mds-combobox__pill {
88
+ font-size: var(--mds-font-type-s-1-size);
89
+ display: inline-flex;
90
+ align-items: center;
91
+ border-radius: $border-radius;
92
+ padding: $constant-size-baseline ($constant-size-baseline * 2);
93
+ max-width: 100%;
94
+ background-color: $constant-color-neutral-lightest;
95
+ }
96
+
97
+ .mds-combobox__pill-text {
98
+ flex: 1 1 0;
99
+ overflow: hidden;
100
+ text-overflow: ellipsis;
101
+ white-space: nowrap;
102
+ }
103
+
104
+ .mds-combobox__pill-icon {
105
+ background: none;
106
+ border: none;
107
+ padding: 0 0 0 ($constant-size-baseline);
108
+ margin: 0;
109
+ cursor: pointer;
110
+ display: inline-flex;
111
+ align-items: center;
112
+ flex-shrink: 0;
113
+
114
+ .mds-icon {
115
+ top: 0;
116
+ }
117
+
118
+ &:focus {
119
+ @include inputFocusStyle();
120
+ border-radius: $border-radius;
121
+ }
122
+ }