Skip to content

Commit 9cf9f25

Browse files
committed
feat(NavigationMenu): add trigger type in items
1 parent 0236399 commit 9cf9f25

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

playground/app/pages/components/navigation-menu.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const items = [
4747
label: 'Components',
4848
icon: 'i-lucide-box',
4949
to: '/components/navigation-menu',
50+
type: 'trigger',
5051
active: true,
5152
defaultOpen: true,
5253
children: [{

src/runtime/components/NavigationMenu.vue

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ export interface NavigationMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cu
4242
trailingIcon?: string
4343
/**
4444
* The type of the item.
45-
* The `label` type only works on `vertical` orientation.
45+
* The `label` type is only displayed in `vertical` orientation.
46+
* The `trigger` type is used to force the item to be collapsible when its a link in `vertical` orientation.
4647
* @defaultValue 'link'
4748
*/
48-
type?: 'label' | 'link'
49+
type?: 'label' | 'trigger' | 'link'
4950
slot?: string
5051
/**
5152
* The value of the item. Avoid using `index` as the value to prevent conflicts in horizontal orientation with Reka UI.
@@ -300,21 +301,21 @@ function getAccordionDefaultValue(list: NavigationMenuItem[]) {
300301
<div v-if="orientation === 'vertical' && item.type === 'label' && !collapsed" :class="ui.label({ class: [props.ui?.label, item.ui?.label, item.class] })">
301302
<ReuseLinkTemplate :item="item" :index="index" />
302303
</div>
303-
<ULink v-else-if="item.type !== 'label'" v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item as Omit<NavigationMenuItem, 'type'>)" custom>
304+
<ULink v-else-if="item.type !== 'label'" v-slot="{ active, ...slotProps }" v-bind="(orientation === 'vertical' && item.children?.length && !collapsed && item.type === 'trigger') ? {} : pickLinkProps(item as Omit<NavigationMenuItem, 'type'>)" custom>
304305
<component
305306
:is="(orientation === 'horizontal' && (item.children?.length || !!slots[(item.slot ? `${item.slot}-content` : 'item-content') as keyof NavigationMenuSlots<T>])) ? NavigationMenuTrigger : ((orientation === 'vertical' && item.children?.length && !collapsed && !(slotProps as any).href) ? AccordionTrigger : NavigationMenuLink)"
306307
as-child
307-
:active="active"
308+
:active="active || item.active"
308309
:disabled="item.disabled"
309310
@select="item.onSelect"
310311
>
311312
<UPopover v-if="orientation === 'vertical' && collapsed && item.children?.length && (!!props.popover || !!item.popover)" v-bind="{ ...popoverProps, ...(typeof item.popover === 'boolean' ? {} : item.popover || {}) }" :ui="{ content: ui.content({ class: [props.ui?.content, item.ui?.content] }) }">
312-
<ULinkBase v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], active, disabled: !!item.disabled, level: level > 0 })">
313-
<ReuseLinkTemplate :item="item" :active="active" :index="index" />
313+
<ULinkBase v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], active: active || item.active, disabled: !!item.disabled, level: level > 0 })">
314+
<ReuseLinkTemplate :item="item" :active="active || item.active" :index="index" />
314315
</ULinkBase>
315316

316317
<template #content>
317-
<slot :name="((item.slot ? `${item.slot}-content` : 'item-content') as keyof NavigationMenuSlots<T>)" :item="item" :active="active" :index="index">
318+
<slot :name="((item.slot ? `${item.slot}-content` : 'item-content') as keyof NavigationMenuSlots<T>)" :item="item" :active="active || item.active" :index="index">
318319
<ul :class="ui.childList({ class: [props.ui?.childList, item.ui?.childList] })">
319320
<li :class="ui.childLabel({ class: [props.ui?.childLabel, item.ui?.childLabel] })">
320321
{{ get(item, props.labelKey as string) }}
@@ -339,17 +340,17 @@ function getAccordionDefaultValue(list: NavigationMenuItem[]) {
339340
</template>
340341
</UPopover>
341342
<UTooltip v-else-if="orientation === 'vertical' && collapsed && (!!props.tooltip || !!item.tooltip)" :text="get(item, props.labelKey as string)" v-bind="{ ...tooltipProps, ...(typeof item.tooltip === 'boolean' ? {} : item.tooltip || {}) }">
342-
<ULinkBase v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], active, disabled: !!item.disabled, level: level > 0 })">
343-
<ReuseLinkTemplate :item="item" :active="active" :index="index" />
343+
<ULinkBase v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], active: active || item.active, disabled: !!item.disabled, level: level > 0 })">
344+
<ReuseLinkTemplate :item="item" :active="active || item.active" :index="index" />
344345
</ULinkBase>
345346
</UTooltip>
346-
<ULinkBase v-else v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], active, disabled: !!item.disabled, level: orientation === 'horizontal' || level > 0 })">
347-
<ReuseLinkTemplate :item="item" :active="active" :index="index" />
347+
<ULinkBase v-else v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], active: active || item.active, disabled: !!item.disabled, level: orientation === 'horizontal' || level > 0 })">
348+
<ReuseLinkTemplate :item="item" :active="active || item.active" :index="index" />
348349
</ULinkBase>
349350
</component>
350351

351352
<NavigationMenuContent v-if="orientation === 'horizontal' && (item.children?.length || !!slots[(item.slot ? `${item.slot}-content` : 'item-content') as keyof NavigationMenuSlots<T>])" v-bind="contentProps" :class="ui.content({ class: [props.ui?.content, item.ui?.content] })">
352-
<slot :name="((item.slot ? `${item.slot}-content` : 'item-content') as keyof NavigationMenuSlots<T>)" :item="item" :active="active" :index="index">
353+
<slot :name="((item.slot ? `${item.slot}-content` : 'item-content') as keyof NavigationMenuSlots<T>)" :item="item" :active="active || item.active" :index="index">
353354
<ul :class="ui.childList({ class: [props.ui?.childList, item.ui?.childList] })">
354355
<li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: [props.ui?.childItem, item.ui?.childItem] })">
355356
<ULink v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>

0 commit comments

Comments
 (0)