sprintify-ui 0.0.96 → 0.0.99

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.
Files changed (31) hide show
  1. package/dist/sprintify-ui.es.js +8035 -7945
  2. package/dist/style.css +2 -2
  3. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +32 -10
  4. package/dist/types/src/components/BaseAutocompleteDropdown.vue.d.ts +88 -0
  5. package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +20 -5
  6. package/dist/types/src/components/BaseBelongsTo.vue.d.ts +18 -3
  7. package/dist/types/src/components/BaseDatePicker.vue.d.ts +1 -1
  8. package/dist/types/src/components/BaseHasMany.vue.d.ts +17 -0
  9. package/dist/types/src/components/BaseLoadingCover.vue.d.ts +1 -1
  10. package/dist/types/src/components/BaseSwitch.vue.d.ts +1 -1
  11. package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +66 -6
  12. package/dist/types/src/components/BaseTagAutocompleteFetch.vue.d.ts +19 -2
  13. package/dist/types/src/composables/clickOutside.d.ts +1 -1
  14. package/dist/types/src/index.d.ts +2 -0
  15. package/package.json +10 -10
  16. package/src/assets/main.css +0 -1
  17. package/src/components/BaseAutocomplete.vue +53 -183
  18. package/src/components/BaseAutocompleteDropdown.vue +344 -0
  19. package/src/components/BaseAutocompleteFetch.vue +8 -3
  20. package/src/components/BaseDatePicker.vue +155 -1
  21. package/src/components/BaseDropdown.stories.js +25 -0
  22. package/src/components/BaseDropdown.vue +2 -2
  23. package/src/components/BaseModalSide.stories.js +1 -3
  24. package/src/components/BaseModalSide.vue +5 -5
  25. package/src/components/BaseTagAutocomplete.stories.js +46 -1
  26. package/src/components/BaseTagAutocomplete.vue +184 -253
  27. package/src/components/BaseTagAutocompleteFetch.stories.js +4 -4
  28. package/src/components/BaseTagAutocompleteFetch.vue +10 -5
  29. package/src/composables/clickOutside.ts +13 -8
  30. package/src/index.ts +3 -1
  31. package/src/assets/pikaday.css +0 -134
