Usage
Use the links prop with the page?.body?.toc?.links you get when fetching a page.
Title
Use the title prop to change the title of the Table of Contents.
{
"wait": "Loading client-side content..."
}Examples
Within a page
Use the ContentToc component in a page to display the Table of Contents:
pages/[...slug].vue
<script setup lang="ts">
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => queryCollection('docs').path(route.path).first())
if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
}
</script>
<template>
<template v-if="page">
<ProseH1>{{ page.title }}</ProseH1>
<template v-if="page?.body?.toc?.links?.length">
<B24ContentToc :links="page.body.toc.links" />
</template>
<div>
<ContentRenderer v-if="page.body" :value="page" />
<B24Separator v-if="surround?.filter(Boolean).length" class="my-4" />
<B24ContentSurround :surround="(surround as any)" />
</div>
</template>
</template>
API
Props
Slots
Emits
Theme
app.config.ts
export default defineAppConfig({
b24ui: {
contentToc: {
slots: {
root: '',
container: 'border-dashed border-b-(length:--ui-border-width-thick) border-(--ui-color-divider-vibrant-default) lg:border-0 flex flex-col',
top: '',
bottom: 'hidden lg:flex lg:flex-col gap-[24px]',
trigger: 'group pb-[12px] cursor-pointer lg:cursor-text focus-visible:outline-(--ui-color-accent-main-primary) focus-visible:outline-2 focus-visible:rounded-[4px] text-(--b24ui-typography-legend-color) text-(length:--ui-font-size-lg)/(--ui-font-line-height-3xs) font-(--ui-font-weight-semi-bold) flex-1 flex items-center gap-[6px]',
title: 'line-clamp-1 lg:line-clamp-2',
trailing: 'ms-auto inline-flex gap-[6px] items-center',
trailingIcon: 'size-[20px] transform transition-transform duration-200 shrink-0 group-data-[state=open]:rotate-180 lg:hidden',
content: 'motion-safe:data-[state=open]:animate-[collapsible-down_200ms_ease-out] motion-safe:data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden focus:outline-none',
list: 'min-w-0',
listWithChildren: 'ms-[12px]',
item: 'min-w-0',
itemWithChildren: '',
link: 'group relative text-(length:--ui-font-size-lg)/(--ui-font-line-height-3xs) flex items-center focus-visible:outline-(--ui-color-accent-main-primary) focus-visible:outline-1 focus-visible:rounded-[4px] text-(--b24ui-typography-description-color) underline-offset-2 hover:text-(--b24ui-typography-label-color) hover:underline pb-[12px]',
linkText: 'line-clamp-2'
},
variants: {
active: {
false: {
link: 'text-(--b24ui-typography-description-color) hover:text-(--b24ui-typography-label-color) transition-colors'
}
},
body: {
true: {
bottom: 'mt-6'
}
}
},
compoundVariants: [
{
active: true,
class: {
link: 'text-(--b24ui-typography-label-color)',
linkLeadingIcon: 'text-(--b24ui-typography-label-color)'
}
}
],
defaultVariants: {}
}
}
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import bitrix24UIPluginVite from '@bitrix24/b24ui-nuxt/vite'
export default defineConfig({
plugins: [
vue(),
bitrix24UIPluginVite({
b24ui: {
contentToc: {
slots: {
root: '',
container: 'border-dashed border-b-(length:--ui-border-width-thick) border-(--ui-color-divider-vibrant-default) lg:border-0 flex flex-col',
top: '',
bottom: 'hidden lg:flex lg:flex-col gap-[24px]',
trigger: 'group pb-[12px] cursor-pointer lg:cursor-text focus-visible:outline-(--ui-color-accent-main-primary) focus-visible:outline-2 focus-visible:rounded-[4px] text-(--b24ui-typography-legend-color) text-(length:--ui-font-size-lg)/(--ui-font-line-height-3xs) font-(--ui-font-weight-semi-bold) flex-1 flex items-center gap-[6px]',
title: 'line-clamp-1 lg:line-clamp-2',
trailing: 'ms-auto inline-flex gap-[6px] items-center',
trailingIcon: 'size-[20px] transform transition-transform duration-200 shrink-0 group-data-[state=open]:rotate-180 lg:hidden',
content: 'motion-safe:data-[state=open]:animate-[collapsible-down_200ms_ease-out] motion-safe:data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden focus:outline-none',
list: 'min-w-0',
listWithChildren: 'ms-[12px]',
item: 'min-w-0',
itemWithChildren: '',
link: 'group relative text-(length:--ui-font-size-lg)/(--ui-font-line-height-3xs) flex items-center focus-visible:outline-(--ui-color-accent-main-primary) focus-visible:outline-1 focus-visible:rounded-[4px] text-(--b24ui-typography-description-color) underline-offset-2 hover:text-(--b24ui-typography-label-color) hover:underline pb-[12px]',
linkText: 'line-clamp-2'
},
variants: {
active: {
false: {
link: 'text-(--b24ui-typography-description-color) hover:text-(--b24ui-typography-label-color) transition-colors'
}
},
body: {
true: {
bottom: 'mt-6'
}
}
},
compoundVariants: [
{
active: true,
class: {
link: 'text-(--b24ui-typography-label-color)',
linkLeadingIcon: 'text-(--b24ui-typography-label-color)'
}
}
],
defaultVariants: {}
}
}
})
]
})