refactor(nav,layout): use `InjectionKey` (#4880)

---------

Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com>
pull/4876/head
Artea 1 month ago committed by hyperz111
parent d32ebcd9e9
commit 8a1f37c971

@ -8,7 +8,7 @@ import VPNav from './components/VPNav.vue'
import VPSidebar from './components/VPSidebar.vue' import VPSidebar from './components/VPSidebar.vue'
import VPSkipLink from './components/VPSkipLink.vue' import VPSkipLink from './components/VPSkipLink.vue'
import { useData } from './composables/data' import { useData } from './composables/data'
import { registerWatchers } from './composables/layout' import { layoutInfoInjectionKey, registerWatchers } from './composables/layout'
import { useSidebarControl } from './composables/sidebar' import { useSidebarControl } from './composables/sidebar'
const { const {
@ -24,7 +24,7 @@ const { frontmatter } = useData()
const slots = useSlots() const slots = useSlots()
const heroImageSlotExists = computed(() => !!slots['home-hero-image']) const heroImageSlotExists = computed(() => !!slots['home-hero-image'])
provide('hero-image-slot-exists', heroImageSlotExists) provide(layoutInfoInjectionKey, { heroImageSlotExists })
</script> </script>
<template> <template>

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { type Ref, inject } from 'vue'
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { inject } from 'vue'
import { layoutInfoInjectionKey } from '../composables/layout'
import VPButton from './VPButton.vue' import VPButton from './VPButton.vue'
import VPImage from './VPImage.vue' import VPImage from './VPImage.vue'
@ -20,7 +21,7 @@ defineProps<{
actions?: HeroAction[] actions?: HeroAction[]
}>() }>()
const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean> const { heroImageSlotExists } = inject(layoutInfoInjectionKey)!
</script> </script>
<template> <template>

@ -2,7 +2,7 @@
import { inBrowser } from 'vitepress' import { inBrowser } from 'vitepress'
import { computed, provide, watchEffect } from 'vue' import { computed, provide, watchEffect } from 'vue'
import { useData } from '../composables/data' import { useData } from '../composables/data'
import { useNav } from '../composables/nav' import { navInjectionKey, useNav } from '../composables/nav'
import VPNavBar from './VPNavBar.vue' import VPNavBar from './VPNavBar.vue'
import VPNavScreen from './VPNavScreen.vue' import VPNavScreen from './VPNavScreen.vue'
@ -13,7 +13,7 @@ const hasNavbar = computed(() => {
return frontmatter.value.navbar !== false return frontmatter.value.navbar !== false
}) })
provide('close-screen', closeScreen) provide(navInjectionKey, { closeScreen })
watchEffect(() => { watchEffect(() => {
if (inBrowser) { if (inBrowser) {

@ -1,13 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { inject } from 'vue' import { inject } from 'vue'
import { navInjectionKey } from '../composables/nav'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const closeScreen = inject('close-screen') as () => void const { closeScreen } = inject(navInjectionKey)!
</script> </script>
<template> <template>

@ -1,13 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { inject } from 'vue' import { inject } from 'vue'
import { navInjectionKey } from '../composables/nav'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const closeScreen = inject('close-screen') as () => void const { closeScreen } = inject(navInjectionKey)!
</script> </script>
<template> <template>

@ -1,6 +1,13 @@
import { inBrowser, onContentUpdated, useRoute } from 'vitepress' import { inBrowser, onContentUpdated, useRoute } from 'vitepress'
import type { DefaultTheme, useLayout as expected } from 'vitepress/theme' import type { DefaultTheme, useLayout as expected } from 'vitepress/theme'
import { computed, shallowReadonly, shallowRef, watch } from 'vue' import {
computed,
shallowReadonly,
shallowRef,
watch,
type ComputedRef,
type InjectionKey
} from 'vue'
import { getSidebar, getSidebarGroups } from '../support/sidebar' import { getSidebar, getSidebarGroups } from '../support/sidebar'
import { useData } from './data' import { useData } from './data'
import { getHeaders } from './outline' import { getHeaders } from './outline'
@ -102,3 +109,10 @@ export function registerWatchers({ closeSidebar }: RegisterWatchersOptions) {
useCloseSidebarOnEscape(closeSidebar) useCloseSidebarOnEscape(closeSidebar)
} }
export interface LayoutInfo {
heroImageSlotExists: ComputedRef<boolean>
}
export const layoutInfoInjectionKey: InjectionKey<LayoutInfo> =
Symbol('layout-info')

@ -1,5 +1,5 @@
import { useRoute } from 'vitepress' import { useRoute } from 'vitepress'
import { ref, watch } from 'vue' import { ref, watch, type InjectionKey } from 'vue'
export function useNav() { export function useNav() {
const isScreenOpen = ref(false) const isScreenOpen = ref(false)
@ -35,3 +35,9 @@ export function useNav() {
toggleScreen toggleScreen
} }
} }
export interface NavExposedMethods {
closeScreen: () => void
}
export const navInjectionKey: InjectionKey<NavExposedMethods> = Symbol('nav')

Loading…
Cancel
Save