NavLinkGroup
Work in progress - this component is not yet ready for use.
Basic
NNavLinkGroup
is a component that renders a group of NNavLink
components.
Preview
Code
<script setup lang="ts">
const links = [
{
leading: 'i-heroicons-user-group',
label: 'Teams',
defaultOpen: true,
children: [
{
label: 'Team Members 1',
to: '/components/nav-link',
},
{
label: 'Team Members 2',
to: '/components/nav-link-group',
},
{
label: 'Team Members 3',
to: '/components/breadcrumb',
},
],
},
{
leading: 'i-heroicons-user',
to: '/components/nav-link',
label: 'Users',
badge: {
label: '20+',
},
},
{
leading: 'i-heroicons-cog',
to: '/components/',
label: 'Settings',
},
{
leading: 'i-heroicons-document-text',
to: '/components/',
label: 'Documentation',
},
{
leading: 'i-heroicons-question-mark-circle',
to: '/components/',
label: 'Help',
},
]
</script>
<template>
<NNavLinkGroup :links="links" />
</template>
Props
import type { NNavLinkProps } from './nav-link'
export interface NNavLinkGroupLink extends NNavLinkProps {
children?: NNavLinkProps[]
defaultOpen?: boolean
}
export interface NVerticalNav {
links: NNavLinkGroupLink[]
}
Presets
type NavLinkGroupPrefix = 'nav-link-group'
export const staticNavLinkGroup: Record<`${NavLinkGroupPrefix}-${string}` | NavLinkGroupPrefix, string> = {
// base
'nav-link-group': 'w-60 flex flex-col border-2 border-base rounded-md border-dashed p-2 space-y-1',
// panel
'nav-link-group-panel': 'mt-1 px-2 space-y-1',
}
export const dynamicNavLinkGroup: [RegExp, (params: RegExpExecArray) => string][] = [
]
export const navLinkGroup = [
...dynamicNavLinkGroup,
staticNavLinkGroup,
]
Components
<script setup lang="ts">
import type { NVerticalNav } from '../../types'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
import { omitProps } from '../../utils'
import NNavLink from './NavLink.vue'
const props = defineProps<NVerticalNav>()
</script>
<template>
<div class="nav-link-group">
<template
v-for="link in props.links"
:key="link.label"
>
<NNavLink
v-if="!link.children"
v-bind="link"
/>
<Disclosure
v-else
v-slot="{ open }"
:default-open="link.defaultOpen"
as="div"
>
<DisclosureButton
as="div"
:disabled="link.disabled"
>
<NNavLink
:una="{
btnTrailing: `h-5 w-5 ${open ? 'rotate-90' : ''}`,
btn: 'w-full',
}"
trailing="i-heroicons-chevron-right-20-solid"
v-bind="omitProps(link, ['children'])"
/>
</DisclosureButton>
<div v-show="open">
<DisclosurePanel
as="ul"
nav-link-group="panel"
static
>
<li v-for="subLink in link.children" :key="subLink.label">
<NNavLink
v-bind="subLink"
:una="{
btnLabel: 'font-normal',
btn: 'w-full pl-8',
}"
/>
</li>
</DisclosurePanel>
</div>
</Disclosure>
</template>
</div>
</template>