main
vue 83 lines 2.15 KB
Raw
1 <template>
2 <n-card
3 size="small"
4 :class="{ 'group cursor-pointer': clickable }"
5 :hoverable
6 content-class="flex items-center gap-4"
7 >
8 <div
9 v-if="iconLeft"
10 class="flex size-12 shrink-0 items-center justify-center rounded-sm p-1"
11 :class="{
12 'bg-warning/10 text-warning': color === 'warning',
13 'bg-success/10 text-success': color === 'success',
14 'bg-error/10 text-error': color === 'danger',
15 'bg-primary/10 text-primary': color === 'primary',
16 'bg-secondary text-secondary': !color
17 }"
18 >
19 <Icon :name="iconLeft" :size="26" />
20 </div>
21 <div class="flex grow flex-col" :class="{ 'gap-1': size === 'small', 'gap-2': size === 'medium' }">
22 <div class="flex items-center justify-between gap-2">
23 <span
24 class="text-secondary transition-colors"
25 :class="{
26 'group-hover:text-primary': clickable,
27 'text-xs uppercase': size === 'small',
28 'text-sm': size === 'medium'
29 }"
30 >
31 <slot name="title">{{ title }}</slot>
32 </span>
33 <Icon
34 v-if="clickable"
35 :name="icon || 'carbon:arrow-up-right'"
36 class="group-hover:text-primary transition-colors"
37 />
38 <Icon v-else-if="icon" :name="icon" />
39 <slot name="header-extra" />
40 </div>
41 <slot />
42 <div
43 class="font-mono text-xl font-semibold"
44 :class="{
45 'text-warning': color === 'warning',
46 'text-success': color === 'success',
47 'text-error': color === 'danger',
48 'text-primary': color === 'primary'
49 }"
50 >
51 <slot name="value">{{ value }}</slot>
52 </div>
53 <div v-if="subtitle || $slots.subtitle" class="text-secondary text-xs">
54 <slot name="subtitle">{{ subtitle }}</slot>
55 </div>
56 </div>
57 </n-card>
58 </template>
59
60 <script setup lang="ts">
61 import { NCard } from "naive-ui"
62 import Icon from "@/components/common/Icon.vue"
63
64 export type CardLinkSize = "small" | "medium"
65 export type CardLinkColor = "warning" | "success" | "danger" | "primary"
66
67 withDefaults(
68 defineProps<{
69 title?: string | number
70 value?: string | number
71 subtitle?: string | number
72 hoverable?: boolean
73 clickable?: boolean
74 icon?: string
75 iconLeft?: string
76 size?: CardLinkSize
77 color?: CardLinkColor
78 }>(),
79 {
80 size: "medium"
81 }
82 )
83 </script>