@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,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidzero-dev/vitepress-theme",
3
- "version": "4.7.1",
3
+ "version": "4.8.1",
4
4
  "description": "Shared VitePress theme for VoidZero projects",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -1,8 +1,7 @@
1
1
  <script setup lang="ts">
2
- import {computed, inject} from 'vue'
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>