@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(
|
|
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
|
|
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 !
|
|
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
|
|
126
|
-
var
|
|
127
|
-
|
|
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 =
|
|
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 (
|
|
143
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
291
|
+
el.multiSelect = new MultiSelect(el);
|
|
223
292
|
});
|
|
224
293
|
}
|
package/package.json
CHANGED
|
@@ -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
|
|
76
|
-
const
|
|
77
|
-
|
|
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
|
|
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((
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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) =>
|
|
233
|
+
[].forEach.call(multiSelectElements, (el) => {
|
|
234
|
+
el.multiSelect = new MultiSelect(el);
|
|
235
|
+
});
|
|
182
236
|
}
|