v2.1.8
/
  • Get Started
  • Components
  • Composables
  • Typography
  • GitHub
  • Layout
  • App
  • Container
  • Error
  • SidebarLayout
  • Element
  • Advice
  • Alert
  • Avatar
  • AvatarGroup
  • Badge
  • Banner
  • Button
  • Calendar
  • Card
  • Chip
  • Collapsible
  • Countdown
  • FieldGroup
  • Kbd
  • Progress
  • Separator
  • Skeleton
  • Form
  • Checkbox
  • CheckboxGroup
  • ColorPicker
  • FileUpload
  • Form
  • FormField
  • Input
  • InputDate
  • InputMenu
  • InputNumber
  • InputTags
  • InputTime
  • PinInput
  • RadioGroup
  • Range
  • Select
  • SelectMenu
  • Switch
  • Textarea
  • Data
  • Accordion
  • DescriptionList
  • Empty
  • Table
  • TableWrapper
  • Timeline
  • User
  • Navigation
  • Breadcrumb
  • CommandPalette
  • Link
  • NavigationMenu
  • Pagination
  • Stepper
  • Tabs
  • Overlay
  • ContextMenu
  • DropdownMenu
  • Modal
  • Popover
  • Slideover
  • Toast
  • Tooltip
  • Page
  • PageCard
  • PageColumns
  • PageGrid
  • PageLinks
  • PageList
  • Dashboard
  • DashboardGroup
  • DashboardSearch
  • DashboardSearchButton
  • AI Chat
  • soonChatMessage
  • soonChatMessages
  • soonChatPalette
  • soonChatPrompt
  • soonChatPromptSubmit
  • Content
  • ContentSearch
  • ContentSearchButton
  • ContentSurround
  • ContentToc
  • Color Mode
  • ColorModeAvatar
  • ColorModeButton
  • ColorModeImage
  • ColorModeSelect
  • ColorModeSwitch
  • i18n
  • LocaleSelect
  • b24icons
  • b24jssdk
Use our Nuxt starter
v2.1.8
  • Docs
  • Components
  • Composables
  • Typography

ContentToc

A sticky table of contents component with dynamic active section highlighting.
GitHub
Nuxt UI
This component is only available when the @nuxt/content module is installed.

Usage

Use the links prop with the page?.body?.toc?.links you get when fetching a page.

On this page

  • Usage
    • Title
  • Examples
    • Within a page
  • API
    • Props
    • Slots
    • Emits
  • Theme
{
  "wait": "Loading client-side content..."
}

Title

Use the title prop to change the title of the Table of Contents.

On this page

  • Usage
    • Title
  • API
    • Props
    • Slots
  • Theme
{
  "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

Prop Default Type
as'nav'any

The element or component this component should render as.

trailingIconicons.chevronDownIconComponent

The icon displayed to collapse the content.

titlet('contentToc.title') string

The title of the table of contents.

links ContentTocLink[]
  • id: string
  • text: string
  • depth: number
  • children?: TocLink[]
  • class?: any
  • b24ui?: Pick<{ root?: ClassNameValue; container?: ClassNameValue; top?: ClassNameValue; bottom?: ClassNameValue; trigger?: ClassNameValue; title?: ClassNameValue; trailing?: ClassNameValue; trailingIcon?: ClassNameValue; content?: ClassNameValue; list?: ClassNameValue; listWithChildren?: ClassNameValue; item?: ClassNameValue; itemWithChildren?: ClassNameValue; link?: ClassNameValue; linkText?: ClassNameValue; }, "item" | "itemWithChildren" | "link" | "linkText">
defaultOpenboolean

The open state of the collapsible when it is initially rendered.
Use when you do not need to control its open state.

openboolean

The controlled open state of the collapsible. Can be binded with v-model.

b24ui { root?: ClassNameValue; container?: ClassNameValue; top?: ClassNameValue; bottom?: ClassNameValue; trigger?: ClassNameValue; title?: ClassNameValue; trailing?: ClassNameValue; trailingIcon?: ClassNameValue; content?: ClassNameValue; list?: ClassNameValue; listWithChildren?: ClassNameValue; item?: ClassNameValue; itemWithChildren?: ClassNameValue; link?: ClassNameValue; linkText?: ClassNameValue; }

Slots

Slot Type
leading{ open: boolean; b24ui: object; }
default{ open: boolean; }
trailing{ open: boolean; b24ui: object; }
content{ links: ContentTocLink[]; }
link{ link: ContentTocLink; }
top{ links?: ContentTocLink[] | undefined; }
bottom{ links?: ContentTocLink[] | undefined; }

Emits

Event Type
update:open[value: boolean]
move[id: string]

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: {}
        }
      }
    })
  ]
})

ContentSurround

A pair of "Previous" and "Next" buttons for sequential page navigation.

ColorModeAvatar

An Avatar that automatically switches its image based on the current theme (light/dark).

On this page

  • Usage
    • Title
  • Examples
    • Within a page
  • API
    • Props
    • Slots
    • Emits
  • Theme
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24