sprintify-ui 0.6.34 → 0.6.35
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 +15345 -15302
- package/dist/style.css +1 -1
- package/dist/tailwindcss/button.js +2 -2
- package/dist/tailwindcss/theme.js +14 -7
- package/dist/types/src/components/BaseButtonGroup.vue.d.ts +9 -0
- package/dist/types/src/components/BaseDataIterator.vue.d.ts +3 -3
- package/dist/types/src/components/BaseDataIteratorSectionButton.vue.d.ts +2 -2
- package/dist/types/src/components/BaseDataIteratorSectionColumns.vue.d.ts +8 -8
- package/dist/types/src/components/BaseDataTable.vue.d.ts +3 -3
- package/dist/types/src/components/BaseDataTableRowAction.vue.d.ts +4 -3
- package/dist/types/src/components/BaseDatePicker.vue.d.ts +10 -0
- package/dist/types/src/components/BaseDateSelect.vue.d.ts +9 -0
- package/dist/types/src/components/BaseRichText.vue.d.ts +9 -0
- package/dist/types/src/components/BaseTable.vue.d.ts +3 -3
- package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +11 -2
- package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +3 -2
- package/dist/types/src/stories/PageInputSizes.vue.d.ts +2 -0
- package/dist/types/src/utils/slots.d.ts +1 -0
- package/package.json +1 -1
- package/src/assets/base-rich-text.css +148 -26
- package/src/components/BaseButton.vue +3 -2
- package/src/components/BaseButtonGroup.vue +37 -9
- package/src/components/BaseColor.vue +29 -31
- package/src/components/BaseDataIterator.stories.js +8 -1
- package/src/components/BaseDataIterator.vue +36 -76
- package/src/components/BaseDataIteratorSectionButton.vue +8 -19
- package/src/components/BaseDataTable.vue +23 -16
- package/src/components/BaseDataTableRowAction.vue +2 -1
- package/src/components/BaseDatePicker.stories.js +23 -0
- package/src/components/BaseDatePicker.vue +65 -8
- package/src/components/BaseDateSelect.stories.js +25 -1
- package/src/components/BaseDateSelect.vue +80 -101
- package/src/components/BaseDropdownAutocomplete.stories.js +30 -15
- package/src/components/BaseHasMany.stories.js +22 -1
- package/src/components/BaseInput.stories.js +1 -1
- package/src/components/BaseInput.vue +4 -3
- package/src/components/BaseMediaPicturesItem.vue +2 -2
- package/src/components/BaseRichText.stories.js +6 -0
- package/src/components/BaseRichText.vue +12 -2
- package/src/components/BaseSelect.vue +5 -0
- package/src/components/BaseTable.vue +2 -1
- package/src/components/BaseTagAutocomplete.stories.js +1 -1
- package/src/components/BaseTagAutocomplete.vue +143 -88
- package/src/components/BaseTagAutocompleteFetch.stories.js +22 -1
- package/src/components/BaseTextareaAutoresize.vue +7 -7
- package/src/composables/inputSize.ts +5 -1
- package/src/stories/InputSizes.stories.js +22 -0
- package/src/stories/PageInputSizes.vue +205 -0
- package/src/utils/slots.ts +13 -0
|
@@ -14,101 +14,55 @@
|
|
|
14
14
|
<div
|
|
15
15
|
class="flex space-x-2 empty:mb-0"
|
|
16
16
|
:class="{
|
|
17
|
-
'mb-2.5': size == 'sm',
|
|
18
|
-
'mb-4': size == 'md',
|
|
17
|
+
'mb-2.5': sizeInternal.size.value == 'sm',
|
|
18
|
+
'mb-4': sizeInternal.size.value == 'md',
|
|
19
19
|
}"
|
|
20
20
|
>
|
|
21
21
|
<!-- Search bar -->
|
|
22
22
|
<div
|
|
23
23
|
v-if="searchable"
|
|
24
|
-
class="grow"
|
|
24
|
+
class="grow min-w-0"
|
|
25
25
|
>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
:class="{
|
|
39
|
-
'h-5 w-5': size == 'sm',
|
|
40
|
-
'h-6 w-6': size == 'md',
|
|
41
|
-
}"
|
|
42
|
-
icon="heroicons:magnifying-glass"
|
|
43
|
-
/>
|
|
44
|
-
</div>
|
|
45
|
-
<input
|
|
46
|
-
ref="searchInput"
|
|
47
|
-
v-model="searchQuery"
|
|
48
|
-
type="text"
|
|
49
|
-
class="w-full h-full py-0 overflow-hidden rounded-md border border-slate-300 bg-white shadow-sm placeholder:font-light placeholder:text-sm focus:ring-blue-300 focus:ring-4"
|
|
50
|
-
:class="{
|
|
51
|
-
'pl-9 pr-8': size == 'sm',
|
|
52
|
-
'pl-10 pr-9': size == 'md',
|
|
53
|
-
}"
|
|
54
|
-
:placeholder="t('sui.autocomplete_placeholder')"
|
|
55
|
-
@input="onSearch"
|
|
56
|
-
>
|
|
57
|
-
<div
|
|
58
|
-
v-if="searchQuery"
|
|
59
|
-
class="absolute right-0 top-0 flex h-full items-center justify-center p-1"
|
|
60
|
-
>
|
|
61
|
-
<button
|
|
62
|
-
type="button"
|
|
63
|
-
class="flex appearance-none items-center rounded p-1 hover:bg-slate-100"
|
|
64
|
-
@click="searchQuery = ''; onSearch('');"
|
|
65
|
-
>
|
|
66
|
-
<BaseIcon
|
|
67
|
-
class="text-slate-500"
|
|
68
|
-
:class="{
|
|
69
|
-
'h-5 w-5': size == 'sm',
|
|
70
|
-
'h-6 w-6': size == 'md',
|
|
71
|
-
}"
|
|
72
|
-
icon="heroicons:x-mark"
|
|
73
|
-
/>
|
|
74
|
-
</button>
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
26
|
+
<BaseInput
|
|
27
|
+
v-model="searchQuery"
|
|
28
|
+
:placeholder="t('sui.autocomplete_placeholder')"
|
|
29
|
+
:size="sizeInternal.size.value"
|
|
30
|
+
class="w-full"
|
|
31
|
+
icon-left="heroicons:magnifying-glass"
|
|
32
|
+
:icon-right="searchQuery ? 'heroicons:x-mark' : undefined"
|
|
33
|
+
@icon-right-click="searchQuery = ''; onSearch('');"
|
|
34
|
+
@update:model-value="onSearch"
|
|
35
|
+
@focus="searchInputFocus = true"
|
|
36
|
+
@blur="searchInputFocus = false"
|
|
37
|
+
/>
|
|
77
38
|
</div>
|
|
78
39
|
|
|
79
40
|
<template v-if="compactLayout">
|
|
80
|
-
<
|
|
41
|
+
<BaseDataIteratorSectionButton
|
|
81
42
|
v-for="(section, i) in sectionsInternal"
|
|
82
43
|
:key="section.name"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@open="openSection(i)"
|
|
88
|
-
/>
|
|
89
|
-
</template>
|
|
44
|
+
:section="section"
|
|
45
|
+
:size="sizeInternal.size.value"
|
|
46
|
+
@open="openSection(i)"
|
|
47
|
+
/>
|
|
90
48
|
</template>
|
|
91
49
|
|
|
92
50
|
<!-- Menu -->
|
|
93
51
|
<BaseMenu
|
|
94
52
|
v-if="actions && actions.length"
|
|
95
53
|
tw-menu="w-52"
|
|
96
|
-
:size="size == 'sm' ? 'xs' : 'sm'"
|
|
54
|
+
:size="sizeInternal.size.value == 'sm' ? 'xs' : 'sm'"
|
|
97
55
|
:items="actions"
|
|
98
56
|
>
|
|
99
57
|
<template #button="{ open }">
|
|
100
|
-
<
|
|
101
|
-
|
|
58
|
+
<BaseButton
|
|
59
|
+
as="div"
|
|
60
|
+
:size="sizeInternal.size.value"
|
|
102
61
|
:class="[
|
|
103
|
-
open ? '
|
|
104
|
-
{
|
|
105
|
-
'h-9 w-9': size == 'sm',
|
|
106
|
-
'h-11 w-11': size == 'md',
|
|
107
|
-
}
|
|
62
|
+
open ? 'input-focus' : '',
|
|
108
63
|
]"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
</div>
|
|
64
|
+
icon="heroicons-solid:dots-vertical"
|
|
65
|
+
/>
|
|
112
66
|
</template>
|
|
113
67
|
</BaseMenu>
|
|
114
68
|
</div>
|
|
@@ -211,6 +165,9 @@
|
|
|
211
165
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
212
166
|
import { t } from '@/i18n';
|
|
213
167
|
type Direction = 'asc' | 'desc';
|
|
168
|
+
import { Size } from '@/utils/sizes';
|
|
169
|
+
import BaseInput from './BaseInput.vue';
|
|
170
|
+
import { useInputSize } from '@/composables/inputSize';
|
|
214
171
|
|
|
215
172
|
const DEFAULT_QUERY = {
|
|
216
173
|
page: 1,
|
|
@@ -234,6 +191,7 @@ import {
|
|
|
234
191
|
import { ActionItem } from '@/types';
|
|
235
192
|
|
|
236
193
|
import BaseMenu from './BaseMenu.vue';
|
|
194
|
+
import BaseButton from './BaseButton.vue';
|
|
237
195
|
import BasePagination from './BasePagination.vue';
|
|
238
196
|
import { config } from '@/index';
|
|
239
197
|
import { useMutationObserver, useResizeObserver } from '@vueuse/core';
|
|
@@ -309,7 +267,7 @@ const props = defineProps({
|
|
|
309
267
|
*/
|
|
310
268
|
size: {
|
|
311
269
|
default: 'md',
|
|
312
|
-
type: String as PropType<
|
|
270
|
+
type: String as PropType<Size>,
|
|
313
271
|
},
|
|
314
272
|
|
|
315
273
|
/**
|
|
@@ -343,12 +301,14 @@ const emit = defineEmits([
|
|
|
343
301
|
]);
|
|
344
302
|
|
|
345
303
|
const dataIteratorNode = ref<null | HTMLElement>(null);
|
|
346
|
-
const
|
|
304
|
+
const searchInputFocus = ref(false);
|
|
347
305
|
|
|
348
306
|
const route = useRoute();
|
|
349
307
|
const router = useRouter();
|
|
350
308
|
const routeName = route.name;
|
|
351
309
|
|
|
310
|
+
const sizeInternal = useInputSize(props.size);
|
|
311
|
+
|
|
352
312
|
let willUnmount = false;
|
|
353
313
|
|
|
354
314
|
onBeforeUnmount(() => {
|
|
@@ -595,7 +555,7 @@ function onRouteChange() {
|
|
|
595
555
|
query.value = newQuery;
|
|
596
556
|
|
|
597
557
|
// Update search input if not in focus
|
|
598
|
-
if (
|
|
558
|
+
if (!searchInputFocus.value) {
|
|
599
559
|
updateSearchInput();
|
|
600
560
|
}
|
|
601
561
|
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
:
|
|
5
|
-
width > 600 ? 'px-4' : 'px-3.5',
|
|
6
|
-
{
|
|
7
|
-
'h-9': size == 'sm',
|
|
8
|
-
'h-11': size == 'md',
|
|
9
|
-
}]"
|
|
2
|
+
<BaseButton
|
|
3
|
+
:icon="section.icon"
|
|
4
|
+
:size="size"
|
|
10
5
|
type="button"
|
|
11
6
|
@click="open()"
|
|
12
7
|
>
|
|
13
|
-
<
|
|
14
|
-
class="h-5 w-5 text-slate-500"
|
|
15
|
-
:icon="section.icon"
|
|
16
|
-
/>
|
|
17
|
-
<span
|
|
18
|
-
v-if="section.title && width > 600"
|
|
19
|
-
class="ml-2 whitespace-pre text-sm"
|
|
20
|
-
>
|
|
8
|
+
<span v-if="section.title && width > 600">
|
|
21
9
|
{{ section.title }}
|
|
22
10
|
</span>
|
|
23
11
|
<BaseBadge
|
|
@@ -28,17 +16,18 @@
|
|
|
28
16
|
>
|
|
29
17
|
{{ section.count }}
|
|
30
18
|
</BaseBadge>
|
|
31
|
-
</
|
|
19
|
+
</BaseButton>
|
|
32
20
|
</template>
|
|
33
21
|
|
|
34
22
|
<script lang="ts" setup>
|
|
35
23
|
import { DataIteratorSection } from '@/types';
|
|
36
|
-
import
|
|
24
|
+
import BaseButton from './BaseButton.vue';
|
|
37
25
|
import BaseBadge from './BaseBadge.vue';
|
|
26
|
+
import { Size } from '@/utils/sizes';
|
|
38
27
|
|
|
39
28
|
defineProps<{
|
|
40
29
|
section: DataIteratorSection;
|
|
41
|
-
size:
|
|
30
|
+
size: Size;
|
|
42
31
|
}>();
|
|
43
32
|
|
|
44
33
|
const emit = defineEmits<{
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
:actions="actions"
|
|
9
9
|
:history-mode="historyMode"
|
|
10
10
|
:layout="layout"
|
|
11
|
-
:size="size"
|
|
11
|
+
:size="sizeInternal.size.value"
|
|
12
12
|
:sections="sectionsInternal"
|
|
13
13
|
:scroll-top-on-fetch="maxHeight ? false : scrollTopOnFetch"
|
|
14
14
|
@fetch="onFetch"
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
:sort-direction="sortDirection"
|
|
88
88
|
:max-height="maxHeight"
|
|
89
89
|
:visible-columns="visibleColumns"
|
|
90
|
-
:size="size"
|
|
90
|
+
:size="sizeInternal.size.value"
|
|
91
91
|
@update:checked-rows="onCheckedRowsUpdate"
|
|
92
92
|
@sort="onSortChange"
|
|
93
93
|
@cell-click="onCellClick"
|
|
@@ -112,27 +112,19 @@
|
|
|
112
112
|
<BaseDataTableRowAction
|
|
113
113
|
:row="row"
|
|
114
114
|
:row-action="rowAction"
|
|
115
|
-
:size="size"
|
|
115
|
+
:size="sizeInternal.size.value"
|
|
116
116
|
/>
|
|
117
117
|
</template>
|
|
118
118
|
<BaseMenu
|
|
119
119
|
v-if="showRowActionMenu"
|
|
120
120
|
:items="rowActionMenuItems(row)"
|
|
121
|
-
:size="
|
|
122
|
-
:tw-button="[
|
|
123
|
-
'btn flex p-0 items-center justify-center',
|
|
124
|
-
{
|
|
125
|
-
'btn-xs py-1 px-2': size == 'sm',
|
|
126
|
-
'btn-sm p-2': size == 'md'
|
|
127
|
-
}
|
|
128
|
-
]"
|
|
121
|
+
:size="menuSize"
|
|
129
122
|
>
|
|
130
123
|
<template #button>
|
|
131
|
-
<
|
|
124
|
+
<BaseButton
|
|
125
|
+
as="div"
|
|
126
|
+
:size="menuSize"
|
|
132
127
|
icon="heroicons-solid:dots-vertical"
|
|
133
|
-
:class="{
|
|
134
|
-
'h-3 w-3': size === 'sm',
|
|
135
|
-
}"
|
|
136
128
|
/>
|
|
137
129
|
</template>
|
|
138
130
|
</BaseMenu>
|
|
@@ -261,6 +253,9 @@ import { RouteLocationRaw } from 'vue-router';
|
|
|
261
253
|
import BaseMenu from './BaseMenu.vue';
|
|
262
254
|
import BaseDataTableRowAction from './BaseDataTableRowAction.vue';
|
|
263
255
|
import { ActionItem } from '@/types';
|
|
256
|
+
import { Size } from '@/utils/sizes';
|
|
257
|
+
import { useInputSize } from '@/composables/inputSize';
|
|
258
|
+
import BaseButton from './BaseButton.vue';
|
|
264
259
|
|
|
265
260
|
const router = useRouter();
|
|
266
261
|
|
|
@@ -467,7 +462,7 @@ const props = defineProps({
|
|
|
467
462
|
*/
|
|
468
463
|
size: {
|
|
469
464
|
default: 'md',
|
|
470
|
-
type: String as PropType<
|
|
465
|
+
type: String as PropType<Size>,
|
|
471
466
|
},
|
|
472
467
|
|
|
473
468
|
sections: {
|
|
@@ -494,6 +489,18 @@ const props = defineProps({
|
|
|
494
489
|
},
|
|
495
490
|
});
|
|
496
491
|
|
|
492
|
+
const sizeInternal = useInputSize(props.size);
|
|
493
|
+
|
|
494
|
+
const menuSize = computed(() => {
|
|
495
|
+
if (sizeInternal.size.value == 'md') {
|
|
496
|
+
return 'sm';
|
|
497
|
+
}
|
|
498
|
+
if (sizeInternal.size.value == 'sm') {
|
|
499
|
+
return 'xs';
|
|
500
|
+
}
|
|
501
|
+
return 'xs';
|
|
502
|
+
})
|
|
503
|
+
|
|
497
504
|
const emit = defineEmits([
|
|
498
505
|
'cell-click',
|
|
499
506
|
'delete',
|
|
@@ -41,11 +41,12 @@
|
|
|
41
41
|
<script lang="ts" setup>
|
|
42
42
|
import { CollectionItem, RowAction } from '@/types';
|
|
43
43
|
import { BaseIcon } from '.';
|
|
44
|
+
import { Size } from '@/utils/sizes';
|
|
44
45
|
|
|
45
46
|
withDefaults(defineProps<{
|
|
46
47
|
row: CollectionItem;
|
|
47
48
|
rowAction: RowAction;
|
|
48
|
-
size?:
|
|
49
|
+
size?: Size,
|
|
49
50
|
}>(), {
|
|
50
51
|
size: 'md',
|
|
51
52
|
});
|
|
@@ -3,6 +3,8 @@ import ShowValue from '@/../.storybook/components/ShowValue.vue';
|
|
|
3
3
|
import { DateTime } from 'luxon';
|
|
4
4
|
import { createFieldStory } from '../../.storybook/utils';
|
|
5
5
|
|
|
6
|
+
const sizes = ['xs', 'sm', 'md'];
|
|
7
|
+
|
|
6
8
|
export default {
|
|
7
9
|
title: 'Form/BaseDatePicker',
|
|
8
10
|
component: BaseDatePicker,
|
|
@@ -17,6 +19,10 @@ export default {
|
|
|
17
19
|
control: { type: 'select' },
|
|
18
20
|
options: ['single', 'multiple', 'range', 'time'],
|
|
19
21
|
},
|
|
22
|
+
size: {
|
|
23
|
+
control: { type: 'select' },
|
|
24
|
+
options: sizes,
|
|
25
|
+
}
|
|
20
26
|
},
|
|
21
27
|
};
|
|
22
28
|
|
|
@@ -119,6 +125,23 @@ DateTimeConversion.args = {
|
|
|
119
125
|
modelValue: '2023-01-05T00:00:00Z',
|
|
120
126
|
};
|
|
121
127
|
|
|
128
|
+
const TemplateSizes = (args) => ({
|
|
129
|
+
components: { BaseDatePicker },
|
|
130
|
+
setup() {
|
|
131
|
+
const value = ref(null);
|
|
132
|
+
const sizes = ['xs', 'sm', 'md'];
|
|
133
|
+
return { args, value, sizes };
|
|
134
|
+
},
|
|
135
|
+
template: `
|
|
136
|
+
<div v-for="size in sizes" :key="size" class="mb-4">
|
|
137
|
+
<p class="text-xs text-slate-600 leading-tight mb-1">{{ size }}</p>
|
|
138
|
+
<BaseDatePicker v-model="value" v-bind="args" :size="size" class="w-full"></BaseDatePicker>
|
|
139
|
+
</div>
|
|
140
|
+
`,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
export const Sizes = TemplateSizes.bind({});
|
|
144
|
+
|
|
122
145
|
export const Field = createFieldStory({
|
|
123
146
|
component: BaseDatePicker,
|
|
124
147
|
componentName: 'BaseDatePicker',
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
>
|
|
8
8
|
<div
|
|
9
9
|
v-if="showInput"
|
|
10
|
-
class="
|
|
10
|
+
:class="iconWrapClasses"
|
|
11
11
|
>
|
|
12
12
|
<BaseIcon
|
|
13
|
-
class="
|
|
13
|
+
:class="iconClasses"
|
|
14
14
|
icon="heroicons:calendar"
|
|
15
15
|
/>
|
|
16
16
|
</div>
|
|
@@ -19,21 +19,21 @@
|
|
|
19
19
|
type="text"
|
|
20
20
|
readonly
|
|
21
21
|
:disabled="disabled"
|
|
22
|
-
class="w-full
|
|
23
|
-
:class="
|
|
22
|
+
class="w-full"
|
|
23
|
+
:class="classes"
|
|
24
24
|
:placeholder="t('sui.click_or_select_date')"
|
|
25
25
|
>
|
|
26
26
|
<div
|
|
27
27
|
v-if="modelValueFormatted && !disabled && showInput"
|
|
28
|
-
class="absolute
|
|
28
|
+
class="absolute top-0 right-0 h-full flex p-1"
|
|
29
29
|
>
|
|
30
30
|
<button
|
|
31
31
|
type="button"
|
|
32
|
-
class="flex items-center rounded
|
|
32
|
+
class="flex justify-center items-center rounded hover:bg-slate-100 aspect-1"
|
|
33
33
|
@click="clear()"
|
|
34
34
|
>
|
|
35
35
|
<BaseIcon
|
|
36
|
-
class="
|
|
36
|
+
:class="iconClasses"
|
|
37
37
|
icon="heroicons:x-mark"
|
|
38
38
|
/>
|
|
39
39
|
</button>
|
|
@@ -54,11 +54,14 @@ import { French } from 'flatpickr/dist/l10n/fr';
|
|
|
54
54
|
import { english } from 'flatpickr/dist/l10n/default';
|
|
55
55
|
import { Instance } from 'flatpickr/dist/types/instance';
|
|
56
56
|
import { useI18nStore } from '@/stores/i18n';
|
|
57
|
+
import { twMerge } from 'tailwind-merge';
|
|
58
|
+
import { Size, sizes } from '@/utils/sizes';
|
|
57
59
|
|
|
58
60
|
const props = withDefaults(
|
|
59
61
|
defineProps<{
|
|
60
62
|
modelValue?: string | null | string[];
|
|
61
63
|
required?: boolean;
|
|
64
|
+
size?: Size;
|
|
62
65
|
disabled?: boolean;
|
|
63
66
|
minDate?: string | Date | null;
|
|
64
67
|
maxDate?: string | Date | null;
|
|
@@ -75,6 +78,7 @@ const props = withDefaults(
|
|
|
75
78
|
modelValue: null,
|
|
76
79
|
required: false,
|
|
77
80
|
disabled: false,
|
|
81
|
+
size: undefined,
|
|
78
82
|
minDate: null,
|
|
79
83
|
maxDate: null,
|
|
80
84
|
hasError: false,
|
|
@@ -100,9 +104,10 @@ const formatInternal = computed(() => {
|
|
|
100
104
|
return 'Y-m-d';
|
|
101
105
|
});
|
|
102
106
|
|
|
103
|
-
const { hasErrorInternal, emitUpdate } = useField({
|
|
107
|
+
const { hasErrorInternal, emitUpdate, sizeInternal } = useField({
|
|
104
108
|
name: computed(() => props.name),
|
|
105
109
|
required: computed(() => props.required),
|
|
110
|
+
size: computed(() => props.size),
|
|
106
111
|
hasError: computed(() => props.hasError),
|
|
107
112
|
emit: emit,
|
|
108
113
|
});
|
|
@@ -293,4 +298,56 @@ function init() {
|
|
|
293
298
|
function clear() {
|
|
294
299
|
emitUpdate(null);
|
|
295
300
|
}
|
|
301
|
+
|
|
302
|
+
const classes = computed(() => {
|
|
303
|
+
const base = 'transition-colors duration-200 input-rounded';
|
|
304
|
+
const focus = 'focus:input-focus'
|
|
305
|
+
const error = hasErrorInternal.value ? 'border-red-500 focus:input-focus-error' : 'border-slate-300';
|
|
306
|
+
const disabled = 'disabled:cursor-not-allowed disabled:text-slate-300';
|
|
307
|
+
const sizeConfig = sizes[sizeInternal.value];
|
|
308
|
+
const padding = {
|
|
309
|
+
'xs': 'pl-6 pr-5',
|
|
310
|
+
'sm': 'pl-[2.1rem] pr-6',
|
|
311
|
+
'md': 'pl-10 pr-7',
|
|
312
|
+
}[sizeInternal.value];
|
|
313
|
+
|
|
314
|
+
const paddingRight = props.modelValue ? padding : 'pr-0';
|
|
315
|
+
|
|
316
|
+
return twMerge(
|
|
317
|
+
base,
|
|
318
|
+
focus,
|
|
319
|
+
error,
|
|
320
|
+
disabled,
|
|
321
|
+
padding,
|
|
322
|
+
paddingRight,
|
|
323
|
+
sizeConfig.height,
|
|
324
|
+
sizeConfig.fontSize,
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const iconWrapClasses = computed(() => {
|
|
329
|
+
const base = 'pointer-events-none absolute top-0 left-0 h-full flex items-center justify-center';
|
|
330
|
+
const padding = {
|
|
331
|
+
'xs': 'pl-2',
|
|
332
|
+
'sm': 'pl-2.5',
|
|
333
|
+
'md': 'pl-3',
|
|
334
|
+
}[sizeInternal.value];
|
|
335
|
+
|
|
336
|
+
return twMerge(
|
|
337
|
+
base,
|
|
338
|
+
padding
|
|
339
|
+
);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
const iconClasses = computed(() => {
|
|
343
|
+
const base = '';
|
|
344
|
+
const error = hasErrorInternal.value ? 'text-red-500' : 'text-slate-500';
|
|
345
|
+
const sizeConfig = sizes[sizeInternal.value];
|
|
346
|
+
|
|
347
|
+
return twMerge(
|
|
348
|
+
base,
|
|
349
|
+
error,
|
|
350
|
+
sizeConfig.iconSize,
|
|
351
|
+
);
|
|
352
|
+
});
|
|
296
353
|
</script>
|
|
@@ -2,10 +2,17 @@ import BaseDateSelect from './BaseDateSelect.vue';
|
|
|
2
2
|
import ShowValue from '@/../.storybook/components/ShowValue.vue';
|
|
3
3
|
import { createFieldStory } from '../../.storybook/utils';
|
|
4
4
|
|
|
5
|
+
const sizes = ['xs', 'sm', 'md'];
|
|
6
|
+
|
|
5
7
|
export default {
|
|
6
8
|
title: 'Form/BaseDateSelect',
|
|
7
9
|
component: BaseDateSelect,
|
|
8
|
-
argTypes: {
|
|
10
|
+
argTypes: {
|
|
11
|
+
size: {
|
|
12
|
+
control: { type: 'select' },
|
|
13
|
+
options: sizes,
|
|
14
|
+
}
|
|
15
|
+
},
|
|
9
16
|
};
|
|
10
17
|
|
|
11
18
|
const Template = (args) => ({
|
|
@@ -40,6 +47,23 @@ Disabled.args = {
|
|
|
40
47
|
disabled: true,
|
|
41
48
|
};
|
|
42
49
|
|
|
50
|
+
const TemplateSizes = (args) => ({
|
|
51
|
+
components: { BaseDateSelect },
|
|
52
|
+
setup() {
|
|
53
|
+
const value = ref(null);
|
|
54
|
+
const sizes = ['xs', 'sm', 'md'];
|
|
55
|
+
return { args, value, sizes };
|
|
56
|
+
},
|
|
57
|
+
template: `
|
|
58
|
+
<div v-for="size in sizes" :key="size" class="mb-4">
|
|
59
|
+
<p class="text-xs text-slate-600 leading-tight mb-1">{{ size }}</p>
|
|
60
|
+
<BaseDateSelect v-model="value" v-bind="args" :size="size" class="w-full"></BaseDateSelect>
|
|
61
|
+
</div>
|
|
62
|
+
`,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const Sizes = TemplateSizes.bind({});
|
|
66
|
+
|
|
43
67
|
export const Field = createFieldStory({
|
|
44
68
|
component: BaseDateSelect,
|
|
45
69
|
componentName: 'BaseDateSelect',
|