sprintify-ui 0.0.103 → 0.0.104
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/sprintify-ui.es.js +8252 -8040
- package/dist/style.css +1 -1
- package/dist/types/src/components/BaseAutocomplete.vue.d.ts +23 -3
- package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +21 -3
- package/dist/types/src/components/BaseBelongsTo.vue.d.ts +21 -3
- package/dist/types/src/components/BaseDropdown.vue.d.ts +9 -0
- package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +123 -0
- package/dist/types/src/components/BaseTable.vue.d.ts +2 -2
- package/dist/types/src/components/index.d.ts +2 -1
- package/dist/types/src/types/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/BaseAutocomplete.stories.js +6 -0
- package/src/components/BaseAutocomplete.vue +65 -15
- package/src/components/BaseAutocompleteDropdown.vue +2 -2
- package/src/components/BaseAutocompleteFetch.stories.js +6 -0
- package/src/components/BaseAutocompleteFetch.vue +29 -3
- package/src/components/BaseBelongsTo.stories.js +6 -0
- package/src/components/BaseBelongsTo.vue +12 -2
- package/src/components/BaseButtonGroup.vue +1 -1
- package/src/components/BaseColor.vue +3 -3
- package/src/components/BaseDropdown.stories.js +1 -1
- package/src/components/BaseDropdown.vue +15 -9
- package/src/components/BaseDropdownAutocomplete.stories.js +178 -0
- package/src/components/BaseDropdownAutocomplete.vue +225 -0
- package/src/components/BaseRadioGroup.vue +4 -1
- package/src/components/BaseTable.vue +1 -1
- package/src/components/BaseTagAutocomplete.vue +4 -4
- package/src/components/index.ts +2 -0
- package/src/types/index.ts +1 -1
- package/dist/types/src/components/BaseFormField.d.ts +0 -81
- package/dist/types/src/components/BaseLocaleForm.vue.d.ts +0 -439
- package/dist/types/src/components/BaseNumberForm.vue.d.ts +0 -401
- package/dist/types/src/components/BasePasswordForm.vue.d.ts +0 -384
- package/dist/types/src/components/BaseTextareaForm.vue.d.ts +0 -413
- package/src/components/BaseFormField.ts +0 -117
- package/src/components/BaseLocaleForm.vue +0 -142
- package/src/components/BaseNumberForm.vue +0 -67
- package/src/components/BasePasswordForm.vue +0 -59
- package/src/components/BaseTextareaForm.vue +0 -101
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="autocomplete">
|
|
3
|
-
<div class="relative">
|
|
3
|
+
<div class="relative z-[1]">
|
|
4
4
|
<div class="relative">
|
|
5
5
|
<input
|
|
6
6
|
ref="inputElement"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
:placeholder="
|
|
10
10
|
placeholder ? placeholder : $t('sui.autocomplete_placeholder')
|
|
11
11
|
"
|
|
12
|
-
class="w-full rounded disabled:cursor-not-allowed disabled:text-slate-300"
|
|
12
|
+
class="w-full rounded pr-9 disabled:cursor-not-allowed disabled:text-slate-300"
|
|
13
13
|
:class="[
|
|
14
14
|
hasErrorInternal ? 'border-red-600' : 'border-slate-300',
|
|
15
15
|
inputClass,
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
</div>
|
|
42
42
|
|
|
43
43
|
<div
|
|
44
|
-
v-if="normalizedModelValue && !disabled &&
|
|
44
|
+
v-if="normalizedModelValue && !disabled && showModelValue"
|
|
45
45
|
class="absolute top-0 right-0 flex h-full items-center p-1"
|
|
46
46
|
>
|
|
47
47
|
<button
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
class="w-full overflow-hidden"
|
|
65
65
|
:class="[
|
|
66
66
|
inline
|
|
67
|
-
? 'relative
|
|
67
|
+
? 'relative'
|
|
68
68
|
: 'absolute top-1 z-menu min-h-[110px] w-full overflow-hidden rounded border border-slate-300 bg-white shadow-md',
|
|
69
69
|
]"
|
|
70
70
|
>
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
:size="size"
|
|
76
76
|
:loading="loading"
|
|
77
77
|
:loading-bottom="loadingBottom"
|
|
78
|
-
:dropdown-class="inline ? '' : 'p-1'"
|
|
78
|
+
:dropdown-class="inline ? 'pt-1' : 'p-1'"
|
|
79
79
|
:keywords="keywords"
|
|
80
80
|
@select="onSelect"
|
|
81
81
|
@scroll-bottom="emit('scrollBottom')"
|
|
@@ -166,7 +166,7 @@ const props = defineProps({
|
|
|
166
166
|
default: 'focus',
|
|
167
167
|
type: String as PropType<'focus' | 'always'>,
|
|
168
168
|
},
|
|
169
|
-
|
|
169
|
+
showModelValue: {
|
|
170
170
|
default: true,
|
|
171
171
|
type: Boolean,
|
|
172
172
|
},
|
|
@@ -174,6 +174,18 @@ const props = defineProps({
|
|
|
174
174
|
default: true,
|
|
175
175
|
type: Boolean,
|
|
176
176
|
},
|
|
177
|
+
/** Show an 'empty option', should use with showModelValue = true for better UX */
|
|
178
|
+
showEmptyOption: {
|
|
179
|
+
default: false,
|
|
180
|
+
type: Boolean,
|
|
181
|
+
},
|
|
182
|
+
emptyOptionLabel: {
|
|
183
|
+
default() {
|
|
184
|
+
const i18n = useI18n();
|
|
185
|
+
return i18n.t('sui.none');
|
|
186
|
+
},
|
|
187
|
+
type: String,
|
|
188
|
+
},
|
|
177
189
|
});
|
|
178
190
|
|
|
179
191
|
const emit = defineEmits([
|
|
@@ -216,10 +228,26 @@ const normalizedModelValue =
|
|
|
216
228
|
hasOptions.normalizedModelValue as ComputedRef<NormalizedOption | null>;
|
|
217
229
|
|
|
218
230
|
const filteredNormalizedOptions = computed((): NormalizedOption[] => {
|
|
231
|
+
let options = normalizedOptions.value;
|
|
232
|
+
|
|
233
|
+
if (props.showEmptyOption) {
|
|
234
|
+
const emptyOption = {
|
|
235
|
+
[props.valueKey]: null,
|
|
236
|
+
[props.labelKey]: props.emptyOptionLabel,
|
|
237
|
+
option: null,
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
options = [
|
|
241
|
+
{ value: null, label: props.emptyOptionLabel, option: emptyOption },
|
|
242
|
+
...options,
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
|
|
219
246
|
if (shouldFilter.value === false) {
|
|
220
|
-
return
|
|
247
|
+
return options;
|
|
221
248
|
}
|
|
222
|
-
|
|
249
|
+
|
|
250
|
+
return options.filter((option) => {
|
|
223
251
|
if (props.filter !== undefined) {
|
|
224
252
|
return props.filter(option);
|
|
225
253
|
}
|
|
@@ -235,12 +263,16 @@ watch(
|
|
|
235
263
|
() => normalizedModelValue.value,
|
|
236
264
|
() => {
|
|
237
265
|
if (normalizedModelValue.value) {
|
|
238
|
-
if (props.
|
|
266
|
+
if (props.showModelValue) {
|
|
239
267
|
setKeywords(normalizedModelValue.value?.label);
|
|
240
268
|
}
|
|
241
269
|
} else {
|
|
242
|
-
if (props.
|
|
243
|
-
|
|
270
|
+
if (props.showModelValue) {
|
|
271
|
+
if (props.showEmptyOption) {
|
|
272
|
+
setKeywords(props.emptyOptionLabel);
|
|
273
|
+
} else {
|
|
274
|
+
setKeywords('');
|
|
275
|
+
}
|
|
244
276
|
}
|
|
245
277
|
}
|
|
246
278
|
},
|
|
@@ -268,8 +300,16 @@ function close() {
|
|
|
268
300
|
blur();
|
|
269
301
|
timerId = setTimeout(() => {
|
|
270
302
|
// If no valid modelValue is set on close, set the keywords to the original value
|
|
271
|
-
if (props.
|
|
272
|
-
|
|
303
|
+
if (props.showModelValue) {
|
|
304
|
+
if (normalizedModelValue.value) {
|
|
305
|
+
setKeywords(normalizedModelValue.value.label);
|
|
306
|
+
} else {
|
|
307
|
+
if (props.showEmptyOption) {
|
|
308
|
+
setKeywords(props.emptyOptionLabel);
|
|
309
|
+
} else {
|
|
310
|
+
setKeywords('');
|
|
311
|
+
}
|
|
312
|
+
}
|
|
273
313
|
}
|
|
274
314
|
}, 10);
|
|
275
315
|
emit('close');
|
|
@@ -282,7 +322,7 @@ const onTextInput = (event: Event) => {
|
|
|
282
322
|
emit('typing', keywords.value);
|
|
283
323
|
|
|
284
324
|
// If keywords is empty, emit null
|
|
285
|
-
if (keywords.value == '') {
|
|
325
|
+
if (keywords.value == '' && !props.showEmptyOption) {
|
|
286
326
|
update(null);
|
|
287
327
|
}
|
|
288
328
|
};
|
|
@@ -321,8 +361,18 @@ function onSelect(normalizedModelValue: Option | null | undefined) {
|
|
|
321
361
|
function update(normalizedSelection: Option | null | undefined) {
|
|
322
362
|
// Re-activate filter
|
|
323
363
|
shouldFilter.value = false;
|
|
364
|
+
|
|
324
365
|
// Emit update
|
|
325
|
-
|
|
366
|
+
let selection = normalizedSelection ? normalizedSelection.option : null;
|
|
367
|
+
|
|
368
|
+
if (
|
|
369
|
+
props.showEmptyOption &&
|
|
370
|
+
normalizedSelection &&
|
|
371
|
+
normalizedSelection.value == null
|
|
372
|
+
) {
|
|
373
|
+
selection = null;
|
|
374
|
+
}
|
|
375
|
+
|
|
326
376
|
emitUpdate(selection);
|
|
327
377
|
}
|
|
328
378
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<ul v-else :class="dropdownClass">
|
|
19
19
|
<li
|
|
20
20
|
v-for="(option, index) in options"
|
|
21
|
-
:key="option.value"
|
|
21
|
+
:key="option.value ? option.value : 'null'"
|
|
22
22
|
:data-index="index"
|
|
23
23
|
class="block"
|
|
24
24
|
>
|
|
@@ -222,7 +222,7 @@ onMounted(() => {
|
|
|
222
222
|
() => {
|
|
223
223
|
emit('scrollBottom');
|
|
224
224
|
},
|
|
225
|
-
{ distance:
|
|
225
|
+
{ distance: 100 }
|
|
226
226
|
);
|
|
227
227
|
});
|
|
228
228
|
|
|
@@ -58,6 +58,12 @@ Disabled.args = {
|
|
|
58
58
|
disabled: true,
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
+
export const ShowEmptyOption = Template.bind({});
|
|
62
|
+
ShowEmptyOption.args = {
|
|
63
|
+
showEmptyOption: true,
|
|
64
|
+
emptyOptionLabel: 'No Jedi',
|
|
65
|
+
};
|
|
66
|
+
|
|
61
67
|
export const Inline = Template.bind({});
|
|
62
68
|
Inline.args = {
|
|
63
69
|
inline: true,
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
:size="size"
|
|
16
16
|
:inline="inline"
|
|
17
17
|
:dropdown-show="dropdownShow"
|
|
18
|
-
:model-value
|
|
18
|
+
:show-model-value="showModelValue"
|
|
19
19
|
:visible-focus="visibleFocus"
|
|
20
|
-
:
|
|
20
|
+
:show-empty-option="showEmptyOption"
|
|
21
|
+
:empty-option-label="emptyOptionLabel"
|
|
22
|
+
:filter="filterOptions"
|
|
21
23
|
@clear="onClear"
|
|
22
24
|
@open="onOpen"
|
|
23
25
|
@typing="onTyping"
|
|
@@ -114,7 +116,7 @@ const props = defineProps({
|
|
|
114
116
|
default: 'focus',
|
|
115
117
|
type: String as PropType<'focus' | 'always'>,
|
|
116
118
|
},
|
|
117
|
-
|
|
119
|
+
showModelValue: {
|
|
118
120
|
default: true,
|
|
119
121
|
type: Boolean,
|
|
120
122
|
},
|
|
@@ -122,6 +124,14 @@ const props = defineProps({
|
|
|
122
124
|
default: true,
|
|
123
125
|
type: Boolean,
|
|
124
126
|
},
|
|
127
|
+
showEmptyOption: {
|
|
128
|
+
default: false,
|
|
129
|
+
type: Boolean,
|
|
130
|
+
},
|
|
131
|
+
emptyOptionLabel: {
|
|
132
|
+
default: undefined,
|
|
133
|
+
type: String,
|
|
134
|
+
},
|
|
125
135
|
});
|
|
126
136
|
|
|
127
137
|
const emit = defineEmits([
|
|
@@ -217,6 +227,22 @@ const debouncedSearch = debounce(() => {
|
|
|
217
227
|
search();
|
|
218
228
|
}, 300);
|
|
219
229
|
|
|
230
|
+
function filterOptions(option: Option): boolean {
|
|
231
|
+
// Do nothing if showEmptyOption is false
|
|
232
|
+
if (!props.showEmptyOption) {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Hide the empty value on search
|
|
237
|
+
if (
|
|
238
|
+
option.value == null &&
|
|
239
|
+
!option.label.toLowerCase().includes(keywords.value.toLowerCase())
|
|
240
|
+
) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
|
|
220
246
|
defineExpose({
|
|
221
247
|
focus: () => autocomplete.value?.focus(),
|
|
222
248
|
blur: () => autocomplete.value?.blur(),
|
|
@@ -54,6 +54,12 @@ Inline.args = {
|
|
|
54
54
|
inline: true,
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
export const ShowEmptyOption = Template.bind({});
|
|
58
|
+
ShowEmptyOption.args = {
|
|
59
|
+
showEmptyOption: true,
|
|
60
|
+
emptyOptionLabel: 'No Jedi',
|
|
61
|
+
};
|
|
62
|
+
|
|
57
63
|
export const Sizes = (args) => ({
|
|
58
64
|
components: { BaseBelongsTo },
|
|
59
65
|
setup() {
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
:inline="inline"
|
|
14
14
|
:size="size"
|
|
15
15
|
:dropdown-show="dropdownShow"
|
|
16
|
-
:model-value
|
|
16
|
+
:show-model-value="showModelValue"
|
|
17
|
+
:show-empty-option="showEmptyOption"
|
|
18
|
+
:empty-option-label="emptyOptionLabel"
|
|
17
19
|
:visible-focus="visibleFocus"
|
|
18
20
|
@update:model-value="onUpdate"
|
|
19
21
|
>
|
|
@@ -95,7 +97,7 @@ const props = defineProps({
|
|
|
95
97
|
default: 'focus',
|
|
96
98
|
type: String as PropType<'focus' | 'always'>,
|
|
97
99
|
},
|
|
98
|
-
|
|
100
|
+
showModelValue: {
|
|
99
101
|
default: true,
|
|
100
102
|
type: Boolean,
|
|
101
103
|
},
|
|
@@ -103,6 +105,14 @@ const props = defineProps({
|
|
|
103
105
|
default: true,
|
|
104
106
|
type: Boolean,
|
|
105
107
|
},
|
|
108
|
+
showEmptyOption: {
|
|
109
|
+
default: false,
|
|
110
|
+
type: Boolean,
|
|
111
|
+
},
|
|
112
|
+
emptyOptionLabel: {
|
|
113
|
+
default: undefined,
|
|
114
|
+
type: String,
|
|
115
|
+
},
|
|
106
116
|
});
|
|
107
117
|
|
|
108
118
|
const http = config.http;
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
>
|
|
17
17
|
<template #option="option">
|
|
18
18
|
<div
|
|
19
|
-
:style="{
|
|
20
|
-
class="
|
|
19
|
+
:style="{ backgroundColor: option.option.value + '' }"
|
|
20
|
+
class="rounded-md border-none p-3"
|
|
21
21
|
:class="[
|
|
22
22
|
option.selected.value ? 'text-white' : 'text-transparent',
|
|
23
23
|
disabled ? ' cursor-not-allowed opacity-50' : '',
|
|
24
24
|
]"
|
|
25
25
|
>
|
|
26
|
-
<BaseIcon icon="heroicons-solid:check-circle" class="
|
|
26
|
+
<BaseIcon icon="heroicons-solid:check-circle" class="h-5 w-5" />
|
|
27
27
|
</div>
|
|
28
28
|
</template>
|
|
29
29
|
</BaseButtonGroup>
|
|
@@ -110,7 +110,7 @@ export const WithAutocomplete = (args) => ({
|
|
|
110
110
|
:inline="true"
|
|
111
111
|
:visibleFocus="false"
|
|
112
112
|
dropdownShow="always"
|
|
113
|
-
:
|
|
113
|
+
:showModelValue="false"
|
|
114
114
|
@update:modelValue="onUpdate($event, close)"
|
|
115
115
|
></BaseAutocomplete>
|
|
116
116
|
</div>
|
|
@@ -15,15 +15,17 @@
|
|
|
15
15
|
leave-from-class="transform scale-100 opacity-100"
|
|
16
16
|
leave-to-class="transform scale-90 opacity-0"
|
|
17
17
|
>
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
<template v-if="showDropdown || keepAlive">
|
|
19
|
+
<div v-show="showDropdown" class="inline-block">
|
|
20
|
+
<slot
|
|
21
|
+
name="dropdown"
|
|
22
|
+
:show-dropdown="showDropdown"
|
|
23
|
+
:close="close"
|
|
24
|
+
:open="open"
|
|
25
|
+
:toggle="toggle"
|
|
26
|
+
></slot>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
27
29
|
</Transition>
|
|
28
30
|
</div>
|
|
29
31
|
</Teleport>
|
|
@@ -58,6 +60,10 @@ const props = defineProps({
|
|
|
58
60
|
default: false,
|
|
59
61
|
type: Boolean,
|
|
60
62
|
},
|
|
63
|
+
keepAlive: {
|
|
64
|
+
default: true,
|
|
65
|
+
type: Boolean,
|
|
66
|
+
},
|
|
61
67
|
});
|
|
62
68
|
|
|
63
69
|
const buttonX = ref(0);
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import BaseBadge from './BaseBadge.vue';
|
|
2
|
+
import BaseDropdownAutocomplete from './BaseDropdownAutocomplete.vue';
|
|
3
|
+
import ShowValue from '@/../.storybook/components/ShowValue.vue';
|
|
4
|
+
import { options } from '../../.storybook/utils';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Components/BaseDropdownAutocomplete',
|
|
8
|
+
component: BaseDropdownAutocomplete,
|
|
9
|
+
argTypes: {
|
|
10
|
+
placement: {
|
|
11
|
+
control: {
|
|
12
|
+
type: 'select',
|
|
13
|
+
options: ['top-start', 'top-end', 'bottom-start', 'bottom-end'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
placement: 'bottom-start',
|
|
19
|
+
padding: 8,
|
|
20
|
+
emptyOptionLabel: 'Nothing',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Autocomplete = (args) => ({
|
|
25
|
+
components: { BaseDropdownAutocomplete, BaseBadge, ShowValue },
|
|
26
|
+
setup() {
|
|
27
|
+
const value = ref(null);
|
|
28
|
+
return { args, options, value };
|
|
29
|
+
},
|
|
30
|
+
template: `
|
|
31
|
+
<BaseDropdownAutocomplete
|
|
32
|
+
v-bind="args"
|
|
33
|
+
v-model="value"
|
|
34
|
+
>
|
|
35
|
+
<template #button="{ newValue }">
|
|
36
|
+
<BaseBadge v-if="newValue">
|
|
37
|
+
{{ newValue.label }}
|
|
38
|
+
</BaseBadge>
|
|
39
|
+
<div v-else>
|
|
40
|
+
<BaseBadge contrast="low">
|
|
41
|
+
Nothing
|
|
42
|
+
</BaseBadge>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
45
|
+
<template #option="{ option }">
|
|
46
|
+
<BaseBadge :contrast="option?.value ? 'high' : 'low'">
|
|
47
|
+
{{ option.label }}
|
|
48
|
+
</BaseBadge>
|
|
49
|
+
</template>
|
|
50
|
+
</BaseDropdownAutocomplete>
|
|
51
|
+
<ShowValue :value="value" />
|
|
52
|
+
`,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
Autocomplete.args = {
|
|
56
|
+
options: options,
|
|
57
|
+
multiple: false,
|
|
58
|
+
labelKey: 'label',
|
|
59
|
+
valueKey: 'value',
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const AutocompleteFetch = (args) => ({
|
|
63
|
+
components: { BaseDropdownAutocomplete, BaseBadge, ShowValue },
|
|
64
|
+
setup() {
|
|
65
|
+
const value = ref(null);
|
|
66
|
+
return { args, options, value };
|
|
67
|
+
},
|
|
68
|
+
template: `
|
|
69
|
+
<BaseDropdownAutocomplete
|
|
70
|
+
v-bind="args"
|
|
71
|
+
v-model="value"
|
|
72
|
+
>
|
|
73
|
+
<template #button="{ newValue }">
|
|
74
|
+
<BaseBadge v-if="newValue" contrast="high">
|
|
75
|
+
{{ newValue.name }}
|
|
76
|
+
</BaseBadge>
|
|
77
|
+
<div v-else>
|
|
78
|
+
<BaseBadge contrast="low">
|
|
79
|
+
Nothing
|
|
80
|
+
</BaseBadge>
|
|
81
|
+
</div>
|
|
82
|
+
</template>
|
|
83
|
+
<template #option="{ option }">
|
|
84
|
+
<BaseBadge :contrast="option?.id ? 'high' : 'low'">
|
|
85
|
+
{{ option.name }}
|
|
86
|
+
</BaseBadge>
|
|
87
|
+
</template>
|
|
88
|
+
</BaseDropdownAutocomplete>
|
|
89
|
+
<ShowValue :value="value" />
|
|
90
|
+
`,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
AutocompleteFetch.args = {
|
|
94
|
+
valueKey: 'id',
|
|
95
|
+
labelKey: 'name',
|
|
96
|
+
url: 'https://effettandem.com/api/content/tags',
|
|
97
|
+
multiple: false,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const TagAutocomplete = (args) => ({
|
|
101
|
+
components: { BaseDropdownAutocomplete, BaseBadge, ShowValue },
|
|
102
|
+
setup() {
|
|
103
|
+
const value = ref([]);
|
|
104
|
+
return { args, options, value };
|
|
105
|
+
},
|
|
106
|
+
template: `
|
|
107
|
+
<BaseDropdownAutocomplete
|
|
108
|
+
v-bind="args"
|
|
109
|
+
v-model="value"
|
|
110
|
+
>
|
|
111
|
+
<template #button="{ newValue }">
|
|
112
|
+
<div v-if="newValue && newValue.length" class="flex flex-wrap gap-0.5">
|
|
113
|
+
<BaseBadge v-for="item in newValue" :key="item.value" contrast="high">
|
|
114
|
+
{{ item.label }}
|
|
115
|
+
</BaseBadge>
|
|
116
|
+
</div>
|
|
117
|
+
<div v-else>
|
|
118
|
+
<BaseBadge contrast="low">
|
|
119
|
+
Nothing
|
|
120
|
+
</BaseBadge>
|
|
121
|
+
</div>
|
|
122
|
+
</template>
|
|
123
|
+
<template #option="{ option }">
|
|
124
|
+
<BaseBadge contrast="high">
|
|
125
|
+
{{ option.label }}
|
|
126
|
+
</BaseBadge>
|
|
127
|
+
</template>
|
|
128
|
+
</BaseDropdownAutocomplete>
|
|
129
|
+
<ShowValue :value="value" />
|
|
130
|
+
`,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
TagAutocomplete.args = {
|
|
134
|
+
options: options,
|
|
135
|
+
multiple: true,
|
|
136
|
+
labelKey: 'label',
|
|
137
|
+
valueKey: 'value',
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const TagAutocompleteFetch = (args) => ({
|
|
141
|
+
components: { BaseDropdownAutocomplete, BaseBadge, ShowValue },
|
|
142
|
+
setup() {
|
|
143
|
+
const value = ref([]);
|
|
144
|
+
return { args, options, value };
|
|
145
|
+
},
|
|
146
|
+
template: `
|
|
147
|
+
<BaseDropdownAutocomplete
|
|
148
|
+
v-bind="args"
|
|
149
|
+
v-model="value"
|
|
150
|
+
>
|
|
151
|
+
<template #button="{ newValue }">
|
|
152
|
+
<div v-if="newValue && newValue.length" class="flex flex-wrap gap-0.5">
|
|
153
|
+
<BaseBadge v-for="item in newValue" :key="item.value" contrast="high">
|
|
154
|
+
{{ item.name }}
|
|
155
|
+
</BaseBadge>
|
|
156
|
+
</div>
|
|
157
|
+
<div v-else>
|
|
158
|
+
<BaseBadge contrast="low">
|
|
159
|
+
Nothing
|
|
160
|
+
</BaseBadge>
|
|
161
|
+
</div>
|
|
162
|
+
</template>
|
|
163
|
+
<template #option="{ option }">
|
|
164
|
+
<BaseBadge contrast="high">
|
|
165
|
+
{{ option.name }}
|
|
166
|
+
</BaseBadge>
|
|
167
|
+
</template>
|
|
168
|
+
</BaseDropdownAutocomplete>
|
|
169
|
+
<ShowValue :value="value" />
|
|
170
|
+
`,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
TagAutocompleteFetch.args = {
|
|
174
|
+
valueKey: 'id',
|
|
175
|
+
labelKey: 'name',
|
|
176
|
+
url: 'https://effettandem.com/api/content/tags',
|
|
177
|
+
multiple: true,
|
|
178
|
+
};
|