Closed agm1984 closed 2 years ago
I think this is related too https://github.com/primefaces/primevue/issues/1700
This also seems related: https://github.com/primefaces/primevue/issues/1741
I didn't notice until now, but in my reproducing example, the page gains a horizontal scrollbar when the menu subitems are expanded.
Duplicate #1700
I've been using the ContextMenu component instead of the TieredMenu component because it works properly when items would go off the screen:
But it has a problem where it loads relative to the mouse position rather than the button position, but I just managed to fix it by generating my own pointer event and passing that to the toggle
function:
Here is an example:
<script setup>
import { ref, reactive, computed } from 'vue';
import Button from 'primevue/button';
import ContextMenu from 'primevue/contextmenu';
const menu = ref();
const toggleMenu = () => {
const el = document.querySelector('#actions');
const coords = el.getBoundingClientRect();
const event = new PointerEvent('click', {
clientX: (coords.x + coords.width),
clientY: (coords.y + coords.height),
});
menu.value.toggle(event);
};
const menuItems = computed(() => ([
reactive({
label: 'Set status to',
icon: 'icon-logout',
items: [
{
label: 'Active',
},
{
label: 'On hold',
},
{
label: 'Terminated',
},
],
}),
reactive({
label: 'Add to program',
icon: 'icon-programs',
command: () => openAddToProgramModal(),
disabled: !employees.checkedRows.length,
}),
reactive({
label: 'Message',
icon: 'icon-message',
command: () => openMessageModal(),
disabled: !employees.checkedRows.length,
}),
reactive({
label: 'Customize columns',
icon: 'icon-settings',
command: () => openCustomizeColumnsModal(),
}),
]));
</script>
<template>
<Button
id="actions"
class="!ml-2 p-button-secondary"
icon="icon-chevron-down"
icon-pos="right"
label="Actions"
@click.stop.prevent="toggleMenu"
/>
<ContextMenu
ref="menu"
:model="menuItems"
/>
</template>
If you look close at @click.stop.prevent="toggleMenu"
, the stop propagation and preventDefault were important to making the menu show. It didn't work without adding those.
The only two pointer event properties you need are clientX
and clientY
. For some unknown reason, those are translated into pageX
and pageY
in the PrimeVue component.
The toggleMenu
is simply grabbing the button element co-ordinates and passing the bottom-right corner of the button to the ContextMenu component, and that causes the menu to load according to the button position rather than the true mouse position.
It is important to note that my solution is for when the button is close to the right-side of the screen. If you add this logic for a button that loads anywhere there is enough room for the menu-width, you will have to change the code to this:
const event = new PointerEvent('click', {
clientX: coords.x,
clientY: (coords.y + coords.height),
});
Describe the bug
When a TieredMenu item has subitems, the subitems load off the screen:
Here is a minimal reproduction: https://codesandbox.io/s/naughty-taussig-rtpl7s?file=/src/App.vue
Here is the code:
Reproducer
No response
PrimeVue version
3.12.6
Vue version
3.x
Language
ES6
Build / Runtime
Vite
Browser(s)
all
Steps to reproduce the behavior
Expected behavior
Submenu items should open on the left side of the menu when their position would go off the side of the viewport