Merge branch 'prod'

pull/4755/head^2
Cagatay Civici 2023-11-04 11:20:29 +03:00
commit b941287a83
9 changed files with 512 additions and 345 deletions

View File

@ -13,8 +13,8 @@ export default {
data() { data() {
return { return {
items: [ items: [
{ label: 'New', icon: 'pi pi-fw pi-plus' }, { label: 'New', icon: 'pi pi-plus' },
{ label: 'Delete', icon: 'pi pi-fw pi-trash' } { label: 'Search', icon: 'pi pi-search' }
], ],
code: { code: {
basic: ` basic: `
@ -32,8 +32,8 @@ export default {
data() { data() {
return { return {
items: [ items: [
{ label: 'New', icon: 'pi pi-fw pi-plus' }, { label: 'New', icon: 'pi pi-plus' },
{ label: 'Delete', icon: 'pi pi-fw pi-trash' } { label: 'Search', icon: 'pi pi-search' }
] ]
}; };
} }
@ -51,8 +51,8 @@ export default {
import { ref } from "vue"; import { ref } from "vue";
const items = ref([ const items = ref([
{ label: 'New', icon: 'pi pi-fw pi-plus' }, { label: 'New', icon: 'pi pi-plus' },
{ label: 'Delete', icon: 'pi pi-fw pi-trash' } { label: 'Search', icon: 'pi pi-search' }
]); ]);
<\/script> <\/script>
` `

105
doc/menu/CommandDoc.vue Normal file
View File

@ -0,0 +1,105 @@
<template>
<DocSectionText v-bind="$attrs">
<p>The <i>command</i> property defines the callback to run when an item is activated by click or a key event.</p>
</DocSectionText>
<div class="card flex justify-content-center">
<Menu :model="items" />
</div>
<DocSectionCode :code="code" />
</template>
<script>
export default {
data() {
return {
items: [
{
label: 'New',
icon: 'pi pi-plus',
command: () => {
this.$toast.add({ severity: 'success', summary: 'Success', detail: 'File created', life: 3000 });
}
},
{
label: 'Search',
icon: 'pi pi-search',
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Search Completed', detail: 'No results found', life: 3000 });
}
}
],
code: {
basic: `
<Menu :model="items" />
<Toast />
`,
options: `
<template>
<div class="card flex justify-content-center">
<Menu :model="items" />
<Toast />
</div>
</template>
<script>
export default {
data() {
return {
items: [
{
label: 'New',
icon: 'pi pi-plus',
command: () => {
this.$toast.add({ severity: 'success', summary: 'Success', detail: 'File created', life: 3000 });
}
},
{
label: 'Search',
icon: 'pi pi-search',
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Search Completed', detail: 'No results found', life: 3000 });
}
}
]
};
}
};
<\/script>
`,
composition: `
<template>
<div class="card flex justify-content-center">
<Menu :model="items" />
<Toast />
</div>
</template>
<script setup>
import { ref } from "vue";
import { useToast } from "primevue/usetoast";
const toast = useToast();
const items = ref([
{
label: 'New',
icon: 'pi pi-plus',
command: () => {
toast.add({ severity: 'success', summary: 'Success', detail: 'File created', life: 3000 });
}
},
{
label: 'Search',
icon: 'pi pi-search',
command: () => {
toast.add({ severity: 'warn', summary: 'Search Completed', detail: 'No results found', life: 3000 });
}
}
]);
<\/script>
`
}
};
}
};
</script>

View File

@ -1,6 +1,6 @@
<template> <template>
<DocSectionText v-bind="$attrs"> <DocSectionText v-bind="$attrs">
<p>Menu supports one level of nesting by defining children with <i>items</i> property.</p> <p>Menu supports single level of grouping by defining children with the <i>items</i> property.</p>
</DocSectionText> </DocSectionText>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items" /> <Menu :model="items" />
@ -14,21 +14,28 @@ export default {
return { return {
items: [ items: [
{ {
label: 'Options', label: 'Documents',
items: [ items: [
{ {
label: 'Update', label: 'New',
icon: 'pi pi-refresh', icon: 'pi pi-plus'
command: () => {
this.$toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
}, },
{ {
label: 'Delete', label: 'Search',
icon: 'pi pi-times', icon: 'pi pi-search'
command: () => { }
this.$toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 }); ]
} },
{
label: 'Profile',
items: [
{
label: 'Settings',
icon: 'pi pi-cog'
},
{
label: 'Logout',
icon: 'pi pi-sign-out'
} }
] ]
} }
@ -36,13 +43,11 @@ export default {
code: { code: {
basic: ` basic: `
<Menu :model="items" /> <Menu :model="items" />
<Toast />
`, `,
options: ` options: `
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items" /> <Menu :model="items" />
<Toast />
</div> </div>
</template> </template>
@ -52,21 +57,28 @@ export default {
return { return {
items: [ items: [
{ {
label: 'Options', label: 'Documents',
items: [ items: [
{ {
label: 'Update', label: 'New',
icon: 'pi pi-refresh', icon: 'pi pi-plus'
command: () => {
this.$toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
}, },
{ {
label: 'Delete', label: 'Search',
icon: 'pi pi-times', icon: 'pi pi-search'
command: () => { }
this.$toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 }); ]
} },
{
label: 'Profile',
items: [
{
label: 'Settings',
icon: 'pi pi-cog'
},
{
label: 'Logout',
icon: 'pi pi-sign-out'
} }
] ]
} }
@ -80,32 +92,36 @@ export default {
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items" /> <Menu :model="items" />
<Toast />
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { useToast } from "primevue/usetoast";
const toast = useToast();
const items = ref([ const items = ref([
{ {
label: 'Options', label: 'Documents',
items: [ items: [
{ {
label: 'Update', label: 'New',
icon: 'pi pi-refresh', icon: 'pi pi-plus'
command: () => {
toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
}, },
{ {
label: 'Delete', label: 'Search',
icon: 'pi pi-times', icon: 'pi pi-search'
command: () => { }
toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 }); ]
} },
{
label: 'Profile',
items: [
{
label: 'Settings',
icon: 'pi pi-cog'
},
{
label: 'Logout',
icon: 'pi pi-sign-out'
} }
] ]
} }

View File

@ -1,9 +1,9 @@
<template> <template>
<DocSectionText v-bind="$attrs"> <DocSectionText v-bind="$attrs">
<p>Popup mode is enabled by adding <i>popup</i> property and calling <i>toggle</i> method with an event of the target.</p> <p>Overlay mode is enabled by adding <i>popup</i> property and calling <i>toggle</i> function of the menu ref with an event of the target.</p>
</DocSectionText> </DocSectionText>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Button type="button" label="Toggle" @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" /> <Button type="button" icon="pi pi-ellipsis-v" plain @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="items" :popup="true" /> <Menu ref="menu" id="overlay_menu" :model="items" :popup="true" />
</div> </div>
<DocSectionCode :code="code" /> <DocSectionCode :code="code" />
@ -18,34 +18,26 @@ export default {
label: 'Options', label: 'Options',
items: [ items: [
{ {
label: 'Update', label: 'Refresh',
icon: 'pi pi-refresh', icon: 'pi pi-refresh'
command: () => {
this.$toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
}, },
{ {
label: 'Delete', label: 'Export',
icon: 'pi pi-times', icon: 'pi pi-upload'
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 });
}
} }
] ]
} }
], ],
code: { code: {
basic: ` basic: `
<Button type="button" label="Toggle" @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" /> <Button type="button" icon="pi pi-ellipsis-v" @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="items" :popup="true" /> <Menu ref="menu" id="overlay_menu" :model="items" :popup="true" />
<Toast />
`, `,
options: ` options: `
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Button type="button" label="Toggle" @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" /> <Button type="button" icon="pi pi-ellipsis-v" @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="items" :popup="true" /> <Menu ref="menu" id="overlay_menu" :model="items" :popup="true" />
<Toast />
</div> </div>
</template> </template>
@ -55,23 +47,12 @@ export default {
return { return {
items: [ items: [
{ {
label: 'Options', label: 'Refresh',
items: [ icon: 'pi pi-refresh'
{ },
label: 'Update', {
icon: 'pi pi-refresh', label: 'Export',
command: () => { icon: 'pi pi-upload'
this.$toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
},
{
label: 'Delete',
icon: 'pi pi-times',
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 });
}
}
]
} }
] ]
}; };
@ -79,46 +60,34 @@ export default {
methods: { methods: {
toggle(event) { toggle(event) {
this.$refs.menu.toggle(event); this.$refs.menu.toggle(event);
},
save() {
this.$toast.add({ severity: 'success', summary: 'Success', detail: 'Data Saved', life: 3000 });
} }
}, }
}; };
<\/script> <\/script>
`, `,
composition: ` composition: `
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Button type="button" label="Toggle" @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" /> <Button type="button" icon="pi pi-ellipsis-v" @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="items" :popup="true" /> <Menu ref="menu" id="overlay_menu" :model="items" :popup="true" />
<Toast />
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { useToast } from "primevue/usetoast";
const toast = useToast();
const menu = ref(); const menu = ref();
const items = ref([ const items = ref([
{ {
label: 'Options', label: 'Options',
items: [ items: [
{ {
label: 'Update', label: 'Refresh',
icon: 'pi pi-refresh', icon: 'pi pi-refresh'
command: () => {
toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
}, },
{ {
label: 'Delete', label: 'Export',
icon: 'pi pi-times', icon: 'pi pi-upload'
command: () => {
toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 });
}
} }
] ]
} }
@ -127,10 +96,6 @@ const items = ref([
const toggle = (event) => { const toggle = (event) => {
menu.value.toggle(event); menu.value.toggle(event);
}; };
const save = () => {
toast.add({severity: 'success', summary: 'Success', detail: 'Data Saved', life: 3000});
};
<\/script> <\/script>
` `
} }

View File

@ -1,27 +1,24 @@
<template> <template>
<DocSectionText v-bind="$attrs"> <DocSectionText v-bind="$attrs">
<p> <p>Items with navigation are defined with templating to be able to use a router link component, an external link or programmatic navigation.</p>
Since v3.33.0 the vue-router dependency of menu components is deprecated and templating should be used to define router links instead. This approach provides flexibility to be able to use any kind of router link component such as
<i>NuxtLink</i> or <i>router-link</i>. Here is an example with vue-router.
</p>
</DocSectionText> </DocSectionText>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items"> <Menu :model="items">
<template #item="{ label, item, props }"> <template #item="{ item, props }">
<router-link v-if="item.route" v-slot="routerProps" :to="item.route" custom> <router-link v-if="item.route" v-slot="{ href, navigate }" :to="item.route" custom>
<a :href="routerProps.href" v-bind="props.action" @click="routerProps.navigate"> <a :href="href" v-bind="props.action" @click="navigate">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</router-link> </router-link>
<a v-else :href="item.url" :target="item.target" v-bind="props.action"> <a v-else v-ripple :href="item.url" :target="item.target" v-bind="props.action">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</template> </template>
</Menu> </Menu>
</div> </div>
<DocSectionCode :code="code" /> <DocSectionCode :code="code" hideStackBlitz hideCodeSandbox />
</template> </template>
<script> <script>
@ -29,38 +26,25 @@ export default {
data() { data() {
return { return {
items: [ items: [
{
label: 'Options',
items: [
{
label: 'Update',
icon: 'pi pi-refresh',
command: () => {
this.$toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
},
{
label: 'Delete',
icon: 'pi pi-times',
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 });
}
}
]
},
{ {
label: 'Navigate', label: 'Navigate',
items: [ items: [
{ {
label: 'Vue Website', label: 'Router Link',
icon: 'pi pi-external-link', icon: 'pi pi-palette',
url: 'https://vuejs.org/', route: '/unstyled'
target: '_blank'
}, },
{ {
label: 'Upload', label: 'Programmatic',
icon: 'pi pi-upload', icon: 'pi pi-link',
route: '/fileupload' command: () => {
this.$router.push('/installation');
}
},
{
label: 'External',
icon: 'pi pi-external-link',
url: 'https://vuejs.org/'
} }
] ]
} }
@ -68,16 +52,16 @@ export default {
code: { code: {
basic: ` basic: `
<Menu :model="items"> <Menu :model="items">
<template #item="{ label, item, props }"> <template #item="{ item, props }">
<router-link v-if="item.route" v-slot="routerProps" :to="item.route" custom> <router-link v-if="item.route" v-slot="{ href, navigate }" :to="item.route" custom>
<a :href="routerProps.href" v-bind="props.action" @click="routerProps.navigate"> <a :href="href" v-bind="props.action" @click="navigate">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</router-link> </router-link>
<a v-else :href="item.url" v-bind="props.action"> <a v-else v-ripple :href="item.url" :target="item.target" v-bind="props.action">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</template> </template>
</Menu> </Menu>
@ -86,20 +70,19 @@ export default {
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items"> <Menu :model="items">
<template #item="{ label, item, props }"> <template #item="{ item, props }">
<router-link v-if="item.route" v-slot="routerProps" :to="item.route" custom> <router-link v-if="item.route" v-slot="{ href, navigate }" :to="item.route" custom>
<a :href="routerProps.href" v-bind="props.action" @click="routerProps.navigate"> <a :href="href" v-bind="props.action" @click="navigate">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</router-link> </router-link>
<a v-else :href="item.url" v-bind="props.action"> <a v-else v-ripple :href="item.url" :target="item.target" v-bind="props.action">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</template> </template>
</Menu> </Menu>
<Toast />
</div> </div>
</template> </template>
@ -109,40 +92,21 @@ export default {
return { return {
items: [ items: [
{ {
label: 'Options', label: 'Router Link',
items: [ icon: 'pi pi-palette',
{ route: '/unstyled'
label: 'Update',
icon: 'pi pi-refresh',
command: () => {
this.$toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
},
{
label: 'Delete',
icon: 'pi pi-times',
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 });
}
}
]
}, },
{ {
label: 'Navigate', label: 'Programmatic',
items: [ icon: 'pi pi-link',
{ command: () => {
label: 'Vue Website', this.$router.push('/installation');
icon: 'pi pi-external-link', }
url: 'https://vuejs.org/', },
target: '_blank', {
}, label: 'External',
{ icon: 'pi pi-external-link',
label: 'Upload', url: 'https://vuejs.org/'
icon: 'pi pi-upload',
route: '/fileupload'
}
]
} }
] ]
}; };
@ -154,62 +118,45 @@ export default {
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items"> <Menu :model="items">
<template #item="{ label, item, props }"> <template #item="{ item, props }">
<router-link v-if="item.route" v-slot="routerProps" :to="item.route" custom> <router-link v-if="item.route" v-slot="{ href, navigate }" :to="item.route" custom>
<a :href="routerProps.href" v-bind="props.action"> <a :href="href" v-bind="props.action" @click="navigate">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</router-link> </router-link>
<a v-else :href="item.url" v-bind="props.action"> <a v-else v-ripple :href="item.url" :target="item.target" v-bind="props.action">
<span v-bind="props.icon" /> <span :class="item.icon" />
<span v-bind="props.label">{{ label }}</span> <span class="ml-2">{{ item.label }}</span>
</a> </a>
</template> </template>
</Menu> </Menu>
<Toast />
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { useRouter } from "vue";
const router = useRouter();
const items = ref([ const items = ref([
{ {
label: 'Options', label: 'Router Link',
items: [ icon: 'pi pi-palette',
{ route: '/unstyled'
label: 'Update',
icon: 'pi pi-refresh',
command: () => {
this.$toast.add({ severity: 'success', summary: 'Updated', detail: 'Data Updated', life: 3000 });
}
},
{
label: 'Delete',
icon: 'pi pi-times',
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Delete', detail: 'Data Deleted', life: 3000 });
}
}
]
}, },
{ {
label: 'Navigate', label: 'Programmatic',
items: [ icon: 'pi pi-link',
{ command: () => {
label: 'Vue Website', this.$router.push('/installation');
icon: 'pi pi-external-link', }
url: 'https://vuejs.org/', },
target: '_blank', {
}, label: 'External',
{ icon: 'pi pi-external-link',
label: 'Upload', url: 'https://vuejs.org/'
icon: 'pi pi-upload',
route: '/fileupload'
}
]
} }
]); ]);
<\/script> <\/script>

View File

@ -1,32 +1,45 @@
<template> <template>
<DocSectionText v-bind="$attrs"> <DocSectionText v-bind="$attrs">
<p> <p>
Menu offers item customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter. When item templating is used, it is suggested to bind the <i>action</i> prop from the slot props to handle Menu offers item customization with the <i>item</i> template that receives the menuitem instance from the model as a parameter. When item templating is used, bind the <i>action</i> prop from the slot props to handle accessibility and pass
accessibility and pass through attributes. Additionally, two slots named <i>start</i> and <i>end</i> are provided to embed content before or after the menu. through attributes. The submenu header has its own <i>submenuheader</i> template and additional slots named <i>start</i> and <i>end</i> are provided to embed content before or after the menu.
</p> </p>
</DocSectionText> </DocSectionText>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items"> <Menu :model="items" class="w-full md:w-15rem">
<template #start> <template #start>
<button @click="profileClick" class="w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround"> <span class="inline-flex align-items-center gap-1 px-2 py-2">
<Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" class="mr-2" shape="circle" /> <svg width="35" height="40" viewBox="0 0 35 40" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2rem">
<div class="flex flex-column align"> <path
<span class="font-bold">Amy Elsner</span> d="M25.87 18.05L23.16 17.45L25.27 20.46V29.78L32.49 23.76V13.53L29.18 14.73L25.87 18.04V18.05ZM25.27 35.49L29.18 31.58V27.67L25.27 30.98V35.49ZM20.16 17.14H20.03H20.17H20.16ZM30.1 5.19L34.89 4.81L33.08 12.33L24.1 15.67L30.08 5.2L30.1 5.19ZM5.72 14.74L2.41 13.54V23.77L9.63 29.79V20.47L11.74 17.46L9.03 18.06L5.72 14.75V14.74ZM9.63 30.98L5.72 27.67V31.58L9.63 35.49V30.98ZM4.8 5.2L10.78 15.67L1.81 12.33L0 4.81L4.79 5.19L4.8 5.2ZM24.37 21.05V34.59L22.56 37.29L20.46 39.4H14.44L12.34 37.29L10.53 34.59V21.05L12.42 18.23L17.45 26.8L22.48 18.23L24.37 21.05ZM22.85 0L22.57 0.69L17.45 13.08L12.33 0.69L12.05 0H22.85Z"
<span class="text-sm">Agent</span> fill="var(--primary-color)"
</div> />
</button> <path
d="M30.69 4.21L24.37 4.81L22.57 0.69L22.86 0H26.48L30.69 4.21ZM23.75 5.67L22.66 3.08L18.05 14.24V17.14H19.7H20.03H20.16H20.2L24.1 15.7L30.11 5.19L23.75 5.67ZM4.21002 4.21L10.53 4.81L12.33 0.69L12.05 0H8.43002L4.22002 4.21H4.21002ZM21.9 17.4L20.6 18.2H14.3L13 17.4L12.4 18.2L12.42 18.23L17.45 26.8L22.48 18.23L22.5 18.2L21.9 17.4ZM4.79002 5.19L10.8 15.7L14.7 17.14H14.74H15.2H16.85V14.24L12.24 3.09L11.15 5.68L4.79002 5.2V5.19Z"
fill="var(--text-color)"
/>
</svg>
<span class="font-medium text-xl font-semibold">PRIME<span class="text-primary">APP</span></span>
</span>
</template> </template>
<template #item="{ item, label, props }"> <template #submenuheader="{ item }">
<a class="flex" v-bind="props.action"> <span class="text-primary font-bold">{{ item.label }}</span>
<span v-bind="props.icon" /> </template>
<span v-bind="props.label">{{ label }}</span> <template #item="{ item, props }">
<a v-ripple class="flex align-items-center" v-bind="props.action">
<span :class="item.icon" />
<span class="ml-2">{{ item.label }}</span>
<Badge v-if="item.badge" class="ml-auto" :value="item.badge" /> <Badge v-if="item.badge" class="ml-auto" :value="item.badge" />
<span v-if="item.shortcut" class="ml-auto border-1 surface-border border-round surface-100 text-sm p-1">{{ item.shortcut }}</span>
</a> </a>
</template> </template>
<template #end> <template #end>
<button class="w-full p-link flex align-items-center p-2 pl-4 text-color hover:surface-200 border-noround"> <button v-ripple class="relative overflow-hidden w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround">
<i class="pi pi-sign-out" /> <Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" class="mr-2" shape="circle" />
<span class="ml-2">Log Out</span> <span class="inline-flex flex-column">
<span class="font-bold">Amy Elsner</span>
<span class="text-sm">Admin</span>
</span>
</button> </button>
</template> </template>
</Menu> </Menu>
@ -39,41 +52,78 @@ export default {
data() { data() {
return { return {
items: [ items: [
{ separator: true }, {
separator: true
},
{
label: 'Documents',
items: [
{
label: 'New',
icon: 'pi pi-plus',
shortcut: '⌘+N'
},
{
label: 'Search',
icon: 'pi pi-search',
shortcut: '⌘+S'
}
]
},
{ {
label: 'Profile', label: 'Profile',
icon: 'pi pi-fw pi-user' items: [
{
label: 'Settings',
icon: 'pi pi-cog',
shortcut: '⌘+O'
},
{
label: 'Messages',
icon: 'pi pi-inbox',
badge: 2
},
{
label: 'Logout',
icon: 'pi pi-sign-out',
shortcut: '⌘+Q'
}
]
}, },
{ {
label: 'Settings', separator: true
icon: 'pi pi-fw pi-cog', }
badge: 2
},
{ separator: true }
], ],
code: { code: {
basic: ` basic: `
<Menu :model="items"> <Menu :model="items" class="w-full md:w-15rem">
<template #start> <template #start>
<button @click="profileClick" class="w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround"> <span class="inline-flex align-items-center gap-1 px-2 py-2">
<Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" class="mr-2" shape="circle" /> <svg width="35" height="40" viewBox="0 0 35 40" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2rem">
<div class="flex flex-column align"> <path d="..." fill="var(--primary-color)" />
<span class="font-bold">Amy Elsner</span> <path d="..." fill="var(--text-color)" />
<span class="text-sm">Agent</span> </svg>
</div> <span class="font-medium text-xl font-semibold">PRIME<span class="text-primary">APP</span></span>
</button> </span>
</template> </template>
<template #item="{ item, label, props }"> <template #submenuheader="{ item }">
<a class="flex" v-bind="props.action"> <span class="text-primary font-bold">{{ item.label }}</span>
<span v-bind="props.icon" /> </template>
<span v-bind="props.label">{{ label }}</span> <template #item="{ item, props }">
<a v-ripple class="flex align-items-center" v-bind="props.action">
<span :class="item.icon" />
<span class="ml-2">{{ item.label }}</span>
<Badge v-if="item.badge" class="ml-auto" :value="item.badge" /> <Badge v-if="item.badge" class="ml-auto" :value="item.badge" />
<span v-if="item.shortcut" class="ml-auto border-1 surface-border border-round surface-100 text-sm p-1">{{ item.shortcut }}</span>
</a> </a>
</template> </template>
<template #end> <template #end>
<button class="w-full p-link flex align-items-center p-2 pl-4 text-color hover:surface-200 border-noround"> <button v-ripple class="relative overflow-hidden w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround">
<i class="pi pi-sign-out" /> <Avatar image="/images/avatar/amyelsner.png" class="mr-2" shape="circle" />
<span class="ml-2">Log Out</span> <span class="inline-flex flex-column">
<span class="font-bold">Amy Elsner</span>
<span class="text-sm">Admin</span>
</span>
</button> </button>
</template> </template>
</Menu> </Menu>
@ -81,31 +131,43 @@ export default {
options: ` options: `
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items"> <Menu :model="items" class="w-full md:w-15rem">
<template #start> <template #start>
<button @click="profileClick" class="w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround"> <span class="inline-flex align-items-center gap-1 px-2 py-2">
<Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" class="mr-2" shape="circle" /> <svg width="35" height="40" viewBox="0 0 35 40" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2rem">
<div class="flex flex-column align"> <path
<span class="font-bold">Amy Elsner</span> d="M25.87 18.05L23.16 17.45L25.27 20.46V29.78L32.49 23.76V13.53L29.18 14.73L25.87 18.04V18.05ZM25.27 35.49L29.18 31.58V27.67L25.27 30.98V35.49ZM20.16 17.14H20.03H20.17H20.16ZM30.1 5.19L34.89 4.81L33.08 12.33L24.1 15.67L30.08 5.2L30.1 5.19ZM5.72 14.74L2.41 13.54V23.77L9.63 29.79V20.47L11.74 17.46L9.03 18.06L5.72 14.75V14.74ZM9.63 30.98L5.72 27.67V31.58L9.63 35.49V30.98ZM4.8 5.2L10.78 15.67L1.81 12.33L0 4.81L4.79 5.19L4.8 5.2ZM24.37 21.05V34.59L22.56 37.29L20.46 39.4H14.44L12.34 37.29L10.53 34.59V21.05L12.42 18.23L17.45 26.8L22.48 18.23L24.37 21.05ZM22.85 0L22.57 0.69L17.45 13.08L12.33 0.69L12.05 0H22.85Z"
<span class="text-sm">Agent</span> fill="var(--primary-color)"
</div> />
</button> <path
d="M30.69 4.21L24.37 4.81L22.57 0.69L22.86 0H26.48L30.69 4.21ZM23.75 5.67L22.66 3.08L18.05 14.24V17.14H19.7H20.03H20.16H20.2L24.1 15.7L30.11 5.19L23.75 5.67ZM4.21002 4.21L10.53 4.81L12.33 0.69L12.05 0H8.43002L4.22002 4.21H4.21002ZM21.9 17.4L20.6 18.2H14.3L13 17.4L12.4 18.2L12.42 18.23L17.45 26.8L22.48 18.23L22.5 18.2L21.9 17.4ZM4.79002 5.19L10.8 15.7L14.7 17.14H14.74H15.2H16.85V14.24L12.24 3.09L11.15 5.68L4.79002 5.2V5.19Z"
fill="var(--text-color)"
/>
</svg>
<span class="font-medium text-xl font-semibold">PRIME<span class="text-primary">APP</span></span>
</span>
</template> </template>
<template #item="{ item, label, props }"> <template #submenuheader="{ item }">
<a class="flex" v-bind="props.action"> <span class="text-primary font-bold">{{ item.label }}</span>
<span v-bind="props.icon" /> </template>
<span v-bind="props.label">{{ label }}</span> <template #item="{ item, props }">
<a v-ripple class="flex align-items-center" v-bind="props.action">
<span :class="item.icon" />
<span class="ml-2">{{ item.label }}</span>
<Badge v-if="item.badge" class="ml-auto" :value="item.badge" /> <Badge v-if="item.badge" class="ml-auto" :value="item.badge" />
<span v-if="item.shortcut" class="ml-auto border-1 surface-border border-round surface-100 text-sm p-1">{{ item.shortcut }}</span>
</a> </a>
</template> </template>
<template #end> <template #end>
<button class="w-full p-link flex align-items-center p-2 pl-4 text-color hover:surface-200 border-noround"> <button v-ripple class="relative overflow-hidden w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround">
<i class="pi pi-sign-out" /> <Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" class="mr-2" shape="circle" />
<span class="ml-2">Log Out</span> <span class="inline-flex flex-column">
<span class="font-bold">Amy Elsner</span>
<span class="text-sm">Admin</span>
</span>
</button> </button>
</template> </template>
</Menu> </Menu>
<Toast />
</div> </div>
</template> </template>
@ -114,24 +176,49 @@ export default {
data() { data() {
return { return {
items: [ items: [
{ separator: true }, {
separator: true
},
{
label: 'Documents',
items: [
{
label: 'New',
icon: 'pi pi-plus',
shortcut: '⌘+N'
},
{
label: 'Search',
icon: 'pi pi-search',
shortcut: '⌘+S'
}
]
},
{ {
label: 'Profile', label: 'Profile',
icon: 'pi pi-fw pi-user' items: [
{
label: 'Settings',
icon: 'pi pi-cog',
shortcut: '⌘+O'
},
{
label: 'Messages',
icon: 'pi pi-inbox',
badge: 2
},
{
label: 'Logout',
icon: 'pi pi-sign-out',
shortcut: '⌘+Q'
}
]
}, },
{ {
label: 'Settings', separator: true
icon: 'pi pi-fw pi-cog', }
badge: 2
},
{ separator: true }
] ]
}; };
},
methods: {
profileClick() {
this.toast.add({ severity: 'info', summary: 'Info', detail: 'Item Selected', life: 3000 });
}
} }
}; };
<\/script> <\/script>
@ -139,66 +226,96 @@ export default {
composition: ` composition: `
<template> <template>
<div class="card flex justify-content-center"> <div class="card flex justify-content-center">
<Menu :model="items"> <Menu :model="items" class="w-full md:w-15rem">
<template #start> <template #start>
<button @click="profileClick" class="w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround"> <span class="inline-flex align-items-center gap-1 px-2 py-2">
<Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" class="mr-2" shape="circle" /> <svg width="35" height="40" viewBox="0 0 35 40" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2rem">
<div class="flex flex-column align"> <path
<span class="font-bold">Amy Elsner</span> d="M25.87 18.05L23.16 17.45L25.27 20.46V29.78L32.49 23.76V13.53L29.18 14.73L25.87 18.04V18.05ZM25.27 35.49L29.18 31.58V27.67L25.27 30.98V35.49ZM20.16 17.14H20.03H20.17H20.16ZM30.1 5.19L34.89 4.81L33.08 12.33L24.1 15.67L30.08 5.2L30.1 5.19ZM5.72 14.74L2.41 13.54V23.77L9.63 29.79V20.47L11.74 17.46L9.03 18.06L5.72 14.75V14.74ZM9.63 30.98L5.72 27.67V31.58L9.63 35.49V30.98ZM4.8 5.2L10.78 15.67L1.81 12.33L0 4.81L4.79 5.19L4.8 5.2ZM24.37 21.05V34.59L22.56 37.29L20.46 39.4H14.44L12.34 37.29L10.53 34.59V21.05L12.42 18.23L17.45 26.8L22.48 18.23L24.37 21.05ZM22.85 0L22.57 0.69L17.45 13.08L12.33 0.69L12.05 0H22.85Z"
<span class="text-sm">Agent</span> fill="var(--primary-color)"
</div> />
</button> <path
d="M30.69 4.21L24.37 4.81L22.57 0.69L22.86 0H26.48L30.69 4.21ZM23.75 5.67L22.66 3.08L18.05 14.24V17.14H19.7H20.03H20.16H20.2L24.1 15.7L30.11 5.19L23.75 5.67ZM4.21002 4.21L10.53 4.81L12.33 0.69L12.05 0H8.43002L4.22002 4.21H4.21002ZM21.9 17.4L20.6 18.2H14.3L13 17.4L12.4 18.2L12.42 18.23L17.45 26.8L22.48 18.23L22.5 18.2L21.9 17.4ZM4.79002 5.19L10.8 15.7L14.7 17.14H14.74H15.2H16.85V14.24L12.24 3.09L11.15 5.68L4.79002 5.2V5.19Z"
fill="var(--text-color)"
/>
</svg>
<span class="font-medium text-xl font-semibold">PRIME<span class="text-primary">APP</span></span>
</span>
</template> </template>
<template #item="{ item, label, props }"> <template #submenuheader="{ item }">
<a class="flex" v-bind="props.action"> <span class="text-primary font-bold">{{ item.label }}</span>
<span v-bind="props.icon" /> </template>
<span v-bind="props.label">{{ label }}</span> <template #item="{ item, props }">
<a v-ripple class="flex align-items-center" v-bind="props.action">
<span :class="item.icon" />
<span class="ml-2">{{ item.label }}</span>
<Badge v-if="item.badge" class="ml-auto" :value="item.badge" /> <Badge v-if="item.badge" class="ml-auto" :value="item.badge" />
<span v-if="item.shortcut" class="ml-auto border-1 surface-border border-round surface-100 text-sm p-1">{{ item.shortcut }}</span>
</a> </a>
</template> </template>
<template #end> <template #end>
<button class="w-full p-link flex align-items-center p-2 pl-4 text-color hover:surface-200 border-noround"> <button v-ripple class="relative overflow-hidden w-full p-link flex align-items-center p-2 pl-3 text-color hover:surface-200 border-noround">
<i class="pi pi-sign-out" /> <Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" class="mr-2" shape="circle" />
<span class="ml-2">Log Out</span> <span class="inline-flex flex-column">
<span class="font-bold">Amy Elsner</span>
<span class="text-sm">Admin</span>
</span>
</button> </button>
</template> </template>
</Menu> </Menu>
<Toast />
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { useToast } from "primevue/usetoast";
const items = ref([ const items = ref([
{ separator: true }, {
separator: true
},
{
label: 'Documents',
items: [
{
label: 'New',
icon: 'pi pi-plus',
shortcut: '⌘+N'
},
{
label: 'Search',
icon: 'pi pi-search',
shortcut: '⌘+S'
}
]
},
{ {
label: 'Profile', label: 'Profile',
icon: 'pi pi-fw pi-user' items: [
{
label: 'Settings',
icon: 'pi pi-cog',
shortcut: '⌘+O'
},
{
label: 'Messages',
icon: 'pi pi-inbox',
badge: 2
},
{
label: 'Logout',
icon: 'pi pi-sign-out',
shortcut: '⌘+Q'
}
]
}, },
{ {
label: 'Settings', separator: true
icon: 'pi pi-fw pi-cog', }
badge: 2
},
{ separator: true }
]); ]);
const toast = useToast();
const profileClick = () => {
toast.add({ severity: 'info', summary: 'Info', detail: 'Item Selected', life: 3000 });
}
<\/script> <\/script>
` `
} }
}; };
},
methods: {
profileClick() {
this.toast.add({ severity: 'info', summary: 'Info', detail: 'Item Selected', life: 3000 });
}
} }
}; };
</script> </script>

View File

@ -4,7 +4,7 @@
</DocSectionText> </DocSectionText>
<div class="card flex flex-column align-items-center"> <div class="card flex flex-column align-items-center">
<p>Scroll down the page to display the ScrollTop component.</p> <p>Scroll down the page to display the ScrollTop component.</p>
<i class="pi pi-angle-down fadeout animation-duration-1000 animation-iteration-infinite" style="fontsize: 2rem"></i> <i class="pi pi-angle-down fadeout animation-duration-1000 animation-iteration-infinite" style="fontsize: 2rem; margin-bottom: 30rem"></i>
<ScrollTop /> <ScrollTop />
</div> </div>
<DocSectionCode :code="code" /> <DocSectionCode :code="code" />

View File

@ -16,7 +16,7 @@
:threshold="100" :threshold="100"
icon="pi pi-arrow-up" icon="pi pi-arrow-up"
:pt="{ :pt="{
root: 'w-2rem h-2rem border-round-sm bg-primary hover:bg-primary', root: 'w-2rem h-2rem border-round-sm bg-primary',
icon: { icon: {
class: 'text-base' class: 'text-base'
} }
@ -33,7 +33,26 @@ export default {
return { return {
code: { code: {
basic: ` basic: `
<ScrollTop target="parent" :threshold="100" icon="pi pi-arrow-up" /> <ScrollPanel style="width: 250px; height: 200px">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae et leo duis ut diam. Ultricies mi quis hendrerit dolor magna eget est lorem. Amet consectetur adipiscing
elit ut. Nam libero justo laoreet sit amet. Pharetra massa massa ultricies mi quis hendrerit dolor magna. Est ultricies integer quis auctor elit sed vulputate. Consequat ac felis donec et. Tellus orci ac auctor augue mauris. Semper
feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Tincidunt arcu non sodales neque sodales. Metus aliquam eleifend mi in nulla posuere sollicitudin aliquam ultrices. Sodales ut etiam sit amet nisl purus. Cursus sit amet
dictum sit amet. Tristique senectus et netus et malesuada fames ac turpis egestas. Et tortor consequat id porta nibh venenatis cras sed. Diam maecenas ultricies mi eget mauris. Eget egestas purus viverra accumsan in nisl nisi.
Suscipit adipiscing bibendum est ultricies integer. Mattis aliquam faucibus purus in massa tempor nec.
</p>
<ScrollTop
target="parent"
:threshold="100"
icon="pi pi-arrow-up"
:pt="{
root: 'w-2rem h-2rem border-round-sm bg-primary',
icon: {
class: 'text-base'
}
}"
/>
</ScrollPanel>
`, `,
options: ` options: `
<template> <template>
@ -51,7 +70,7 @@ export default {
:threshold="100" :threshold="100"
icon="pi pi-arrow-up" icon="pi pi-arrow-up"
:pt="{ :pt="{
root: 'w-2rem h-2rem border-round-sm bg-primary hover:bg-primary', root: 'w-2rem h-2rem border-round-sm bg-primary',
icon: { icon: {
class: 'text-base' class: 'text-base'
} }
@ -77,7 +96,7 @@ export default {
:threshold="100" :threshold="100"
icon="pi pi-arrow-up" icon="pi pi-arrow-up"
:pt="{ :pt="{
root: 'w-2rem h-2rem border-round-sm bg-primary hover:bg-primary', root: 'w-2rem h-2rem border-round-sm bg-primary',
icon: { icon: {
class: 'text-base' class: 'text-base'
} }

View File

@ -1,18 +1,11 @@
<template> <template>
<DocComponent <DocComponent title="Vue Menu Component" header="Menu" description="Menu displays a list of items in vertical orientation." :componentDocs="docs" :apiDocs="['Menu', 'MenuItem']" :ptTabComponent="ptComponent" :themingDocs="themingDoc" />
title="Vue Menu Component"
header="Menu"
description="Menu is a navigation/command component that supports dynamic and static positioning."
:componentDocs="docs"
:apiDocs="['Menu', 'MenuItem']"
:ptTabComponent="ptComponent"
:themingDocs="themingDoc"
/>
</template> </template>
<script> <script>
import AccessibilityDoc from '@/doc/menu/AccessibilityDoc.vue'; import AccessibilityDoc from '@/doc/menu/AccessibilityDoc.vue';
import BasicDoc from '@/doc/menu/BasicDoc.vue'; import BasicDoc from '@/doc/menu/BasicDoc.vue';
import CommandDoc from '@/doc/menu/CommandDoc.vue';
import GroupDoc from '@/doc/menu/GroupDoc.vue'; import GroupDoc from '@/doc/menu/GroupDoc.vue';
import ImportDoc from '@/doc/menu/ImportDoc.vue'; import ImportDoc from '@/doc/menu/ImportDoc.vue';
import PopupDoc from '@/doc/menu/PopupDoc.vue'; import PopupDoc from '@/doc/menu/PopupDoc.vue';
@ -50,6 +43,11 @@ export default {
label: 'Template', label: 'Template',
component: TemplateDoc component: TemplateDoc
}, },
{
id: 'command',
label: 'Command',
component: CommandDoc
},
{ {
id: 'router', id: 'router',
label: 'Router', label: 'Router',