Skip to content

Commit

Permalink
feat(config): single source of truth for merged config ; fix inheri…
Browse files Browse the repository at this point in the history
…tance
  • Loading branch information
Tahul committed Jan 27, 2023
1 parent fe2e315 commit e7023f9
Show file tree
Hide file tree
Showing 18 changed files with 173 additions and 150 deletions.
3 changes: 2 additions & 1 deletion .docs/content/0.index.md
Expand Up @@ -4,7 +4,8 @@ navigation: false
layout: page
header:
fixed:
initial: true
initial: false
lg: false
---

:ellipsis{right=0px width=75% blur=150px}
Expand Down
7 changes: 7 additions & 0 deletions .docs/content/1.introduction/1.getting-started.md
@@ -1,3 +1,10 @@
---
header:
fixed:
initial: false
lg: false
---

# Getting Started

From your Markdown files to a deployed website in few minutes.
Expand Down
35 changes: 20 additions & 15 deletions .docs/content/2.api/2.composables.md
Expand Up @@ -6,35 +6,40 @@ Discover the Docus composables to use in your custom Vue components and pages.

`useDocus()`{lang=ts} gives access to docus runtime config, all default values and your custom config from `app.config.ts`

- `config` refers to the merged config of the current page.

`main`, `header`, `aside`, `footer` and `titleTemplate` can be set from `_dir.yml` and any `page.md` file.

The configs in `app.config` file will be used as defaults.

```vue
<script setup>
const docus = useDocus()
const { config } = useDocus()
</script>
<template>
<div>
<h1>{{ docus.title }}</h1>
<p>{{ docus.description }}</p>
<h1>{{ config.title }}</h1>
<p>{{ config.description }}</p>
</div>
</template>
```

## `useCurrentNavigation()`
- `tree` refers to the current navigation tree that is displayed in the `aside` component.

