pull/1533/head
Cagatay Civici 2021-08-31 15:00:07 +03:00
commit 28d33b0a5b
22 changed files with 337 additions and 82 deletions

View File

@ -28,6 +28,12 @@ const DockProps = [
type: "boolean",
default: "true",
description: "Whether to apply 'router-link-active-exact' class if route exactly matches the item path."
},
{
name: "tooltipOptions",
type: "object",
default: "null",
description: "Whether to display the tooltip on items. The modifiers of tooltip can be used like an object in it. Valid keys are 'event' and 'position'."
}
];

View File

@ -22,7 +22,7 @@ const ImageSlots = [
{
name: "indicator",
description: "Custom content for the preview indicator"
}-
}
];
module.exports = {

View File

@ -100,6 +100,12 @@ const SpeedDialProps = [
type: "any",
default: "null",
description: "Style class of the element."
},
{
name: "tooltipOptions",
type: "object",
default: "null",
description: "Whether to display the tooltip on items. The modifiers of tooltip can be used like an object in it. Valid keys are 'event' and 'position'."
}
];

View File

@ -10,6 +10,31 @@ const TabMenuProps = [
type: "boolean",
default: "true",
description: "Defines if active route highlight should match the exact route path."
},
{
name: "activeIndex",
type: "number",
default: "0",
description: "Active index of menuitem."
}
];
const TabMenuEvents = [
{
name: "tab-change",
description: "Callback to invoke when an active tab is changed.",
arguments: [
{
name: "event.originalEvent",
type: "object",
description: "Original event"
},
{
name: "event.index",
type: "number",
description: "Index of the selected tab"
}
]
}
];
@ -25,6 +50,7 @@ module.exports = {
name: "TabMenu",
description: "TabMenu is a navigation component that displays items as tab headers.",
props: TabMenuProps,
events: TabMenuEvents,
slots: TabMenuSlots
}
};

View File

@ -110,7 +110,7 @@ const VirtualScrollerSlots = [
{
name: "content",
description: "Custom content for the component"
}
},
{
name: "loader",
description: "Custom content for the loader items"

View File

@ -312,7 +312,7 @@ export default {
let right = 0;
let next = this.$el.nextElementSibling;
if (next) {
right = DomHandler.getOuterWidth(next) + parseFloat(next.style.left);
right = DomHandler.getOuterWidth(next) + parseFloat(next.style.right || 0);
}
this.styleObject.right = right + 'px';
}
@ -320,7 +320,7 @@ export default {
let left = 0;
let prev = this.$el.previousElementSibling;
if (prev) {
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left);
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left || 0);
}
this.styleObject.left = left + 'px';
}

View File

@ -156,7 +156,7 @@ export default {
let right = 0;
let next = this.$el.nextElementSibling;
if (next) {
right = DomHandler.getOuterWidth(next) + parseFloat(next.style.right);
right = DomHandler.getOuterWidth(next) + parseFloat(next.style.right || 0);
}
this.styleObject.right = right + 'px';
}
@ -164,7 +164,7 @@ export default {
let left = 0;
let prev = this.$el.previousElementSibling;
if (prev) {
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left);
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left || 0);
}
this.styleObject.left = left + 'px';
}

View File

