57 lines
1.8 KiB
Vue
57 lines
1.8 KiB
Vue
<script setup lang="ts">
|
|
import { Download, BadgeCheck, ArrowUpRight } from '@lucide/vue'
|
|
import type { Theme } from '../types'
|
|
import { previewUrl, modeLabel } from '../site'
|
|
defineProps<{ theme: Theme }>()
|
|
defineEmits<{ open: [theme: Theme]; preview: [theme: Theme] }>()
|
|
</script>
|
|
<template>
|
|
<article class="theme-card">
|
|
<button
|
|
class="theme-swatch"
|
|
:class="`swatch-${theme.needTheme}`"
|
|
:aria-label="`查看 ${theme.name}${theme.previewUrl ? ' 的预览' : ' 的详情'}`"
|
|
@click="theme.previewUrl ? $emit('preview', theme) : $emit('open', theme)"
|
|
>
|
|
<img
|
|
v-if="previewUrl(theme.previewUrl)"
|
|
:src="previewUrl(theme.previewUrl)"
|
|
:alt="`${theme.name} 预览`"
|
|
loading="lazy"
|
|
/>
|
|
<span v-else class="swatch-window">
|
|
<span class="window-dots">● ● ●</span>
|
|
<span class="swatch-lines">
|
|
<i />
|
|
<i />
|
|
<i />
|
|
</span>
|
|
<span class="swatch-brand">
|
|
Aa
|
|
<span>AutoLibrary</span>
|
|
</span>
|
|
</span>
|
|
</button>
|
|
<div class="theme-card-body">
|
|
<button class="theme-card-title" @click="$emit('open', theme)">
|
|
<span>{{ theme.name }}</span>
|
|
<BadgeCheck v-if="theme.verified" class="accent" :size="17" aria-label="认证作者" />
|
|
<ArrowUpRight class="theme-card-arrow" :size="17" />
|
|
</button>
|
|
<p class="caption">{{ theme.author }} · {{ theme.version }}</p>
|
|
<p class="theme-brief">{{ theme.brief }}</p>
|
|
<div class="tags">
|
|
<span v-for="tag in theme.tags" :key="tag">{{ tag }}</span>
|
|
</div>
|
|
<div class="theme-card-meta">
|
|
<span>{{ modeLabel(theme.needTheme) }}</span>
|
|
<span>
|
|
<Download :size="13" />
|
|
{{ theme.downloadCount }}
|
|
</span>
|
|
</div>
|
|
<slot />
|
|
</div>
|
|
</article>
|
|
</template>
|