docus 5.6.1 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/app.vue +13 -1
- package/app/assets/icons/LICENSE +14 -0
- package/app/assets/icons/ai.svg +1 -0
- package/app/components/LanguageSelect.vue +1 -4
- package/app/components/OgImage/OgImageDocs.vue +2 -4
- package/app/components/OgImage/OgImageLanding.vue +36 -13
- package/app/components/app/AppFooterRight.vue +32 -14
- package/app/components/app/AppHeader.vue +10 -0
- package/app/components/app/AppHeaderBottom.vue +20 -0
- package/app/components/app/AppHeaderBottomRight.vue +3 -0
- package/app/components/docs/DocsAsideLeftBody.vue +2 -4
- package/app/components/docs/DocsAsideLeftTop.vue +18 -1
- package/app/components/docs/DocsAsideMobileBar.vue +88 -0
- package/app/components/docs/DocsAsideRight.vue +33 -0
- package/app/components/docs/DocsAsideRightBottom.vue +1 -1
- package/app/composables/useDocusI18n.ts +21 -5
- package/app/composables/useLogoAssets.ts +1 -1
- package/app/composables/useSubNavigation.ts +55 -0
- package/app/pages/[[lang]]/[...slug].vue +4 -13
- package/i18n/locales/ar.json +1 -0
- package/i18n/locales/be.json +1 -0
- package/i18n/locales/bg.json +1 -0
- package/i18n/locales/bn.json +1 -0
- package/i18n/locales/ca.json +1 -0
- package/i18n/locales/ckb.json +1 -0
- package/i18n/locales/cs.json +1 -0
- package/i18n/locales/da.json +1 -0
- package/i18n/locales/de.json +1 -0
- package/i18n/locales/el.json +1 -0
- package/i18n/locales/en.json +1 -0
- package/i18n/locales/es.json +1 -0
- package/i18n/locales/et.json +1 -0
- package/i18n/locales/fi.json +1 -0
- package/i18n/locales/fr.json +1 -0
- package/i18n/locales/he.json +1 -0
- package/i18n/locales/hi.json +1 -0
- package/i18n/locales/hy.json +1 -0
- package/i18n/locales/id.json +1 -0
- package/i18n/locales/it.json +1 -0
- package/i18n/locales/ja.json +1 -0
- package/i18n/locales/kk.json +1 -0
- package/i18n/locales/km.json +1 -0
- package/i18n/locales/ko.json +1 -0
- package/i18n/locales/ky.json +1 -0
- package/i18n/locales/lb.json +1 -0
- package/i18n/locales/ms.json +1 -0
- package/i18n/locales/nb.json +1 -0
- package/i18n/locales/nl.json +1 -0
- package/i18n/locales/pl.json +1 -0
- package/i18n/locales/pt-BR.json +1 -0
- package/i18n/locales/ro.json +1 -0
- package/i18n/locales/ru.json +1 -0
- package/i18n/locales/si.json +1 -0
- package/i18n/locales/sl.json +1 -0
- package/i18n/locales/sv.json +1 -0
- package/i18n/locales/tr.json +1 -0
- package/i18n/locales/uk.json +1 -0
- package/i18n/locales/ur.json +1 -0
- package/i18n/locales/vi.json +1 -0
- package/i18n/locales/zh-CN.json +1 -0
- package/modules/assistant/runtime/components/AssistantChat.vue +2 -2
- package/modules/assistant/runtime/components/AssistantPanel.vue +1 -1
- package/modules/assistant/runtime/components/AssistantPreStream.vue +1 -1
- package/modules/assistant/runtime/composables/useAssistant.ts +7 -3
- package/modules/assistant/runtime/server/api/search.ts +3 -2
- package/modules/config.ts +18 -6
- package/modules/markdown-rewrite.ts +7 -3
- package/modules/routing.ts +4 -1
- package/nuxt.config.ts +24 -2
- package/nuxt.schema.ts +15 -1
- package/package.json +13 -14
- package/server/mcp/tools/get-page.ts +2 -4
- package/server/mcp/tools/list-pages.ts +2 -1
- package/server/routes/sitemap.xml.ts +3 -3
package/app/app.vue
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { ContentNavigationItem, PageCollections } from '@nuxt/content'
|
|
3
3
|
import * as nuxtUiLocales from '@nuxt/ui/locale'
|
|
4
4
|
import { transformNavigation } from './utils/navigation'
|
|
5
|
+
import { useSubNavigation } from './composables/useSubNavigation'
|
|
5
6
|
|
|
6
7
|
const { seo } = useAppConfig()
|
|
7
8
|
const site = useSiteConfig()
|
|
@@ -55,6 +56,8 @@ const { data: files } = useLazyAsyncData(`search_${collectionName.value}`, () =>
|
|
|
55
56
|
})
|
|
56
57
|
|
|
57
58
|
provide('navigation', navigation)
|
|
59
|
+
|
|
60
|
+
const { subNavigationMode } = useSubNavigation(navigation)
|
|
58
61
|
</script>
|
|
59
62
|
|
|
60
63
|
<template>
|
|
@@ -62,7 +65,7 @@ provide('navigation', navigation)
|
|
|
62
65
|
<NuxtLoadingIndicator color="var(--ui-primary)" />
|
|
63
66
|
|
|
64
67
|
<div
|
|
65
|
-
class="transition-[margin-right] duration-200 ease-linear will-change-[margin-right]"
|
|
68
|
+
:class="['transition-[margin-right] duration-200 ease-linear will-change-[margin-right]', { 'docus-sub-header': subNavigationMode === 'header' }]"
|
|
66
69
|
:style="{ marginRight: shouldPushContent ? `${assistantPanelWidth}px` : '0' }"
|
|
67
70
|
>
|
|
68
71
|
<AppHeader v-if="$route.meta.header !== false" />
|
|
@@ -84,3 +87,12 @@ provide('navigation', navigation)
|
|
|
84
87
|
</ClientOnly>
|
|
85
88
|
</UApp>
|
|
86
89
|
</template>
|
|
90
|
+
|
|
91
|
+
<style>
|
|
92
|
+
@media (min-width: 1024px) {
|
|
93
|
+
.docus-sub-header {
|
|
94
|
+
/* 64px base header + 48px sub-navigation bar */
|
|
95
|
+
--ui-header-height: 112px;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Copyright © Nucleo
|
|
2
|
+
|
|
3
|
+
Version 1.3, January 3, 2024
|
|
4
|
+
|
|
5
|
+
Nucleo Icons
|
|
6
|
+
|
|
7
|
+
https://nucleoapp.com/
|
|
8
|
+
|
|
9
|
+
- Redistribution of icons is prohibited.
|
|
10
|
+
- Icons are restricted for use only within the product they are bundled with.
|
|
11
|
+
|
|
12
|
+
For more details:
|
|
13
|
+
|
|
14
|
+
https://nucleoapp.com/license
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" id="artificial-intelligence" aria-hidden="true" viewBox="0 0 20 20"><title>artificial-intelligence</title><g fill="currentColor"><polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="10.5 15 7 5 6 5 2.5 15"/><line x1="9.586" x2="3.414" y1="12.5" y2="12.5" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="13.5 9 15.5 9 15.5 15"/><line x1="13.5" x2="17.5" y1="15" y2="15" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><path fill="currentColor" stroke-width="0" d="m17.6527,3.9647l-1.2005-.4503-.4506-1.2005c-.1562-.4185-.8468-.4185-1.0031,0l-.4506,1.2005-1.2005.4503c-.2086.0785-.3474.2783-.3474.5015s.1388.4231.3474.5015l1.2005.4503.4506,1.2005c.0781.2093.2783.3477.5015.3477s.4234-.1385.5015-.3477l.4506-1.2005,1.2005-.4503c.2086-.0785.3474-.2783.3474-.5015s-.1388-.4231-.3474-.5015h0Z"/></g></svg>
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { computed } from 'vue'
|
|
3
|
-
|
|
4
2
|
const props = withDefaults(defineProps<{ title?: string, description?: string, headline?: string }>(), {
|
|
5
3
|
title: 'title',
|
|
6
4
|
description: 'description',
|
|
7
5
|
})
|
|
8
6
|
|
|
9
|
-
const title =
|
|
10
|
-
const description =
|
|
7
|
+
const title = (props.title || '').slice(0, 60)
|
|
8
|
+
const description = (props.description || '').slice(0, 200)
|
|
11
9
|
</script>
|
|
12
10
|
|
|
13
11
|
<template>
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const props = withDefaults(defineProps<{ title?: string, description?: string, headline?: string }>(), {
|
|
2
|
+
const props = withDefaults(defineProps<{ title?: string, description?: string }>(), {
|
|
5
3
|
title: 'title',
|
|
6
4
|
description: 'description',
|
|
7
5
|
})
|
|
8
6
|
|
|
9
|
-
const
|
|
10
|
-
const
|
|
7
|
+
const appConfig = useAppConfig()
|
|
8
|
+
const logoPath = appConfig.header?.logo?.dark || appConfig.header?.logo?.light
|
|
9
|
+
|
|
10
|
+
const logoSvg = await fetchLogoSvg(logoPath)
|
|
11
|
+
|
|
12
|
+
const title = (props.title || '').slice(0, 60)
|
|
13
|
+
const description = (props.description || '').slice(0, 200)
|
|
14
|
+
|
|
15
|
+
async function fetchLogoSvg(path?: string): Promise<string> {
|
|
16
|
+
if (!path) return ''
|
|
17
|
+
try {
|
|
18
|
+
// eslint-disable-next-line
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
const { url: siteUrl } = useSiteConfig()
|
|
21
|
+
const url = path.startsWith('http') ? path : `${siteUrl}${path}`
|
|
22
|
+
const svg = await $fetch<string>(url, { responseType: 'text' })
|
|
23
|
+
return svg.replace('<svg', '<svg width="100%" height="100%"')
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return ''
|
|
27
|
+
}
|
|
28
|
+
}
|
|
11
29
|
</script>
|
|
12
30
|
|
|
13
31
|
<template>
|
|
14
32
|
<div class="w-full h-full flex items-center justify-center bg-neutral-900">
|
|
15
33
|
<svg
|
|
16
|
-
class="absolute right-0 top-0 opacity-50
|
|
34
|
+
class="absolute right-0 top-0 opacity-50"
|
|
17
35
|
width="629"
|
|
18
36
|
height="593"
|
|
19
37
|
viewBox="0 0 629 593"
|
|
@@ -54,19 +72,24 @@ const description = computed(() => (props.description || '').slice(0, 200))
|
|
|
54
72
|
</defs>
|
|
55
73
|
</svg>
|
|
56
74
|
|
|
57
|
-
<div
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
75
|
+
<div
|
|
76
|
+
class="flex flex-col items-center justify-center p-8"
|
|
77
|
+
>
|
|
78
|
+
<div
|
|
79
|
+
v-if="logoSvg"
|
|
80
|
+
class="flex items-center justify-center mb-10 max-w-[900px]"
|
|
81
|
+
style="width: 72px; height: 72px;"
|
|
82
|
+
v-html="logoSvg"
|
|
83
|
+
/>
|
|
61
84
|
<h1
|
|
62
85
|
v-if="title"
|
|
63
|
-
class="
|
|
86
|
+
class="m-0 text-5xl font-semibold mb-4 text-white text-center"
|
|
64
87
|
>
|
|
65
|
-
|
|
88
|
+
{{ title }}
|
|
66
89
|
</h1>
|
|
67
90
|
<p
|
|
68
91
|
v-if="description"
|
|
69
|
-
class="text-center text-2xl text-neutral-300 leading-tight"
|
|
92
|
+
class="text-center text-2xl text-neutral-300 leading-tight max-w-[800px]"
|
|
70
93
|
>
|
|
71
94
|
{{ description }}
|
|
72
95
|
</p>
|
|
@@ -1,20 +1,38 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const appConfig = useAppConfig()
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
'
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
interface FooterLink {
|
|
5
|
+
'icon': string
|
|
6
|
+
'to': string
|
|
7
|
+
'target': '_blank'
|
|
8
|
+
'aria-label': string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const links = computed<FooterLink[]>(() => {
|
|
12
|
+
const socialLinks = Object.entries(appConfig.socials || {}).flatMap(([key, url]) => {
|
|
13
|
+
if (typeof url !== 'string' || !url) {
|
|
14
|
+
return []
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return [{
|
|
18
|
+
'icon': `i-simple-icons-${key}`,
|
|
19
|
+
'to': url,
|
|
20
|
+
'target': '_blank' as const,
|
|
21
|
+
'aria-label': `${key} social link`,
|
|
22
|
+
}]
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const githubLink = appConfig.github && appConfig.github.url
|
|
26
|
+
? [{
|
|
27
|
+
'icon': 'i-simple-icons-github',
|
|
28
|
+
'to': appConfig.github.url,
|
|
29
|
+
'target': '_blank' as const,
|
|
30
|
+
'aria-label': 'GitHub repository',
|
|
31
|
+
}]
|
|
32
|
+
: []
|
|
33
|
+
|
|
34
|
+
return [...socialLinks, ...githubLink]
|
|
35
|
+
})
|
|
18
36
|
</script>
|
|
19
37
|
|
|
20
38
|
<template>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { useDocusI18n } from '../../composables/useDocusI18n'
|
|
3
|
+
import { useSubNavigation } from '~/composables/useSubNavigation'
|
|
3
4
|
|
|
4
5
|
const appConfig = useAppConfig()
|
|
5
6
|
const site = useSiteConfig()
|
|
6
7
|
|
|
7
8
|
const { isEnabled: isAssistantEnabled } = useAssistant()
|
|
8
9
|
const { localePath, isEnabled, locales } = useDocusI18n()
|
|
10
|
+
const { subNavigationMode } = useSubNavigation()
|
|
9
11
|
|
|
10
12
|
const links = computed(() => appConfig.github && appConfig.github.url
|
|
11
13
|
? [
|
|
@@ -22,6 +24,7 @@ const links = computed(() => appConfig.github && appConfig.github.url
|
|
|
22
24
|
<template>
|
|
23
25
|
<UHeader
|
|
24
26
|
:ui="{ center: 'flex-1' }"
|
|
27
|
+
:class="{ 'flex flex-col': subNavigationMode === 'header' }"
|
|
25
28
|
:to="localePath('/')"
|
|
26
29
|
:title="appConfig.header?.title || site.name"
|
|
27
30
|
>
|
|
@@ -83,5 +86,12 @@ const links = computed(() => appConfig.github && appConfig.github.url
|
|
|
83
86
|
<template #body>
|
|
84
87
|
<AppHeaderBody />
|
|
85
88
|
</template>
|
|
89
|
+
|
|
90
|
+
<template
|
|
91
|
+
v-if="subNavigationMode === 'header'"
|
|
92
|
+
#bottom
|
|
93
|
+
>
|
|
94
|
+
<AppHeaderBottom />
|
|
95
|
+
</template>
|
|
86
96
|
</UHeader>
|
|
87
97
|
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useSubNavigation } from '~/composables/useSubNavigation'
|
|
3
|
+
|
|
4
|
+
const { sections } = useSubNavigation()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<USeparator class="hidden lg:flex" />
|
|
9
|
+
|
|
10
|
+
<UContainer class="hidden lg:flex items-center justify-between">
|
|
11
|
+
<UNavigationMenu
|
|
12
|
+
:items="sections"
|
|
13
|
+
variant="pill"
|
|
14
|
+
highlight
|
|
15
|
+
class="-mx-2.5 -mb-px"
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
<AppHeaderBottomRight />
|
|
19
|
+
</UContainer>
|
|
20
|
+
</template>
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const navigation = inject<Ref<ContentNavigationItem[]>>('navigation')
|
|
2
|
+
const { sidebarNavigation } = useSubNavigation()
|
|
5
3
|
</script>
|
|
6
4
|
|
|
7
5
|
<template>
|
|
8
6
|
<UContentNavigation
|
|
9
7
|
highlight
|
|
10
|
-
:navigation="
|
|
8
|
+
:navigation="sidebarNavigation"
|
|
11
9
|
/>
|
|
12
10
|
</template>
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useSubNavigation } from '~/composables/useSubNavigation'
|
|
3
|
+
|
|
4
|
+
const { subNavigationMode, sections } = useSubNavigation()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
1
7
|
<template>
|
|
2
|
-
<div
|
|
8
|
+
<div
|
|
9
|
+
v-if="subNavigationMode === 'aside'"
|
|
10
|
+
class="mb-2"
|
|
11
|
+
>
|
|
12
|
+
<UPageAnchors :links="sections" />
|
|
13
|
+
<USeparator
|
|
14
|
+
type="dashed"
|
|
15
|
+
class="my-4"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div v-else />
|
|
3
20
|
</template>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useSubNavigation } from '~/composables/useSubNavigation'
|
|
3
|
+
import type { ContentTocLink } from '@nuxt/ui'
|
|
4
|
+
|
|
5
|
+
defineProps<{
|
|
6
|
+
links?: ContentTocLink[]
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const { subNavigationMode, sidebarNavigation, currentSection } = useSubNavigation()
|
|
10
|
+
const { t } = useDocusI18n()
|
|
11
|
+
|
|
12
|
+
const menuDrawerOpen = ref(false)
|
|
13
|
+
const tocDrawerOpen = ref(false)
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<div
|
|
18
|
+
v-if="subNavigationMode"
|
|
19
|
+
class="lg:hidden sticky top-(--ui-header-height) z-10 bg-default/75 backdrop-blur -mx-4 p-2 border-b border-dashed border-default flex justify-between"
|
|
20
|
+
>
|
|
21
|
+
<UDrawer
|
|
22
|
+
v-model:open="menuDrawerOpen"
|
|
23
|
+
direction="left"
|
|
24
|
+
:title="currentSection?.title"
|
|
25
|
+
:handle="false"
|
|
26
|
+
inset
|
|
27
|
+
side="left"
|
|
28
|
+
:ui="{ content: 'w-full max-w-2/3' }"
|
|
29
|
+
>
|
|
30
|
+
<UButton
|
|
31
|
+
:label="t('docs.menu')"
|
|
32
|
+
icon="i-lucide-text-align-start"
|
|
33
|
+
color="neutral"
|
|
34
|
+
variant="link"
|
|
35
|
+
size="xs"
|
|
36
|
+
:aria-label="t('docs.menu')"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<template #body>
|
|
40
|
+
<UContentNavigation
|
|
41
|
+
:navigation="sidebarNavigation"
|
|
42
|
+
default-open
|
|
43
|
+
trailing-icon="i-lucide-chevron-right"
|
|
44
|
+
:ui="{ linkTrailingIcon: 'group-data-[state=open]:rotate-90' }"
|
|
45
|
+
highlight
|
|
46
|
+
/>
|
|
47
|
+
</template>
|
|
48
|
+
</UDrawer>
|
|
49
|
+
|
|
50
|
+
<UDrawer
|
|
51
|
+
v-model:open="tocDrawerOpen"
|
|
52
|
+
direction="right"
|
|
53
|
+
:handle="false"
|
|
54
|
+
inset
|
|
55
|
+
side="right"
|
|
56
|
+
no-body-styles
|
|
57
|
+
:ui="{ content: 'w-full max-w-2/3' }"
|
|
58
|
+
>
|
|
59
|
+
<UButton
|
|
60
|
+
:label="t('docs.toc')"
|
|
61
|
+
trailing-icon="i-lucide-chevron-right"
|
|
62
|
+
color="neutral"
|
|
63
|
+
variant="link"
|
|
64
|
+
size="xs"
|
|
65
|
+
:aria-label="t('docs.toc')"
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
<template #body>
|
|
69
|
+
<UContentToc
|
|
70
|
+
v-if="links?.length"
|
|
71
|
+
:links="links"
|
|
72
|
+
:open="true"
|
|
73
|
+
default-open
|
|
74
|
+
:ui="{
|
|
75
|
+
root: '!mx-0 !px-1 top-0 overflow-visible',
|
|
76
|
+
container: '!pt-0 border-b-0',
|
|
77
|
+
trailingIcon: 'hidden',
|
|
78
|
+
bottom: 'flex flex-col',
|
|
79
|
+
}"
|
|
80
|
+
>
|
|
81
|
+
<template #bottom>
|
|
82
|
+
<DocsAsideRightBottom />
|
|
83
|
+
</template>
|
|
84
|
+
</UContentToc>
|
|
85
|
+
</template>
|
|
86
|
+
</UDrawer>
|
|
87
|
+
</div>
|
|
88
|
+
</template>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useSubNavigation } from '~/composables/useSubNavigation'
|
|
3
|
+
import type { DocsCollectionItem } from '@nuxt/content'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
page?: DocsCollectionItem | null
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const links = computed(() => props.page?.body?.toc?.links || [])
|
|
10
|
+
|
|
11
|
+
const { shouldPushContent: shouldHideToc } = useAssistant()
|
|
12
|
+
const { subNavigationMode } = useSubNavigation()
|
|
13
|
+
const appConfig = useAppConfig()
|
|
14
|
+
const { t } = useDocusI18n()
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<div>
|
|
19
|
+
<UContentToc
|
|
20
|
+
v-if="links.length && !shouldHideToc"
|
|
21
|
+
highlight
|
|
22
|
+
:title="appConfig.toc?.title || t('docs.toc')"
|
|
23
|
+
:links="links"
|
|
24
|
+
:class="{ 'hidden lg:block': subNavigationMode }"
|
|
25
|
+
>
|
|
26
|
+
<template #bottom>
|
|
27
|
+
<DocsAsideRightBottom />
|
|
28
|
+
</template>
|
|
29
|
+
</UContentToc>
|
|
30
|
+
|
|
31
|
+
<DocsAsideMobileBar :links="links" />
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
@@ -16,7 +16,7 @@ const explainIcon = computed(() => appConfig.assistant?.icons?.explain || 'i-luc
|
|
|
16
16
|
<template>
|
|
17
17
|
<div
|
|
18
18
|
v-if="appConfig.toc?.bottom?.links?.length || showExplainWithAi"
|
|
19
|
-
class="
|
|
19
|
+
class="space-y-6"
|
|
20
20
|
>
|
|
21
21
|
<USeparator type="dashed" />
|
|
22
22
|
|
|
@@ -1,12 +1,27 @@
|
|
|
1
|
+
import { useNuxtApp, useRuntimeConfig } from '#imports'
|
|
1
2
|
import type { LocaleObject } from '@nuxtjs/i18n'
|
|
3
|
+
import type { Ref } from 'vue'
|
|
4
|
+
import { ref } from 'vue'
|
|
5
|
+
|
|
6
|
+
type DocusNuxtApp = ReturnType<typeof useNuxtApp> & {
|
|
7
|
+
$i18n?: {
|
|
8
|
+
locale: Ref<string>
|
|
9
|
+
t: (key: string) => string
|
|
10
|
+
}
|
|
11
|
+
$locale?: string
|
|
12
|
+
$localeMessages?: Record<string, unknown>
|
|
13
|
+
$localePath?: (path: string) => string
|
|
14
|
+
$switchLocalePath?: (locale?: string) => string
|
|
15
|
+
}
|
|
2
16
|
|
|
3
17
|
export const useDocusI18n = () => {
|
|
4
18
|
const config = useRuntimeConfig().public
|
|
19
|
+
const nuxtApp = useNuxtApp() as DocusNuxtApp
|
|
5
20
|
const isEnabled = ref(!!config.i18n)
|
|
6
21
|
|
|
7
22
|
if (!isEnabled.value) {
|
|
8
|
-
const locale =
|
|
9
|
-
const localeMessages =
|
|
23
|
+
const locale = nuxtApp.$locale || 'en'
|
|
24
|
+
const localeMessages = nuxtApp.$localeMessages || {}
|
|
10
25
|
|
|
11
26
|
return {
|
|
12
27
|
isEnabled,
|
|
@@ -21,7 +36,8 @@ export const useDocusI18n = () => {
|
|
|
21
36
|
}
|
|
22
37
|
}
|
|
23
38
|
|
|
24
|
-
const
|
|
39
|
+
const locale = nuxtApp.$i18n?.locale || ref('en')
|
|
40
|
+
const t = nuxtApp.$i18n?.t || ((key: string) => key)
|
|
25
41
|
const filteredLocales = (config.docus as { filteredLocales: LocaleObject<string>[] })?.filteredLocales || []
|
|
26
42
|
|
|
27
43
|
return {
|
|
@@ -29,7 +45,7 @@ export const useDocusI18n = () => {
|
|
|
29
45
|
locale,
|
|
30
46
|
locales: filteredLocales,
|
|
31
47
|
t,
|
|
32
|
-
localePath:
|
|
33
|
-
switchLocalePath:
|
|
48
|
+
localePath: nuxtApp.$localePath || ((path: string) => path),
|
|
49
|
+
switchLocalePath: nuxtApp.$switchLocalePath || (() => ''),
|
|
34
50
|
}
|
|
35
51
|
}
|
|
@@ -65,7 +65,7 @@ function triggerLinkDownload(url: string, filename: string) {
|
|
|
65
65
|
|
|
66
66
|
export const useLogoAssets = () => {
|
|
67
67
|
const appConfig = useAppConfig()
|
|
68
|
-
const colorMode = useColorMode()
|
|
68
|
+
const colorMode = useColorMode() as { value: string, forced?: boolean }
|
|
69
69
|
const toast = useToast()
|
|
70
70
|
const { t } = useDocusI18n()
|
|
71
71
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ContentNavigationItem } from '@nuxt/content'
|
|
2
|
+
|
|
3
|
+
function getFirstPagePath(item: ContentNavigationItem): string {
|
|
4
|
+
let current = item
|
|
5
|
+
while (current.children?.length) {
|
|
6
|
+
current = current.children[0]!
|
|
7
|
+
}
|
|
8
|
+
return current.path
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function useSubNavigation(providedNavigation?: Ref<ContentNavigationItem[] | null | undefined>) {
|
|
12
|
+
const route = useRoute()
|
|
13
|
+
const appConfig = useAppConfig()
|
|
14
|
+
const navigation = providedNavigation ?? inject<Ref<ContentNavigationItem[]>>('navigation')
|
|
15
|
+
|
|
16
|
+
const isDocsPage = computed(() => route.meta.layout === 'docs')
|
|
17
|
+
|
|
18
|
+
const subNavigationMode = computed(() => {
|
|
19
|
+
if (!isDocsPage.value) return undefined
|
|
20
|
+
return (appConfig.navigation as { sub?: 'header' | 'aside' } | undefined)?.sub
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const currentSection = computed(() => {
|
|
24
|
+
if (!subNavigationMode.value || !navigation?.value) return undefined
|
|
25
|
+
return navigation.value.find(item =>
|
|
26
|
+
route.path === item.path || route.path.startsWith(item.path + '/'),
|
|
27
|
+
)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const sections = computed(() => {
|
|
31
|
+
if (!subNavigationMode.value || !navigation?.value) return []
|
|
32
|
+
return navigation.value
|
|
33
|
+
.filter(item => item.children?.length)
|
|
34
|
+
.map(item => ({
|
|
35
|
+
label: item.title,
|
|
36
|
+
icon: item.icon as string | undefined,
|
|
37
|
+
to: getFirstPagePath(item),
|
|
38
|
+
active: route.path === item.path || route.path.startsWith(item.path + '/'),
|
|
39
|
+
}))
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const sidebarNavigation = computed(() => {
|
|
43
|
+
if (subNavigationMode.value && currentSection.value) {
|
|
44
|
+
return currentSection.value.children || []
|
|
45
|
+
}
|
|
46
|
+
return navigation?.value || []
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
subNavigationMode,
|
|
51
|
+
sections,
|
|
52
|
+
currentSection,
|
|
53
|
+
sidebarNavigation,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -131,19 +131,10 @@ addPrerenderPath(`/raw${route.path}.md`)
|
|
|
131
131
|
<UContentSurround :surround="surround" />
|
|
132
132
|
</UPageBody>
|
|
133
133
|
|
|
134
|
-
<template
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
<UContentToc
|
|
139
|
-
highlight
|
|
140
|
-
:title="appConfig.toc?.title || t('docs.toc')"
|
|
141
|
-
:links="page.body?.toc?.links"
|
|
142
|
-
>
|
|
143
|
-
<template #bottom>
|
|
144
|
-
<DocsAsideRightBottom />
|
|
145
|
-
</template>
|
|
146
|
-
</UContentToc>
|
|
134
|
+
<template #right>
|
|
135
|
+
<DocsAsideRight
|
|
136
|
+
:page="page"
|
|
137
|
+
/>
|
|
147
138
|
</template>
|
|
148
139
|
</UPage>
|
|
149
140
|
</template>
|
package/i18n/locales/ar.json
CHANGED
package/i18n/locales/be.json
CHANGED
package/i18n/locales/bg.json
CHANGED
package/i18n/locales/bn.json
CHANGED
package/i18n/locales/ca.json
CHANGED
package/i18n/locales/ckb.json
CHANGED
package/i18n/locales/cs.json
CHANGED