Skip to content

Commit 42813ce

Browse files
antfubrc-dd
andauthored
feat(theme): support themeable images for logo and hero (#745)
Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com>
1 parent 35772ca commit 42813ce

File tree

5 files changed

+57
-13
lines changed

5 files changed

+57
-13
lines changed

src/client/theme-default/components/VPHero.vue

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
<script setup lang="ts">
2+
import type { DefaultTheme } from 'vitepress/theme'
23
import VPButton from './VPButton.vue'
4+
import VPImage from './VPImage.vue'
35
46
export interface HeroAction {
57
theme?: 'brand' | 'alt'
68
text: string
79
link: string
810
}
911
10-
export interface Image {
11-
src: string
12-
alt?: string
13-
}
14-
1512
defineProps<{
1613
name?: string
1714
text: string
1815
tagline?: string
19-
image?: Image
16+
image?: DefaultTheme.ThemeableImage
2017
actions?: HeroAction[]
2118
}>()
2219
</script>
@@ -25,7 +22,9 @@ defineProps<{
2522
<div class="VPHero" :class="{ 'has-image': image }">
2623
<div class="container">
2724
<div class="main">
28-
<h1 v-if="name" class="name"><span class="clip">{{ name }}</span></h1>
25+
<h1 v-if="name" class="name">
26+
<span class="clip">{{ name }}</span>
27+
</h1>
2928
<p v-if="text" class="text">{{ text }}</p>
3029
<p v-if="tagline" class="tagline">{{ tagline }}</p>
3130

@@ -45,7 +44,7 @@ defineProps<{
4544
<div v-if="image" class="image">
4645
<div class="image-container">
4746
<div class="image-bg" />
48-
<img class="image-src" :src="image.src" :alt="image.alt">
47+
<VPImage class="image-src" :image="image" />
4948
</div>
5049
</div>
5150
</div>
@@ -293,7 +292,7 @@ defineProps<{
293292
}
294293
}
295294
296-
.image-src {
295+
:deep(.image-src) {
297296
position: absolute;
298297
top: 50%;
299298
left: 50%;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<script setup lang="ts">
2+
import { withBase } from 'vitepress'
3+
import type { DefaultTheme } from 'vitepress/theme'
4+
5+
defineProps<{
6+
image: DefaultTheme.ThemeableImage
7+
}>()
8+
</script>
9+
10+
<script lang="ts">
11+
export default {
12+
inheritAttrs: false
13+
}
14+
</script>
15+
16+
<template>
17+
<template v-if="image">
18+
<img
19+
v-if="typeof image === 'string' || 'src' in image"
20+
class="VPImage"
21+
v-bind="typeof image === 'string' ? $attrs : { ...image, ...$attrs }"
22+
:src="withBase(typeof image === 'string' ? image : image.src)"
23+
/>
24+
<template v-else>
25+
<VPImage class="dark" :image="image.dark" v-bind="$attrs" />
26+
<VPImage class="light" :image="image.light" v-bind="$attrs" />
27+
</template>
28+
</template>
29+
</template>
30+
31+
<style scoped>
32+
html:not(.dark) .VPImage.dark {
33+
display: none;
34+
}
35+
.dark .VPImage.light {
36+
display: none;
37+
}
38+
</style>

src/client/theme-default/components/VPNavBarTitle.vue

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import { useData } from 'vitepress'
33
import { useSidebar } from '../composables/sidebar'
4+
import VPImage from './VPImage.vue'
45
56
const { site, theme } = useData()
67
const { hasSidebar } = useSidebar()
@@ -9,7 +10,7 @@ const { hasSidebar } = useSidebar()
910
<template>
1011
<div class="VPNavBarTitle" :class="{ 'has-sidebar': hasSidebar }">
1112
<a class="title" :href="site.base">
12-
<img v-if="theme.logo" class="logo" :src="theme.logo">
13+
<VPImage class="logo" :image="theme.logo" />
1314
<template v-if="theme.siteTitle">{{ theme.siteTitle }}</template>
1415
<template v-else-if="theme.siteTitle === undefined">{{ site.title }}</template>
1516
</a>
@@ -52,7 +53,7 @@ const { hasSidebar } = useSidebar()
5253
}
5354
}
5455
55-
.logo {
56+
:deep(.logo) {
5657
margin-right: 8px;
5758
height: 24px;
5859
}

src/client/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"types": ["vite/client"],
1313
"paths": {
1414
"/@theme/*": ["theme-default/*"],
15-
"vitepress": ["index.ts"]
15+
"vitepress": ["index.ts"],
16+
"vitepress/theme": ["../../types/default-theme.d"]
1617
}
1718
},
1819
"include": ["."]

types/default-theme.d.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export namespace DefaultTheme {
55
*
66
* @example '/logo.svg'
77
*/
8-
logo?: string
8+
logo?: ThemeableImage
99

1010
/**
1111
* Custom site title in navbar. If the value is undefined,
@@ -96,6 +96,11 @@ export namespace DefaultTheme {
9696
items: (NavItemChildren | NavItemWithLink)[]
9797
}
9898

99+
// image -----------------------------------------------------------------------
100+
101+
export type ThemeableImage = Image | { light: Image; dark: Image }
102+
export type Image = string | { src: string; alt?: string }
103+
99104
// sidebar -------------------------------------------------------------------
100105

101106
export type Sidebar = SidebarGroup[] | SidebarMulti

0 commit comments

Comments
 (0)