@voidzero-dev/vitepress-theme 4.0.0 → 4.0.2
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/README.md +50 -22
- package/package.json +2 -2
- package/src/components/oss/Header.vue +22 -3
- package/src/components/vitepress-default/VPLocalNavOutlineDropdown.vue +1 -0
- package/src/oxc.ts +1 -1
- package/src/rolldown.ts +1 -1
- package/src/styles/index.css +0 -14
- package/src/styles/marketing.css +2 -2
- package/src/styles/vitepress-default/components/vp-doc.css +3 -3
- package/src/vitest.ts +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,44 @@
|
|
|
1
1
|
# @voidzero-dev/vitepress-theme
|
|
2
2
|
|
|
3
|
-
Shared VitePress theme for VoidZero projects, including Vite+, Vite, Vitest, Rolldown, and
|
|
3
|
+
Shared VitePress theme for VoidZero projects, including Vite+, Vite, Vitest, Rolldown, and Oxc.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Publishing package
|
|
6
|
+
|
|
7
|
+
Make to sure to in latest commit
|
|
8
|
+
|
|
9
|
+
1. Update version in `package.json`
|
|
10
|
+
2. Add tag locally `git tag vx.y.z` (matching version in package.json)
|
|
11
|
+
3. Push changes `git push origin`
|
|
12
|
+
4. Push to remote `git push origin vx.y.z`
|
|
13
|
+
5. Go to GitHub UI > "Releases" > "Tags" > Click the latest tag > "Create release from tag"
|
|
14
|
+
6. Click "Publish release"
|
|
15
|
+
|
|
16
|
+
## Developing locally
|
|
17
|
+
|
|
18
|
+
For local development, linking is required between this theme directory and the downstream VoidZero project directories.
|
|
19
|
+
|
|
20
|
+
1. Link theme into docs repos
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# In theme
|
|
24
|
+
pnpm install
|
|
25
|
+
# Make @voidzero-dev/vitepress-theme available for global linking
|
|
26
|
+
pnpm link --global
|
|
27
|
+
|
|
28
|
+
# In project docs
|
|
29
|
+
pnpm install
|
|
30
|
+
# Link to theme
|
|
31
|
+
pnpm link @voidzero-dev/vitepress-theme
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. Start VitePress server:
|
|
6
35
|
|
|
7
36
|
```bash
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
pnpm add @voidzero-dev/vitepress-theme
|
|
37
|
+
# In project docs
|
|
38
|
+
pnpm dev
|
|
11
39
|
```
|
|
12
40
|
|
|
13
|
-
|
|
41
|
+
The downstream project will automatically reflect theme changes via HMR.
|
|
14
42
|
|
|
15
43
|
## Usage
|
|
16
44
|
|
|
@@ -19,21 +47,21 @@ If developing locally, run `pnpm link` between the two directories instead.
|
|
|
19
47
|
In your `.vitepress/config.ts`:
|
|
20
48
|
|
|
21
49
|
```ts
|
|
22
|
-
import { defineConfig } from
|
|
23
|
-
import { extendConfig } from
|
|
50
|
+
import { defineConfig } from "vitepress";
|
|
51
|
+
import { extendConfig } from "@voidzero-dev/vitepress-theme/config";
|
|
24
52
|
|
|
25
53
|
const config = defineConfig({
|
|
26
54
|
themeConfig: {
|
|
27
|
-
variant:
|
|
55
|
+
variant: "viteplus", // or 'vite', 'vitest', etc.
|
|
28
56
|
nav: [
|
|
29
|
-
{ text:
|
|
57
|
+
{ text: "Home", link: "/" },
|
|
30
58
|
// ... your navigation
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
})
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
});
|
|
34
62
|
|
|
35
63
|
// inject theme specific config
|
|
36
|
-
export default extendConfig(config)
|
|
64
|
+
export default extendConfig(config);
|
|
37
65
|
```
|
|
38
66
|
|
|
39
67
|
Note the theme config injects the Tailwind plugin so the downstream project doesn't have to. If the downstream project
|
|
@@ -43,14 +71,14 @@ Note the theme config injects the Tailwind plugin so the downstream project does
|
|
|
43
71
|
In your `.vitepress/theme/index.ts`:
|
|
44
72
|
|
|
45
73
|
```ts
|
|
46
|
-
import type { Theme } from
|
|
47
|
-
import Theme from
|
|
48
|
-
import
|
|
74
|
+
import type { Theme } from "vitepress";
|
|
75
|
+
import Theme from "@voidzero-dev/vitepress-theme";
|
|
76
|
+
import "./styles.css";
|
|
49
77
|
|
|
50
78
|
export default {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} satisfies Theme
|
|
79
|
+
extends: BaseTheme as unknown as Theme,
|
|
80
|
+
Layout,
|
|
81
|
+
} satisfies Theme;
|
|
54
82
|
```
|
|
55
83
|
|
|
56
84
|
In the CSS, import the CSS from theme (which imports tailwind):
|
|
@@ -63,7 +91,7 @@ In the CSS, import the CSS from theme (which imports tailwind):
|
|
|
63
91
|
|
|
64
92
|
/* Project specific branding colors */
|
|
65
93
|
:root[data-variant="vite"] {
|
|
66
|
-
--color-brand: #
|
|
94
|
+
--color-brand: #6b1eb9;
|
|
67
95
|
}
|
|
68
96
|
|
|
69
97
|
:root.dark:not([data-theme])[data-variant="vite"],
|
|
@@ -72,6 +100,6 @@ In the CSS, import the CSS from theme (which imports tailwind):
|
|
|
72
100
|
}
|
|
73
101
|
|
|
74
102
|
:root[data-theme="light"][data-variant="vite"] {
|
|
75
|
-
--color-brand: #
|
|
103
|
+
--color-brand: #6b1eb9;
|
|
76
104
|
}
|
|
77
105
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voidzero-dev/vitepress-theme",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Shared VitePress theme for VoidZero projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"*.css"
|
|
16
16
|
],
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"vitepress": "^2.0.0-alpha.
|
|
18
|
+
"vitepress": "^2.0.0-alpha.15",
|
|
19
19
|
"vue": "^3.5.0"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
@@ -4,6 +4,7 @@ import { normalizeLink } from '@vp-support/utils'
|
|
|
4
4
|
import { ref, computed, onMounted, onUnmounted, watch, nextTick, inject } from 'vue'
|
|
5
5
|
import { getSearchProvider } from '@vp-support/search-config'
|
|
6
6
|
import { themeContextKey } from '../../types/theme-context'
|
|
7
|
+
import { EXTERNAL_URL_RE } from '../../support/vitepress-default/shared-utils'
|
|
7
8
|
|
|
8
9
|
// Import VitePress header components
|
|
9
10
|
import VPNavBarSearch from '@vp-default/VPNavBarSearch.vue'
|
|
@@ -49,6 +50,9 @@ const languageMenuOpen = ref(false)
|
|
|
49
50
|
// Check if nav item is a dropdown (has children)
|
|
50
51
|
const isDropdown = (item: any) => 'items' in item && Array.isArray(item.items)
|
|
51
52
|
|
|
53
|
+
// Check if a link is external
|
|
54
|
+
const isExternalLink = (link: string) => EXTERNAL_URL_RE.test(link)
|
|
55
|
+
|
|
52
56
|
// Toggle accordion for dropdown items
|
|
53
57
|
const toggleAccordion = (index: number) => {
|
|
54
58
|
if (expandedAccordions.value.has(index)) {
|
|
@@ -314,7 +318,12 @@ onUnmounted(() => {
|
|
|
314
318
|
<!-- Direct link item -->
|
|
315
319
|
<li v-if="'link' in childItem">
|
|
316
320
|
<a :href="normalizeLink(childItem.link)" @click="closeMobileMenu"
|
|
317
|
-
:
|
|
321
|
+
:target="isExternalLink(childItem.link) ? '_blank' : undefined"
|
|
322
|
+
:rel="isExternalLink(childItem.link) ? 'noreferrer' : undefined"
|
|
323
|
+
:class="[
|
|
324
|
+
{ 'bg-primary/10 dark:bg-white/10': route.path === normalizeLink(childItem.link) },
|
|
325
|
+
{ 'vp-external-link-icon': isExternalLink(childItem.link) }
|
|
326
|
+
]"
|
|
318
327
|
class="block py-2 px-4 text-base font-sans text-grey dark:text-white/80 hover:text-primary dark:hover:text-white">
|
|
319
328
|
{{ childItem.text }}
|
|
320
329
|
</a>
|
|
@@ -328,7 +337,12 @@ onUnmounted(() => {
|
|
|
328
337
|
<ul class="space-y-1">
|
|
329
338
|
<li v-for="nestedItem in childItem.items" :key="nestedItem.link || nestedItem.text">
|
|
330
339
|
<a v-if="nestedItem.link" :href="normalizeLink(nestedItem.link)" @click="closeMobileMenu"
|
|
331
|
-
:
|
|
340
|
+
:target="isExternalLink(nestedItem.link) ? '_blank' : undefined"
|
|
341
|
+
:rel="isExternalLink(nestedItem.link) ? 'noreferrer' : undefined"
|
|
342
|
+
:class="[
|
|
343
|
+
{ 'bg-primary/10 dark:bg-white/10': route.path === normalizeLink(nestedItem.link) },
|
|
344
|
+
{ 'vp-external-link-icon': isExternalLink(nestedItem.link) }
|
|
345
|
+
]"
|
|
332
346
|
class="block py-2 px-4 text-base font-sans text-grey dark:text-white/80 hover:text-primary dark:hover:text-white">
|
|
333
347
|
{{ nestedItem.text }}
|
|
334
348
|
</a>
|
|
@@ -340,7 +354,12 @@ onUnmounted(() => {
|
|
|
340
354
|
</template>
|
|
341
355
|
<!-- Regular link item -->
|
|
342
356
|
<a v-else-if="navItem.link" :href="normalizeLink(navItem.link)" @click="closeMobileMenu"
|
|
343
|
-
:
|
|
357
|
+
:target="isExternalLink(navItem.link) ? '_blank' : undefined"
|
|
358
|
+
:rel="isExternalLink(navItem.link) ? 'noreferrer' : undefined"
|
|
359
|
+
:class="[
|
|
360
|
+
{ 'bg-primary/10 dark:bg-white/10': route.path === normalizeLink(navItem.link) },
|
|
361
|
+
{ 'vp-external-link-icon': isExternalLink(navItem.link) }
|
|
362
|
+
]"
|
|
344
363
|
class="block py-3 px-4 text-lg font-sans text-primary dark:text-white">
|
|
345
364
|
{{ navItem.text }}
|
|
346
365
|
</a>
|
package/src/oxc.ts
CHANGED
package/src/rolldown.ts
CHANGED
package/src/styles/index.css
CHANGED
|
@@ -48,17 +48,3 @@
|
|
|
48
48
|
:root[data-theme="light"] {
|
|
49
49
|
--color-brand: var(--color-electric);
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
/* Rolldown */
|
|
53
|
-
:root[data-variant="rolldown"] {
|
|
54
|
-
--color-brand: #D44803;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
:root.dark:not([data-theme])[data-variant="rolldown"],
|
|
58
|
-
:root[data-theme="dark"][data-variant="rolldown"] {
|
|
59
|
-
--color-brand: var(--color-fire);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
:root[data-theme="light"][data-variant="rolldown"] {
|
|
63
|
-
--color-brand: #D44803;
|
|
64
|
-
}
|
package/src/styles/marketing.css
CHANGED
|
@@ -82,11 +82,11 @@
|
|
|
82
82
|
border-left: 5px solid transparent;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
.dark .wrapper--ticks::before, .dark .tick-left::before {
|
|
86
86
|
border-left-color: var(--color-nickel);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
.dark .wrapper--ticks::after, .dark .tick-right::after {
|
|
90
90
|
border-right-color: var(--color-nickel);
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -542,12 +542,12 @@
|
|
|
542
542
|
display: inline-block;
|
|
543
543
|
margin-top: -1px;
|
|
544
544
|
margin-left: 4px;
|
|
545
|
-
width:
|
|
546
|
-
height:
|
|
545
|
+
width: 12px;
|
|
546
|
+
height: 12px;
|
|
547
547
|
background: currentColor;
|
|
548
548
|
color: var(--vp-c-text-3);
|
|
549
549
|
flex-shrink: 0;
|
|
550
|
-
--icon: url("data:image/svg+xml
|
|
550
|
+
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.81802 2.81803L9.18198 2.81803L9.18198 9.18199' stroke='black' stroke-width='1.25' stroke-linejoin='round'/%3E%3Cpath d='M9.18213 2.81802L2.81817 9.18198' stroke='black' stroke-width='1.25' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
551
551
|
-webkit-mask-image: var(--icon);
|
|
552
552
|
mask-image: var(--icon);
|
|
553
553
|
/*rtl:raw:transform: scaleX(-1);*/
|