@saasmakers/ui 0.1.108 → 0.1.110
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/app/components/bases/BaseAvatar.vue +5 -4
- package/app/components/bases/BaseEmoji.vue +5 -4
- package/app/components/bases/BaseIcon.vue +5 -4
- package/app/components/bases/BaseOverlay.vue +5 -4
- package/app/components/bases/BaseQuote.vue +5 -4
- package/app/components/bases/BaseSpinner.vue +5 -4
- package/app/components/bases/BaseTag.vue +5 -4
- package/app/components/bases/BaseToast.vue +4 -9
- package/app/components/fields/FieldLabel.vue +5 -8
- package/app/components/fields/FieldSelect.vue +12 -23
- package/app/components/fields/FieldTime.vue +5 -5
- package/app/composables/useChartist.ts +1 -0
- package/app/composables/useToasts.ts +3 -1
- package/nuxt.config.ts +33 -39
- package/package.json +3 -3
- package/uno.config.ts +2 -0
|
@@ -68,9 +68,9 @@ function onFocus() {
|
|
|
68
68
|
hovered.value = true
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
function
|
|
72
|
-
if (
|
|
73
|
-
|
|
71
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
72
|
+
if (isClickable.value) {
|
|
73
|
+
(event.currentTarget as HTMLElement).click()
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -109,7 +109,8 @@ function onMouseLeave() {
|
|
|
109
109
|
:aria-disabled="!isClickable"
|
|
110
110
|
tabindex="0"
|
|
111
111
|
@click="onClick"
|
|
112
|
-
@keydown.
|
|
112
|
+
@keydown.enter="onKeyDown"
|
|
113
|
+
@keydown.space.prevent="onKeyDown"
|
|
113
114
|
>
|
|
114
115
|
<img
|
|
115
116
|
class="h-full w-full object-cover drag-none"
|
|
@@ -22,9 +22,9 @@ function onClick(event: MouseEvent) {
|
|
|
22
22
|
emit('click', event, props.emoji)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function
|
|
26
|
-
if (
|
|
27
|
-
|
|
25
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
26
|
+
if (props.clickable) {
|
|
27
|
+
(event.currentTarget as HTMLElement).click()
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
</script>
|
|
@@ -52,7 +52,8 @@ function onKeydown(event: KeyboardEvent) {
|
|
|
52
52
|
role="button"
|
|
53
53
|
tabindex="0"
|
|
54
54
|
@click="onClick"
|
|
55
|
-
@keydown.
|
|
55
|
+
@keydown.enter="onKeyDown"
|
|
56
|
+
@keydown.space.prevent="onKeyDown"
|
|
56
57
|
>
|
|
57
58
|
<img
|
|
58
59
|
v-if="emoji"
|
|
@@ -99,9 +99,9 @@ function onClick(event: MouseEvent) {
|
|
|
99
99
|
emit('click', event)
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
function
|
|
103
|
-
if (
|
|
104
|
-
|
|
102
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
103
|
+
if (isClickable.value) {
|
|
104
|
+
(event.currentTarget as HTMLElement).click()
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
</script>
|
|
@@ -117,7 +117,8 @@ function onKeydown(event: KeyboardEvent) {
|
|
|
117
117
|
role="button"
|
|
118
118
|
tabindex="0"
|
|
119
119
|
@click="onClick"
|
|
120
|
-
@keydown.
|
|
120
|
+
@keydown.enter="onKeyDown"
|
|
121
|
+
@keydown.space.prevent="onKeyDown"
|
|
121
122
|
>
|
|
122
123
|
<component
|
|
123
124
|
:is="to ? NuxtLinkLocale : 'span'"
|
|
@@ -37,9 +37,9 @@ function onClose(event: KeyboardEvent | MouseEvent) {
|
|
|
37
37
|
emit('close', event)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function
|
|
41
|
-
if (
|
|
42
|
-
|
|
40
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
41
|
+
if (isClickable.value) {
|
|
42
|
+
(event.currentTarget as HTMLElement).click()
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -59,7 +59,8 @@ onKeyStroke('Escape', (event) => {
|
|
|
59
59
|
role="button"
|
|
60
60
|
tabindex="0"
|
|
61
61
|
@click="onClick"
|
|
62
|
-
@keydown.
|
|
62
|
+
@keydown.enter="onKeyDown"
|
|
63
|
+
@keydown.space.prevent="onKeyDown"
|
|
63
64
|
>
|
|
64
65
|
<BaseIcon
|
|
65
66
|
v-if="hasClose"
|
|
@@ -52,9 +52,9 @@ function onBubbleClick(event: MouseEvent) {
|
|
|
52
52
|
emit('click', event)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
function
|
|
56
|
-
if (
|
|
57
|
-
|
|
55
|
+
function onBubbleKeyDown(event: KeyboardEvent) {
|
|
56
|
+
if (props.clickable) {
|
|
57
|
+
(event.currentTarget as HTMLElement).click()
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -111,7 +111,8 @@ function onClose(event: MouseEvent) {
|
|
|
111
111
|
:aria-disabled="!clickable"
|
|
112
112
|
tabindex="0"
|
|
113
113
|
@click="onBubbleClick"
|
|
114
|
-
@keydown.
|
|
114
|
+
@keydown.enter="onBubbleKeyDown"
|
|
115
|
+
@keydown.space.prevent="onBubbleKeyDown"
|
|
115
116
|
>
|
|
116
117
|
<div class="flex items-center">
|
|
117
118
|
<div
|
|
@@ -19,9 +19,9 @@ function onClick(event: MouseEvent) {
|
|
|
19
19
|
emit('click', event, props.id)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function
|
|
23
|
-
if (
|
|
24
|
-
|
|
22
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
23
|
+
if (props.clickable) {
|
|
24
|
+
(event.currentTarget as HTMLElement).click()
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
</script>
|
|
@@ -38,7 +38,8 @@ function onKeydown(event: KeyboardEvent) {
|
|
|
38
38
|
:aria-disabled="!clickable"
|
|
39
39
|
tabindex="0"
|
|
40
40
|
@click="onClick"
|
|
41
|
-
@keydown.
|
|
41
|
+
@keydown.enter="onKeyDown"
|
|
42
|
+
@keydown.space.prevent="onKeyDown"
|
|
42
43
|
>
|
|
43
44
|
<div
|
|
44
45
|
class="relative inline-block cursor-wait flex-initial"
|
|
@@ -74,9 +74,9 @@ function onInputSubmit(event: KeyboardEvent) {
|
|
|
74
74
|
emit('inputSubmit', event, form.name.trim(), props.id)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
function
|
|
78
|
-
if (
|
|
79
|
-
|
|
77
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
78
|
+
if (props.clickable) {
|
|
79
|
+
(event.currentTarget as HTMLElement).click()
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -100,7 +100,8 @@ function onRemove(event: MouseEvent) {
|
|
|
100
100
|
:aria-disabled="!clickable"
|
|
101
101
|
tabindex="0"
|
|
102
102
|
@click.stop="onClick"
|
|
103
|
-
@keydown.
|
|
103
|
+
@keydown.enter.stop="onKeyDown"
|
|
104
|
+
@keydown.space.prevent.stop="onKeyDown"
|
|
104
105
|
@mouseenter="onMouseEnter"
|
|
105
106
|
@mouseleave="onMouseLeave"
|
|
106
107
|
@focusin="onFocus"
|
|
@@ -14,15 +14,9 @@ const emit = defineEmits<{
|
|
|
14
14
|
|
|
15
15
|
const { getIcon } = useLayerIcons()
|
|
16
16
|
|
|
17
|
-
function onClose(event: MouseEvent) {
|
|
17
|
+
function onClose(event: KeyboardEvent | MouseEvent) {
|
|
18
18
|
if (props.hasClose) {
|
|
19
|
-
emit('close', event, props)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function onKeydown(event: KeyboardEvent) {
|
|
24
|
-
if ((event.key === 'Enter' || event.key === ' ') && props.hasClose) {
|
|
25
|
-
onClose(event as unknown as MouseEvent)
|
|
19
|
+
emit('close', event as MouseEvent, props)
|
|
26
20
|
}
|
|
27
21
|
}
|
|
28
22
|
</script>
|
|
@@ -34,7 +28,8 @@ function onKeydown(event: KeyboardEvent) {
|
|
|
34
28
|
role="button"
|
|
35
29
|
tabindex="0"
|
|
36
30
|
@click="onClose"
|
|
37
|
-
@keydown.
|
|
31
|
+
@keydown.enter="onClose"
|
|
32
|
+
@keydown.space.prevent="onClose"
|
|
38
33
|
>
|
|
39
34
|
<BaseIcon
|
|
40
35
|
class="pointer-events-none flex-initial"
|
|
@@ -24,15 +24,11 @@ const isClickable = computed(() => {
|
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
function onClick(event: MouseEvent) {
|
|
27
|
-
|
|
28
|
-
emit('click', event)
|
|
29
|
-
}
|
|
27
|
+
emit('click', event)
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
onClick(event as unknown as MouseEvent)
|
|
35
|
-
}
|
|
30
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
31
|
+
(event.currentTarget as HTMLElement).click()
|
|
36
32
|
}
|
|
37
33
|
</script>
|
|
38
34
|
|
|
@@ -61,7 +57,8 @@ function onKeydown(event: KeyboardEvent) {
|
|
|
61
57
|
:tabindex="isClickable && !forField ? 0 : undefined"
|
|
62
58
|
:type="isClickable && !forField ? 'button' : undefined"
|
|
63
59
|
@click="isClickable ? onClick : undefined"
|
|
64
|
-
@keydown.
|
|
60
|
+
@keydown.enter="isClickable ? onKeyDown : undefined"
|
|
61
|
+
@keydown.space.prevent="isClickable ? onKeyDown : undefined"
|
|
65
62
|
>
|
|
66
63
|
<BaseIcon
|
|
67
64
|
:icon="icon"
|
|
@@ -70,12 +70,6 @@ const selectedOption = computed(() => {
|
|
|
70
70
|
})
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
-
function onBlur() {
|
|
74
|
-
if (props.openOnHover && !props.disabled) {
|
|
75
|
-
opened.value = false
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
73
|
function onClose() {
|
|
80
74
|
reset()
|
|
81
75
|
}
|
|
@@ -96,26 +90,20 @@ function onContainerKeypress(event: KeyboardEvent) {
|
|
|
96
90
|
}
|
|
97
91
|
}
|
|
98
92
|
|
|
99
|
-
function onFocus() {
|
|
100
|
-
if (props.openOnHover && !props.disabled) {
|
|
101
|
-
opened.value = true
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
93
|
function onLabelClick() {
|
|
106
94
|
if (!props.disabled) {
|
|
107
95
|
opened.value = !opened.value
|
|
108
96
|
}
|
|
109
97
|
}
|
|
110
98
|
|
|
111
|
-
function
|
|
99
|
+
function onMouseEnterOrFocus() {
|
|
112
100
|
if (props.openOnHover && !props.disabled) {
|
|
113
101
|
opened.value = true
|
|
114
102
|
}
|
|
115
103
|
}
|
|
116
104
|
|
|
117
|
-
function
|
|
118
|
-
if (props.openOnHover) {
|
|
105
|
+
function onMouseLeaveOrBlur() {
|
|
106
|
+
if (props.openOnHover && !props.disabled) {
|
|
119
107
|
opened.value = false
|
|
120
108
|
}
|
|
121
109
|
}
|
|
@@ -134,9 +122,9 @@ function onOptionClick(event: MouseEvent, option: FieldSelectOption) {
|
|
|
134
122
|
}
|
|
135
123
|
}
|
|
136
124
|
|
|
137
|
-
function
|
|
138
|
-
if (
|
|
139
|
-
|
|
125
|
+
function onOptionKeyDown(event: KeyboardEvent) {
|
|
126
|
+
if (!props.disabled) {
|
|
127
|
+
(event.currentTarget as HTMLElement).click()
|
|
140
128
|
}
|
|
141
129
|
}
|
|
142
130
|
|
|
@@ -198,10 +186,10 @@ function selectOption(event: MouseEvent, value: string) {
|
|
|
198
186
|
tabindex="0"
|
|
199
187
|
@click="onContainerClick"
|
|
200
188
|
@keypress.prevent="onContainerKeypress"
|
|
201
|
-
@mouseenter="
|
|
202
|
-
@mouseleave="
|
|
203
|
-
@focusin="
|
|
204
|
-
@focusout="
|
|
189
|
+
@mouseenter="onMouseEnterOrFocus"
|
|
190
|
+
@mouseleave="onMouseLeaveOrBlur"
|
|
191
|
+
@focusin="onMouseEnterOrFocus"
|
|
192
|
+
@focusout="onMouseLeaveOrBlur"
|
|
205
193
|
>
|
|
206
194
|
<template v-if="selectedOption">
|
|
207
195
|
<BaseIcon
|
|
@@ -283,7 +271,8 @@ function selectOption(event: MouseEvent, value: string) {
|
|
|
283
271
|
role="button"
|
|
284
272
|
tabindex="0"
|
|
285
273
|
@click="onOptionClick($event, option)"
|
|
286
|
-
@keydown.prevent="
|
|
274
|
+
@keydown.enter.prevent="onOptionKeyDown"
|
|
275
|
+
@keydown.space.prevent="onOptionKeyDown"
|
|
287
276
|
>
|
|
288
277
|
<BaseIcon
|
|
289
278
|
v-if="option.text"
|
|
@@ -33,10 +33,9 @@ function onContainerClick() {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
inputRef.value.showPicker()
|
|
36
|
+
function onContainerKeyDown(event: KeyboardEvent) {
|
|
37
|
+
if (!props.disabled) {
|
|
38
|
+
(event.currentTarget as HTMLElement).click()
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -74,7 +73,8 @@ function onFieldBlur(event: FocusEvent) {
|
|
|
74
73
|
:aria-disabled="disabled"
|
|
75
74
|
tabindex="0"
|
|
76
75
|
@click="onContainerClick"
|
|
77
|
-
@keydown.
|
|
76
|
+
@keydown.enter="onContainerKeyDown"
|
|
77
|
+
@keydown.space.prevent="onContainerKeyDown"
|
|
78
78
|
>
|
|
79
79
|
<BaseIcon
|
|
80
80
|
:icon="getIcon('clock')"
|
|
@@ -50,6 +50,7 @@ export default function useChartist() {
|
|
|
50
50
|
// Clean up the dash attributes after it finishes
|
|
51
51
|
const total = delay + duration + (stagger ? stagger * (lineCtx.seriesIndex ?? 0) : 0)
|
|
52
52
|
|
|
53
|
+
// eslint-disable-next-line sonarjs/no-nested-functions
|
|
53
54
|
globalThis.setTimeout(() => {
|
|
54
55
|
lineCtx.element.attr({
|
|
55
56
|
'stroke-dasharray': undefined,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto'
|
|
2
|
+
|
|
1
3
|
const toasts = ref<BaseToast[]>([])
|
|
2
4
|
|
|
3
5
|
export default function useToast() {
|
|
@@ -20,7 +22,7 @@ export default function useToast() {
|
|
|
20
22
|
const createToast = (message: string, status: BaseStatus = 'success', i18nParams?: Record<string, number | string>) => {
|
|
21
23
|
if (import.meta.client) {
|
|
22
24
|
const toast: BaseToast = {
|
|
23
|
-
id:
|
|
25
|
+
id: randomUUID(),
|
|
24
26
|
status: status || 'success',
|
|
25
27
|
text: message.includes(' ') ? message : nuxtApp.$i18n.t(`toasts.${message}`, i18nParams || {}),
|
|
26
28
|
}
|
package/nuxt.config.ts
CHANGED
|
@@ -6,26 +6,21 @@ import uno from './uno.config.js'
|
|
|
6
6
|
const currentDir = path.dirname(fileURLToPath(import.meta.url))
|
|
7
7
|
|
|
8
8
|
export default defineNuxtConfig({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
vueCompilerOptions: { strictTemplates: true },
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
// --> COMPONENTS, CSS & MODULES <--
|
|
9
|
+
modules: [
|
|
10
|
+
'@nuxt/icon',
|
|
11
|
+
'@nuxt/scripts',
|
|
12
|
+
'@nuxtjs/color-mode',
|
|
13
|
+
'@nuxtjs/i18n',
|
|
14
|
+
'@nuxtjs/plausible',
|
|
15
|
+
'@nuxtjs/robots',
|
|
16
|
+
'@nuxtjs/sitemap',
|
|
17
|
+
'@nuxtjs/storybook',
|
|
18
|
+
'@pinia/nuxt',
|
|
19
|
+
'@unocss/nuxt',
|
|
20
|
+
'@vueuse/nuxt',
|
|
21
|
+
'floating-vue/nuxt',
|
|
22
|
+
'motion-v/nuxt',
|
|
23
|
+
],
|
|
29
24
|
|
|
30
25
|
components: [
|
|
31
26
|
{
|
|
@@ -42,6 +37,8 @@ export default defineNuxtConfig({
|
|
|
42
37
|
},
|
|
43
38
|
],
|
|
44
39
|
|
|
40
|
+
devtools: { enabled: true },
|
|
41
|
+
|
|
45
42
|
css: [
|
|
46
43
|
'@unocss/reset/tailwind.css',
|
|
47
44
|
path.join(currentDir, './app/assets/styles/chartist.css'),
|
|
@@ -49,31 +46,28 @@ export default defineNuxtConfig({
|
|
|
49
46
|
path.join(currentDir, './app/assets/styles/v-popper.css'),
|
|
50
47
|
],
|
|
51
48
|
|
|
52
|
-
modules: [
|
|
53
|
-
'@nuxt/icon',
|
|
54
|
-
'@nuxt/scripts',
|
|
55
|
-
'@nuxtjs/color-mode',
|
|
56
|
-
'@nuxtjs/i18n',
|
|
57
|
-
'@nuxtjs/plausible',
|
|
58
|
-
'@nuxtjs/robots',
|
|
59
|
-
'@nuxtjs/sitemap',
|
|
60
|
-
'@nuxtjs/storybook',
|
|
61
|
-
'@pinia/nuxt',
|
|
62
|
-
'@unocss/nuxt',
|
|
63
|
-
'@vueuse/nuxt',
|
|
64
|
-
'floating-vue/nuxt',
|
|
65
|
-
'motion-v/nuxt',
|
|
66
|
-
],
|
|
67
|
-
|
|
68
|
-
// --> MODULES <--
|
|
69
|
-
|
|
70
49
|
colorMode: {
|
|
71
50
|
classSuffix: '',
|
|
72
51
|
fallback: 'light',
|
|
73
52
|
preference: 'system',
|
|
74
53
|
},
|
|
75
54
|
|
|
76
|
-
|
|
55
|
+
experimental: { typedPages: true },
|
|
56
|
+
|
|
57
|
+
compatibilityDate: '2025-09-24',
|
|
58
|
+
|
|
59
|
+
typescript: {
|
|
60
|
+
strict: true,
|
|
61
|
+
|
|
62
|
+
tsConfig: {
|
|
63
|
+
compilerOptions: {
|
|
64
|
+
noUncheckedIndexedAccess: false,
|
|
65
|
+
noUnusedParameters: true,
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
vueCompilerOptions: { strictTemplates: true },
|
|
69
|
+
},
|
|
70
|
+
},
|
|
77
71
|
|
|
78
72
|
i18n: {
|
|
79
73
|
defaultLocale: 'en',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasmakers/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.110",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Reusable Nuxt UI components for SaaS Makers projects",
|
|
6
6
|
"repository": {
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"nuxt": "4.2.2",
|
|
57
57
|
"typescript": "5.9.3",
|
|
58
|
-
"@saasmakers/shared": "0.1.
|
|
58
|
+
"@saasmakers/shared": "0.1.16"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@saasmakers/shared": "^0.1.
|
|
61
|
+
"@saasmakers/shared": "^0.1.16",
|
|
62
62
|
"nuxt": "4.2.2"
|
|
63
63
|
},
|
|
64
64
|
"publishConfig": {
|
package/uno.config.ts
CHANGED
|
@@ -187,9 +187,11 @@ export const theme = {
|
|
|
187
187
|
/* eslint-enable perfectionist/sort-objects */
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
/* eslint-disable nuxt/nuxt-config-keys-order */
|
|
190
191
|
export default defineConfig({
|
|
191
192
|
presets,
|
|
192
193
|
rules,
|
|
193
194
|
shortcuts,
|
|
194
195
|
theme,
|
|
195
196
|
})
|
|
197
|
+
/* eslint-enable nuxt/nuxt-config-keys-order */
|