@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
|
@@ -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"
|
|
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(['
|
|
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
|
-
@
|
|
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
|
|
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="{
|
|
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 = (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
339
|
-
|
|
340
|
-
|
|
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
|
};
|
package/src/variables.scss
CHANGED
|
@@ -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
|
|