@internetstiftelsen/styleguide 4.0.12 → 4.0.14

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');
@@ -64,6 +69,7 @@ var MultiSelect = function () {
64
69
 
65
70
  this.getData();
66
71
  this.attach();
72
+ this.sync();
67
73
  }
68
74
 
69
75
  _createClass(MultiSelect, [{
@@ -101,15 +107,45 @@ var MultiSelect = function () {
101
107
  value: function clearSuggestions() {
102
108
  this.suggestionsBox.innerHTML = '';
103
109
  }
110
+ }, {
111
+ key: 'addSuggestions',
112
+ value: function addSuggestions(suggestions) {
113
+ var _this2 = this;
114
+
115
+ this.data = [].concat(_toConsumableArray(this.data), _toConsumableArray(suggestions.filter(function (s) {
116
+ return !_this2.data.find(function (d) {
117
+ return d.value === s.value;
118
+ });
119
+ })));
120
+ }
121
+ }, {
122
+ key: 'sync',
123
+ value: function sync() {
124
+ var _this3 = this;
125
+
126
+ var inputs = this.element.querySelectorAll('input[name="' + this.name + '[]"]');
127
+
128
+ this.selectedItems = [];
129
+
130
+ inputs.forEach(function (input) {
131
+ var item = _this3.data.find(function (d) {
132
+ return d.value === input.value;
133
+ });
134
+
135
+ if (item) {
136
+ _this3.addItem(item, false);
137
+ }
138
+ });
139
+ }
104
140
  }, {
105
141
  key: 'filterData',
106
142
  value: function filterData(query) {
107
- var _this2 = this;
143
+ var _this4 = this;
108
144
 
109
145
  return this.data.filter(function (item) {
110
146
  return item.name.toLowerCase().startsWith(query.toLowerCase());
111
147
  }).filter(function (item) {
112
- return !_this2.selectedItems.includes(item.name);
148
+ return !_this4.selectedItems.includes(item.name);
113
149
  });
114
150
  }
115
151
  }, {
@@ -117,16 +153,24 @@ var MultiSelect = function () {
117
153
  value: function populateSuggestions(suggestions) {
118
154
  var cls = (0, _className2.default)(this.baseClassName + '__suggestion-btn');
119
155
  this.suggestionsBox.innerHTML = suggestions.map(function (item) {
120
- return '<button class=\'' + cls + '\' tabindex=\'0\'>' + item.name + '</button>';
156
+ return '<button class=\'' + cls + '\' tabindex=\'0\' value="' + item.value + '">' + item.name + '</button>';
121
157
  }).join('');
122
158
  }
123
159
  }, {
124
160
  key: 'removeItem',
125
- value: function removeItem(item, index) {
126
- var selectedItemsList = this.element.querySelector('.js-m-multi-select-selected-items');
127
- selectedItemsList.removeChild(item);
161
+ value: function removeItem(item) {
162
+ var node = this.element.querySelector('.js-m-multi-select-selected-items li[data-value="' + item.value + '"]');
163
+
164
+ if (!node) {
165
+ return;
166
+ }
167
+
168
+ var parent = node.closest('.js-m-multi-select-selected-items');
169
+ var index = Array.prototype.indexOf.call(parent.children, node);
170
+
171
+ node.remove();
128
172
 
129
- var remainingItems = selectedItemsList.getElementsByTagName('div');
173
+ var remainingItems = parent.getElementsByTagName('li');
130
174
 
131
175
  // Focus management: set focus to the next item, or the search input if no items left
132
176
  if (remainingItems.length > 0) {
@@ -139,17 +183,27 @@ var MultiSelect = function () {
139
183
  this.input.focus();
140
184
  }
141
185
 
142
- this.selectedItems = this.selectedItems.filter(function (name) {
143
- return name !== item.firstChild.textContent.trim();
186
+ this.selectedItems = this.selectedItems.filter(function (i) {
187
+ return i.value !== item.value;
144
188
  });
189
+
190
+ var itemInput = this.element.querySelector('input[value="' + item.value + '"]');
191
+ itemInput.remove();
145
192
  }
146
193
  }, {
147
194
  key: 'addItem',
148
195
  value: function addItem(item) {
149
- var _this3 = this;
196
+ var _this5 = this;
197
+
198
+ var save = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
199
+
200
+ if (!item) {
201
+ return;
202
+ }
150
203
 
151
204
  var newItem = document.createElement('li');
152
- newItem.textContent = item + ' ';
205
+ newItem.textContent = item.name + ' ';
206
+ newItem.setAttribute('data-value', item.value);
153
207
  newItem.classList.add((0, _className2.default)('a-tag'));
154
208
  newItem.classList.add((0, _className2.default)(this.baseClassName + '__tag'));
155
209
 
@@ -159,17 +213,27 @@ var MultiSelect = function () {
159
213
  var buttonTextContainer = document.createElement('span');
160
214
  buttonTextContainer.classList.add('u-visuallyhidden');
161
215
  removeBtn.appendChild(buttonTextContainer);
162
- buttonTextContainer.textContent = 'Ta bort ' + item; // Accessibility label for screen readers
216
+ buttonTextContainer.textContent = 'Ta bort ' + item.name; // Accessibility label for screen readers
163
217
 
164
218
  // Event listener for removing the selected item
165
219
  removeBtn.addEventListener('click', function () {
166
- _this3.removeItem(newItem, Array.from(_this3.selectedItemsList.children).indexOf(newItem));
220
+ _this5.removeItem(item);
167
221
  });
168
222
 
169
223
  newItem.appendChild(removeBtn);
170
224
 
171
225
  this.selectedItemsList.appendChild(newItem);
172
226
  this.selectedItems.push(item);
227
+
228
+ if (save) {
229
+ var itemInput = document.createElement('input');
230
+
231
+ itemInput.type = 'hidden';
232
+ itemInput.name = this.name + '[]';
233
+ itemInput.value = item.value;
234
+
235
+ this.element.appendChild(itemInput);
236
+ }
173
237
  }
174
238
  }, {
175
239
  key: 'removeHighlight',
@@ -204,7 +268,12 @@ var MultiSelect = function () {
204
268
  var items = this.suggestionsBox.getElementsByClassName(this.baseClassName + '__suggestion-btn');
205
269
 
206
270
  if (this.currentFocus > -1 && items[this.currentFocus]) {
207
- this.addItem(items[this.currentFocus].textContent);
271
+ var item = items[this.currentFocus];
272
+
273
+ this.addItem(this.data.find(function (d) {
274
+ return d.value === item.value;
275
+ }));
276
+
208
277
  this.clearSuggestions();
209
278
  this.input.value = '';
210
279
  this.resetFocus();
@@ -219,6 +288,6 @@ var multiSelectElements = document.querySelectorAll('.js-m-multi-select');
219
288
 
220
289
  if (multiSelectElements) {
221
290
  [].forEach.call(multiSelectElements, function (el) {
222
- return new MultiSelect(el);
291
+ el.multiSelect = new MultiSelect(el);
223
292
  });
224
293
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetstiftelsen/styleguide",
3
- "version": "4.0.12",
3
+ "version": "4.0.14",
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');
@@ -13,6 +14,7 @@ class MultiSelect {
13
14
 
14
15
  this.getData();
15
16
  this.attach();
17
+ this.sync();
16
18
  }
17
19
 
18
20
  getData() {
@@ -45,6 +47,27 @@ class MultiSelect {
45
47
  this.suggestionsBox.innerHTML = '';
46
48
  }
47
49
 
50
+ addSuggestions(suggestions) {
51
+ this.data = [
52
+ ...this.data,
53
+ ...suggestions.filter((s) => !this.data.find((d) => d.value === s.value)),
54
+ ];
55
+ }
56
+
57
+ sync() {
58
+ const inputs = this.element.querySelectorAll(`input[name="${this.name}[]"]`);
59
+
60
+ this.selectedItems = [];
61
+
62
+ inputs.forEach((input) => {
63
+ const item = this.data.find((d) => d.value === input.value);
64
+
65
+ if (item) {
66
+ this.addItem(item, false);
67
+ }
68
+ });
69
+ }
70
+
48
71
  filterData(query) {
49
72
  return this.data
50
73
  .filter((item) => item.name.toLowerCase().startsWith(query.toLowerCase()))
@@ -53,7 +76,7 @@ class MultiSelect {
53
76
 
54
77
  populateSuggestions(suggestions) {
55
78
  const cls = className(`${this.baseClassName}__suggestion-btn`);
56
- this.suggestionsBox.innerHTML = suggestions.map((item) => `<button class='${cls}' tabindex='0'>${item.name}</button>`).join('');
79
+ this.suggestionsBox.innerHTML = suggestions.map((item) => `<button class='${cls}' tabindex='0' value="${item.value}">${item.name}</button>`).join('');
57
80
  }
58
81
 
59
82
  onInput = () => {
@@ -72,11 +95,19 @@ class MultiSelect {
72
95
  this.resetFocus();
73
96
  }
74
97
 
75
- removeItem(item, index) {
76
- const selectedItemsList = this.element.querySelector('.js-m-multi-select-selected-items');
77
- selectedItemsList.removeChild(item);
98
+ removeItem(item) {
99
+ const node = this.element.querySelector(`.js-m-multi-select-selected-items li[data-value="${item.value}"]`);
100
+
101
+ if (!node) {
102
+ return;
103
+ }
78
104
 
79
- const remainingItems = selectedItemsList.getElementsByTagName('div');
105
+ const parent = node.closest('.js-m-multi-select-selected-items');
106
+ const index = Array.prototype.indexOf.call(parent.children, node);
107
+
108
+ node.remove();
109
+
110
+ const remainingItems = parent.getElementsByTagName('li');
80
111
 
81
112
  // Focus management: set focus to the next item, or the search input if no items left
82
113
  if (remainingItems.length > 0) {
@@ -90,12 +121,20 @@ class MultiSelect {
90
121
  }
91
122
 
92
123
  this.selectedItems = this.selectedItems
93
- .filter((name) => name !== item.firstChild.textContent.trim());
124
+ .filter((i) => i.value !== item.value);
125
+
126
+ const itemInput = this.element.querySelector(`input[value="${item.value}"]`);
127
+ itemInput.remove();
94
128
  }
95
129
 
96
- addItem(item) {
130
+ addItem(item, save = true) {
131
+ if (!item) {
132
+ return;
133
+ }
134
+
97
135
  const newItem = document.createElement('li');
98
- newItem.textContent = `${item} `;
136
+ newItem.textContent = `${item.name} `;
137
+ newItem.setAttribute('data-value', item.value);
99
138
  newItem.classList.add(className('a-tag'));
100
139
  newItem.classList.add(className(`${this.baseClassName}__tag`));
101
140
 
@@ -105,17 +144,27 @@ class MultiSelect {
105
144
  const buttonTextContainer = document.createElement('span');
106
145
  buttonTextContainer.classList.add('u-visuallyhidden');
107
146
  removeBtn.appendChild(buttonTextContainer);
108
- buttonTextContainer.textContent = `Ta bort ${item}`; // Accessibility label for screen readers
147
+ buttonTextContainer.textContent = `Ta bort ${item.name}`; // Accessibility label for screen readers
109
148
 
110
149
  // Event listener for removing the selected item
111
150
  removeBtn.addEventListener('click', () => {
112
- this.removeItem(newItem, Array.from(this.selectedItemsList.children).indexOf(newItem));
151
+ this.removeItem(item);
113
152
  });
114
153
 
115
154
  newItem.appendChild(removeBtn);
116
155
 
117
156
  this.selectedItemsList.appendChild(newItem);
118
157
  this.selectedItems.push(item);
158
+
159
+ if (save) {
160
+ const itemInput = document.createElement('input');
161
+
162
+ itemInput.type = 'hidden';
163
+ itemInput.name = `${this.name}[]`;
164
+ itemInput.value = item.value;
165
+
166
+ this.element.appendChild(itemInput);
167
+ }
119
168
  }
120
169
 
121
170
  removeHighlight() {
@@ -147,7 +196,10 @@ class MultiSelect {
147
196
  const items = this.suggestionsBox.getElementsByClassName(`${this.baseClassName}__suggestion-btn`);
148
197
 
149
198
  if (this.currentFocus > -1 && items[this.currentFocus]) {
150
- this.addItem(items[this.currentFocus].textContent);
199
+ const item = items[this.currentFocus];
200
+
201
+ this.addItem(this.data.find((d) => d.value === item.value));
202
+
151
203
  this.clearSuggestions();
152
204
  this.input.value = '';
153
205
  this.resetFocus();
@@ -168,7 +220,7 @@ class MultiSelect {
168
220
 
169
221
  onClick = (e) => {
170
222
  if (e.target.classList.contains(className(`${this.baseClassName}__suggestion-btn`))) {
171
- this.addItem(e.target.textContent);
223
+ this.addItem(this.data.find((d) => d.value === e.target.value));
172
224
  this.clearSuggestions();
173
225
  this.input.value = '';
174
226
  }
@@ -178,5 +230,7 @@ class MultiSelect {
178
230
  const multiSelectElements = document.querySelectorAll('.js-m-multi-select');
179
231
 
180
232
  if (multiSelectElements) {
181
- [].forEach.call(multiSelectElements, (el) => new MultiSelect(el));
233
+ [].forEach.call(multiSelectElements, (el) => {
234
+ el.multiSelect = new MultiSelect(el);
235
+ });
182
236
  }