@saasmakers/ui 2.0.48 → 2.0.50
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.
|
@@ -3,22 +3,17 @@ import { NuxtLinkLocale } from '#components'
|
|
|
3
3
|
import type { BaseCard } from '../../types/bases'
|
|
4
4
|
|
|
5
5
|
const props = withDefaults(defineProps<BaseCard>(), {
|
|
6
|
-
avatar: '',
|
|
7
6
|
clickable: true,
|
|
8
7
|
color: 'gray',
|
|
9
8
|
description: '',
|
|
10
9
|
disabled: false,
|
|
11
10
|
emoji: undefined,
|
|
12
|
-
hasBackground: true,
|
|
13
11
|
hasChevron: false,
|
|
14
|
-
icon: undefined,
|
|
15
12
|
id: undefined,
|
|
16
13
|
image: '',
|
|
17
14
|
isSelected: false,
|
|
18
15
|
orientation: 'horizontal',
|
|
19
|
-
size: 'base',
|
|
20
16
|
title: undefined,
|
|
21
|
-
titleIcon: undefined,
|
|
22
17
|
to: undefined,
|
|
23
18
|
})
|
|
24
19
|
|
|
@@ -28,44 +23,16 @@ const emit = defineEmits<{
|
|
|
28
23
|
|
|
29
24
|
defineSlots<{
|
|
30
25
|
default?: () => VNode[]
|
|
31
|
-
innerBoxLeft?: () => VNode[]
|
|
32
|
-
innerBoxRight?: () => VNode[]
|
|
33
|
-
outerBoxLeft?: () => VNode[]
|
|
34
|
-
outerBoxRight?: () => VNode[]
|
|
35
|
-
right?: () => VNode[]
|
|
36
26
|
}>()
|
|
37
27
|
|
|
38
|
-
const hasAvatarBox = computed<boolean>(() => {
|
|
39
|
-
return !!(props.avatar || props.emoji || props.icon || props.image)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
28
|
const hasMediaBox = computed<boolean>(() => {
|
|
43
|
-
return !!(props.
|
|
29
|
+
return !!(props.image || (props.emoji && props.orientation !== 'horizontal'))
|
|
44
30
|
})
|
|
45
31
|
|
|
46
|
-
const isHorizontal = computed(() => props.orientation === 'horizontal')
|
|
47
|
-
|
|
48
32
|
const isClickable = computed(() => {
|
|
49
33
|
return props.to || props.clickable
|
|
50
34
|
})
|
|
51
35
|
|
|
52
|
-
const titleColorClass = computed(() => {
|
|
53
|
-
if (!isHorizontal.value || props.color === 'gray') {
|
|
54
|
-
return 'text-gray-900 dark:text-gray-100'
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const colorClasses: Partial<Record<BaseColor, string>> = {
|
|
58
|
-
black: 'text-gray-900 dark:text-gray-100',
|
|
59
|
-
green: 'text-green-600 dark:text-green-400',
|
|
60
|
-
indigo: 'text-indigo-600 dark:text-indigo-400',
|
|
61
|
-
orange: 'text-orange-600 dark:text-orange-400',
|
|
62
|
-
red: 'text-red-600 dark:text-red-400',
|
|
63
|
-
white: 'text-gray-900 dark:text-gray-100',
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return colorClasses[props.color] ?? 'text-gray-900 dark:text-gray-100'
|
|
67
|
-
})
|
|
68
|
-
|
|
69
36
|
function onClick(event: MouseEvent) {
|
|
70
37
|
emit('click', event, props.id)
|
|
71
38
|
}
|
|
@@ -79,15 +46,12 @@ function onClick(event: MouseEvent) {
|
|
|
79
46
|
'cursor-default': !isClickable,
|
|
80
47
|
'cursor-pointer': isClickable,
|
|
81
48
|
'opacity-50': disabled,
|
|
82
|
-
'base-surface h-12 overflow-hidden pl-2 pr-2.5':
|
|
83
|
-
'base-surface
|
|
84
|
-
'base-
|
|
85
|
-
'
|
|
86
|
-
'
|
|
87
|
-
'
|
|
88
|
-
'rounded-lg': hasBackground && isHorizontal,
|
|
89
|
-
'rounded-xl': hasBackground && !isHorizontal,
|
|
90
|
-
'relative': !isHorizontal,
|
|
49
|
+
'base-surface h-12 overflow-hidden pl-2 pr-2.5': orientation === 'horizontal',
|
|
50
|
+
'base-surface p-3': orientation !== 'horizontal',
|
|
51
|
+
'base-border-hover': isClickable,
|
|
52
|
+
'rounded-lg': orientation === 'horizontal',
|
|
53
|
+
'rounded-xl': orientation !== 'horizontal',
|
|
54
|
+
'relative': orientation !== 'horizontal',
|
|
91
55
|
}"
|
|
92
56
|
:to="disabled ? undefined : to"
|
|
93
57
|
@click="onClick"
|
|
@@ -95,23 +59,19 @@ function onClick(event: MouseEvent) {
|
|
|
95
59
|
<div
|
|
96
60
|
class="flex overflow-hidden"
|
|
97
61
|
:class="{
|
|
98
|
-
'h-12 w-full flex-row items-center text-left':
|
|
99
|
-
'
|
|
100
|
-
'flex-row items-center text-left': isHorizontal && !hasBackground,
|
|
101
|
-
'flex-col items-center text-center': !isHorizontal,
|
|
62
|
+
'h-12 w-full flex-row items-center text-left': orientation === 'horizontal',
|
|
63
|
+
'flex-col items-center text-center': orientation !== 'horizontal',
|
|
102
64
|
}"
|
|
103
65
|
>
|
|
104
66
|
<span
|
|
105
67
|
class="flex items-center"
|
|
106
68
|
:class="{
|
|
107
|
-
'shrink-0 justify-center':
|
|
108
|
-
'justify-center':
|
|
69
|
+
'shrink-0 justify-center': orientation === 'horizontal',
|
|
70
|
+
'justify-center': orientation !== 'horizontal',
|
|
109
71
|
}"
|
|
110
72
|
>
|
|
111
|
-
<slot name="outerBoxLeft" />
|
|
112
|
-
|
|
113
73
|
<BaseEmoji
|
|
114
|
-
v-if="emoji &&
|
|
74
|
+
v-if="emoji && orientation === 'horizontal'"
|
|
115
75
|
class="mr-2 shrink-0 bg-gray-100 flex-initial dark:bg-gray-900"
|
|
116
76
|
:clickable="false"
|
|
117
77
|
:emoji="emoji"
|
|
@@ -119,115 +79,79 @@ function onClick(event: MouseEvent) {
|
|
|
119
79
|
/>
|
|
120
80
|
|
|
121
81
|
<span
|
|
122
|
-
v-if="hasMediaBox
|
|
82
|
+
v-if="hasMediaBox"
|
|
123
83
|
class="relative z-10 flex items-center justify-center flex-initial"
|
|
124
84
|
:class="{
|
|
125
|
-
'border shadow-inner': !
|
|
126
|
-
'
|
|
127
|
-
'
|
|
128
|
-
'
|
|
129
|
-
'
|
|
130
|
-
'mb-2': !isHorizontal && size === 'base',
|
|
131
|
-
'mb-3': !isHorizontal && size === 'lg',
|
|
132
|
-
'h-9 w-9': size === 'base' && isHorizontal,
|
|
133
|
-
'h-11 w-11': size === 'lg' && isHorizontal,
|
|
134
|
-
'h-20 w-20': size === 'base' && !isHorizontal,
|
|
135
|
-
'h-24 w-24': size === 'lg' && !isHorizontal,
|
|
85
|
+
'border shadow-inner rounded-lg base-border bg-gray-100 dark:bg-gray-900': !image && (!emoji || orientation !== 'horizontal'),
|
|
86
|
+
'mr-2': orientation === 'horizontal',
|
|
87
|
+
'mb-2': orientation !== 'horizontal',
|
|
88
|
+
'h-9 w-9': orientation === 'horizontal',
|
|
89
|
+
'h-20 w-20': orientation !== 'horizontal',
|
|
136
90
|
}"
|
|
137
91
|
>
|
|
138
|
-
<slot name="innerBoxLeft" />
|
|
139
|
-
|
|
140
|
-
<BaseAvatar
|
|
141
|
-
v-if="avatar"
|
|
142
|
-
class="rounded-lg flex-initial"
|
|
143
|
-
:class="{
|
|
144
|
-
'h-10 w-10': size === 'base' && isHorizontal,
|
|
145
|
-
'h-12 w-12': size === 'lg' && isHorizontal,
|
|
146
|
-
'h-20 w-20': size === 'base' && !isHorizontal,
|
|
147
|
-
'h-24 w-24': size === 'lg' && !isHorizontal,
|
|
148
|
-
}"
|
|
149
|
-
:src="avatar"
|
|
150
|
-
/>
|
|
151
|
-
|
|
152
92
|
<BaseEmoji
|
|
153
|
-
v-
|
|
93
|
+
v-if="emoji && orientation !== 'horizontal'"
|
|
154
94
|
class="m-0.5"
|
|
155
95
|
:emoji="emoji"
|
|
156
96
|
:has-box="false"
|
|
157
|
-
:size="size === 'lg' ? 'lg' : 'base'"
|
|
158
|
-
/>
|
|
159
|
-
|
|
160
|
-
<BaseIcon
|
|
161
|
-
v-else-if="icon"
|
|
162
|
-
:color="color"
|
|
163
|
-
:icon="icon"
|
|
164
|
-
:size="size === 'lg' ? '2xl' : 'lg'"
|
|
165
97
|
/>
|
|
166
98
|
|
|
167
99
|
<img
|
|
168
100
|
v-else-if="image"
|
|
169
101
|
class="select-none rounded-lg object-cover shadow-sm transition-[filter] duration-300 drag-none flex-initial"
|
|
170
102
|
:class="{
|
|
171
|
-
'h-9 w-9':
|
|
172
|
-
'h-
|
|
173
|
-
'h-20 w-20': size === 'base' && !isHorizontal,
|
|
174
|
-
'h-24 w-24': size === 'lg' && !isHorizontal,
|
|
103
|
+
'h-9 w-9': orientation === 'horizontal',
|
|
104
|
+
'h-20 w-20': orientation !== 'horizontal',
|
|
175
105
|
'grayscale': disabled,
|
|
176
106
|
}"
|
|
177
107
|
:alt="title"
|
|
178
108
|
loading="lazy"
|
|
179
109
|
:src="image"
|
|
180
110
|
>
|
|
181
|
-
|
|
182
|
-
<slot name="innerBoxRight" />
|
|
183
111
|
</span>
|
|
184
|
-
|
|
185
|
-
<slot name="outerBoxRight" />
|
|
186
112
|
</span>
|
|
187
113
|
|
|
188
114
|
<div
|
|
189
115
|
class="min-w-0 flex flex-col justify-center leading-snug"
|
|
190
116
|
:class="{
|
|
191
|
-
'flex-1':
|
|
192
|
-
'w-full':
|
|
193
|
-
'
|
|
194
|
-
'mr-5': isHorizontal && size === 'lg' && (to || hasChevron),
|
|
195
|
-
'items-center': !isHorizontal,
|
|
117
|
+
'flex-1': orientation === 'horizontal',
|
|
118
|
+
'w-full': orientation !== 'horizontal',
|
|
119
|
+
'items-center': orientation !== 'horizontal',
|
|
196
120
|
}"
|
|
197
121
|
>
|
|
198
122
|
<div
|
|
199
123
|
class="w-full flex flex-col"
|
|
200
124
|
:class="{
|
|
201
|
-
'gap-0':
|
|
202
|
-
'gap-
|
|
203
|
-
'gap-1': !isHorizontal && size === 'base',
|
|
204
|
-
'gap-1.5': !isHorizontal && size === 'lg',
|
|
125
|
+
'gap-0': orientation === 'horizontal',
|
|
126
|
+
'gap-1': orientation !== 'horizontal',
|
|
205
127
|
}"
|
|
206
128
|
>
|
|
207
129
|
<p
|
|
208
|
-
v-if="title &&
|
|
130
|
+
v-if="title && orientation === 'horizontal'"
|
|
209
131
|
class="line-clamp-1 min-w-0 break-words text-xs font-medium tracking-tight uppercase"
|
|
210
|
-
:class="
|
|
132
|
+
:class="{
|
|
133
|
+
'text-gray-900 dark:text-gray-100': color === 'gray' || color === 'black' || color === 'white',
|
|
134
|
+
'text-green-600 dark:text-green-400': color === 'green',
|
|
135
|
+
'text-indigo-600 dark:text-indigo-400': color === 'indigo',
|
|
136
|
+
'text-orange-600 dark:text-orange-400': color === 'orange',
|
|
137
|
+
'text-red-600 dark:text-red-400': color === 'red',
|
|
138
|
+
}"
|
|
211
139
|
>
|
|
212
140
|
{{ title }}
|
|
213
141
|
</p>
|
|
214
142
|
|
|
215
143
|
<BaseIcon
|
|
216
144
|
v-else-if="title"
|
|
217
|
-
class="w-full"
|
|
218
|
-
|
|
219
|
-
:color="isHorizontal ? color : undefined"
|
|
220
|
-
:icon="titleIcon"
|
|
221
|
-
:size="size === 'lg' ? 'base' : 'sm'"
|
|
145
|
+
class="w-full self-center"
|
|
146
|
+
size="sm"
|
|
222
147
|
:text="title"
|
|
223
|
-
:truncate="isHorizontal"
|
|
224
148
|
/>
|
|
225
149
|
|
|
226
150
|
<BaseText
|
|
227
|
-
v-if="description &&
|
|
151
|
+
v-if="description && orientation !== 'horizontal'"
|
|
228
152
|
block
|
|
229
153
|
class="text-gray-600 dark:text-gray-400"
|
|
230
|
-
|
|
154
|
+
size="2xs"
|
|
231
155
|
:text="description"
|
|
232
156
|
/>
|
|
233
157
|
</div>
|
|
@@ -237,23 +161,20 @@ function onClick(event: MouseEvent) {
|
|
|
237
161
|
v-if="isSelected"
|
|
238
162
|
class="flex-initial"
|
|
239
163
|
:class="{
|
|
240
|
-
'mr-1.5 self-center':
|
|
241
|
-
'absolute right-2 top-2':
|
|
242
|
-
'absolute right-2.5 top-2.5': !isHorizontal && size === 'lg',
|
|
164
|
+
'mr-1.5 self-center': orientation === 'horizontal',
|
|
165
|
+
'absolute right-2 top-2': orientation !== 'horizontal',
|
|
243
166
|
}"
|
|
244
167
|
color="green"
|
|
245
168
|
:icon="getLayerIcon('checkCircle')"
|
|
246
|
-
|
|
169
|
+
size="xl"
|
|
247
170
|
/>
|
|
248
171
|
|
|
249
172
|
<BaseIcon
|
|
250
|
-
v-else-if="
|
|
173
|
+
v-else-if="orientation === 'horizontal' && (to || hasChevron)"
|
|
251
174
|
class="self-center text-gray-500 flex-initial dark:text-gray-500 group-hover:text-gray-900 dark:group-hover:text-gray-100"
|
|
252
175
|
:icon="getLayerIcon('chevronRight')"
|
|
253
|
-
|
|
176
|
+
size="xl"
|
|
254
177
|
/>
|
|
255
|
-
|
|
256
|
-
<slot name="right" />
|
|
257
178
|
</div>
|
|
258
179
|
|
|
259
180
|
<slot />
|
|
@@ -100,15 +100,29 @@ function onClick(event: MouseEvent) {
|
|
|
100
100
|
emit('click', event)
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
function onEnterKeyDown(event: KeyboardEvent) {
|
|
104
|
+
if (!props.to) {
|
|
105
|
+
onKeyDown(event)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
103
109
|
function onKeyDown(event: KeyboardEvent) {
|
|
104
110
|
if (isClickable.value) {
|
|
105
111
|
(event.currentTarget as HTMLElement).click()
|
|
106
112
|
}
|
|
107
113
|
}
|
|
114
|
+
|
|
115
|
+
function onSpaceKeyDown(event: KeyboardEvent) {
|
|
116
|
+
if (!props.to) {
|
|
117
|
+
event.preventDefault()
|
|
118
|
+
onKeyDown(event)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
108
121
|
</script>
|
|
109
122
|
|
|
110
123
|
<template>
|
|
111
|
-
<
|
|
124
|
+
<component
|
|
125
|
+
:is="to ? NuxtLinkLocale : 'div'"
|
|
112
126
|
class="flex items-center"
|
|
113
127
|
:class="{
|
|
114
128
|
'group cursor-pointer hover:underline hover:text-black dark:hover:text-white': isClickable && text,
|
|
@@ -116,14 +130,14 @@ function onKeyDown(event: KeyboardEvent) {
|
|
|
116
130
|
'flex-row': !reverse,
|
|
117
131
|
'flex-row-reverse': reverse,
|
|
118
132
|
}"
|
|
119
|
-
:role="isClickable ? 'button' : undefined"
|
|
120
|
-
:tabindex="isClickable ? 0 : undefined"
|
|
133
|
+
:role="isClickable && !to ? 'button' : undefined"
|
|
134
|
+
:tabindex="isClickable && !to ? 0 : undefined"
|
|
135
|
+
:to="to"
|
|
121
136
|
@click="onClick"
|
|
122
|
-
@keydown.enter="
|
|
123
|
-
@keydown.space
|
|
137
|
+
@keydown.enter="onEnterKeyDown"
|
|
138
|
+
@keydown.space="onSpaceKeyDown"
|
|
124
139
|
>
|
|
125
|
-
<
|
|
126
|
-
:is="to ? NuxtLinkLocale : 'span'"
|
|
140
|
+
<span
|
|
127
141
|
v-if="finalIcon && !loading"
|
|
128
142
|
class="flex items-center justify-center"
|
|
129
143
|
:class="{
|
|
@@ -153,10 +167,9 @@ function onKeyDown(event: KeyboardEvent) {
|
|
|
153
167
|
'group-hover:text-orange-700 dark:group-hover:text-orange-300': isClickable && finalColor === 'orange',
|
|
154
168
|
'group-hover:text-red-700 dark:group-hover:text-red-300': isClickable && finalColor === 'red',
|
|
155
169
|
}"
|
|
156
|
-
:to="to"
|
|
157
170
|
>
|
|
158
171
|
<Icon :name="finalIcon" />
|
|
159
|
-
</
|
|
172
|
+
</span>
|
|
160
173
|
|
|
161
174
|
<BaseSpinner
|
|
162
175
|
v-else-if="loading"
|
|
@@ -176,7 +189,7 @@ function onKeyDown(event: KeyboardEvent) {
|
|
|
176
189
|
:truncate="truncate"
|
|
177
190
|
:underline="underline"
|
|
178
191
|
/>
|
|
179
|
-
</
|
|
192
|
+
</component>
|
|
180
193
|
</template>
|
|
181
194
|
|
|
182
195
|
<i18n lang="json">
|
package/app/types/bases.d.ts
CHANGED
|
@@ -81,29 +81,22 @@ export type BaseButtonSize
|
|
|
81
81
|
export type BaseButtonType = 'button' | 'reset' | 'submit'
|
|
82
82
|
|
|
83
83
|
export interface BaseCard {
|
|
84
|
-
avatar?: string
|
|
85
84
|
clickable?: boolean
|
|
86
85
|
color?: BaseColor
|
|
87
86
|
description?: string
|
|
88
87
|
disabled?: boolean
|
|
89
88
|
emoji?: string
|
|
90
|
-
hasBackground?: boolean
|
|
91
89
|
hasChevron?: boolean
|
|
92
|
-
icon?: string
|
|
93
90
|
id?: number | string
|
|
94
91
|
image?: string
|
|
95
92
|
isSelected?: boolean
|
|
96
93
|
orientation?: BaseCardOrientation
|
|
97
|
-
size?: BaseCardSize
|
|
98
94
|
title?: string
|
|
99
|
-
titleIcon?: string
|
|
100
95
|
to?: RouteLocationNamedI18n
|
|
101
96
|
}
|
|
102
97
|
|
|
103
98
|
export type BaseCardOrientation = 'horizontal' | 'vertical'
|
|
104
99
|
|
|
105
|
-
export type BaseCardSize = 'base' | 'lg'
|
|
106
|
-
|
|
107
100
|
export interface BaseCharacter {
|
|
108
101
|
character?: BaseCharacterCharacter
|
|
109
102
|
size?: BaseCharacterSize
|
package/app/types/global.d.ts
CHANGED
|
@@ -30,7 +30,6 @@ declare global {
|
|
|
30
30
|
type BaseButtonType = import('./bases').BaseButtonType
|
|
31
31
|
type BaseCard = import('./bases').BaseCard
|
|
32
32
|
type BaseCardOrientation = import('./bases').BaseCardOrientation
|
|
33
|
-
type BaseCardSize = import('./bases').BaseCardSize
|
|
34
33
|
type BaseCharacter = import('./bases').BaseCharacter
|
|
35
34
|
type BaseCharacterCharacter = import('./bases').BaseCharacterCharacter
|
|
36
35
|
type BaseCharacterSize = import('./bases').BaseCharacterSize
|