@saasmakers/ui 1.4.47 → 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.
@@ -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>
@@ -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
@@ -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
package/nuxt.config.ts CHANGED
@@ -16,6 +16,7 @@ export default defineNuxtConfig({
16
16
  '@nuxtjs/robots',
17
17
  '@nuxtjs/sitemap',
18
18
  '@pinia/nuxt',
19
+ 'pinia-plugin-persistedstate/nuxt',
19
20
  '@unocss/nuxt',
20
21
  '@vueuse/nuxt',
21
22
  'floating-vue/nuxt',
@@ -47,6 +48,8 @@ export default defineNuxtConfig({
47
48
  path.join(currentDir, './app/assets/styles/v-popper.css'),
48
49
  ],
49
50
 
51
+ piniaPluginPersistedstate: { storage: 'localStorage' },
52
+
50
53
  colorMode: {
51
54
  classSuffix: '',
52
55
  fallback: 'light',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasmakers/ui",
3
- "version": "1.4.47",
3
+ "version": "1.4.49",
4
4
  "private": false,
5
5
  "description": "Reusable Nuxt UI components for SaaS Makers projects",
6
6
  "license": "MIT",
@@ -43,6 +43,7 @@
43
43
  "motion-v": "1.7.4",
44
44
  "numbro": "2.5.0",
45
45
  "pinia": "3.0.4",
46
+ "pinia-plugin-persistedstate": "4.7.1",
46
47
  "snarkdown": "2.0.0",
47
48
  "unocss": "66.7.0",
48
49
  "vue": "3.5.38",