ContentSurround
Usage
Use the surround
prop with the surround
value you get when fetching a page surround.
<script setup lang="ts">
const route = useRoute()
const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
return queryCollectionItemSurroundings('content', route.path, {
fields: ['description']
})
})
</script>
<template>
<UContentSurround :surround="(surround as any)" />
</template>
Prev / Next
Use the prev-icon
and next-icon
props to customize the buttons Icon.
<script setup lang="ts">
const surround = ref([
{
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>
<UContentSurround
prev-icon="i-lucide-chevron-left"
next-icon="i-lucide-chevron-right"
:surround="surround"
/>
</template>
Examples
Within a page
Use the ContentSurround component in a page to display the prev and next links:
<script setup lang="ts">
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => queryCollection('content').path(route.path).first())
if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
}
</script>
<template>
<UPage v-if="page">
<UPageHeader :title="page.title" />
<UPageBody>
<ContentRenderer v-if="page.body" :value="page" />
<USeparator v-if="surround?.filter(Boolean).length" />
<UContentSurround :surround="(surround as any)" />
</UPageBody>
<template v-if="page?.body?.toc?.links?.length" #right>
<UContentToc :links="page.body.toc.links" />
</template>
</UPage>
</template>
API
Props
Prop | Default | Type |
---|---|---|
as |
|
The element or component this component should render as. |
prevIcon |
|
The icon displayed in the prev link. |
nextIcon |
|
The icon displayed in the next link. |
surround |
| |
ui |
|
Slots
Slot | Type |
---|---|
link |
|
link-leading |
|
link-title |
|
link-description |
|
Theme
export default defineAppConfig({
uiPro: {
contentSurround: {
slots: {
root: 'grid sm:grid-cols-2 gap-8',
link: [
'group block px-6 py-8 rounded-[calc(var(--ui-radius)*2)] border border-(--ui-border) hover:bg-(--ui-bg-elevated)/50 focus-visible:outline-(--ui-primary)',
'transition-colors'
],
linkLeading: [
'inline-flex items-center rounded-full p-1.5 bg-(--ui-bg-elevated) group-hover:bg-(--ui-primary)/10 ring ring-(--ui-border-accented) mb-4 group-hover:ring-(--ui-primary)/50',
'transition'
],
linkLeadingIcon: [
'size-5 shrink-0 text-(--ui-text-highlighted) group-hover:text-(--ui-primary)',
'transition-[color,translate]'
],
linkTitle: 'font-medium text-[15px] text-(--ui-text-highlighted) mb-1 truncate',
linkDescription: 'text-sm text-(--ui-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'
]
}
}
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
uiPro: {
contentSurround: {
slots: {
root: 'grid sm:grid-cols-2 gap-8',
link: [
'group block px-6 py-8 rounded-[calc(var(--ui-radius)*2)] border border-(--ui-border) hover:bg-(--ui-bg-elevated)/50 focus-visible:outline-(--ui-primary)',
'transition-colors'
],
linkLeading: [
'inline-flex items-center rounded-full p-1.5 bg-(--ui-bg-elevated) group-hover:bg-(--ui-primary)/10 ring ring-(--ui-border-accented) mb-4 group-hover:ring-(--ui-primary)/50',
'transition'
],
linkLeadingIcon: [
'size-5 shrink-0 text-(--ui-text-highlighted) group-hover:text-(--ui-primary)',
'transition-[color,translate]'
],
linkTitle: 'font-medium text-[15px] text-(--ui-text-highlighted) mb-1 truncate',
linkDescription: 'text-sm text-(--ui-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'
]
}
}
}
}
}
})
]
})