17
17
<div v-else class =" image-placeholder" >
18
18
<Icon :name =" item.icon" size =" 3em" color =" var(--vp-c-brand)" />
19
19
</div >
20
+ <div v-if =" item.priceLabel" class =" price-corner-tag" >
21
+ <span class =" price-corner-text" >{{ item.priceLabel }}</span >
22
+ </div >
20
23
</div >
21
24
<div class =" card-content" >
22
- <h3 class =" card-title" >{{ item.title }}</h3 >
23
- <p class =" card-description" >{{ item.description }}</p >
24
- <div class =" card-tags" >
25
- <span
26
- v-for =" (tag, tagIndex) in item.tags"
27
- :key =" tagIndex"
28
- class =" badge"
29
- :style =" getTagColors(tag)"
30
- >{{ tag }}</span >
31
- </div >
32
- <div class =" card-footer" >
25
+ <div class =" card-header" >
33
26
<div class =" item-developer-info" >
34
27
<img
35
28
:src =" getGithubAvatarUrl(item.githubUser)"
40
33
{{ item.githubUser }}
41
34
</span >
42
35
</div >
43
- <div v-if =" !item.link" class =" built-in-label" >内置</div >
44
36
<a
45
- v-else
37
+ v-if = " item.link "
46
38
:href =" item.link"
47
39
class =" github-link no-external-icon"
48
40
target =" _blank"
49
41
rel =" noopener noreferrer"
50
42
aria-label =" GitHub仓库"
51
43
@click.stop
52
44
>
53
- <Icon name =" mdi:github" size =" 1.5em " color =" var(--vp-c-text-2)" />
45
+ <Icon name =" mdi:github" size =" 1.1em " color =" var(--vp-c-text-2)" />
54
46
</a >
47
+ <span v-else class =" built-in-label-inline" >内置</span >
48
+ </div >
49
+ <h3 class =" card-title" >{{ item.title }}</h3 >
50
+ <p class =" card-description" >{{ item.description }}</p >
51
+ <div class =" card-tags" >
52
+ <span
53
+ v-for =" (tag, tagIndex) in item.tags"
54
+ :key =" tagIndex"
55
+ class =" badge"
56
+ :style =" getTagColors(tag)"
57
+ >{{ tag }}</span >
55
58
</div >
56
59
</div >
57
60
</div >
58
61
</div >
59
62
</template >
60
63
61
64
<script setup lang="ts">
65
+ import type { CSSProperties } from ' vue' ;
62
66
63
67
export interface PluginItem {
64
68
icon: string
@@ -68,6 +72,7 @@ export interface PluginItem {
68
72
link? : string
69
73
image? : string
70
74
githubUser: string
75
+ priceLabel? : ' 免费' | ' 付费'
71
76
}
72
77
73
78
const props = withDefaults (
@@ -80,32 +85,31 @@ const props = withDefaults(
80
85
}
81
86
)
82
87
83
- interface TagColors {
84
- color? : string
85
- backgroundColor? : string
86
- borderColor? : string
88
+ interface TagColors extends CSSProperties {
87
89
}
88
90
89
91
const getTagColors = (tag : string ): TagColors => {
90
92
const colors: Record <string , TagColors > = {
91
93
' MySQL' : { color: ' #006484' , backgroundColor: ' rgba(0, 100, 132, 0.1)' , borderColor: ' rgba(0, 100, 132, 0.2)' },
92
- ' PostgreSQL' : { color: ' #336699' , backgroundColor: ' rgba(51, 102, 153, 0.1)' , borderColor: ' rgba(51, 102, 153, 0.2)' },
94
+ ' PostgreSQL' : {
95
+ color: ' #336699' ,
96
+ backgroundColor: ' rgba(51, 102, 153, 0.1)' ,
97
+ borderColor: ' rgba(51, 102, 153, 0.2)'
98
+ },
93
99
' fba' : { color: ' #8b5cf6' , backgroundColor: ' rgba(139, 92, 246, 0.1)' , borderColor: ' rgba(139, 92, 246, 0.2)' },
94
100
' fba_ui' : { color: ' #a855f7' , backgroundColor: ' rgba(168, 85, 247, 0.1)' , borderColor: ' rgba(168, 85, 247, 0.2)' },
95
101
' app' : { color: ' #f97316' , backgroundColor: ' rgba(249, 115, 22, 0.1)' , borderColor: ' rgba(249, 115, 22, 0.2)' },
96
102
' extra' : { color: ' #64748b' , backgroundColor: ' rgba(100, 116, 139, 0.1)' , borderColor: ' rgba(100, 116, 139, 0.2)' },
97
- ' pay' : { color: ' #ef4444' , backgroundColor: ' rgba(239, 68, 68, 0.1)' , borderColor: ' rgba(239, 68, 68, 0.2)' },
98
- ' free' : { color: ' #10b981' , backgroundColor: ' rgba(16, 185, 129, 0.1)' , borderColor: ' rgba(16, 185, 129, 0.2)' }
99
103
};
100
104
return colors [tag ] || {
101
105
color: ' var(--vp-c-text-2)' ,
102
106
backgroundColor: ' var(--vp-c-bg-soft)' ,
103
- borderColor: ' var(--vp-c-divider-light )'
107
+ borderColor: ' var(--vp-c-divider)'
104
108
};
105
109
}
106
110
107
111
const getGithubAvatarUrl = (username : string ) => {
108
- return ` https://github.com/${username }.png?size=32 ` ;
112
+ return ` https://github.com/${ username }.png?size=32 ` ;
109
113
};
110
114
111
115
const handleCardClick = (item : PluginItem ) => {
@@ -183,51 +187,13 @@ const handleCardClick = (item: PluginItem) => {
183
187
flex-grow : 1 ;
184
188
display : flex ;
185
189
flex-direction : column ;
186
- justify-content : space-between ;
187
- }
188
-
189
- .card-title {
190
- font-size : 1rem ;
191
- font-weight : 600 ;
192
- color : var (--vp-c-text-1 );
193
- margin : 0 0 0.4rem 0 ;
194
- line-height : 1.4 ;
195
- }
196
-
197
- .card-description {
198
- color : var (--vp-c-text-2 );
199
- font-size : 0.85rem ;
200
- line-height : 1.5 ;
201
- margin : 0 0 0.8rem 0 ;
202
- flex-grow : 1 ;
203
- }
204
-
205
- .card-tags {
206
- display : flex ;
207
- flex-wrap : wrap ;
208
- align-items : center ;
209
- gap : 0.4rem ;
210
- margin-bottom : 0.8rem ;
211
- }
212
-
213
- .badge {
214
- display : inline-flex ;
215
- align-items : center ;
216
- justify-content : center ;
217
- padding : 0.1rem 0.5rem ;
218
- border-radius : 4px ;
219
- font-size : 0.75rem ;
220
- line-height : 1 ;
221
- font-weight : 500 ;
222
- white-space : nowrap ;
223
- border : 1px solid transparent ;
224
190
}
225
191
226
- .card-footer {
192
+ .card-header {
227
193
display : flex ;
228
194
justify-content : space-between ;
229
195
align-items : center ;
230
- gap : 0.5 rem ;
196
+ margin-bottom : 0.8 rem ; /* Space below the header */
231
197
}
232
198
233
199
.item-developer-info {
@@ -256,25 +222,74 @@ const handleCardClick = (item: PluginItem) => {
256
222
}
257
223
258
224
.github-link {
259
- transition : all 0.2s ease ;
260
- pointer-events : none ;
225
+ color : var (--vp-c-text-2 );
226
+ transition : color 0.2s ease ;
227
+ pointer-events : auto ; /* Allow clicks on the icon */
228
+ flex-shrink : 0 ;
229
+ display : inline-flex ;
230
+ align-items : center ;
231
+ margin-left : 0.5rem ; /* Space between developer info and icon */
232
+ }
233
+
234
+ .github-link :hover {
235
+ color : var (--vp-c-brand );
261
236
}
262
237
263
238
.no-external-icon ::after {
264
239
content : none !important ;
265
240
}
266
241
267
- .built-in-label {
268
- font-size : 0.85 rem ;
242
+ .built-in-label-inline {
243
+ font-size : 0.75 rem ;
269
244
color : var (--vp-c-text-2 );
270
- padding : 0 ;
271
- border-radius : 0 ;
245
+ padding : 0.1rem 0.4rem ;
246
+ border-radius : 4px ;
247
+ border : 1px solid var (--vp-c-divider );
248
+ background-color : var (--vp-c-bg-soft );
272
249
flex-shrink : 0 ;
273
- margin-left : auto ;
250
+ margin-left : 0.5 rem ; /* Space between developer info and label */
274
251
white-space : nowrap ;
275
252
font-weight : 500 ;
276
253
}
277
254
255
+
256
+ .card-title {
257
+ font-size : 1rem ;
258
+ font-weight : 600 ;
259
+ color : var (--vp-c-text-1 );
260
+ margin : 0 0 0.4rem 0 ;
261
+ line-height : 1.4 ;
262
+ }
263
+
264
+ .card-description {
265
+ color : var (--vp-c-text-2 );
266
+ font-size : 0.85rem ;
267
+ line-height : 1.5 ;
268
+ margin : 0 0 0.8rem 0 ;
269
+ flex-grow : 1 ;
270
+ }
271
+
272
+ .card-tags {
273
+ display : flex ;
274
+ flex-wrap : wrap ;
275
+ align-items : center ;
276
+ gap : 0.4rem ;
277
+ margin-top : auto ;
278
+ }
279
+
280
+ .badge {
281
+ display : inline-flex ;
282
+ align-items : center ;
283
+ justify-content : center ;
284
+ padding : 0.1rem 0.5rem ;
285
+ border-radius : 4px ;
286
+ font-size : 0.75rem ;
287
+ line-height : 1 ;
288
+ font-weight : 500 ;
289
+ white-space : nowrap ;
290
+ border : 1px solid transparent ;
291
+ }
292
+
278
293
@media (min-width : 768px ) {
279
294
.plugin-card-container {
280
295
grid-template-columns : repeat (2 , 1fr );
0 commit comments