mp-design-system 1.0.4 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) 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.config.js +1 -1
  31. package/src/_includes/components/input/input.njk +0 -2
  32. package/src/_includes/components/input/macro.njk +14 -10
  33. package/src/_includes/components/input/radio.scss +9 -0
  34. package/src/_includes/components/off-canvas/macro.njk +5 -0
  35. package/src/_includes/components/off-canvas/off-canvas.config.js +28 -0
  36. package/src/_includes/components/off-canvas/off-canvas.njk +28 -0
  37. package/src/{assets/scss/objects → _includes/components/off-canvas}/off-canvas.scss +21 -4
  38. package/src/_includes/includes/color-swatches.njk +220 -0
  39. package/src/_includes/includes/system-footer.njk +1 -1
  40. package/src/_includes/library-navigation/brand-nav.njk +3 -2
  41. package/src/_includes/navigation/store.njk +29 -0
  42. package/src/_includes/system.njk +1 -1
  43. package/src/assets/js/app.js +2 -0
  44. package/src/assets/js/imports/combobox.js +66 -0
  45. package/src/assets/js/imports/off-canvas.js +195 -74
  46. package/src/assets/scss/components/index.scss +1 -0
  47. package/src/assets/scss/library.scss +4 -2
  48. package/src/assets/scss/objects/index.scss +0 -1
  49. package/src/assets/svg/arc.svg +1 -1
  50. package/src/assets/svg/concentric.svg +1 -1
  51. package/src/assets/svg/crystal.svg +1 -1
  52. package/src/assets/svg/dots-pattern.svg +1 -1
  53. package/src/brand/colors.njk +2 -216
  54. package/src/brand/index.njk +7 -6
  55. package/src/brand/requirements.md +98 -0
  56. package/src/brand/{downloads.njk → resources.njk} +15 -1
  57. package/src/index.njk +13 -10
  58. package/src/quickstart.md +41 -0
  59. package/dist/build/arc.a8e07ecd.svg +0 -1
  60. package/dist/build/concentric.05eaed9c.svg +0 -1
  61. package/dist/build/crystal.a90c9e1f.svg +0 -1
  62. package/src/brand/basics.md +0 -36
  63. package/src/checklist.md +0 -71
  64. 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
+ }
@@ -39,7 +39,7 @@ module.exports = {
39
39
  {
40
40
  title: 'Disabled',
41
41
  context: {
42
- disabled: false
42
+ disabled: true
43
43
  }
44
44
  }
45
45
  ],
@@ -1,5 +1,4 @@
1
1
  {% inputWrapper params.error %}
2
- <div class="c-form-row u-disabled">
3
2
  <label class="{{ 'u-hidden' if params.hideLabel else 'c-label' }}" for="{{ params.id }}">{{ params.label }}</label>
4
3
  {% if params.button %}
5
4
  <div class="u-flex u-border">
@@ -11,5 +10,4 @@
11
10
  {% if params.button %}
12
11
  </div>
13
12
  {% endif %}
14
- </div>
15
13
  {% endinputWrapper %}
@@ -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 %}
@@ -7,6 +7,8 @@
7
7
  @include padding-left('l');
8
8
  position: relative;
9
9
  @include step(-1);
10
+ box-decoration-break: clone;
11
+ -webkit-box-decoration-break: clone;
10
12
 
11
13
  &:before {
12
14
  transform: translateY(-50%);
@@ -91,3 +93,10 @@
91
93
  box-shadow: inset 0 0 0 5px color('utility-blue', 'step--1');
92
94
  }
93
95
  }
96
+
97
+ .c-off-canvas .c-checkbox-group {
98
+ &> * {
99
+ width: 100%;
100
+ margin-left: 0;
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="c-checkbox-group u-flow--m">
11
+ <label class="c-label" data-off-canvas="header">{{ params.header }}</label>
12
+ <div class="o-grid o-grid--of-three" 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"] %}
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;
@@ -68,18 +72,31 @@
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
+ }
95
+
96
+ .c-checkbox-group {
97
+ [data-off-canvas="header"],
98
+ [data-off-canvas="footer"] {
99
+ display: none;
100
+ }
101
+ }
85
102
  }
@@ -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;