ContentSurround
Une paire de liens précédent et suivant pour naviguer entre les pages.
Utilisation
Utilisez la prop surround avec la valeur surround que vous obtenez lors de la récupération d'un surround de page.
<script setup lang="ts">
const route = useRoute()
const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
return queryCollectionItemSurroundings('docs', route.path, {
fields: ['description']
})
})
</script>
<template>
<UContentSurround :surround="(surround as any)" />
</template>
Prev/Suivant
Utilisez les props prev-icon et next-icon pour personnaliser les boutons Icon.
<script setup lang="ts">
import type { ContentSurroundLink } from '@nuxt/ui'
const surround = ref<ContentSurroundLink[]>([
{
title: 'ContentSearchButton',
path: '/docs/components/content-search-button',
stem: 'docs/2.components/content-search-button',
description: 'A pre-styled Button to open the ContentSearch modal.'
},
{
title: 'ContentToc',
path: '/docs/components/content-toc',
stem: 'docs/2.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><script setup lang="ts">
import { ref } from 'vue'
import type { ContentSurroundLink } from '@nuxt/ui'
const surround = ref<ContentSurroundLink[]>([
{
title: 'ContentSearchButton',
path: '/docs/components/content-search-button',
stem: 'docs/2.components/content-search-button',
description: 'A pre-styled Button to open the ContentSearch modal.'
},
{
title: 'ContentToc',
path: '/docs/components/content-toc',
stem: 'docs/2.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>Exemples
Au sein d'une page
Utilisez le composant ContentSurround dans une page pour afficher les liens précédent et suivant:
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>
<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 | 'div' | anyThe element or component this component should render as. |
prevIcon | appConfig.ui.icons.arrowLeft | anyThe icon displayed in the prev link. |
nextIcon | appConfig.ui.icons.arrowRight | anyThe icon displayed in the next link. |
surround | T[] | |
ui | { root?: SlotClass; link?: SlotClass; linkLeading?: SlotClass; linkLeadingIcon?: SlotClass; linkTitle?: SlotClass; linkDescription?: SlotClass; } |
Slots électronique
| 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; } |
Thème
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 outline-primary/25 focus-visible:outline-3 focus-visible:border-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] ease-out motion-reduce:transition-none'
],
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 rtl:group-active:translate-x-0.5'
},
right: {
link: 'text-end',
linkLeadingIcon: 'group-active:translate-x-0.5 rtl:group-active:-translate-x-0.5'
}
}
}
}
}
})vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/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 outline-primary/25 focus-visible:outline-3 focus-visible:border-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] ease-out motion-reduce:transition-none'
],
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 rtl:group-active:translate-x-0.5'
},
right: {
link: 'text-end',
linkLeadingIcon: 'group-active:translate-x-0.5 rtl:group-active:-translate-x-0.5'
}
}
}
}
}
})
]
})Changelog écrit
No recent changes