sprintify-ui 0.5.11 → 0.6.0
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 +16157 -17178
- package/dist/style.css +1 -1
- package/dist/tailwindcss/index.js +1 -0
- package/dist/types/src/components/BaseAddressForm.vue.d.ts +0 -5
- package/dist/types/src/components/BaseAutocomplete.vue.d.ts +10 -1
- package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +10 -1
- package/dist/types/src/components/BaseAvatar.vue.d.ts +18 -0
- package/dist/types/src/components/BaseBelongsTo.vue.d.ts +9 -0
- package/dist/types/src/components/BaseBelongsToFetch.vue.d.ts +9 -0
- package/dist/types/src/components/BaseCalendar.vue.d.ts +2 -2
- package/dist/types/src/components/BaseClipboard.vue.d.ts +0 -1
- package/dist/types/src/components/BaseDisplayRelativeTime.vue.d.ts +3 -4
- package/dist/types/src/components/BaseDropdown.vue.d.ts +12 -35
- package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +5 -15
- package/dist/types/src/components/BaseIconPicker.vue.d.ts +9 -9
- package/dist/types/src/components/BaseInput.vue.d.ts +2 -2
- package/dist/types/src/components/BaseInputLabel.vue.d.ts +0 -1
- package/dist/types/src/components/BaseInputPercent.vue.d.ts +2 -2
- package/dist/types/src/components/BaseLoadingCover.vue.d.ts +2 -2
- package/dist/types/src/components/BaseMediaLibrary.vue.d.ts +1 -1
- package/dist/types/src/components/BaseMenu.vue.d.ts +14 -5
- package/dist/types/src/components/BaseModalCenter.vue.d.ts +1 -1
- package/dist/types/src/components/BaseModalSide.vue.d.ts +1 -1
- package/dist/types/src/components/BaseRichText.vue.d.ts +1 -1
- package/dist/types/src/components/BaseSelect.vue.d.ts +1 -1
- package/dist/types/src/components/BaseTableColumn.vue.d.ts +2 -2
- package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +10 -1
- package/dist/types/src/components/BaseTagAutocompleteFetch.vue.d.ts +10 -1
- package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +1 -1
- package/dist/types/src/components/BaseTooltip.vue.d.ts +19 -0
- package/dist/types/src/components/index.d.ts +1 -2
- package/dist/types/src/composables/tooltip.d.ts +7 -0
- package/package.json +2 -3
- package/src/assets/main.css +0 -1
- package/src/components/BaseAddressForm.vue +1 -2
- package/src/components/BaseAutocomplete.vue +27 -5
- package/src/components/BaseAutocompleteFetch.vue +5 -0
- package/src/components/BaseAvatar.vue +42 -2
- package/src/components/BaseAvatarGroup.stories.js +1 -1
- package/src/components/BaseAvatarGroup.vue +2 -2
- package/src/components/BaseBelongsTo.vue +5 -0
- package/src/components/BaseBelongsToFetch.vue +5 -0
- package/src/components/BaseClipboard.vue +56 -34
- package/src/components/BaseCounter.vue +1 -1
- package/src/components/BaseDataTable.vue +3 -1
- package/src/components/BaseDatePicker.vue +4 -4
- package/src/components/BaseDisplayRelativeTime.vue +15 -12
- package/src/components/BaseDropdown.stories.js +22 -65
- package/src/components/BaseDropdown.vue +37 -243
- package/src/components/BaseDropdownAutocomplete.vue +5 -30
- package/src/components/BaseHeader.vue +0 -1
- package/src/components/BaseInputLabel.vue +14 -11
- package/src/components/BaseLayoutNotificationDropdown.vue +1 -2
- package/src/components/BaseMenu.vue +121 -111
- package/src/components/BaseTagAutocomplete.vue +19 -2
- package/src/components/BaseTagAutocompleteFetch.vue +5 -0
- package/src/components/BaseTooltip.vue +40 -0
- package/src/components/index.ts +0 -2
- package/src/composables/tooltip.ts +43 -0
- package/dist/types/src/components/BaseClickOutside.vue.d.ts +0 -28
- package/src/components/BaseClickOutside.vue +0 -37
|
@@ -26,11 +26,10 @@
|
|
|
26
26
|
ref="inputElement"
|
|
27
27
|
:value="keywords"
|
|
28
28
|
type="text"
|
|
29
|
-
:placeholder="
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
class="relative w-full pr-9 disabled:cursor-not-allowed disabled:text-slate-300"
|
|
29
|
+
:placeholder="placeholder ? placeholder : t('sui.autocomplete_placeholder')"
|
|
30
|
+
class="relative w-full placeholder:text-slate-400 disabled:cursor-not-allowed disabled:text-slate-300"
|
|
33
31
|
:class="[
|
|
32
|
+
showDeleteButton ? 'pr-9' : '',
|
|
34
33
|
select ? '-left-px rounded-r' : 'rounded',
|
|
35
34
|
hasErrorInternal ? 'border-red-600' : 'border-slate-300',
|
|
36
35
|
inputSizeClass,
|
|
@@ -63,7 +62,7 @@
|
|
|
63
62
|
</div>
|
|
64
63
|
|
|
65
64
|
<div
|
|
66
|
-
v-if="
|
|
65
|
+
v-if="showDeleteButton"
|
|
67
66
|
class="absolute right-0 top-0 flex h-full items-center p-1"
|
|
68
67
|
>
|
|
69
68
|
<button
|
|
@@ -207,6 +206,10 @@ const props = defineProps({
|
|
|
207
206
|
default: true,
|
|
208
207
|
type: Boolean,
|
|
209
208
|
},
|
|
209
|
+
focusOnMount: {
|
|
210
|
+
default: false,
|
|
211
|
+
type: Boolean,
|
|
212
|
+
},
|
|
210
213
|
/** Show an 'empty option', should use with showModelValue = true for better UX */
|
|
211
214
|
showEmptyOption: {
|
|
212
215
|
default: false,
|
|
@@ -249,6 +252,20 @@ const hasOptions = useHasOptions(
|
|
|
249
252
|
computed(() => false)
|
|
250
253
|
);
|
|
251
254
|
|
|
255
|
+
let openOfFocusTimeout = 0;
|
|
256
|
+
|
|
257
|
+
onMounted(() => {
|
|
258
|
+
openOfFocusTimeout = setTimeout(() => {
|
|
259
|
+
if (props.focusOnMount) {
|
|
260
|
+
open();
|
|
261
|
+
}
|
|
262
|
+
}, 10)
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
onBeforeUnmount(() => {
|
|
266
|
+
clearTimeout(openOfFocusTimeout);
|
|
267
|
+
});
|
|
268
|
+
|
|
252
269
|
const drawer = ref<InstanceType<typeof BaseAutocompleteDrawer> | null>(null);
|
|
253
270
|
|
|
254
271
|
let timerId = 0;
|
|
@@ -321,6 +338,7 @@ useClickOutside(autocomplete, () => {
|
|
|
321
338
|
function open() {
|
|
322
339
|
clearInterval(timerId);
|
|
323
340
|
// Always focus as a safety
|
|
341
|
+
|
|
324
342
|
focus();
|
|
325
343
|
// Only emit open if value changes
|
|
326
344
|
if (!opened.value) {
|
|
@@ -513,6 +531,10 @@ const iconWrapClass = computed(() => {
|
|
|
513
531
|
return 'pl-2.5';
|
|
514
532
|
});
|
|
515
533
|
|
|
534
|
+
const showDeleteButton = computed(() => {
|
|
535
|
+
return normalizedModelValue.value && !props.disabled && props.showModelValue;
|
|
536
|
+
});
|
|
537
|
+
|
|
516
538
|
defineExpose({
|
|
517
539
|
focus,
|
|
518
540
|
blur,
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
:dropdown-show="dropdownShow"
|
|
18
18
|
:show-model-value="showModelValue"
|
|
19
19
|
:visible-focus="visibleFocus"
|
|
20
|
+
:focus-on-mount="focusOnMount"
|
|
20
21
|
:show-empty-option="showEmptyOption"
|
|
21
22
|
:empty-option-label="emptyOptionLabel"
|
|
22
23
|
:select="select"
|
|
@@ -144,6 +145,10 @@ const props = defineProps({
|
|
|
144
145
|
default: true,
|
|
145
146
|
type: Boolean,
|
|
146
147
|
},
|
|
148
|
+
focusOnMount: {
|
|
149
|
+
default: false,
|
|
150
|
+
type: Boolean,
|
|
151
|
+
},
|
|
147
152
|
showEmptyOption: {
|
|
148
153
|
default: false,
|
|
149
154
|
type: Boolean,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:is="to ? 'RouterLink' : 'div'"
|
|
4
|
+
ref="buttonRef"
|
|
4
5
|
:to="to"
|
|
5
|
-
class="
|
|
6
|
+
:class="classInternal"
|
|
6
7
|
>
|
|
7
8
|
<img
|
|
8
9
|
:src="user.avatar_url"
|
|
9
10
|
:class="[sizeClass, detailsPosition == 'left' ? 'order-2' : 'order-1']"
|
|
10
|
-
class="shrink-0 overflow-hidden rounded-full object-cover object-center"
|
|
11
|
+
class="shrink-0 block overflow-hidden rounded-full object-cover object-center"
|
|
11
12
|
>
|
|
12
13
|
<div
|
|
13
14
|
v-if="showDetails"
|
|
@@ -28,6 +29,20 @@
|
|
|
28
29
|
{{ user.email }}
|
|
29
30
|
</div>
|
|
30
31
|
</div>
|
|
32
|
+
|
|
33
|
+
<BaseTooltip
|
|
34
|
+
v-if="tooltip"
|
|
35
|
+
:target="buttonRef"
|
|
36
|
+
>
|
|
37
|
+
<div>
|
|
38
|
+
<p class="text-xs font-medium leading-tight">
|
|
39
|
+
{{ user.full_name }}
|
|
40
|
+
</p>
|
|
41
|
+
<p class="text-xs text-slate-500 leading-tight">
|
|
42
|
+
{{ user.email }}
|
|
43
|
+
</p>
|
|
44
|
+
</div>
|
|
45
|
+
</BaseTooltip>
|
|
31
46
|
</component>
|
|
32
47
|
</template>
|
|
33
48
|
|
|
@@ -35,6 +50,12 @@
|
|
|
35
50
|
import { PropType } from 'vue';
|
|
36
51
|
import { User } from '@/types/User';
|
|
37
52
|
import { RouteLocationRaw } from 'vue-router';
|
|
53
|
+
import { twMerge } from 'tailwind-merge';
|
|
54
|
+
import BaseTooltip from './BaseTooltip.vue';
|
|
55
|
+
|
|
56
|
+
defineOptions({
|
|
57
|
+
inheritAttrs: false,
|
|
58
|
+
})
|
|
38
59
|
|
|
39
60
|
const props = defineProps({
|
|
40
61
|
user: {
|
|
@@ -53,12 +74,31 @@ const props = defineProps({
|
|
|
53
74
|
default: 'right',
|
|
54
75
|
type: String as PropType<'left' | 'right'>,
|
|
55
76
|
},
|
|
77
|
+
class: {
|
|
78
|
+
default: '',
|
|
79
|
+
type: String,
|
|
80
|
+
},
|
|
81
|
+
tooltip: {
|
|
82
|
+
default: false,
|
|
83
|
+
type: Boolean,
|
|
84
|
+
},
|
|
56
85
|
to: {
|
|
57
86
|
default: undefined,
|
|
58
87
|
type: [String, Object] as PropType<RouteLocationRaw>,
|
|
59
88
|
},
|
|
60
89
|
});
|
|
61
90
|
|
|
91
|
+
const classInternal = computed(() => {
|
|
92
|
+
return twMerge(
|
|
93
|
+
'inline-flex',
|
|
94
|
+
'shrink-0',
|
|
95
|
+
'items-center',
|
|
96
|
+
props.class,
|
|
97
|
+
);
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const buttonRef = ref<HTMLElement | null>(null);
|
|
101
|
+
|
|
62
102
|
const sizeClass = computed((): string => {
|
|
63
103
|
const base = 'h-9 w-9';
|
|
64
104
|
|
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
|
|
14
14
|
const user = {
|
|
15
15
|
email: 'jane@witify.io',
|
|
16
|
-
full_name: 'Jane Doe',
|
|
16
|
+
full_name: 'Jane Doe with a very long name',
|
|
17
17
|
avatar_url:
|
|
18
18
|
'https://images.unsplash.com/photo-1494790108377-be9c29b29330??auto=format&fit=crop&w=200&h=200&q=80&g=face',
|
|
19
19
|
};
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
<div
|
|
4
4
|
v-for="(user, index) in users"
|
|
5
5
|
:key="user.email + '-' + index"
|
|
6
|
-
role="tooltip"
|
|
7
6
|
class="shrink-0"
|
|
8
|
-
:aria-label="user.full_name + '\n' + user.email"
|
|
9
7
|
:style="{
|
|
10
8
|
marginLeft: index === 0 ? '0' : '-' + spacing,
|
|
11
9
|
}"
|
|
12
10
|
>
|
|
13
11
|
<div class="rounded-full border-[3px] border-white">
|
|
14
12
|
<BaseAvatar
|
|
13
|
+
class="flex"
|
|
14
|
+
tooltip
|
|
15
15
|
:user="user"
|
|
16
16
|
:size="size"
|
|
17
17
|
:show-details="false"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
:show-empty-option="showEmptyOption"
|
|
18
18
|
:empty-option-label="emptyOptionLabel"
|
|
19
19
|
:visible-focus="visibleFocus"
|
|
20
|
+
:focus-on-mount="focusOnMount"
|
|
20
21
|
:select="select"
|
|
21
22
|
@update:model-value="onUpdate"
|
|
22
23
|
>
|
|
@@ -105,6 +106,10 @@ const props = defineProps({
|
|
|
105
106
|
default: true,
|
|
106
107
|
type: Boolean,
|
|
107
108
|
},
|
|
109
|
+
focusOnMount: {
|
|
110
|
+
default: false,
|
|
111
|
+
type: Boolean,
|
|
112
|
+
},
|
|
108
113
|
showEmptyOption: {
|
|
109
114
|
default: false,
|
|
110
115
|
type: Boolean,
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
:show-empty-option="showEmptyOption"
|
|
18
18
|
:empty-option-label="emptyOptionLabel"
|
|
19
19
|
:visible-focus="visibleFocus"
|
|
20
|
+
:focus-on-mount="focusOnMount"
|
|
20
21
|
:select="select"
|
|
21
22
|
@update:model-value="onUpdate"
|
|
22
23
|
>
|
|
@@ -115,6 +116,10 @@ const props = defineProps({
|
|
|
115
116
|
default: true,
|
|
116
117
|
type: Boolean,
|
|
117
118
|
},
|
|
119
|
+
focusOnMount: {
|
|
120
|
+
default: false,
|
|
121
|
+
type: Boolean,
|
|
122
|
+
},
|
|
118
123
|
showEmptyOption: {
|
|
119
124
|
default: false,
|
|
120
125
|
type: Boolean,
|
|
@@ -1,17 +1,63 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
|
-
ref="
|
|
3
|
+
ref="buttonRef"
|
|
4
4
|
type="button"
|
|
5
5
|
class="relative inline-flex items-center"
|
|
6
|
+
@click="copyText"
|
|
6
7
|
>
|
|
7
8
|
<slot />
|
|
9
|
+
<Teleport
|
|
10
|
+
to="body"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
ref="floatingRef"
|
|
14
|
+
:style="floatingStyles"
|
|
15
|
+
class="fixed top-0 left-0 pointer-events-none"
|
|
16
|
+
>
|
|
17
|
+
<transition
|
|
18
|
+
enter-active-class="transition duration-200 ease-out"
|
|
19
|
+
enter-from-class="transform -translate-y-2 scale-95 opacity-0"
|
|
20
|
+
enter-to-class="transform translate-y-0 scale-100 opacity-100"
|
|
21
|
+
leave-active-class="transition duration-75 ease-in"
|
|
22
|
+
leave-from-class="transform translate-y-0 scale-100 opacity-100"
|
|
23
|
+
leave-to-class="transform -translate-y-2 scale-95 opacity-0"
|
|
24
|
+
>
|
|
25
|
+
<div
|
|
26
|
+
v-if="showTooltip"
|
|
27
|
+
class="bg-white shadow-md ring-1 ring-black ring-opacity-10 text-slate-900 rounded-md pt-1.5 pb-2 px-3 text-xs"
|
|
28
|
+
>
|
|
29
|
+
<div v-if="showCopied">
|
|
30
|
+
<div class="flex items-center">
|
|
31
|
+
<svg
|
|
32
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
33
|
+
fill="none"
|
|
34
|
+
viewBox="0 0 24 24"
|
|
35
|
+
stroke-width="1.5"
|
|
36
|
+
stroke="currentColor"
|
|
37
|
+
class="w-5 h-5 mr-1 text-green-500"
|
|
38
|
+
>
|
|
39
|
+
<path
|
|
40
|
+
stroke-linecap="round"
|
|
41
|
+
stroke-linejoin="round"
|
|
42
|
+
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
43
|
+
></path>
|
|
44
|
+
</svg>
|
|
45
|
+
{{ t('sui.copied') }}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div v-else>
|
|
49
|
+
{{ t('sui.click_to_copy') }}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</transition>
|
|
53
|
+
</div>
|
|
54
|
+
</Teleport>
|
|
8
55
|
</button>
|
|
9
56
|
</template>
|
|
10
57
|
|
|
11
58
|
<script lang="ts" setup>
|
|
12
59
|
import { t } from '@/i18n';
|
|
13
|
-
import {
|
|
14
|
-
import 'tippy.js/dist/tippy.css'
|
|
60
|
+
import { useTooltip } from '@/composables/tooltip';
|
|
15
61
|
|
|
16
62
|
const showCopied = ref(false);
|
|
17
63
|
|
|
@@ -22,33 +68,10 @@ const props = defineProps({
|
|
|
22
68
|
},
|
|
23
69
|
});
|
|
24
70
|
|
|
25
|
-
const
|
|
71
|
+
const buttonRef = ref();
|
|
72
|
+
const floatingRef = ref();
|
|
26
73
|
|
|
27
|
-
const
|
|
28
|
-
return showCopied.value ?
|
|
29
|
-
`<div class="flex items-center">
|
|
30
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-1 text-green-500">
|
|
31
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
32
|
-
</svg>
|
|
33
|
-
${t('sui.copied')}
|
|
34
|
-
</div>` :
|
|
35
|
-
|
|
36
|
-
t('sui.click_to_copy')
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
useTippy(btn, {
|
|
40
|
-
content: content,
|
|
41
|
-
placement: 'auto',
|
|
42
|
-
interactive: true,
|
|
43
|
-
hideOnClick: 'toggle',
|
|
44
|
-
trigger: 'mouseenter click',
|
|
45
|
-
allowHTML: true,
|
|
46
|
-
onTrigger(instance, event) {
|
|
47
|
-
if (event.type === 'click') {
|
|
48
|
-
copyText(instance)
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
})
|
|
74
|
+
const { showTooltip, floatingStyles } = useTooltip(buttonRef, floatingRef);
|
|
52
75
|
|
|
53
76
|
async function writeText(text: string) {
|
|
54
77
|
if (
|
|
@@ -64,19 +87,18 @@ async function writeText(text: string) {
|
|
|
64
87
|
|
|
65
88
|
let timeoutId = undefined as undefined | number;
|
|
66
89
|
|
|
67
|
-
function copyText(
|
|
68
|
-
|
|
90
|
+
function copyText() {
|
|
69
91
|
writeText(props.value);
|
|
70
|
-
showSuccessMessage(
|
|
92
|
+
showSuccessMessage();
|
|
71
93
|
}
|
|
72
94
|
|
|
73
|
-
function showSuccessMessage(
|
|
95
|
+
function showSuccessMessage() {
|
|
74
96
|
showCopied.value = true;
|
|
75
97
|
timeoutId = setTimeout(() => {
|
|
76
|
-
instance.hide();
|
|
77
98
|
clearTimeout(timeoutId);
|
|
78
99
|
setTimeout(() => {
|
|
79
100
|
showCopied.value = false;
|
|
101
|
+
showTooltip.value = false;
|
|
80
102
|
}, 200);
|
|
81
103
|
}, 1600);
|
|
82
104
|
}
|
|
@@ -623,7 +623,7 @@ function onUpdateVisibleColumn() {
|
|
|
623
623
|
*/
|
|
624
624
|
|
|
625
625
|
const rowActionsInternal = computed<RowAction[]>(() => {
|
|
626
|
-
const actions =
|
|
626
|
+
const actions = [];
|
|
627
627
|
|
|
628
628
|
if (props.editUrl && props.editButton) {
|
|
629
629
|
actions.push({
|
|
@@ -634,6 +634,8 @@ const rowActionsInternal = computed<RowAction[]>(() => {
|
|
|
634
634
|
});
|
|
635
635
|
}
|
|
636
636
|
|
|
637
|
+
actions.push(...cloneDeep(props.rowActions) ?? []);
|
|
638
|
+
|
|
637
639
|
if (props.deleteUrl && props.deleteButton) {
|
|
638
640
|
actions.push({
|
|
639
641
|
label: t('sui.delete'),
|
|
@@ -232,10 +232,10 @@ onMounted(() => {
|
|
|
232
232
|
init();
|
|
233
233
|
});
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
onUnmounted(() => {
|
|
236
|
+
// Cause weird animation problems when using with BaseDropdown
|
|
237
|
+
// We assume the calendar will self destroy when the component is unmounted
|
|
238
|
+
// picker?.destroy();
|
|
239
239
|
});
|
|
240
240
|
|
|
241
241
|
function init() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:is="as"
|
|
4
|
-
|
|
4
|
+
ref="tooltipRef"
|
|
5
5
|
>
|
|
6
6
|
<slot
|
|
7
7
|
name="default"
|
|
@@ -11,6 +11,15 @@
|
|
|
11
11
|
{{ readableDate }}
|
|
12
12
|
</span>
|
|
13
13
|
</slot>
|
|
14
|
+
|
|
15
|
+
<BaseTooltip
|
|
16
|
+
v-if="tooltip"
|
|
17
|
+
:target="tooltipRef"
|
|
18
|
+
>
|
|
19
|
+
<div class="text-xs">
|
|
20
|
+
{{ tooltipContent }}
|
|
21
|
+
</div>
|
|
22
|
+
</BaseTooltip>
|
|
14
23
|
</component>
|
|
15
24
|
</template>
|
|
16
25
|
|
|
@@ -19,16 +28,15 @@ import { t } from '@/i18n';
|
|
|
19
28
|
import { useI18nStore } from '@/stores/i18n';
|
|
20
29
|
import humanizeDuration from 'humanize-duration';
|
|
21
30
|
import { DateTime } from 'luxon';
|
|
22
|
-
import
|
|
23
|
-
import 'tippy.js/dist/tippy.css'
|
|
31
|
+
import BaseTooltip from './BaseTooltip.vue';
|
|
24
32
|
|
|
25
33
|
const props = defineProps({
|
|
26
34
|
value: {
|
|
27
35
|
required: true,
|
|
28
36
|
type: String,
|
|
29
37
|
},
|
|
30
|
-
|
|
31
|
-
default:
|
|
38
|
+
tooltip: {
|
|
39
|
+
default: true,
|
|
32
40
|
type: Boolean,
|
|
33
41
|
},
|
|
34
42
|
timeZone: {
|
|
@@ -41,19 +49,14 @@ const props = defineProps({
|
|
|
41
49
|
},
|
|
42
50
|
});
|
|
43
51
|
|
|
44
|
-
const
|
|
52
|
+
const tooltipRef = ref();
|
|
45
53
|
|
|
46
54
|
const tooltipContent = computed(() => {
|
|
47
55
|
return DateTime.fromISO(props.value)
|
|
48
56
|
.setLocale(useI18nStore().locale)
|
|
49
|
-
.toLocaleString(DateTime.
|
|
57
|
+
.toLocaleString(DateTime.DATETIME_MED);
|
|
50
58
|
});
|
|
51
59
|
|
|
52
|
-
useTippy(tooltip, {
|
|
53
|
-
content: tooltipContent,
|
|
54
|
-
placement: 'auto',
|
|
55
|
-
})
|
|
56
|
-
|
|
57
60
|
const now = ref(DateTime.now().toSeconds());
|
|
58
61
|
|
|
59
62
|
function getMinutes(duration: number) {
|
|
@@ -3,7 +3,6 @@ import BaseAutocomplete from './BaseAutocomplete.vue';
|
|
|
3
3
|
import BaseModalCenter from './BaseModalCenter.vue';
|
|
4
4
|
import BaseDropdown from './BaseDropdown.vue';
|
|
5
5
|
import BaseDatePicker from './BaseDatePicker.vue';
|
|
6
|
-
import BaseClickOutside from './BaseClickOutside.vue';
|
|
7
6
|
import { options } from '../../.storybook/utils';
|
|
8
7
|
|
|
9
8
|
const items = [];
|
|
@@ -21,13 +20,12 @@ export default {
|
|
|
21
20
|
placement: {
|
|
22
21
|
control: {
|
|
23
22
|
type: 'select',
|
|
24
|
-
options: ['top-start', 'top-end', 'bottom-start', 'bottom-end'],
|
|
25
23
|
},
|
|
24
|
+
options: ['top-start', 'top-end', 'bottom-start', 'bottom-end'],
|
|
26
25
|
},
|
|
27
26
|
},
|
|
28
27
|
args: {
|
|
29
28
|
placement: 'bottom-start',
|
|
30
|
-
padding: 8,
|
|
31
29
|
},
|
|
32
30
|
};
|
|
33
31
|
|
|
@@ -73,40 +71,23 @@ export const WithAutocomplete = (args) => ({
|
|
|
73
71
|
components: { BaseDropdown, BaseAutocomplete, BaseBadge },
|
|
74
72
|
setup() {
|
|
75
73
|
const value = ref(null);
|
|
76
|
-
const autocomplete = ref(null);
|
|
77
|
-
|
|
78
|
-
function onOpen() {
|
|
79
|
-
if (autocomplete.value) {
|
|
80
|
-
setTimeout(() => {
|
|
81
|
-
autocomplete.value.open();
|
|
82
|
-
}, 1);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function onClose() {
|
|
87
|
-
setTimeout(() => {
|
|
88
|
-
if (autocomplete.value) {
|
|
89
|
-
autocomplete.value.setKeywords('');
|
|
90
|
-
}
|
|
91
|
-
}, 10);
|
|
92
|
-
}
|
|
93
74
|
|
|
94
75
|
function onUpdate(v, close) {
|
|
95
76
|
if (v) {
|
|
96
77
|
close();
|
|
97
78
|
}
|
|
98
79
|
}
|
|
99
|
-
|
|
80
|
+
|
|
81
|
+
return { args, options, value, onUpdate };
|
|
100
82
|
},
|
|
101
83
|
template: `
|
|
102
|
-
<BaseDropdown
|
|
84
|
+
<BaseDropdown v-bind="args">
|
|
103
85
|
<template #button>
|
|
104
86
|
<BaseBadge>{{ value ? value.label : 'Select a Character' }}</BaseBadge>
|
|
105
87
|
</template>
|
|
106
88
|
<template #dropdown="{close}">
|
|
107
|
-
<div class="bg-white shadow
|
|
89
|
+
<div class="bg-white shadow-lg rounded-md border py-2 px-2" style="min-width: 250px">
|
|
108
90
|
<BaseAutocomplete
|
|
109
|
-
ref="autocomplete"
|
|
110
91
|
required
|
|
111
92
|
v-model="value"
|
|
112
93
|
label-key="label"
|
|
@@ -117,6 +98,7 @@ export const WithAutocomplete = (args) => ({
|
|
|
117
98
|
:visibleFocus="false"
|
|
118
99
|
dropdownShow="always"
|
|
119
100
|
:showModelValue="false"
|
|
101
|
+
focus-on-mount
|
|
120
102
|
@update:modelValue="onUpdate($event, close)"
|
|
121
103
|
></BaseAutocomplete>
|
|
122
104
|
</div>
|
|
@@ -128,37 +110,8 @@ export const WithAutocomplete = (args) => ({
|
|
|
128
110
|
WithAutocomplete.args = {
|
|
129
111
|
animated: true,
|
|
130
112
|
placement: 'bottom-start',
|
|
131
|
-
padding: 3,
|
|
132
113
|
};
|
|
133
114
|
|
|
134
|
-
export const ModalWithScroll = (args) => ({
|
|
135
|
-
components: { BaseDropdown, BaseModalCenter },
|
|
136
|
-
setup() {
|
|
137
|
-
return { args, items };
|
|
138
|
-
},
|
|
139
|
-
template: `
|
|
140
|
-
<BaseModalCenter :model-value="true">
|
|
141
|
-
<div class="p-10 bg-white">
|
|
142
|
-
<BaseDropdown v-bind="args">
|
|
143
|
-
<template #button>
|
|
144
|
-
<div class="btn btn-primary">Click me</div>
|
|
145
|
-
</template>
|
|
146
|
-
<template #dropdown>
|
|
147
|
-
<div
|
|
148
|
-
class="bg-white shadow py-1 px-1 rounded"
|
|
149
|
-
style="max-height: 200px; overflow: auto;"
|
|
150
|
-
data-scroll-lock-scrollable>
|
|
151
|
-
<button type="button" v-for="item in items" :key="item.label" class="block text-sm px-4 py-1.5">{{ item.label }}</button>
|
|
152
|
-
</div>
|
|
153
|
-
</template>
|
|
154
|
-
</BaseDropdown>
|
|
155
|
-
|
|
156
|
-
<div style="height: 3000px;"></div>
|
|
157
|
-
</div>
|
|
158
|
-
</BaseModalCenter>
|
|
159
|
-
`,
|
|
160
|
-
});
|
|
161
|
-
|
|
162
115
|
export const WithDatePicker = (args) => ({
|
|
163
116
|
components: { BaseDropdown, BaseDatePicker },
|
|
164
117
|
setup() {
|
|
@@ -171,7 +124,7 @@ export const WithDatePicker = (args) => ({
|
|
|
171
124
|
<div class="btn btn-primary">Click me</div>
|
|
172
125
|
</template>
|
|
173
126
|
<template #dropdown>
|
|
174
|
-
<div class="bg-white shadow-lg rounded
|
|
127
|
+
<div class="bg-white shadow-lg rounded-md ring-1 ring-black ring-opacity-10 p-2">
|
|
175
128
|
<BaseDatePicker v-model="date" :show-input="true" inline></BaseDatePicker>
|
|
176
129
|
</div>
|
|
177
130
|
</template>
|
|
@@ -180,31 +133,35 @@ export const WithDatePicker = (args) => ({
|
|
|
180
133
|
});
|
|
181
134
|
|
|
182
135
|
WithDatePicker.args = {
|
|
136
|
+
animated: true,
|
|
183
137
|
placement: 'bottom-start',
|
|
184
138
|
};
|
|
185
139
|
|
|
186
|
-
export const
|
|
187
|
-
components: { BaseDropdown,
|
|
140
|
+
export const ModalWithScroll = (args) => ({
|
|
141
|
+
components: { BaseDropdown, BaseModalCenter },
|
|
188
142
|
setup() {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
return { args, items, onClickOutside };
|
|
143
|
+
const open = ref(true);
|
|
144
|
+
return { args, items, open };
|
|
193
145
|
},
|
|
194
146
|
template: `
|
|
195
|
-
<
|
|
196
|
-
<div class="
|
|
147
|
+
<BaseModalCenter v-model="open">
|
|
148
|
+
<div class="p-10 bg-white">
|
|
197
149
|
<BaseDropdown v-bind="args">
|
|
198
150
|
<template #button>
|
|
199
151
|
<div class="btn btn-primary">Click me</div>
|
|
200
152
|
</template>
|
|
201
153
|
<template #dropdown>
|
|
202
|
-
<div
|
|
203
|
-
|
|
154
|
+
<div
|
|
155
|
+
class="bg-white shadow py-1 px-1 rounded"
|
|
156
|
+
style="max-height: 200px; overflow: auto;"
|
|
157
|
+
data-scroll-lock-scrollable>
|
|
158
|
+
<button type="button" v-for="item in items" :key="item.label" class="block text-sm px-4 py-1.5">{{ item.label }}</button>
|
|
204
159
|
</div>
|
|
205
160
|
</template>
|
|
206
161
|
</BaseDropdown>
|
|
162
|
+
|
|
163
|
+
<div style="height: 3000px;"></div>
|
|
207
164
|
</div>
|
|
208
|
-
</
|
|
165
|
+
</BaseModalCenter>
|
|
209
166
|
`,
|
|
210
167
|
});
|