@v1nt1248/3nclient-lib 0.3.39 → 0.3.41
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/dist/src/components/ui3n-menu/types.d.ts +5 -0
- package/dist/src/components/ui3n-menu/ui3n-menu.d.ts +1 -0
- package/dist/style.css +1 -1
- package/dist/ui3n-components.js +777 -751
- package/package.json +1 -1
- package/src/components/ui3n-autocomplete/ui3n-autocomplete.vue +79 -22
- package/src/components/ui3n-menu/types.ts +5 -0
- package/src/components/ui3n-menu/ui3n-menu.vue +9 -1
- package/src/components/ui3n-selector/ui3n-selector.vue +1 -2
package/package.json
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
items: () => [],
|
|
27
27
|
itemTitle: 'name',
|
|
28
28
|
itemValue: 'id',
|
|
29
|
+
addNewValue: false,
|
|
29
30
|
});
|
|
30
31
|
const emits = defineEmits<Ui3nAutocompleteEmits<T>>();
|
|
31
32
|
defineSlots<Ui3nAutocompleteSlots<T>>();
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
const activeItemsIndex = ref<Nullable<number>>(null);
|
|
41
42
|
const isLastChipHighlighted = ref(false);
|
|
42
43
|
const isNewValueValid = ref(true);
|
|
44
|
+
const selectedFromMenu = ref(false);
|
|
43
45
|
|
|
44
46
|
const ids = computed(() =>
|
|
45
47
|
props.returnObject ? (props.modelValue as T[]).map(item => item.id) : (props.modelValue as Array<T[keyof T]>),
|
|
@@ -89,12 +91,60 @@
|
|
|
89
91
|
activeItemsIndex.value = null;
|
|
90
92
|
isLastChipHighlighted.value = false;
|
|
91
93
|
|
|
94
|
+
if (!selectedFromMenu.value) {
|
|
95
|
+
tryAddNewValue();
|
|
96
|
+
}
|
|
97
|
+
|
|
92
98
|
setTimeout(() => {
|
|
93
99
|
isMenuOpen.value = false;
|
|
94
100
|
query.value = '';
|
|
101
|
+
selectedFromMenu.value = false;
|
|
95
102
|
}, 150);
|
|
96
103
|
}
|
|
97
104
|
|
|
105
|
+
function tryAddNewValue(): boolean {
|
|
106
|
+
if (!props.addNewValue || props.disabled) return false;
|
|
107
|
+
|
|
108
|
+
const text = query.value.trim();
|
|
109
|
+
if (!text) return false;
|
|
110
|
+
|
|
111
|
+
isNewValueValid.value = !props.newValueValidator ? true : props.newValueValidator(text);
|
|
112
|
+
emits('valid:new-value', isNewValueValid.value);
|
|
113
|
+
if (!isNewValueValid.value) return false;
|
|
114
|
+
|
|
115
|
+
const item = {
|
|
116
|
+
id: getRandomId(6),
|
|
117
|
+
[props.itemTitle]: text,
|
|
118
|
+
[props.itemValue]: text,
|
|
119
|
+
} as unknown as T;
|
|
120
|
+
|
|
121
|
+
if (!props.multiple) {
|
|
122
|
+
const newValue = props.returnObject ? [item] : [item[props.itemValue]];
|
|
123
|
+
emits('update:modelValue', newValue);
|
|
124
|
+
} else {
|
|
125
|
+
const alreadyPresent = props.returnObject
|
|
126
|
+
? (props.modelValue as T[]).some(
|
|
127
|
+
v => v[props.itemValue] === item[props.itemValue] || v[props.itemTitle] === item[props.itemTitle],
|
|
128
|
+
)
|
|
129
|
+
: props.modelValue.some(v => v === item[props.itemValue]);
|
|
130
|
+
|
|
131
|
+
if (!alreadyPresent) {
|
|
132
|
+
const updatedValue = cloneDeep(props.modelValue);
|
|
133
|
+
// @ts-ignore
|
|
134
|
+
updatedValue.push(props.returnObject ? item : item[props.itemValue]);
|
|
135
|
+
emits('update:modelValue', updatedValue);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
isNewValueValid.value = true;
|
|
140
|
+
props.clearOnSelect && (query.value = '');
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function onItemMouseDown() {
|
|
145
|
+
selectedFromMenu.value = true;
|
|
146
|
+
}
|
|
147
|
+
|
|
98
148
|
function onItemClick(item: T) {
|
|
99
149
|
if (props.disabled) return;
|
|
100
150
|
|
|
@@ -155,7 +205,7 @@
|
|
|
155
205
|
}
|
|
156
206
|
}
|
|
157
207
|
|
|
158
|
-
function
|
|
208
|
+
function handlePressingEscKey() {
|
|
159
209
|
emits('update:focused', false);
|
|
160
210
|
isMenuOpen.value = false;
|
|
161
211
|
activeItemsIndex.value = null;
|
|
@@ -164,34 +214,35 @@
|
|
|
164
214
|
activatorEl.value && activatorEl.value.blur();
|
|
165
215
|
}
|
|
166
216
|
|
|
167
|
-
function
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
activeItemsIndex.value = 0;
|
|
171
|
-
menuBodyEl.value && menuBodyEl.value.focus({ preventScroll: true });
|
|
172
|
-
return;
|
|
217
|
+
function handlePressingTabKey() {
|
|
218
|
+
if (props.addNewValue) {
|
|
219
|
+
tryAddNewValue();
|
|
173
220
|
}
|
|
174
221
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
id: getRandomId(6),
|
|
181
|
-
[props.itemTitle]: query.value,
|
|
182
|
-
[props.itemValue]: query.value,
|
|
183
|
-
};
|
|
184
|
-
onItemClick(item as unknown as T);
|
|
185
|
-
}
|
|
186
|
-
props.clearOnSelect && (query.value = '');
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
222
|
+
emits('update:focused', false);
|
|
223
|
+
isMenuOpen.value = false;
|
|
224
|
+
activeItemsIndex.value = null;
|
|
225
|
+
query.value = '';
|
|
226
|
+
}
|
|
189
227
|
|
|
228
|
+
function handlePressingEnterKey() {
|
|
190
229
|
if (activeItemsIndex.value !== null) {
|
|
191
230
|
const item = filteredItems.value[activeItemsIndex.value!];
|
|
192
231
|
onItemClick(item);
|
|
193
232
|
activeItemsIndex.value = null;
|
|
194
233
|
props.clearOnSelect && (query.value = '');
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (props.addNewValue && query.value.trim()) {
|
|
238
|
+
tryAddNewValue();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!isMenuOpen.value) {
|
|
243
|
+
isMenuOpen.value = true;
|
|
244
|
+
activeItemsIndex.value = 0;
|
|
245
|
+
menuBodyEl.value && menuBodyEl.value.focus({ preventScroll: true });
|
|
195
246
|
}
|
|
196
247
|
}
|
|
197
248
|
|
|
@@ -229,8 +280,11 @@
|
|
|
229
280
|
}
|
|
230
281
|
|
|
231
282
|
case 'esc':
|
|
283
|
+
handlePressingEscKey();
|
|
284
|
+
break;
|
|
285
|
+
|
|
232
286
|
case 'tab':
|
|
233
|
-
|
|
287
|
+
handlePressingTabKey();
|
|
234
288
|
break;
|
|
235
289
|
|
|
236
290
|
case 'enter': {
|
|
@@ -251,6 +305,7 @@
|
|
|
251
305
|
isMenuOpen.value = false;
|
|
252
306
|
activeItemsIndex.value = null;
|
|
253
307
|
isNewValueValid.value = true;
|
|
308
|
+
selectedFromMenu.value = false;
|
|
254
309
|
|
|
255
310
|
emits('update:modelValue', [] as unknown as T[] & Array<T[keyof T]>);
|
|
256
311
|
emits('update:search', '');
|
|
@@ -323,6 +378,7 @@
|
|
|
323
378
|
|
|
324
379
|
<ui3n-menu
|
|
325
380
|
v-model="isMenuOpen"
|
|
381
|
+
width="100%"
|
|
326
382
|
:lock-scroll="lockScroll"
|
|
327
383
|
:offset-x="2"
|
|
328
384
|
:offset-y="4"
|
|
@@ -413,6 +469,7 @@
|
|
|
413
469
|
activeItemsIndex === index && $style.itemSelected,
|
|
414
470
|
disabled && $style.itemDisabled,
|
|
415
471
|
]"
|
|
472
|
+
@mousedown="onItemMouseDown"
|
|
416
473
|
@click.stop.prevent="onItemClick(item)"
|
|
417
474
|
>
|
|
418
475
|
<slot
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
closeOnClick: true,
|
|
17
17
|
closeOnClickOutside: true,
|
|
18
18
|
disabled: false,
|
|
19
|
+
width: 'max-content',
|
|
19
20
|
});
|
|
20
21
|
const emits = defineEmits<Ui3nMenuEmits>();
|
|
21
22
|
defineSlots<Ui3nMenuSlots>();
|
|
@@ -90,6 +91,13 @@
|
|
|
90
91
|
};
|
|
91
92
|
});
|
|
92
93
|
|
|
94
|
+
const rootStyles = computed(() => {
|
|
95
|
+
const numericWidth = !isNaN(Number(props.width));
|
|
96
|
+
const widthStr = numericWidth ? `${props.width}px` : String(props.width);
|
|
97
|
+
|
|
98
|
+
return { width: widthStr };
|
|
99
|
+
});
|
|
100
|
+
|
|
93
101
|
function preventScrollEvent(e: Event) {
|
|
94
102
|
e.preventDefault();
|
|
95
103
|
}
|
|
@@ -262,6 +270,7 @@
|
|
|
262
270
|
ref="menu-element"
|
|
263
271
|
:id="id"
|
|
264
272
|
:class="$style.ui3nMenu"
|
|
273
|
+
:style="rootStyles"
|
|
265
274
|
@click="emits('click', $event)"
|
|
266
275
|
>
|
|
267
276
|
<div
|
|
@@ -292,7 +301,6 @@
|
|
|
292
301
|
--ui3n-menu-content-bg: var(--color-bg-control-secondary-default);
|
|
293
302
|
|
|
294
303
|
position: relative;
|
|
295
|
-
width: max-content;
|
|
296
304
|
display: inline-block;
|
|
297
305
|
overflow: visible;
|
|
298
306
|
}
|
|
@@ -259,6 +259,7 @@
|
|
|
259
259
|
|
|
260
260
|
<ui3n-menu
|
|
261
261
|
v-model="isMenuOpen"
|
|
262
|
+
width="100%"
|
|
262
263
|
:offset-x="-3"
|
|
263
264
|
:offset-y="4"
|
|
264
265
|
position-autoupdate
|
|
@@ -399,8 +400,6 @@
|
|
|
399
400
|
}
|
|
400
401
|
|
|
401
402
|
.menu {
|
|
402
|
-
width: 100%;
|
|
403
|
-
max-width: 100% !important;
|
|
404
403
|
border-radius: var(--ui3n-selector-border-radius);
|
|
405
404
|
|
|
406
405
|
& > div {
|