goodteditor-ui 1.0.41 → 1.0.43

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,6 +1,6 @@
1
1
  {
2
2
  "name": "goodteditor-ui",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "main": "index.js",
5
5
  "homepage": "https://goodt-ui.netlify.app/",
6
6
  "scripts": {
@@ -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="less" scoped>
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
- keyup: e => e.key == 'Enter' && this.onInputEnter(e),
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(e) {
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(e) {
189
+ onInputFocus() {
174
190
  this.rootHasFocus = true;
175
191
  },
176
- onInputBlur(e) {
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.code) {
251
+ case 'Tab':
252
+ case 'Comma':
253
+ case 'Semicolon':
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.code) {
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>
@@ -411,18 +411,25 @@ export default {
411
411
  onKeyDown(e) {
412
412
  let list = this.getDatalistRef();
413
413
  if (e.key === Key.ESC) {
414
- this.popoverShow = false;
414
+ if (this.popoverShow) {
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();
423
+ }
415
424
  return;
416
425
  }
417
- if (e.key === Key.ENTER) {
418
- if (!this.popoverShow) {
419
- this.popoverShow = true;
420
- }
426
+ if (e.key === Key.ENTER && !this.popoverShow) {
427
+ this.popoverShow = true;
421
428
  }
422
429
  if (this.popoverShow) {
423
430
  list && list.onKeyDown(e);
424
431
  }
425
- },
426
- },
432
+ }
433
+ }
427
434
  };
428
435
  </script>