@signal24/vue-foundation 4.25.3 → 4.25.5
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/demo/components/demo-vf-smart-select.vue +70 -7
- package/dist/src/components/vf-smart-select.vue.d.ts +2 -0
- package/dist/src/helpers/object.d.ts +1 -0
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/dist/vue-foundation.es.js +546 -541
- package/package.json +1 -1
- package/src/components/vf-smart-select.vue +23 -11
- package/src/helpers/object.ts +4 -0
package/package.json
CHANGED
|
@@ -51,7 +51,9 @@
|
|
|
51
51
|
|
|
52
52
|
<script lang="ts" setup generic="T, V = T">
|
|
53
53
|
import { debounce, groupBy, isEqual, uniq } from 'lodash';
|
|
54
|
-
import { computed, onMounted,
|
|
54
|
+
import { computed, onMounted, ref, watch } from 'vue';
|
|
55
|
+
|
|
56
|
+
import { isNotNullOrUndefined } from '@/helpers';
|
|
55
57
|
|
|
56
58
|
import { escapeHtml } from '../helpers/string';
|
|
57
59
|
import type { VfSmartSelectOptionDescriptor } from './vf-smart-select.types';
|
|
@@ -63,6 +65,7 @@ const VALID_KEYS = `\`1234567890-=[]\\;',./~!@#$%^&*()_+{}|:"<>?qwertyuiopasdfgh
|
|
|
63
65
|
|
|
64
66
|
const props = defineProps<{
|
|
65
67
|
modelValue: V | null;
|
|
68
|
+
loadingText?: string;
|
|
66
69
|
loadOptions?: (searchText: string | null) => Promise<T[]>;
|
|
67
70
|
options?: T[];
|
|
68
71
|
prependOptions?: T[];
|
|
@@ -82,6 +85,7 @@ const props = defineProps<{
|
|
|
82
85
|
formatter?: (option: T) => string;
|
|
83
86
|
subtitleFormatter?: (option: T) => string;
|
|
84
87
|
classForOption?: (option: T) => string;
|
|
88
|
+
selectionFormatter?: (option: T) => string;
|
|
85
89
|
nullTitle?: string;
|
|
86
90
|
noResultsText?: string;
|
|
87
91
|
disabled?: boolean;
|
|
@@ -108,7 +112,7 @@ const optionsContainer = ref<HTMLDivElement>();
|
|
|
108
112
|
|
|
109
113
|
const isLoading = ref(false);
|
|
110
114
|
const isLoaded = ref(false);
|
|
111
|
-
const loadedOptions = ref<T[]>(
|
|
115
|
+
const loadedOptions = ref<T[]>();
|
|
112
116
|
const isSearching = ref(false);
|
|
113
117
|
const searchText = ref('');
|
|
114
118
|
const selectedOption = ref<T | null>(null);
|
|
@@ -120,7 +124,7 @@ const shouldShowCreateTextOnNewItem = computed(() => props.showCreateTextOnNewIt
|
|
|
120
124
|
|
|
121
125
|
const effectivePrependOptions = computed(() => props.prependOptions ?? []);
|
|
122
126
|
const effectiveAppendOptions = computed(() => props.appendOptions ?? []);
|
|
123
|
-
const effectiveDisabled = computed(() => !!props.disabled);
|
|
127
|
+
const effectiveDisabled = computed(() => !!props.disabled || (!props.options && !loadedOptions.value));
|
|
124
128
|
const effectivePlaceholder = computed(() => {
|
|
125
129
|
if (!isLoaded.value && props.preload) return 'Loading...';
|
|
126
130
|
if (props.nullTitle) return props.nullTitle;
|
|
@@ -149,8 +153,12 @@ const effectiveFormatter = computed(() => {
|
|
|
149
153
|
if (props.labelField) return (option: T) => String(option[props.labelField!]);
|
|
150
154
|
return (option: T) => String(option);
|
|
151
155
|
});
|
|
156
|
+
const effectiveSelectionFormatter = computed(() => {
|
|
157
|
+
if (props.selectionFormatter) return props.selectionFormatter;
|
|
158
|
+
return effectiveFormatter.value;
|
|
159
|
+
});
|
|
152
160
|
|
|
153
|
-
const allOptions = computed(() => [...effectivePrependOptions.value, ...loadedOptions.value, ...effectiveAppendOptions.value]);
|
|
161
|
+
const allOptions = computed(() => [...effectivePrependOptions.value, ...(loadedOptions.value ?? []), ...effectiveAppendOptions.value]);
|
|
154
162
|
const isGrouped = computed(() => !!(props.groupField || props.groupFormatter));
|
|
155
163
|
|
|
156
164
|
const optionsDescriptors = computed(() => {
|
|
@@ -249,7 +257,7 @@ watch(() => props.modelValue, handleValueChanged);
|
|
|
249
257
|
watch(
|
|
250
258
|
() => props.options,
|
|
251
259
|
() => {
|
|
252
|
-
loadedOptions.value = props.options
|
|
260
|
+
loadedOptions.value = props.options;
|
|
253
261
|
isLoaded.value = true;
|
|
254
262
|
}
|
|
255
263
|
);
|
|
@@ -301,17 +309,21 @@ onMounted(async () => {
|
|
|
301
309
|
if (props.options) {
|
|
302
310
|
loadedOptions.value = [...props.options];
|
|
303
311
|
isLoaded.value = true;
|
|
304
|
-
} else if (props.preload) {
|
|
312
|
+
} else if (props.loadOptions && props.preload) {
|
|
305
313
|
await loadRemoteOptions();
|
|
306
314
|
}
|
|
307
315
|
|
|
308
|
-
|
|
316
|
+
if (!props.options && (props.valueField || props.valueExtractor)) {
|
|
317
|
+
searchText.value = props.loadingText ?? '...';
|
|
318
|
+
} else {
|
|
319
|
+
handleValueChanged();
|
|
320
|
+
}
|
|
309
321
|
|
|
310
322
|
watch(selectedOption, () => {
|
|
311
323
|
if (selectedOption.value !== props.modelValue) {
|
|
312
324
|
emit(
|
|
313
325
|
'update:modelValue',
|
|
314
|
-
selectedOption.value
|
|
326
|
+
isNotNullOrUndefined(selectedOption.value) && effectiveValueExtractor.value !== null
|
|
315
327
|
? effectiveValueExtractor.value(selectedOption.value)
|
|
316
328
|
: selectedOption.value
|
|
317
329
|
);
|
|
@@ -536,7 +548,7 @@ function selectOption(option: VfSmartSelectOptionDescriptor<T>) {
|
|
|
536
548
|
const selectedDecoratedOption = optionsDescriptors.value.find(decoratedOption => decoratedOption.key == option.key);
|
|
537
549
|
const realOption = selectedDecoratedOption!.ref;
|
|
538
550
|
selectedOption.value = realOption!;
|
|
539
|
-
selectedOptionTitle.value =
|
|
551
|
+
selectedOptionTitle.value = effectiveSelectionFormatter.value(realOption!);
|
|
540
552
|
searchText.value = selectedOptionTitle.value ?? '';
|
|
541
553
|
}
|
|
542
554
|
|
|
@@ -549,7 +561,7 @@ function handleValueChanged() {
|
|
|
549
561
|
selectedOption.value = effectiveValueExtractor.value
|
|
550
562
|
? allOptions.value.find(o => props.modelValue === effectiveValueExtractor.value!(o))
|
|
551
563
|
: props.modelValue;
|
|
552
|
-
selectedOptionTitle.value = selectedOption.value
|
|
564
|
+
selectedOptionTitle.value = isNotNullOrUndefined(selectedOption.value) ? effectiveSelectionFormatter.value(selectedOption.value) : null;
|
|
553
565
|
searchText.value = selectedOptionTitle.value ?? '';
|
|
554
566
|
} else {
|
|
555
567
|
selectedOption.value = null;
|
|
@@ -559,7 +571,7 @@ function handleValueChanged() {
|
|
|
559
571
|
}
|
|
560
572
|
|
|
561
573
|
function addRemoteOption(option: T) {
|
|
562
|
-
loadedOptions.value
|
|
574
|
+
loadedOptions.value!.unshift(option);
|
|
563
575
|
}
|
|
564
576
|
|
|
565
577
|
function focusNextInput() {
|
package/src/helpers/object.ts
CHANGED