@ -6,6 +6,7 @@ interface DockProps {
class?: string;
style?: any;
exact?: boolean;
tooltipOptions?: any;
}
declare class Dock {

View File

@ -1,6 +1,6 @@
<template>
<div :class="containerClass" :style="style">
<DockSub :model="model" :template="$slots.item" :exact="exact"></DockSub>
<DockSub :model="model" :template="$slots.item" :exact="exact" :tooltipOptions="tooltipOptions"></DockSub>
</div>
</template>
@ -17,6 +17,7 @@ export default {
model: null,
class: null,
style: null,
tooltipOptions: null,
exact: {
type: Boolean,
default: true

View File

@ -5,7 +5,7 @@
<template v-if="!template">
<router-link v-if="item.to && !disabled(item)" :to="item.to" custom v-slot="{navigate, href, isActive, isExactActive}">
<a :href="href" role="menuitem" :class="linkClass(item, {isActive, isExactActive})" :target="item.target"
:data-pr-tooltip="item.label" @click="onItemClick($event, item, navigate)">
v-tooltip:[tooltipOptions]="{value: item.label, disabled: !tooltipOptions}" @click="onItemClick($event, item, navigate)">
<template v-if="typeof item.icon === 'string'">
<span :class="['p-dock-action-icon', item.icon]" v-ripple></span>
</template>
@ -13,7 +13,7 @@
</a>
</router-link>
<a v-else :href="item.url" role="menuitem" :class="linkClass(item)" :target="item.target"
:data-pr-tooltip="item.label" @click="onItemClick($event, item)" :tabindex="disabled(item) ? null : '0'">
v-tooltip:[tooltipOptions]="{value: item.label, disabled: !tooltipOptions}" @click="onItemClick($event, item)" :tabindex="disabled(item) ? null : '0'">
<template v-if="typeof item.icon === 'string'">
<span :class="['p-dock-action-icon', item.icon]" v-ripple></span>
</template>
@ -41,7 +41,8 @@ export default {
exact: {
type: Boolean,
default: true
}
},
tooltipOptions: null
},
data() {
return {

View File

@ -18,6 +18,7 @@ interface SpeedDialProps {
rotateAnimation?: boolean;
class?: string;
style?: any;
tooltipOptions?: any;
}
declare class SpeedDial {

View File

@ -7,7 +7,7 @@
<li v-for="(item, index) of model" :key="index" class="p-speeddial-item" :style="getItemStyle(index)" role="none">
<template v-if="!$slots.item">
<a :href="item.url || '#'" role="menuitem" :class="['p-speeddial-action', { 'p-disabled': item.disabled }]" :target="item.target"
:data-pr-tooltip="item.label" @click="onItemClick($event, item)" v-ripple>
v-tooltip:[tooltipOptions]="{value: item.label, disabled: !tooltipOptions}" @click="onItemClick($event, item)" v-ripple>
<span v-if="item.icon" :class="['p-speeddial-action-icon', item.icon]"></span>
</a>
</template>
@ -73,6 +73,7 @@ export default {
type: Boolean,
default: true
},
tooltipOptions: null,
style: null,
class: null
},

View File

@ -3,6 +3,7 @@ import { VNode } from 'vue';
interface TabMenuProps {
model?: any[];
exact?: boolean;
activeIndex?: number;
}
declare class TabMenu {

View File

@ -5,7 +5,7 @@
<router-link v-if="item.to && !disabled(item)" :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">
<template v-if="!$slots.item">
<a :href="href" class="p-menuitem-link" @click="onItemClick($event, item, navigate)" role="presentation" v-ripple>
<a :href="href" class="p-menuitem-link" @click="onItemClick($event, item, i, navigate)" role="presentation" v-ripple>
<span :class="getItemIcon(item)" v-if="item.icon"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
@ -13,9 +13,9 @@
<component v-else :is="$slots.item" :item="item"></component>
</li>
</router-link>
<li v-else-if="visible(item)" :class="getItemClass(item)" role="tab">
<li v-else-if="visible(item)" :class="getItemClass(item, i)" role="tab">
<template v-if="!$slots.item">
<a :href="item.url" class="p-menuitem-link" :target="item.target" @click="onItemClick($event, item)" role="presentation" :tabindex="disabled(item) ? null : '0'" v-ripple>
<a :href="item.url" class="p-menuitem-link" :target="item.target" @click="onItemClick($event, item, i)" role="presentation" :tabindex="disabled(item) ? null : '0'" v-ripple>
<span :class="getItemIcon(item)" v-if="item.icon"></span>
<span class="p-menuitem-text">{{item.label}}</span>
</a>
@ -34,6 +34,7 @@ import Ripple from 'primevue/ripple';
export default {
name: 'TabMenu',
emits: ['update:activeIndex', 'tab-change'],
props: {
model: {
type: Array,
@ -42,9 +43,18 @@ export default {
exact: {
type: Boolean,
default: true
},
activeIndex: {
type: Number,
default: 0
}
},
timeout: null,
data() {
return {
d_activeIndex: this.activeIndex
}
},
mounted() {
this.updateInkBar();
},
@ -57,10 +67,13 @@ export default {
watch: {
$route() {
this.timeout = setTimeout(() => this.updateInkBar(), 50);
},
activeIndex(newValue) {
this.d_activeIndex = newValue;
}
},
methods: {
onItemClick(event, item, navigate) {
onItemClick(event, item, index, navigate) {
if (this.disabled(item)) {
event.preventDefault();
return;
@ -76,9 +89,20 @@ export default {
if (item.to && navigate) {
navigate(event);
}
if (index !== this.d_activeIndex) {
this.d_activeIndex = index;
this.$emit('update:activeIndex', this.d_activeIndex);
}
this.$emit('tab-change', {
originalEvent: event,
index: index
});
},
getItemClass(item) {
getItemClass(item, index) {
return ['p-tabmenuitem', item.class, {
'p-highlight': this.d_activeIndex === index,
'p-disabled': this.disabled(item)
}];
},

View File

@ -241,10 +241,27 @@ function getTarget(el) {
return DomHandler.hasClass(el, 'p-inputwrapper') ? DomHandler.findSingle(el, 'input'): el;
}
function getModifiers(options) {
// modifiers
if (options.modifiers && Object.keys(options.modifiers).length) {
return options.modifiers;
}
// arg
if (options.arg && typeof options.arg === 'object') {
return Object.entries(options.arg).reduce((acc, [key, val]) => {
if (key === 'event' || key === 'position') acc[val] = true;
return acc;
}, {});
}
return {};
}
const Tooltip = {
beforeMount(el, options) {
let target = getTarget(el);
target.$_ptooltipModifiers = options.modifiers;
target.$_ptooltipModifiers = getModifiers(options);
if (typeof options.value === 'string') {
target.$_ptooltipValue = options.value;
target.$_ptooltipDisabled = false;
@ -271,7 +288,7 @@ const Tooltip = {
},
updated(el, options) {
let target = getTarget(el);
target.$_ptooltipModifiers = options.modifiers;
target.$_ptooltipModifiers = getModifiers(options);
if (typeof options.value === 'string') {
target.$_ptooltipValue = options.value;
@ -281,8 +298,7 @@ const Tooltip = {
target.$_ptooltipValue = options.value.value;
target.$_ptooltipDisabled = options.value.disabled;
}
},
}
};
export default Tooltip;

View File

@ -89,6 +89,12 @@ import Dock from 'primevue/dock';
<td>true</td>
<td>Whether to apply 'router-link-active-exact' class if route exactly matches the item path.</td>
</tr>
<tr>
<td>tooltipOptions</td>
<td>object</td>
<td>null</td>
<td>Whether to display the tooltip on items. The modifiers of <router-link to="/tooltip">Tooltip</router-link> can be used like an object in it. Valid keys are 'event' and 'position'.</td>
</tr>
</tbody>
</table>
</div>

View File

@ -269,7 +269,7 @@ app.use(PrimeVue, {
<th>
<div class="p-d-flex p-ai-center">
<img src="../../assets/images//browsers/edge.svg" alt="edge" style="width: 1.5rem;" class="p-mr-2">
IE / Edge
Edge
</div>
</th>
<th>
@ -300,7 +300,7 @@ app.use(PrimeVue, {
</thead>
<tbody>
<tr>
<td>IE11, Edge</td>
<td>Edge</td>
<td>Last 2 versions</td>
<td>Last 2 versions</td>
<td>Last 2 versions</td>

View File

@ -37,9 +37,9 @@
<div class="card">
<h5>Tooltip</h5>
<div class="speeddial-tooltip-demo" :style="{ position: 'relative', height: '350px' }">
<SpeedDial :model="items" direction="up" class="speeddial-right" buttonClassName="p-button-danger" />
<SpeedDial :model="items" direction="up" class="speeddial-right" buttonClassName="p-button-danger" :tooltipOptions="{position: 'left'}" />
<SpeedDial :model="items" direction="up" class="speeddial-left" buttonClassName="p-button-help" />
<SpeedDial :model="items" direction="up" class="speeddial-left" buttonClassName="p-button-help" :tooltipOptions="{position: 'right'}" />
</div>
</div>

View File

@ -179,6 +179,12 @@ items: [
<td>null</td>
<td>Inline style of the element.</td>
</tr>
<tr>
<td>tooltipOptions</td>
<td>object</td>
<td>null</td>
<td>Whether to display the tooltip on items. The modifiers of <router-link to="/tooltip">Tooltip</router-link> can be used like an object in it. Valid keys are 'event' and 'position'.</td>
</tr>
</tbody>
</table>
</div>
@ -313,9 +319,9 @@ export default {
<div class="card">
<h5>Tooltip</h5>
<div class="speeddial-tooltip-demo" :style="{ position: 'relative', height: '350px' }">
<SpeedDial :model="items" direction="up" class="speeddial-right" buttonClassName="p-button-danger" />
<SpeedDial :model="items" direction="up" class="speeddial-right" buttonClassName="p-button-danger" :tooltipOptions="{position: 'left'}" />
<SpeedDial :model="items" direction="up" class="speeddial-left" buttonClassName="p-button-help" />
<SpeedDial :model="items" direction="up" class="speeddial-left" buttonClassName="p-button-help" :tooltipOptions="{position: 'right'}" />
</div>
</div>
@ -524,9 +530,9 @@ export default {
<div class="card">
<h5>Tooltip</h5>
<div class="speeddial-tooltip-demo" :style="{ position: 'relative', height: '350px' }">
<SpeedDial :model="items" direction="up" class="speeddial-right" buttonClassName="p-button-danger" />
<SpeedDial :model="items" direction="up" class="speeddial-right" buttonClassName="p-button-danger" :tooltipOptions="{position: 'left'}" />
<SpeedDial :model="items" direction="up" class="speeddial-left" buttonClassName="p-button-help" />
<SpeedDial :model="items" direction="up" class="speeddial-left" buttonClassName="p-button-help" :tooltipOptions="{position: 'right'}" />
</div>
</div>

View File

@ -11,11 +11,11 @@
<div class="p-fluid p-formgrid p-grid">
<div class="p-field p-col-12 p-md-6">
<label for="class">Class</label>
<Dropdown inputId="class" v-model="selectedClass" :options="classes" @change="setVagons($event)" optionLabel="name" placeholder="Select a Class" />
<Dropdown inputId="class" v-model="selectedClass" :options="classes" @change="setWagons($event)" optionLabel="name" placeholder="Select a Class" />
</div>
<div class="p-field p-col-12 p-md-6">
<label for="lastname">Wagon</label>
<Dropdown inputId="wagon" v-model="selectedVagon" :options="vagons" @change="setSeats($event)" optionLabel="vagon" placeholder="Select a Vagon" />
<Dropdown inputId="wagon" v-model="selectedWagon" :options="wagons" @change="setSeats($event)" optionLabel="wagon" placeholder="Select a Wagon" />
</div>
<div class="p-field p-col-12">
<label for="seat">Seat</label>
@ -43,24 +43,24 @@ export default {
{name: 'Second Class', code: 'B', factor: 2},
{name: 'Third Class', code: 'C', factor: 3}
],
vagons: [],
selectedVagon: '',
wagons: [],
selectedWagon: '',
seats: [],
selectedSeat: ''
}
},
methods: {
setVagons(event) {
setWagons(event) {
if (this.selectedClass && event.value) {
this.vagons = [];
this.wagons = [];
this.seats = [];
for (let i = 1; i < 3 * event.value.factor; i++) {
this.vagons.push({vagon: i + event.value.code, type: event.value.name, factor: event.value.factor});
this.wagons.push({wagon: i + event.value.code, type: event.value.name, factor: event.value.factor});
}
}
},
setSeats(event) {
if (this.selectedVagon && event.value) {
if (this.selectedWagon && event.value) {
this.seats = [];
for (let i = 1; i < 10 * event.value.factor; i++) {
this.seats.push({seat: i, type: event.value.type});
@ -68,7 +68,7 @@ export default {
}
},
nextPage() {
this.$emit('next-page', {formData: {class: this.selectedClass.name, vagon: this.selectedVagon.vagon, seat: this.selectedSeat.seat}, pageIndex: 1});
this.$emit('next-page', {formData: {class: this.selectedClass.name, wagon: this.selectedWagon.wagon, seat: this.selectedSeat.seat}, pageIndex: 1});
},
prevPage() {
this.$emit('prev-page', {pageIndex: 1});

View File

@ -10,9 +10,21 @@
<div class="content-section implementation">
<div class="card">
<h5>Default</h5>
<TabMenu :model="items" />
<router-view/>
</div>
<div class="card">
<h5>Programmatic</h5>
<div class="p-py-2">
<Button @click="active = 0" class="p-button-text" label="Activate 1st" />
<Button @click="active = 1" class="p-button-text p-mr-2" label="Activate 2nd" />
<Button @click="active = 2" class="p-button-text p-mr-2" label="Activate 3rd" />
</div>
<TabMenu :model="items2" v-model:activeIndex="active" />
</div>
</div>
<TabMenuDoc />
@ -25,12 +37,20 @@ import TabMenuDoc from './TabMenuDoc';
export default {
data() {
return {
active: 3,
items: [
{label: 'Home', icon: 'pi pi-fw pi-home', to: '/tabmenu'},
{label: 'Calendar', icon: 'pi pi-fw pi-calendar', to: '/tabmenu/calendar'},
{label: 'Edit', icon: 'pi pi-fw pi-pencil', to: '/tabmenu/edit'},
{label: 'Documentation', icon: 'pi pi-fw pi-file', to: '/tabmenu/documentation'},
{label: 'Settings', icon: 'pi pi-fw pi-cog', to: '/tabmenu/settings'}
],
items2: [
{label: 'Home', icon: 'pi pi-fw pi-home'},
{label: 'Calendar', icon: 'pi pi-fw pi-calendar'},
{label: 'Edit', icon: 'pi pi-fw pi-pencil'},
{label: 'Documentation', icon: 'pi pi-fw pi-file'},
{label: 'Settings', icon: 'pi pi-fw pi-cog'}
]
}
},

View File

@ -10,9 +10,32 @@ import TabMenu from 'primevue/tabmenu';
<p>TabMenu uses the common MenuModel API to define the items, visit <router-link to="/menumodel">MenuModel API</router-link> for details.</p>
<h5>Getting Started</h5>
<p>TabMenu is integrated with Vue Router and requires a collection of menuitems as its model.</p>
<p>TabMenu requires a collection of menuitems as its model.</p>
<pre v-code><code>
&lt;TabMenu :model="items" /&gt;
</code></pre>
<pre v-code.script><code>
export default {
data() {
return {
items: [
{label: 'Home', icon: 'pi pi-fw pi-home'},
{label: 'Calendar', icon: 'pi pi-fw pi-calendar'},
{label: 'Edit', icon: 'pi pi-fw pi-pencil'},
{label: 'Documentation', icon: 'pi pi-fw pi-file'},
{label: 'Settings', icon: 'pi pi-fw pi-cog'}
]
}
}
}
</code></pre>
<p>TabMenu can be also integrated with Vue Router.</p>
<pre v-code><code>
&lt;TabMenu :model="items" /&gt;
&lt;router-view /&gt;
</code></pre>
@ -32,10 +55,24 @@ export default {
}
}
</code></pre>
<h5>Active</h5>
<p>Visibility of the content is specified with the activeIndex property that supports one or two-way binding.</p>
<pre v-code><code>
&lt;TabMenu :model="items" :activeIndex="activeIndex" /&gt;
</code></pre>
<p>Two-way binding requires v-model.</p>
<pre v-code><code>
&lt;TabMenu :model="items" v-model:activeIndex="activeIndex" /&gt;
</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>
<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;
@ -69,6 +106,34 @@ export default {
<td>boolean</td>
<td>true</td>
<td>Defines if active route highlight should match the exact route path.</td>
</tr>
<tr>
<td>activeIndex</td>
<td>number</td>
<td>0</td>
<td>Active index of menuitem.</td>
</tr>
</tbody>
</table>
</div>
<h5>Events</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>tab-change</td>
<td>event.originalEvent: Browser event <br/>
event.index: Index of the selected tab
</td>
<td>Callback to invoke when an active tab is changed.</td>
</tr>
</tbody>
</table>
@ -146,8 +211,22 @@ export default {
content: `
<template>
<div>
<TabMenu :model="items" />
<router-view />
<div class="card">
<h5>Default</h5>
<TabMenu :model="items" />
<router-view/>
</div>
<div class="card">
<h5>Programmatic</h5>
<div class="p-py-2">
<Button @click="active = 0" class="p-button-text" label="Activate 1st" />
<Button @click="active = 1" class="p-button-text p-mr-2" label="Activate 2nd" />
<Button @click="active = 2" class="p-button-text p-mr-2" label="Activate 3rd" />
</div>
<TabMenu :model="items2" v-model:activeIndex="active" />
</div>
</div>
</template>
@ -155,6 +234,7 @@ export default {
export default {
data() {
return {
active: 3,
items: [
{
label: 'Home',
@ -181,6 +261,28 @@ export default {
icon: 'pi pi-fw pi-cog',
to: '/settings'
}
],
items2: [
{
label: 'Home',
icon: 'pi pi-fw pi-home'
},
{
label: 'Calendar',
icon: 'pi pi-fw pi-calendar'
},
{
label: 'Edit',
icon: 'pi pi-fw pi-pencil'
},
{
label: 'Documentation',
icon: 'pi pi-fw pi-file'
},
{
label: 'Settings',
icon: 'pi pi-fw pi-cog'
}
]
}
}
@ -198,8 +300,22 @@ export default {
content: `
<template>
<div>
<TabMenu :model="items" />
<router-view />
<div class="card">
<h5>Default</h5>
<TabMenu :model="items" />
<router-view/>
</div>
<div class="card">
<h5>Programmatic</h5>
<div class="p-py-2">
<Button @click="active = 0" class="p-button-text" label="Activate 1st" />
<Button @click="active = 1" class="p-button-text p-mr-2" label="Activate 2nd" />
<Button @click="active = 2" class="p-button-text p-mr-2" label="Activate 3rd" />
</div>
<TabMenu :model="items2" v-model:activeIndex="active" />
</div>
</div>
</template>
@ -208,6 +324,7 @@ import { ref } from 'vue';
export default {
setup() {
const active = ref(3);
const items = ref([
{
label: 'Home',
@ -235,8 +352,30 @@ export default {
to: '/settings'
}
]);
const items2 = ref([
{
label: 'Home',
icon: 'pi pi-fw pi-home'
},
{
label: 'Calendar',
icon: 'pi pi-fw pi-calendar'
},
{
label: 'Edit',
icon: 'pi pi-fw pi-pencil'
},
{
label: 'Documentation',
icon: 'pi pi-fw pi-file'
},
{
label: 'Settings',
icon: 'pi pi-fw pi-cog'
}
]);
return { items }
return { active, items, items2 }
}
}
<\\/script>