docus 3.0.0-beta.2 → 3.0.0-beta.5

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.
Files changed (144) hide show
  1. package/package.json +12 -19
  2. package/{app → theme/app}/router.options.ts +0 -0
  3. package/{assets → theme/assets}/css/fonts.css +0 -0
  4. package/theme/assets/css/main.css +104 -0
  5. package/{components → theme/components}/app/Container.vue +0 -0
  6. package/{components → theme/components}/app/Footer.vue +4 -4
  7. package/theme/components/app/MobileNav.vue +83 -0
  8. package/theme/components/app/Navbar.vue +37 -0
  9. package/{components → theme/components}/app/NavbarLogo.vue +4 -4
  10. package/{components → theme/components}/app/Page.vue +0 -0
  11. package/{components → theme/components}/app/PoweredByDocus.vue +0 -0
  12. package/{components → theme/components}/content/Alert.vue +0 -0
  13. package/{components → theme/components}/content/BlockHero.vue +0 -0
  14. package/{components → theme/components}/content/ButtonLink.vue +1 -1
  15. package/{components → theme/components}/content/Card.vue +0 -0
  16. package/{components → theme/components}/content/CardGrid.vue +0 -0
  17. package/{components → theme/components}/content/CodeBlock.vue +0 -0
  18. package/{components → theme/components}/content/CodeGroup.vue +6 -6
  19. package/{components → theme/components}/content/CopyButton.vue +0 -0
  20. package/{components → theme/components}/content/List.vue +0 -0
  21. package/{components → theme/components}/content/NeedContribution.vue +0 -0
  22. package/{components → theme/components}/content/ReadMore.vue +0 -0
  23. package/{components → theme/components}/content/Sandbox.vue +2 -2
  24. package/{components → theme/components}/content/TabsHeader.vue +2 -2
  25. package/{components → theme/components}/content/Terminal.vue +0 -0
  26. package/{components → theme/components}/content/VideoPlayer.vue +0 -0
  27. package/theme/components/dev/Debug.vue +63 -0
  28. package/{components → theme/components}/docs/DocsAside.vue +2 -2
  29. package/{components → theme/components}/docs/DocsAsideTree.vue +8 -6
  30. package/{components → theme/components}/docs/DocsHero.vue +0 -0
  31. package/{components → theme/components}/docs/DocsPage.vue +0 -1
  32. package/theme/components/docs/DocsPageContent.vue +32 -0
  33. package/{components → theme/components}/docs/DocsToc.vue +15 -12
  34. package/{components → theme/components}/globals/Icon.vue +0 -0
  35. package/{components → theme/components}/globals/Logo.vue +0 -0
  36. package/{components → theme/components}/globals/NuxtImg.vue +0 -0
  37. package/{components → theme/components}/globals/SocialIcons.vue +2 -2
  38. package/{components → theme/components}/globals/ThemeSelect.vue +1 -1
  39. package/{components → theme/components}/icons/IconAlgolia.vue +0 -0
  40. package/{components → theme/components}/icons/IconArrowLeft.vue +0 -0
  41. package/{components → theme/components}/icons/IconArrowRight.vue +0 -0
  42. package/{components → theme/components}/icons/IconBadgeCheck.vue +0 -0
  43. package/{components → theme/components}/icons/IconCheck.vue +0 -0
  44. package/{components → theme/components}/icons/IconCheckCircle.vue +0 -0
  45. package/{components → theme/components}/icons/IconChevronRight.vue +0 -0
  46. package/{components → theme/components}/icons/IconClipboardCheck.vue +0 -0
  47. package/{components → theme/components}/icons/IconClipboardCopy.vue +0 -0
  48. package/{components → theme/components}/icons/IconCodeSandbox.vue +0 -0
  49. package/{components → theme/components}/icons/IconCopy.vue +0 -0
  50. package/{components → theme/components}/icons/IconDots.vue +0 -0
  51. package/{components → theme/components}/icons/IconEdit.vue +0 -0
  52. package/{components → theme/components}/icons/IconExclamationCircle.vue +0 -0
  53. package/{components → theme/components}/icons/IconExclamationTriangle.vue +0 -0
  54. package/{components → theme/components}/icons/IconExternalLink.vue +0 -0
  55. package/{components → theme/components}/icons/IconGit.vue +0 -0
  56. package/{components → theme/components}/icons/IconGitHub.vue +0 -0
  57. package/{components → theme/components}/icons/IconHeart.vue +0 -0
  58. package/{components → theme/components}/icons/IconInformationCircle.vue +0 -0
  59. package/{components → theme/components}/icons/IconLighthouse.vue +0 -0
  60. package/{components → theme/components}/icons/IconLine.vue +0 -0
  61. package/{components → theme/components}/icons/IconMarkdown.vue +0 -0
  62. package/{components → theme/components}/icons/IconMenu.vue +0 -0
  63. package/{components → theme/components}/icons/IconMenuAlt.vue +0 -0
  64. package/{components → theme/components}/icons/IconMinus.vue +0 -0
  65. package/{components → theme/components}/icons/IconMoon.vue +0 -0
  66. package/{components → theme/components}/icons/IconNuxt.vue +0 -0
  67. package/{components → theme/components}/icons/IconNuxtContent.vue +0 -0
  68. package/{components → theme/components}/icons/IconNuxtLabs.vue +0 -0
  69. package/{components → theme/components}/icons/IconPlus.vue +0 -0
  70. package/{components → theme/components}/icons/IconPuzzle.vue +0 -0
  71. package/{components → theme/components}/icons/IconSSG.vue +0 -0
  72. package/{components → theme/components}/icons/IconSearch.vue +0 -0
  73. package/{components → theme/components}/icons/IconSun.vue +0 -0
  74. package/theme/components/icons/IconTailwind.vue +3 -0
  75. package/{components → theme/components}/icons/IconTocBack.vue +0 -0
  76. package/{components → theme/components}/icons/IconTocCurrent.vue +0 -0
  77. package/{components → theme/components}/icons/IconTocNext.vue +0 -0
  78. package/{components → theme/components}/icons/IconTranslate.vue +0 -0
  79. package/{components → theme/components}/icons/IconTwitter.vue +0 -0
  80. package/{components → theme/components}/icons/IconVite.vue +0 -0
  81. package/{components → theme/components}/icons/IconVue.vue +0 -0
  82. package/{components → theme/components}/icons/IconVueTelescope.vue +0 -0
  83. package/{components → theme/components}/icons/IconWindi.vue +0 -0
  84. package/{components → theme/components}/icons/IconX.vue +0 -0
  85. package/{components → theme/components}/icons/IconXCircle.vue +0 -0
  86. package/{components → theme/components}/icons/IconZap.vue +0 -0
  87. package/{components → theme/components}/prose/ProseA.vue +3 -3
  88. package/{components → theme/components}/prose/ProseBlockquote.vue +1 -1
  89. package/{components → theme/components}/prose/ProseCode.vue +3 -4
  90. package/{components → theme/components}/prose/ProseCodeInline.vue +2 -2
  91. package/{components → theme/components}/prose/ProseEm.vue +0 -0
  92. package/{components → theme/components}/prose/ProseH1.vue +0 -0
  93. package/{components → theme/components}/prose/ProseH2.vue +0 -0
  94. package/{components → theme/components}/prose/ProseH3.vue +0 -0
  95. package/{components → theme/components}/prose/ProseH4.vue +0 -0
  96. package/{components → theme/components}/prose/ProseHr.vue +1 -1
  97. package/{components → theme/components}/prose/ProseImg.vue +0 -0
  98. package/{components → theme/components}/prose/ProseLi.vue +2 -2
  99. package/{components → theme/components}/prose/ProseOl.vue +0 -0
  100. package/{components → theme/components}/prose/ProseP.vue +0 -0
  101. package/{components → theme/components}/prose/ProseStrong.vue +0 -0
  102. package/{components → theme/components}/prose/ProseTable.vue +0 -0
  103. package/{components → theme/components}/prose/ProseTbody.vue +0 -0
  104. package/{components → theme/components}/prose/ProseTd.vue +0 -0
  105. package/{components → theme/components}/prose/ProseTh.vue +1 -1
  106. package/{components → theme/components}/prose/ProseThead.vue +1 -1
  107. package/{components → theme/components}/prose/ProseTr.vue +1 -1
  108. package/{components → theme/components}/prose/ProseUl.vue +0 -0
  109. package/theme/composables/useDocus.ts +42 -0
  110. package/theme/composables/useMenu.ts +7 -0
  111. package/{composables → theme/composables}/useScrollToHeading.ts +0 -0
  112. package/{composables → theme/composables}/useScrollspy.ts +0 -0
  113. package/theme/composables/useUserAgent.ts +5 -0
  114. package/{composables/useTheme.ts → theme/composables/utils.ts} +0 -8
  115. package/{layouts → theme/layouts}/default.vue +6 -8
  116. package/{layouts → theme/layouts}/page.vue +7 -1
  117. package/theme/middleware/components.ts +25 -0
  118. package/theme/middleware/navigation.global.ts +12 -0
  119. package/theme/middleware/page.ts +8 -0
  120. package/theme/middleware/theme.global.ts +12 -0
  121. package/{nuxt.config.ts → theme/nuxt.config.ts} +84 -64
  122. package/theme/pages/[...slug].vue +62 -0
  123. package/theme/plugins/menu.ts +65 -0
  124. package/theme/plugins/user-agent.ts +25 -0
  125. package/theme/utils/components.ts +25 -0
  126. package/theme/utils/navigation.ts +49 -0
  127. package/theme/utils/plugin.ts +21 -0
  128. package/theme/utils/queries.ts +68 -0
  129. package/theme/utils/state.ts +32 -0
  130. package/theme/utils/theme.ts +64 -0
  131. package/assets/css/main.css +0 -11
  132. package/assets/css/tailwind.css +0 -282
  133. package/components/app/Navbar.vue +0 -26
  134. package/components/docs/DocsPageContent.vue +0 -31
  135. package/composables/useContent.ts +0 -156
  136. package/composables/useMenu.ts +0 -22
  137. package/pages/[...slug].vue +0 -26
  138. package/public/android-chrome-192x192.png +0 -0
  139. package/public/android-chrome-512x512.png +0 -0
  140. package/public/apple-touch-icon.png +0 -0
  141. package/public/favicon-16x16.png +0 -0
  142. package/public/favicon-32x32.png +0 -0
  143. package/public/favicon.ico +0 -0
  144. package/public/site.webmanifest +0 -1
