Skip to content

Commit

Permalink
feat(NavigationMenu): add collapsed prop
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamincanac committed Jan 16, 2025
1 parent 931211a commit 3fc2210
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 62 deletions.
22 changes: 14 additions & 8 deletions playground/app/pages/components/navigation-menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ const highlightColor = ref()
const variant = ref(theme.defaultVariants.variant)
const orientation = ref('vertical' as const)
const highlight = ref(true)
const collapsed = ref(false)
const items = [
[{
label: 'Link',
type: 'label' as const
}, {
label: 'Documentation',
icon: 'i-lucide-book-open',
badge: 10,
Expand Down Expand Up @@ -40,33 +44,33 @@ const items = [
defaultOpen: true,
children: [{
label: 'Link',
icon: 'i-lucide-file',
icon: 'i-lucide-link',
description: 'Use NuxtLink with superpowers.',
to: '/components/link'
}, {
label: 'Modal',
icon: 'i-lucide-file',
description: 'Display a modal within your application.',
icon: 'i-lucide-square',
description: 'Display a modal dialog overlay for important content.',
to: '/components/modal'
}, {
label: 'NavigationMenu',
icon: 'i-lucide-file',
icon: 'i-lucide-list',
description: 'Display a list of links.',
to: '/components/navigation-menu',
trailingIcon: 'i-lucide-check'
}, {
label: 'Pagination',
icon: 'i-lucide-file',
icon: 'i-lucide-parking-meter',
description: 'Display a list of pages.',
to: '/components/pagination'
}, {
label: 'Popover',
icon: 'i-lucide-file',
icon: 'i-lucide-message-circle',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/components/popover'
}, {
label: 'Progress',
icon: 'i-lucide-file',
icon: 'i-lucide-loader',
description: 'Show a horizontal bar to indicate task progression.',
to: '/components/progress'
}]
Expand All @@ -89,20 +93,22 @@ const items = [
<USelect v-model="color" :items="colors" placeholder="Color" />
<USelect v-model="variant" :items="variants" placeholder="Variant" />
<USelect v-model="orientation" :items="orientations" placeholder="Orientation" />
<USwitch v-model="collapsed" label="Collapsed" />
<USwitch v-model="highlight" label="Highlight" />
<USelect v-model="highlightColor" :items="colors" placeholder="Highlight color" />
</div>

<UNavigationMenu
arrow
:collapsed="collapsed"
:items="items"
:color="color"
:variant="variant"
:orientation="orientation"
:highlight="highlight"
:highlight-color="highlightColor"
:class="highlight && 'data-[orientation=horizontal]:border-b border-[var(--ui-border)]'"
class="data-[orientation=vertical]:w-48"
class="data-[orientation=vertical]:data-[collapsed=false]:w-48"
/>
</div>
</template>
16 changes: 13 additions & 3 deletions src/runtime/components/NavigationMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export interface NavigationMenuProps<T> extends Pick<NavigationMenuRootProps, 'm
* @defaultValue 'horizontal'
*/
orientation?: NavigationMenuRootProps['orientation']
/**
* Collapse the navigation menu to only show icons.
* Only works when `orientation` is `vertical`.
* @defaultValue false
*/
collapsed?: boolean
/** Display a line next to the active item. */
highlight?: boolean
highlightColor?: NavigationMenuVariants['highlightColor']
Expand Down Expand Up @@ -173,6 +179,7 @@ const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: N
const ui = computed(() => navigationMenu({
orientation: props.orientation,
collapsed: props.collapsed,
color: props.color,
variant: props.variant,
highlight: props.highlight,
Expand All @@ -190,15 +197,18 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
<UIcon v-else-if="item.icon" :name="item.icon" :class="ui.linkLeadingIcon({ class: props.ui?.linkLeadingIcon, active, disabled: !!item.disabled })" />
</slot>

<span v-if="get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label` : 'item-label']" :class="ui.linkLabel({ class: props.ui?.linkLabel })">
<span
v-if="(!collapsed || orientation !== 'vertical') && (get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label` : 'item-label'])"
:class="ui.linkLabel({ class: props.ui?.linkLabel })"
>
<slot :name="item.slot ? `${item.slot}-label` : 'item-label'" :item="(item as T)" :active="active" :index="index">
{{ get(item, props.labelKey as string) }}
</slot>

<UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.linkLabelExternalIcon({ class: props.ui?.linkLabelExternalIcon, active })" />
</span>

<span v-if="item.badge || (orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])) || (orientation === 'vertical' && item.children?.length) || item.trailingIcon || !!slots[item.slot ? `${item.slot}-trailing` : 'item-trailing']" :class="ui.linkTrailing({ class: props.ui?.linkTrailing })">
<span v-if="(!collapsed || orientation !== 'vertical') && (item.badge || (orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])) || (orientation === 'vertical' && item.children?.length) || item.trailingIcon || !!slots[item.slot ? `${item.slot}-trailing` : 'item-trailing'])" :class="ui.linkTrailing({ class: props.ui?.linkTrailing })">
<slot :name="item.slot ? `${item.slot}-trailing` : 'item-trailing'" :item="(item as T)" :active="active" :index="index">
<UBadge
v-if="item.badge"
Expand All @@ -216,7 +226,7 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
</slot>
</DefineItemTemplate>

<NavigationMenuRoot v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })">
<NavigationMenuRoot v-bind="rootProps" :data-collapsed="collapsed" :class="ui.root({ class: [props.class, props.ui?.root] })">
<template v-for="(list, listIndex) in lists" :key="`list-${listIndex}`">
<NavigationMenuList :class="ui.list({ class: props.ui?.list })">
<component
Expand Down
20 changes: 17 additions & 3 deletions src/theme/navigation-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ export default (options: Required<ModuleOptions>) => ({
},
vertical: {
root: 'flex-col',
link: 'flex-row px-2.5 py-1.5 before:inset-y-px before:inset-x-0',
childList: 'ms-5 border-s border-[var(--ui-border)]',
childItem: 'ps-1.5 -ms-px'
link: 'flex-row px-2.5 py-1.5 before:inset-y-px before:inset-x-0'
}
},
active: {
Expand All @@ -87,6 +85,9 @@ export default (options: Required<ModuleOptions>) => ({
},
level: {
true: ''
},
collapsed: {
true: ''
}
},
compoundVariants: [{
Expand Down Expand Up @@ -216,6 +217,19 @@ export default (options: Required<ModuleOptions>) => ({
class: {
link: 'after:bg-[var(--ui-bg-inverted)]'
}
}, {
orientation: 'vertical',
collapsed: false,
class: {
childList: 'ms-5 border-s border-[var(--ui-border)]',
childItem: 'ps-1.5 -ms-px'
}
}, {
orientation: 'vertical',
collapsed: true,
class: {
link: 'px-1.5'
}
}],
defaultVariants: {
color: 'primary',
Expand Down
Loading

0 comments on commit 3fc2210

Please sign in to comment.