@madgex/design-system 14.3.0 → 14.4.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/dist/assets/icons-inline.svg +1 -1
- package/dist/assets/icons.json +1 -1
- package/dist/assets/icons.svg +1 -1
- package/dist/css/index.css +1 -1
- package/dist/js/index.js +1 -1
- package/package.json +4 -4
- package/src/components/accordion/_template.njk +35 -33
- package/src/components/accordion/accordion.config.js +0 -81
- package/src/components/accordion/accordion.js +53 -43
- package/src/components/accordion/accordion.njk +1 -24
- package/src/components/button/button.config.js +1 -42
- package/src/components/button/button.njk +1 -14
- package/src/components/card/card.config.js +0 -93
- package/src/components/card/card.njk +1 -22
- package/src/components/icons/icons.njk +1 -161
- package/src/components/inputs/combobox/README.md +44 -51
- package/src/components/inputs/combobox/_template.njk +11 -31
- package/src/components/inputs/combobox/combobox.config.js +23 -22
- package/src/components/inputs/combobox/combobox.njk +4 -4
- package/src/components/inputs/combobox/combobox.scss +3 -0
- package/src/js/index.js +5 -2
- package/src/layout/containers/index.njk +1 -0
- package/src/layout/forms/forms.config.js +7 -1
- package/src/layout/forms/forms.njk +8 -4
- package/src/typography/index.njk +1 -0
- package/tasks/svgsprite.js +62 -49
- package/src/components/accordion/README.md +0 -46
- package/src/components/button/README.md +0 -27
- package/src/components/card/README.md +0 -114
- package/src/components/icons/README.md +0 -62
- package/src/layout/containers/01-base-containers.njk +0 -30
- package/src/layout/containers/02-branded-containers.njk +0 -13
- package/src/layout/containers/03-ad-containers.njk +0 -6
- package/src/layout/containers/04-highlighted-containers.njk +0 -3
- package/src/layout/containers/README.md +0 -30
- package/src/layout/containers/ad-containers.config.json +0 -3
- package/src/layout/containers/base-containers.config.json +0 -3
- package/src/layout/containers/branded-containers.config.json +0 -3
- package/src/layout/containers/highlighted-containers.config.json +0 -3
- package/src/typography/font-types.config.json +0 -3
- package/src/typography/font-types.njk +0 -43
- package/src/typography/headings.njk +0 -9
- package/src/typography/lists.njk +0 -111
|
@@ -2,97 +2,4 @@ module.exports = {
|
|
|
2
2
|
title: 'Card',
|
|
3
3
|
label: 'Card',
|
|
4
4
|
status: 'ready',
|
|
5
|
-
context: {
|
|
6
|
-
fractalLabel: 'Card',
|
|
7
|
-
inList: false,
|
|
8
|
-
classes: '',
|
|
9
|
-
content: '<h4>Card Title</h4><p>paragraph</p>',
|
|
10
|
-
id: 'default',
|
|
11
|
-
},
|
|
12
|
-
variants: [
|
|
13
|
-
{
|
|
14
|
-
name: 'card-in-list',
|
|
15
|
-
context: {
|
|
16
|
-
fractalLabel: 'Card used in a list',
|
|
17
|
-
inList: true,
|
|
18
|
-
classes: '',
|
|
19
|
-
content: '<h4>Card used in list (li instead of div)</h4><p>paragraph</p>',
|
|
20
|
-
id: 'in-list',
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'card-with-highlight',
|
|
25
|
-
context: {
|
|
26
|
-
fractalLabel: 'Card with background',
|
|
27
|
-
inList: false,
|
|
28
|
-
classes: 'mds-card--highlighted',
|
|
29
|
-
content: '<h4>Card Title</h4><p>paragraph</p>',
|
|
30
|
-
id: 'with-background',
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
name: 'card-with-custom-styling',
|
|
35
|
-
context: {
|
|
36
|
-
fractalLabel: 'Card with custom styling',
|
|
37
|
-
inList: false,
|
|
38
|
-
classes: 'mds-card--1',
|
|
39
|
-
content: '<h4>Card Title</h4><p>paragraph</p>',
|
|
40
|
-
id: 'with-custom-styling',
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: 'card-with-badges',
|
|
45
|
-
context: {
|
|
46
|
-
fractalLabel: 'Card with badges',
|
|
47
|
-
inList: false,
|
|
48
|
-
content: '<h4>Card Title</h4><p>paragraph</p>',
|
|
49
|
-
id: 'with-badge',
|
|
50
|
-
badges: {
|
|
51
|
-
left: [
|
|
52
|
-
{
|
|
53
|
-
label: 'Top Job',
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
right: [
|
|
57
|
-
{
|
|
58
|
-
label: 'Approved Employer',
|
|
59
|
-
styleId: '1',
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
label: 'New',
|
|
63
|
-
styleId: 'new',
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
name: 'link-card',
|
|
71
|
-
context: {
|
|
72
|
-
fractalLabel: 'Card with a link',
|
|
73
|
-
link: {
|
|
74
|
-
href: 'https://www.google.com',
|
|
75
|
-
title: 'Card with link',
|
|
76
|
-
containerElement: 'h3',
|
|
77
|
-
},
|
|
78
|
-
classes: '',
|
|
79
|
-
content: '<p>content</p><p>content</p><p>content</p><p>content</p>',
|
|
80
|
-
id: 'with link',
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: 'list-link-card',
|
|
85
|
-
context: {
|
|
86
|
-
fractalLabel: 'Card with link used in a list',
|
|
87
|
-
inList: true,
|
|
88
|
-
link: {
|
|
89
|
-
href: 'https://www.google.com',
|
|
90
|
-
title: 'Card with link',
|
|
91
|
-
},
|
|
92
|
-
classes: '',
|
|
93
|
-
content: '<p>content</p><p>content</p><p>content</p><p>content</p>',
|
|
94
|
-
id: 'in-list',
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
],
|
|
98
5
|
};
|
|
@@ -1,22 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
<div class="mds-margin-bottom-b5">
|
|
4
|
-
<h2>{{ fractalLabel }}</h2>
|
|
5
|
-
{%- if inList -%}
|
|
6
|
-
<ul>
|
|
7
|
-
{%- endif -%}
|
|
8
|
-
|
|
9
|
-
{% call MdsCard({
|
|
10
|
-
inList: inList,
|
|
11
|
-
classes: classes,
|
|
12
|
-
id: id,
|
|
13
|
-
badges: badges,
|
|
14
|
-
link: link
|
|
15
|
-
}) -%}
|
|
16
|
-
<!-- example - in normal use `safe` is discouraged as it is dangerous, and not needed -->
|
|
17
|
-
{{ content | safe }}
|
|
18
|
-
{%- endcall %}
|
|
19
|
-
{%- if inList -%}
|
|
20
|
-
</ul>
|
|
21
|
-
{%- endif -%}
|
|
22
|
-
</div>
|
|
1
|
+
<a href="/storybook/" target="_top">Moved to Storybook</a>
|
|
@@ -1,161 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
{% from "./icons/_macro.njk" import MdsIcon %}
|
|
4
|
-
|
|
5
|
-
<h2>Different sizes</h2>
|
|
6
|
-
|
|
7
|
-
<p>{{ MdsIcon({
|
|
8
|
-
iconName: 'star-fill',
|
|
9
|
-
classes: 'mds-icon--sm',
|
|
10
|
-
visuallyHiddenLabel: 'Shortlisted'
|
|
11
|
-
}) }} : small (16px)</p>
|
|
12
|
-
<p>{{ MdsIcon({
|
|
13
|
-
iconName: 'star-fill',
|
|
14
|
-
classes: 'mds-icon--md'
|
|
15
|
-
}) }} : medium (24px)</p>
|
|
16
|
-
<p>{{ MdsIcon({
|
|
17
|
-
iconName: 'star-fill',
|
|
18
|
-
classes: 'mds-icon--lg'
|
|
19
|
-
}) }} : large (32px)</p>
|
|
20
|
-
<p>{{ MdsIcon({
|
|
21
|
-
iconName: 'star-fill',
|
|
22
|
-
classes: 'mds-icon--xl'
|
|
23
|
-
}) }} : extra large (48px)</p>
|
|
24
|
-
<p>{{ MdsIcon({
|
|
25
|
-
iconName: 'star-fill',
|
|
26
|
-
classes: 'mds-icon--xxl'
|
|
27
|
-
}) }} : extra extra large (72px)</p>
|
|
28
|
-
|
|
29
|
-
<br><hr><br>
|
|
30
|
-
|
|
31
|
-
<h2>Icon with text</h2>
|
|
32
|
-
|
|
33
|
-
<p>{{- MdsIcon({
|
|
34
|
-
iconName: 'email',
|
|
35
|
-
classes: 'mds-icon--before'
|
|
36
|
-
}) -}}Email me</p>
|
|
37
|
-
|
|
38
|
-
<p><a href="#">Apply{{- MdsIcon({
|
|
39
|
-
iconName: 'chevron-right',
|
|
40
|
-
classes: 'mds-icon--after'
|
|
41
|
-
}) -}}</a></p>
|
|
42
|
-
|
|
43
|
-
<div>
|
|
44
|
-
<span>Share this job</span>
|
|
45
|
-
<ul class="mds-list mds-list--inline mds-display-inline-block">
|
|
46
|
-
<li class="mds-list__item">
|
|
47
|
-
<a href="#">
|
|
48
|
-
{{- MdsIcon({
|
|
49
|
-
iconName: 'social-facebook',
|
|
50
|
-
visuallyHiddenLabel: 'Facebook'
|
|
51
|
-
}) -}}
|
|
52
|
-
</a>
|
|
53
|
-
</li>
|
|
54
|
-
<li class="mds-list__item">
|
|
55
|
-
<a href="#">
|
|
56
|
-
{{- MdsIcon({
|
|
57
|
-
iconName: 'social-twitter',
|
|
58
|
-
visuallyHiddenLabel: 'Twitter'
|
|
59
|
-
}) -}}
|
|
60
|
-
</a>
|
|
61
|
-
</li>
|
|
62
|
-
<li class="mds-list__item">
|
|
63
|
-
<a href="#">
|
|
64
|
-
{{- MdsIcon({
|
|
65
|
-
iconName: 'social-linkedin',
|
|
66
|
-
visuallyHiddenLabel: 'LinkedIn'
|
|
67
|
-
}) -}}
|
|
68
|
-
</a>
|
|
69
|
-
</li>
|
|
70
|
-
<li class="mds-list__item">
|
|
71
|
-
<a href="#">
|
|
72
|
-
{{- MdsIcon({
|
|
73
|
-
iconName: 'social-pinterest',
|
|
74
|
-
visuallyHiddenLabel: 'Pinterest'
|
|
75
|
-
}) -}}
|
|
76
|
-
</a>
|
|
77
|
-
</li>
|
|
78
|
-
<li class="mds-list__item">
|
|
79
|
-
<a href="#">
|
|
80
|
-
{{- MdsIcon({
|
|
81
|
-
iconName: 'social-reddit',
|
|
82
|
-
visuallyHiddenLabel: 'Reddit'
|
|
83
|
-
}) -}}
|
|
84
|
-
</a>
|
|
85
|
-
</li>
|
|
86
|
-
</ul>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
<br><hr><br>
|
|
90
|
-
|
|
91
|
-
<h2>Spinner</h2>
|
|
92
|
-
{{- MdsIcon({
|
|
93
|
-
iconName: 'spinner',
|
|
94
|
-
visuallyHiddenLabel: 'Loading...'
|
|
95
|
-
}) -}}
|
|
96
|
-
|
|
97
|
-
<br><hr><br>
|
|
98
|
-
|
|
99
|
-
<h2>Has container</h2>
|
|
100
|
-
{{- MdsIcon({
|
|
101
|
-
iconName: 'cross',
|
|
102
|
-
visuallyHiddenLabel: 'Error',
|
|
103
|
-
classes: 'mds-icon--md',
|
|
104
|
-
hasContainer: true,
|
|
105
|
-
containerClasses: 'mds-icon-container--circle mds-icon-container--error'
|
|
106
|
-
}) -}}
|
|
107
|
-
|
|
108
|
-
<br><hr><br>
|
|
109
|
-
|
|
110
|
-
<h2>Icons using inline SVG</h2>
|
|
111
|
-
|
|
112
|
-
<div>
|
|
113
|
-
<span>Share this job</span>
|
|
114
|
-
<ul class="mds-list mds-list--inline mds-display-inline-block">
|
|
115
|
-
<li class="mds-list__item">
|
|
116
|
-
<a href="#">
|
|
117
|
-
{{- MdsIcon({
|
|
118
|
-
iconName: 'social-facebook',
|
|
119
|
-
visuallyHiddenLabel: 'Facebook',
|
|
120
|
-
path: ''
|
|
121
|
-
}) -}}
|
|
122
|
-
</a>
|
|
123
|
-
</li>
|
|
124
|
-
<li class="mds-list__item">
|
|
125
|
-
<a href="#">
|
|
126
|
-
{{- MdsIcon({
|
|
127
|
-
iconName: 'social-twitter',
|
|
128
|
-
visuallyHiddenLabel: 'Twitter',
|
|
129
|
-
path: ''
|
|
130
|
-
}) -}}
|
|
131
|
-
</a>
|
|
132
|
-
</li>
|
|
133
|
-
<li class="mds-list__item">
|
|
134
|
-
<a href="#">
|
|
135
|
-
{{- MdsIcon({
|
|
136
|
-
iconName: 'social-linkedin',
|
|
137
|
-
visuallyHiddenLabel: 'LinkedIn',
|
|
138
|
-
path: ''
|
|
139
|
-
}) -}}
|
|
140
|
-
</a>
|
|
141
|
-
</li>
|
|
142
|
-
<li class="mds-list__item">
|
|
143
|
-
<a href="#">
|
|
144
|
-
{{- MdsIcon({
|
|
145
|
-
iconName: 'social-pinterest',
|
|
146
|
-
visuallyHiddenLabel: 'Pinterest',
|
|
147
|
-
path: ''
|
|
148
|
-
}) -}}
|
|
149
|
-
</a>
|
|
150
|
-
</li>
|
|
151
|
-
<li class="mds-list__item">
|
|
152
|
-
<a href="#">
|
|
153
|
-
{{- MdsIcon({
|
|
154
|
-
iconName: 'social-reddit',
|
|
155
|
-
visuallyHiddenLabel: 'Reddit',
|
|
156
|
-
path: ''
|
|
157
|
-
}) -}}
|
|
158
|
-
</a>
|
|
159
|
-
</li>
|
|
160
|
-
</ul>
|
|
161
|
-
</div>
|
|
1
|
+
<a href="/storybook/" target="_top">Moved to Storybook</a>
|
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
This component provides autocomplete search functionality to select an option from a list of options.
|
|
4
4
|
|
|
5
|
-
Options can be provided via
|
|
6
|
-
|
|
7
|
-
`value` is an Object or Array of Objects representing the selected option or options.
|
|
5
|
+
Options can be provided via `<option value="value">label</option>` children, or obtained from an API using the `apiUrl` parameter.
|
|
8
6
|
|
|
9
7
|
## Parameters - Nunjucks
|
|
10
8
|
|
|
11
9
|
- `id`: the id of your combobox **required**
|
|
12
10
|
- `name`: the name of the input for form submission. Uses ID unless specified - **recommended**
|
|
13
11
|
- `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
12
|
- `searchText`: _Not_ the value, but the current text inside the search input.
|
|
16
|
-
- `
|
|
17
|
-
- `apiUrl`: when populated, `options` is ignored and data is fetched from an API URL instead
|
|
13
|
+
- `apiUrl`: when populated, options data is fetched from an API URL
|
|
18
14
|
- `apiQueryKey`: the query parameter name added to `apiUrl` - (defaults to 'searchText')
|
|
19
15
|
- `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
|
-
- `
|
|
21
|
-
- `
|
|
16
|
+
- `apiOptionLabelPath`: relative to options object returned from API response, e.g. `label` or `title` or `nested.object.label` (defaults to `label`)
|
|
17
|
+
- `apiOptionValuePath`: relative to options object returned from API response, e.g. `value` or `score` or `nested.object.value` (defaults to `value`)
|
|
22
18
|
- `multiple`: Boolean, whether to treat `value` input and output as an Array, or a singular. Also to display pills. default `false`
|
|
23
19
|
- `fallbackTo`: the form element to use as a fallback. Should be either 'select' or 'input' **recommended** (see notes underneath)
|
|
24
|
-
- `
|
|
20
|
+
- `fallbackValue`: only when `fallbackTo` is `input`, the `value` attribute of the fallback `input` element
|
|
21
|
+
- `placeholder`: the placeholder for your input **recommended**
|
|
25
22
|
- `classes`: add extra classes to the trigger
|
|
26
23
|
- `helpText`: Helper text to display under the label
|
|
27
24
|
- `tooltipMessage`: Toggles a tooltip with this message to appear on the input
|
|
28
25
|
- `validationError`: The error message provided by validation
|
|
29
26
|
- `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"
|
|
27
|
+
- `type`: applied as `data-type` attribute, the name of the options api e.g "location-lookup"
|
|
31
28
|
- `i18n`: an `object`, Text to translate/customise
|
|
32
29
|
- `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.
|
|
30
|
+
- `attributes`: an `object`, attribute key/values applied directly to `mds-combobox` element
|
|
31
|
+
- `hideLabel` — Boolean, visually hides the label.
|
|
32
|
+
- `optional` - Boolean, marks field as optional in the label only
|
|
33
33
|
|
|
34
34
|
```
|
|
35
35
|
i18n: {
|
|
@@ -48,13 +48,7 @@ i18n: {
|
|
|
48
48
|
|
|
49
49
|
## Usage
|
|
50
50
|
|
|
51
|
-
MdsCombobox usage revolves around
|
|
52
|
-
If `multiple` mode is true,`params.value` must be undefined or an `array`, otherwise undefined or an `object`.
|
|
53
|
-
|
|
54
|
-
The params `value`, `options`, `optionLabelPath` and `optionValuePath` are tightly coupled and must be compatible with each other:
|
|
55
|
-
|
|
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`
|
|
51
|
+
MdsCombobox usage revolves around options provided by `<option value="">label</option>` child elements as available options and the initial value comes from `<option selected>` children, and optionally an API (`apiUrl` in use), and being in `multiple` mode via `params.multiple`.
|
|
58
52
|
|
|
59
53
|
## Fallback
|
|
60
54
|
|
|
@@ -63,65 +57,52 @@ When JavaScript is unavailable, the combobox will gracefully degrade to a native
|
|
|
63
57
|
Both fallback elements share the same `id` as the combobox to ensure the label remains properly associated. However, the fallback's `name` attribute will be `[name]_fallback` to distinguish it from the JavaScript-enabled version. This allows your server-side code to detect when the fallback was used and handle the form submission appropriately.
|
|
64
58
|
|
|
65
59
|
**Choosing a fallback type:**
|
|
60
|
+
|
|
66
61
|
- Use `fallbackTo: 'select'` when you have a static, predefined list of options that work well in a standard dropdown.
|
|
67
62
|
- Use `fallbackTo: 'input'` when options are dynamic (from an API) or when you prefer a text input. With a text input fallback, users can type and submit values that your server can then process (e.g., look up a location ID from a location name).
|
|
63
|
+
- Use `fallbackValue` when using `fallbackTo: 'input'` to populate the fallback's value
|
|
68
64
|
|
|
69
|
-
### Example - Single mode - no API -
|
|
70
|
-
|
|
71
|
-
As our options object uses the default property names, we don't need to specify them.
|
|
72
|
-
|
|
73
|
-
```njk
|
|
74
|
-
{\% call MdsCombobox({
|
|
75
|
-
id:'my-id',
|
|
76
|
-
name: 'my-combo',
|
|
77
|
-
labelText:'My Combo',
|
|
78
|
-
options: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ]
|
|
79
|
-
}) \%}
|
|
80
|
-
{\% endcall \%}
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
#### with prefilled value
|
|
65
|
+
### Example - Single mode - no API - no option selected
|
|
85
66
|
|
|
86
67
|
```njk
|
|
87
68
|
{\% call MdsCombobox({
|
|
88
69
|
id:'my-id',
|
|
89
70
|
name: 'my-combo',
|
|
90
71
|
labelText:'My Combo',
|
|
91
|
-
value: {value: 'value-2', label: 'my-label-2'},
|
|
92
|
-
options: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ]
|
|
93
72
|
}) \%}
|
|
73
|
+
<option value="value-1">My label 1</option>
|
|
74
|
+
<option value="value-2">My label 2</option>
|
|
94
75
|
{\% endcall \%}
|
|
95
76
|
|
|
96
77
|
```
|
|
97
78
|
|
|
98
|
-
|
|
79
|
+
#### with pre-selected value
|
|
99
80
|
|
|
100
81
|
```njk
|
|
101
82
|
{\% call MdsCombobox({
|
|
102
83
|
id:'my-id',
|
|
103
84
|
name: 'my-combo',
|
|
104
85
|
labelText:'My Combo',
|
|
105
|
-
|
|
106
|
-
|
|
86
|
+
fallbackTo:'input',
|
|
87
|
+
fallbackValue:'value-2'
|
|
107
88
|
}) \%}
|
|
89
|
+
<option value="value-1">My label 1</option>
|
|
90
|
+
<option value="value-2" selected>My label 2</option>
|
|
108
91
|
{\% endcall \%}
|
|
109
92
|
|
|
110
93
|
```
|
|
111
94
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Note the value should be an array when using multiple mode.
|
|
95
|
+
### Example - Multiple mode - no API
|
|
115
96
|
|
|
116
97
|
```njk
|
|
117
98
|
{\% call MdsCombobox({
|
|
118
99
|
id:'my-id',
|
|
119
100
|
name: 'my-combo',
|
|
120
101
|
labelText:'My Combo',
|
|
121
|
-
value: [{value: 'value-2', label: 'my-label-2'}],
|
|
122
|
-
options: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ],
|
|
123
102
|
multiple: true
|
|
124
103
|
}) \%}
|
|
104
|
+
<option value="value-1">My label 1</option>
|
|
105
|
+
<option value="value-2">My label 2</option>
|
|
125
106
|
{\% endcall \%}
|
|
126
107
|
|
|
127
108
|
```
|
|
@@ -138,8 +119,8 @@ like so `[{word: 'something', score: 12},...]`. It also used `?keyword` for the
|
|
|
138
119
|
labelText:'My Combo',
|
|
139
120
|
apiUrl: '/api/location-lookup',
|
|
140
121
|
apiQueryKey: 'keyword',
|
|
141
|
-
|
|
142
|
-
|
|
122
|
+
apiOptionLabelPath: 'word',
|
|
123
|
+
apiOptionValuePath: 'score'
|
|
143
124
|
}) \%}
|
|
144
125
|
{\% endcall \%}
|
|
145
126
|
|
|
@@ -152,12 +133,13 @@ like so `[{word: 'something', score: 12},...]`. It also used `?keyword` for the
|
|
|
152
133
|
id:'my-id',
|
|
153
134
|
name: 'my-combo',
|
|
154
135
|
labelText:'My Combo',
|
|
155
|
-
value: {word: 'my-label-2', score: 'value-2'},
|
|
156
136
|
apiUrl: '/api/location-lookup',
|
|
157
137
|
apiQueryKey: 'keyword',
|
|
158
|
-
|
|
159
|
-
|
|
138
|
+
apiOptionLabelPath: 'word',
|
|
139
|
+
apiOptionValuePath: 'score'
|
|
160
140
|
}) \%}
|
|
141
|
+
{# we can render selected options on the server even when using API #}
|
|
142
|
+
<option value="value-2" selected>My label 2</option>
|
|
161
143
|
{\% endcall \%}
|
|
162
144
|
|
|
163
145
|
```
|
|
@@ -183,18 +165,18 @@ options:
|
|
|
183
165
|
|
|
184
166
|
#### with prefilled value
|
|
185
167
|
|
|
186
|
-
Note the value is an array for multiple mode.
|
|
187
|
-
|
|
188
168
|
```njk
|
|
189
169
|
{\% call MdsCombobox({
|
|
190
170
|
id:'my-id',
|
|
191
171
|
name: 'my-combo',
|
|
192
172
|
labelText:'My Combo',
|
|
193
|
-
value: [{label: 'my-label-1', value: 'value-1'},{label: 'my-label-2', value: 'value-2'} ],
|
|
194
173
|
apiUrl: '/api/location-lookup',
|
|
195
174
|
apiOptionsPath: 'data',
|
|
196
175
|
multiple: true
|
|
197
176
|
}) \%}
|
|
177
|
+
{# we can render selected options on the server even when using API #}
|
|
178
|
+
<option value="value-1" selected>My label 1</option>
|
|
179
|
+
<option value="value-2" selected>My label 2</option>
|
|
198
180
|
{\% endcall \%}
|
|
199
181
|
|
|
200
182
|
```
|
|
@@ -208,3 +190,14 @@ When Javascript is not available, either a native combobox or native input will
|
|
|
208
190
|
aria-describedBy has been added to notify screen reader users how to interact with the autocomplete suggestions.
|
|
209
191
|
|
|
210
192
|
Note: There is a known issue with the `aria-activedescendant` attribute when using VoiceOver + Safari (it works on other browsers). VO doesn't read the current option. See https://bugs.webkit.org/show_bug.cgi?id=231724
|
|
193
|
+
|
|
194
|
+
## Vue only usage - `<mds-combobox/>`
|
|
195
|
+
|
|
196
|
+
### Props
|
|
197
|
+
|
|
198
|
+
- `value` : `{Array|Object}`, the selected option(s)
|
|
199
|
+
- `options`: Alterative to child Web Component's `<option/>` elements
|
|
200
|
+
|
|
201
|
+
### Events
|
|
202
|
+
|
|
203
|
+
- `update:value` & `change` : on value change
|
|
@@ -41,18 +41,16 @@
|
|
|
41
41
|
<mds-combobox
|
|
42
42
|
combobox-id="{{ comboboxId }}"
|
|
43
43
|
name="{{ comboboxName }}"
|
|
44
|
-
placeholder="{{ params.placeholder }}"
|
|
44
|
+
{% if params.placeholder %}placeholder="{{ params.placeholder }}"{% endif %}
|
|
45
45
|
iconpath="{{ defaultIconPath }}"
|
|
46
|
-
{% if params.options and params.options.length %}options="{{params.options | dump }}"{% endif %}
|
|
47
46
|
{% if params.apiUrl %}api-url="{{params.apiUrl}}"{% endif%}
|
|
48
47
|
{% if params.apiQueryKey %}api-query-key="{{params.apiQueryKey}}"{% endif%}
|
|
49
48
|
{% if params.apiOptionsPath %}api-options-path="{{params.apiOptionsPath}}"{% endif%}
|
|
50
|
-
{% if params.
|
|
51
|
-
{% if params.
|
|
49
|
+
{% if params.apiOptionLabelPath %}api-option-label-path="{{params.apiOptionLabelPath}}"{% endif%}
|
|
50
|
+
{% if params.apiOptionValuePath %}api-option-value-path="{{params.apiOptionValuePath}}"{% endif%}
|
|
52
51
|
i18n="{{ params.i18n | dump }}"
|
|
53
52
|
data-aria-invalid="{{ params.validationError }}"
|
|
54
53
|
{% if params.minSearchCharacters %}min-search-characters="{{ params.minSearchCharacters }}"{% endif %}
|
|
55
|
-
{% if params.value %}value="{{ params.value | dump }}"{% endif %}
|
|
56
54
|
{% if params.searchText %}search-text="{{ params.searchText }}"{% endif %}
|
|
57
55
|
{% if params.multiple %}multiple{% endif %}
|
|
58
56
|
{% if ariaDescribedBy %} describedby-id="{{ariaDescribedBy}}"{% endif -%}
|
|
@@ -60,13 +58,7 @@
|
|
|
60
58
|
>
|
|
61
59
|
{# all 'default slot' fallback content is removed from DOM when vue component loads #}
|
|
62
60
|
<div class="mds-form-element__fallback">
|
|
63
|
-
|
|
64
|
-
{% set _optionValuePath = params.optionValuePath or "value" %}
|
|
65
|
-
{% set _optionLabelPath = params.optionLabelPath or "label" %}
|
|
66
|
-
{# if no provided options, at least try to render select input with value's options #}
|
|
67
|
-
{% set _options = params.options or (params.multiple and params.value) %}
|
|
68
|
-
|
|
69
|
-
{% if params.fallbackTo === 'select' and _options %}
|
|
61
|
+
{% if params.fallbackTo === 'select' %}
|
|
70
62
|
<select
|
|
71
63
|
class="mds-form-control"
|
|
72
64
|
id="{{ comboboxId }}"
|
|
@@ -74,23 +66,11 @@
|
|
|
74
66
|
{% if params.multiple %}multiple{% endif %}
|
|
75
67
|
{% if ariaDescribedBy %}aria-describedby="{{ariaDescribedBy}}"{% endif %}
|
|
76
68
|
>
|
|
77
|
-
<option>{{ placeholder }}</option>
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
{% if not params.multiple and params.value %}
|
|
83
|
-
{# not multiple mode, see if value #}
|
|
84
|
-
{% if params.value[_optionValuePath] === option[_optionValuePath] %}selected{% endif %}
|
|
85
|
-
{% elseif params.value %}
|
|
86
|
-
{# multiple mode, so we assume params.value is an array #}
|
|
87
|
-
{% for valOpt in params.value %}
|
|
88
|
-
{%if valOpt[_optionValuePath] === option[_optionValuePath] %} selected {% endif %}
|
|
89
|
-
{% endfor %}
|
|
90
|
-
{% endif %}
|
|
91
|
-
>{{ option[_optionLabelPath] }}</option>
|
|
92
|
-
{%- endfor -%}
|
|
93
|
-
{%- endif -%}
|
|
69
|
+
{% if params.placeholder %}<option>{{ params.placeholder }}</option>{% endif %}
|
|
70
|
+
{# caller should be a list of `<option>`s, we can reuse this for the select fallback #}
|
|
71
|
+
{% if caller %}
|
|
72
|
+
{{- caller() -}}
|
|
73
|
+
{% endif %}
|
|
94
74
|
</select>
|
|
95
75
|
{# we cant have multiple mode and use input #}
|
|
96
76
|
{% elseif params.fallbackTo === 'input' %}
|
|
@@ -100,8 +80,8 @@
|
|
|
100
80
|
name="{{ comboboxName }}_fallback"
|
|
101
81
|
autocomplete="off"
|
|
102
82
|
id="{{ comboboxId }}"
|
|
103
|
-
{% if params.
|
|
104
|
-
placeholder="{{ placeholder }}"
|
|
83
|
+
{% if params.fallbackValue %} value="{{params.fallbackValue}}"{% endif %}
|
|
84
|
+
{% if params.placeholder %}placeholder="{{ params.placeholder }}"{% endif %}
|
|
105
85
|
{% if params.validationError %}aria-invalid="true"{% endif %}
|
|
106
86
|
{% if ariaDescribedBy %}aria-describedby="{{ariaDescribedBy}}"{% endif %}
|
|
107
87
|
/>
|
|
@@ -18,7 +18,7 @@ module.exports = {
|
|
|
18
18
|
id: 'distance-selection',
|
|
19
19
|
optional: 'true',
|
|
20
20
|
labelText: 'How far are you willing to travel?',
|
|
21
|
-
|
|
21
|
+
content: optionsDistance.map((item) => `<option value="${item.value}">${item.label}</option>`).join(''),
|
|
22
22
|
fallbackTo: 'select',
|
|
23
23
|
classes: 'im-a-custom-class',
|
|
24
24
|
},
|
|
@@ -31,7 +31,7 @@ module.exports = {
|
|
|
31
31
|
id: 'salary-selection',
|
|
32
32
|
optional: 'true',
|
|
33
33
|
labelText: 'Salary expectations?',
|
|
34
|
-
|
|
34
|
+
content: optionsSalary.map((item) => `<option value="${item.value}">${item.label}</option>`).join(''),
|
|
35
35
|
searchText: 'Up to',
|
|
36
36
|
fallbackTo: 'select',
|
|
37
37
|
},
|
|
@@ -50,8 +50,8 @@ module.exports = {
|
|
|
50
50
|
apiUrl: 'https://api.datamuse.com/sug',
|
|
51
51
|
apiQueryKey: 's',
|
|
52
52
|
apiOptionsPath: undefined,
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
apiOptionLabelPath: 'word',
|
|
54
|
+
apiOptionValuePath: 'score',
|
|
55
55
|
i18n: {
|
|
56
56
|
requiredIcon: 'Required (test i18n)',
|
|
57
57
|
loadingText: 'Loading (test i18n)',
|
|
@@ -64,40 +64,41 @@ module.exports = {
|
|
|
64
64
|
},
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
|
-
name: 'AJAX autocomplete
|
|
67
|
+
name: 'AJAX autocomplete pre-selected',
|
|
68
68
|
context: {
|
|
69
69
|
useAutocomplete: true,
|
|
70
|
-
variantTitle: 'AJAX autocomplete
|
|
70
|
+
variantTitle: 'AJAX autocomplete pre-selected',
|
|
71
71
|
name: 'keywords-prefilled',
|
|
72
72
|
id: 'keywords-lookup-prefilled',
|
|
73
73
|
labelText: 'Keywords:',
|
|
74
74
|
placeholder: 'eg. Testimonials',
|
|
75
|
-
|
|
75
|
+
content: `<option value="the-value" selected>Initial Value</option>`,
|
|
76
76
|
fallbackTo: 'input',
|
|
77
77
|
minSearchCharacters: 3,
|
|
78
78
|
apiUrl: 'https://api.datamuse.com/sug',
|
|
79
79
|
apiQueryKey: 's',
|
|
80
80
|
apiOptionsPath: undefined,
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
apiOptionLabelPath: 'word',
|
|
82
|
+
apiOptionValuePath: 'score',
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
|
-
name: 'AJAX autocomplete
|
|
86
|
+
name: 'AJAX autocomplete pre-selected with validation error',
|
|
87
87
|
context: {
|
|
88
88
|
useAutocomplete: true,
|
|
89
|
-
variantTitle: 'AJAX autocomplete
|
|
89
|
+
variantTitle: 'AJAX autocomplete pre-selected with validation error',
|
|
90
90
|
name: 'keywordsprefilled-error',
|
|
91
91
|
id: 'keywords-lookup-prefilled-validation-error',
|
|
92
92
|
labelText: 'Keywords:',
|
|
93
93
|
placeholder: 'eg. Testimonials',
|
|
94
|
-
|
|
94
|
+
content: `<option value="the-value" selected>Initial Value</option>`,
|
|
95
95
|
fallbackTo: 'input',
|
|
96
96
|
validationError: 'There was an error',
|
|
97
|
+
apiUrl: 'https://api.datamuse.com/sug',
|
|
97
98
|
apiQueryKey: 's',
|
|
98
99
|
apiOptionsPath: undefined,
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
apiOptionLabelPath: 'word',
|
|
101
|
+
apiOptionValuePath: 'score',
|
|
101
102
|
},
|
|
102
103
|
},
|
|
103
104
|
{
|
|
@@ -114,8 +115,8 @@ module.exports = {
|
|
|
114
115
|
apiUrl: 'https://api.datamuse.com/sug',
|
|
115
116
|
apiQueryKey: 's',
|
|
116
117
|
apiOptionsPath: undefined,
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
apiOptionLabelPath: 'word',
|
|
119
|
+
apiOptionValuePath: 'score',
|
|
119
120
|
multiple: true,
|
|
120
121
|
i18n: {
|
|
121
122
|
requiredIcon: 'Required (test i18n)',
|
|
@@ -137,17 +138,17 @@ module.exports = {
|
|
|
137
138
|
id: 'keywords-lookup-multiselect-prefilled',
|
|
138
139
|
labelText: 'Keywords:',
|
|
139
140
|
placeholder: 'eg. Web developer',
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
content: `
|
|
142
|
+
<option value="the-value-1" selected>Initial Value 1</option>
|
|
143
|
+
<option value="the-value-2" selected>Initial Value 2</option>
|
|
144
|
+
`,
|
|
144
145
|
fallbackTo: 'select',
|
|
145
146
|
minSearchCharacters: 3,
|
|
146
147
|
apiUrl: 'https://api.datamuse.com/sug',
|
|
147
148
|
apiQueryKey: 's',
|
|
148
149
|
apiOptionsPath: undefined,
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
apiOptionLabelPath: 'word',
|
|
151
|
+
apiOptionValuePath: 'score',
|
|
151
152
|
multiple: true,
|
|
152
153
|
i18n: {
|
|
153
154
|
requiredIcon: 'Required (test i18n)',
|