docus 3.0.0-beta.1 → 3.0.0-beta.10

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 (145) 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 +2 -0
  6. package/{components → theme/components}/app/Footer.vue +5 -3
  7. package/theme/components/app/MobileNav.vue +85 -0
  8. package/theme/components/app/Navbar.vue +37 -0
  9. package/{components → theme/components}/app/NavbarLogo.vue +5 -3
  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 +2 -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 +7 -6
  19. package/{components → theme/components}/content/CopyButton.vue +1 -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 +1 -0
  23. package/{components → theme/components}/content/Sandbox.vue +4 -2
  24. package/{components → theme/components}/content/TabsHeader.vue +2 -2
  25. package/{components → theme/components}/content/Terminal.vue +22 -28
  26. package/{components → theme/components}/content/VideoPlayer.vue +2 -0
  27. package/theme/components/dev/Debug.vue +65 -0
  28. package/{components → theme/components}/docs/DocsAside.vue +3 -1
  29. package/{components → theme/components}/docs/DocsAsideTree.vue +9 -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 +16 -11
  34. package/{components → theme/components}/globals/Icon.vue +2 -2
  35. package/{components → theme/components}/globals/Logo.vue +0 -0
  36. package/{components → theme/components}/globals/NuxtImg.vue +2 -0
  37. package/{components → theme/components}/globals/SocialIcons.vue +3 -1
  38. package/{components → theme/components}/globals/ThemeSelect.vue +3 -3
  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 +2 -2
  97. package/theme/components/prose/ProseImg.vue +30 -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 +43 -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 +1 -0
  113. package/theme/composables/useUserAgent.ts +7 -0
  114. package/{composables/useTheme.ts → theme/composables/utils.ts} +0 -6
  115. package/{layouts → theme/layouts}/default.vue +7 -5
  116. package/{layouts → theme/layouts}/page.vue +9 -1
  117. package/theme/middleware/components.ts +26 -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 +64 -0
  123. package/theme/plugins/menu.ts +67 -0
  124. package/theme/plugins/user-agent.ts +27 -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 +33 -0
  130. package/theme/utils/theme.ts +66 -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 -29
  135. package/components/prose/ProseImg.vue +0 -32
  136. package/composables/useContent.ts +0 -155
  137. package/composables/useMenu.ts +0 -20
  138. package/pages/[...slug].vue +0 -24
  139. package/public/android-chrome-192x192.png +0 -0
  140. package/public/android-chrome-512x512.png +0 -0
  141. package/public/apple-touch-icon.png +0 -0
  142. package/public/favicon-16x16.png +0 -0
  143. package/public/favicon-32x32.png +0 -0
  144. package/public/favicon.ico +0 -0
  145. package/public/site.webmanifest +0 -1