@@ -0,0 +1,344 @@
1
+ <template>
2
+ <div class="relative w-full overflow-hidden">
3
+ <div
4
+ ref="dropdown"
5
+ data-scroll-lock-scrollable
6
+ class="max-h-[214px] w-full overflow-y-auto"
7
+ >
8
+ <!-- Slot empty -->
9
+ <slot v-if="options.length == 0" name="empty">
10
+ <div
11
+ class="flex items-center justify-center px-5 py-10 text-center text-slate-600"
12
+ >
13
+ {{ $t('sui.nothing_found') }}
14
+ </div>
15
+ </slot>
16
+
17
+ <!-- Option list -->
18
+ <ul v-else :class="dropdownClass">
19
+ <li
20
+ v-for="(option, index) in options"
21
+ :key="option.value"
22
+ ref="optionRefs"
23
+ class="block"
24
+ >
25
+ <button
26
+ class="block w-full cursor-pointer select-none appearance-none border-none text-left focus:outline-none"
27
+ type="button"
28
+ tabindex="-1"
29
+ @click="onSelect(option)"
30
+ @mouseenter="onOptionMouseEnter(index)"
31
+ @mousemove="onOptionMouseMove(index)"
32
+ >
33
+ <slot
34
+ name="option"
35
+ :option="option.option"
36
+ :selected="isSelected(option)"
37
+ :active="focusOption && focusOption.value == option.value"
38
+ >
39
+ <div
40
+ class="flex items-center rounded px-[0.75em] py-[0.5em]"
41
+ :class="[optionClass(option), optionSizeClass]"
42
+ >
43
+ <div class="grow">
44
+ {{ option.label }}
45
+ </div>
46
+ <div class="shrink-0">
47
+ <BaseIcon
48
+ v-if="isSelected(option)"
49
+ icon="heroicons:check-20-solid"
50
+ :class="optionIconClass"
51
+ ></BaseIcon>
52
+ </div>
53
+ </div>
54
+ </slot>
55
+ </button>
56
+ </li>
57
+ </ul>
58
+
59
+ <!-- Loading bottom -->
60
+ <!-- This component should always take the same amount of space whether it's visible or not -->
61
+ <!-- This is to prevent infinite scroll jumps -->
62
+ <div
63
+ :class="[loadingBottom ? 'opacity-100' : 'opacity-0']"
64
+ class="relative py-3 text-center"
65
+ >
66
+ <div
67
+ class="absolute inset-0 h-full w-full bg-gradient-to-b from-transparent to-white"
68
+ ></div>
69
+ <BaseSpinnerSmall
70
+ class="mx-auto h-7 w-7 text-slate-300"
71
+ ></BaseSpinnerSmall>
72
+ </div>
73
+ </div>
74
+
75
+ <div ref="footer">
76
+ <div v-if="$slots.footer" class="bg-white">
77
+ <slot :options="options" name="footer" />
78
+ </div>
79
+ </div>
80
+
81
+ <div
82
+ v-if="loading"
83
+ class="absolute inset-0 h-full w-full space-y-1 bg-white p-2"
84
+ >
85
+ <div class="space-y-1">
86
+ <BaseSkeleton class="h-7 w-full" delay="0ms"></BaseSkeleton>
87
+ <BaseSkeleton class="h-7 w-full opacity-70" delay="50ms"></BaseSkeleton>
88
+ <BaseSkeleton
89
+ class="h-7 w-full opacity-30"
90
+ delay="100ms"
91
+ ></BaseSkeleton>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </template>
96
+
97
+ <script lang="ts" setup>
98
+ import { Ref, PropType } from 'vue';
99
+ import { useInfiniteScroll } from '@vueuse/core';
100
+ import { NormalizedOption } from '@/types';
101
+ import { isArray, isObject, throttle } from 'lodash';
102
+ import BaseSkeleton from './BaseSkeleton.vue';
103
+ import { BaseIcon } from '.';
104
+ import BaseSpinnerSmall from '../svg/BaseSpinnerSmall.vue';
105
+
106
+ const props = defineProps({
107
+ selected: {
108
+ type: [Array, Object, null, undefined] as PropType<
109
+ NormalizedOption[] | NormalizedOption | null | undefined
110
+ >,
111
+ default: undefined,
112
+ },
113
+ options: {
114
+ type: Array as PropType<NormalizedOption[]>,
115
+ default() {
116
+ return [];
117
+ },
118
+ },
119
+ keywords: {
120
+ type: String,
121
+ default: '',
122
+ },
123
+ loading: {
124
+ type: Boolean,
125
+ default: false,
126
+ },
127
+ loadingBottom: {
128
+ type: Boolean,
129
+ default: false,
130
+ },
131
+ size: {
132
+ type: String as PropType<'xs' | 'sm' | 'base'>,
133
+ default: 'base',
134
+ },
135
+ dropdownClass: {
136
+ type: String,
137
+ default: '',
138
+ },
139
+ });
140
+
141
+ const emit = defineEmits(['scrollBottom', 'select']);
142
+
143
+ const dropdown = ref(null) as Ref<HTMLDivElement | null>;
144
+ const optionRefs = ref([]) as Ref<HTMLElement[]>;
145
+
146
+ let mouseIsMoving = false;
147
+
148
+ // Focus
149
+
150
+ const focusIndex = ref(0);
151
+
152
+ const focusOption = computed(() => {
153
+ return (
154
+ props.options[Math.min(focusIndex.value, props.options.length - 1)] ?? null
155
+ );
156
+ });
157
+
158
+ // Selecting
159
+
160
+ function onSelect(option: NormalizedOption) {
161
+ emit('select', option);
162
+ }
163
+
164
+ function isSelected(option: NormalizedOption): boolean {
165
+ if (isArray(props.selected)) {
166
+ return props.selected.some((modelValue) => {
167
+ return modelValue.value === option.value;
168
+ });
169
+ }
170
+
171
+ if (isObject(props.selected)) {
172
+ return props.selected.value == option.value;
173
+ }
174
+
175
+ return false;
176
+ }
177
+
178
+ // Arrow actions
179
+
180
+ window.addEventListener('keydown', onKeyDown);
181
+
182
+ onBeforeUnmount(() => {
183
+ window.removeEventListener('keydown', onKeyDown);
184
+ });
185
+
186
+ function onKeyDown(event: KeyboardEvent) {
187
+ const key = event.key;
188
+
189
+ mouseIsMoving = false;
190
+
191
+ if (props.loading) {
192
+ return;
193
+ }
194
+
195
+ if (key === 'ArrowDown') {
196
+ if (focusIndex.value < props.options.length - 1) {
197
+ focusIndex.value++;
198
+ } else {
199
+ focusIndex.value = 0;
200
+ }
201
+ scrollToFocus();
202
+ return;
203
+ }
204
+
205
+ if (key === 'ArrowUp') {
206
+ if (focusIndex.value > 0) {
207
+ focusIndex.value--;
208
+ } else {
209
+ focusIndex.value = Math.max(0, props.options.length - 1);
210
+ }
211
+ scrollToFocus();
212
+ return;
213
+ }
214
+
215
+ if (key === 'Enter') {
216
+ event.preventDefault();
217
+ if (focusOption.value) {
218
+ onSelect(focusOption.value);
219
+ }
220
+ return;
221
+ }
222
+ }
223
+
224
+ // Infinite scroll
225
+
226
+ onMounted(() => {
227
+ useInfiniteScroll(
228
+ dropdown.value,
229
+ () => {
230
+ emit('scrollBottom');
231
+ },
232
+ { distance: 60 }
233
+ );
234
+ });
235
+
236
+ function scrollToFocus() {
237
+ if (!optionRefs.value) {
238
+ return;
239
+ }
240
+
241
+ const option = optionRefs.value[focusIndex.value] ?? null;
242
+
243
+ if (!option) {
244
+ return;
245
+ }
246
+
247
+ option.scrollIntoView({
248
+ block: 'center',
249
+ inline: 'center',
250
+ });
251
+ }
252
+
253
+ // Validate focus index
254
+
255
+ watch(
256
+ () => props.options,
257
+ () => {
258
+ focusIndex.value = Math.max(
259
+ 0,
260
+ Math.min(focusIndex.value, props.options.length - 1)
261
+ );
262
+ },
263
+ { immediate: true }
264
+ );
265
+
266
+ // Update the focusIndex when the selected value changes
267
+
268
+ watch(
269
+ () => props.selected,
270
+ () => {
271
+ if (
272
+ props.selected &&
273
+ isObject(props.selected) &&
274
+ !isArray(props.selected)
275
+ ) {
276
+ const selected = props.selected as NormalizedOption;
277
+ const index = props.options.findIndex(
278
+ (option) => option.value === selected.value
279
+ );
280
+ if (index >= 0) {
281
+ focusIndex.value = index;
282
+ }
283
+ } else {
284
+ focusIndex.value = 0;
285
+ }
286
+ },
287
+ { immediate: true }
288
+ );
289
+
290
+ // Scroll top when the keywords change
291
+
292
+ watch(
293
+ () => props.keywords,
294
+ () => {
295
+ if (dropdown.value) {
296
+ dropdown.value.scrollTop = 0;
297
+ }
298
+ // Reset the focusIndex
299
+ focusIndex.value = 0;
300
+ }
301
+ );
302
+
303
+ const onOptionMouseEnter = (index: number) => {
304
+ if (mouseIsMoving) {
305
+ focusIndex.value = index;
306
+ }
307
+ };
308
+
309
+ const onOptionMouseMove = throttle((index: number) => {
310
+ mouseIsMoving = true;
311
+ }, 10);
312
+
313
+ // Classes
314
+
315
+ const optionClass = (option: NormalizedOption) => {
316
+ const focus = focusOption.value && focusOption.value.value == option.value;
317
+
318
+ if (focus) {
319
+ return 'bg-slate-200';
320
+ }
321
+
322
+ return 'bg-white';
323
+ };
324
+
325
+ const optionSizeClass = computed(() => {
326
+ if (props.size == 'xs') {
327
+ return 'text-xs';
328
+ }
329
+ if (props.size == 'sm') {
330
+ return 'text-sm';
331
+ }
332
+ return 'text-sm';
333
+ });
334
+
335
+ const optionIconClass = computed(() => {
336
+ if (props.size == 'xs') {
337
+ return 'w-4 h-4';
338
+ }
339
+ if (props.size == 'sm') {
340
+ return 'w-5 h-5';
341
+ }
342
+ return 'w-5 h-5';
343
+ });
344
+ </script>
@@ -2,6 +2,7 @@
2
2
  <BaseAutocomplete
