ContentNavigation

GitHub
An accordion-style navigation component for organizing page links.
This component is only available when the @nuxt/content module is installed.

Usage

Use the navigation prop with the navigation value you get when fetching the navigation of your app.

<script setup lang="ts">
import type { ContentNavigationItem } from '@nuxt/content';
import type { Ref } from 'vue';
import { inject } from 'vue';

const navigation = inject<Ref<Array<ContentNavigationItem>>>('navigation');
</script>

<template>
  <PContentNavigation
    :navigation="navigation"
    highlight
  />
</template>

Type

Set the type prop to single to only allow one item to be open at a time. Defaults to multiple.

<script setup lang="ts">
const navigation = ref([
  {
    title: 'Guide',
    icon: 'i-lucide:book-open',
    path: '#getting-started',
    children: [
      {
        title: 'Introduction',
        path: '#introduction',
        active: true
      },
      {
        title: 'Installation',
        path: '#installation'
      }
    ]
  },
  {
    title: 'Composables',
    icon: 'i-lucide:database',
    path: '#composables',
    children: [
      {
        title: 'defineShortcuts',
        path: '#defineshortcuts'
      },
      {
        title: 'useModal',
        path: '#usemodal'
      }
    ]
  }
])
</script>

<template>
  <PContentNavigation type="single" />
</template>

Color

Use the color prop to change the color of the navigation links.

<script setup lang="ts">
const navigation = ref([
  {
    title: 'Guide',
    icon: 'i-lucide:book-open',
    path: '#getting-started',
    children: [
      {
        title: 'Introduction',
        path: '#introduction',
        active: true
      },
      {
        title: 'Installation',
        path: '#installation'
      }
    ]
  },
  {
    title: 'Composables',
    icon: 'i-lucide:database',
    path: '#composables',
    children: [
      {
        title: 'defineShortcuts',
        path: '#defineshortcuts'
      },
      {
        title: 'useModal',
        path: '#usemodal'
      }
    ]
  }
])
</script>

<template>
  <PContentNavigation color="neutral" />
</template>

Variant

Use the variant prop to change the variant of the navigation links.

<script setup lang="ts">
const navigation = ref([
  {
    title: 'Guide',
    icon: 'i-lucide:book-open',
    path: '#getting-started',
    children: [
      {
        title: 'Introduction',
        path: '#introduction',
        active: true
      },
      {
        title: 'Installation',
        path: '#installation'
      }
    ]
  },
  {
    title: 'Composables',
    icon: 'i-lucide:database',
    path: '#composables',
    children: [
      {
        title: 'defineShortcuts',
        path: '#defineshortcuts'
      },
      {
        title: 'useModal',
        path: '#usemodal'
      }
    ]
  }
])
</script>

<template>
  <PContentNavigation variant="link" />
</template>

Highlight

Use the highlight prop to display a highlighted border for the active link.

Use the highlight-color prop to change the color of the border. It defaults to the color prop.

<script setup lang="ts">
const navigation = ref([
  {
    title: 'Guide',
    icon: 'i-lucide:book-open',
    path: '#getting-started',
    children: [
      {
        title: 'Introduction',
        path: '#introduction',
        active: true
      },
      {
        title: 'Installation',
        path: '#installation'
      }
    ]
  },
  {
    title: 'Composables',
    icon: 'i-lucide:database',
    path: '#composables',
    children: [
      {
        title: 'defineShortcuts',
        path: '#defineshortcuts'
      },
      {
        title: 'useModal',
        path: '#usemodal'
      }
    ]
  }
])
</script>

<template>
  <PContentNavigation highlight highlight-color="primary" color="primary" variant="pill" />
</template>

Trailing Icon

<script setup lang="ts">
const navigation = ref([
  {
    title: 'Guide',
    icon: 'i-lucide:book-open',
    path: '#getting-started',
    children: [
      {
        title: 'Introduction',
        path: '#introduction',
        active: true
      },
      {
        title: 'Installation',
        path: '#installation'
      }
    ]
  },
  {
    title: 'Composables',
    icon: 'i-lucide:database',
    path: '#composables',
    children: [
      {
        title: 'defineShortcuts',
        path: '#defineshortcuts'
      },
      {
        title: 'useModal',
        path: '#usemodal'
      }
    ]
  }
])
</script>

<template>
  <PContentNavigation trailing-icon="i-lucide:arrow-up" />
