mp-design-system 1.0.3 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. package/dist/build/arc.abe174a6.svg +1 -0
  2. package/dist/build/concentric.465e6b4d.svg +1 -0
  3. package/dist/build/crystal.8300dbe3.svg +1 -0
  4. package/dist/build/{dots-pattern.1b95f054.svg → dots-pattern.1bae0e23.svg} +1 -1
  5. package/dist/build/js/app.js +1 -1
  6. package/dist/build/js/app.js.map +1 -1
  7. package/dist/build/scss/library.css +1 -1
  8. package/dist/build/scss/library.css.map +1 -1
  9. package/dist/build/scss/main.css +1 -1
  10. package/dist/build/scss/main.css.map +1 -1
  11. package/package.json +1 -1
  12. package/src/_data/config.js +1 -1
  13. package/src/_headers +9 -0
  14. package/src/_includes/components/card/card.config.js +10 -6
  15. package/src/_includes/components/component/preview-cards-three-alt.njk +1 -1
  16. package/src/_includes/components/component/preview-cards-three.njk +1 -1
  17. package/src/_includes/components/component/preview-cards-two.njk +1 -1
  18. package/src/_includes/components/component/preview-content-width.njk +1 -1
  19. package/src/_includes/components/component/preview-default.njk +1 -1
  20. package/src/_includes/components/component/preview-form.njk +1 -1
  21. package/src/_includes/components/dynamic-form/dynamic-form.config.js +16 -0
  22. package/src/_includes/components/dynamic-form/dynamic-form.njk +319 -0
  23. package/src/_includes/components/dynamic-form/dynamic-form.scss +77 -0
  24. package/src/_includes/components/dynamic-form/macro.njk +5 -0
  25. package/src/_includes/components/header/header.config.js +30 -0
  26. package/src/_includes/components/header/header.njk +15 -0
  27. package/src/_includes/components/input/combobox.njk +17 -0
  28. package/src/_includes/components/input/combobox.scss +31 -0
  29. package/src/_includes/components/input/combox.config.js +49 -0
  30. package/src/_includes/components/input/input.scss +5 -1
  31. package/src/_includes/components/input/macro.njk +14 -10
  32. package/src/_includes/components/input/radio.scss +9 -0
  33. package/src/_includes/components/off-canvas/macro.njk +5 -0
  34. package/src/_includes/components/off-canvas/off-canvas.config.js +28 -0
  35. package/src/_includes/components/off-canvas/off-canvas.njk +28 -0
  36. package/src/{assets/scss/objects → _includes/components/off-canvas}/off-canvas.scss +15 -5
  37. package/src/_includes/includes/color-swatches.njk +220 -0
  38. package/src/_includes/includes/system-footer.njk +1 -1
  39. package/src/_includes/library-navigation/brand-nav.njk +3 -2
  40. package/src/_includes/navigation/store.njk +29 -0
  41. package/src/_includes/system.njk +1 -1
  42. package/src/assets/js/app.js +2 -0
  43. package/src/assets/js/imports/combobox.js +66 -0
  44. package/src/assets/js/imports/off-canvas.js +197 -70
  45. package/src/assets/scss/components/index.scss +1 -0
  46. package/src/assets/scss/library.scss +4 -2
  47. package/src/assets/scss/objects/index.scss +0 -1
  48. package/src/assets/svg/arc.svg +1 -1
  49. package/src/assets/svg/concentric.svg +1 -1
  50. package/src/assets/svg/crystal.svg +1 -1
  51. package/src/assets/svg/dots-pattern.svg +1 -1
  52. package/src/brand/colors.njk +2 -216
  53. package/src/brand/index.njk +7 -6
  54. package/src/brand/requirements.md +98 -0
  55. package/src/brand/{downloads.njk → resources.njk} +15 -1
  56. package/src/index.njk +13 -10
  57. package/src/quickstart.md +41 -0
  58. package/dist/build/arc.a8e07ecd.svg +0 -1
  59. package/dist/build/concentric.05eaed9c.svg +0 -1
  60. package/dist/build/crystal.a90c9e1f.svg +0 -1
  61. package/src/brand/basics.md +0 -36
  62. package/src/checklist.md +0 -71
  63. package/src/patterns/off-canvas.njk +0 -42
