Fixed #1244 - Templating for Menus

pull/1281/head
Cagatay Civici 2021-05-17 14:58:53 +03:00
parent eb32efc9e1
commit d7c01c8f6e
33 changed files with 482 additions and 121 deletions

View File

@ -13,10 +13,18 @@ const BreadcrumbProps = [
}
];
const BreadcrumbSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
breadcrumb: {
name: "Breadcrumb",
description: "Breadcrumb provides contextual information about page hierarchy.",
props: BreadcrumbProps
props: BreadcrumbProps,
slots: BreadcrumbSlots
}
};

View File

@ -31,10 +31,18 @@ const ContextMenuProps = [
}
];
const ContextMenuSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
contextmenu: {
name: "ContextMenu",
description: "ContextMenu displays an overlay menu on right click of its target.",
props: ContextMenuProps
props: ContextMenuProps,
slots: ContextMenuSlots
}
};

View File

@ -13,10 +13,18 @@ const MegaMenuProps = [
}
];
const MegaMenuSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
megamenu: {
name: "MegaMenu",
description: "MegaMenu is navigation component that displays submenus together.",
props: MegaMenuProps
props: MegaMenuProps,
slots: MegaMenuSlots
}
};

View File

@ -31,10 +31,18 @@ const MenuProps = [
}
];
const MenuSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
menu: {
name: "Menu",
description: "Menu is a navigation / command component that supports dynamic and static positioning.",
props: MenuProps
props: MenuProps,
slots: MenuSlots
}
};

View File

@ -15,6 +15,10 @@ const MenubarSlots = [
{
name: "end",
description: "Custom content after the content"
},
{
name: "item",
description: "Template of a menuitem."
}
];

View File

@ -7,10 +7,18 @@ const PanelMenuProps = [
}
];
const PanelMenuSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
panelmenu: {
name: "PanelMenu",
description: "PanelMenu is a hybrid of Accordion and Tree components",
props: PanelMenuProps
props: PanelMenuProps,
slots: PanelMenuSlots
}
};

View File

@ -19,10 +19,18 @@ const StepsProps = [
}
];
const StepsSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
steps: {
name: "steps",
description: "Steps components is an indicator for the steps in a wizard workflow.",
props: StepsProps
props: StepsProps,
slots: StepsSlots
}
};

View File

@ -13,10 +13,18 @@ const TabMenuProps = [
}
];
const TabMenuSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
tabmenu: {
name: "TabMenu",
description: "TabMenu is a navigation component that displays items as tab headers.",
props: TabMenuProps
props: TabMenuProps,
slots: TabMenuSlots
}
};

View File

@ -31,10 +31,18 @@ const TieredMenuProps = [
}
];
const TieredMenuSlots = [
{
name: "item",
description: "Template of a menuitem."
}
];
module.exports = {
tieredmenu: {
name: "TieredMenu",
description: "TieredMenu displays submenus in nested overlays.",
props: TieredMenuProps
props: TieredMenuProps,
slots: TieredMenuSlots
}
};

View File

@ -1,10 +1,10 @@
<template>
<nav class="p-breadcrumb p-component" aria-label="Breadcrumb">
<ul>
<BreadcrumbItem v-if="home" :item="home" class="p-breadcrumb-home" />
<BreadcrumbItem v-if="home" :item="home" class="p-breadcrumb-home" :template="$slots.item"/>
<template v-for="item of model" :key="item.label" >
<li class="p-breadcrumb-chevron pi pi-chevron-right"></li>
<BreadcrumbItem :item="item" />
<BreadcrumbItem :item="item" :template="$slots.item" />
</template>
</ul>
</nav>

View File

