feat(theme): 导航栏、侧边栏图标支持图片链接和svg字符串 #65

This commit is contained in:
pengzhanbo 2024-04-17 12:12:08 +08:00
parent 72357e9c37
commit 6dd3bbacc0
12 changed files with 76 additions and 19 deletions

View File

@ -71,7 +71,7 @@ export interface NotesSidebarItem {
/**
*
*/
icon?: string
icon?: string | { svg: string }
}
export type NotesData = Record<string, NotesSidebarItem[]>

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import VIcon from '../VIcon.vue'
import MenuLink from './MenuLink.vue'
defineProps<{
text?: string
icon?: string
icon?: string | { svg: string }
items: any[]
}>()
</script>
@ -11,7 +12,7 @@ defineProps<{
<template>
<div class="menu-group">
<p v-if="text" class="title">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<span v-text="text" />
</p>

View File

@ -2,6 +2,7 @@
import { usePageData } from 'vuepress/client'
import { isActive } from '../../utils/index.js'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
item: any
@ -22,7 +23,7 @@ const page = usePageData()
}"
:href="item.link"
>
<Icon v-if="item.icon" :name="item.icon" />
<VIcon v-if="item.icon" :name="item.icon" />
<i v-text="item.text" />
</AutoLink>
</div>

View File

@ -1,10 +1,11 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { useFlyout } from '../../composables/flyout.js'
import VIcon from '../VIcon.vue'
import VMenu from './VMenu.vue'
defineProps<{
prefixIcon?: string
prefixIcon?: string | { svg: string }
icon?: any
button?: string
label?: string
@ -44,7 +45,7 @@ export default {
@click="open = !open"
>
<span v-if="button || icon" class="text">
<Icon v-if="prefixIcon" :name="prefixIcon" />
<VIcon v-if="prefixIcon" :name="prefixIcon" />
<span v-if="icon" class="option-icon" :class="[icon]" />
<span v-if="button" v-html="button" />
<span class="vpi-chevron-down text-icon" />

View File

@ -3,6 +3,7 @@ import { usePageData } from 'vuepress/client'
import type { NavItemWithLink } from '../../../shared/index.js'
import { isActive } from '../../utils/index.js'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
item: NavItemWithLink
@ -23,7 +24,7 @@ const page = usePageData()
:href="item.link"
:no-icon="true"
>
<Icon v-if="item.icon" :name="item.icon" />
<VIcon v-if="item.icon" :name="item.icon" />
<i v-text="item.text" />
</AutoLink>
</template>

View File

@ -1,11 +1,12 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import VIcon from '../VIcon.vue'
import NavScreenMenuGroupLink from './NavScreenMenuGroupLink.vue'
import NavScreenMenuGroupSection from './NavScreenMenuGroupSection.vue'
const props = defineProps<{
text: string
icon?: string
icon?: string | { svg: string }
items: any[]
}>()
@ -29,7 +30,7 @@ function toggle() {
@click="toggle"
>
<span class="button-text">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<i v-text="text" />
</span>
<span class="vpi-plus button-icon" />

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import { inject } from 'vue'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
icon?: string
icon?: string | { svg: string }
text: string
link: string
}>()
@ -17,7 +18,7 @@ const closeScreen = inject('close-screen') as () => void
:href="link"
@click="closeScreen"
>
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<i v-text="text" />
</AutoLink>
</template>

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import type { NavItemWithLink } from '../../../shared/index.js'
import VIcon from '../VIcon.vue'
import NavScreenMenuGroupLink from './NavScreenMenuGroupLink.vue'
defineProps<{
icon?: string
icon?: string | { svg: string }
text?: string
items: NavItemWithLink[]
}>()
@ -12,7 +13,7 @@ defineProps<{
<template>
<div class="nav-screen-menu-group-section">
<p v-if="text" class="title">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
{{ text }}
</p>
<NavScreenMenuGroupLink

View File

@ -1,11 +1,12 @@
<script lang="ts" setup>
import { inject } from 'vue'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
text: string
link: string
icon?: string
icon?: string | { svg: string }
}>()
const closeScreen = inject('close-screen') as () => void
@ -13,7 +14,7 @@ const closeScreen = inject('close-screen') as () => void
<template>
<AutoLink class="nav-screen-menu-link" :href="link" @click="closeScreen">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<i v-text="text" />
</AutoLink>
</template>

View File

@ -3,6 +3,7 @@ import type { NotesSidebarItem } from '@vuepress-plume/plugin-notes-data'
import { computed } from 'vue'
import { useSidebarControl } from '../composables/sidebar.js'
import AutoLink from './AutoLink.vue'
import VIcon from './VIcon.vue'
const props = defineProps<{
item: NotesSidebarItem
@ -68,7 +69,7 @@ function onCaretClick() {
>
<div class="indicator" />
<Icon v-if="item.icon" :name="item.icon" />
<VIcon v-if="item.icon" :name="item.icon" />
<AutoLink
v-if="item.link"
@ -222,6 +223,11 @@ function onCaretClick() {
transition: color var(--t-color);
}
.item :deep(.vp__img) {
height: 0.9em;
margin: 0 0.25rem 0 0;
}
.item:hover .caret {
color: var(--vp-c-text-2);
}

View File

@ -0,0 +1,43 @@
<script setup lang="ts">
import { computed } from 'vue'
import { isLinkHttp } from 'vuepress/shared'
import { withBase } from 'vuepress/client'
const props = defineProps<{
name: string | { svg: string }
}>()
const isLink = computed(() =>
typeof props.name === 'string' && (isLinkHttp(props.name) || props.name[0] === '/'),
)
const isSvg = computed(() => typeof props.name === 'object' && !!props.name.svg)
const svg = computed(() => {
if (isSvg.value)
return (props.name as { svg: string }).svg
return ''
})
const link = computed(() => {
if (isLink.value) {
const link = props.name as string
return isLinkHttp(link) ? link : withBase(link)
}
return ''
})
</script>
<template>
<img v-if="isLink" class="vp__img" :src="link" alt="">
<span v-else-if="isSvg" class="vp-iconify" v-html="svg" />
<Icon v-else :name="name" />
</template>
<style scoped>
.vp__img {
display: inline-block;
height: 1em;
margin: 0.3em;
vertical-align: middle;
}
</style>

View File

@ -3,7 +3,7 @@ export type NavItem = NavItemWithLink | NavItemWithChildren
export interface NavItemWithLink {
text: string
link: string
icon?: string
icon?: string | { svg: string }
/**
* `activeMatch` is expected to be a regex string. We can't use actual
@ -14,13 +14,13 @@ export interface NavItemWithLink {
export interface NavItemChildren {
text?: string
icon?: string
icon?: string | { svg: string }
items: NavItemWithLink[]
}
export interface NavItemWithChildren {
text?: string
icon?: string
icon?: string | { svg: string }
items: (NavItemChildren | NavItemWithLink)[]
/**