3
3
  ref="input"
4
4
  :loading="showLoading && page == 1"
5
+ :loading-bottom="showLoading && page > 1"
5
6
  :model-value="modelValue"
6
7
  :disabled="disabled"
7
8
  :name="name"
@@ -46,7 +47,7 @@
46
47
 
47
48
  <script lang="ts" setup>
48
49
  import { config } from '@/index';
49
- import { debounce } from 'lodash';
50
+ import { debounce, throttle } from 'lodash';
50
51
  import { PropType, Ref } from 'vue';
51
52
  import { Option } from '@/types';
52
53
  import BaseAutocomplete from './BaseAutocomplete.vue';
@@ -161,12 +162,16 @@ const onClear = () => {
161
162
  emit('clear');
162
163
  };
163
164
 
164
- const scrollBottom = () => {
165
+ const scrollBottom = throttle(() => {
166
+ if (fetching.value) {
167
+ return;
168
+ }
169
+
165
170
  if (!reachedEnd.value) {
166
171
  page.value++;
167
172
  search();
168
173
  }
169
- };
174
+ }, 500);
170
175
 
171
176
  function search() {
172
177
  if (fetching.value) {
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <div class="relative">
2
+ <div
3
+ class="base-date-picker relative"
4
+ :class="{ 'base-date-picker--inline': inline }"
5
+ >
3
6
  <div
4
7
  class="pointer-events-none absolute top-0 left-0 flex h-10 items-center justify-center pl-2.5"
5
8
  >
@@ -205,3 +208,154 @@ function arrayRotate(arr: any[], reverse = false): any[] {
205
208
  return arr;
206
209
  }
207
210
  </script>
211
+
212
+ <style lang="postcss">
213
+ @import 'pikaday/css/pikaday.css';
214
+
215
+ .base-date-picker--inline {
216
+ .pikaday-white.pika-single {
217
+ box-shadow: none;
218
+ border: none;
219
+ padding: 0;
220
+ }
221
+ .pika-lendar {
222
+ margin: 0;
223
+ margin-top: 0.25rem;
224
+ }
225
+ }
226
+
227
+ .pikaday-white {
228
+ --backgroundColor: #ffffff;
229
+ --textColor: #718096;
230
+ --currentDateTextColor: #3182ce;
231
+ --selectedDateBackgroundColor: #3182ce;
232
+ --selectedDateTextColor: #ffffff;
233
+
234
+ --labelTextColor: #4a5568; /* eg. May 2020 */
235
+ --weekDaysTextColor: #a0aec0; /* eg. Mo Tu We ....*/
236
+
237
+ font-family: inherit;
238
+ background-color: var(--backgroundColor);
239
+ padding: 0.5rem;
240
+ z-index: 60;
241
+ margin: 6px 0 0 0;
242
+
243
+ @apply shadow;
244
+ @apply rounded-lg;
245
+ }
246
+
247
+ .pikaday-white .pika-title {
248
+ width: 100%;
249
+ text-align: center;
250
+ display: flex;
251
+ justify-content: flex-start;
252
+ margin-bottom: 5px;
253
+ }
254
+
255
+ /* Next/Previous */
256
+ .pikaday-white .pika-prev,
257
+ .pikaday-white .pika-next {
258
+ position: absolute;
259
+ outline: none;
260
+ padding: 0;
261
+ width: 28px;
262
+ height: 28px;
263
+ top: -1px;
264
+ display: inline-block;
265
+ margin-top: 0;
266
+ cursor: pointer;
267
+ /* hide text using text-indent trick, using width value (it's enough) */
268
+ text-indent: -9999px;
269
+ white-space: nowrap;
270
+ overflow: hidden;
271
+ background-color: transparent;
272
+ background-position: center center;
273
+ background-repeat: no-repeat;
274
+ opacity: 0.8;
275
+ }
276
+ .pikaday-white .pika-prev:hover,
277
+ .pikaday-white .pika-next:hover {
278
+ opacity: 1;
279
+ }
280
+ .pikaday-white .pika-prev {
281
+ right: 30px;
282
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2364748b'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15 19l-7-7 7-7'%3E%3C/path%3E%3C/svg%3E");
283
+ }
284
+ .pikaday-white .pika-next {
285
+ right: 2px;
286
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2364748b'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5l7 7-7 7'%3E%3C/path%3E%3C/svg%3E");
287
+ }
288
+ .pika-prev.is-disabled,
289
+ .pika-next.is-disabled {
290
+ cursor: default;
291
+ opacity: 0.2;
292
+ }
293
+
294
+ .pikaday-white .pika-label {
295
+ @apply mr-1.5 rounded border border-slate-200 py-1 px-2 text-[15px] font-normal leading-none;
296
+ }
297
+
298
+ /* Show Month & Year select */
299
+ .pikaday-white .pika-label {
300
+ position: relative; /* add this */
301
+ /* some additional code */
302
+ }
303
+
304
+ .pikaday-white .pika-select-month,
305
+ .pikaday-white .pika-select-year {
306
+ /*display: none;*/
307
+ width: 100%;
308
+ cursor: pointer;
309
+ position: absolute;
310
+ z-index: 9998;
311
+ margin: 0;
312
+ left: 0;
313
+ top: 0;
314
+ opacity: 0;
315
+ padding: 0px;
316
+ }
317
+
318
+ .pikaday-white table {
319
+ width: 100%;
320
+ border-collapse: collapse;
321
+ }
322
+
323
+ .pikaday-white table th {
324
+ width: 2.5em;
325
+ height: 2.5em;
326
+ font-weight: normal;
327
+ color: var(--weekDaysTextColor);
328
+ font-size: 13px;
329
+ text-align: center;
330
+ }
331
+ .pikaday-white table th abbr {
332
+ text-decoration: none;
333
+ }
334
+ .pikaday-white table td {
335
+ padding: 1px;
336
+ }
337
+ .pikaday-white table td button {
338
+ width: 2.5em;
339
+ height: 2.5em;
340
+ text-align: center;
341
+ @apply rounded-full;
342
+ font-size: 13px;
343
+ background-color: var(--backgroundColor);
344
+ }
345
+ .pikaday-white table td button:hover {
346
+ @apply bg-slate-100;
347
+ @apply text-slate-900;
348
+ }
349
+ .pikaday-white table td.is-today button {
350
+ color: var(--currentDateTextColor);
351
+ }
352
+ .pikaday-white table td.is-selected button {
353
+ @apply bg-primary-500;
354
+ @apply text-white;
355
+ @apply font-normal;
356
+ }
357
+
358
+ .pikaday-white table td button {
359
+ color: var(--textColor);
360
+ }
361
+ </style>
@@ -2,6 +2,7 @@ import BaseBadge from './BaseBadge.vue';
2
2
  import BaseAutocomplete from './BaseAutocomplete.vue';
3
3
  import BaseModalCenter from './BaseModalCenter.vue';
4
4
  import BaseDropdown from './BaseDropdown.vue';
5
+ import BaseDatePicker from './BaseDatePicker.vue';
5
6
  import { options } from '../../.storybook/utils';
6
7
 
7
8
  const items = [];
@@ -151,3 +152,27 @@ export const ModalWithScroll = (args) => ({
151
152
  </BaseModalCenter>
152
153
  `,
153
154
  });
155
+
156
+ export const WithDatePicker = (args) => ({
157
+ components: { BaseDropdown, BaseDatePicker },
158
+ setup() {
159
+ const date = ref('2022-01-01');
160
+ return { args, items, date };
161
+ },
162
+ template: `
163
+ <BaseDropdown v-bind="args">
164
+ <template #button>
165
+ <div class="btn btn-primary">Click me</div>
166
+ </template>
167
+ <template #dropdown>
168
+ <div class="bg-white shadow-lg rounded border p-2 w-[260px]">
169
+ <BaseDatePicker v-model="date" inline></BaseDatePicker>
170
+ </div>
171
+ </template>
172
+ </BaseDropdown>
173
+ `,
174
+ });
175
+
176
+ WithDatePicker.args = {
177
+ placement: 'bottom-start',
178
+ };
@@ -137,8 +137,8 @@ function deactivate() {
137
137
 
138
138
  useClickOutside(
139
139
  dropdown,
140
- (outside: boolean) => {
141
- if (outside && showDropdown.value) {
140
+ () => {
141
+ if (showDropdown.value) {
142
142
  close();
143
143
  }
144
144
  },
@@ -5,9 +5,7 @@ import BaseAvatar from './BaseAvatar.vue';
5
5
  export default {
6
6
  title: 'Components/BaseModalSide',
7
7
  component: BaseModalSide,
8
- args: {
9
- position: 'bottom-right',
10
- },
8
+ args: {},
11
9
  };
12
10
 
13
11
  const Template = (args) => ({
@@ -96,14 +96,14 @@ const props = defineProps({
96
96
 
97
97
  const emit = defineEmits(['update:modelValue']);
98
98
 
99
- const modal = useModal(
100
- computed(() => props.modelValue),
101
- emit
102
- );
103
-
104
99
  const breakpoints = useBreakpoints();
105
100
 
106
101
  const realMaxWidth = computed((): string => {
107
102
  return breakpoints.greater('sm').value ? props.maxWidth : '100%';
108
103
  });
104
+
105
+ const modal = useModal(
106
+ computed(() => props.modelValue),
107
+ emit
108
+ );
109
109
  </script>
@@ -3,10 +3,25 @@ import BaseTagAutocomplete from './BaseTagAutocomplete.vue';
3
3
  import ShowValue from '@/../.storybook/components/ShowValue.vue';
4
4
  import BaseAppNotifications from './BaseAppNotifications.vue';
5
5
 
6
+ const sizes = ['xs', 'sm', 'base'];
7
+
6
8
  export default {
7
9
  title: 'Form/BaseTagAutocomplete',
8
10
  component: BaseTagAutocomplete,
9
- argTypes: {},
11
+ argTypes: {
12
+ size: {
13
+ control: {
14
+ type: 'select',
15
+ options: sizes,
16
+ },
17
+ },
18
+ dropdownShow: {
19
+ control: {
20
+ type: 'select',
21
+ options: ['always', 'focus'],
22
+ },
23
+ },
24
+ },
10
25
  args: {
11
26
  labelKey: 'label',
12
27
  valueKey: 'value',
@@ -30,6 +45,17 @@ const Template = (args) => ({
30
45
  export const Demo = Template.bind({});
31
46
  Demo.args = {};
32
47
 
48
+ export const AlwaysShowDropdown = Template.bind({});
49
+ AlwaysShowDropdown.args = {
50
+ inline: true,
51
+ dropdownShow: 'always',
52
+ };
53
+
54
+ export const NoFocus = Template.bind({});
55
+ NoFocus.args = {
56
+ visibleFocus: false,
57
+ };
58
+
33
59
  export const Disabled = Template.bind({});
34
60
  Disabled.args = {
35
61
  options: options,
@@ -42,6 +68,25 @@ Loading.args = {
42
68
  loading: true,
43
69
  };
44
70
 
71
+ export const Inline = Template.bind({});
72
+ Inline.args = {
73
+ inline: true,
74
+ };
75
+
76
+ export const Sizes = (args) => ({
77
+ components: { BaseTagAutocomplete },
78
+ setup() {
79
+ const value = ref([]);
80
+ return { args, sizes, value };
81
+ },
82
+ template: `
83
+ <div v-for="size in sizes" class="mb-1">
84
+ <p class="text-xs text-slate-600 leading-tight">{{ size }}</p>
85
+ <BaseTagAutocomplete v-model="value" v-bind="args" :size="size"></BaseTagAutocomplete>
86
+ </div>
87
+ `,
88
+ });
89
+
45
90
  export const SlotOption = (args) => ({
46
91
  components: { BaseTagAutocomplete, ShowValue, BaseAppNotifications },
47
92
  setup() {