feat(theme): add sidebar icon supported

This commit is contained in:
pengzhanbo 2024-03-14 04:43:49 +08:00
parent 90896934eb
commit eb4a73b6d7
4 changed files with 72 additions and 1 deletions

View File

@ -30,6 +30,7 @@ interface NotePage {
relativePath: string relativePath: string
title: string title: string
link: string link: string
frontmatter: Record<string, any>
} }
function resolvedNotesData(app: App, options: NotesDataOptions, result: NotesData) { function resolvedNotesData(app: App, options: NotesDataOptions, result: NotesData) {
@ -52,6 +53,7 @@ function resolvedNotesData(app: App, options: NotesDataOptions, result: NotesDat
relativePath: page.filePathRelative?.replace(DIR_PATTERN, '') || '', relativePath: page.filePathRelative?.replace(DIR_PATTERN, '') || '',
title: page.title, title: page.title,
link: page.path, link: page.path,
frontmatter: page.frontmatter,
})) }))
notes.forEach((note) => { notes.forEach((note) => {
result[normalizePath(path.join('/', link, note.link))] = initSidebar( result[normalizePath(path.join('/', link, note.link))] = initSidebar(
@ -141,7 +143,7 @@ function initSidebarByAuto(
const RE_INDEX = ['index.md', 'README.md', 'readme.md'] const RE_INDEX = ['index.md', 'README.md', 'readme.md']
const result: NotesSidebarItem[] = [] const result: NotesSidebarItem[] = []
for (const page of pages) { for (const page of pages) {
const { relativePath, title, link } = page const { relativePath, title, link, frontmatter } = page
const paths = relativePath const paths = relativePath
.slice(note.dir.replace(/^\/|\/$/g, '').length + 1) .slice(note.dir.replace(/^\/|\/$/g, '').length + 1)
.split('/') .split('/')
@ -160,6 +162,9 @@ function initSidebarByAuto(
current.link = link current.link = link
current.text = title current.text = title
} }
if (frontmatter.icon)
current.icon = frontmatter.icon
items = current.items as NotesSidebarItem[] items = current.items as NotesSidebarItem[]
index++ index++
} }
@ -177,6 +182,7 @@ function initSidebarByConfig(
return { return {
text: current?.title || text, text: current?.title || text,
link: current?.link, link: current?.link,
icon: current?.frontmatter.icon,
items: [], items: [],
} }
} }
@ -185,6 +191,7 @@ function initSidebarByConfig(
return { return {
text: item.text || item.dir || current?.title, text: item.text || item.dir || current?.title,
collapsed: item.collapsed, collapsed: item.collapsed,
icon: item.icon || current?.frontmatter.icon,
link: item.link, link: item.link,
items: initSidebarByConfig( items: initSidebarByConfig(
{ {

View File

@ -1,28 +1,76 @@
export interface NotesDataOptions { export interface NotesDataOptions {
/**
*
* @default '/notes'
*/
dir: string dir: string
/**
*
* @default '/'
*/
link: string link: string
/**
* global include
*/
include?: string | string[] include?: string | string[]
/**
* global exclude
*/
exclude?: string | string[] exclude?: string | string[]
/**
*
*/
notes: NotesItemOptions[] notes: NotesItemOptions[]
} }
export type NotesItemOptions = (Omit<NotesItem, 'text'> & { text?: string }) export type NotesItemOptions = (Omit<NotesItem, 'text'> & { text?: string })
export interface NotesItem { export interface NotesItem {
/**
*
*/
dir: string dir: string
/**
* `notes.link`
*/
link: string link: string
/**
*
*/
text: string text: string
/**
*
*/
sidebar?: NotesSidebar | 'auto' sidebar?: NotesSidebar | 'auto'
} }
export type NotesSidebar = (NotesSidebarItem | string)[] export type NotesSidebar = (NotesSidebarItem | string)[]
export interface NotesSidebarItem { export interface NotesSidebarItem {
/**
* 使 `dir`
*/
text?: string text?: string
/**
*
*/
link?: string link?: string
/**
*
*/
dir?: string dir?: string
/**
* ,
* @default undefined
*/
collapsed?: boolean collapsed?: boolean
/**
*
*/
items?: NotesSidebar items?: NotesSidebar
/**
*
*/
icon?: string icon?: string
} }

View File

@ -69,6 +69,8 @@ function onCaretClick() {
> >
<div class="indicator" /> <div class="indicator" />
<Icon v-if="item.icon" :name="item.icon" />
<AutoLink <AutoLink
v-if="item.link" v-if="item.link"
:tag="linkTag" :tag="linkTag"
@ -118,6 +120,7 @@ function onCaretClick() {
.item { .item {
position: relative; position: relative;
display: flex; display: flex;
align-items: center;
width: 100%; width: 100%;
} }
@ -207,6 +210,13 @@ function onCaretClick() {
transition: color var(--t-color); transition: color var(--t-color);
} }
.item :deep(.vp-iconify) {
margin: 0 0.25rem 0 0;
font-size: 0.9em;
color: var(--vp-c-text-2);
transition: color var(--t-color);
}
.item:hover .caret { .item:hover .caret {
color: var(--vp-c-text-2); color: var(--vp-c-text-2);
} }
@ -215,6 +225,11 @@ function onCaretClick() {
color: var(--vp-c-text-1); color: var(--vp-c-text-1);
} }
.sidebar-item:not(.collapsible) > .item:hover :deep(.vp-iconify),
.sidebar-item:not(.collapsible).has-active > .item > :deep(.vp-iconify) {
color: var(--vp-c-brand-1);
}
.caret-icon { .caret-icon {
width: 18px; width: 18px;
height: 18px; height: 18px;

View File

@ -109,6 +109,7 @@ export interface PlumeThemePageFrontmatter {
next?: string | NavItemWithLink next?: string | NavItemWithLink
backToTop?: boolean backToTop?: boolean
externalLink?: boolean externalLink?: boolean
readingTime?: boolean
} }
export interface PlumeThemePostFrontmatter extends PlumeThemePageFrontmatter { export interface PlumeThemePostFrontmatter extends PlumeThemePageFrontmatter {