import { useRoute, useSiteData } from 'vitepress'; import { h } from 'vue'; import { joinUrl, isActive } from '../utils'; export const SideBarItem = (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, path) { return path ? // keep relative hash to the same page path.startsWith('#') ? path : joinUrl(base, path) : undefined; } function createChildren(active, children, headers) { 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) { return mapHeaders(groupHeaders(headers)); } function groupHeaders(headers) { headers = headers.map((h) => Object.assign({}, h)); let lastH2; 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) { return headers.map((header) => ({ text: header.title, link: `#${header.slug}`, children: header.children ? mapHeaders(header.children) : undefined })); }