@ -1,15 +1,18 @@
<template>
<li :class="containerClass" v-if="visible()">
<router-link v-if="item.to" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" class="p-menuitem-link" @click="onClick($event, navigate)">
<template v-if="!template">
<router-link v-if="item.to" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" class="p-menuitem-link" @click="onClick($event, navigate)">
<span v-if="item.icon" :class="iconClass"></span>
<span v-if="item.label" class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url||'#'" class="p-menuitem-link" @click="onClick" :target="item.target">
<span v-if="item.icon" :class="iconClass"></span>
<span v-if="item.label" class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url||'#'" class="p-menuitem-link" @click="onClick" :target="item.target">
<span v-if="item.icon" :class="iconClass"></span>
<span v-if="item.label" class="p-menuitem-text">{{item.label}}</span>
</a>
</template>
<component v-else :is="template" :item="item"></component>
</li>
</template>
@ -17,7 +20,8 @@
export default {
name: 'BreadcrumbItem',
props: {
item: null
item: null,
template: null
},
methods: {
onClick(event, navigate) {

View File

@ -2,7 +2,7 @@
<Teleport :to="appendTo">
<transition name="p-contextmenu" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
<div :ref="containerRef" :class="containerClass" v-if="visible" v-bind="$attrs">
<ContextMenuSub :model="model" :root="true" @leaf-click="onLeafClick" />
<ContextMenuSub :model="model" :root="true" @leaf-click="onLeafClick" :template="$slots.item"/>
</div>
</transition>
</Teleport>

View File

@ -4,19 +4,22 @@
<template v-for="(item, i) of model" :key="item.label + i.toString()">
<li role="none" :class="getItemClass(item)" :style="item.style" v-if="visible(item) && !item.separator"
@mouseenter="onItemMouseEnter($event, item)">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onItemClick($event, item, navigate)" :class="getLinkClass(item)" v-ripple role="menuitem">
<template v-if="!template">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onItemClick($event, item, navigate)" :class="getLinkClass(item)" v-ripple role="menuitem">
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" @click="onItemClick($event, item)" v-ripple
:aria-haspopup="item.items != null" :aria-expanded="item === activeItem" role="menuitem" :tabindex="item.disabled ? null : '0'">
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
<span class="p-submenu-icon pi pi-angle-right" v-if="item.items"></span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" @click="onItemClick($event, item)" v-ripple
:aria-haspopup="item.items != null" :aria-expanded="item === activeItem" role="menuitem" :tabindex="item.disabled ? null : '0'">
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
<span class="p-submenu-icon pi pi-angle-right" v-if="item.items"></span>
</a>
<ContextMenuSub :model="item.items" v-if="visible(item) && item.items" :key="item.label + '_sub_'"
</template>
<component v-else :is="template" :item="item"></component>
<ContextMenuSub :model="item.items" v-if="visible(item) && item.items" :key="item.label + '_sub_'" :template="template"
@leaf-click="onLeafClick" :parentActive="item === activeItem" />
</li>
<li :class="['p-menu-separator', item.class]" :style="item.style" v-if="visible(item) && item.separator" :key="'separator' + i.toString()" role="separator"></li>
@ -44,6 +47,10 @@ export default {
parentActive: {
type: Boolean,
default: false
},
template: {
type: Object,
default: null
}
},
watch: {

View File

@ -4,18 +4,21 @@
<template v-for="(category,index) of model" :key="category.label + '_' + index">
<li v-if="visible(category)" :class="getCategoryClass(category)" :style="category.style"
@mouseenter="onCategoryMouseEnter($event, category)" role="none">
<router-link v-if="category.to && !category.disabled" :to="category.to" custom v-slot="{navigate, href}">
<a :href="href" :class="getLinkClass(category)" @click="onCategoryClick($event, category, navigate)" @keydown="onCategoryKeydown($event, category)" role="menuitem" v-ripple>
<template v-if="!$slots.item">
<router-link v-if="category.to && !category.disabled" :to="category.to" custom v-slot="{navigate, href}">
<a :href="href" :class="getLinkClass(category)" @click="onCategoryClick($event, category, navigate)" @keydown="onCategoryKeydown($event, category)" role="menuitem" v-ripple>
<span v-if="category.icon" :class="getCategoryIcon(category)"></span>
<span class="p-menuitem-text">{{category.label}}</span>
</a>
</router-link>
<a v-else :href="category.url" :class="getLinkClass(category)" :target="category.target" @click="onCategoryClick($event, category)" @keydown="onCategoryKeydown($event, category)"
role="menuitem" :aria-haspopup="category.items != null" :aria-expanded="category === activeItem" :tabindex="category.disabled ? null : '0'" v-ripple>
<span v-if="category.icon" :class="getCategoryIcon(category)"></span>
<span class="p-menuitem-text">{{category.label}}</span>
<span v-if="category.items" :class="getCategorySubMenuIcon()"></span>
</a>
</router-link>
<a v-else :href="category.url" :class="getLinkClass(category)" :target="category.target" @click="onCategoryClick($event, category)" @keydown="onCategoryKeydown($event, category)"
role="menuitem" :aria-haspopup="category.items != null" :aria-expanded="category === activeItem" :tabindex="category.disabled ? null : '0'" v-ripple>
<span v-if="category.icon" :class="getCategoryIcon(category)"></span>
<span class="p-menuitem-text">{{category.label}}</span>
<span v-if="category.items" :class="getCategorySubMenuIcon()"></span>
</a>
</template>
<component v-else :is="$slots.item" :item="item"></component>
<div class="p-megamenu-panel" v-if="category.items">
<div class="p-megamenu-grid">
<div v-for="(column,columnIndex) of category.items" :key="category.label + '_column_' + columnIndex" :class="getColumnClassName(category)">
@ -23,17 +26,20 @@
<li :class="getSubmenuHeaderClass(submenu)" :style="submenu.style" role="presentation">{{submenu.label}}</li>
<template v-for="(item, i) of submenu.items" :key="item.label + i.toString()">
<li role="none" :class="getSubmenuItemClass(item)" :style="item.style" v-if="visible(item) && !item.separator">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" :class="getLinkClass(item)" @click="onLeafClick($event, item, navigate)" role="menuitem" v-ripple>
<template v-if="!$slots.item">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" :class="getLinkClass(item)" @click="onLeafClick($event, item, navigate)" role="menuitem" v-ripple>
<span v-if="item.icon" :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" @click="onLeafClick($event, item)" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span v-if="item.icon" :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
<span :class="getSubmenuIcon()" v-if="item.items"></span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" @click="onLeafClick($event, item)" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span v-if="item.icon" :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
<span :class="getSubmenuIcon()" v-if="item.items"></span>
</a>
</template>
<component v-else :is="$slots.item" :item="item"></component>
</li>
<li :class="['p-menu-separator', item.class]" :style="item.style" v-if="visible(item) && item.separator" :key="'separator' + i.toString()" role="separator"></li>
</template>

View File

@ -5,14 +5,16 @@
<ul class="p-menu-list p-reset" role="menu">
<template v-for="(item, i) of model" :key="item.label + i.toString()">
<template v-if="item.items && visible(item) && !item.separator">
<li class="p-submenu-header" v-if="item.items">{{item.label}}</li>
<li class="p-submenu-header" v-if="item.items">
<slot name="item" :item="item">{{item.label}}</slot>
</li>
<template v-for="(child, j) of item.items" :key="child.label + i + j">
<Menuitem v-if="visible(child) && !child.separator" :item="child" @click="itemClick" />
<Menuitem v-if="visible(child) && !child.separator" :item="child" @click="itemClick" :template="$slots.item" />
<li v-else-if="visible(child) && child.separator" :class="['p-menu-separator', child.class]" :style="child.style" :key="'separator' + i + j" role="separator"></li>
</template>
</template>
<li v-else-if="visible(item) && item.separator" :class="['p-menu-separator', item.class]" :style="item.style" :key="'separator' + i.toString()" role="separator"></li>
<Menuitem v-else :key="item.label + i.toString()" :item="item" @click="itemClick" />
<Menuitem v-else :key="item.label + i.toString()" :item="item" @click="itemClick" :template="$slots.item" />
</template>
</ul>
</div>

View File

@ -1,15 +1,18 @@
<template>
<li :class="containerClass" role="none" :style="item.style" v-if="visible()">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onClick($event, navigate)" :class="linkClass" v-ripple role="menuitem">
<template v-if="!template">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onClick($event, navigate)" :class="linkClass" v-ripple role="menuitem">
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="linkClass" @click="onClick" :target="item.target" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="linkClass" @click="onClick" :target="item.target" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</template>
<component v-else :is="template" :item="item"></component>
</li>
</template>
@ -21,7 +24,8 @@ export default {
inheritAttrs: false,
emits: ['click'],
props: {
item: null
item: null,
template: null
},
methods: {
onClick(event, navigate) {

View File

@ -6,7 +6,7 @@
<a ref="menubutton" tabindex="0" class="p-menubar-button" @click="toggle($event)">
<i class="pi pi-bars" />
</a>
<MenubarSub ref="rootmenu" :model="model" :root="true" :mobileActive="mobileActive" @leaf-click="onLeafClick"/>
<MenubarSub ref="rootmenu" :model="model" :root="true" :mobileActive="mobileActive" @leaf-click="onLeafClick" :template="$slots.item"/>
<div class="p-menubar-end" v-if="$slots.end">
<slot name="end"></slot>
</div>

View File

@ -3,20 +3,23 @@
<template v-for="(item, i) of model" :key="item.label + i.toString()">
<li role="none" :class="getItemClass(item)" :style="item.style" v-if="visible(item) && !item.separator"
@mouseenter="onItemMouseEnter($event, item)">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onItemClick($event, item, navigate)" :class="getLinkClass(item)" v-ripple @keydown="onItemKeyDown($event, item)" role="menuitem">
<template v-if="!template">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onItemClick($event, item, navigate)" :class="getLinkClass(item)" v-ripple @keydown="onItemKeyDown($event, item)" role="menuitem">
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" :aria-haspopup="item.items != null" :aria-expanded="item === activeItem"
@click="onItemClick($event, item)" @keydown="onItemKeyDown($event, item)" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" :aria-haspopup="item.items != null" :aria-expanded="item === activeItem"
@click="onItemClick($event, item)" @keydown="onItemKeyDown($event, item)" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
<span :class="getSubmenuIcon()" v-if="item.items"></span>
</a>
<span :class="getSubmenuIcon()" v-if="item.items"></span>
</a>
</template>
<component v-else :is="template" :item="item"></component>
<MenubarSub :model="item.items" v-if="visible(item) && item.items" :key="item.label + '_sub_'" :mobileActive="mobileActive"
@leaf-click="onLeafClick" @keydown-item="onChildItemKeyDown" :parentActive="item === activeItem" />
@leaf-click="onLeafClick" @keydown-item="onChildItemKeyDown" :parentActive="item === activeItem" :template="template" />
</li>
<li :class="['p-menu-separator', item.class]" :style="item.style" v-if="visible(item) && item.separator" :key="'separator' + i.toString()" role="separator"></li>
</template>
@ -50,6 +53,10 @@ export default {
mobileActive: {
type: Boolean,
default: false
},
template: {
type: Object,
default: null
}
},
documentClickListener: null,

View File

@ -3,24 +3,27 @@
<template v-for="(item, index) of model" :key="item.label + '_' + index">
<div v-if="visible(item)" :class="getPanelClass(item)" :style="item.style">
<div :class="getHeaderClass(item)" :style="item.style">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" class="p-panelmenu-header-link" @click="onItemClick($event, item, navigate)" role="treeitem">
<template v-if="!$slots.item">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" class="p-panelmenu-header-link" @click="onItemClick($event, item, navigate)" role="treeitem">
<span v-if="item.icon" :class="getPanelIcon(item)"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" class="p-panelmenu-header-link" @click="onItemClick($event, item)" :tabindex="item.disabled ? null : '0'"
:aria-expanded="isActive(item)" :id="ariaId +'_header'" :aria-controls="ariaId +'_content'">
<span v-if="item.items" :class="getPanelToggleIcon(item)"></span>
<span v-if="item.icon" :class="getPanelIcon(item)"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" class="p-panelmenu-header-link" @click="onItemClick($event, item)" :tabindex="item.disabled ? null : '0'"
:aria-expanded="isActive(item)" :id="ariaId +'_header'" :aria-controls="ariaId +'_content'">
<span v-if="item.items" :class="getPanelToggleIcon(item)"></span>
<span v-if="item.icon" :class="getPanelIcon(item)"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</template>
<component v-else :is="$slots.item" :item="item"></component>
</div>
<transition name="p-toggleable-content">
<div class="p-toggleable-content" v-show="item === activeItem"
role="region" :id="ariaId +'_content' " :aria-labelledby="ariaId +'_header'">
<div class="p-panelmenu-content" v-if="item.items">
<PanelMenuSub :model="item.items" class="p-panelmenu-root-submenu" />
<PanelMenuSub :model="item.items" class="p-panelmenu-root-submenu" :template="$slots.item" />
</div>
</div>
</transition>

View File

@ -2,21 +2,24 @@
<ul class="p-submenu-list" role="tree">
<template v-for="(item, i) of model" :key="item.label + i.toString()">
<li role="none" :class="getItemClass(item)" :style="item.style" v-if="visible(item) && !item.separator">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" :class="getLinkClass(item)" @click="onItemClick($event, item, navigate)" role="treeitem" :aria-expanded="isActive(item)">
<template v-if="!template">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" :class="getLinkClass(item)" @click="onItemClick($event, item, navigate)" role="treeitem" :aria-expanded="isActive(item)">
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" @click="onItemClick($event, item)"
role="treeitem" :aria-expanded="isActive(item)" :tabindex="item.disabled ? null : '0'">
<span :class="getSubmenuIcon(item)" v-if="item.items"></span>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" @click="onItemClick($event, item)"
role="treeitem" :aria-expanded="isActive(item)" :tabindex="item.disabled ? null : '0'">
<span :class="getSubmenuIcon(item)" v-if="item.items"></span>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</template>
<component v-else :is="template" :item="item"></component>
<transition name="p-toggleable-content">
<div class="p-toggleable-content" v-show="item === activeItem">
<PanelMenuSub :model="item.items" v-if="visible(item) && item.items" :key="item.label + '_sub_'" />
<PanelMenuSub :model="item.items" v-if="visible(item) && item.items" :key="item.label + '_sub_'" :template="template" />
</div>
</transition>
</li>
@ -32,6 +35,10 @@ export default {
model: {
type: null,
default: null
},
template: {
type: Object,
default: null
}
},
data() {

View File

@ -3,16 +3,19 @@
<ul role="tablist">
<template v-for="(item,index) of model" :key="item.to">
<li v-if="visible(item)" :class="getItemClass(item)" :style="item.style" role="tab" :aria-selected="isActive(item)" :aria-expanded="isActive(item)">
<router-link :to="item.to" v-if="!isItemDisabled(item)" custom v-slot="{navigate, href}">
<a :href="href" class="p-menuitem-link" @click="onItemClick($event, item, navigate)" role="presentation">
<template v-if="!$slots.item">
<router-link :to="item.to" v-if="!isItemDisabled(item)" custom v-slot="{navigate, href}">
<a :href="href" class="p-menuitem-link" @click="onItemClick($event, item, navigate)" role="presentation">
<span class="p-steps-number">{{index + 1}}</span>
<span class="p-steps-title">{{item.label}}</span>
</a>
</router-link>
<span v-else class="p-menuitem-link" role="presentation">
<span class="p-steps-number">{{index + 1}}</span>
<span class="p-steps-title">{{item.label}}</span>
</a>
</router-link>
<span v-else class="p-menuitem-link" role="presentation">
<span class="p-steps-number">{{index + 1}}</span>
<span class="p-steps-title">{{item.label}}</span>
</span>
</span>
</template>
<component v-else :is="$slots.item" :item="item"></component>
</li>
</template>
</ul>

View File

@ -4,17 +4,23 @@
<template v-for="(item,i) of model" :key="item.label + '_' + i.toString()">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href, isActive, isExactActive}">
<li :class="getRouteItemClass(item,isActive,isExactActive)" :style="item.style" v-if="visible(item)" role="tab">
<a :href="href" class="p-menuitem-link" @click="onItemClick($event, item, navigate)" role="presentation" v-ripple>
<span :class="getItemIcon(item)" v-if="item.icon"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
<template v-if="!$slots.item">
<a :href="href" class="p-menuitem-link" @click="onItemClick($event, item, navigate)" role="presentation" v-ripple>
<span :class="getItemIcon(item)" v-if="item.icon"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</template>
<component v-else :is="$slots.item" :item="item"></component>
</li>
</router-link>
<li v-else-if="visible(item)" :class="getItemClass(item)" role="tab">
<a :href="item.url" class="p-menuitem-link" :target="item.target" @click="onItemClick($event, item)" role="presentation" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="getItemIcon(item)" v-if="item.icon"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
<template v-if="!$slots.item">
<a :href="item.url" class="p-menuitem-link" :target="item.target" @click="onItemClick($event, item)" role="presentation" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="getItemIcon(item)" v-if="item.icon"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</template>
<component v-else :is="$slots.item" :item="item"></component>
</li>
</template>
<li ref="inkbar" class="p-tabmenu-ink-bar"></li>
@ -38,15 +44,19 @@ export default {
default: true
}
},
timeout: null,
mounted() {
this.updateInkBar();
},
updated() {
this.updateInkBar();
},
beforeUnmount() {
clearTimeout(this.timeout);
},
watch: {
$route() {
setTimeout(() => this.updateInkBar(), 50);
this.timeout = setTimeout(() => this.updateInkBar(), 50);
}
},
methods: {

View File

@ -2,7 +2,7 @@
<Teleport :to="appendTo" :disabled="!popup">
<transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
<div :ref="containerRef" :class="containerClass" v-if="popup ? visible : true" v-bind="$attrs" @click="onOverlayClick">
<TieredMenuSub :model="model" :root="true" :popup="popup" @leaf-click="onLeafClick"/>
<TieredMenuSub :model="model" :root="true" :popup="popup" @leaf-click="onLeafClick" :template="$slots.item" />
</div>
</transition>
</Teleport>

View File

@ -3,19 +3,22 @@
<template v-for="(item, i) of model" :key="item.label + i.toString()">
<li :class="getItemClass(item)" :style="item.style" v-if="visible(item) && !item.separator"
@mouseenter="onItemMouseEnter($event, item)" role="none">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onItemClick($event, item, navigate)" :class="getLinkClass(item)" v-ripple @keydown="onItemKeyDown($event, item)" role="menuitem">
<template v-if="!template">
<router-link v-if="item.to && !item.disabled" :to="item.to" custom v-slot="{navigate, href}">
<a :href="href" @click="onItemClick($event, item, navigate)" :class="getLinkClass(item)" v-ripple @keydown="onItemKeyDown($event, item)" role="menuitem">
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" :aria-haspopup="item.items != null" :aria-expanded="item === activeItem"
@click="onItemClick($event, item)" @keydown="onItemKeyDown($event, item)" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
</router-link>
<a v-else :href="item.url" :class="getLinkClass(item)" :target="item.target" :aria-haspopup="item.items != null" :aria-expanded="item === activeItem"
@click="onItemClick($event, item)" @keydown="onItemKeyDown($event, item)" role="menuitem" :tabindex="item.disabled ? null : '0'" v-ripple>
<span :class="['p-menuitem-icon', item.icon]"></span>
<span class="p-menuitem-text">{{item.label}}</span>
<span class="p-submenu-icon pi pi-angle-right" v-if="item.items"></span>
</a>
<TieredMenuSub :model="item.items" v-if="visible(item) && item.items" :key="item.label + '_sub_'"
<span class="p-submenu-icon pi pi-angle-right" v-if="item.items"></span>
</a>
</template>
<component v-else :is="template" :item="item"></component>
<TieredMenuSub :model="item.items" v-if="visible(item) && item.items" :key="item.label + '_sub_'" :template="template"
@leaf-click="onLeafClick" @keydown-item="onChildItemKeyDown" :parentActive="item === activeItem" />
</li>
<li :class="['p-menu-separator', item.class]" :style="item.style" v-if="visible(item) && item.separator" :key="'separator' + i.toString()" role="separator"></li>
@ -46,6 +49,10 @@ export default {
parentActive: {
type: Boolean,
default: false
},
template: {
type: Object,
default: null
}
},
documentClickListener: null,

View File

@ -32,6 +32,17 @@ export default {
}
}
</code></pre>
<h5>Templating</h5>
<p>Breadcrumb offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;Breadcrumb :home="home" :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/Breadcrumb&gt;
</template>
</code></pre>
<h5>Properties</h5>
@ -63,6 +74,24 @@ export default {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">

View File

@ -183,6 +183,17 @@ export default {
}
}
</code></pre>
<h5>Templating</h5>
<p>ContextMenu offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;ContextMenu :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/ContextMenu&gt;
</template>
</code></pre>
<h5>Properties</h5>
@ -262,6 +273,24 @@ export default {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">

View File

@ -143,11 +143,16 @@ export default {
</code></pre>
<h5>Custom Content</h5>
<p>Any content inside the megamenu will be displayed on the right side by default. You may use ".p-megamenu-custom" style class to change the location of the content.</p>
<p>Any content inside the megamenu will be displayed on the right side by default. You may use ".p-megamenu-custom" style class to change the location of the content.
Additionally, MegaMenu offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.
</p>
<pre v-code><code><template v-pre>
&lt;MegaMenu :model="items"&gt;
&lt;InputText placeholder="Search" type="text" /&gt;
&lt;Button label="Logout" icon="pi pi-power-off" /&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/MegaMenu&gt;
</template>
</code></pre>
@ -181,6 +186,24 @@ export default {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">

View File

@ -84,6 +84,17 @@ toggle(event) {
this.$refs.menu.toggle(event);
}
</code></pre>
<h5>Templating</h5>
<p>Menu offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;Menu :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/Menu&gt;
</template>
</code></pre>
<h5>Properties</h5>
@ -164,6 +175,24 @@ toggle(event) {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">

View File

@ -155,12 +155,15 @@ export default {
</code></pre>
<h5>Custom Content</h5>
<p>Two slots named "start" and "end" are provided to embed content before or after the menubar.</p>
<p>Two slots named "start" and "end" are provided to embed content before or after the menubar. In additon Menubar, offers item customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;Menubar :model="items"&gt;
&lt;template #start&gt;
Before
&lt;/template&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;template #end&gt;
After
&lt;/template&gt;
@ -209,6 +212,10 @@ export default {
<td>end</td>
<td>-</td>
</tr>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>

View File

@ -141,6 +141,17 @@ export default {
}
}
</code></pre>
<h5>Templating</h5>
<p>PanelMenu offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;PanelMenu :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/PanelMenu&gt;
</template>
</code></pre>
<h5>Properties</h5>
@ -166,6 +177,24 @@ export default {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">

View File

@ -49,6 +49,17 @@ export default {
&lt;Steps :model="items" :readonly="false" /&gt;
&lt;router-view /&gt;
</code></pre>
<h5>Templating</h5>
<p>Steps offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;Steps :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/Steps&gt;
</template>
</code></pre>
<h5>Properties</h5>
@ -86,6 +97,24 @@ export default {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">

View File

@ -32,6 +32,17 @@ export default {
}
}
</code></pre>
<h5>Templating</h5>
<p>TabMenu offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;TabMenu :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/TabMenu&gt;
</template>
</code></pre>
<h5>Properties</h5>
@ -63,6 +74,24 @@ export default {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">

View File

@ -157,7 +157,7 @@ export default {
</code></pre>
<h5>Popup Mode</h5>
<h5>Popup Mode</h5>
<p>TieredMenu is inline by default whereas popup mode is supported by enabling popup property and calling toggle method with an event of the target.</p>
<pre v-code><code>
@ -171,6 +171,17 @@ toggle(event) {
this.$refs.menu.toggle(event);
}
</code></pre>
<h5>Templating</h5>
<p>TieredMenu offers content customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter.</p>
<pre v-code><code><template v-pre>
&lt;TieredMenu :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;a :href="item.url"&gt;{{item.label}}&lt;/a&gt;
&lt;/template&gt;
&lt;/TieredMenu&gt;
</template>
</code></pre>
<h5>Properties</h5>
@ -251,6 +262,24 @@ toggle(event) {
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>item</td>
<td>item: Menuitem instance</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">