feat(theme): support themeable images for logo and hero (#745)

Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com>
pull/803/head
Anthony Fu 3 years ago committed by GitHub
parent 35772ca8d0
commit 42813ce936
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,7 @@
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme'
import VPButton from './VPButton.vue'
import VPImage from './VPImage.vue'
export interface HeroAction {
theme?: 'brand' | 'alt'
@ -7,16 +9,11 @@ export interface HeroAction {
link: string
}
export interface Image {
src: string
alt?: string
}
defineProps<{
name?: string
text: string
tagline?: string
image?: Image
image?: DefaultTheme.ThemeableImage
actions?: HeroAction[]
}>()
</script>
@ -25,7 +22,9 @@ defineProps<{
<div class="VPHero" :class="{ 'has-image': image }">
<div class="container">
<div class="main">
<h1 v-if="name" class="name"><span class="clip">{{ name }}</span></h1>
<h1 v-if="name" class="name">
<span class="clip">{{ name }}</span>
</h1>
<p v-if="text" class="text">{{ text }}</p>
<p v-if="tagline" class="tagline">{{ tagline }}</p>
@ -45,7 +44,7 @@ defineProps<{
<div v-if="image" class="image">
<div class="image-container">
<div class="image-bg" />
<img class="image-src" :src="image.src" :alt="image.alt">
<VPImage class="image-src" :image="image" />
</div>
</div>
</div>
@ -293,7 +292,7 @@ defineProps<{
}
}
.image-src {
:deep(.image-src) {
position: absolute;
top: 50%;
left: 50%;

@ -0,0 +1,38 @@
<script setup lang="ts">
import { withBase } from 'vitepress'
import type { DefaultTheme } from 'vitepress/theme'
defineProps<{
image: DefaultTheme.ThemeableImage
}>()
</script>
<script lang="ts">
export default {
inheritAttrs: false
}
</script>
<template>
<template v-if="image">
<img
v-if="typeof image === 'string' || 'src' in image"
class="VPImage"
v-bind="typeof image === 'string' ? $attrs : { ...image, ...$attrs }"
:src="withBase(typeof image === 'string' ? image : image.src)"
/>
<template v-else>
<VPImage class="dark" :image="image.dark" v-bind="$attrs" />
<VPImage class="light" :image="image.light" v-bind="$attrs" />
</template>
</template>
</template>
<style scoped>
html:not(.dark) .VPImage.dark {
display: none;
}
.dark .VPImage.light {
display: none;
}
</style>

@ -1,6 +1,7 @@
<script setup lang="ts">
import { useData } from 'vitepress'
import { useSidebar } from '../composables/sidebar'
import VPImage from './VPImage.vue'
const { site, theme } = useData()
const { hasSidebar } = useSidebar()
@ -9,7 +10,7 @@ const { hasSidebar } = useSidebar()
<template>
<div class="VPNavBarTitle" :class="{ 'has-sidebar': hasSidebar }">
<a class="title" :href="site.base">
<img v-if="theme.logo" class="logo" :src="theme.logo">
<VPImage class="logo" :image="theme.logo" />
<template v-if="theme.siteTitle">{{ theme.siteTitle }}</template>
<template v-else-if="theme.siteTitle === undefined">{{ site.title }}</template>
</a>
@ -52,7 +53,7 @@ const { hasSidebar } = useSidebar()
}
}
.logo {
:deep(.logo) {
margin-right: 8px;
height: 24px;
}

@ -12,7 +12,8 @@
"types": ["vite/client"],
"paths": {
"/@theme/*": ["theme-default/*"],
"vitepress": ["index.ts"]
"vitepress": ["index.ts"],
"vitepress/theme": ["../../types/default-theme.d"]
}
},
"include": ["."]

@ -5,7 +5,7 @@ export namespace DefaultTheme {
*
* @example '/logo.svg'
*/
logo?: string
logo?: ThemeableImage
/**
* Custom site title in navbar. If the value is undefined,
@ -96,6 +96,11 @@ export namespace DefaultTheme {
items: (NavItemChildren | NavItemWithLink)[]
}
// image -----------------------------------------------------------------------
export type ThemeableImage = Image | { light: Image; dark: Image }
export type Image = string | { src: string; alt?: string }
// sidebar -------------------------------------------------------------------
export type Sidebar = SidebarGroup[] | SidebarMulti

Loading…
Cancel
Save