navigation
VerticalNavigation
Display a vertical navigation.
Usage
Pass an array to the links
prop of the VerticalNavigation component. Each link can have the following properties:
label
- The label of the link.icon
- The icon of the link.iconClass
- The class of the icon of the link.avatar
- The avatar of the link. You can pass all the props of the Avatar component.badge
- A badge to display next to the label.click
- The click handler of the link.
You can also pass any property from the NuxtLink component such as to
, exact
, etc.
<script setup>
const links = [{
label: 'Profile',
avatar: {
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
},
badge: 100
}, {
label: 'Installation',
icon: 'i-heroicons-home',
to: '/getting-started/installation'
}, {
label: 'Vertical Navigation',
icon: 'i-heroicons-chart-bar',
to: '/navigation/vertical-navigation'
}, {
label: 'Command Palette',
icon: 'i-heroicons-command-line',
to: '/navigation/command-palette'
}]
</script>
<template>
<UVerticalNavigation :links="links" />
</template>
Slots
You can use slots to customize links display.
default
Use the #default
slot to customize the link label. You will have access to the link
and isActive
properties in the slot scope.
<script setup>
const links = [{
label: 'Navigation',
children: [{
label: 'Vertical Navigation',
to: '/navigation/vertical-navigation'
}, {
label: 'Command Palette',
to: '/navigation/command-palette'
}]
}, {
label: 'Data',
children: [{
label: 'Table',
to: '/data/table'
}]
}]
</script>
<template>
<UVerticalNavigation :links="links">
<template #default="{ link }">
<div class="relative text-left w-full">
<div class="mb-2">
{{ link.label }}
</div>
<UVerticalNavigation v-if="link.children" :links="link.children" />
</div>
</template>
</UVerticalNavigation>
</template>
avatar
Use the #avatar
slot to customize the link avatar. You will have access to the link
and isActive
properties in the slot scope.
<script setup>
const links = [{
avatar: {
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
},
label: 'Benjamin Canac',
to: 'https://github.com/benjamincanac',
target: '_blank'
}, ...]
const { ui } = useAppConfig()
</script>
<template>
<UVerticalNavigation :links="links">
<template #avatar="{ link }">
<UAvatar
v-if="link.avatar"
v-bind="{ size: ui.verticalNavigation.avatar.size, ...link.avatar }"
:class="[ui.verticalNavigation.avatar.base]"
/>
<UIcon v-else name="i-heroicons-user-circle-20-solid" class="text-lg" />
</template>
</UVerticalNavigation>
</template>
icon
Use the #icon
slot to customize the link icon. You will have access to the link
and isActive
properties in the slot scope.
<script setup>
const types = {
bug: {
icon: 'i-heroicons-bug-ant-20-solid',
color: 'text-red-500'
},
docs: {
icon: 'i-heroicons-document-text-20-solid',
color: 'text-blue-500'
},
lock: {
icon: 'i-heroicons-lock-closed-20-solid',
color: 'text-gray dark:text-white'
},
default: {
icon: 'i-heroicons-question-mark-circle-20-solid',
color: 'text-green-500'
}
}
const links = [{
label: 'UDropdown and UPopover dropdown menu, dropdown will be obscured',
type: 'bug'
}, {
label: 'Uncaught (in promise) ReferenceError: ref is not defined',
type: 'lock'
}, {
label: 'Fully styled and customizable components for Nuxt.',
type: 'docs'
}, {
label: 'Can I pass a tailwind color to UNotifications with `toast.add()` ?'
}]
</script>
<template>
<UVerticalNavigation :links="links">
<template #icon="{ link }">
<UIcon v-if="link.type" :name="types[link.type].icon" :class="types[link.type].color" class="text-base" />
<UIcon v-else :name="types.default.icon" :class="types.default.color" class="text-base" />
</template>
</UVerticalNavigation>
</template>
badge
Use the #badge
slot to customize the link badge. You will have access to the link
and isActive
properties in the slot scope.
<script setup>
const links = [{
label: '.github',
icon: 'i-heroicons-folder-20-solid',
badge: 'chore(github): use pnpm 8',
time: 'last month'
}, {
label: '.editorconfig',
icon: 'i-heroicons-document-solid',
badge: 'Initial commit',
time: '2 years ago'
}, {
label: '.package.json',
icon: 'i-heroicons-document-solid',
badge: 'chore(deps): bump',
time: '16 hours ago'
}]
</script>
<template>
<UVerticalNavigation
:links="links"
class="w-full"
:ui="{
label: 'truncate relative text-gray-900 dark:text-white flex-initial w-32 text-left'
}"
>
<template #badge="{ link }">
<div class="flex-1 flex justify-between relative truncate">
<div>{{ link.badge }}</div>
<div>{{ link.time }}</div>
</div>
</template>
</UVerticalNavigation>
</template>
Props
{}
[]
Preset
{
"wrapper": "relative",
"base": "group relative flex items-center gap-2 focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-1 focus-visible:before:ring-primary-500 dark:focus-visible:before:ring-primary-400 before:absolute before:inset-px before:rounded-md disabled:cursor-not-allowed disabled:opacity-75",
"ring": "focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-primary-500 dark:focus-visible:ring-primary-400",
"padding": "px-3 py-1.5",
"width": "w-full",
"rounded": "rounded-md",
"font": "font-medium",
"size": "text-sm",
"active": "text-gray-900 dark:text-white before:bg-gray-100 dark:before:bg-gray-800",
"inactive": "text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:before:bg-gray-50 dark:hover:before:bg-gray-800/50",
"label": "truncate relative",
"icon": {
"base": "flex-shrink-0 w-4 h-4",
"active": "text-gray-700 dark:text-gray-200",
"inactive": "text-gray-400 dark:text-gray-500 group-hover:text-gray-700 dark:group-hover:text-gray-200"
},
"avatar": {
"base": "flex-shrink-0",
"size": "3xs"
},
"badge": {
"base": "relative ms-auto inline-block py-0.5 px-2 text-xs rounded-md -me-1 -my-0.5",
"active": "bg-white dark:bg-gray-900",
"inactive": "bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white group-hover:bg-white dark:group-hover:bg-gray-900"
}
}