@formixru/b2b-ui 4.1.0 → 4.2.1

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": "@formixru/b2b-ui",
3
- "version": "4.1.0",
3
+ "version": "4.2.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,6 @@
9
9
  type="text"
10
10
  :placeholder="props.placeholder"
11
11
  autocomplete="off"
12
- @input="emit('input', $event)"
13
12
  @focusin="emit('focusin', $event)"
14
13
  @focusout="emit('focusout', $event)"
15
14
  @keydown="emit('keydown', $event)"
@@ -22,7 +21,9 @@
22
21
  emit('submit');
23
22
  "
24
23
  >
25
- <span v-show="props.isLoading" class="search-input__spinner"><span class="spinner"></span></span>
24
+ <span v-show="props.isLoading" class="search-input__spinner">
25
+ <span class="spinner"></span>
26
+ </span>
26
27
  <svg v-show="!props.isLoading" class="search-input__submit-icon">
27
28
  <use :href="`${ICONS_PATH}#search`" />
28
29
  </svg>
@@ -40,7 +41,7 @@ import { ref, useTemplateRef, watch, watchEffect } from 'vue';
40
41
 
41
42
  const ICONS_PATH = window.ICONS_PATH;
42
43
 
43
- const emit = defineEmits(['input', 'focusin', 'focusout', 'keydown', 'submit']);
44
+ const emit = defineEmits(['focusin', 'focusout', 'keydown', 'submit']);
44
45
  const model = defineModel({ type: String, default: '' });
45
46
 