@@ -0,0 +1,17 @@
1
+ {# <div class="c-combobox">
2
+ <input type="text" class="c-combobox__input" id="combobox-input" aria-haspopup="listbox" aria-expanded="false" aria-labelledby="combobox-label" autocomplete="off" placeholder="Select an option" role="combobox" aria-owns="combobox-options">
3
+ <ul class="c-combobox__dropdown" id="combobox-options" role="listbox" aria-labelledby="combobox-input">
4
+ <li data-value="option1" role="option">Option 1</li>
5
+ <li data-value="option2" role="option">Option 2</li>
6
+ <li data-value="option3" role="option">Option 3</li>
7
+ </ul>
8
+ <div> #}
9
+
10
+ <div class="c-combobox">
11
+ <input type="text" id="combobox-input" class="c-combobox__input" placeholder="Type to search..." autocomplete="off" aria-controls="combobox-list" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-owns="combobox-select">
12
+ <ul id="combobox-select" class="c-combobox__select" role="listbox" aria-label="Options" tabindex="-1">
13
+ <li role="option" aria-selected="false">Option 1</li>
14
+ <li role="option" aria-selected="false">Option 2</li>
15
+ <li role="option" aria-selected="false">Option 3</li>
16
+ </ul>
17
+ </div>
@@ -0,0 +1,31 @@
1
+ .c-combobox {
2
+ position: relative;
3
+ display: inline-block;
4
+
5
+ &__input {
6
+ width: 200px;
7
+ padding: 5px;
8
+ }
9
+
10
+ &__select {
11
+ position: absolute;
12
+ z-index: 1;
13
+ list-style-type: none;
14
+ padding: 0;
15
+ margin: 0;
16
+ background-color: #f9f9f9;
17
+ border: 1px solid #ccc;
18
+ border-top: none;
19
+ display: none;
20
+
21
+ li {
22
+ padding: 10px;
23
+ cursor: pointer;
24
+
25
+ &[aria-selected="true"] {
26
+ background-color: #e6e6e6;
27
+ }
28
+ }
29
+ }
30
+
31
+ }
@@ -0,0 +1,49 @@
1
+ const categories = require('../component/categories');
2
+
3
+ module.exports = {
4
+ title: 'Combobox',
5
+ category: categories.form,
6
+ component: {
7
+ name: 'combobox',
8
+ folder: 'input'
9
+ },
10
+ figma: 'https://www.figma.com/file/rUQ6aPQAfBX55o3hH0Lqb3/Design-exploration?node-id=213%3A918',
11
+ preview: 'form',
12
+ context: {
13
+ label: 'Label',
14
+ name: 'name',
15
+ id: 'id',
16
+ type: 'text',
17
+ placeholder: 'Placeholder',
18
+ required: true
19
+ },
20
+ variants: [
21
+ {
22
+ title: 'With error',
23
+ context: {
24
+ error: true
25
+ }
26
+ },
27
+ {
28
+ title: 'With error message',
29
+ context: {
30
+ error: 'This field is required'
31
+ }
32
+ },
33
+ {
34
+ title: 'Disabled',
35
+ context: {
36
+ disabled: true
37
+ }
38
+ }
39
+ ],
40
+ props: [
41
+ {
42
+ table: [
43
+ ['label', 'string'],
44
+ ['id', 'string', 'ID attribute'],
45
+ ['name', 'string', 'Name attribute (falls back to ID)'],
46
+ ]
47
+ }
48
+ ]
49
+ }
@@ -86,7 +86,7 @@
86
86
 
87
87
  &[disabled],
88
88
  [disabled],
89
- .u-disabled & {
89
+ &--disabled {
90
90
  background-color: color('petrol', 'step-2');
91
91
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" id="lock" viewBox="0 0 25 24" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.45 4.17A4 4 0 0 1 16.28 7v3h-8V7a4 4 0 0 1 1.17-2.83ZM6.28 10V7a6 6 0 1 1 12 0v3h.22c1.64 0 2.78 1.46 2.78 3v7c0 1.54-1.14 3-2.78 3H6.06c-1.65 0-2.78-1.46-2.78-3v-7c0-1.54 1.13-3 2.78-3h.22Zm1 2H6.06c-.33 0-.78.33-.78 1v7c0 .67.45 1 .78 1H18.5c.32 0 .78-.33.78-1v-7c0-.67-.46-1-.78-1H7.28Zm3 3.35a2 2 0 1 1 3 1.73v1.77a1 1 0 1 1-2 0v-1.77a2 2 0 0 1-1-1.73Z"/></svg>');
92
92
  background-position: right var(--space-2xs) center;
@@ -97,6 +97,10 @@
97
97
  }
98
98
  }
99
99
 
100
+ .u-disabled > .c-input {
101
+ @extend .c-input--disabled;
102
+ }
103
+
100
104
  .c-input--with-button {
101
105
  // padding-right: 44px;
102
106
  border: 0;
@@ -1,25 +1,29 @@
1
1
  {% from "components/component/component.njk" import c %}
2
2
 
3
- {% macro input(params) %}
4
- {{ c({ name: 'input' }, params) }}
5
- {% endmacro %}
6
-
7
- {% macro select(params) %}
8
- {{ c({ name: 'select', folder: 'input' }, params) }}
9
- {% endmacro %}
10
-
11
- {% macro textarea(params) %}
12
- {{ c({ name: 'textarea', folder: 'input' }, params) }}
3
+ {% macro combobox(params, type = 'combobox') %}
4
+ {{ c({ name: 'combobox', folder: 'input' }, params) }}
13
5
  {% endmacro %}
14
6
 
15
7
  {% macro checkbox(params, type = 'checkbox') %}
16
8
  {{ c({ name: 'checkbox', folder: 'input' }, params) }}
17
9
  {% endmacro %}
18
10
 
11
+ {% macro input(params) %}
12
+ {{ c({ name: 'input' }, params) }}
13
+ {% endmacro %}
14
+
19
15
  {% macro radio(params) %}
20
16
  {{ c({ name: 'radio', folder: 'input' }, params) }}
21
17
  {% endmacro %}
22
18
 
19
+ {% macro select(params) %}
20
+ {{ c({ name: 'select', folder: 'input' }, params) }}
21
+ {% endmacro %}
22
+
23
23
  {% macro toggle(params, type='toggle') %}
24
24
  {{ c({ name: 'toggle', folder: 'input' }, params) }}
25
25
  {% endmacro %}
26
+
27
+ {% macro textarea(params) %}
28
+ {{ c({ name: 'textarea', folder: 'input' }, params) }}
29
+ {% endmacro %}
@@ -91,3 +91,12 @@
91
91
  box-shadow: inset 0 0 0 5px color('utility-blue', 'step--1');
92
92
  }
93
93
  }
