@internetstiftelsen/styleguide 4.0.12 → 4.0.13

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.
@@ -8,6 +8,8 @@ var _className2 = _interopRequireDefault(_className);
8
8
 
9
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
10
 
11
+ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
12
+
11
13
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12
14
 
13
15
  var MultiSelect = function () {
@@ -47,7 +49,9 @@ var MultiSelect = function () {
47
49
 
48
50
  this.onClick = function (e) {
49
51
  if (e.target.classList.contains((0, _className2.default)(_this.baseClassName + '__suggestion-btn'))) {
50
- _this.addItem(e.target.textContent);
52
+ _this.addItem(_this.data.find(function (d) {
53
+ return d.value === e.target.value;
54
+ }));
51
55
  _this.clearSuggestions();
52
56
  _this.input.value = '';
53
57
  }
@@ -56,6 +60,7 @@ var MultiSelect = function () {
56
60
  this.element = el;
57
61
  this.baseClassName = 'm-multi-select';
58
62
  this.currentFocus = -1;
63
+ this.name = this.element.getAttribute('data-multi-select-name');
59
64
  this.input = this.element.querySelector('.js-' + this.baseClassName + '__input');
60
65
  this.suggestionsBox = this.element.querySelector('.js-' + this.baseClassName + '-suggestions-box');
61
66
  this.selectedItemsList = this.element.querySelector('.js-m-multi-select-selected-items');
@@ -101,15 +106,26 @@ var MultiSelect = function () {
101
106
  value: function clearSuggestions() {
102
107
  this.suggestionsBox.innerHTML = '';
103
108
  }
109
+ }, {
110
+ key: 'addSuggestions',
111
+ value: function addSuggestions(suggestions) {
112
+ var _this2 = this;
113
+
114
+ this.data = [].concat(_toConsumableArray(this.data), _toConsumableArray(suggestions.filter(function (s) {
115
+ return !_this2.data.find(function (d) {
116
+ return d.value === s.value;
117
+ });
118
+ })));
119
+ }
104
120
  }, {
105
121
  key: 'filterData',
106
122
  value: function filterData(query) {
107
- var _this2 = this;
123
+ var _this3 = this;
108
124
 
109
125
  return this.data.filter(function (item) {
110
126
  return item.name.toLowerCase().startsWith(query.toLowerCase());
111
127
  }).filter(function (item) {
112
- return !_this2.selectedItems.includes(item.name);
128
+ return !_this3.selectedItems.includes(item.name);
113
129
  });
114
130
  }
115
131
  }, {
@@ -117,16 +133,24 @@ var MultiSelect = function () {
117
133
  value: function populateSuggestions(suggestions) {
118
134
  var cls = (0, _className2.default)(this.baseClassName + '__suggestion-btn');
119
135
  this.suggestionsBox.innerHTML = suggestions.map(function (item) {
120
- return '<button class=\'' + cls + '\' tabindex=\'0\'>' + item.name + '</button>';
136
+ return '<button class=\'' + cls + '\' tabindex=\'0\' value="' + item.value + '">' + item.name + '</button>';
121
137
  }).join('');
122
138
  }
123
139
  }, {
124
140
  key: 'removeItem',
125
- value: function removeItem(item, index) {
126
- var selectedItemsList = this.element.querySelector('.js-m-multi-select-selected-items');
127
- selectedItemsList.removeChild(item);
141
+ value: function removeItem(item) {
142
+ var node = this.element.querySelector('.js-m-multi-select-selected-items li[data-value="' + item.value + '"]');
143
+
144
+ if (!node) {
145
+ return;
146
+ }
147
+
148
+ var parent = node.closest('.js-m-multi-select-selected-items');
149
+ var index = Array.prototype.indexOf.call(parent.children, node);
128
150
 
129
- var remainingItems = selectedItemsList.getElementsByTagName('div');
151
+ node.remove();
152
+
153
+ var remainingItems = parent.getElementsByTagName('li');
130
154
 
131
155
  // Focus management: set focus to the next item, or the search input if no items left
132
156
  if (remainingItems.length > 0) {
@@ -139,17 +163,25 @@ var MultiSelect = function () {
139
163
  this.input.focus();
140
164
  }
141
165
 
142
- this.selectedItems = this.selectedItems.filter(function (name) {
143
- return name !== item.firstChild.textContent.trim();
166
+ this.selectedItems = this.selectedItems.filter(function (i) {
167
+ return i.value !== item.value;
144
168
  });
169
+
170
+ var itemInput = this.element.querySelector('input[value="' + item.value + '"]');
171
+ itemInput.remove();
145
172
  }
146
173
  }, {
147
174
  key: 'addItem',
148
175
  value: function addItem(item) {
149
- var _this3 = this;
176
+ var _this4 = this;
177
+
178
+ if (!item) {
179
+ return;
180
+ }
150
181
 
151
182
  var newItem = document.createElement('li');
152
- newItem.textContent = item + ' ';
183
+ newItem.textContent = item.name + ' ';
184
+ newItem.setAttribute('data-value', item.value);
153
185
  newItem.classList.add((0, _className2.default)('a-tag'));
154
186
  newItem.classList.add((0, _className2.default)(this.baseClassName + '__tag'));
155
187
 
@@ -159,17 +191,25 @@ var MultiSelect = function () {
159
191
  var buttonTextContainer = document.createElement('span');
160
192
  buttonTextContainer.classList.add('u-visuallyhidden');
161
193
  removeBtn.appendChild(buttonTextContainer);
162
- buttonTextContainer.textContent = 'Ta bort ' + item; // Accessibility label for screen readers
194
+ buttonTextContainer.textContent = 'Ta bort ' + item.name; // Accessibility label for screen readers
163
195
 
164
196
  // Event listener for removing the selected item
165
197
  removeBtn.addEventListener('click', function () {
166
- _this3.removeItem(newItem, Array.from(_this3.selectedItemsList.children).indexOf(newItem));
198
+ _this4.removeItem(item);
167
199
  });
168
200
 
169
201
  newItem.appendChild(removeBtn);
170
202
 
171
203
  this.selectedItemsList.appendChild(newItem);
172
204
  this.selectedItems.push(item);
205
+
206
+ var itemInput = document.createElement('input');
207
+
208
+ itemInput.type = 'hidden';
209
+ itemInput.name = this.name + '[]';
210
+ itemInput.value = item.value;
211
+
212
+ this.element.appendChild(itemInput);
173
213
  }
174
214
  }, {
175
215
  key: 'removeHighlight',
@@ -204,7 +244,12 @@ var MultiSelect = function () {
204
244
  var items = this.suggestionsBox.getElementsByClassName(this.baseClassName + '__suggestion-btn');
205
245
 
206
246
  if (this.currentFocus > -1 && items[this.currentFocus]) {
207
- this.addItem(items[this.currentFocus].textContent);
247
+ var item = items[this.currentFocus];
248
+
249
+ this.addItem(this.data.find(function (d) {
250
+ return d.value === item.value;
251
+ }));
252
+
208
253
  this.clearSuggestions();
209
254
  this.input.value = '';
210
255
  this.resetFocus();
@@ -219,6 +264,6 @@ var multiSelectElements = document.querySelectorAll('.js-m-multi-select');
219
264
 
220
265
  if (multiSelectElements) {
221
266
  [].forEach.call(multiSelectElements, function (el) {
222
- return new MultiSelect(el);
267
+ el.multiSelect = new MultiSelect(el);
223
268
  });
224
269
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetstiftelsen/styleguide",
3
- "version": "4.0.12",
3
+ "version": "4.0.13",
4
4
  "main": "dist/components.js",
5
5
  "ports": {
6
6
  "fractal": "3000"
@@ -9,6 +9,10 @@
9
9
  content: $namespace;
10
10
  }
11
11
 
12
+ @include e(search) {
13
+ position: relative;
14
+ }
15
+
12
16
  @include e(suggestions-box) {
13
17
  position: absolute;
14
18
  border-top: none;
@@ -5,6 +5,7 @@ class MultiSelect {
5
5
  this.element = el;
6
6
  this.baseClassName = 'm-multi-select';
7
7
  this.currentFocus = -1;
8
+ this.name = this.element.getAttribute('data-multi-select-name');
8
9
  this.input = this.element.querySelector(`.js-${this.baseClassName}__input`);
9
10
  this.suggestionsBox = this.element.querySelector(`.js-${this.baseClassName}-suggestions-box`);
10
11
  this.selectedItemsList = this.element.querySelector('.js-m-multi-select-selected-items');
@@ -45,6 +46,13 @@ class MultiSelect {
45
46
  this.suggestionsBox.innerHTML = '';
46
47
  }
47
48
 
49
+ addSuggestions(suggestions) {
50
+ this.data = [
51
+ ...this.data,
52
+ ...suggestions.filter((s) => !this.data.find((d) => d.value === s.value)),
53
+ ];
54
+ }
55
+
48
56
  filterData(query) {
49
57
  return this.data
50
58
  .filter((item) => item.name.toLowerCase().startsWith(query.toLowerCase()))
@@ -53,7 +61,7 @@ class MultiSelect {
53
61
 
54
62
  populateSuggestions(suggestions) {
55
63
  const cls = className(`${this.baseClassName}__suggestion-btn`);
56
- this.suggestionsBox.innerHTML = suggestions.map((item) => `<button class='${cls}' tabindex='0'>${item.name}</button>`).join('');
64
+ this.suggestionsBox.innerHTML = suggestions.map((item) => `<button class='${cls}' tabindex='0' value="${item.value}">${item.name}</button>`).join('');
57
65
  }
58
66
 
59
67
  onInput = () => {
@@ -72,11 +80,19 @@ class MultiSelect {
72
80
  this.resetFocus();
73
81
  }
74
82
 
75
- removeItem(item, index) {
76
- const selectedItemsList = this.element.querySelector('.js-m-multi-select-selected-items');
77
- selectedItemsList.removeChild(item);
83
+ removeItem(item) {
84
+ const node = this.element.querySelector(`.js-m-multi-select-selected-items li[data-value="${item.value}"]`);
85
+
86
+ if (!node) {
87
+ return;
88
+ }
89
+
90
+ const parent = node.closest('.js-m-multi-select-selected-items');
91
+ const index = Array.prototype.indexOf.call(parent.children, node);
78
92
 
79
- const remainingItems = selectedItemsList.getElementsByTagName('div');
93
+ node.remove();
94
+
95
+ const remainingItems = parent.getElementsByTagName('li');
80
96
 
81
97
  // Focus management: set focus to the next item, or the search input if no items left
82
98
  if (remainingItems.length > 0) {
@@ -90,12 +106,20 @@ class MultiSelect {
90
106
  }
91
107
 
92
108
  this.selectedItems = this.selectedItems
93
- .filter((name) => name !== item.firstChild.textContent.trim());
109
+ .filter((i) => i.value !== item.value);
110
+
111
+ const itemInput = this.element.querySelector(`input[value="${item.value}"]`);
112
+ itemInput.remove();
94
113
  }
95
114
 
96
115
  addItem(item) {
116
+ if (!item) {
117
+ return;
118
+ }
119
+
97
120
  const newItem = document.createElement('li');
98
- newItem.textContent = `${item} `;
121
+ newItem.textContent = `${item.name} `;
122
+ newItem.setAttribute('data-value', item.value);
99
123
  newItem.classList.add(className('a-tag'));
100
124
  newItem.classList.add(className(`${this.baseClassName}__tag`));
101
125
 
@@ -105,17 +129,25 @@ class MultiSelect {
105
129
  const buttonTextContainer = document.createElement('span');
106
130
  buttonTextContainer.classList.add('u-visuallyhidden');
107
131
  removeBtn.appendChild(buttonTextContainer);
108
- buttonTextContainer.textContent = `Ta bort ${item}`; // Accessibility label for screen readers
132
+ buttonTextContainer.textContent = `Ta bort ${item.name}`; // Accessibility label for screen readers
109
133
 
110
134
  // Event listener for removing the selected item
111
135
  removeBtn.addEventListener('click', () => {
112
- this.removeItem(newItem, Array.from(this.selectedItemsList.children).indexOf(newItem));
136
+ this.removeItem(item);
113
137
  });
114
138
 
115
139
  newItem.appendChild(removeBtn);
116
140
 
117
141
  this.selectedItemsList.appendChild(newItem);
118
142
  this.selectedItems.push(item);
143
+
144
+ const itemInput = document.createElement('input');
145
+
146
+ itemInput.type = 'hidden';
147
+ itemInput.name = `${this.name}[]`;
148
+ itemInput.value = item.value;
149
+
150
+ this.element.appendChild(itemInput);
119
151
  }
120
152
 
121
153
  removeHighlight() {
@@ -147,7 +179,10 @@ class MultiSelect {
147
179
  const items = this.suggestionsBox.getElementsByClassName(`${this.baseClassName}__suggestion-btn`);
148
180
 
149
181
  if (this.currentFocus > -1 && items[this.currentFocus]) {
150
- this.addItem(items[this.currentFocus].textContent);
182
+ const item = items[this.currentFocus];
183
+
184
+ this.addItem(this.data.find((d) => d.value === item.value));
185
+
151
186
  this.clearSuggestions();
152
187
  this.input.value = '';
153
188
  this.resetFocus();
@@ -168,7 +203,7 @@ class MultiSelect {
168
203
 
169
204
  onClick = (e) => {
170
205
  if (e.target.classList.contains(className(`${this.baseClassName}__suggestion-btn`))) {
171
- this.addItem(e.target.textContent);
206
+ this.addItem(this.data.find((d) => d.value === e.target.value));
172
207
  this.clearSuggestions();
173
208
  this.input.value = '';
174
209
  }
@@ -178,5 +213,7 @@ class MultiSelect {
178
213
  const multiSelectElements = document.querySelectorAll('.js-m-multi-select');
179
214
 
180
215
  if (multiSelectElements) {
181
- [].forEach.call(multiSelectElements, (el) => new MultiSelect(el));
216
+ [].forEach.call(multiSelectElements, (el) => {
217
+ el.multiSelect = new MultiSelect(el);
218
+ });
182
219
  }