返回 slidev
FeatureTag.vue
根目录 / docs / .vitepress / theme / components / FeatureTag.vue
1 <script setup lang="ts">
2 import { useData, withBase } from 'vitepress'
3 import { computed } from 'vue'
4
5 const props = defineProps<{
6 tag: string
7 removable?: boolean
8 noclick?: boolean
9 }>()
10 const emit = defineEmits(['remove'])
11
12 const { isDark } = useData()
13
14 function getHashColorFromString(
15 name: string,
16 opacity: number | string = 1,
17 ) {
18 name += 'salt'
19 let hash = 0
20 for (let i = 0; i < name.length; i++)
21 hash = name.charCodeAt(i) + ((hash << 5) - hash)
22 const h = hash % 360
23 return getHsla(h, opacity)
24 }
25
26 function getHsla(
27 hue: number,
28 opacity: number | string = 1,
29 ) {
30 const saturation = isDark.value ? 50 : 65
31 const lightness = isDark.value ? 60 : 40
32 return `hsla(${hue}, ${saturation}%, ${lightness}%, ${opacity})`
33 }
34
35 const formattedTag = computed(() => {
36 let tag = props.tag
37 if (tag === tag.toUpperCase()) {
38 return tag
39 }
40 tag = tag.replace(/\b(API|CLI)\b/gi, m => m.toUpperCase())
41 .replace(/-/g, ' ')
42 return tag[0].toUpperCase() + tag.slice(1)
43 })
44
45 const colors = computed(() => {
46 return [
47 getHashColorFromString(props.tag),
48 getHashColorFromString(props.tag, 0.7),
49 getHashColorFromString(props.tag, 0.5),
50 getHashColorFromString(props.tag, 0.2),
51 getHashColorFromString(props.tag, 0.1),
52 ]
53 })
54 </script>
55
56 <template>
57 <a v-if="props.removable" class="feature-tag flex gap-1 items-center">
58 {{ formattedTag }}
59 <button class="flex items-center op-70 hover:bg-gray-200/20 hover:op90 rounded-full mr--1" @click="emit('remove')">
60 <div class="i-carbon:close" />
61 </button>
62 </a>
63 <span v-else-if="props.noclick" class="feature-tag">
64 {{ formattedTag }}
65 </span>
66 <a v-else class="feature-tag" :href="withBase(`/features/#tags=${tag}`)">
67 {{ formattedTag }}
68 </a>
69 </template>
70
71 <style scoped>
72 .feature-tag {
73 --uno: 'text-sm px-2 py-.5 rounded-md select-none !decoration-none border border-solid h-max';
74 background-color: v-bind('colors[4]');
75 color: v-bind('colors[0]') !important;
76 border-color: v-bind('colors[3]');
77 }
78
79 .feature-tag:hover {
80 background-color: v-bind('colors[3]');
81 }
82 </style>
83
83 lines Plain Text