@saasmakers/ui 1.4.48 → 1.4.49
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/BaseCard.vue +201 -0
- package/app/types/bases.d.ts +25 -0
- package/app/types/global.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { NuxtLinkLocale } from '#components'
|
|
3
|
+
import type { BaseCard } from '../../types/bases'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<BaseCard>(), {
|
|
6
|
+
avatar: '',
|
|
7
|
+
clickable: true,
|
|
8
|
+
color: 'gray',
|
|
9
|
+
description: '',
|
|
10
|
+
details: '',
|
|
11
|
+
detailsIcon: undefined,
|
|
12
|
+
direction: 'horizontal',
|
|
13
|
+
emoji: undefined,
|
|
14
|
+
hasBackground: true,
|
|
15
|
+
hasChevron: false,
|
|
16
|
+
icon: undefined,
|
|
17
|
+
id: undefined,
|
|
18
|
+
image: '',
|
|
19
|
+
isSelected: false,
|
|
20
|
+
size: 'base',
|
|
21
|
+
title: undefined,
|
|
22
|
+
titleIcon: undefined,
|
|
23
|
+
to: undefined,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const emit = defineEmits<{
|
|
27
|
+
click: [event: MouseEvent, id?: number | string]
|
|
28
|
+
}>()
|
|
29
|
+
|
|
30
|
+
defineSlots<{
|
|
31
|
+
default?: () => VNode[]
|
|
32
|
+
detailsLeft?: () => VNode[]
|
|
33
|
+
innerBoxLeft?: () => VNode[]
|
|
34
|
+
innerBoxRight?: () => VNode[]
|
|
35
|
+
outerBoxLeft?: () => VNode[]
|
|
36
|
+
outerBoxRight?: () => VNode[]
|
|
37
|
+
right?: () => VNode[]
|
|
38
|
+
}>()
|
|
39
|
+
|
|
40
|
+
const { getIcon } = useLayerIcons()
|
|
41
|
+
const hasAvatarBox = computed<boolean>(() => !!(props.avatar || props.emoji || props.icon || props.image))
|
|
42
|
+
|
|
43
|
+
const isClickable = computed(() => {
|
|
44
|
+
return props.to || props.clickable
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
function onClick(event: MouseEvent) {
|
|
48
|
+
emit('click', event, props.id)
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<template>
|
|
53
|
+
<component
|
|
54
|
+
:is="to ? NuxtLinkLocale : 'div'"
|
|
55
|
+
class="group flex flex-col"
|
|
56
|
+
:class="{
|
|
57
|
+
'cursor-pointer': isClickable,
|
|
58
|
+
'border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 shadow-sm p-1.5 pr-2.5': hasBackground,
|
|
59
|
+
'hover:border-gray-300 dark:hover:border-gray-700': hasBackground && isClickable,
|
|
60
|
+
'rounded-lg': ['sm'].includes(size) && hasBackground,
|
|
61
|
+
'rounded-xl': ['base', 'lg'].includes(size) && hasBackground,
|
|
62
|
+
}"
|
|
63
|
+
:to="to"
|
|
64
|
+
@click="onClick"
|
|
65
|
+
>
|
|
66
|
+
<div
|
|
67
|
+
class="flex overflow-hidden"
|
|
68
|
+
:class="{
|
|
69
|
+
'flex-row items-center text-left': direction === 'horizontal',
|
|
70
|
+
'flex-col text-center': direction === 'vertical',
|
|
71
|
+
}"
|
|
72
|
+
>
|
|
73
|
+
<span class="flex justify-center">
|
|
74
|
+
<slot name="outerBoxLeft" />
|
|
75
|
+
|
|
76
|
+
<span
|
|
77
|
+
v-if="hasAvatarBox"
|
|
78
|
+
class="relative z-10 flex items-center justify-center flex-initial"
|
|
79
|
+
:class="{
|
|
80
|
+
'border shadow-inner': !avatar && !image,
|
|
81
|
+
'rounded-md': !avatar && !image && size === 'sm',
|
|
82
|
+
'rounded-lg': !avatar && !image && ['base', 'lg'].includes(size),
|
|
83
|
+
'border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-900': !avatar && !image,
|
|
84
|
+
'h-8 w-8': size === 'sm' && !avatar && !image,
|
|
85
|
+
'h-9 w-9': size === 'base' && !avatar && !image,
|
|
86
|
+
'h-10 w-10': size === 'lg' && !avatar && !image,
|
|
87
|
+
'mr-2': direction === 'horizontal',
|
|
88
|
+
'mb-1': direction === 'vertical',
|
|
89
|
+
}"
|
|
90
|
+
>
|
|
91
|
+
<slot name="innerBoxLeft" />
|
|
92
|
+
|
|
93
|
+
<BaseAvatar
|
|
94
|
+
v-if="avatar"
|
|
95
|
+
class="rounded-lg flex-initial"
|
|
96
|
+
:class="{
|
|
97
|
+
'h-8 w-8': size === 'sm',
|
|
98
|
+
'h-10 w-10': size === 'base',
|
|
99
|
+
'h-14 w-14': size === 'lg',
|
|
100
|
+
}"
|
|
101
|
+
:src="avatar"
|
|
102
|
+
/>
|
|
103
|
+
|
|
104
|
+
<BaseEmoji
|
|
105
|
+
v-else-if="emoji"
|
|
106
|
+
class="m-0.5"
|
|
107
|
+
:emoji="emoji"
|
|
108
|
+
:has-box="false"
|
|
109
|
+
/>
|
|
110
|
+
|
|
111
|
+
<BaseIcon
|
|
112
|
+
v-else-if="icon"
|
|
113
|
+
class="text-lg"
|
|
114
|
+
:color="color"
|
|
115
|
+
:icon="icon"
|
|
116
|
+
/>
|
|
117
|
+
|
|
118
|
+
<img
|
|
119
|
+
v-else-if="image"
|
|
120
|
+
class="flex-initial object-cover shadow-sm drag-none"
|
|
121
|
+
:class="{
|
|
122
|
+
'h-7 w-7 rounded-md': size === 'sm',
|
|
123
|
+
'h-9 w-9 rounded-lg': size === 'base',
|
|
124
|
+
'h-10 w-10 rounded-lg': size === 'lg',
|
|
125
|
+
}"
|
|
126
|
+
:alt="title"
|
|
127
|
+
loading="lazy"
|
|
128
|
+
:src="image"
|
|
129
|
+
>
|
|
130
|
+
|
|
131
|
+
<slot name="innerBoxRight" />
|
|
132
|
+
</span>
|
|
133
|
+
|
|
134
|
+
<slot name="outerBoxRight" />
|
|
135
|
+
</span>
|
|
136
|
+
|
|
137
|
+
<div
|
|
138
|
+
class="flex min-w-0 flex-1 flex-col justify-center leading-snug"
|
|
139
|
+
:class="{
|
|
140
|
+
'mr-4': direction === 'horizontal',
|
|
141
|
+
'items-center': direction === 'vertical',
|
|
142
|
+
}"
|
|
143
|
+
>
|
|
144
|
+
<div
|
|
145
|
+
class="flex w-full flex-col"
|
|
146
|
+
:class="{
|
|
147
|
+
'gap-0': ['sm', 'base'].includes(size),
|
|
148
|
+
'gap-0.25': size === 'lg',
|
|
149
|
+
}"
|
|
150
|
+
>
|
|
151
|
+
<BaseIcon
|
|
152
|
+
v-if="title"
|
|
153
|
+
class="w-full"
|
|
154
|
+
:class="{ 'self-center': !hasAvatarBox }"
|
|
155
|
+
:icon="titleIcon"
|
|
156
|
+
:size="size"
|
|
157
|
+
:text="title"
|
|
158
|
+
truncate
|
|
159
|
+
/>
|
|
160
|
+
|
|
161
|
+
<BaseText
|
|
162
|
+
v-if="description"
|
|
163
|
+
block
|
|
164
|
+
class="text-gray-600 leading-4 dark:text-gray-400"
|
|
165
|
+
:size="size === 'lg' ? 'xs' : '2xs'"
|
|
166
|
+
:text="description"
|
|
167
|
+
/>
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
<div class="flex items-center">
|
|
171
|
+
<slot name="detailsLeft" />
|
|
172
|
+
|
|
173
|
+
<BaseIcon
|
|
174
|
+
v-if="details"
|
|
175
|
+
class="mt-0.5 whitespace-nowrap text-gray-700 font-semibold tracking-tighter dark:text-gray-300"
|
|
176
|
+
:icon="detailsIcon"
|
|
177
|
+
size="2xs"
|
|
178
|
+
:text="details"
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<BaseIcon
|
|
184
|
+
v-if="isSelected"
|
|
185
|
+
class="mr-1.5 self-center text-2xl flex-initial"
|
|
186
|
+
color="green"
|
|
187
|
+
:icon="getIcon('checkCircle')"
|
|
188
|
+
/>
|
|
189
|
+
|
|
190
|
+
<BaseIcon
|
|
191
|
+
v-else-if="to || hasChevron"
|
|
192
|
+
class="self-center text-xl text-gray-500 flex-initial dark:text-gray-500 group-hover:text-gray-900 dark:group-hover:text-gray-100"
|
|
193
|
+
:icon="getIcon('chevronRight')"
|
|
194
|
+
/>
|
|
195
|
+
|
|
196
|
+
<slot name="right" />
|
|
197
|
+
</div>
|
|
198
|
+
|
|
199
|
+
<slot />
|
|
200
|
+
</component>
|
|
201
|
+
</template>
|
package/app/types/bases.d.ts
CHANGED
|
@@ -72,6 +72,31 @@ export type BaseButtonSize
|
|
|
72
72
|
|
|
73
73
|
export type BaseButtonType = 'button' | 'reset' | 'submit'
|
|
74
74
|
|
|
75
|
+
export interface BaseCard {
|
|
76
|
+
avatar?: string
|
|
77
|
+
clickable?: boolean
|
|
78
|
+
color?: BaseColor
|
|
79
|
+
description?: string
|
|
80
|
+
details?: string
|
|
81
|
+
detailsIcon?: string
|
|
82
|
+
direction?: BaseCardDirection
|
|
83
|
+
emoji?: string
|
|
84
|
+
hasBackground?: boolean
|
|
85
|
+
hasChevron?: boolean
|
|
86
|
+
icon?: string
|
|
87
|
+
id?: number | string
|
|
88
|
+
image?: string
|
|
89
|
+
isSelected?: boolean
|
|
90
|
+
size?: BaseCardSize
|
|
91
|
+
title?: string
|
|
92
|
+
titleIcon?: string
|
|
93
|
+
to?: RouteLocationNamedI18n
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type BaseCardDirection = 'horizontal' | 'vertical'
|
|
97
|
+
|
|
98
|
+
export type BaseCardSize = 'base' | 'lg' | 'sm'
|
|
99
|
+
|
|
75
100
|
export interface BaseCharacter {
|
|
76
101
|
character?: BaseCharacterCharacter
|
|
77
102
|
size?: BaseCharacterSize
|
package/app/types/global.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ declare global {
|
|
|
12
12
|
type BaseButtonRounded = import('./bases').BaseButtonRounded
|
|
13
13
|
type BaseButtonSize = import('./bases').BaseButtonSize
|
|
14
14
|
type BaseButtonType = import('./bases').BaseButtonType
|
|
15
|
+
type BaseCard = import('./bases').BaseCard
|
|
16
|
+
type BaseCardDirection = import('./bases').BaseCardDirection
|
|
17
|
+
type BaseCardSize = import('./bases').BaseCardSize
|
|
15
18
|
type BaseCharacter = import('./bases').BaseCharacter
|
|
16
19
|
type BaseCharacterCharacter = import('./bases').BaseCharacterCharacter
|
|
17
20
|
type BaseCharacterSize = import('./bases').BaseCharacterSize
|