</template>

Examples

Within a layout

layouts/docs.vue
<script setup lang="ts">
import type { ContentNavigationItem } from '@nuxt/content';

const navigation = inject<Ref<Array<ContentNavigationItem>>>('navigation');
</script>

<template>
  <ExampleLayout>
    <template #left>
      <div>
        <PContentNavigation
          :navigation="navigation"
          highlight
        />
      </div>
    </template>

    <slot />
  </ExampleLayout>
</template>

Within a header

Use the ContentNavigation component inside the content slot of a Header component to display the navigation of the page on mobile:

components/Header.vue
<script setup lang="ts">
import type { ContentNavigationItem } from '@nuxt/content';

const navigation = inject<Ref<Array<ContentNavigationItem>>>('navigation');
</script>

<template>
  <PHeader>
    <template #body>
      <PContentNavigation
        :navigation="navigation"
        highlight
      />
    </template>
  </PHeader>
</template>

API

Props

Prop Default Type

Slots

Slot Type

Emits

Event Type

Theme

We use unocss-variants to customize the theme. Read more about it in the theming guide.

Below is the theme configuration skeleton for the PContentNavigation. Since the component is provided unstyled by default, you will need to fill in these values to apply your own custom look and feel. If you prefer to use our pre-built, opinionated styling, you can instead use our UnoCSS preset, this docs is using it as well.

app.config.ts
export default defineAppConfig({
  pohon: {
    contentNavigation: {
      slots: {
        root: '',
        content: '',
        list: '',
        item: '',
        listWithChildren: '',
        itemWithChildren: '',
        trigger: '',
        link: '',
        linkLeadingIcon: '',
        linkTrailing: '',
        linkTrailingBadge: '',
        linkTrailingBadgeSize: '',
        linkTrailingIcon: '',
        linkTitle: '',
        linkTitleExternalIcon: ''
      },
      variants: {
        color: {
          primary: {
            trigger: '',
            link: ''
          },
          secondary: {
            trigger: '',
            link: ''
          },
          success: {
            trigger: '',
            link: ''
          },
          info: {
            trigger: '',
            link: ''
          },
          warning: {
            trigger: '',
            link: ''
          },
          error: {
            trigger: '',
            link: ''
          },
          neutral: {
            trigger: '',
            link: ''
          }
        },
        highlightColor: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        variant: {
          pill: '',
          link: ''
        },
        active: {
          true: {
            link: ''
          },
          false: {
            link: '',
            linkLeadingIcon: ''
          }
        },
        disabled: {
          true: {
            trigger: ''
          }
        },
        highlight: {
          true: {}
        },
        level: {
          true: {
            item: '',
            itemWithChildren: ''
          }
        }
      },
      defaultVariants: {
        color: 'primary',
        highlightColor: 'primary',
        variant: 'pill'
      }
    }
  }
};
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import pohon from 'pohon-ui/vite'

export default defineAppConfig({
  pohon: {
    contentNavigation: {
      slots: {
        root: '',
        content: '',
        list: '',
        item: '',
        listWithChildren: '',
        itemWithChildren: '',
        trigger: '',
        link: '',
        linkLeadingIcon: '',
        linkTrailing: '',
        linkTrailingBadge: '',
        linkTrailingBadgeSize: '',
        linkTrailingIcon: '',
        linkTitle: '',
        linkTitleExternalIcon: ''
      },
      variants: {
        color: {
          primary: {
            trigger: '',
            link: ''
          },
          secondary: {
            trigger: '',
            link: ''
          },
          success: {
            trigger: '',
            link: ''
          },
          info: {
            trigger: '',
            link: ''
          },
          warning: {
            trigger: '',
            link: ''
          },
          error: {
            trigger: '',
            link: ''
          },
          neutral: {
            trigger: '',
            link: ''
          }
        },
        highlightColor: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        variant: {
          pill: '',
          link: ''
        },
        active: {
          true: {
            link: ''
          },
          false: {
            link: '',
            linkLeadingIcon: ''
          }
        },
        disabled: {
          true: {
            trigger: ''
          }
        },
        highlight: {
          true: {}
        },
        level: {
          true: {
            item: '',
            itemWithChildren: ''
          }
        }
      },
      defaultVariants: {
        color: 'primary',
        highlightColor: 'primary',
        variant: 'pill'
      }
    }
  }
};

Changelog

No recent changes