@voidzero-dev/vitepress-theme 4.7.1 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {useData} from 'vitepress'
|
|
4
|
-
import { Icon } from '@iconify/vue'
|
|
2
|
+
import {inject} from 'vue'
|
|
5
3
|
import { themeContextKey } from '../../types/theme-context'
|
|
4
|
+
import FooterNav from './FooterNav.vue'
|
|
6
5
|
|
|
7
6
|
// Props for CTA section
|
|
8
7
|
withDefaults(defineProps<{
|
|
@@ -17,62 +16,7 @@ withDefaults(defineProps<{
|
|
|
17
16
|
buttonLink: '/guide/'
|
|
18
17
|
})
|
|
19
18
|
|
|
20
|
-
const {theme} = useData()
|
|
21
19
|
const { footerBg: backgroundImage } = inject(themeContextKey)!
|
|
22
|
-
|
|
23
|
-
// Social icon name mapping
|
|
24
|
-
const socialIconName = (icon: string): string => {
|
|
25
|
-
const key = icon.toLowerCase()
|
|
26
|
-
if (key === 'twitter') return 'simple-icons:x'
|
|
27
|
-
return `simple-icons:${key}`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Footer configuration from theme
|
|
31
|
-
interface FooterLink {
|
|
32
|
-
text: string
|
|
33
|
-
link: string
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface FooterColumn {
|
|
37
|
-
title: string
|
|
38
|
-
items: FooterLink[]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
interface SocialLink {
|
|
42
|
-
icon: string
|
|
43
|
-
link: string
|
|
44
|
-
label?: string
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface FooterConfig {
|
|
48
|
-
message?: string
|
|
49
|
-
copyright?: string
|
|
50
|
-
nav?: FooterColumn[]
|
|
51
|
-
social?: SocialLink[]
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const footerConfig = computed<FooterConfig>(() => {
|
|
55
|
-
const footer = theme.value.footer || {}
|
|
56
|
-
return footer as FooterConfig
|
|
57
|
-
})
|
|
58
|
-
const footerNav = computed(() => footerConfig.value.nav || [])
|
|
59
|
-
const footerSocial = computed(() => footerConfig.value.social || [])
|
|
60
|
-
const footerCopyright = computed(() =>
|
|
61
|
-
footerConfig.value.copyright || `© ${new Date().getFullYear()} VoidZero Inc. All Rights Reserved.`
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
// Get display label for social link
|
|
65
|
-
const getSocialLabel = (social: SocialLink): string => {
|
|
66
|
-
if (social.label) return social.label
|
|
67
|
-
const labels: Record<string, string> = {
|
|
68
|
-
github: 'GitHub',
|
|
69
|
-
discord: 'Discord',
|
|
70
|
-
bluesky: 'Bluesky',
|
|
71
|
-
twitter: 'X.com',
|
|
72
|
-
x: 'X.com',
|
|
73
|
-
}
|
|
74
|
-
return labels[social.icon.toLowerCase()] || social.icon
|
|
75
|
-
}
|
|
76
20
|
</script>
|
|
77
21
|
|
|
78
22
|
<template>
|
|
@@ -91,39 +35,7 @@ const getSocialLabel = (social: SocialLink): string => {
|
|
|
91
35
|
</a>
|
|
92
36
|
</div>
|
|
93
37
|
</div>
|
|
94
|
-
<div
|
|
95
|
-
class="px-5 md:px-24 pt-10 md:pt-16 pb-16 md:pb-40 flex flex-col md:flex-row gap-10 md:gap-0 md:justify-between">
|
|
96
|
-
<div class="flex flex-col md:flex-row gap-10 md:gap-20">
|
|
97
|
-
<div v-for="column in footerNav" :key="column.title">
|
|
98
|
-
<p class="text-grey text-xs font-mono uppercase tracking-wide mb-8">{{ column.title }}</p>
|
|
99
|
-
<ul class="flex flex-col gap-3">
|
|
100
|
-
<li v-for="item in column.items" :key="item.link">
|
|
101
|
-
<a :href="item.link" class="text-white text-base">{{ item.text }}</a>
|
|
102
|
-
</li>
|
|
103
|
-
</ul>
|
|
104
|
-
</div>
|
|
105
|
-
</div>
|
|
106
|
-
<div v-if="footerSocial.length">
|
|
107
|
-
<p class="text-grey text-xs font-mono uppercase tracking-wide mb-8">Social</p>
|
|
108
|
-
<ul class="flex flex-col gap-3">
|
|
109
|
-
<li v-for="social in footerSocial" :key="social.link">
|
|
110
|
-
<a :href="social.link" class="text-white text-base flex gap-3 items-center" target="_blank"
|
|
111
|
-
rel="noopener noreferrer">
|
|
112
|
-
<Icon :icon="socialIconName(social.icon)" class="size-[18px]" :aria-label="getSocialLabel(social)" />
|
|
113
|
-
{{ getSocialLabel(social) }}
|
|
114
|
-
</a>
|
|
115
|
-
</li>
|
|
116
|
-
</ul>
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
|
-
</section>
|
|
120
|
-
<section
|
|
121
|
-
class="wrapper wrapper--ticks border-t py-5 px-5 md:px-24 flex flex-col md:flex-row gap-3 md:gap-0 justify-between items-start md:items-center">
|
|
122
|
-
<p class="text-sm">{{ footerCopyright }}</p>
|
|
123
|
-
<div class="gap-10 text-sm hidden md:flex">
|
|
124
|
-
<!-- <a href="https://voidzero.dev/terms" class="text-grey">Terms & Conditions</a>
|
|
125
|
-
<a href="https://voidzero.dev/privacy" class="text-grey">Privacy Policy</a>-->
|
|
126
|
-
</div>
|
|
127
38
|
</section>
|
|
39
|
+
<FooterNav />
|
|
128
40
|
</footer>
|
|
129
41
|
</template>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {computed} from 'vue'
|
|
3
|
+
import {useData} from 'vitepress'
|
|
4
|
+
import { Icon } from '@iconify/vue'
|
|
5
|
+
|
|
6
|
+
const {theme} = useData()
|
|
7
|
+
|
|
8
|
+
// Social icon name mapping
|
|
9
|
+
const socialIconName = (icon: string): string => {
|
|
10
|
+
const key = icon.toLowerCase()
|
|
11
|
+
if (key === 'twitter') return 'simple-icons:x'
|
|
12
|
+
return `simple-icons:${key}`
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Footer configuration from theme
|
|
16
|
+
interface FooterLink {
|
|
17
|
+
text: string
|
|
18
|
+
link: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface FooterColumn {
|
|
22
|
+
title: string
|
|
23
|
+
items: FooterLink[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface SocialLink {
|
|
27
|
+
icon: string
|
|
28
|
+
link: string
|
|
29
|
+
label?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface FooterConfig {
|
|
33
|
+
message?: string
|
|
34
|
+
copyright?: string
|
|
35
|
+
nav?: FooterColumn[]
|
|
36
|
+
social?: SocialLink[]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const footerConfig = computed<FooterConfig>(() => {
|
|
40
|
+
const footer = theme.value.footer || {}
|
|
41
|
+
return footer as FooterConfig
|
|
42
|
+
})
|
|
43
|
+
const footerNav = computed(() => footerConfig.value.nav || [])
|
|
44
|
+
const footerSocial = computed(() => footerConfig.value.social || [])
|
|
45
|
+
const footerCopyright = computed(() =>
|
|
46
|
+
footerConfig.value.copyright || `© ${new Date().getFullYear()} VoidZero Inc. All Rights Reserved.`
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
// Get display label for social link
|
|
50
|
+
const getSocialLabel = (social: SocialLink): string => {
|
|
51
|
+
if (social.label) return social.label
|
|
52
|
+
const labels: Record<string, string> = {
|
|
53
|
+
github: 'GitHub',
|
|
54
|
+
discord: 'Discord',
|
|
55
|
+
bluesky: 'Bluesky',
|
|
56
|
+
twitter: 'X.com',
|
|
57
|
+
x: 'X.com',
|
|
58
|
+
}
|
|
59
|
+
return labels[social.icon.toLowerCase()] || social.icon
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<div>
|
|
65
|
+
<section class="wrapper wrapper--ticks border-t">
|
|
66
|
+
<div
|
|
67
|
+
class="px-5 md:px-24 pt-10 md:pt-16 pb-16 md:pb-40 flex flex-col md:flex-row gap-10 md:gap-0 md:justify-between">
|
|
68
|
+
<div class="flex flex-col md:flex-row gap-10 md:gap-20">
|
|
69
|
+
<div v-for="column in footerNav" :key="column.title">
|
|
70
|
+
<p class="text-[var(--vp-c-text-2)] text-xs font-mono uppercase tracking-wide mb-8">{{ column.title }}</p>
|
|
71
|
+
<ul class="flex flex-col gap-3">
|
|
72
|
+
<li v-for="item in column.items" :key="item.link">
|
|
73
|
+
<a :href="item.link" class="text-[var(--vp-c-text-1)] text-base">{{ item.text }}</a>
|
|
74
|
+
</li>
|
|
75
|
+
</ul>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
<div v-if="footerSocial.length">
|
|
79
|
+
<p class="text-[var(--vp-c-text-2)] text-xs font-mono uppercase tracking-wide mb-8">Social</p>
|
|
80
|
+
<ul class="flex flex-col gap-3">
|
|
81
|
+
<li v-for="social in footerSocial" :key="social.link">
|
|
82
|
+
<a :href="social.link" class="text-[var(--vp-c-text-1)] text-base flex gap-3 items-center" target="_blank"
|
|
83
|
+
rel="noopener noreferrer">
|
|
84
|
+
<Icon :icon="socialIconName(social.icon)" class="size-[18px]" :aria-label="getSocialLabel(social)" />
|
|
85
|
+
{{ getSocialLabel(social) }}
|
|
86
|
+
</a>
|
|
87
|
+
</li>
|
|
88
|
+
</ul>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</section>
|
|
92
|
+
<section
|
|
93
|
+
class="wrapper wrapper--ticks border-t py-5 px-5 md:px-24 flex flex-col md:flex-row gap-3 md:gap-0 justify-between items-start md:items-center">
|
|
94
|
+
<p class="text-sm">{{ footerCopyright }}</p>
|
|
95
|
+
<div class="gap-10 text-sm hidden md:flex">
|
|
96
|
+
<!-- <a href="https://voidzero.dev/terms" class="text-grey">Terms & Conditions</a>
|
|
97
|
+
<a href="https://voidzero.dev/privacy" class="text-grey">Privacy Policy</a>-->
|
|
98
|
+
</div>
|
|
99
|
+
</section>
|
|
100
|
+
</div>
|
|
101
|
+
</template>
|