46
47
  const props = defineProps({
@@ -118,6 +118,11 @@ $b: '.suggest-input';
118
118
  color: $suggest-input-item-active-color;
119
119
  }
120
120
 
121
+ &_disabled {
122
+ color: $suggest-input-item-disabled-color;
123
+ pointer-events: none;
124
+ }
125
+
121
126
  mark {
122
127
  background-color: transparent;
123
128
  color: $suggest-input-item-mark-color;
@@ -10,7 +10,7 @@
10
10
  :input-delay="0"
11
11
  :input-css-classes="props.inputCssClasses"
12
12
  :is-loading="isLoading"
13
- @input="handleInput()"
13
+ @update:model-value="handleInput()"
14
14
  @focusin="focusin()"
15
15
  @focusout="focusout($event)"
16
16
  @keydown="arrowNavigation($event)"
@@ -33,7 +33,13 @@
33
33
  @keydown="arrowNavigation($event)"
34
34
  />
35
35
  <div v-show="isLoading && !props.searchInput" class="suggest-input__loader"><div class="spinner"></div></div>
36
- <button v-show="isClearVisible && !props.searchInput" ref="$clear" class="suggest-input__clear" type="button" @click="clear()">
36
+ <button
37
+ v-show="isClearVisible && !props.searchInput"
38
+ ref="$clear"
39
+ class="suggest-input__clear"
40
+ type="button"
41
+ @click="clear()"
42
+ >
37
43
  <svg class="suggest-input__clear-icon"><use :href="`${ICONS_PATH}#close`" /></svg>
38
44
  </button>
39
45
  <div v-show="showSuggests" ref="$list" class="suggest-input__list" @mouseover="focusSuggestIndex = -1">
@@ -42,7 +48,10 @@
42
48
  v-for="(item, index) in formattedSuggests"
43
49
  :key="index"
44
50
  class="suggest-input__list-item"
45
- :class="{ 'suggest-input__list-item_focus': index === focusSuggestIndex }"
51
+ :class="{
52
+ 'suggest-input__list-item_focus': index === focusSuggestIndex,
53
+ 'suggest-input__list-item_disabled': item.disabled,
54
+ }"
46
55
  tabindex="0"
47
56
  @click="select(item)"
48
57
  >
@@ -245,7 +254,10 @@ const cancelRequest = () => {
245
254
  isLoading.value = false;
246
255
  };
247
256
 
248
- const handleInput = () => {
257
+ const handleInput = async () => {
258
+ // Ждём, чтобы model.value точно обновилось (может быть задержка из-за v-model/@update:model-value в SearchInput)
259
+ await nextTick();
260
+
249
261
  if (model.value.length >= props.minlength) {
250
262
  _debouncedGetSuggests(model.value);
251
263
  } else {
@@ -283,13 +295,17 @@ const clear = () => {
283
295
  showSuggests.value = false;
284
296
  };
285
297
 
286
- const select = ({ label, value }) => {
298
+ const select = (item) => {
299
+ if (item.disabled) {
300
+ return;
301
+ }
302
+
287
303
  cancelRequest();
288
- model.value = label;
304
+ model.value = item.label;
289
305
  showSuggests.value = false;
290
306
  emit('select', {
291
307
  input: model.value,
292
- value,
308
+ value: item.value,
293
309
  });
294
310
  };
295
311
 
@@ -298,15 +314,32 @@ const arrowNavigation = async (event) => {
298
314
  if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
299
315
  event.preventDefault();
300
316
 
317
+ const len = suggests.value.length;
318
+ if (len === 0) {
319
+ return;
320
+ }
321
+
301
322
  switch (event.key) {
302
323
  case 'ArrowDown': {
303
- focusSuggestIndex.value =
304
- suggests.value.length === focusSuggestIndex.value + 1 ? 0 : focusSuggestIndex.value + 1;
324
+ let nextIndex = focusSuggestIndex.value;
325
+ for (let i = 0; i < len; i++) {
326
+ nextIndex = (nextIndex + 1) % len;
327
+ if (!suggests.value[nextIndex]?.disabled) {
328
+ focusSuggestIndex.value = nextIndex;
329
+ break;
330
+ }
331
+ }
305
332
  break;
306
333
  }
307
334
  case 'ArrowUp': {
308
- focusSuggestIndex.value =
309
- focusSuggestIndex.value <= 0 ? suggests.value.length - 1 : focusSuggestIndex.value - 1;
335
+ let nextIndex = focusSuggestIndex.value === -1 ? 0 : focusSuggestIndex.value;
336
+ for (let i = 0; i < len; i++) {
337
+ nextIndex = (nextIndex - 1 + len) % len;
338
+ if (!suggests.value[nextIndex]?.disabled) {
339
+ focusSuggestIndex.value = nextIndex;
340
+ break;
341
+ }
342
+ }
310
343
  break;
311
344
  }
312
345
  }
@@ -334,11 +367,16 @@ const arrowNavigation = async (event) => {
334
367
  }
335
368
  }
336
369
  }
370
+
337
371
  if (event.key === 'Enter' && focusSuggestIndex.value >= 0) {
338
- // Ждём, чтобы событие нажатия Enter сработало у других обработчиков (например, в формах)
339
- setTimeout(() => {
340
- select(suggests.value[focusSuggestIndex.value]);
341
- });
372
+ const item = suggests.value[focusSuggestIndex.value];
373
+
374
+ if (item && !item.disabled) {
375
+ // Ждём, чтобы событие нажатия Enter сработало у других обработчиков (например, в формах)
376
+ setTimeout(() => {
377
+ select(item);
378
+ });
379
+ }
342
380
  }
343
381
  }
344
382
  };
@@ -602,6 +602,8 @@ $suggest-input-item-font: ('font-size': $font-size, 'line-height': $line-height)
602
602
  $suggest-input-item-mark-color: inherit !default;
603
603
  $suggest-input-item-mark-font: ('font-weight': bold) !default;
604
604
 
605
+ $suggest-input-item-disabled-color: $font-color-tertiary !default;
606
+
605
607
  $suggest-input-item-active-bg: $color-grey-90 !default;
606
608
  $suggest-input-item-active-color: $font-color-action !default;
607
609