From 6ff1ff31511a979dc0c08a349121ae54aa542f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:28:40 +0200 Subject: [PATCH 01/20] feat(theme): move theme config into _theme.yml file --- content/_theme.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 content/_theme.yml diff --git a/content/_theme.yml b/content/_theme.yml new file mode 100644 index 000000000..01f92e389 --- /dev/null +++ b/content/_theme.yml @@ -0,0 +1,17 @@ +title: Docus +twitter: "@docus_" +github: nuxtlabs/docus +header: + title: false + logo: true +footer: + credits: + icon: IconNuxtLabs + text: Made by Nuxt Labs + icons: + - label: NuxtJS + href: https://nuxtjs.org + component: IconNuxtLabs + - label: Vue Telescope + href: https://vuetelescope.com + component: IconVueTelescope From a606027c021d474cef689bfd27cb30905ec1e30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:29:10 +0200 Subject: [PATCH 02/20] feat(config): update nuxt.config --- nuxt.config.ts | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/nuxt.config.ts b/nuxt.config.ts index c72ce07d2..9378bbc69 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -6,41 +6,24 @@ import { resolve } from 'pathe' const themeDir = fileURLToPath(new URL('./', import.meta.url)) const resolveThemeDir = (path: string) => resolve(themeDir, path) +const plugins = [] + +// Only register the plugin in development as it's not needed in production +if (process.env.NODE_ENV === 'development') { + plugins.push({ + src: resolveThemeDir('utils/plugin.ts'), + }) +} + export default defineNuxtConfig({ runtimeConfig: { public: { plausible: { domain: process.env.PLAUSIBLE_DOMAIN, }, - theme: { - title: 'Docus', - twitter: '@docus_', - github: 'nuxtlabs/docus', - header: { - title: false, - logo: true, - }, - footer: { - credits: { - icon: 'IconNuxtLabs', - text: 'Made by Nuxt Labs', - }, - icons: [ - { - label: 'NuxtJS', - href: 'https://nuxtjs.org', - component: 'IconNuxt', - }, - { - label: 'Vue Telescope', - href: 'https://vuetelescope.com', - component: 'IconVueTelescope', - }, - ], - }, - }, }, }, + plugins, head: { title: 'Docus', link: [ From 9b96c098ea22eab7a0c4829f1ce2bae284ed8538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:29:27 +0200 Subject: [PATCH 03/20] feat(usedocus): drop useContent in favor of useDocus --- composables/useContent.ts | 156 -------------------------------------- composables/useDocus.ts | 42 ++++++++++ 2 files changed, 42 insertions(+), 156 deletions(-) delete mode 100644 composables/useContent.ts create mode 100644 composables/useDocus.ts diff --git a/composables/useContent.ts b/composables/useContent.ts deleted file mode 100644 index eecc2724d..000000000 --- a/composables/useContent.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { withoutTrailingSlash } from 'ufo' -import type { NavItem, ParsedContent } from '@nuxt/content/dist/runtime/types' -import { computed, fetchContentNavigation, onBeforeUnmount, onMounted, queryContent, useNuxtApp, useRoute, useState } from '#imports' - -let closeHook - -export const useContent = () => { - const route = useRoute() - - const path = computed(() => withoutTrailingSlash(route.path)) - - /** - * Navigation tree from root of app. - */ - const navigation = useState('navigation', () => null) - - /** - * Current page complete data. - */ - const page = useState(`content-page-${path.value}`, () => null) - - /** - * Previous and next page data. - * Format: [prev, next] - */ - const surround = useState(`content-surround-${path.value}`, () => null) - - /** - * Table of contents from parsed page. - */ - const toc = computed(() => page?.value?.body?.toc?.links || []) - - /** - * Content type from parsed page. - */ - const type = computed(() => page.value?.meta?.type) - - /** - * Next page from `surround`. - */ - const next = computed(() => surround.value?.[1] || null) - - /** - * Previous page from `surround`. - */ - const prev = computed(() => surround.value?.[0] || null) - - /** - * Page list fetching helper. - */ - const fetchDir = async(path: string) => await queryContent(path).find() - - /** - * Find first child link from a navigation node. - */ - const findBottomLink = (link: NavItem) => { - let slug = link.slug - - if (link.children && link.children.length) - slug = findBottomLink(link.children[0]) - - return slug - } - - /** - * Find current navigation node from a path. - */ - const navFromPath = (path: string, tree: NavItem[] = navigation.value) => { - for (const file of tree) { - if (file.children) { - const result = navFromPath(path, file.children) - if (result) - return result - } - - if (file.slug === path) - return file - } - } - - /** - * Navigation fetching helper. - */ - const fetchNavigation = async(force = false) => { - if (navigation.value !== null && !force) - return - - navigation.value = await fetchContentNavigation() - } - - /** - * Local page fetching helper. - */ - const fetchPage = async(force = false) => { - if (page.value !== null && !force) - return - - const splitted = path.value.split('/') - const directory = splitted.slice(0, splitted.length - 1).join('/') - - // Get navigation node from current path - const file = navFromPath(path.value, navigation.value) - - if (file && !file.children) { - // Path queried has a page (and is not a directory) - await Promise.all([ - queryContent().where({ id: file.id }).findOne() as Promise, - queryContent(directory).findSurround(path.value) as Promise, - ]).then(([_page, _surround]) => { - page.value = _page - surround.value = _surround - }) - } - else if (file) { - navigateTo(findBottomLink(file)) - } - } - - // Re-fetch page on change (development only) - if (process.dev) { - onMounted( - () => { - // Cleanup previous hook before registering new one. - if (closeHook) - closeHook() - - const { hook } = useNuxtApp() - - closeHook = hook('app:data:refresh', async() => { - await fetchNavigation(true) - await fetchPage(true) - }) - }, - ) - onBeforeUnmount(() => closeHook && closeHook()) - } - - return { - // useState references - navigation, - page, - surround, - // Fetching helpers - fetchDir, - fetchPage, - fetchNavigation, - // Computed values - next, - prev, - type, - toc, - // Methods - navFromPath, - findBottomLink, - } -} diff --git a/composables/useDocus.ts b/composables/useDocus.ts new file mode 100644 index 000000000..9229f2dbd --- /dev/null +++ b/composables/useDocus.ts @@ -0,0 +1,42 @@ +import { useDocusState } from '../utils/state' + +export const useDocus = () => { + const { theme, navigation, page, surround } = useDocusState() + + /** + * Table of contents from parsed page. + */ + const toc = computed(() => page?.value?.body?.toc || []) + + /** + * Content type from parsed page. + */ + const type = computed(() => page.value?.meta?.type) + + /** + * Layout type from parsed page. + */ + const layout = computed(() => page.value?.meta?.layout) + + /** + * Next page from `surround`. + */ + const next = computed(() => surround.value?.[1] || null) + + /** + * Previous page from `surround`. + */ + const prev = computed(() => surround.value?.[0] || null) + + return { + theme, + navigation, + surround, + page, + toc, + type, + layout, + next, + prev, + } +} From 52131b3fe6e462f2a1cd11e4c5333c3d75d397b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:37:00 +0200 Subject: [PATCH 04/20] feat(queries): implement queries (page/nav/theme) --- utils/queries.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 utils/queries.ts diff --git a/utils/queries.ts b/utils/queries.ts new file mode 100644 index 000000000..5eeca58af --- /dev/null +++ b/utils/queries.ts @@ -0,0 +1,65 @@ +import { withoutTrailingSlash } from 'ufo' +import type { ParsedContent } from '@nuxt/content/dist/runtime/types' +import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router' +import { defaultThemeConfig } from './theme' +import { fileFromPath, findBottomLink } from './navigation' +import { useDocusState } from './state' +import { fetchContentNavigation, queryContent } from '#imports' + +export const pageQuery = async(route: RouteLocationNormalized | RouteLocationNormalizedLoaded) => { + const path = withoutTrailingSlash(route.path) + const splitted = path.split('/') + const directory = splitted.slice(0, splitted.length - 1).join('/') + + const { page, surround, navigation } = useDocusState() + + // Get navigation node from current path + const file = fileFromPath(path, navigation.value) + + // Path queried has a page (and is not a directory) + if (file && !file.children) { + await Promise.all([ + queryContent().where({ id: file.id }).findOne() as Promise, + queryContent(directory).findSurround(path) as Promise, + ]).then( + ([_page, _surround]) => { + page.value = _page + surround.value = _surround + + // Handle layout update from page + if (_page?.layout) + route.meta.layout = _page?.layout + else + route.meta.layout = 'default' + }, + ) + } + // Handle redirection in case the current path is not a page + else if (file) { + return navigateTo(findBottomLink(file)) + } +} + +export const navigationQuery = async() => { + const { navigation } = useDocusState() + + navigation.value = await fetchContentNavigation() +} + +export const themeQuery = async() => { + const { theme } = useDocusState() + + // Fetch _theme.yml at `content/` root. + const query = await queryContent().where({ + id: 'content:_theme.yml', + }).findOne() + + if (!query) { + // Assign default theme config if none found. + theme.value = defaultThemeConfig + + return + } + + theme.value = query.body +} From 4a6ac226d864e575fd73b60af7bca9768a4451c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:37:14 +0200 Subject: [PATCH 05/20] chore(deps): upgrade deps (latest nuxt3) --- package.json | 2 +- yarn.lock | 170 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 124 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index ce32b3fcb..dd4df1584 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "@antfu/eslint-config": "^0.20.6", "@nuxtjs/eslint-config-typescript": "^9.0.0", "eslint": "^8.13.0", - "nuxt": "^3.0.0-rc.1", + "nuxt": "npm:nuxt3@latest", "parse-entities": "^4.0.0", "typescript": "^4.6.3" }, diff --git a/yarn.lock b/yarn.lock index 5ff793787..66a069744 100644 --- a/yarn.lock +++ b/yarn.lock @@ -694,6 +694,32 @@ __metadata: languageName: node linkType: hard +"@nuxt/kit@npm:@nuxt/kit-edge@3.0.0-rc.1-27515112.2d202b5": + version: 3.0.0-rc.1-27515112.2d202b5 + resolution: "@nuxt/kit-edge@npm:3.0.0-rc.1-27515112.2d202b5" + dependencies: + "@nuxt/schema": "npm:@nuxt/schema-edge@3.0.0-rc.1-27515112.2d202b5" + c12: ^0.2.7 + consola: ^2.15.3 + defu: ^6.0.0 + globby: ^13.1.1 + hash-sum: ^2.0.0 + ignore: ^5.2.0 + jiti: ^1.13.0 + knitwork: ^0.1.1 + lodash.template: ^4.5.0 + mlly: ^0.5.2 + pathe: ^0.2.0 + pkg-types: ^0.3.2 + scule: ^0.2.1 + semver: ^7.3.7 + unctx: ^1.1.4 + unimport: ^0.1.6 + untyped: ^0.4.4 + checksum: e9c18f25d80cd20f87a9d905302fd64f1d190f643f7447ee1b1bcc155e130b0a917dfc8522ed01dfd0ca0d67d7f223a2253222d0321b5835199a36a25983b03e + languageName: node + linkType: hard + "@nuxt/kit@npm:@nuxt/kit-edge@latest": version: 3.0.0-rc.1-27510277.648a70e resolution: "@nuxt/kit-edge@npm:3.0.0-rc.1-27510277.648a70e" @@ -798,6 +824,24 @@ __metadata: languageName: node linkType: hard +"@nuxt/schema@npm:@nuxt/schema-edge@3.0.0-rc.1-27515112.2d202b5": + version: 3.0.0-rc.1-27515112.2d202b5 + resolution: "@nuxt/schema-edge@npm:3.0.0-rc.1-27515112.2d202b5" + dependencies: + c12: ^0.2.7 + create-require: ^1.1.1 + defu: ^6.0.0 + jiti: ^1.13.0 + pathe: ^0.2.0 + postcss-import-resolver: ^2.0.0 + scule: ^0.2.1 + std-env: ^3.1.1 + ufo: ^0.8.3 + unimport: ^0.1.6 + checksum: ac2966f9da23441dde9a5a5ac06b1eb336c7895eb31d2b8447ee8d5be3e717f55816f1368dbc69c005c7481d973f5c8cf659f2966659fe12bed8af804c99318a + languageName: node + linkType: hard + "@nuxt/schema@npm:^3.0.0-rc.1": version: 3.0.0-rc.1 resolution: "@nuxt/schema@npm:3.0.0-rc.1" @@ -853,18 +897,18 @@ __metadata: languageName: node linkType: hard -"@nuxt/vite-builder@npm:^3.0.0-rc.1": - version: 3.0.0-rc.1 - resolution: "@nuxt/vite-builder@npm:3.0.0-rc.1" +"@nuxt/vite-builder@npm:@nuxt/vite-builder-edge@3.0.0-rc.1-27515112.2d202b5": + version: 3.0.0-rc.1-27515112.2d202b5 + resolution: "@nuxt/vite-builder-edge@npm:3.0.0-rc.1-27515112.2d202b5" dependencies: - "@nuxt/kit": ^3.0.0-rc.1 + "@nuxt/kit": "npm:@nuxt/kit-edge@3.0.0-rc.1-27515112.2d202b5" "@vitejs/plugin-vue": ^2.3.1 "@vitejs/plugin-vue-jsx": ^1.3.10 - autoprefixer: ^10.4.4 + autoprefixer: ^10.4.5 chokidar: ^3.5.3 cssnano: ^5.1.7 defu: ^6.0.0 - esbuild: ^0.14.36 + esbuild: ^0.14.38 escape-string-regexp: ^5.0.0 externality: ^0.2.1 fs-extra: ^10.1.0 @@ -883,11 +927,11 @@ __metadata: ufo: ^0.8.3 unplugin: ^0.6.2 vite: ^2.9.5 - vite-node: ^0.9.3 + vite-node: ^0.10.0 vite-plugin-checker: ^0.4.6 peerDependencies: vue: 3.2.33 - checksum: 457cd1262eb39af884f2530ed667cfb9aec6ae60e96f9643fbf339b9c81a39ab05b503436585e57a9ce4d8f335abc99b31a9a04f05bf7ede4724c4c00793b95b + checksum: 9391a08de98b7defc83941ef263f148aa5174e05835155822c32367bcd0a219be8a694942b9101e1178665a59a566fe08fbb672768c94db5293684c105583c9a languageName: node linkType: hard @@ -976,9 +1020,9 @@ __metadata: languageName: node linkType: hard -"@rollup/plugin-commonjs@npm:^21.1.0": - version: 21.1.0 - resolution: "@rollup/plugin-commonjs@npm:21.1.0" +"@rollup/plugin-commonjs@npm:^22.0.0": + version: 22.0.0 + resolution: "@rollup/plugin-commonjs@npm:22.0.0" dependencies: "@rollup/pluginutils": ^3.1.0 commondir: ^1.0.1 @@ -988,8 +1032,8 @@ __metadata: magic-string: ^0.25.7 resolve: ^1.17.0 peerDependencies: - rollup: ^2.38.3 - checksum: e8280f4b6192729f2bdf878c48c451dc441075f2a12f22c688393f48a6b95e8ff83caaacc3df4eb1d81516e08a0e3a669213632879910d85dd630b37bb284df7 + rollup: ^2.68.0 + checksum: fdcce2bf58875fde0e06f001544c0d9a0509a12929393862f72dcef8fcbf4d5d0ba0d5db6cf10ba4351335caf67a3dbdb95000678c468585e3972994f92e2ce9 languageName: node linkType: hard @@ -2007,7 +2051,7 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:^10.2.5, autoprefixer@npm:^10.4.2, autoprefixer@npm:^10.4.4": +"autoprefixer@npm:^10.2.5, autoprefixer@npm:^10.4.2": version: 10.4.4 resolution: "autoprefixer@npm:10.4.4" dependencies: @@ -2025,6 +2069,24 @@ __metadata: languageName: node linkType: hard +"autoprefixer@npm:^10.4.5": + version: 10.4.5 + resolution: "autoprefixer@npm:10.4.5" + dependencies: + browserslist: ^4.20.2 + caniuse-lite: ^1.0.30001332 + fraction.js: ^4.2.0 + normalize-range: ^0.1.2 + picocolors: ^1.0.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.1.0 + bin: + autoprefixer: bin/autoprefixer + checksum: 6c638d8f515a9c37776f9d6b1263e497768d9e8d8ad3b45d901513ba0f26c74df73f4afb84efd3253ab3d1c57803b4e2d97ad9b8919ef1955e373fcf24661213 + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.5": version: 1.0.5 resolution: "available-typed-arrays@npm:1.0.5" @@ -2290,7 +2352,7 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001317": +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001317, caniuse-lite@npm:^1.0.30001332": version: 1.0.30001332 resolution: "caniuse-lite@npm:1.0.30001332" checksum: e54182ea42ab3d2ff1440f9a6480292f7ab23c00c188df7ad65586312e4da567e8bedd5cb5fb8f0ff4193dc027a54e17e0b3c0b6db5d5a3fb61c7726ff9c45b3 @@ -3234,7 +3296,7 @@ __metadata: defu: ^6.0.0 eslint: ^8.13.0 lodash-es: ^4.17.21 - nuxt: ^3.0.0-rc.1 + nuxt: "npm:nuxt3@latest" parse-entities: ^4.0.0 tailwindcss: ^3.0.24 typescript: ^4.6.3 @@ -3620,7 +3682,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.14.27, esbuild@npm:^0.14.36": +"esbuild@npm:^0.14.27, esbuild@npm:^0.14.38": version: 0.14.38 resolution: "esbuild@npm:0.14.38" dependencies: @@ -6123,6 +6185,20 @@ __metadata: languageName: node linkType: hard +"listhen@npm:^0.2.11": + version: 0.2.11 + resolution: "listhen@npm:0.2.11" + dependencies: + clipboardy: ^3.0.0 + colorette: ^2.0.16 + defu: ^6.0.0 + get-port-please: ^2.5.0 + http-shutdown: ^1.2.2 + selfsigned: ^2.0.1 + checksum: c4b7e6f9574643d685577c519f31bf4f24cd3daccb7d9bbace23948a356b068fcd5758d4da154799aca18a032a27aeca5e98b3288369060eb2b939ddc510927d + languageName: node + linkType: hard + "loader-utils@npm:^2.0.0": version: 2.0.2 resolution: "loader-utils@npm:2.0.2" @@ -7290,15 +7366,15 @@ __metadata: languageName: node linkType: hard -"nitropack@npm:^0.3.5": - version: 0.3.5 - resolution: "nitropack@npm:0.3.5" +"nitropack@npm:^0.3.7": + version: 0.3.7 + resolution: "nitropack@npm:0.3.7" dependencies: "@cloudflare/kv-asset-handler": ^0.2.0 "@netlify/functions": ^1.0.0 "@nuxt/devalue": ^2.0.0 "@rollup/plugin-alias": ^3.1.9 - "@rollup/plugin-commonjs": ^21.1.0 + "@rollup/plugin-commonjs": ^22.0.0 "@rollup/plugin-inject": ^4.0.4 "@rollup/plugin-json": ^4.1.0 "@rollup/plugin-node-resolve": ^13.2.1 @@ -7311,7 +7387,7 @@ __metadata: archiver: ^5.3.1 base64-js: ^1.5.1 buffer: ^6.0.3 - c12: ^0.2.5 + c12: ^0.2.7 chalk: ^5.0.1 chokidar: ^3.5.3 connect: ^3.7.0 @@ -7320,7 +7396,7 @@ __metadata: defu: ^6.0.0 destr: ^1.1.1 dot-prop: ^7.2.0 - esbuild: ^0.14.36 + esbuild: ^0.14.38 etag: ^1.8.1 events: ^3.3.0 fs-extra: ^10.1.0 @@ -7334,7 +7410,7 @@ __metadata: is-primitive: ^3.0.1 jiti: ^1.13.0 klona: ^2.0.5 - listhen: ^0.2.10 + listhen: ^0.2.11 mime: ^3.0.0 mlly: ^0.5.2 mri: ^1.2.0 @@ -7365,7 +7441,7 @@ __metadata: bin: nitro: dist/cli.mjs nitropack: dist/cli.mjs - checksum: e904eb5bdd4bc78607d31abc8ab73285f35626f59eb9a385b2771135e71774d42797183a65f4d54bd304472bcf3746f67073cbf79e506f8e72cd10b8fed2d12e + checksum: 36778fb6b9ec3dc26b29a9cde3dd00c26c95c19b524e33bacef5cf2bbb769350eb9063ec80304916e5c15de3a5c004480f6f07083c9ea3217fd064321d28600b languageName: node linkType: hard @@ -7619,17 +7695,17 @@ __metadata: languageName: node linkType: hard -"nuxi@npm:^3.0.0-rc.1": - version: 3.0.0-rc.1 - resolution: "nuxi@npm:3.0.0-rc.1" +"nuxi@npm:nuxi-edge@3.0.0-rc.1-27515112.2d202b5": + version: 3.0.0-rc.1-27515112.2d202b5 + resolution: "nuxi-edge@npm:3.0.0-rc.1-27515112.2d202b5" dependencies: fsevents: ~2.3.2 dependenciesMeta: fsevents: optional: true bin: - nuxi: bin/nuxi.mjs - checksum: f2a3d77475cb3e13b014aa247216f5458a6c8848d7d2a03de8da04aea8eb06f489944969d25253a601e9b4c28e2352747ef0a8b7785710e183d82baa02f43892 + nuxi-edge: ./bin/nuxi.mjs + checksum: 404b1acc7eac8f0596ade158ee9a2e0237f716b8645aee9fa44d0ebe2cff831150f7e5856d22c53d4406c11a842c8bc648b5e0e00722dc7d4597b370bac927f8 languageName: node linkType: hard @@ -7644,15 +7720,15 @@ __metadata: languageName: node linkType: hard -"nuxt@npm:^3.0.0-rc.1": - version: 3.0.0-rc.1 - resolution: "nuxt@npm:3.0.0-rc.1" +"nuxt@npm:nuxt3@latest": + version: 3.0.0-rc.1-27515112.2d202b5 + resolution: "nuxt3@npm:3.0.0-rc.1-27515112.2d202b5" dependencies: - "@nuxt/kit": ^3.0.0-rc.1 - "@nuxt/schema": ^3.0.0-rc.1 + "@nuxt/kit": "npm:@nuxt/kit-edge@3.0.0-rc.1-27515112.2d202b5" + "@nuxt/schema": "npm:@nuxt/schema-edge@3.0.0-rc.1-27515112.2d202b5" "@nuxt/telemetry": ^2.1.2 "@nuxt/ui-templates": ^0.1.0 - "@nuxt/vite-builder": ^3.0.0-rc.1 + "@nuxt/vite-builder": "npm:@nuxt/vite-builder-edge@3.0.0-rc.1-27515112.2d202b5" "@vue/reactivity": ^3.2.33 "@vue/shared": ^3.2.33 "@vueuse/head": ^0.7.6 @@ -7669,8 +7745,8 @@ __metadata: knitwork: ^0.1.1 magic-string: ^0.26.1 mlly: ^0.5.2 - nitropack: ^0.3.5 - nuxi: ^3.0.0-rc.1 + nitropack: ^0.3.7 + nuxi: "npm:nuxi-edge@3.0.0-rc.1-27515112.2d202b5" ohash: ^0.1.0 ohmyfetch: ^0.4.15 pathe: ^0.2.0 @@ -7683,12 +7759,12 @@ __metadata: unplugin: ^0.6.2 untyped: ^0.4.4 vue: ^3.2.33 - vue-bundle-renderer: ^0.3.6 + vue-bundle-renderer: ^0.3.7 vue-router: ^4.0.14 bin: - nuxi: bin/nuxt.mjs - nuxt: bin/nuxt.mjs - checksum: 49b00c52f40b2f6077f49afd2620ce854b0febdb3f93c53bf73a30908d2eeb35a2674dd1b9902e9c2ab16b93284b8944d980ca31f6fe1bac93e8dad3c0e68793 + nuxi: ./bin/nuxt.mjs + nuxt: ./bin/nuxt.mjs + checksum: e94b46d535fc3a8000497e4a96c76ad34cbd68775b85b8a3f44e718f5a7c6ab5036cb9be2e1e4bc72285693aaed6503910562108948c1d19dafb879652e7d1c5 languageName: node linkType: hard @@ -10779,9 +10855,9 @@ __metadata: languageName: node linkType: hard -"vite-node@npm:^0.9.3": - version: 0.9.4 - resolution: "vite-node@npm:0.9.4" +"vite-node@npm:^0.10.0": + version: 0.10.0 + resolution: "vite-node@npm:0.10.0" dependencies: kolorist: ^1.5.1 minimist: ^1.2.6 @@ -10790,7 +10866,7 @@ __metadata: vite: ^2.9.5 bin: vite-node: vite-node.mjs - checksum: 6eba8029a0ecf52b0c66d0de96fdab1e2979b31db614075f8c39c3240c68e87fc018f3d6b30e5e259a0f0a894d951852319c330a4944f3f98cfc8af508a65163 + checksum: 2508ed0fdd170c3c9ff3d748643dcbed2a0b6dd0def45de9800ab07a254d435d0708300e8d35ecceaafbd7e650255a880c1baebd213082b28dc9cb85e5af9eae languageName: node linkType: hard @@ -10910,7 +10986,7 @@ __metadata: languageName: node linkType: hard -"vue-bundle-renderer@npm:^0.3.6": +"vue-bundle-renderer@npm:^0.3.7": version: 0.3.7 resolution: "vue-bundle-renderer@npm:0.3.7" dependencies: From 9560ad8d1f949a823e4aeb2abdd6a74f7d93d9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:37:40 +0200 Subject: [PATCH 06/20] feat(usetheme): drop useTheme composable --- composables/{useTheme.ts => utils.ts} | 8 -------- 1 file changed, 8 deletions(-) rename composables/{useTheme.ts => utils.ts} (51%) diff --git a/composables/useTheme.ts b/composables/utils.ts similarity index 51% rename from composables/useTheme.ts rename to composables/utils.ts index 276c8fbdc..3a938f59f 100644 --- a/composables/useTheme.ts +++ b/composables/utils.ts @@ -1,11 +1,3 @@ -import { useRuntimeConfig } from '#imports' - -export const useTheme = () => { - const { theme } = useRuntimeConfig() - - return theme -} - export const classNames = (...args: any[]) => { const classes = args.filter(Boolean).join(' ') return classes.length ? classes : undefined From f33bb733442c2bbaaa17f7f0d8a8a70ad0365cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:38:02 +0200 Subject: [PATCH 07/20] feat(theme): add default theme config and typings --- utils/theme.ts | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 utils/theme.ts diff --git a/utils/theme.ts b/utils/theme.ts new file mode 100644 index 000000000..1215f77d3 --- /dev/null +++ b/utils/theme.ts @@ -0,0 +1,50 @@ +interface Icon { + label: string + href: string + component: string +} + +export interface ThemeConfig { + title: string + twitter: string + github: string + header: { + title: false | string + logo: boolean | string + } + footer: { + credits: false | { + icon: string + text: string + } + icons: Icon[] + } +} + +export const defaultThemeConfig: ThemeConfig = { + title: 'Docus', + twitter: '@docus_', + github: 'nuxtlabs/docus', + header: { + title: false, + logo: true, + }, + footer: { + credits: { + icon: 'IconNuxtLabs', + text: 'Made by Nuxt Labs', + }, + icons: [ + { + label: 'NuxtJS', + href: 'https://nuxtjs.org', + component: 'IconNuxtLabs', + }, + { + label: 'Vue Telescope', + href: 'https://vuetelescope.com', + component: 'IconVueTelescope', + }, + ], + }, +} From 806a13304dd3bc000eeed78d69d3816264d46bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:38:19 +0200 Subject: [PATCH 08/20] feat(usedocusstate): add internal composable for docus state --- utils/state.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 utils/state.ts diff --git a/utils/state.ts b/utils/state.ts new file mode 100644 index 000000000..f401786c1 --- /dev/null +++ b/utils/state.ts @@ -0,0 +1,32 @@ +import type { NavItem, ParsedContent } from '@nuxt/content/dist/runtime/types' +import type { ThemeConfig } from './theme' + +export const useDocusState = () => { + /** + * Navigation tree from root of app. + */ + const navigation = useState('docus-navigation', () => null) + + /** + * Current page complete data. + */ + const page = useState('docus-page', () => null) + + /** + * Previous and next page data. + * Format: [prev, next] + */ + const surround = useState('docus-page-surround', () => null) + + /** + * Theme configuration. + */ + const theme = useState('docus-theme', () => null) + + return { + navigation, + page, + surround, + theme, + } +} From 59c92576f3d786ad6be4265443cc66f8fb5653a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:38:32 +0200 Subject: [PATCH 09/20] feat(navigation): add navigation utils --- utils/navigation.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 utils/navigation.ts diff --git a/utils/navigation.ts b/utils/navigation.ts new file mode 100644 index 000000000..5a12a534d --- /dev/null +++ b/utils/navigation.ts @@ -0,0 +1,49 @@ +import type { NavItem } from '@nuxt/content/dist/runtime/types' + +/** + * Find first child link from a navigation node. + */ +export const findBottomLink = (link: NavItem) => { + for (const child of link.children) { + if (!child.children) + return child.slug + } + + for (const child of link.children) { + const result = findBottomLink(child) + if (result) + return result + } +} + +/** + * Find current navigation directory from a path. + */ +export const navFromPath = (path: string, tree: NavItem[]) => { + for (const file of tree) { + if (file.slug === path && !file.id) + return file + + if (file.children) { + const result = navFromPath(path, file.children) + if (result) + return result + } + } +} + +/** + * Find a navigation node from a path. + */ +export const fileFromPath = (path: string, tree: NavItem[]) => { + for (const file of tree) { + if (file.children) { + const result = fileFromPath(path, file.children) + if (result) + return result + } + + if (file.slug === path) + return file + } +} From 330da3432066a6a87c274b27dfc4507566d0260b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:38:42 +0200 Subject: [PATCH 10/20] feat(components): add components utils --- utils/components.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 utils/components.ts diff --git a/utils/components.ts b/utils/components.ts new file mode 100644 index 000000000..819ef2b14 --- /dev/null +++ b/utils/components.ts @@ -0,0 +1,20 @@ +import { isHTMLTag } from '@vue/shared' + +export const flattenComponents = (body, flattened = []) => { + for (const node of body) { + if (node?.tag) { + let tag = node.tag + + if (isHTMLTag(node.tag)) + tag = `prose-${node.tag}` + + if (!flattened.includes(tag)) + flattened.push(tag) + } + + if (node.children) + flattenComponents(node.children, flattened) + } + + return flattened +} From 9cf2304fcec877bc4a4c628ba81d0caf3567d80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:38:59 +0200 Subject: [PATCH 11/20] feat(middleware): implement middlewares --- middleware/navigation.global.ts | 12 ++++++++++++ middleware/page.ts | 22 ++++++++++++++++++++++ middleware/theme.global.ts | 12 ++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 middleware/navigation.global.ts create mode 100644 middleware/page.ts create mode 100644 middleware/theme.global.ts diff --git a/middleware/navigation.global.ts b/middleware/navigation.global.ts new file mode 100644 index 000000000..4936d1e2b --- /dev/null +++ b/middleware/navigation.global.ts @@ -0,0 +1,12 @@ +import { useDocusState } from '../utils/state' +import { navigationQuery } from '../utils/queries' +import { defineNuxtRouteMiddleware } from '#imports' + +export default defineNuxtRouteMiddleware( + async() => { + const { navigation } = useDocusState() + + if (!navigation.value) + await navigationQuery() + }, +) diff --git a/middleware/page.ts b/middleware/page.ts new file mode 100644 index 000000000..e312dd1f0 --- /dev/null +++ b/middleware/page.ts @@ -0,0 +1,22 @@ +import { pageQuery } from '../utils/queries' +// import { flattenComponents } from '../utils/components' +// import { useDocusState } from '../utils/state' +import { defineNuxtRouteMiddleware } from '#imports' + +export default defineNuxtRouteMiddleware( + async(to) => { + await pageQuery(to) + + /* + Wished this worked + + const { page } = useDocusState() + + // Components used in page (prose + Vue components) + const components = flattenComponents(page.value.body.children) + + // Inject components into page chunk + for (const component of components) resolveComponent(component) + */ + }, +) diff --git a/middleware/theme.global.ts b/middleware/theme.global.ts new file mode 100644 index 000000000..b6c1bf03e --- /dev/null +++ b/middleware/theme.global.ts @@ -0,0 +1,12 @@ +import { useDocusState } from '../utils/state' +import { themeQuery } from '../utils/queries' +import { defineNuxtRouteMiddleware } from '#imports' + +export default defineNuxtRouteMiddleware( + async() => { + const { theme } = useDocusState() + + if (!theme.value) + await themeQuery() + }, +) From a0e20b8152dcf7ce580f7f48f9332d112e66bcce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:39:13 +0200 Subject: [PATCH 12/20] feat(hmr): preserve hmr via a plugin --- utils/plugin.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 utils/plugin.ts diff --git a/utils/plugin.ts b/utils/plugin.ts new file mode 100644 index 000000000..e16c89c25 --- /dev/null +++ b/utils/plugin.ts @@ -0,0 +1,21 @@ +import { navigationQuery, pageQuery, themeQuery } from './queries' +import { useRoute } from '#imports' + +/** + * Plugin enabled only in development + * Ensure hot reload works with content sources + */ +export default defineNuxtPlugin( + (nuxt) => { + nuxt.hook( + 'app:data:refresh', + async() => { + const route = useRoute() + + await navigationQuery() + await themeQuery() + await pageQuery(route) + }, + ) + }, +) From 6f5c45f58ab1a92f72197af1f3cfae063d1f5058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:39:44 +0200 Subject: [PATCH 13/20] feat(layout): update layouts and use app.vue (maybe fallback to full layouts) --- app.vue | 9 +++++++++ layouts/default.vue | 38 ++++++++++++-------------------------- layouts/page.vue | 10 ++-------- 3 files changed, 23 insertions(+), 34 deletions(-) create mode 100644 app.vue diff --git a/app.vue b/app.vue new file mode 100644 index 000000000..91f8ad627 --- /dev/null +++ b/app.vue @@ -0,0 +1,9 @@ + diff --git a/layouts/default.vue b/layouts/default.vue index 44ab0db8c..e8ec27efa 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -1,29 +1,15 @@ - - diff --git a/layouts/page.vue b/layouts/page.vue index cdfb4a131..6c2fc5ace 100644 --- a/layouts/page.vue +++ b/layouts/page.vue @@ -1,11 +1,5 @@ From da9d56c2cf43abd484d065ccbf349cc5c2838147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Tue, 26 Apr 2022 22:40:01 +0200 Subject: [PATCH 14/20] feat(page): update page implementation --- pages/[...slug].vue | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/pages/[...slug].vue b/pages/[...slug].vue index da3befc87..d4c974751 100644 --- a/pages/[...slug].vue +++ b/pages/[...slug].vue @@ -1,16 +1,9 @@