1717 <div v-else class =" image-placeholder" >
1818 <Icon :name =" item.icon" size =" 3em" color =" var(--vp-c-brand)" />
1919 </div >
20+ <div v-if =" item.priceLabel" class =" price-corner-tag" >
21+ <span class =" price-corner-text" >{{ item.priceLabel }}</span >
22+ </div >
2023 </div >
2124 <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" >
3326 <div class =" item-developer-info" >
3427 <img
3528 :src =" getGithubAvatarUrl(item.githubUser)"
4033 {{ item.githubUser }}
4134 </span >
4235 </div >
43- <div v-if =" !item.link" class =" built-in-label" >内置</div >
4436 <a
45- v-else
37+ v-if = " item.link "
4638 :href =" item.link"
4739 class =" github-link no-external-icon"
4840 target =" _blank"
4941 rel =" noopener noreferrer"
5042 aria-label =" GitHub仓库"
5143 @click.stop
5244 >
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)" />
5446 </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 >
5558 </div >
5659 </div >
5760 </div >
5861 </div >
5962</template >
6063
6164<script setup lang="ts">
65+ import type { CSSProperties } from ' vue' ;
6266
6367export interface PluginItem {
6468 icon: string
@@ -68,6 +72,7 @@ export interface PluginItem {
6872 link? : string
6973 image? : string
7074 githubUser: string
75+ priceLabel? : ' 免费' | ' 付费'
7176}
7277
7378const props = withDefaults (
@@ -80,32 +85,31 @@ const props = withDefaults(
8085 }
8186)
8287
83- interface TagColors {
84- color? : string
85- backgroundColor? : string
86- borderColor? : string
88+ interface TagColors extends CSSProperties {
8789}
8890
8991const getTagColors = (tag : string ): TagColors => {
9092 const colors: Record <string , TagColors > = {
9193 ' 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+ },
9399 ' fba' : { color: ' #8b5cf6' , backgroundColor: ' rgba(139, 92, 246, 0.1)' , borderColor: ' rgba(139, 92, 246, 0.2)' },
94100 ' fba_ui' : { color: ' #a855f7' , backgroundColor: ' rgba(168, 85, 247, 0.1)' , borderColor: ' rgba(168, 85, 247, 0.2)' },
95101 ' app' : { color: ' #f97316' , backgroundColor: ' rgba(249, 115, 22, 0.1)' , borderColor: ' rgba(249, 115, 22, 0.2)' },
96102 ' 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)' }
99103 };
100104 return colors [tag ] || {
101105 color: ' var(--vp-c-text-2)' ,
102106 backgroundColor: ' var(--vp-c-bg-soft)' ,
103- borderColor: ' var(--vp-c-divider-light )'
107+ borderColor: ' var(--vp-c-divider)'
104108 };
105109}
106110
107111const getGithubAvatarUrl = (username : string ) => {
108- return ` https://github.com/${username }.png?size=32 ` ;
112+ return ` https://github.com/${ username }.png?size=32 ` ;
109113};
110114
111115const handleCardClick = (item : PluginItem ) => {
@@ -183,51 +187,13 @@ const handleCardClick = (item: PluginItem) => {
183187 flex-grow : 1 ;
184188 display : flex ;
185189 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 ;
224190}
225191
226- .card-footer {
192+ .card-header {
227193 display : flex ;
228194 justify-content : space-between ;
229195 align-items : center ;
230- gap : 0.5 rem ;
196+ margin-bottom : 0.8 rem ; /* Space below the header */
231197}
232198
233199.item-developer-info {
@@ -256,25 +222,74 @@ const handleCardClick = (item: PluginItem) => {
256222}
257223
258224.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 );
261236}
262237
263238.no-external-icon ::after {
264239 content : none !important ;
265240}
266241
267- .built-in-label {
268- font-size : 0.85 rem ;
242+ .built-in-label-inline {
243+ font-size : 0.75 rem ;
269244 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 );
272249 flex-shrink : 0 ;
273- margin-left : auto ;
250+ margin-left : 0.5 rem ; /* Space between developer info and label */
274251 white-space : nowrap ;
275252 font-weight : 500 ;
276253}
277254
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+
278293@media (min-width : 768px ) {
279294 .plugin-card-container {
280295 grid-template-columns : repeat (2 , 1fr );
0 commit comments