Comments (2)
Hi, thanks for the in-depth response. I investigated this further since posting the issue and eventually settled on handling which item was clicked myself.
On the context menu event, I'd pass the item that was right clicked to the event handler, where I stored it in a ref. Then, on the events that require the specific right clicked element, I just refer to that variable. Bit of a cheat, but very simple to understand at least 🤷♂️
Here's an updated PoC with that implemented: https://stackblitz.com/edit/nuxt-ui-6oeqq4
Thanks for you're suggestion regardless, your method would probably have been my next attempt!
from ui.
I think the problem might be the fact that you are binding the :virtual-element
prop to the same ref
in every iteration. This way the virtualElement
's value is actually the one you set in the last iteration of the v-for
, so it doesn't matter which ContextMenu
you click, it will be the one set in the last iteration, thus having the last item passed into the logClicked
function all the time.
I think what you might probably want to do is create different virtualElement
objects for your UContextMenu
components.
Not sure if this is what you wanted to achieve, but one solution could be to use an array to handle the different UContextMenu
s v-model
and virtualElement
attributes:
<template>
<UContainer class="min-h-screen flex items-center">
<UCard
@click="logClicked(item)"
v-for="(item, i) in items" // get the index, so you can bind the components
@contextmenu.prevent="() => onContextMenu(i)" // you can use the index to signal which ContextMenu triggered the event
:key="item"
class="flex-1"
:ui="{
background: 'bg-gray-50 dark:bg-gray-800/50',
ring: 'ring-1 ring-gray-300 dark:ring-gray-700',
divide: 'divide-y divide-gray-300 dark:divide-gray-700',
header: { base: 'font-bold' },
}"
>
<p>{{ item }}</p>
<UContextMenu v-model="isOpen[i]" :virtual-element="virtualElements[i]"> // bind it to the correct objects
<p class="hover:bg-gray-100 p-4" @click="logClicked(item)">Copy Link</p>
</UContextMenu>
</UCard>
</UContainer>
<UNotifications />
</template>
<script setup>
// Context Menu Setup
const { x, y } = useMouse();
const { y: windowY } = useWindowScroll();
const isOpen = ref([false, false, false]); // use an array to handle different ContextMenu open states
const virtualElements = ref([ // the same, just with the virtualElement attributes
{ getBoundingClientRect: () => ({}) },
{ getBoundingClientRect: () => ({}) },
{ getBoundingClientRect: () => ({}) },
]);
function onContextMenu(index) {
const top = unref(y) - unref(windowY);
const left = unref(x);
// set the correct ContextMenu virtualElement data
virtualElements.value[index].getBoundingClientRect = () => ({
width: 0,
height: 0,
top,
left,
});
isOpen.value[index] = true; // set the correct ContextMenus open state
}
// PoC Setup
const items = ['Item 1', 'Item 2', 'Item 3'];
const logClicked = (item) => {
console.log('The item that was clicked is: ' + item);
alert('The clicked item is: ' + item);
};
</script>
<style>
body {
@apply antialiased font-sans text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-900;
}
</style>
There might be other solutions, like refactoring out this component to its own component, having it own its state. For example, you could create a CopyLinkCard
component, that has it's own isOpen
and virtualElement
state and onContextMenu
function - that way you can be sure, that they are not going to interfere in a v-for
, meaning you can leave out the whole array and index stuff I just wrote before.
I hope this is what you were looking for and also hope my answer made sense.
from ui.
Related Issues (20)
- Vertical Carousel option
- Using Embla for Carousel
- automated UCarousel HOT 1
- Collaborators
- SelectMenu onBlur selects first item when searchable is true HOT 3
- [Dropdown] Prevent click from parent button. HOT 1
- No intellisense or types working in vscode? HOT 14
- useModal not working HOT 2
- Submit a form using a shortcut key HOT 1
- InputMenu increase padding when using backspace in Safari. HOT 2
- Possibility to change the loading icon position (left or right) HOT 4
- Why is my tooltip's overflow hidden and the background transparent? HOT 12
- Opening multiple slideover closes the previous ones automatically HOT 2
- Add UButton form props ? HOT 8
- Difference between the UI packages HOT 1
- UPopover Added non-passive event listener to a scroll-blocking 'touchstart' event HOT 1
- `UTabs` default icon field
- Adaptation for vue? HOT 2
- UTable - Change default loading to use USkeleton HOT 2
- Nested Zod schemas validation fails HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ui.