sprintify-ui 0.4.2 → 0.4.3
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 +16912 -14697
- package/dist/style.css +1 -1
- package/dist/types/src/components/BaseCharacterCounter.vue.d.ts +1 -1
- package/dist/types/src/components/BaseClipboard.vue.d.ts +1 -0
- package/dist/types/src/components/BaseDisplayRelativeTime.vue.d.ts +2 -20
- package/dist/types/src/components/BaseDropdown.vue.d.ts +3 -3
- package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +3 -3
- package/dist/types/src/components/BaseIconPicker.vue.d.ts +8 -8
- package/dist/types/src/components/BaseInputLabel.vue.d.ts +2 -3
- package/dist/types/src/components/BaseLoadingCover.vue.d.ts +2 -2
- 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/BaseShortcut.vue.d.ts +1 -1
- package/package.json +3 -2
- package/src/components/BaseClipboard.stories.js +3 -2
- package/src/components/BaseClipboard.vue +37 -53
- package/src/components/BaseDisplayRelativeTime.stories.js +0 -12
- package/src/components/BaseDisplayRelativeTime.vue +17 -18
- package/src/components/BaseInputLabel.stories.js +1 -1
- package/src/components/BaseInputLabel.vue +30 -48
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprintify-ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build": "rimraf dist && vue-tsc && vite build",
|
|
6
6
|
"build-fast": "rimraf dist && vite build",
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@headlessui/vue": "^1.7.12",
|
|
43
43
|
"color2k": "^2.0.2",
|
|
44
|
-
"tailwind-merge": "^1.12.0"
|
|
44
|
+
"tailwind-merge": "^1.12.0",
|
|
45
|
+
"vue-tippy": "^6.3.1"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@babel/core": "^7.20.12",
|
|
@@ -3,6 +3,7 @@ import BaseClipboard from './BaseClipboard.vue';
|
|
|
3
3
|
export default {
|
|
4
4
|
title: 'Components/BaseClipboard',
|
|
5
5
|
component: BaseClipboard,
|
|
6
|
+
args: {},
|
|
6
7
|
argTypes: {},
|
|
7
8
|
};
|
|
8
9
|
|
|
@@ -12,13 +13,13 @@ const Template = (args) => ({
|
|
|
12
13
|
return { args };
|
|
13
14
|
},
|
|
14
15
|
template: `
|
|
15
|
-
<BaseClipboard class="mb-3">
|
|
16
|
+
<BaseClipboard v-bind="args" class="mb-3">
|
|
16
17
|
<span class="underline text-blue-600">{{ args.value }}</span>
|
|
17
18
|
</BaseClipboard>
|
|
18
19
|
|
|
19
20
|
<br>
|
|
20
21
|
|
|
21
|
-
<BaseClipboard class="mb-3 border border-slate-200 rounded px-2 py-px">
|
|
22
|
+
<BaseClipboard v-bind="args" class="mb-3 border border-slate-200 rounded px-2 py-px">
|
|
22
23
|
<BaseIcon icon="heroicons:server" class="mr-2 text-slate-500" />
|
|
23
24
|
<span class="font-mono text-sm text-slate-600">{{ args.value }}</span>
|
|
24
25
|
</BaseClipboard>
|
|
@@ -1,50 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
|
+
ref="btn"
|
|
3
4
|
type="button"
|
|
4
5
|
class="relative inline-flex items-center"
|
|
5
|
-
@click="copyText()"
|
|
6
|
-
@mouseenter="showTooltip()"
|
|
7
|
-
@mouseleave="hideTooltip()"
|
|
8
6
|
>
|
|
9
7
|
<slot />
|
|
10
|
-
<transition
|
|
11
|
-
enter-active-class="transition duration-200 ease-out"
|
|
12
|
-
enter-from-class="transform scale-90 opacity-0"
|
|
13
|
-
enter-to-class="transform scale-100 opacity-100"
|
|
14
|
-
leave-active-class="transition duration-75 ease-in"
|
|
15
|
-
leave-from-class="transform scale-100 opacity-100"
|
|
16
|
-
leave-to-class="transform scale-90 opacity-0"
|
|
17
|
-
>
|
|
18
|
-
<div
|
|
19
|
-
v-show="tooltipShown"
|
|
20
|
-
class="pointer-events-none absolute left-full z-[1] items-center"
|
|
21
|
-
>
|
|
22
|
-
<div
|
|
23
|
-
class="ml-2 whitespace-nowrap rounded bg-slate-900 bg-opacity-80 px-3 py-2 text-xs leading-tight text-white backdrop-blur"
|
|
24
|
-
>
|
|
25
|
-
<div
|
|
26
|
-
v-if="showCopied"
|
|
27
|
-
class="flex items-center"
|
|
28
|
-
>
|
|
29
|
-
<BaseIcon
|
|
30
|
-
class="mr-1 text-green-500"
|
|
31
|
-
icon="heroicons:check-circle-solid"
|
|
32
|
-
/>
|
|
33
|
-
{{ t('sui.copied') }}
|
|
34
|
-
</div>
|
|
35
|
-
<div v-else>
|
|
36
|
-
{{ t('sui.click_to_copy') }}
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
</transition>
|
|
41
8
|
</button>
|
|
42
9
|
</template>
|
|
43
10
|
|
|
44
11
|
<script lang="ts" setup>
|
|
45
12
|
import { t } from '@/i18n';
|
|
13
|
+
import { useTippy } from 'vue-tippy'
|
|
14
|
+
import 'tippy.js/dist/tippy.css'
|
|
46
15
|
|
|
47
|
-
const tooltipShown = ref(false);
|
|
48
16
|
const showCopied = ref(false);
|
|
49
17
|
|
|
50
18
|
const props = defineProps({
|
|
@@ -54,6 +22,34 @@ const props = defineProps({
|
|
|
54
22
|
},
|
|
55
23
|
});
|
|
56
24
|
|
|
25
|
+
const btn = ref();
|
|
26
|
+
|
|
27
|
+
const content = computed(() => {
|
|
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
|
+
})
|
|
52
|
+
|
|
57
53
|
async function writeText(text: string) {
|
|
58
54
|
if (
|
|
59
55
|
typeof navigator === 'undefined' ||
|
|
@@ -66,31 +62,19 @@ async function writeText(text: string) {
|
|
|
66
62
|
await navigator.clipboard.writeText(text);
|
|
67
63
|
}
|
|
68
64
|
|
|
69
|
-
let timeoutId =
|
|
65
|
+
let timeoutId = undefined as undefined | number;
|
|
70
66
|
|
|
71
|
-
function
|
|
72
|
-
tooltipShown.value = true;
|
|
73
|
-
}
|
|
67
|
+
function copyText(instance: any) {
|
|
74
68
|
|
|
75
|
-
function hideTooltip() {
|
|
76
|
-
tooltipShown.value = false;
|
|
77
|
-
setTimeout(() => {
|
|
78
|
-
showCopied.value = false;
|
|
79
|
-
}, 200);
|
|
80
|
-
if (timeoutId) {
|
|
81
|
-
clearTimeout(timeoutId);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function copyText() {
|
|
86
69
|
writeText(props.value);
|
|
87
|
-
showSuccessMessage();
|
|
70
|
+
showSuccessMessage(instance);
|
|
88
71
|
}
|
|
89
72
|
|
|
90
|
-
function showSuccessMessage() {
|
|
73
|
+
function showSuccessMessage(instance: any) {
|
|
91
74
|
showCopied.value = true;
|
|
92
75
|
timeoutId = setTimeout(() => {
|
|
93
|
-
|
|
76
|
+
instance.hide();
|
|
77
|
+
clearTimeout(timeoutId);
|
|
94
78
|
setTimeout(() => {
|
|
95
79
|
showCopied.value = false;
|
|
96
80
|
}, 200);
|
|
@@ -8,16 +8,6 @@ export default {
|
|
|
8
8
|
showTooltip: {
|
|
9
9
|
control: { type: 'boolean' },
|
|
10
10
|
},
|
|
11
|
-
tooltipPosition: {
|
|
12
|
-
options: ['top', 'bottom', 'right', 'left'],
|
|
13
|
-
control: { type: 'radio' },
|
|
14
|
-
if: { arg: 'showTooltip' },
|
|
15
|
-
},
|
|
16
|
-
tooltipSize: {
|
|
17
|
-
options: ['small', 'medium', 'large'],
|
|
18
|
-
control: { type: 'radio' },
|
|
19
|
-
if: { arg: 'showTooltip' },
|
|
20
|
-
},
|
|
21
11
|
},
|
|
22
12
|
args: {
|
|
23
13
|
value: DateTime.now().minus({ minutes: 2 }).toISO(),
|
|
@@ -37,8 +27,6 @@ const Template = (args) => ({
|
|
|
37
27
|
export const Demo = Template.bind({});
|
|
38
28
|
Demo.args = {
|
|
39
29
|
showTooltip: true,
|
|
40
|
-
tooltipPosition: 'top',
|
|
41
|
-
tooltipSize: 'large',
|
|
42
30
|
};
|
|
43
31
|
|
|
44
32
|
const TemplateCustom = (args) => ({
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:is="as"
|
|
4
|
-
:
|
|
5
|
-
:data-microtip-position="showTooltip ? tooltipPosition : undefined"
|
|
6
|
-
:data-microtip-size="showTooltip ? tooltipSize : undefined"
|
|
7
|
-
:role="showTooltip ? 'tooltip' : undefined"
|
|
4
|
+
:ref="showTooltip ? 'tooltip' : ''"
|
|
8
5
|
>
|
|
9
6
|
<slot
|
|
10
7
|
name="default"
|
|
@@ -22,7 +19,9 @@ import { t } from '@/i18n';
|
|
|
22
19
|
import { useI18nStore } from '@/stores/i18n';
|
|
23
20
|
import humanizeDuration from 'humanize-duration';
|
|
24
21
|
import { DateTime } from 'luxon';
|
|
25
|
-
import {
|
|
22
|
+
import { useTippy } from 'vue-tippy'
|
|
23
|
+
import 'tippy.js/dist/tippy.css'
|
|
24
|
+
|
|
26
25
|
const props = defineProps({
|
|
27
26
|
value: {
|
|
28
27
|
required: true,
|
|
@@ -32,14 +31,6 @@ const props = defineProps({
|
|
|
32
31
|
default: false,
|
|
33
32
|
type: Boolean,
|
|
34
33
|
},
|
|
35
|
-
tooltipPosition: {
|
|
36
|
-
default: 'top',
|
|
37
|
-
type: String as PropType<'top' | 'right' | 'left' | 'bottom'>,
|
|
38
|
-
},
|
|
39
|
-
tooltipSize: {
|
|
40
|
-
default: 'large',
|
|
41
|
-
type: String as PropType<'small' | 'medium' | 'large'>,
|
|
42
|
-
},
|
|
43
34
|
timeZone: {
|
|
44
35
|
default: 'utc',
|
|
45
36
|
type: String,
|
|
@@ -50,6 +41,19 @@ const props = defineProps({
|
|
|
50
41
|
},
|
|
51
42
|
});
|
|
52
43
|
|
|
44
|
+
const tooltip = ref();
|
|
45
|
+
|
|
46
|
+
const tooltipContent = computed(() => {
|
|
47
|
+
return DateTime.fromISO(props.value)
|
|
48
|
+
.setLocale(useI18nStore().locale)
|
|
49
|
+
.toLocaleString(DateTime.DATETIME_FULL);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
useTippy(tooltip, {
|
|
53
|
+
content: tooltipContent,
|
|
54
|
+
placement: 'auto',
|
|
55
|
+
})
|
|
56
|
+
|
|
53
57
|
const now = ref(DateTime.now().toSeconds());
|
|
54
58
|
|
|
55
59
|
function getMinutes(duration: number) {
|
|
@@ -111,11 +115,6 @@ const readableDate = computed(() => {
|
|
|
111
115
|
return t('sui.x_ago', { duration: durationHuman });
|
|
112
116
|
});
|
|
113
117
|
|
|
114
|
-
const tooltip = computed(() => {
|
|
115
|
-
return DateTime.fromISO(props.value)
|
|
116
|
-
.setLocale(useI18nStore().locale)
|
|
117
|
-
.toLocaleString(DateTime.DATETIME_FULL);
|
|
118
|
-
});
|
|
119
118
|
|
|
120
119
|
onBeforeUnmount(() => {
|
|
121
120
|
clearInterval(intervalId);
|
|
@@ -20,7 +20,7 @@ const Template = (args) => ({
|
|
|
20
20
|
return { args };
|
|
21
21
|
},
|
|
22
22
|
template: `
|
|
23
|
-
<form @submit.prevent=""
|
|
23
|
+
<form @submit.prevent="">
|
|
24
24
|
<BaseInputLabel v-bind="args"></BaseInputLabel>
|
|
25
25
|
<BaseInput required name="name" placeholder="Enter your first name"></BaseInput>
|
|
26
26
|
</form>
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<label :class="classes">
|
|
3
3
|
<div
|
|
4
|
-
|
|
4
|
+
:ref="help ? 'info' : ''"
|
|
5
|
+
class="relative inline-flex items-center"
|
|
5
6
|
:class="[help ? 'cursor-help' : 'cursor-default']"
|
|
6
|
-
@mouseenter="showTooltip = true"
|
|
7
|
-
@mouseleave="showTooltip = false"
|
|
8
7
|
>
|
|
9
8
|
<span> {{ label }}</span>
|
|
10
9
|
|
|
@@ -18,58 +17,41 @@
|
|
|
18
17
|
v-if="required"
|
|
19
18
|
class="ml-0.5 text-red-600"
|
|
20
19
|
> *</span>
|
|
21
|
-
|
|
22
|
-
<Transition
|
|
23
|
-
enter-active-class="transition duration-200 ease-out"
|
|
24
|
-
enter-from-class="transform scale-95 opacity-0"
|
|
25
|
-
enter-to-class="transform scale-100 opacity-100"
|
|
26
|
-
leave-active-class="transition duration-75 ease-in"
|
|
27
|
-
leave-from-class="transform scale-100 opacity-100"
|
|
28
|
-
leave-to-class="transform scale-95 opacity-0"
|
|
29
|
-
>
|
|
30
|
-
<div
|
|
31
|
-
v-if="showTooltip && help"
|
|
32
|
-
class="pointer-events-none absolute bottom-[100%] left-0 z-[1] w-auto max-w-[300px]"
|
|
33
|
-
>
|
|
34
|
-
<div
|
|
35
|
-
class="relative bottom-1 rounded-md bg-slate-700 py-1 px-2 text-xs leading-tight text-white"
|
|
36
|
-
>
|
|
37
|
-
{{ help }}
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
</Transition>
|
|
41
20
|
</div>
|
|
42
21
|
</label>
|
|
43
22
|
</template>
|
|
44
23
|
|
|
45
|
-
<script lang="ts">
|
|
46
|
-
import {
|
|
24
|
+
<script lang="ts" setup>
|
|
25
|
+
import { PropType } from 'vue';
|
|
47
26
|
import { Icon as BaseIcon } from '@iconify/vue';
|
|
27
|
+
import { useTippy } from 'vue-tippy'
|
|
28
|
+
import 'tippy.js/dist/tippy.css'
|
|
48
29
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
default: 'mb-1 block text-sm',
|
|
62
|
-
type: String,
|
|
63
|
-
},
|
|
64
|
-
help: {
|
|
65
|
-
default: null,
|
|
66
|
-
type: [String, null] as PropType<string | null>,
|
|
67
|
-
},
|
|
30
|
+
const props = defineProps({
|
|
31
|
+
required: {
|
|
32
|
+
default: false,
|
|
33
|
+
type: Boolean,
|
|
34
|
+
},
|
|
35
|
+
label: {
|
|
36
|
+
required: true,
|
|
37
|
+
type: String,
|
|
38
|
+
},
|
|
39
|
+
classes: {
|
|
40
|
+
default: 'mb-1 block text-sm',
|
|
41
|
+
type: String,
|
|
68
42
|
},
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
43
|
+
help: {
|
|
44
|
+
default: null,
|
|
45
|
+
type: [String, null] as PropType<string | null>,
|
|
73
46
|
},
|
|
74
47
|
});
|
|
48
|
+
|
|
49
|
+
const info = ref();
|
|
50
|
+
const content = computed(() => { return props.help })
|
|
51
|
+
|
|
52
|
+
useTippy(info, {
|
|
53
|
+
content: content,
|
|
54
|
+
placement: 'auto',
|
|
55
|
+
})
|
|
56
|
+
|
|
75
57
|
</script>
|