goodteditor-ui 1.0.42 → 1.0.44
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.
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="ui-input-tags form-elem" :class="cssClass" @focus="onRootFocus" tabindex="0">
|
|
3
3
|
<div class="ui-input-tags-tags" v-if="value.length">
|
|
4
|
-
<!--
|
|
4
|
+
<!--
|
|
5
5
|
@slot Tag slot
|
|
6
6
|
@binding {String} tag tag
|
|
7
7
|
@binding {Function} remove remove tag function(tag)
|
|
8
8
|
-->
|
|
9
9
|
<slot name="tag" v-for="tag in value" v-bind="{ tag, remove: removeTag }">
|
|
10
10
|
<ui-badge
|
|
11
|
-
class="ui-input-tags-badge mar-none mar-right-2 mar-bot-2 pull-left"
|
|
11
|
+
class="ui-input-tags-badge mar-none mar-right-2 mar-bot-2 pull-left cursor-pointer"
|
|
12
|
+
:class="{ 'ui-input-tags-badge--selected': tagSelected === tag }"
|
|
12
13
|
theme="primary"
|
|
13
14
|
size="small"
|
|
14
15
|
:key="tag"
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
</ui-badge>
|
|
20
21
|
</slot>
|
|
21
22
|
</div>
|
|
22
|
-
<!--
|
|
23
|
+
<!--
|
|
23
24
|
@slot Custom input slot
|
|
24
25
|
@binding {String} id input id attribute value
|
|
25
26
|
@binding {String} value input value
|
|
@@ -52,10 +53,11 @@
|
|
|
52
53
|
</slot>
|
|
53
54
|
</div>
|
|
54
55
|
</template>
|
|
55
|
-
<style lang="
|
|
56
|
+
<style lang="pcss" scoped>
|
|
56
57
|
.ui-input-tags {
|
|
57
58
|
display: inline-flex;
|
|
58
59
|
flex-wrap: wrap;
|
|
60
|
+
|
|
59
61
|
&-input {
|
|
60
62
|
line-height: 1.5;
|
|
61
63
|
border: none;
|
|
@@ -64,13 +66,18 @@
|
|
|
64
66
|
background: transparent;
|
|
65
67
|
outline: none;
|
|
66
68
|
}
|
|
69
|
+
|
|
67
70
|
&-tags {
|
|
68
71
|
max-width: 100%;
|
|
69
72
|
}
|
|
73
|
+
|
|
70
74
|
&-badge {
|
|
71
75
|
white-space: normal;
|
|
72
76
|
overflow-wrap: break-word;
|
|
73
77
|
word-break: break-word;
|
|
78
|
+
&--selected {
|
|
79
|
+
background-color: var(--color-primary-dark);
|
|
80
|
+
}
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
</style>
|
|
@@ -113,6 +120,7 @@ export default {
|
|
|
113
120
|
data() {
|
|
114
121
|
return {
|
|
115
122
|
newTag: '',
|
|
123
|
+
tagSelected: null,
|
|
116
124
|
inputBinds: {
|
|
117
125
|
placeholder: this.placeholder,
|
|
118
126
|
readonly: this.readonly,
|
|
@@ -121,11 +129,15 @@ export default {
|
|
|
121
129
|
input: this.onInputInput,
|
|
122
130
|
focus: this.onInputFocus,
|
|
123
131
|
blur: this.onInputBlur,
|
|
124
|
-
|
|
132
|
+
keydown: this.onInputKeydown
|
|
125
133
|
},
|
|
126
134
|
};
|
|
127
135
|
},
|
|
128
136
|
methods: {
|
|
137
|
+
/**
|
|
138
|
+
*
|
|
139
|
+
* @param {string} value
|
|
140
|
+
*/
|
|
129
141
|
setNewTag(value) {
|
|
130
142
|
this.newTag = value;
|
|
131
143
|
},
|
|
@@ -150,6 +162,9 @@ export default {
|
|
|
150
162
|
this.$emit('change', tags);
|
|
151
163
|
this.newTag = '';
|
|
152
164
|
},
|
|
165
|
+
/**
|
|
166
|
+
* @param {string} tag
|
|
167
|
+
*/
|
|
153
168
|
removeTag(tag) {
|
|
154
169
|
let tags = this.value.filter(t => t !== tag);
|
|
155
170
|
/**
|
|
@@ -163,22 +178,118 @@ export default {
|
|
|
163
178
|
*/
|
|
164
179
|
this.$emit('change', tags);
|
|
165
180
|
},
|
|
166
|
-
onRootFocus(
|
|
181
|
+
onRootFocus() {
|
|
167
182
|
let input = this.getInputRef();
|
|
168
183
|
input && input.focus();
|
|
169
184
|
},
|
|
170
185
|
onInputInput(e) {
|
|
171
186
|
this.newTag = e.target.value;
|
|
187
|
+
this.tagSelected = null;
|
|
172
188
|
},
|
|
173
|
-
onInputFocus(
|
|
189
|
+
onInputFocus() {
|
|
174
190
|
this.rootHasFocus = true;
|
|
175
191
|
},
|
|
176
|
-
onInputBlur(
|
|
192
|
+
onInputBlur() {
|
|
177
193
|
this.rootHasFocus = false;
|
|
178
194
|
},
|
|
195
|
+
/**
|
|
196
|
+
* @param {KeyboardEvent} e
|
|
197
|
+
*/
|
|
179
198
|
onInputEnter(e) {
|
|
199
|
+
e.preventDefault();
|
|
200
|
+
e.stopPropagation();
|
|
180
201
|
this.addTag();
|
|
181
202
|
},
|
|
203
|
+
/**
|
|
204
|
+
* @param {KeyboardEvent} e
|
|
205
|
+
*/
|
|
206
|
+
onInputEsc(e) {
|
|
207
|
+
e.stopPropagation();
|
|
208
|
+
let input = this.getInputRef();
|
|
209
|
+
input && input.blur();
|
|
210
|
+
},
|
|
211
|
+
/**
|
|
212
|
+
*
|
|
213
|
+
* @param {number} direction
|
|
214
|
+
*/
|
|
215
|
+
selectTag(direction = -1) {
|
|
216
|
+
const lastIndex = this.value.length - 1;
|
|
217
|
+
let tagSelected = this.tagSelected;
|
|
218
|
+
|
|
219
|
+
if (tagSelected === null) {
|
|
220
|
+
tagSelected = this.value[lastIndex] ?? null;
|
|
221
|
+
} else {
|
|
222
|
+
let index = this.value.findIndex((tag) => tag === tagSelected) + direction;
|
|
223
|
+
if (index > lastIndex) {
|
|
224
|
+
index = 0;
|
|
225
|
+
}
|
|
226
|
+
if (index < 0) {
|
|
227
|
+
index = lastIndex;
|
|
228
|
+
}
|
|
229
|
+
tagSelected = this.value[index];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (tagSelected === null) {
|
|
233
|
+
this.onRootFocus();
|
|
234
|
+
}
|
|
235
|
+
this.tagSelected = tagSelected;
|
|
236
|
+
},
|
|
237
|
+
/**
|
|
238
|
+
*
|
|
239
|
+
* @param {KeyboardEvent} e
|
|
240
|
+
* @return {boolean}
|
|
241
|
+
*/
|
|
242
|
+
canSelectTag(e) {
|
|
243
|
+
return e.target.value === '' && ['Backspace', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].indexOf(e.code)
|
|
244
|
+
},
|
|
245
|
+
/**
|
|
246
|
+
*
|
|
247
|
+
* @param {KeyboardEvent} e
|
|
248
|
+
*/
|
|
249
|
+
onInputKeydown(e) {
|
|
250
|
+
switch (e.key) {
|
|
251
|
+
case ',':
|
|
252
|
+
case ';':
|
|
253
|
+
case 'Tab':
|
|
254
|
+
case 'Enter': {
|
|
255
|
+
this.onInputEnter(e);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
case 'Escape': {
|
|
259
|
+
this.onInputEsc(e);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (this.canSelectTag(e) === false) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
switch (e.key) {
|
|
269
|
+
case 'Backspace': {
|
|
270
|
+
if (this.tagSelected === null) {
|
|
271
|
+
this.selectTag();
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this.removeTag(this.tagSelected);
|
|
275
|
+
this.tagSelected = null;
|
|
276
|
+
this.$nextTick(() => {
|
|
277
|
+
this.selectTag();
|
|
278
|
+
});
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
case 'ArrowLeft':
|
|
282
|
+
case 'ArrowUp': {
|
|
283
|
+
this.selectTag(-1);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
case 'ArrowRight':
|
|
287
|
+
case 'ArrowDown': {
|
|
288
|
+
this.selectTag(1);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
182
293
|
},
|
|
183
294
|
};
|
|
184
295
|
</script>
|
|
@@ -413,8 +413,14 @@ export default {
|
|
|
413
413
|
if (e.key === Key.ESC) {
|
|
414
414
|
if (this.popoverShow) {
|
|
415
415
|
e.stopPropagation();
|
|
416
|
+
this.popoverShow = false;
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
if (this.rootHasFocus) {
|
|
420
|
+
e.stopPropagation();
|
|
421
|
+
this.rootHasFocus = false;
|
|
422
|
+
this.$el.blur();
|
|
416
423
|
}
|
|
417
|
-
this.popoverShow = false;
|
|
418
424
|
return;
|
|
419
425
|
}
|
|
420
426
|
if (e.key === Key.ENTER && !this.popoverShow) {
|