alexkatz / react-tiny-popover Goto Github PK
View Code? Open in Web Editor NEWA simple and highly customizable popover react higher order component with no other dependencies! Typescript friendly.
License: MIT License
A simple and highly customizable popover react higher order component with no other dependencies! Typescript friendly.
License: MIT License
Hi, I've created an pull request to fix React error #170 and you've merged it. Thanks for that! Are you going to publish new release with this patch?
Hello,
I was wondering if you have taken this into consideration. Basically I want to use this for a dropdown menu (the options are going to be rendered in a popover) and would be very useful to know inside children where the popover is placed (to apply custom style on 'trigger').
I have tried using some ref (since state is not allowed), but still is not fine since on the 1st render the position is not available. I guess an onReposition
callback or maybe a functional child component...?
Not really sure the impact of this feature, because I expect a lot of renders will happen, but I ll fork the project and give it a try.
Does anybody have an idea if there is a way of achieving this using the extension as it is?
I'm having trouble using Popovers inside of each other.
Here is the code:
<Popover
isOpen={showMore}
disableReposition
onClickOutside={() => this.setState({ showMore: false, showActiveDetails: false })}
content={(
<Flyout>
<Popover
isOpen={showActiveDetails}
disableReposition
onClickOutside={() => this.setState({ showMore: false, showActiveDetails: false })}
content={(
<Flyout>Other stuff</Flyout>
)}
>
<FlyoutOption onClick={() => this.setState({ showActiveDetails: true })}>
Show active details
</FlyoutOption>
</Popover>
<FlyoutOption>
Other stuff
</FlyoutOption>
</Flyout>
)}
>
<button
onClick={() => this.setState({ showMore: true })}
>
Open
</button>
</Popover>
Expected behavior: Clicking the open button shows the parent popover, then clicking on 'show active details' opens another popover. Clicking outside the inner popover (in the parent), would hide the inner. Clicking outside the parent would hide both.
Actual behavior: Opening parent and child works well. Clicking parent doesn't hide child. Clicking outside both hides the parent, breaks the child, and prevents either from opening again.
Observations: It looks like the child isn't being unmounted when the parent is unmounted.
I see there is a "containerClassName" which is good for styling the component in separate css file.
I would be ideal to have the same property for the ArrowContainer component.
Hi,
After upgrading to 5.0, with the ArrowContainer here, it's 10px more to the right, leaving it out of alignment. Reason, it's also considering the margin and going to the middle of the space.
Thanks.
To activate strict mode add StrictMode element to ReactDOM rendered like this:
ReactDOM.render(
<React.StrictMode>
<Root store={store} />
</React.StrictMode>,
document.getElementById('root')
);
Then react-tiny-popover gives this warning in the browser:
Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Popover which is inside StrictMode. Instead, add a ref directly to the element you want to reference.
The Popover.tsx uses deprecated findDOMNode function in componentDidMount and componentDidUpdate. These should be refactored to use ref instead.
Here's more info about the issue:
I use contentLocation and get client position from another element that it is not the child of popover component it shows correctly when open but if I scroll up or down it follows too how to fix this. Thank you
We are opening the popover onMouseOver but we would like to close it also after the mouse has moved out of the popover.
There is an event function onClickOutside provided but there is no function onMouseOutside (when the mouse has moved out of the popover).
Would be a useful feature to have! Would it be worth implementing?
This plugin is not supporting transition duration zero and that is causing side effects.
For example I have a set of HTML nodes, each one of them renders a [...] button, and when you click it we render popover content, when that popover is rendered then I go to another HTML block that has [...] button and then without closing the current popover I click that [...] button, what happens is that the first popover is faded out (opacity: 0) and never removed from the DOM, it is also clickable despite the user does not see it.
I managed to fix it by adding transitionDuration={0.000001} which feels like a small hack.
In the past I proposed a fix by allowing support transitionDuration=0
So I propose 2 things:
Line 264: is not taking into account when you pass 0 for transitionDuration, || in this line will ignore 0 value.
this.removePopoverTimeout = window.setTimeout(remove, (transitionDuration || Constants.FADE_TRANSITION) * 1000);
Suggested code change as follows:
if (!this.willUnmount || transitionDuration > 0) {
this.removePopoverTimeout = window.setTimeout(remove, (transitionDuration || Constants.FADE_TRANSITION) * 1000);
} else {
remove();
}
Opacity 0:
<div class="UI__Popover__popover" style="overflow: hidden; position: absolute; top: 247px; left: 234px; opacity: 0; transition: opacity 0.35s ease 0s;">
Visible One:
<div class="UI__Popover__popover" style="overflow: hidden; position: absolute; top: 247px; left: 665px; opacity: 1; transition: opacity 0.35s ease 0s;">
getting this error: node_modules/react-tiny-popover/dist/index.d.ts(55,24): error TS2694: Namespace 'React' has no exported member 'CSSWideKeyword'.
my investigation concludes that they removed CSSWideKeyword after react 15: https://github.com/DefinitelyTyped/DefinitelyTyped/search?utf8=%E2%9C%93&q=CSSWideKeyword&type=
this may be a related issue on their repo: DefinitelyTyped/DefinitelyTyped#20743
I don't know if this can be solved.. but just reporting it.
great library other wise!
Hi there!
What needs to happen for React 16 Portals to be supported? Is that something someone could take on and submit a PR for? The portal-progress
branch seems to be behind master, but might be what is shipped on NPM?
I have a warning: findDOMNode was passed an instance of Popover which is inside StrictMode. Instead, add a ref directly to the element you want to reference.
How critical is this?
Has anyone figured out a way to add a border around both the popover and the arrow? Similar to http://www.cssarrowplease.com/
A co-worker and I have spent quite some time recently trying to understand why my react-testing Jest tests expecting the popover to be closed were failing. Here's what I found - it might be useful to add this stuff to the docs:
it('should close when clicked away from', async () => {
jest.useFakeTimers(); // necessary
const { getByText, queryByText } = renderPopover();
jest.runAllTimers(); // necessary
fireEvent.click(getByText('Popover trigger'));
expect(getByText('Popover content.')).toBeDefined();
fireEvent.click(getByText('Element outside of the popover trigger'));
jest.runOnlyPendingTimers(); // necessary
expect(queryByText('Popover content.')).toBeNull();
});
I believe the Jest fake timers are necessary because of some setTimeout
calls in the code of this library.
It's also worth mentioning that the react-testing waitForElementToBeRemoved
method doesn't work with this library hence this:
jest.runOnlyPendingTimers();
expect(queryByText('Popover content.')).toBeNull();
I also found that the windowBorderPadding
must be set to 0
, otherwise the popover gets re-positioned, failing my tests.
Hey, I just wanted to check if there was any kind of support for redux integration?
So far the popover content is rendered outside the "App" so the provider does not wrap the popover, making redux integration more difficult.
Has anyone found a good way of combining the two so far?
Hi! First of all thanks for this package. I think it's the best package for popovers. It has the only generic logic of positioning and this is great. I'm using it in Tooltips, Dropdown, Selects, Datepickers and other components.
For example, I've found a way to use it in new react-select v2. If you are interesting I can share a code.
In some interfaces I need to control the width of content depends on target element size. e.g. min-width of menu list in select has to be not thinner than control width.
do you have an idea how it can be done with tiny popover?
I need to change popover div-container class name to apply my own styling through separate css file, not through props containerStyle
If I render a popover with isOpen: true
and close it afterwards with isOpen: false
, the popover is removed from the DOM.
Is there a way to tell react-tiny-popover
to retain the already rendered popover in the DOM, without removing it? I basically need to just hide the popover.
This would be useful especially if the component inside of the popover is rendered progressively (think of an infinite scroll containing the notifications of a user). If the component is heavy, reopening the popover after closing leads to some seconds of waiting before seeing the popover again.
Change of Popover render method to having the following code makes a breaking change to the component API, which is not a good practice for the component which is being downloaded 20K+ times a week.
return (
<>
{children(this.target)}
{popoverContent}
</>
);
Why do you expect children being a function instead of a normal React component(s)?
Trying to figure out what changed between the 5.0.0 and the 5.1.0 release. This is a place where I usually check the "GitHub releases" page, or just check the tags.
Doing a tag can be as easy as git tag 5.1.0; git push --tags
, but will be very helpful when looking at the commits backwards to see what release correspond to what tag. It's even nicer when projects also write a bit about each release, what changes went in etc, but this is not required IMHO for such a small project, it's easy enough just to read the commit subjects, and the linked PRs and the code.
Thanks! (You can do this retroactively for a few releases to back-fill some handy data).
I do want the popover to get appended to a div instead of body how do I do that. Is there an option to do that.
Hi, I like your lib and its works fantastic.
One problem I found is that containerClassName
is not updated in ComponentDidUpdate
. This is small change so if someone could add it to his changes I would really appreciate it.
Thanks
HI :)
When you have some texts inside the popover, no matter what kind of text (plain text, input, textarea, etc.), and you perform a quick selection of some text starting from inside the popover but end the selection outside it, the popover fire the event onClickOutside
, which is the event we usually use to attach some functions to close the popover.
So, the goal is to have a way to perform selections that end outside the popover, without to fire the event onClickOutside
.
Firstly, thank you for working on this great project and providing it to us to use.
However, 4.1.0 changes from using findDOMNode to cloning the child node and adding a ref parameter to it in order to access the dom node. Unfortunately, this is a breaking change, as any use of react tiny popover that does not directly pass a host node as a child will now be broken and be required to update their code to use forwardRef.
If this approach of cloning the child to insert a ref is to be maintained, the release of version 4.1.0 should be revoked and relabelled as 5.0.0 as it is a breaking change. This is important, as many people have tools that automatically merge minor updates as 4.1.0 as they are not supposed to be breaking change.
Additionally, a warning should be added to the documentation that says refs need to be forwarded. It would be great to catch the error introduced when refs are not forwarded, and to make the error more descriptive too.
However, I'm not sure this is actually the best approach. Using cloneElement is kind of "magic", and it is only by reading the diff of the update that I was able to figure out why 4.1.0 broke our app and how to fix it. Two alternative approaches if you wish to use refs is to automatically wrap the child with a div, and then use ref.current.firstChild
to access the child, or to replace the child with a render function that you pass the ref. Both of these would also likely be considered breaking changes and require a 5.0.0 moniker.
It works is 3.4.5 but not in 4.0.0, any one else had this issue?
I display a 200px height popover. Due to a change in the number of displayed items, the popover reduces the height to 100px. Unfortunately it doesn't change its position at the same time, so it starts to levitate somewhere above the element to which it was attached. After using mouse scroll it comes back to right place.
Is there any possibility to manually recalculate the position of the popover?
As stated in title.
react-tiny-popover/src/Popover.tsx
Line 61 in 6660ff6
Currently, I'm showing the popover when the user right-clicks (aka. onContextMenu
) on an element.
However, if they right-click on another element, the existing popover will remain (as it's not considered a click by the onClickOutside
handler).
Hey @alexkatz,
Thanks for this library. Could you please specify the license agreement?
Is it under MIT license?
Thanks!
You are making breaking changes to lib but it is hard to understand whether there are breaking changes or not.
Hi.
Thx for your package but this package have little issue when content have button or other element onClick and into function use setState auto fire onOutsideClick and close popover.
Pls fix it.
When I apply box-shadow
to the React element for the property: content
. The box-shadow is never getting applied.
Attaching in a codesandbox link. The box-shadow
is never respected.
To overcome the issue I had to give box-shadow
to className: react-tiny-popover-container
. which is not an ideal case.
Currently experiencing this error in "react-tiny-popover": "^6.0.0-beta.2",
Where import Popover from 'react-tiny-popover
throws and export error whereas import {Popover} from 'react-tiny-popover
works fine.
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
If the later is the case, then the docs should be updated to reflect these changes I guess.
With the release of React 16.9 they're now actively warning against usage.
Hello. What may be the reason that elements generated by Popover remain in react tree after popover close? They are not in DOM, but in React tree (visible in React Dev Tools). Is it a kind of leakage? Is it a problem with portals?
You can try with the original demo: https://alexkatz.github.io/react-tiny-popover/
Open/close popover many times and you will find many ArrowContainer in tree
IMHO all window listeners and timer interval are removed on destroy, so what is the reason?
If target is lost, it probably means it was not rendered, what's the point of rendering the popover in the corner of the screen?
Rendering children outside of react app causes issues. For example, trying to pop over a component containing a Redux connect dependency results in a failure to connect to Redux entirely.
Trying to get it working inside an iframe but it doesn't align to the HTML element.
I'm trying to use
contentLocation={{ left:left + rect.left, top: top + rect.top - 6 + plus + (rect.onClickTop || 0) - (rect.offsetTop || 0) }}
When I click the button 'render popover in the orange box', I am seeing the popover attached to the blue box.
I was attempting to use this prop in my current solution and was seeing issues with the output as well.
Is this feature still supported?
Because the ArrowContainer seems to handle its own styling, and there is no good way to get scss variables from your typescript file, it is difficult to match the styling from the popover itself to the arrowcontainer if your popover is getting its color from a scss variable. I have currently resorted to hard-coding the hex value of my variable into my typescript file. It would be great if there was some way to set the styling for the arrowContainer using a class.
Hi. I have a really weird issue. It seems like everything is working as intended EXCEPT for the final removal of the element from the DOM. This happens when I trigger a number of popups at once. It's not consistent. Sometimes they'll hide just fine, sometimes they'll fade out but not be removed. Mousing over and out of a "failed" one will cause it to work as intended again. No errors appear in the console. Here's the code and images pertaining to the state of the elements.
constructor(props){
super(props);
this.disableTooltip = this.disableTooltip.bind(this);
this.enableTooltip = this.enableTooltip.bind(this);
this.state = {tooltipEnabled: false, changed: false};
}
disableTooltip(){
this.setState({
tooltipEnabled: false,
changed: true
});
}
enableTooltip() {
this.setState({
tooltipEnabled: true,
changed: true
});
}
render() {
return (
<Popover isOpen={this.state.tooltipEnabled}
transitionDuration={0.25}
position={'top'}
content={({ position, targetRect, popoverRect }) => (
<ArrowContainer
position={position}
targetRect={targetRect}
popoverRect={popoverRect}
arrowColor={"white"}
arrowSize={8}
arrowStyle={{ opacity: 1 }}>
<div class="item-tooltip">
asdf
</div>
</ArrowContainer>
)}>
<div onMouseOver={this.enableTooltip} onMouseOut={this.disableTooltip} style={{zindex: '10000', position:'absolute', top: '0', left: '0', width:'100%', height:'100%'}}></div>
</Popover>
);
}
As you can see on the popover, internalisOpen is false, yet isTransitioningToClosed is true, and the component is perpetually in the DOM (though transparent) until I mouse over and mouse off of it.
Am I doing something wrong here or is this a bug?
Currently the only transition effect is opacity changing. how about support more effect or allow customization?
Popover isn't work in IE11 even after polyfill everything
We are using popover as a tooltip. While hover on list that each element has a tooltip, sometimes popover elements are not clean from dom.
There are code sample. https://codesandbox.io/s/react-tiny-popover-demo-hbs9z?file=/src/index.js
I think there is a problem about hide with transition. because when I close to if (!this.willUnmount)
block in removePopover() method Popover.tsx class, this bug is fixed. But I couldn't find work correctly when hide with transition.
` private removePopover() {
// this should now be a callback to handle event listening upon portal disappearance
const { /* transitionDuration, */ isOpen } = this.props
if (this.popoverDiv) {
this.popoverDiv.style.opacity = "0"
}
const remove = () => {
if (this.willUnmount || !isOpen || !this.popoverDiv.parentNode) {
window.clearInterval(this.targetPositionIntervalHandler)
window.removeEventListener("resize", this.onResize)
window.removeEventListener("click", this.onClick)
//@ts-ignore
this.targetPositionIntervalHandler = undefined
this.setState({ isTransitioningToClosed: false })
}
}
/* if (!this.willUnmount) {
this.removePopoverTimeout = window.setTimeout(
remove,
(transitionDuration || Constants.FADE_TRANSITION) * 1000,
)
} else { */
remove()
/* } */
}`
I'm removing component which contains react-tiny-popover from DOM-tree. Nothing breaks, but this error shows in console:
Error: Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.
at invariant (react-dom.development.js?f8c1:55)
at findCurrentUnmaskedContext (react-dom.development.js?f8c1:9545)
at getContextForSubtree (react-dom.development.js?f8c1:19022)
at updateContainerAtExpirationTime (react-dom.development.js?f8c1:19076)
at updateContainer (react-dom.development.js?f8c1:19140)
at ReactRoot.legacy_renderSubtreeIntoContainer (react-dom.development.js?f8c1:19428)
at legacyRenderSubtreeIntoContainer (react-dom.development.js?f8c1:19555)
at Object.unstable_renderSubtreeIntoContainer (react-dom.development.js?f8c1:19603)
at ProxyComponent.Popover.renderWithPosition (index.js?d533:272)
at ProxyComponent.eval (react-hot-loader.development.js?9cb3:587)
This error causes by Popover component, I checked, when I do the same actions without this component, everything is ok.
If I pass in transitionDuration={0}
it appears that it's treated the same as if it's not passed in at all (i.e., it uses the default .35
).
This is a great component but:
One of the most interesting things is that you can make it a modal or a div, that is my case I'm transforming it to be a slide in panel (bottom to top) when agent is a mobile device, sometimes the popover in mobile devices is difficult to handle, so I wonder if it is possible to add desired transition via configuration when the popover appears so in this case I can slide it in instead of the default fade in.
Also I have notice browser become a bit slow, thing in browser console sometimes are slow, like when you use arrows to navigate console history and I thing is maybe cause of this component, maybe setInterval fault.
Thanks
I want to constrain the popover content within container div, adjust nudgetLeft and nudgeTop according to div.
I have gone throught documentation and found option of using contentDestination but that is not working for me, throwing error cannot read remove of null on passing ref to this option.
If i am doing something wrong please provide some working example using this example.
Demo provided in read.me is also not showing popover in orange box.
Recently we came across a use case where i am using button inside the popover. I am using that button to duplicate a tab as it works in chrome. but the new tab which is created has popover in a open state. so i would request to have a functionality to close the popover on click inside the child component.
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.