valgeirb / vue3-popper Goto Github PK
View Code? Open in Web Editor NEWA Vue.js popover component based on PopperJS
Home Page: https://valgeirb.github.io/vue3-popper
License: MIT License
A Vue.js popover component based on PopperJS
Home Page: https://valgeirb.github.io/vue3-popper
License: MIT License
Hey, I've been using your popper component for a long time now, but I tried upgrading to the newest version today in hopes to resolve an issue I'm having, but I am getting a crash anytime I upgrade to a version higher than 1.2.1. I was on 1.1.0 previously. I did a few installs one version at a time and found that everything runs ok for 1.1.0, 1.2.0 and 1.2.1. But anything higher than that and I get the following runtime crash...
I don't see any open issues related to this, so I wanted to get your input, if you have the time. Anything that immediately comes to mind that I might be missing? Thanks!
Hey, I love what you've got so far! I do have a specific need though for our client and I was going to see if you could help me out? Basically, when using the "hover" option for the Popper, we would like to keep the popper open as long as the user is hovering over either the trigger element or the popper itself. We are using this to provide a user some options (with buttons for confirming/rejecting and such) when hovering over certain elements. Is there any way we can make that happen? I'd appreciate it, and thanks for your time!
related issues: #24
zIndex
should be add into popper element's style
Hi. Thank you for this great component!
But, it makes additional <div>
on top of my slot content.
Question: Is there a way to avoid this? (Use default slot directly, not in the wrapper)
Thanks!
vue3-popper/src/component/Popper.vue
Lines 3 to 15 in 9306f8d
Description of the bug
If you don't want a border around the popper and use --popper-theme-border-width: 0
, this also removes the arrow completely. It looks like the arrow size is linked to the same --popper-theme-border-width
variable.
To Reproduce
Steps to reproduce the behavior:
arrow
property, observe an arrow shows up--popper-theme-border-width
var to 0
Expected behavior
Arrow size to have independent styling variable from the popper's own border
Screenshots
With border 2px:
Border is correctly removed, but arrow is gone.
We have a use case where we want to display poppers on SVG elements.
The easiest and leaner solution is to have standard tooltips generated with the <title>
SVG element, see this proof-of-concept: https://gitlab.com/simevo/vue3-svg-map
Cons: you can't control the tooltip etc.
We have successfully integrated bootstrap5 popovers (based on Popper 2), this works well like this:
<path
v-for="v in venue_shapes"
:key="v.id"
:d="v.d"
data-bs-toggle="popover"
data-bs-trigger="hover focus"
data-bs-content="`<table class='table'><tr><td>Probabilità</td></tr><tr><td>${ probabilita[v.id] }</td></tr></table>`"
/>
You just enable them in the mounted
hook and they work. But of course they are not reactive!
vue3-popper looks like the solution to make them reactive. So I have tried using this library in the vue3popper branch of the vue3-svg-map prototype: https://gitlab.com/simevo/vue3-svg-map/-/merge_requests/1
Unfortunately when the <Popper>
element is expanded, it generates a bunch of HTML tags which are simply ignored in the SVG,
therefore the map disappears.:
Is there an easy solution to make vue3-popper work with SVG ?
Is it possible to just put it on top?
Is there a way to keep popper open after user hovers on the trigger(for nav dropdown purposes)?
Greetings!
I get your idea why you add those styles (border + margin) but that is a not good thing (imo). Styles in <style> have high precedence and if I want to cancel them (I really do) I need to use !important flag in my styles - that's pity. Why don't you use ::before/::after pseudo-classes to keep hover zone?
'close' slot property is undefined on popover showing, it's okay to add some checking like
if (popover && popover.close) {
popover.close();
}
Also problem can be looked at demo page.
Error text is
TypeError: Cannot destructure property 'close' of 'undefined' as it is undefined.
The Popper is nice, simple and works well. However I'm now using it in a project that requires manual opening of the Popper while retaining the automatic closing (especially the click outside) functionality.
When I use the sample code for manually opening the click out side doesn't work anymore. Reviewing your code showed that using the 'show' flag puts the component in manual mode. I tried to trick by setting the show = null in the onOpen event, but that results in a lot of warnings on the onMount and onBeforeMount.
TLDR: Can I retain automatic closing with manual showing?
Hi! First, thank you for your great lib!
When we render a lot of popper, the browser will drastically slow down (due to popper.js)
Do you know how to render the popper on the fly ?
Or a way to render the content only when the selector is hovered ?
Thx you!
Description of the bug
A clear and concise description of what the bug is.
Reproduction link
If you can, create a reproduction on CodeSandbox
// In file vue3-popper/dist/popper.ssr.js
function render(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1);
}function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Investigate if this is a realistic improvement.
Original issue description #3:
is it possible to use 1 popper for multiple elements? in vue-tippy i could use :to="element" to change the element where the popper was bound to
why: in a table with 100 rows and 3 columns where every column has a popper, this would be 300 poppers
nice would be to have 3 popper, one for each column and when i hover over a table-cell i will change a variable so the content within the popper can update
is that possible?
I have wrapped Popper in my own custom Select element, so I may have multiple Select components on same page. When one of them is opened, it doesn't close if I click on another Select component.
UPD:
Oh, it works fine actually, the problem was that I need to stop click propagation in order not to fire click event on parent elements, because they have their own listeners.
So I made this:
Popper(@click.stop="")
And that problem was solved, but another one appeared.
Description of the bug
I would like to pass custom modifiers but there seems to be no way to do this using this package? Maybe you have some ideas? Or maybe I missed something.
Expected behavior
Should be able to modify the Popper instance directly to override the default options
It'd be nice if instead of using scoped classes or the global .popper
class we could pass style definitions using CSS modules.
E.g.
<template>
<popper
v-bind="$attrs"
:classes="$style.myStyle"
:offset-distance="4"
hover arrow
>
<slot />
<template #content="props">
<slot name="content" v-bind="props" />
</template>
</popper>
</template>
<script>
import Popper from 'vue3-popper'
export default {
name: 'CustomPopper',
components: {
Popper,
},
}
</script>
<style module lang="scss">
.myStyle {
background: black;
color: white;
}
</style>
The classes
prop would then be applied as :class="classes"
in the popper component.
This will make it easier to pass in custom styling, and even dynamic styling based on prop values.
Happy to make a PR if interested.
Description of the bug
Nested popper clickoutside close all poppers
Reproduction link
https://codesandbox.io/s/proud-fast-qi8x4
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The last active popper needs to be closed and not all of the poppers
Additional context
See this library as a reference for working demo of the expected behavior:
https://github.com/runfaj/react-nested-popper/
it will perfect if add it :)
Could be nice to have a build UMD package.
Edit: Building and using "iife" package throws an error "Uncaught ReferenceError: regeneratorRuntime is not defined"
Hello!
I've been using this package in my team's application recently. Thanks for it, it's really convenient.
This is mainly a feature request for adding click modifiers onto the triggerNode
.
Sometimes I have the triggerNode embedded in a div and would like to make sure that clicking on the trigger node doesn't fire any events for its containing element (such as with click.stop
on the child).
This opened up the possibility of using the manual controls exposed by vue3-popper, but I'd lose a lot of the built in convenience of using this as a wrapper for all of my app's popovers (click away, for example).
Thanks for the work!
It should be very useful to use defineExpose
in order to expose the close and open functions.
Then we could be able to open or close a popper from somewhere else in the page, something like:
## script
const foo = ref()
const openFoo = () => foo.value?.open()
## Template
<Popper ref="foo">blablabla</Popper>
<button @click="openFoo">I can open the popper Foo</button>
Thanks for creating this awesome library. Took me 5 minutes to get up and running with my own tooltip component and works excellent.
Really appreciate the work you put into this! ❤️
Hi, great work on the library I am enjoying it! I was using Vue-3-popper v1.2.1 and Vue 3.1.2 and it works fine, but when I try to upgrade Vue to 3.2.x and Vue-3-popper to 1.3.0 I get strange runtime errors that I cannot explain. Hoping you can help me fix it.
These are the 2 errors I see, which prevents my entire view from loading.
I've followed the documentation and made my own wrapper component for the Popper component.
I use it like this in my view:
<PopoverIcon class="d-inline-flex" :content="$tc('contractOverview.table.contractExpirationWarning', { count: item.data.remainingDays})"><i class="pi pi-exclamation-circle" /></PopoverIcon>
However, when I try to upgrade to Vue 3.2 even the sample component does not work for me. I think it could be related to the slot property, but seeing as even the example does not work I don't know how to fix it. Any idea what could be causing this?
Even though I have set the placement to "top" it still flips to bottom when it want to. Is there a way to force placement to always be top?
<Popper :hover="true" arrow placement="top" ...>
....
</Popper>
I am having problems with the click event when it is inside the popper component apparently the event is being duplicated.
Maybe this is already possible but couldn't figure it out from the doc, but I need a way to manually show the popper, a "show" or similar property would allow for this.
Sorry for posting as a bug.
I need to make popup the same width as a trigger for things like selects, date pickers, etc.
Thanks in advance!
Apologies if I'm getting this wrong, but it appears to apply styling to the element the popper is attached to:
element.style {
border: 12px solid transparent;
margin: -12px;
--23121010: 9999;
}
I would suggest styling of the attached element is removed and left to the user.
Click outside close not working when use it inside the side panel and modal dialog.
Add a new prop that gives more options for how the Popper transitions its open/close state.
Currently fade
is baked in, look into adding more.
Description of the bug
when I want to get default slots in my compoent, I only can get the default slots from vue3-popper.
Because I found there is a default slot in vue3-popper.
<template #content> <div class="select-options"> <slot /> </div> </template>
Can you please add an MIT license to your great project :)
Hi, is there a way to append the popper to the body so that it can escape overflow: hidden
parents? Thanks.
Using a content
prop instead of having to use the content
slot can simplify the usage of the Popper component in many cases.
This is a great library, thanks for building it! I'm wondering how we can close the popper without implementing full manual control?
Problem: I need to close the popper on scroll, but want to retain the default open/close functionality of the component, so I don't want to eject to full manual control.
Description of the bug
In Nuxt3 the useClickAway
composable throws an error within an SSR context: window is not defined
.
The error occurs here:
if (!window) {
return;
}
however I have no idea why Nuxt complains here since the expression !window
should just evaluate to a thruthy value and therefore just process the if-statement.
The following will fix the issue:
if (typeof window !== 'undefined' || !window) {
return;
}
I will submit a PR
Would it be possible to override the default transition animation when opening/closing the popper with our own?
Right now there is no way to tell Popper to close when you hover over it with mouse. Sometimes it is useful when there are buttons behind popper and you can't click on them because popper is in front of them.
This is an issue only when you set the mode to hover=true
It would be nice to have an option to hide it on hover like this
<Popper :hover="true" :closeOnHover="true">
....
</Popper>
hey great work!
i'm just switching to vue 3 and used vue-tippy before
what i'm struggling with:
situation 1:
often i load more content from server when tippy is shown. i COULD solve this with the show-event but its really dirty ^^
it would be nice if i nut just could "import" the close-function, but also isOpen
example: <template #content="{close, isOpen}">
if this would be possible i could conditionally decide what to render and trigger what to fetch for the server
situation 2:
is it possible to use 1 popper for multiple elements? in vue-tippy i could use :to="element" to change the element where the popper was bound to
why: in a table with 100 rows and 3 columns where every column has a popper, this would be 300 poppers
nice would be to have 3 popper, one for each column and when i hover over a table-cell i will change a variable so the content within the popper can update
is that possible?
Hi! First of all; great job writing this very easy to use popper component!
I would like to request a feature regarding conditional rendering. I have the following scenario:
<template>
<Popper arrow hover>
<button> hover me! </button>
<template #content v-if="condition ">
Show popper only when condition is met
</template>
</Popper>
</template>
I get an empty popper element on hover, due to the fact that I conditionally render the content template.
I can pass a show
prop to the Popper
component, or the popperNode
checks if the content slot is defined: https://github.com/valgeirb/vue3-popper/blob/main/src/component/Popper.vue#L18
I would like the popper element to not be rendered / shown when I explicitly say so. It can be visible by default (implicitly) of course.
Description of the bug
Popper events are emitted even if popper is disabled
To Reproduce
Expected behavior
Events should not be triggered or emitted when popper is disabled
If you have a Popper with a closeDelay
and hover
props and you
It still closes. It should stay open.
You should remove the usage of directives and use composable for click away... for example: https://vueuse.org/core/onClickOutside/
They aren't working in SSR apps, and require custom transformers in build tools.
Vue documentation says:
We recommend to prefer using components as the abstraction mechanism instead of directives.
I am trying to maintain show=true
while deleting elements from within a v-for loop of generated buttons. I have prepared and attached a Vue file which contains a simple example of the unwanted behavior:
PopperTest.txt
In my current project I am using a Popper within a vuedraggable list-group, to contain another vuedraggable list-group (with a v-model bound to an array of objects), in which case the closing behavior only occurs when the last element of any array is spliced and the model is updated, not just any of the list elements.
I have also tried binding the show attribute to a computed property and can get the popper to show as expected. From here I would then like to still be able to close the Popper with v-click-outside functionality, but the event is not exposed in the API. I would greatly appreciate if I could call a onClickOutside method from a Popper click-outside event!
Hi, I installed popper and there is no style. Version is 1.1.0. Any suggestion?
Hi, I have a Popper which has some elements which may be destroyed like so:
<Popper><template #content="#content">
<div class="popper-body"><button v-if="show" @click="show = false">Click me</button>
<div class="after-click" v-if="!show">More Content</div>
</div>
</template>
<p>Trigger</p>
</Popper>
Clicking the button unexpectedly closes the popper because of the following code in the library:
beforeMount: (el, binding) => {
el.clickAwayEvent = (event) => {
if (!(el == event.target || el.contains(event.target)) && binding.value.enabled) {
binding.value.handler();
}
};
document.addEventListener("click", el.clickAwayEvent);
}
The check el.contains(event.target)
will return false, since the event target (the button) is now disconnected from the DOM.
I suggest changing this check to use event.path
, i.e.: event.path.includes(el)
Unrelated but it would be nice to be able to destroy poppers. I am using a lot of these things all over my DOM and rather than just hiding or showing them, I would like to destroy the DOM. For example, if I have 100 poppers on the page, every click I make will trigger this handler 100 times, since the component is always alive.
Thank you!
Description of the bug
Page where popper is in use does not work when server side rendered with following error:
[vite] Internal server error: regeneratorRuntime is not defined at [email protected][email protected]/node_modules/vue3-popper/dist/popper.ssr.js:1951:49
Expected behavior
Expected to work as client side rendered
Additional context
Add any other context about the problem here.
Vite + Vue3 + vite-ssr + [email protected]
After doing some digging it seems like regeneratorRuntime
is related to babel
but that's about all I could find.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.