ContentSurround

GitLab
Um par de links de anterior e próximo para navegar entre as páginas.
Este componente só está disponível quando o módulo @nuxt/content está instalado.

Uso

Use a prop surround com o valor surround que você obtém ao buscar as páginas adjacentes.

Anterior / Próximo

Use as props prev-icon e next-icon para personalizar o Icon dos botões.

<script setup lang="ts">
import type { ContentSurroundLink } from '@nitro/ui'

const surround = ref<ContentSurroundLink[]>([
  {
    title: 'ContentSearchButton',
    path: '/components/content-search-button',
    stem: '3.components/content-search-button',
    description: 'A pre-styled Button to open the ContentSearch modal.'
  },
  {
    title: 'ContentToc',
    path: '/components/content-toc',
    stem: '3.components/content-toc',
    description: 'A sticky Table of Contents with customizable slots.'
  }
])
</script>

<template>
  <NContentSurround
    prev-icon="i-lucide-chevron-left"
    next-icon="i-lucide-chevron-right"
    :surround="surround"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ContentSurroundLink } from '@nitro/ui'

const surround = ref<ContentSurroundLink[]>([
  {
    title: 'ContentSearchButton',
    path: '/components/content-search-button',
    stem: '3.components/content-search-button',
    description: 'A pre-styled Button to open the ContentSearch modal.'
  },
  {
    title: 'ContentToc',
    path: '/components/content-toc',
    stem: '3.components/content-toc',
    description: 'A sticky Table of Contents with customizable slots.'
  }
])
</script>

<template>
  <NContentSurround
    prev-icon="i-lucide-chevron-left"
    next-icon="i-lucide-chevron-right"
    :surround="surround"
  />
</template>

Exemplos

Dentro de uma página

Use o componente ContentSurround em uma página para exibir os links de anterior e próximo:

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>
  <NPage v-if="page">
    <NPageHeader :title="page.title" />

    <NPageBody>
      <ContentRenderer v-if="page.body" :value="page" />

      <NSeparator v-if="surround?.filter(Boolean).length" />

      <NContentSurround :surround="(surround as any)" />
    </NPageBody>

    <template v-if="page?.body?.toc?.links?.length" #right>
      <NContentToc :links="page.body.toc.links" />
    </template>
  </NPage>
</template>

API

Props

Prop Default Type
as'div'any

The element or component this component should render as.

prevIconappConfig.ui.icons.arrowLeftany

The icon displayed in the prev link.

nextIconappConfig.ui.icons.arrowRightany

The icon displayed in the next link.

surround T[]
ui { root?: SlotClass; link?: SlotClass; linkLeading?: SlotClass; linkLeadingIcon?: SlotClass; linkTitle?: SlotClass; linkDescription?: SlotClass; }

Slots

Slot Type
link{ link: T; ui: object; }
link-leading{ link: T; ui: object; }
link-title{ link: T; ui: object; }
link-description{ link: T; ui: object; }

Tema

app.config.ts
export default defineAppConfig({
  ui: {
    contentSurround: {
      slots: {
        root: 'grid grid-cols-1 sm:grid-cols-2 gap-8',
        link: 'group block px-6 py-8 rounded-lg border border-default hover:bg-elevated/50 focus-visible:outline-primary transition-colors',
        linkLeading: 'inline-flex items-center rounded-full p-1.5 bg-elevated group-hover:bg-primary/10 ring ring-accented mb-4 group-hover:ring-primary/50 transition',
        linkLeadingIcon: 'size-5 shrink-0 text-highlighted group-hover:text-primary transition-[color,translate]',
        linkTitle: 'font-medium text-[15px] text-highlighted mb-1 truncate',
        linkDescription: 'text-sm text-muted line-clamp-2'
      },
      variants: {
        direction: {
          left: {
            linkLeadingIcon: 'group-active:-translate-x-0.5'
          },
          right: {
            link: 'text-right',
            linkLeadingIcon: 'group-active:translate-x-0.5'
          }
        }
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        contentSurround: {
          slots: {
            root: 'grid grid-cols-1 sm:grid-cols-2 gap-8',
            link: 'group block px-6 py-8 rounded-lg border border-default hover:bg-elevated/50 focus-visible:outline-primary transition-colors',
            linkLeading: 'inline-flex items-center rounded-full p-1.5 bg-elevated group-hover:bg-primary/10 ring ring-accented mb-4 group-hover:ring-primary/50 transition',
            linkLeadingIcon: 'size-5 shrink-0 text-highlighted group-hover:text-primary transition-[color,translate]',
            linkTitle: 'font-medium text-[15px] text-highlighted mb-1 truncate',
            linkDescription: 'text-sm text-muted line-clamp-2'
          },
          variants: {
            direction: {
              left: {
                linkLeadingIcon: 'group-active:-translate-x-0.5'
              },
              right: {
                link: 'text-right',
                linkLeadingIcon: 'group-active:translate-x-0.5'
              }
            }
          }
        }
      }
    })
  ]
})

Changelog

No recent changes