mirror of https://github.com/vuejs/vitepress
Merge branch 'master' of https://github.com/ChrisShank/vitepress into feat/user-markdown-options
commit
939c3b1967
@ -1,4 +1,6 @@
|
||||
/dist
|
||||
/node_modules
|
||||
/src/client/shared
|
||||
/src/node/shared
|
||||
*.log
|
||||
.DS_Store
|
||||
|
@ -0,0 +1,7 @@
|
||||
const fs = require('fs-extra')
|
||||
const glob = require('globby')
|
||||
|
||||
glob.sync('src/shared/**/*.ts').forEach((file) => {
|
||||
fs.copy(file, file.replace(/^src\//, 'src/node/'))
|
||||
fs.copy(file, file.replace(/^src\//, 'src/client/'))
|
||||
})
|
@ -1,13 +1,31 @@
|
||||
// copy and watch non-ts files in src/client
|
||||
const fs = require('fs-extra')
|
||||
const chokidar = require('chokidar')
|
||||
|
||||
function toDest(file) {
|
||||
function toClientAndNode(method, file) {
|
||||
if (method === 'copy') {
|
||||
fs.copy(file, file.replace(/^src\//, 'src/node/'))
|
||||
fs.copy(file, file.replace(/^src\//, 'src/client/'))
|
||||
} else if (method === 'remove') {
|
||||
fs.remove(file.replace(/^src\//, 'src/node/'))
|
||||
fs.remove(file.replace(/^src\//, 'src/client/'))
|
||||
}
|
||||
}
|
||||
|
||||
function toDist(file) {
|
||||
return file.replace(/^src\//, 'dist/')
|
||||
}
|
||||
|
||||
// copy shared files to the client and node directory whenever they change.
|
||||
chokidar
|
||||
.watch('src/shared/**/*.ts')
|
||||
.on('change', (file) => toClientAndNode('copy', file))
|
||||
.on('add', (file) => toClientAndNode('copy', file))
|
||||
.on('unlink', (file) => toClientAndNode('remove', file))
|
||||
|
||||
// copy non ts files, such as an html or css, to the dist directory whenever
|
||||
// they change.
|
||||
chokidar
|
||||
.watch('src/client/**/!(*.ts|tsconfig.json)')
|
||||
.on('change', (file) => fs.copy(file, toDest(file)))
|
||||
.on('add', (file) => fs.copy(file, toDest(file)))
|
||||
.on('unlink', (file) => fs.remove(toDest(file)))
|
||||
.on('change', (file) => fs.copy(file, toDist(file)))
|
||||
.on('add', (file) => fs.copy(file, toDist(file)))
|
||||
.on('unlink', (file) => fs.remove(toDist(file)))
|
||||
|
@ -1,14 +0,0 @@
|
||||
import { inject, InjectionKey, Ref } from 'vue'
|
||||
import { PageData } from '../../../../types/shared'
|
||||
|
||||
export type PageDataRef = Ref<PageData>
|
||||
|
||||
export const pageDataSymbol: InjectionKey<PageDataRef> = Symbol()
|
||||
|
||||
export function usePageData(): PageDataRef {
|
||||
const data = inject(pageDataSymbol)
|
||||
if (!data) {
|
||||
throw new Error('usePageData() is called without provider.')
|
||||
}
|
||||
return data
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
import { useRoute, useSiteData } from 'vitepress'
|
||||
import { FunctionalComponent, h, VNode } from 'vue'
|
||||
import { Header } from '../../../../types/shared'
|
||||
import { joinUrl, isActive } from '../utils'
|
||||
import { ResolvedSidebarItem } from './SideBar'
|
||||
|
||||
interface HeaderWithChildren extends Header {
|
||||
children?: Header[]
|
||||
}
|
||||
|
||||
export const SideBarItem: FunctionalComponent<{
|
||||
item: ResolvedSidebarItem
|
||||
}> = (props) => {
|
||||
const {
|
||||
item: { link: relLink, text, children }
|
||||
} = props
|
||||
|
||||
const route = useRoute()
|
||||
const siteData = useSiteData()
|
||||
|
||||
const link = resolveLink(siteData.value.base, relLink || '')
|
||||
const active = isActive(route, link)
|
||||
const headers = route.data.headers
|
||||
const childItems = createChildren(active, children, headers)
|
||||
|
||||
return h('li', { class: 'sidebar-item' }, [
|
||||
h(
|
||||
link ? 'a' : 'p',
|
||||
{
|
||||
class: { 'sidebar-link': true, active },
|
||||
href: link
|
||||
},
|
||||
text
|
||||
),
|
||||
childItems
|
||||
])
|
||||
}
|
||||
|
||||
function resolveLink(base: string, path: string): string | undefined {
|
||||
return path
|
||||
? // keep relative hash to the same page
|
||||
path.startsWith('#')
|
||||
? path
|
||||
: joinUrl(base, path)
|
||||
: undefined
|
||||
}
|
||||
|
||||
function createChildren(
|
||||
active: boolean,
|
||||
children?: ResolvedSidebarItem[],
|
||||
headers?: Header[]
|
||||
): VNode | null {
|
||||
if (children && children.length > 0) {
|
||||
return h(
|
||||
'ul',
|
||||
{ class: 'sidebar-items' },
|
||||
children.map((c) => {
|
||||
return h(SideBarItem, { item: c })
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return active && headers
|
||||
? createChildren(false, resolveHeaders(headers))
|
||||
: null
|
||||
}
|
||||
|
||||
function resolveHeaders(headers: Header[]): ResolvedSidebarItem[] {
|
||||
return mapHeaders(groupHeaders(headers))
|
||||
}
|
||||
|
||||
function groupHeaders(headers: Header[]): HeaderWithChildren[] {
|
||||
headers = headers.map((h) => Object.assign({}, h))
|
||||
let lastH2: HeaderWithChildren
|
||||
headers.forEach((h) => {
|
||||
if (h.level === 2) {
|
||||
lastH2 = h
|
||||
} else if (lastH2) {
|
||||
;(lastH2.children || (lastH2.children = [])).push(h)
|
||||
}
|
||||
})
|
||||
return headers.filter((h) => h.level === 2)
|
||||
}
|
||||
|
||||
function mapHeaders(headers: HeaderWithChildren[]): ResolvedSidebarItem[] {
|
||||
return headers.map((header) => ({
|
||||
text: header.title,
|
||||
link: `#${header.slug}`,
|
||||
children: header.children ? mapHeaders(header.children) : undefined
|
||||
}))
|
||||
}
|
@ -1,10 +1,17 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist",
|
||||
"baseUrl": ".",
|
||||
"outDir": "../../dist/node",
|
||||
"module": "commonjs",
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"sourceMap": true
|
||||
"sourceMap": true,
|
||||
"paths": {
|
||||
"/@types/*": ["../../types/*"]
|
||||
}
|
||||
},
|
||||
"include": [".", "../shared", "../../types/shared.d.ts"]
|
||||
"include": [
|
||||
".",
|
||||
"../../types/shared.d.ts"
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in new issue