Files
Library/node_modules/vitepress/dist/client/theme-default/composables/layout.js
2026-01-09 23:05:52 -05:00

77 lines
2.8 KiB
JavaScript

import { inBrowser, onContentUpdated, useRoute } from 'vitepress';
import { computed, shallowReadonly, shallowRef, watch } from 'vue';
import { getSidebar, getSidebarGroups } from '../support/sidebar';
import { useData } from './data';
import { getHeaders } from './outline';
import { useCloseSidebarOnEscape } from './sidebar';
const headers = shallowRef([]);
const sidebar = shallowRef([]);
const is960 = shallowRef(false);
export function useLayout() {
const { frontmatter, theme } = useData();
const isHome = computed(() => {
return !!(frontmatter.value.isHome ?? frontmatter.value.layout === 'home');
});
const hasSidebar = computed(() => {
return (frontmatter.value.sidebar !== false &&
sidebar.value.length > 0 &&
!isHome.value);
});
const isSidebarEnabled = computed(() => hasSidebar.value && is960.value);
const sidebarGroups = computed(() => {
return hasSidebar.value ? getSidebarGroups(sidebar.value) : [];
});
const hasAside = computed(() => {
if (isHome.value)
return false;
if (frontmatter.value.aside != null)
return !!frontmatter.value.aside;
return theme.value.aside !== false;
});
const leftAside = computed(() => {
if (!hasAside.value)
return false;
return frontmatter.value.aside == null
? theme.value.aside === 'left'
: frontmatter.value.aside === 'left';
});
const hasLocalNav = computed(() => {
return headers.value.length > 0;
});
return {
isHome,
sidebar: shallowReadonly(sidebar),
sidebarGroups,
hasSidebar,
isSidebarEnabled,
hasAside,
leftAside,
headers: shallowReadonly(headers),
hasLocalNav
};
}
export function registerWatchers({ closeSidebar }) {
const { frontmatter, page, theme } = useData();
watch(() => [page.value.relativePath, theme.value.sidebar], ([relativePath, sidebarConfig]) => {
const newSidebar = sidebarConfig
? getSidebar(sidebarConfig, relativePath)
: [];
if (JSON.stringify(newSidebar) !== JSON.stringify(sidebar.value)) {
sidebar.value = newSidebar;
}
}, { immediate: true, deep: true, flush: 'sync' });
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline);
});
if (inBrowser) {
is960.value = window.innerWidth >= 960;
window.addEventListener('resize', () => {
is960.value = window.innerWidth >= 960;
}, { passive: true });
}
const route = useRoute();
watch(() => route.path, closeSidebar);
useCloseSidebarOnEscape(closeSidebar);
}
export const layoutInfoInjectionKey = Symbol('layout-info');