@@ -6,41 +6,72 @@ import { resolve } from 'pathe'
6
6
  const themeDir = fileURLToPath(new URL('./', import.meta.url))
7
7
  const resolveThemeDir = (path: string) => resolve(themeDir, path)
8
8
 
9
+ const plugins = []
10
+
11
+ const components = [
12
+ {
13
+ prefix: '',
14
+ path: './components/app',
15
+ global: true,
16
+ },
17
+ {
18
+ prefix: '',
19
+ path: './components/docs',
20
+ global: true,
21
+ },
22
+ {
23
+ prefix: '',
24
+ path: './components/prose',
25
+ global: true,
26
+ },
27
+ {
28
+ prefix: '',
29
+ path: './components/globals',
30
+ global: true,
31
+ },
32
+ {
33
+ prefix: '',
34
+ path: './components/content',
35
+ global: true,
36
+ },
37
+ {
38
+ prefix: '',
39
+ path: './components/icons',
40
+ global: true,
41
+ },
42
+ {
43
+ prefix: '',
44
+ path: './components/icons',
45
+ global: true,
46
+ },
47
+ ]
48
+
49
+ // Only register the plugin in development as it's not needed in production
50
+ if (process.env.NODE_ENV === 'development') {
51
+ // Dev plugin
52
+ plugins.push({
53
+ src: resolveThemeDir('utils/plugin.ts'),
54
+ })
55
+ }
56
+
57
+ // Dev components
58
+ components.push({
59
+ prefix: '',
60
+ path: './components/dev',
61
+ global: true,
62
+ })
63
+
9
64
  export default defineNuxtConfig({
65
+ /*
10
66
  runtimeConfig: {
11
67
  public: {
12
68
  plausible: {
13
69
  domain: process.env.PLAUSIBLE_DOMAIN,
14
70
  },
15
- theme: {
16
- title: 'Docus',
17
- twitter: '@docus_',
18
- github: 'nuxtlabs/docus',
19
- header: {
20
- title: false,
21
- logo: true,
22
- },
23
- footer: {
24
- credits: {
25
- icon: 'IconNuxtLabs',
26
- text: 'Made by Nuxt Labs',
27
- },
28
- icons: [
29
- {
30
- label: 'NuxtJS',
31
- href: 'https://nuxtjs.org',
32
- component: 'IconNuxt',
33
- },
34
- {
35
- label: 'Vue Telescope',
36
- href: 'https://vuetelescope.com',
37
- component: 'IconVueTelescope',
38
- },
39
- ],
40
- },
41
- },
42
71
  },
43
72
  },
73
+ */
74
+ plugins,
44
75
  head: {
45
76
  title: 'Docus',
46
77
  link: [
@@ -61,46 +92,29 @@ export default defineNuxtConfig({
61
92
  /**
62
93
  * Components
63
94
  */
64
- components: [
65
- {
66
- prefix: '',
67
- path: './components/app',
68
- global: true,
69
- },
70
- {
71
- prefix: '',
72
- path: './components/docs',
73
- global: true,
74
- },
75
- {
76
- prefix: '',
77
- path: './components/prose',
78
- global: true,
79
- },
80
- {
81
- prefix: '',
82
- path: './components/globals',
83
- global: true,
84
- },
85
- {
86
- prefix: '',
87
- path: './components/content',
88
- global: true,
89
- },
90
- {
91
- prefix: '',
92
- path: './components/icons',
93
- global: true,
94
- },
95
- ],
95
+ // To enable for `components` middleware
96
+ //
97
+ // components: [
98
+ // './components/app',
99
+ // './components/docs',
100
+ // './components/prose',
101
+ // './components/globals',
102
+ // './components/content',
103
+ // './components/dev',
104
+ // {
105
+ // prefix: '',
106
+ // path: './components/icons',
107
+ // global: true,
108
+ // },
109
+ // ],
110
+ // To enable for working build
111
+ components,
96
112
  css: [
97
- resolveThemeDir('assets/css/main.css'),
98
113
  resolveThemeDir('assets/css/fonts.css'),
99
- resolveThemeDir('assets/css/tailwind.css'),
100
114
  ],
101
115
  tailwindcss: {
102
116
  viewer: false,
103
-
117
+ cssPath: resolveThemeDir('assets/css/main.css'),
104
118
  config: {
105
119
  darkMode: 'class',
106
120
  theme: {
@@ -112,6 +126,10 @@ export default defineNuxtConfig({
112
126
  fontFamily: {
113
127
  sans: 'Inter, sans-serif',
114
128
  },
129
+ spacing: {
130
+ base: '320px',
131
+ header: 'var(--header-height)',
132
+ },
115
133
  },
116
134
  },
117
135
  plugins: [
@@ -121,12 +139,13 @@ export default defineNuxtConfig({
121
139
  require('@tailwindcss/aspect-ratio'),
122
140
  ],
123
141
  content: [
142
+ '~/content/**/*.{md,yml,json,json5,csv}',
143
+ resolveThemeDir('assets/**/*.{mjs,vue,js,ts}'),
124
144
  resolveThemeDir('components/**/*.{mjs,vue,js,ts}'),
125
145
  resolveThemeDir('layouts/**/*.{mjs,vue,js,ts}'),
126
146
  resolveThemeDir('pages/**/*.{mjs,vue,js,ts}'),
127
147
  ],
128
148
  safelist: [24, 36, 48, 60, 72, 84, 96, 108, 120].map(number => `pl-[${number}px]`),
129
- cssPath: resolveThemeDir('assets/css/tailwind.css'),
130
149
  },
131
150
  },
132
151
  content: {
@@ -146,6 +165,7 @@ export default defineNuxtConfig({
146
165
  '@nuxtjs/tailwindcss',
147
166
  '@nuxtjs/color-mode',
148
167
  '@nuxthq/admin',
149
- 'vue-plausible',
168
+ // 'vue-plausible',
169
+ '@vueuse/nuxt',
150
170
  ],
151
171
  })
@@ -0,0 +1,62 @@
1
+ <script setup lang="ts">
2
+ definePageMeta({
3
+ middleware: [
4
+ 'page',
5
+ /* 'components' */
6
+ ],
7
+ })
8
+
9
+ const { page, theme } = useDocus()
10
+
11
+ useHead({
12
+ title: `${theme.value?.title} | ${page.value?.title}`,
13
+ description: page.value?.description || theme.value?.description || '',
14
+ meta: [
15
+ { hid: 'og:site_name', property: 'og:site_name', content: 'Nuxt' },
16
+ { hid: 'og:type', property: 'og:type', content: 'website' },
17
+ { hid: 'twitter:site', name: 'twitter:site', content: theme.value?.url || theme.value?.twitter || '' },
18
+ {
19
+ hid: 'twitter:card',
20
+ name: 'twitter:card',
21
+ content: 'summary_large_image',
22
+ },
23
+ {
24
+ hid: 'og:image',
25
+ property: 'og:image',
26
+ content: theme.value?.cover || '',
27
+ },
28
+ {
29
+ hid: 'og:image:secure_url',
30
+ property: 'og:image:secure_url',
31
+ content: theme.value?.cover || '',
32
+ },
33
+ {
34
+ hid: 'og:image:alt',
35
+ property: 'og:image:alt',
36
+ content: theme.value?.coverAlt || '',
37
+ },
38
+ {
39
+ hid: 'twitter:image',
40
+ name: 'twitter:image',
41
+ content: theme.value?.cover || '',
42
+ },
43
+ ],
44
+ })
45
+ </script>
46
+
47
+ <template>
48
+ <Content v-if="page" class="content" :document="page" />
49
+ <p v-else>
50
+ <Alert type="warning">
51
+ Page not found!
52
+ </Alert>
53
+ </p>
54
+ </template>
55
+
56
+ <style scoped>
57
+ .content {
58
+ & > :first-child {
59
+ margin-top: 0 !important;
60
+ }
61
+ }
62
+ </style>
@@ -0,0 +1,65 @@
1
+ export default defineNuxtPlugin((ctx: any) => {
2
+ // Menu visible reference
3
+ const visible = ref(false)
4
+
5
+ // Current tab visible reference
6
+ const currentTab = ref()
7
+
8
+ // Scrollbar gap (used for responsive menu)
9
+ const scrollBarGap = ref()
10
+
11
+ // Open the menu
12
+ const open = () => (visible.value = true)
13
+
14
+ // Close the menu
15
+ const close = () => (visible.value = false)
16
+
17
+ // Toggle the menu (useful for one-off buttons)
18
+ const toggle = () => (visible.value = !visible.value)
19
+
20
+ // Toggle a tab from its id
21
+ const toggleTab = (tab: string) =>
22
+ currentTab.value === tab ? (currentTab.value = undefined) : (currentTab.value = tab)
23
+
24
+ // Watch route change, close on change
25
+ ctx.$router.afterEach(() => setTimeout(close, 50))
26
+
27
+ // Watch visible and remove overflow so the scrollbar disappears when menu is opened
28
+ if (process.client) {
29
+ watch(
30
+ visible,
31
+ (isVisible) => {
32
+ const html = document.querySelector('html')
33
+
34
+ if (isVisible) {
35
+ scrollBarGap.value = window.innerWidth - document.documentElement.clientWidth
36
+ html.style.overflow = 'hidden'
37
+ html.style.paddingRight = `${scrollBarGap.value}px`
38
+ }
39
+ else {
40
+ setTimeout(() => {
41
+ html.style.overflow = ''
42
+ html.style.paddingRight = ''
43
+ }, 100) /* had to put it, because of layout shift on leave transition */
44
+ }
45
+ },
46
+ {
47
+ immediate: true,
48
+ },
49
+ )
50
+ }
51
+
52
+ return {
53
+ provide: {
54
+ menu: {
55
+ scrollBarGap,
56
+ visible,
57
+ close,
58
+ open,
59
+ toggle,
60
+ currentTab,
61
+ toggleTab,
62
+ },
63
+ },
64
+ }
65
+ })
@@ -0,0 +1,25 @@
1
+ export default defineNuxtPlugin(() => {
2
+ const isDesktopSafari = ref(false)
3
+ const isDesktopFirefox = ref(false)
4
+
5
+ const refresh = () => {
6
+ isDesktopSafari.value
7
+ = !/Mobi|Android/i.test(navigator.userAgent)
8
+ && /Safari/i.test(navigator.userAgent)
9
+ && !/Chrome|Chromium/i.test(navigator.userAgent)
10
+
11
+ isDesktopFirefox.value = !/Mobi|Android/i.test(navigator.userAgent) && /Firefox/i.test(navigator.userAgent)
12
+ }
13
+
14
+ if (process.client)
15
+ refresh()
16
+
17
+ return {
18
+ provide: {
19
+ userAgent: {
20
+ isDesktopSafari,
21
+ isDesktopFirefox,
22
+ },
23
+ },
24
+ }
25
+ })
@@ -0,0 +1,25 @@
1
+ import { isHTMLTag } from '@vue/shared'
2
+ import { pascalCase } from 'scule'
3
+ import { useRuntimeConfig } from '#imports'
4
+
5
+ export const flattenComponents = (body, flattened = []) => {
6
+ // Grab tags list from content config
7
+ const { content: { tags = {} } } = useRuntimeConfig().public
8
+
9
+ for (const node of body) {
10
+ if (node?.tag) {
11
+ let tag = node.tag
12
+
13
+ if (Object.keys(tags).includes(tag))
14
+ tag = pascalCase(`prose-${tag}`)
15
+
16
+ if (!isHTMLTag(tag) && !flattened.includes(tag))
17
+ flattened.push(pascalCase(tag))
18
+ }
19
+
20
+ if (node.children)
21
+ flattenComponents(node.children, flattened)
22
+ }
23
+
24
+ return flattened
25
+ }
@@ -0,0 +1,49 @@
1
+ import type { NavItem } from '@nuxt/content/dist/runtime/types'
2
+
3
+ /**
4
+ * Find first child link from a navigation node.
5
+ */
6
+ export const findBottomLink = (link: NavItem) => {
7
+ for (const child of link.children) {
8
+ if (!child.children)
9
+ return child.slug
10
+ }
11
+
12
+ for (const child of link.children) {
13
+ const result = findBottomLink(child)
14
+ if (result)
15
+ return result
16
+ }
17
+ }
18
+
19
+ /**
20
+ * Find current navigation directory from a path.
21
+ */
22
+ export const navFromPath = (path: string, tree: NavItem[]) => {
23
+ for (const file of tree) {
24
+ if (file.slug === path && !file.id)
25
+ return file
26
+
27
+ if (file.children) {
28
+ const result = navFromPath(path, file.children)
29
+ if (result)
30
+ return result
31
+ }
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Find a navigation node from a path.
37
+ */
38
+ export const fileFromPath = (path: string, tree: NavItem[]) => {
39
+ for (const file of tree) {
40
+ if (file.children) {
41
+ const result = fileFromPath(path, file.children)
42
+ if (result)
43
+ return result
44
+ }
45
+
46
+ if (file.slug === path)
47
+ return file
48
+ }
49
+ }
@@ -0,0 +1,21 @@
1
+ import { queryNavigation, queryPage, queryTheme } from './queries'
2
+ import { useRoute } from '#imports'
3
+
4
+ /**
5
+ * Plugin enabled only in development
6
+ * Ensure hot reload works with content sources
7
+ */
8
+ export default defineNuxtPlugin(
9
+ (nuxt) => {
10
+ nuxt.hook(
11
+ 'app:data:refresh',
12
+ async() => {
13
+ const route = useRoute()
14
+
15
+ await queryNavigation()
16
+ await queryTheme()
17
+ await queryPage(route)
18
+ },
19
+ )
20
+ },
21
+ )
@@ -0,0 +1,68 @@
1
+ import { withoutTrailingSlash } from 'ufo'
2
+ import type { ParsedContent } from '@nuxt/content/dist/runtime/types'
3
+ import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router'
4
+ import { defaultThemeConfig } from './theme'
5
+ import { useDocusState } from './state'
6
+ import { fetchContentNavigation, queryContent } from '#imports'
7
+
8
+ export const queryPage = async(route: RouteLocationNormalized | RouteLocationNormalizedLoaded) => {
9
+ const path = withoutTrailingSlash(route.path)
10
+
11
+ const { page, surround } = useDocusState()
12
+
13
+ try {
14
+ await Promise.all([
15
+ queryContent().where({ slug: path }).findOne() as Promise<ParsedContent>,
16
+ queryContent().where({ partial: { $not: true }, navigation: { $not: false } }).findSurround(path) as Promise<ParsedContent[]>,
17
+ ]).then(
18
+ ([_page, _surround]) => {
19
+ if (_page)
20
+ page.value = _page
21
+ else page.value = undefined
22
+
23
+ if (_surround && _surround.length)
24
+ surround.value = _surround
25
+ else surround.value = undefined
26
+
27
+ // Handle layout update from page
28
+ if (_page?.layout)
29
+ route.meta.layout = _page?.layout
30
+ else
31
+ route.meta.layout = 'default'
32
+ },
33
+ )
34
+ }
35
+ catch (e) {
36
+ console.warn(`Could not find page for path ${path}!`)
37
+ page.value = undefined
38
+ surround.value = undefined
39
+ }
40
+ }
41
+
42
+ export const queryNavigation = async() => {
43
+ const { navigation } = useDocusState()
44
+
45
+ navigation.value = await fetchContentNavigation(queryContent().where({
46
+ navigation: {
47
+ $not: false,
48
+ },
49
+ }))
50
+ }
51
+
52
+ export const queryTheme = async() => {
53
+ const { theme } = useDocusState()
54
+
55
+ // Fetch _theme.yml at `content/` root.
56
+ const query = await queryContent().where({
57
+ id: 'content:_theme.yml',
58
+ }).findOne()
59
+
60
+ if (!query) {
61
+ // Assign default theme config if none found.
62
+ theme.value = defaultThemeConfig
63
+
64
+ return
65
+ }
66
+
67
+ theme.value = query.body
68
+ }
@@ -0,0 +1,32 @@
1
+ import type { NavItem, ParsedContent } from '@nuxt/content/dist/runtime/types'
2
+ import type { ThemeConfig } from './theme'
3
+
4
+ export const useDocusState = () => {
5
+ /**
6
+ * Navigation tree from root of app.
7
+ */
8
+ const navigation = useState<NavItem[]>('docus-navigation', () => null)
9
+
10
+ /**
11
+ * Current page complete data.
12
+ */
13
+ const page = useState<ParsedContent>('docus-page', () => null)
14
+
15
+ /**
16
+ * Previous and next page data.
17
+ * Format: [prev, next]
18
+ */
19
+ const surround = useState<ParsedContent[]>('docus-page-surround', () => null)
20
+
21
+ /**
22
+ * Theme configuration.
23
+ */
24
+ const theme = useState<ThemeConfig>('docus-theme', () => null)
25
+
26
+ return {
27
+ navigation,
28
+ page,
29
+ surround,
30
+ theme,
31
+ }
32
+ }
@@ -0,0 +1,64 @@
1
+ export interface ThemeIcon {
2
+ label: string
3
+ href: string
4
+ component: string
5
+ }
6
+
7
+ export interface ThemeDebugConfig {
8
+ page: boolean
9
+ navigation: boolean
10
+ theme: boolean
11
+ }
12
+
13
+ export interface ThemeConfig {
14
+ title: string
15
+ description: string
16
+ twitter: string
17
+ github: string
18
+ cover: string
19
+ coverAlt: string
20
+ header: {
21
+ title: false | string
22
+ logo: boolean | string
23
+ }
24
+ footer: {
25
+ credits: false | {
26
+ icon: string
27
+ text: string
28
+ }
29
+ icons: ThemeIcon[]
30
+ }
31
+ debug: boolean | ThemeDebugConfig
32
+ }
33
+
34
+ export const defaultThemeConfig: ThemeConfig = {
35
+ title: 'Docus',
36
+ twitter: '@docus_',
37
+ github: 'nuxtlabs/docus',
38
+ description: 'Write pages in markdown, use Vue components and enjoy the power of Nuxt with a blazing fast developer experience.',
39
+ header: {
40
+ title: false,
41
+ logo: true,
42
+ },
43
+ cover: 'https://user-images.githubusercontent.com/904724/105075054-872fac80-5a89-11eb-8aab-46dd254ad986.png',
44
+ coverAlt: 'A screenshot of a website built with Docus with the Docus logo on top of it.',
45
+ footer: {
46
+ credits: {
47
+ icon: 'IconNuxtLabs',
48
+ text: 'Made by NuxtLabs',
49
+ },
50
+ icons: [
51
+ {
52
+ label: 'NuxtJS',
53
+ href: 'https://nuxtjs.org',
54
+ component: 'IconNuxtLabs',
55
+ },
56
+ {
57
+ label: 'Vue Telescope',
58
+ href: 'https://vuetelescope.com',
59
+ component: 'IconVueTelescope',
60
+ },
61
+ ],
62
+ },
63
+ debug: true,
64
+ }
@@ -1,11 +0,0 @@
1
- html {
2
- @apply text-primary bg-white overflow-y-scroll;
3
-
4
- &.dark {
5
- @apply bg-gray-900;
6
- }
7
- }
8
-
9
- body {
10
- @apply antialiased font-sans text-gray-700 dark:text-gray-200;
11
- }