94
+
95
+ .c-off-canvas {
96
+ .c-checkbox-group {
97
+ &> * {
98
+ width: 100%;
99
+ margin-left: 0;
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,5 @@
1
+ {% from "components/component/component.njk" import c %}
2
+
3
+ {% macro off-canvas(params) %}
4
+ {{ c({ name: 'off-canvas' }, params) }}
5
+ {% endmacro %}
@@ -0,0 +1,28 @@
1
+ module.exports = {
2
+ title: 'Off-canvas',
3
+ component: {
4
+ name: 'off-canvas',
5
+ },
6
+ context: {
7
+ target: {
8
+ id: 'areasOfInterest',
9
+ button: {
10
+ text: 'Update'
11
+ }
12
+ },
13
+ header: 'Areas of interest',
14
+ toggle: {
15
+ text: 'Add areas of interest'
16
+ },
17
+ },
18
+ variants: [
19
+ {
20
+ title: 'Mobile only',
21
+ context: {
22
+ classes: 'c-off-canvas--mobile'
23
+ }
24
+ }
25
+ ],
26
+ props: [
27
+ ]
28
+ }
@@ -0,0 +1,28 @@
1
+ {% from "components/input/macro.njk" import checkbox %}
2
+
3
+ {%- set classNames = "mp c-button c-off-canvas__toggle" -%}
4
+
5
+ {%- if params.classes -%}
6
+ {% set classNames = classNames + " " + params.classes %}
7
+ {% endif %}
8
+
9
+ <div>
10
+ <div id="{{ params.target.id }}" class="u-flow--m">
11
+ <label class="c-label" data-off-canvas="header">{{ params.header }}</label>
12
+ <div class="o-grid o-grid--of-three c-checkbox-group" data-off-canvas="main">
13
+ {% for _ in ["3D structure / imaging", "Binding affinity", "Binding kinetics", "Chemical identification", "Contaminant detection and analysis", "Crystal structure determination", "Elemental analysis", "Elemental quantification", "Enzyme kinetics", "Epitaxy analysis", "Ground truthing", "Interface roughness", "Label-free analysis", "Microrheology", "Moisture content", "Molecular size", "Molecular structure", "Molecular weight", "Particle concentration", "Particle shape", "Particle size", "Phase identification", "Phase quantification", "Pore size distribution", "Powder flow", "Protein aggregation", "Protein mobility", "Protein stability", "Reciprocal space analysis", "Remote sensing", "Residual stress", "Texture analysis", "Thin film metrology", "Viscosity", "Zeta potential"] %}
14
+ <div>
15
+ {{ checkbox({
16
+ label: _,
17
+ name: params.target.id,
18
+ id: _,
19
+ value: _
20
+ })}}
21
+ </div>
22
+ {% endfor %}
23
+ </div>
24
+ <button class="mp c-button o-off-canvas__update" data-off-canvas="footer" data-off-canvas-close="true">{{ params.target.button.text }}</button>
25
+ </div>
26
+
27
+ <button class="{{ classNames }}" data-target="{{ params.target.id }}" aria-controls="{{ params.target.id }}" aria-expanded="false" aria-label="Toggle {{ params.header }}" onclick="return false">{{ params.toggle.text }}</button>
28
+ </div>
@@ -1,4 +1,4 @@
1
- .o-off-canvas {
1
+ .c-off-canvas {
2
2
  position: fixed;
3
3
  top: 0;
4
4
  left: 0;
@@ -10,6 +10,10 @@
10
10
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
11
11
  z-index: 9999;
12
12
 
13
+ &> * + * {
14
+ margin: 0 !important;
15
+ }
16
+
13
17
  &__backdrop {
14
18
  position: fixed;
15
19
  top: 0;
@@ -50,7 +54,7 @@
50
54
 
51
55
  &__main {
52
56
  @include margin-bottom('m');
53
- @include padding(0, 's');
57
+ @include padding('3xs', 's');
54
58
  overflow-y: scroll;
55
59
  }
56
60
 
@@ -68,18 +72,24 @@
68
72
  @include padding('s');
69
73
  }
70
74
 
71
- &--open {
75
+ &--active {
72
76
  opacity: 1;
73
77
  visibility: visible;
74
78
  transition: opacity 0.3s ease;
75
79
 
76
- .o-off-canvas__backdrop {
80
+ .c-off-canvas__backdrop {
77
81
  opacity: 1;
78
82
  visibility: visible;
79
83
  }
80
84
 
81
- .o-off-canvas__content {
85
+ .c-off-canvas__content {
82
86
  right: 0;
83
87
  }
84
88
  }
89
+ }
90
+
91
+ @media only screen and (min-width: 40em) {
92
+ .c-off-canvas--mobile {
93
+ display: none !important;
94
+ }
85
95
  }
@@ -0,0 +1,220 @@
1
+ {% set colors = [
2
+ {
3
+ name: 'MP Petrol',
4
+ key: 'Petrol',
5
+ steps: [
6
+ {
7
+ name: "-1",
8
+ hex: '003039',
9
+ cmyk: '93.65.57.57',
10
+ pantone: 'PAN 547'
11
+ },
12
+ {
13
+ name: 0,
14
+ hex: '005461',
15
+ cmyk: '93.54.49.27',
16
+ pantone: 'PAN 3165'
17
+ },
18
+ {
19
+ name: 1,
20
+ hex: '3d7b87',
21
+ cmyk: '78.39.40.08'
22
+ },
23
+ {
24
+ name: 2,
25
+ hex: 'bfd3d6',
26
+ cmyk: '24.09.13.00'
27
+ },
28
+ {
29
+ name: 3,
30
+ hex: 'ebf1f2',
31
+ cmyk: '06.02.03.00'
32
+ }
33
+ ]
34
+ },
35
+ {
36
+ name: 'MP Blue',
37
+ key: 'Blue',
38
+ steps: [
39
+ {
40
+ name: "-1",
41
+ hex: '00758c',
42
+ cmyk: '89.42.35.07'
43
+ },
44
+ {
45
+ name: 0,
46
+ hex: '00a2c2',
47
+ cmyk: '77.17.17.00',
48
+ pantone: 'PAN 312'
49
+ },
50
+ {
51
+ name: 1,
52
+ hex: '47bcd3',
53
+ cmyk: '64.04.15.00'
54
+ },
55
+ {
56
+ name: 2,
57
+ hex: 'c2e9f0',
58
+ cmyk: '22.00.05.00'
59
+ },
60
+ {
61
+ name: 3,
62
+ hex: 'ebf8fa',
63
+ cmyk: '06.00.01.00'
64
+ }
65
+ ]
66
+ },
67
+ {
68
+ name: 'MP Green',
69
+ key: 'Green',
70
+ steps: [
71
+ {
72
+ name: "-1",
73
+ hex: '0e7a0e',
74
+ cmyk: '87.27.100.16'
75
+ },
76
+ {
77
+ name: 0,
78
+ hex: '13aa13',
79
+ cmyk: '81.04.100.01',
80
+ pantone: 'PAN 354'
81
+ },
82
+ {
83
+ name: 1,
84
+ hex: '55c255',
85
+ cmyk: '66.00.89.00'
86
+ },
87
+ {
88
+ name: 2,
89
+ hex: 'c6ebc6',
90
+ cmyk: '22.00.28.00'
91
+ },
92
+ {
93
+ name: 3,
94
+ hex: 'ecf8ec',
95
+ cmyk: '06.00.08.00'
96
+ }
97
+ ]
98
+ },
99
+ {
100
+ name: 'MP Rubine',
101
+ key: 'Red',
102
+ steps: [
103
+ {
104
+ name: 0,
105
+ hex: 'ce0058',
106
+ cmyk: '14.100.50.2',
107
+ pantone: 'PAN Rubine Red'
108
+ }
109
+ ]
110
+ },
111
+ {
112
+ name: 'MP Charcoal',
113
+ key: 'Grey',
114
+ steps: [
115
+
116
+ {
117
+ name: "-1",
118
+ hex: '1c1c1c',
119
+ cmyk: '00.00.00.95'
120
+ },
121
+ {
122
+ name: 0,
123
+ hex: '333333',
124
+ cmyk: '00.00.00.91',
125
+ pantone: 'PAN 447'
126
+ },
127
+ {
128
+ name: 1,
129
+ hex: '959595',
130
+ cmyk: '00.00.00.70'
131
+ },
132
+ {
133
+ name: 2,
134
+ hex: 'cecece',
135
+ cmyk: '00.00.00.22'
136
+ },
137
+ {
138
+ name: 3,
139
+ hex: 'efefef',
140
+ cmyk: '00.00.00.08'
141
+ }
142
+ ]
143
+ },
144
+ {
145
+ name: 'MP Utility Gold',
146
+ key: 'Utility-Orange',
147
+ steps: [
148
+
149
+ {
150
+ name: "-1",
151
+ hex: 'AE7809',
152
+ cmyk: '29.51.100.10'
153
+ },
154
+ {
155
+ name: 0,
156
+ hex: 'F2A60D',
157
+ cmyk: '04.38.100.00'
158
+ },
159
+ {
160
+ name: 1,
161
+ hex: 'F6BF51',
162
+ cmyk: '03.26.79.00'
163
+ },
164
+ {
165
+ name: 2,
166
+ hex: 'FCEAC5',
167
+ cmyk: '01.07.25.00'
168
+ },
169
+ {
170
+ name: 3,
171
+ hex: 'FEF8EC',
172
+ cmyk: '00.02.06.00'
173
+ }
174
+ ]
175
+ },
176
+ {
177
+ name: 'MP Utility Blue',
178
+ key: 'Utility-Blue',
179
+ steps: [
180
+ {
181
+ name: 0,
182
+ hex: '006daf',
183
+ cmyk: '86.48.3.5'
184
+ }
185
+ ]
186
+ }
187
+ ] %}
188
+
189
+ {% macro swatches(params) %}
190
+ <div class="u-flow--2xs">
191
+ {% for color in colors %}
192
+ <h3 class="c-h c-h--step-1">{{ color.name }}</h3>
193
+ <div class="c-library__swatch-grid c-library__swatch-grid--has-labels ">
194
+ {% for step in color.steps %}
195
+ {% set classname %}
196
+ {{- 'c-library__swatch'}}{# Let's build a string #}
197
+ {{ 'u-bg-'+color.key | slug}}{# Set the background color to color.key -#}
198
+ {{ '-step-'+step.name if step.name!=0 }} {# If it's not step zero, add the -step-x suffix -#}
199
+ {# Set the text color to white, or a dark color #}
200
+ {{ 'u-'+color.key|slug+'-step--1' if (step.name==2) or (step.name==3) else 'u-white' -}}
201
+ {% endset %}
202
+ <div class="{{classname}}">
203
+ <span>Step {{step.name}}</span>
204
+ </div>
205
+ <table class="c-table">
206
+ <tbody>
207
+ <tr><td>Hex</td><td>#{{step.hex | upper}}</td></tr>
208
+ {% if params.print %}
209
+ <tr><td>CMYK</td><td>{{step.cmyk}}</td></tr>
210
+ <tr class="{{ "u-petrol-step-3" if not step.pantone }}">
211
+ <td>Pantone</td><td>{{step.pantone if step.pantone}}</td>
212
+ </tr>
213
+ {% endif %}
214
+ </tbody>
215
+ </table>
216
+ {% endfor %}
217
+ </div>
218
+ {% endfor%}
219
+ </div>
220
+ {% endmacro %}
@@ -5,7 +5,7 @@
5
5
  <div class="o-grid o-grid--8/3-switch o-grid--push">
6
6
  <ol class="u-flow--xs u-margin-top-2xs">
7
7
  <li><h3>Quick links</h3></li>
8
- <li><a href="/brand/downloads">Popular downloads</a></li>
8
+ <li><a href="/brand/resources">Brand resources</a></li>
9
9
  <li><a href="/checklist">Franklin checklist</a></li>
10
10
  </ol>
11
11
  <div class="mp o-prose u-flow--prose u-step--1">
@@ -5,8 +5,9 @@
5
5
  <h3>Brand & visual identity</h3>
6
6
  <ul>
7
7
  {{ libraryList('Overview', '/brand/', page.url) }}
8
- {{ libraryList('The basics', '/brand/basics/', page.url) }}
9
- {{ libraryList('Downloads', '/brand/downloads/', page.url) }}
8
+ {{ libraryList('Quick start', '/quickstart/', page.url) }}
9
+ {{ libraryList('Requirements', '/brand/requirements/', page.url) }}
10
+ {{ libraryList('Resources', '/brand/resources/', page.url) }}
10
11
  {{ libraryList('Logo', '/brand/logo/', page.url) }}
11
12
  {{ libraryList('Colors', '/brand/colors/', page.url) }}
12
13
  {{ libraryList('Typography', '/brand/typography/', page.url) }}
@@ -0,0 +1,29 @@
1
+ <nav class="c-header__site c-header__site--with-home" aria-label="Site">
2
+ <ul>
3
+ <li>
4
+ <a href="/prototype/products">Store home</a>
5
+ </li>
6
+ <li>
7
+ <a href="/prototype/sections">Consumables</a>
8
+ </li>
9
+ <li>
10
+ <a href="">Standards</a>
11
+ </li>
12
+ <li>
13
+ <a href="/prototype/webinars">Accessories</a>
14
+ </li>
15
+ <li>
16
+ <a href="">Contracts & agreements</a>
17
+ </li>
18
+ <li>
19
+ <a href="">Software</a>
20
+ </li>
21
+ <a class="mp c-button c-button--small c-button--tight c-button--outline-white c-header__push u-margin-right-m" href="">Basket (0)</a>
22
+ <li>
23
+ <a href="">Log in</a>
24
+ </li>
25
+ <li>
26
+ <a href="">Register</a>
27
+ </li>
28
+ </ul>
29
+ </nav>
@@ -17,7 +17,7 @@
17
17
  {% if sidebar %}
18
18
  <div class="c-library__body">
19
19
  <nav class="c-library__sidebar c-library-stretch" id="sidebar">
20
- <div class="u-flow--m">
20
+ <div class="u-flow--m u-sticky">
21
21
  {% block sidebar %}{% endblock %}
22
22
  </div>
23
23
  </nav>
@@ -1,6 +1,7 @@
1
1
  import Accordion from './imports/accordion';
2
2
  import Carousel from './imports/carousel';
3
3
  import ClearForm from './imports/clear-form';
4
+ import Combobox from './imports/combobox';
4
5
  import Comparison from './imports/comparison';
5
6
  import Gallery from './imports/gallery';
6
7
  import HeroPattern from './imports/hero-pattern';
@@ -22,6 +23,7 @@ import Tabs from './imports/tabs';
22
23
  Accordion();
23
24
  Carousel();
24
25
  ClearForm();
26
+ Combobox();
25
27
  Comparison();
26
28
  Gallery();
27
29
  HeroPattern();
@@ -0,0 +1,66 @@
1
+ function Combobox() {
2
+ const comboboxes = Array.from(document.querySelectorAll('.c-combobox'));
3
+
4
+ comboboxes.forEach(function (combobox) {
5
+ const input = combobox.querySelector('.c-combobox__input');
6
+ const select = combobox.querySelector('.c-combobox__select');
7
+ const options = Array.from(select.querySelectorAll('li[role="option"]'));
8
+
9
+ // Set initial state
10
+ input.setAttribute('aria-expanded', 'false');
11
+ input.setAttribute('aria-owns', select.id);
12
+ input.setAttribute('aria-controls', select.id);
13
+
14
+ // Event listeners
15
+ input.addEventListener('focus', function () {
16
+ input.setAttribute('aria-expanded', 'true');
17
+ select.setAttribute('aria-expanded', 'true');
18
+ });
19
+
20
+ input.addEventListener('blur', function () {
21
+ input.setAttribute('aria-expanded', 'false');
22
+ select.setAttribute('aria-expanded', 'false');
23
+ });
24
+
25
+ input.addEventListener('input', function () {
26
+ const inputValue = input.value.toLowerCase();
27
+
28
+ options.forEach(function (option) {
29
+ const optionText = option.textContent.toLowerCase();
30
+
31
+ if (optionText.includes(inputValue)) {
32
+ option.style.display = '';
33
+ option.setAttribute('aria-hidden', 'false');
34
+ } else {
35
+ option.style.display = 'none';
36
+ option.setAttribute('aria-hidden', 'true');
37
+ }
38
+ });
39
+ });
40
+
41
+ select.addEventListener('click', function (event) {
42
+ const target = event.target;
43
+ const isOption = target.getAttribute('role') === 'option';
44
+
45
+ if (isOption) {
46
+ const selectedOption = select.querySelector('[aria-selected="true"]');
47
+ if (selectedOption) {
48
+ selectedOption.setAttribute('aria-selected', 'false');
49
+ }
50
+
51
+ target.setAttribute('aria-selected', 'true');
52
+ input.value = target.textContent;
53
+
54
+ input.focus();
55
+ }
56
+ });
57
+
58
+ // Display options initially
59
+ options.forEach(function (option) {
60
+ option.style.display = '';
61
+ option.setAttribute('aria-hidden', 'false');
62
+ });
63
+ });
64
+ }
65
+
66
+ export default Combobox;