@@ -0,0 +1,66 @@
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
+ url: string
16
+ description: string
17
+ twitter: string
18
+ github: string
19
+ cover: string
20
+ coverAlt: string
21
+ header: {
22
+ title: false | string
23
+ logo: boolean | string
24
+ }
25
+ footer: {
26
+ credits: false | {
27
+ icon: string
28
+ text: string
29
+ }
30
+ icons: ThemeIcon[]
31
+ }
32
+ debug: boolean | ThemeDebugConfig
33
+ }
34
+
35
+ export const defaultThemeConfig: ThemeConfig = {
36
+ title: 'Docus',
37
+ url: 'https://docus.dev',
38
+ twitter: '@docus_',
39
+ github: 'nuxtlabs/docus',
40
+ description: 'Write pages in markdown, use Vue components and enjoy the power of Nuxt with a blazing fast developer experience.',
41
+ header: {
42
+ title: false,
43
+ logo: true,
44
+ },
45
+ cover: 'https://user-images.githubusercontent.com/904724/105075054-872fac80-5a89-11eb-8aab-46dd254ad986.png',
46
+ coverAlt: 'A screenshot of a website built with Docus with the Docus logo on top of it.',
47
+ footer: {
48
+ credits: {
49
+ icon: 'IconNuxtLabs',
50
+ text: 'Made by NuxtLabs',
51
+ },
52
+ icons: [
53
+ {
54
+ label: 'NuxtJS',
55
+ href: 'https://nuxtjs.org',
56
+ component: 'IconNuxtLabs',
57
+ },
58
+ {
59
+ label: 'Vue Telescope',
60
+ href: 'https://vuetelescope.com',
61
+ component: 'IconVueTelescope',
62
+ },
63
+ ],
64
+ },
65
+ debug: true,
66
+ }
@@ -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
- }
@@ -1,282 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- @layer components {
6
- /* Base */
7
- .text-primary {
8
- @apply text-gray-900 dark:text-gray-50;
9
- }
10
-
11
- .text-secondary {
12
- @apply text-gray-500 dark:text-gray-400;
13
- }
14
-
15
- .text-secondary-active {
16
- @apply text-primary-500 dark:text-primary-400;
17
- }
18
-
19
- .text-secondary-hover {
20
- @apply hover:text-primary-500 hover:dark:text-primary-400;
21
- }
22
-
23
- .text-secondary-group-hover {
24
- @apply group-hover:dark:text-primary-400 group-hover:text-primary-500;
25
- }
26
-
27
- .transition-base {
28
- @apply transition-colors transition-opacity duration-100 ease-in-out;
29
- }
30
-
31
- /* Icons */
32
- .icon-base {
33
- @apply transition-base text-secondary text-secondary-hover;
34
- }
35
-
36
- /* ProseA */
37
- .d-prose-a-text {
38
- @apply text-primary-500;
39
- }
40
-
41
- .d-prose-a-border {
42
- @apply border-b border-transparent;
43
- }
44
-
45
- .d-prose-a-border-hover {
46
- @apply border-b border-primary-500;
47
- }
48
-
49
- .d-prose-a-headline-border {
50
- @apply border-b border-dashed border-gray-900 dark:border-gray-100;
51
- }
52
-
53
- /* ProseBlockquote */
54
- .d-prose-blockquote-border {
55
- @apply border-l-2 border-gray-200 dark:border-gray-700;
56
- }
57
-
58
- .d-prose-blockquote-text {
59
- @apply text-secondary;
60
- }
61
-
62
- /** UNCONVERTED **/
63
- .d-body-bg {
64
- @apply bg-white dark:bg-gray-900;
65
- }
66
-
67
- .d-body-text-color {
68
- @apply text-gray-900 dark:text-gray-50;
69
- }
70
-
71
- .d-secondary-bg {
72
- @apply bg-gray-500 dark:bg-gray-400;
73
- }
74
-
75
- .d-secondary-text {
76
- @apply text-gray-500 dark:text-gray-400;
77
- }
78
-
79
- .d-secondary-text-hover {
80
- @apply text-primary-500 dark:text-primary-400;
81
- }
82
-
83
- .d-tertiary-text {
84
- @apply text-gray-400 dark:text-gray-500;
85
- }
86
-
87
- .d-border-tertiary {
88
- @apply border-gray-400 dark:border-gray-500;
89
- }
90
-
91
- .d-primary-text-hover {
92
- @apply text-gray-600 dark:text-gray-400;
93
- }
94
-
95
- .d-secondary-text-active {
96
- @apply text-gray-900 dark:text-gray-300;
97
- }
98
-
99
- .d-prose-code-inline-bg {
100
- background-color: #282c34;
101
- }
102
-
103
- .d-prose-code-bg {
104
- background-color: #282c34;
105
- }
106
-
107
- .d-prose-thead-border {
108
- @apply border-b border-gray-200 dark:border-gray-700;
109
- }
110
-
111
- .d-prose-tr-border {
112
- @apply border-b border-gray-100 dark:border-gray-800;
113
- }
114
-
115
- .d-prose-blockquote-border {
116
- @apply border-l-2 border-gray-200 dark:border-gray-700;
117
- }
118
-
119
- .d-prose-blockquote-text {
120
- @apply d-secondary-text;
121
- }
122
-
123
- .d-prose-a-text {
124
- @apply text-primary-500;
125
- }
126
-
127
- .d-prose-a-border {
128
- @apply border-b border-transparent;
129
- }
130
-
131
- .d-prose-a-border-hover {
132
- @apply border-b border-primary-500;
133
- }
134
-
135
- .d-prose-a-headline-border {
136
- @apply border-b border-dashed border-gray-900 dark:border-gray-100;
137
- }
138
-
139
- .d-text-primary {
140
- @apply text-primary-500 dark:text-primary-400;
141
- }
142
-
143
- .d-border-primary {
144
- @apply border-primary-500 dark:border-primary-400;
145
- }
146
-
147
- .d-bg-primary {
148
- @apply bg-primary-500 dark:bg-primary-400;
149
- }
150
-
151
- .d-page-mobile-toc-bg {
152
- @apply bg-white bg-opacity-80 dark:bg-gray-900 dark:bg-opacity-80;
153
- }
154
-
155
- .d-aside-header-bg {
156
- @apply bg-gray-50 dark:bg-gray-800;
157
- }
158
-
159
- .d-active-aside-navigation-item-bg {
160
- @apply bg-primary-50 dark:bg-primary-900;
161
- }
162
-
163
- .d-active-aside-navigation-item-text {
164
- @apply text-primary-500 dark:text-primary-400 ;
165
- }
166
-
167
- .d-code-group-header-bg {
168
- @apply bg-gray-200 dark:bg-gray-700;
169
- }
170
-
171
- .d-code-group-tab {
172
- @apply bg-gray-300 dark:bg-gray-600;
173
- }
174
-
175
- .d-prose-code-inline-in-heading-border-hover {
176
- @apply border-gray-500 dark:border-gray-200;
177
- }
178
-
179
- .d-prose-hr-border {
180
- @apply border-t border-gray-100 dark:border-gray-800;
181
- }
182
-
183
- .d-prose-ul-li-bullet {
184
- @apply d-secondary-bg;
185
- }
186
-
187
- .d-text-icon {
188
- @apply d-secondary-text hover:d-secondary-text-hover;
189
- }
190
-
191
- .d-icon {
192
- @apply d-text-icon focus:outline-none;
193
- }
194
-
195
- .light-img {
196
- @apply dark:hidden;
197
- }
198
-
199
- .dark-img {
200
- @apply light:hidden;
201
- }
202
-
203
- .d-max-w-container {
204
- @apply max-w-7xl;
205
- }
206
-
207
- .d-px-container {
208
- @apply px-4 sm:px-6;
209
- }
210
-
211
- .d-container {
212
- @apply d-max-w-container mx-auto;
213
- }
214
-
215
- .d-container-content {
216
- @apply d-container d-px-container;
217
- }
218
-
219
- .d-blur-header {
220
- @apply blur-12;
221
- }
222
-
223
- .d-bg-header {
224
- @apply bg-white bg-opacity-80 dark:bg-gray-900 dark:bg-opacity-80;
225
- }
226
-
227
- .d-border {
228
- @apply light:border-gray-200 light:border-opacity-50 dark:border-gray-800;
229
- }
230
-
231
- .d-border-hover {
232
- @apply border-primary-200 dark:border-gray-700;
233
- }
234
-
235
- .d-border-header {
236
- @apply border-b border-gray-200 dark:border-gray-800 border-opacity-50;
237
- }
238
-
239
- .d-header {
240
- @apply sticky w-full top-0 z-50 d-bg-header d-border-header d-blur-header h-header;
241
- }
242
-
243
- .d-header-title {
244
- @apply text-2xl font-bold tracking-tighter text-gray-900 dark:text-gray-100;
245
- }
246
-
247
- .d-header-title-logo {
248
- @apply d-header-title ml-4;
249
- }
250
-
251
- .d-header-logo {
252
- @apply flex items-center flex-none lg:w-60;
253
- }
254
-
255
- .d-logo-color {
256
- @apply text-black dark:text-white;
257
- }
258
-
259
- .d-logo {
260
- @apply w-auto h-6 md:h-8 d-logo-color;
261
- }
262
-
263
- .d-heading-title {
264
- @apply !mb-0 !mt-0 flex-1 !text-4xl font-semibold tracking-tight;
265
- }
266
-
267
- .d-heading-description {
268
- @apply !mt-2 !mb-0 text-lg font-medium d-secondary-text;
269
- }
270
-
271
- .d-heading-hr {
272
- @apply !mt-4 !mb-0 d-border;
273
- }
274
-
275
- .d-aside-title {
276
- @apply py-2 text-base font-semibold text-gray-900 cursor-pointer dark:text-gray-100;
277
- }
278
-
279
- .d-badge {
280
- @apply text-gray-600 dark:text-gray-400 bg-gray-900;
281
- }
282
- }
@@ -1,26 +0,0 @@
1
- <template>
2
- <header class="sticky w-full h-[4rem] top-0 z-50 bg-white bg-opacity-80 dark:bg-gray-900 dark:bg-opacity-80 border-b border-gray-200 dark:border-gray-800 border-opacity-50 sticky w-full top-0 z-50 backdrop-blur supports-backdrop-blur:bg-white/95">
3
- <Container class="flex flex-none h-full">
4
- <!-- <NavigationButton v-if="aside" /> -->
5
-
6
- <div class="justify-center flex items-center flex-1 lg:flex-none">
7
- <NavbarLogo />
8
- </div>
9
-
10
- <div class="items-center hidden lg:flex lg:flex-1">
11
- <!-- <HeaderNavigation /> -->
12
- </div>
13
-
14
- <!-- Desktop: Right section -->
15
- <div class="flex items-center justify-end lg:flex-none">
16
- <!-- <ColorSwitcher /> -->
17
-
18
- <div class="items-center justify-end hidden lg:flex">
19
- <!-- <LangSwitcher /> -->
20
- <ThemeSelect />
21
- <!-- <SocialIcons /> -->
22
- </div>
23
- </div>
24
- </Container>
25
- </header>
26
- </template>
@@ -1,29 +0,0 @@
1
- <script setup lang="ts">
2
- const { page } = useContent()
3
-
4
- const isOpen = ref(false)
5
- </script>
6
-
7
- <template>
8
- <div class="flex flex-col-reverse lg:grid lg:grid-cols-10 gap-8 relative">
9
- <div
10
- class="col-span-10 lg:col-span-8"
11
- >
12
- <slot />
13
- </div>
14
-
15
- <div
16
- class="lg:col-span-2 lg:self-start overflow-x-hidden sticky top-16 -mx-4 sm:-mx-6 px-4 sm:px-6 lg:mx-0 lg:px-0 lg:pt-8 lg:-mt-8 backdrop-blur-md lg:max-h-[calc(100vh-64px)]"
17
- >
18
- <div class="py-4 lg:py-0">
19
- <button class="flex lg:hidden items-center gap-3" @click="isOpen = !isOpen">
20
- <span class="u-text-gray-900 font-semibold text-sm">Table of Contents</span>
21
-
22
- <Icon name="heroicons-outline:chevron-right" class="w-4 h-4 u-text-gray-400 transition-transform duration-100 transform" :class="[isOpen ? 'rotate-90' : 'rotate-0']" />
23
- </button>
24
-
25
- <DocsToc class="mt-4 lg:mt-0" :class="[isOpen ? 'lg:block' : 'hidden lg:block']" />
26
- </div>
27
- </div>
28
- </div>
29
- </template>
@@ -1,32 +0,0 @@
1
- <script>
2
- export default {
3
- props: {
4
- src: {
5
- type: String,
6
- default: '',
7
- },
8
- alt: {
9
- type: String,
10
- default: '',
11
- },
12
- width: {
13
- type: [String, Number],
14
- default: undefined,
15
- },
16
- height: {
17
- type: [String, Number],
18
- default: undefined,
19
- },
20
- },
21
- }
22
- </script>
23
-
24
- <template>
25
- <NuxtImg :src="src" :alt="alt" :width="width" :height="height" />
26
- </template>
27
-
28
- <style lang="postcss" scoped>
29
- :deep(img) {
30
- @apply my-[1em];
31
- }
32
- </style>
@@ -1,155 +0,0 @@
1
- import { withoutTrailingSlash } from 'ufo'
2
- import type { NavItem, ParsedContent } from '@nuxt/content/dist/runtime/types'
3
-
4
- let closeHook
5
-
6
- export const useContent = () => {
7
- const route = useRoute()
8
-
9
- const path = computed(() => withoutTrailingSlash(route.path))
10
-
11
- /**
12
- * Navigation tree from root of app.
13
- */
14
- const navigation = useState<NavItem[]>('navigation', () => null)
15
-
16
- /**
17
- * Current page complete data.
18
- */
19
- const page = useState<ParsedContent>(`content-page-${path.value}`, () => null)
20
-
21
- /**
22
- * Previous and next page data.
23
- * Format: [prev, next]
24
- */
25
- const surround = useState<ParsedContent[]>(`content-surround-${path.value}`, () => null)
26
-
27
- /**
28
- * Table of contents from parsed page.
29
- */
30
- const toc = computed(() => page?.value?.body?.toc?.links || [])
31
-
32
- /**
33
- * Content type from parsed page.
34
- */
35
- const type = computed(() => page.value?.meta?.type)
36
-
37
- /**
38
- * Next page from `surround`.
39
- */
40
- const next = computed(() => surround.value?.[1] || null)
41
-
42
- /**
43
- * Previous page from `surround`.
44
- */
45
- const prev = computed(() => surround.value?.[0] || null)
46
-
47
- /**
48
- * Page list fetching helper.
49
- */
50
- const fetchDir = async(path: string) => await queryContent(path).find()
51
-
52
- /**
53
- * Find first child link from a navigation node.
54
- */
55
- const findBottomLink = (link: NavItem) => {
56
- let slug = link.slug
57
-
58
- if (link.children && link.children.length)
59
- slug = findBottomLink(link.children[0])
60
-
61
- return slug
62
- }
63
-
64
- /**
65
- * Find current navigation node from a path.
66
- */
67
- const navFromPath = (path: string, tree: NavItem[] = navigation.value) => {
68
- for (const file of tree) {
69
- if (file.children) {
70
- const result = navFromPath(path, file.children)
71
- if (result)
72
- return result
73
- }
74
-
75
- if (file.slug === path)
76
- return file
77
- }
78
- }
79
-
80
- /**
81
- * Navigation fetching helper.
82
- */
83
- const fetchNavigation = async(force = false) => {
84
- if (navigation.value !== null && !force)
85
- return
86
-
87
- navigation.value = await fetchContentNavigation()
88
- }
89
-
90
- /**
91
- * Local page fetching helper.
92
- */
93
- const fetchPage = async(force = false) => {
94
- if (page.value !== null && !force)
95
- return
96
-
97
- const splitted = path.value.split('/')
98
- const directory = splitted.slice(0, splitted.length - 1).join('/')
99
-
100
- // Get navigation node from current path
101
- const file = navFromPath(path.value, navigation.value)
102
-
103
- if (file && !file.children) {
104
- // Path queried has a page (and is not a directory)
105
- await Promise.all([
106
- queryContent().where({ id: file.id }).findOne() as Promise<ParsedContent>,
107
- queryContent(directory).findSurround(path.value) as Promise<ParsedContent[]>,
108
- ]).then(([_page, _surround]) => {
109
- page.value = _page
110
- surround.value = _surround
111
- })
112
- }
113
- else if (file) {
114
- navigateTo(findBottomLink(file))
115
- }
116
- }
117
-
118
- // Re-fetch page on change (development only)
119
- if (process.dev) {
120
- onMounted(
121
- () => {
122
- // Cleanup previous hook before registering new one.
123
- if (closeHook)
124
- closeHook()
125
-
126
- const { hook } = useNuxtApp()
127
-
128
- closeHook = hook('app:data:refresh', async() => {
129
- await fetchNavigation(true)
130
- await fetchPage(true)
131
- })
132
- },
133
- )
134
- onBeforeUnmount(() => closeHook && closeHook())
135
- }
136
-
137
- return {
138
- // useState references
139
- navigation,
140
- page,
141
- surround,
142
- // Fetching helpers
143
- fetchDir,
144
- fetchPage,
145
- fetchNavigation,
146
- // Computed values
147
- next,
148
- prev,
149
- type,
150
- toc,
151
- // Methods
152
- navFromPath,
153
- findBottomLink,
154
- }
155
- }
@@ -1,20 +0,0 @@
1
- export const useMenu = () => {
2
- // Menu visible reference
3
- const visible = useState('menu-visible', () => false)
4
-
5
- // Open the menu
6
- const open = () => (visible.value = true)
7
-
8
- // Close the menu
9
- const close = () => (visible.value = false)
10
-
11
- // Toggle the menu (useful for one-off buttons)
12
- const toggle = () => (visible.value = !visible.value)
13
-
14
- return {
15
- open,
16
- close,
17
- toggle,
18
- visible,
19
- }
20
- }
@@ -1,24 +0,0 @@
1
- <script setup lang="ts">
2
- const router = useRouter()
3
-
4
- const { page, fetchPage } = useContent()
5
-
6
- await fetchPage()
7
-
8
- if (page.value && page.value.layout)
9
- router.currentRoute.value.meta.layout = page.value.layout
10
- else
11
- router.currentRoute.value.meta.layout = 'default'
12
- </script>
13
-
14
- <template>
15
- <Content v-if="page" class="content" :document="page" />
16
- </template>
17
-
18
- <style scoped>
19
- .content {
20
- & > :first-child {
21
- margin-top: 0 !important;
22
- }
23
- }
24
- </style>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1 +0,0 @@
1
- {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}