`useCurrentNavigation()`{lang="ts"} gives access to current navigation calculated from @nuxt/content navigation object and features in theme and pages front-matter.
```vue
<script setup>
const { tree } = useDocus()
</script>
```ts
const {
// Navigation object
tree,
// Aside config computed from front-matter and theme config
asideConfig
} = useCurrentNavigation()
<template>
<DocsAsideTree :links="tree" />
</template>
```

::source-link
---
source: "/packages/docs-theme/composables/useCurrentNavigation.ts"
source: "composables/useDocus.ts"
---
::

Expand All @@ -57,7 +62,7 @@ const {

::source-link
---
source: "/packages/docs-theme/composables/useMenu.ts"
source: "composables/useMenu.ts"
---
::

Expand All @@ -78,6 +83,6 @@ const {

::source-link
---
source: "/packages/docs-theme/composables/useScrollspy.ts"
source: "composables/useScrollspy.ts"
---
::
18 changes: 9 additions & 9 deletions components/app/AppFooter.vue
@@ -1,20 +1,20 @@
<script setup lang="ts">
const docus = useDocus()
const { config } = useDocus()
const socialIcons = ref(null)
const icons = computed(() => docus.value?.footer?.iconLinks || [])
const textLinks = computed(() => docus.value?.footer?.textLinks || [])
const socialIconsCount = computed(() => Object.entries(docus.value?.socials || {}).filter(([_, v]) => v).length)
const icons = computed(() => config.value?.footer?.iconLinks || [])
const textLinks = computed(() => config.value?.footer?.textLinks || [])
const socialIconsCount = computed(() => Object.entries(config.value?.socials || {}).filter(([_, v]) => v).length)
const nbSocialIcons = computed(() => (socialIcons.value ? socialIconsCount.value : 0))
</script>

<template>
<footer>
<Container :fluid="docus?.footer?.fluid" padded class="footer-container">
<Container :fluid="config?.footer?.fluid" padded class="footer-container">
<!-- Left -->
<div class="left">
<a v-if="docus?.footer?.credits" :href="docus?.footer?.credits?.href || '#'" rel="noopener" target="_blank">
<Component :is="docus?.footer?.credits?.icon" v-if="docus?.footer?.credits?.icon" class="left-icon" />
<p v-if="docus?.footer?.credits?.text">{{ docus.footer.credits.text }}</p>
<a v-if="config?.footer?.credits" :href="config?.footer?.credits?.href || '#'" rel="noopener" target="_blank">
<Component :is="config?.footer?.credits?.icon" v-if="config?.footer?.credits?.icon" class="left-icon" />
<p v-if="config?.footer?.credits?.text">{{ config.footer.credits.text }}</p>
</a>
</div>
Expand Down Expand Up @@ -42,7 +42,7 @@ const nbSocialIcons = computed(() => (socialIcons.value ? socialIconsCount.value
:href="icon.href"
target="_blank"
>
<Icon :name="icon.icon || icon.component" />
<Icon :name="icon.icon" />
</a>
<AppSocialIcons ref="socialIcons" />
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/app/AppHeader.vue
@@ -1,5 +1,5 @@
<script setup lang="ts">
const docus = useDocus()
const { config } = useDocus()
const { navigation } = useContent()
const { hasDocSearch } = useDocSearch()
Expand All @@ -12,7 +12,7 @@ defineProps({

<template>
<header :class="{ 'has-dialog': hasDialog, 'has-doc-search': hasDocSearch }">
<Container :fluid="docus?.header?.fluid ">
<Container :fluid="config?.header?.fluid ">
<div class="section left">
<AppHeaderDialog v-if="hasDialog" />
<AppHeaderLogo />
Expand Down
4 changes: 2 additions & 2 deletions components/app/AppHeaderDialog.vue
Expand Up @@ -2,9 +2,9 @@
import ThemeSelect from './ThemeSelect.vue'
const { navigation } = useContent()
const docus = useDocus()
const { config } = useDocus()
const filtered = computed(() => docus.value.aside?.exclude || [])
const filtered = computed(() => config.value.aside?.exclude || [])
const links = computed(() => {
return (navigation.value || []).filter((item: any) => {
Expand Down
6 changes: 3 additions & 3 deletions components/app/AppHeaderLogo.vue
@@ -1,7 +1,7 @@
<script setup lang="ts">
const docus = useDocus()
const logo = computed(() => docus.value.header?.logo || false)
const title = computed(() => docus.value.header?.title || docus.value.title)
const { config } = useDocus()
const logo = computed(() => config.value.header?.logo || false)
const title = computed(() => config.value.header?.title || config.value.title)
</script>

<template>
Expand Down
8 changes: 4 additions & 4 deletions components/app/AppHeaderNavigation.vue
Expand Up @@ -2,11 +2,11 @@
const route = useRoute()
const { navBottomLink } = useContentHelpers()
const { navigation } = useContent()
const docus = useDocus()
const { config } = useDocus()
const hasNavigation = computed(() => !!docus.value.aside?.level)
const hasNavigation = computed(() => !!config.value.aside?.level)
const filtered = computed(() => docus.value.header?.exclude || [])
const filtered = computed(() => config.value.header?.exclude || [])
const tree = computed(() => {
return (navigation.value || []).filter((item: any) => {
Expand All @@ -30,7 +30,7 @@ const isActive = (link: any) => (link.exact ? route.fullPath === link._path : ro
:to="link.redirect? link.redirect : navBottomLink(link)"
:class="{ active: isActive(link) }"
>
<Icon v-if="link.icon && docus?.header?.showLinkIcon" :name="link.icon" />
<Icon v-if="link.icon && config?.header?.showLinkIcon" :name="link.icon" />
{{ link.title }}
</NuxtLink>
</li>
Expand Down
32 changes: 6 additions & 26 deletions components/app/AppLayout.vue
@@ -1,43 +1,23 @@
<script setup lang="ts">
const docus = useDocus()
const { navigation, page } = useContent()
const { navKeyFromPath } = useContentHelpers()
const headerPosition = computed(() => page.value?.header?.fixed || docus?.value?.header?.fixed || true)
const titleTemplate = computed(() => {
const appTitleTemplate = docus?.value?.titleTemplate || `%s · ${docus?.value?.title}`
if (page.value) {
return page.value.head?.titleTemplate || navKeyFromPath(page.value._path, 'titleTemplate', navigation.value || []) || appTitleTemplate
}
return appTitleTemplate
})
// TODO: remove?
defineProps({
padded: {
type: Boolean,
default: true
}
})
const { config } = useDocus()
useHead({
titleTemplate: titleTemplate.value,
titleTemplate: config.value.titleTemplate,
meta: [
{ name: 'twitter:card', content: 'summary_large_image' }
]
})
watch(titleTemplate, () => useHead({ titleTemplate: titleTemplate.value }))
watch(config.value.titleTemplate, () => useHead({ titleTemplate: config.value.titleTemplate }))
useContentHead(docus.value as any)
useContentHead(config.value as any)
</script>

<template>
<div>
<AppLoadingBar />
<AppHeader v-if="docus?.header" :fixed="headerPosition" />
<AppHeader v-if="Object.keys(config?.header).length" :fixed="config?.header?.fixed" />
<slot />
<AppFooter v-if="docus?.footer" />
<AppFooter v-if="Object.keys(config?.footer).length" />
</div>
</template>
4 changes: 2 additions & 2 deletions components/app/AppSocialIcons.vue
@@ -1,10 +1,10 @@
<script setup lang="ts">
const socials = ['twitter', 'facebook', 'instagram', 'youtube', 'github', 'medium']
const docus = useDocus()
const { config } = useDocus()
const icons = computed<any>(() => {
return Object.entries(docus.value.socials || {})
return Object.entries(config.value.socials || {})
.map(([key, value]) => {
if (typeof value === 'object') {
return value
Expand Down
2 changes: 1 addition & 1 deletion components/docs/DocsAside.vue
@@ -1,5 +1,5 @@
<script setup lang="ts">
const { tree } = useCurrentNavigation()
const { tree } = useDocus()
</script>

<template>
Expand Down
6 changes: 3 additions & 3 deletions components/docs/DocsAsideTree.vue
Expand Up @@ -21,7 +21,7 @@ const props = defineProps({
})
const route = useRoute()
const docus = useDocus()
const { config } = useDocus()
const collapsedMap = useState(`docus-docs-aside-collapse-map-${props.parent?._path || '/'}`, () => {
if (props.level === 0) {
Expand All @@ -47,12 +47,12 @@ const isCollapsed = (link: any) => {
}
// Check if aside.collapsed has been set in YML
if (link.aside?.hasOwnProperty('collapsed')) { return link.aside.collapsed }
if (link?.aside?.collapsed) { return link.aside.collapsed }
// Return value grabbed from the link
if (link?.collapsed) { return link?.collapsed }
if (docus?.value?.aside?.collapsed) { return docus.value.aside?.collapsed }
if (config?.value?.aside?.collapsed) { return config.value.aside?.collapsed }
}
return false
Expand Down
4 changes: 2 additions & 2 deletions components/docs/DocsPageBottom.vue
@@ -1,11 +1,11 @@
<script setup lang="ts">
const { page } = useContent()
const docus = useDocus()
const { config } = useDocus()
</script>

<template>
<div v-if="page" class="docs-page-bottom">
<div v-if="docus?.github?.edit" class="edit-link">
<div v-if="config?.github?.edit" class="edit-link">
<Icon name="uil:edit" />
<EditOnLink v-slot="{ url }" :page="page">
<ProseA :to="url">
Expand Down
26 changes: 18 additions & 8 deletions components/docs/DocsPageLayout.vue
@@ -1,12 +1,10 @@
<script setup lang="ts">
const { page, navigation } = useContent()
const { layoutConfig } = useCurrentNavigation()
const { config } = useDocus()
const route = useRoute()
const fallbackValue = (value: string, fallback = true) => {
if (typeof page.value?.[value] !== 'undefined') {
return page.value[value]
}
if (typeof page.value?.[value] !== 'undefined') { return page.value[value] }
return fallback
}
Expand Down Expand Up @@ -56,16 +54,16 @@ onBeforeUnmount(() => {

<template>
<Container
:fluid="page?.fluid || layoutConfig?.fluid"
:padded="page?.padded || layoutConfig?.padded || true"
:fluid="config?.main?.fluid"
:padded="config?.main?.padded"
class="docs-page-content"
:class="{
fluid: page?.fluid || layoutConfig?.fluid
fluid: config?.main?.fluid,
}"
>
<!-- Aside -->
<aside v-if="hasAside" ref="asideNav" class="aside-nav">
<DocsAside />
<DocsAside class="app-aside" />
</aside>
<!-- Page Body -->
Expand Down Expand Up @@ -103,6 +101,18 @@ onBeforeUnmount(() => {
<style scoped lang="ts">
css({
variants: {
fixed: {
true: {
'.app-aside': {
backgroundColor: 'blue'
},
},
options: {
default: true
}
}
},
'.docs-page-content': {
position: 'relative',
display: 'flex',
Expand Down

0 comments on commit e7023f9

Please sign in to comment.