Giter Site home page Giter Site logo

react-popover's Introduction

react-popover

React Versions Support

react-popover >= 0.5.0 supports React 16 while react-popover < 0.5.0 works with React 15.x.x and likely lower. There is no plan to support older versions of this library with back-ported patches and PRs for that purpose are not welcome since it increases maintenance for the authors.

Installation

yarn add react-popover

Examples

API

export default Popover(props, target)

props :: {…​}


body :: Node | Array Node

The popover content.


isOpen :: Boolean

Determines Whether or not the popover is rendered.


preferPlace :: Enum String | Null

Sets a preference of where to position the Popover. Only useful to specify placement in case of multiple available fits. Defaults to null. Valid values are:

above | right | below | left

Prefer an explicit side.

row | column

Prefer an orientation.

start | end

Prefer an order.

null

No preference, automatic resolution. This is the default.


place :: String | Null

Like preferPlace except that the given place is a requirement. The resolver becomes scoped or disabled. It is scoped if the place is an orientation or order but disabled if it is a side. For example place: "row" scopes the resolver to above or below placement but place: "above" removes any need for the resolver.


onOuterAction :: (Event) → Void

A callback function executed every time the user does an action (mousedown or touchstart) outside the DOM tree of both Popover and Target. A canonical use-case is to automatically close the Popover on any external user action.


refreshIntervalMs :: Number | Falsey

The polling speed (AKA time between each poll) in milliseconds for checking if a layout refresh is required. This polling is required because it is the only robust way to track the position of a target in the DOM. Defaults to 200. Set to a falsey value to disable.


enterExitTransitionDurationMs :: Number | Falsey

The amount of time in milliseconds that it takes to complete the enter and exit animation. Defaults to '500'.


tipSize :: Number

Defines the size of the tip pointer. Use .01 to disable tip. Defaults to '7'.


Standard
  • Properties like className and style.


target :: ReactElement

  • The React Element that this popover will orient itself around. target rendering tree is unaffected. Popover will become its owner.


appendTarget :: DOMElement

  • The DOM element which the portal will mount into. In effect the popover will become an appended child of this DOM element. Defaults to 'document.body'.

react-popover's People

Contributors

alexnisnevich avatar alexuribekenzan avatar betree avatar carnewal avatar cbmono avatar chriscinelli avatar gabehayes avatar hosmelq avatar jasonkuhrt avatar kerumen avatar pasviegas avatar prayogoa avatar sch avatar stephen avatar t3chnoboy avatar timceedi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-popover's Issues

Rendering Component just gives 'querySelector' of null`

I'm trying to create a simple popover menu, however im confused about how I actually render my header with a popover?

I keep getting an Uncaught TypeError: Cannot read property 'querySelector' of null

Am I using the api incorrectly?

import Popover from 'react-popover';

... 

render(){
    var menu = ( <div >Popover Menu</div> )
    var header =  ( <div> Menu Header</div> );
    var popoverProps = {
        body:menu,
        isOpen:true,
        place:'bottom'
    }

    return React.createElement(Popover, popoverProps, header)
}

Research how layers will work

After trying to refactor into a usable and likely more-correct system from the current nonsense that this sketch is using, I quickly realized that I've got the hardest part of the problem ahead of me:

@stresslimit So the current takeaways:

  • Indeed the popover is not supposed to be rendered around its target as-far-as the DOM tree is concerned
  • Another concept is required altogether which goes along the lines of "layers" but has different implementations.

Example from React Bootstrap: http://react-bootstrap.github.io/components.html#popovers

    <OverlayTrigger trigger='click' placement='left' overlay={<Popover title='Popover left'><strong>Holy guacamole!</strong> Check this info.</Popover>}>
      <Button bsStyle='default'>Holy guacamole!</Button>
    </OverlayTrigger>

The good news is I am not crazy; all my concerns and notes about the problem I'm seeing unfold/thinking-through are leading to the right place. For example I basically came to this conclusion on the way home repeated by someone else way before:

react-bootstrap/react-bootstrap#27 (comment)

  1. Attach the modal pane to the document body, and wire it up to the trigger via refs and callbacks. The communication chain in React will be fiddly, but this will be an implementation-internal issue. I think this will involve some black magic, but will be a more solid implementation.

To paraphrase, have popover completely pass-through its children in its render and then render its own popover component to the body.

It seems that all discussion culminate in the OverlayTrigger component in Bootstrap React and the dedicated repo linked above pieterv/react-layers.

Lastly, in case readers do not read the links, keep in mind these links include discussions and references from the core community so this issue is taking from "trusted" minds in this domain.

onOuterAction triggers erroniously when click is on an element changed by react

When you click on something that toggles its own existence based on react state, the event.target isn't in the DOM anymore and it triggers onOuterAction. A common case: a div inside the popover that changes to another div when you click on it, based on some underlying state.

The relevant react-popover code:

  checkForOuterAction: function checkForOuterAction(event) {
    var isOuterAction = !this.containerEl.contains(event.target) && !this.targetEl.contains(event.target);
    if (isOuterAction) this.props.onOuterAction();
  },

When checkForOuterAction is called, event.target returns the div, but the div is no longer in the DOM because it was rerendered to be the other div. Therefore isOuterAction returns true.

I don't think this.containerEl.contains(event.target) is a robust solution. Unless there's a good way to make this work with react's rerendering system, it seems like onOuterAction needs to be implemented with an invisible page wide overlay div underneath the popover.

Support React 0.12.x

We cannot use React.findDOMNode in React 0.12.x. Instead we must use method #getDOMNode.

Ideally we can have our library adapt to the React version that is detected.

positioning in IE 11 not working

The inline styles of the popover container element always have left and top set to 0.

I'm investigating why this is., any help would be appreciated!

Really loving this component!

Add ie10 support

React Popover relies on Flexbox for layout. To use Flexbox in ie10 requires not just a prefix but different properties and values (namely to display).

https://github.com/jsstyles/css-vendor does not handle this problem. Therefore we currently do not support ie10!

Uncaught Error: A valid ReactComponent must be returned.

For some reason I'm getting this error:

Uncaught Error: Invariant Violation: Popover.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

It seems to import just fine and I'm trying a variety of props, but always getting this.

Zone choice should factor in body size

Zone choice is currently based on what is the absolute largest area. However to get expected results we must account for body size too. The algorithm for this must be specified.

Throttle resize/scroll events especially on frameEl

We should throttle resize events. Particularly when the resize event is coming from window. If resize events are firing as often from elements then ditto there.

Currently frameEl equals window and when resizing occurs the app grinds down in performance.

render to string nodejs

How can I use this on server side? I get an error as soon as I'm importing since window is undefined

Tidy demo logs

There are various ugly warnings in the demo logs that bias the experience toward unease, confusion and sloppiness.

FireFox bugs

  1. ReferenceError: event is not defined (strange...)
  2. Webkit only prefixes are preventing FireFox from doing Flex layout (Expected, references #9)

pickZone picks the wrong zone.

I have preferPlace="below" but on Chrome for Android it is always ignored and always position on above. This happen even when the screen is scrolled down and a button is at the top of the viewport. When it is tapped, the popover is shown above the button where nothing is visible.

There is a problem with doesFitWithin that return false even if there is actually enough space.
However, at the minimum, if there are no availZones thepreferPlace should be used.

Allow definition of birth place

Currently the popover always transitions in from top-left which is so far never what we want.

Making birthplace default to be relative to lockPoint would make a lot of sense. Details of exactly how the animation can be worked out at implementation time but presumably a whole fade-in combined with a slide slide from main start to main end.

sh: testem: command not found

react-popover$ npm run test

> [email protected] test /Users/dustin/src/react-popover
> testem

sh: testem: command not found

If I add testem as a devDependency, I get a testem error:

Error: Cannot find module '/Users/dustin/src/react-popover/webpack.test.config.js'

Restore examples

The were handy, but currently the test system stole the webpack system away. We will probably need multiple webpack config files I guess.

React 0.14.0 compatibility

Following errors are visible on React 0.14:

Warning: React.render is deprecated. Please use ReactDOM.render from require('react-dom') instead.
Warning: React.findDOMNode is deprecated. Please use ReactDOM.findDOMNode from require('react-dom') instead.

Also when installing package with npm install react-popover :

@[email protected] /project
├── UNMET PEER DEPENDENCY [email protected]
└── [email protected]

Close on outer action

Expose options that enables a common Popover closing pattern which is to automatically close the Popover on some external (out of bounds) action by the user.

An example of this behaviour is the OS X definition popover (image below). If the user makes any mouse action outside the popover then it [the popover] will automatically close. In fact this appears to be the only way it closes. There is not even a x close button.

screen shot 2015-05-05 at 4 11 46 pm

Popover tip positioning broken

It should be positioned using relative crossStart of popover instead of absolute. This regression was introduced when scroll handling was added.

Allow styles and props to be extended

Currently styles on popover and popover-body are lexically hard-coded. Props passed down to popover are not transparently added to popover root such as className.

Component keeps listening to events after unmount in certain situations

I have found a use case where the Popover component is unmounted without calling exit(), which means the scroll / timer / onOuterAction listeners are all still hooked up. This is causes issues with the next Popover that I use because there are now two actions hooked up to onOuterAction, which means that no matter where I click, even on the Popover, it thinks it's an outer action and closes the Popover.

I propose that exit() be called in componentWillUnmount() {} to be sure that the component gets cleaned up properly.

Current componentWillUmount():

  componentWillUnmount: function componentWillUnmount() {
    clearInterval(this.checkLayoutInterval);
  }

Suggested componentWillUmount():

  componentWillUnmount: function componentWillUnmount() {
    this.exit();
  }

Failed to execute 'removeChild' on 'Node'

In Chrome and Safari I am seeing a new error when the Popover is dismissed:

Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.detector.destroy
@ on-resize.js:81uninitialize
@ on-resize.js:29off 
@ on-resize.js:117untrackPopover 
@ index.js:404exit 
@ index.js:295componentDidUpdate 
@ index.js:284chainedFunction 
@ ReactClass.js:542assign.notifyAll 
@ CallbackQueue.js:65ON_DOM_READY_QUEUEING.close 
@ ReactReconcileTransaction.js:81Mixin.closeAll 
@ Transaction.js:202Mixin.perform 
@ Transaction.js:149Mixin.perform 
@ Transaction.js:136assign.perform 
@ ReactUpdates.js:86flushBatchedUpdates 
@ ReactUpdates.js:147wrapper 
@ ReactPerf.js:66Mixin.closeAll 
@ Transaction.js:202Mixin.perform 
@ Transaction.js:149ReactDefaultBatchingStrategy.batchedUpdates 
@ ReactDefaultBatchingStrategy.js:62batchedUpdates 
@ ReactUpdates.js:94ReactEventListener.dispatchEvent 
@ ReactEventListener.js:204

I think this SO Question is related.

The bug seems to come from the on-resize detector.

React Native support

Should we support React Native? It seems like there is no logical reason not to. There is an existing RN Popover by @jeanregisser. We can start this issue by reviewing his implementation as I've never personally worked on a RN Element.

Handle scrolling contexts

The layout system breaks in the face of a scrolling container.

  • While scrolling the popover must maintain its correct position
  • If the target is scrolled out of view then the popover should enter a state of targetOutsideViewbox.

Example in JSX

Is it possible to use this plugin in JSX? Do you have an example?
Something like:

renderBody() {
    return <p>content</p>
}

<Popover isOpen={state.isOpen} body={renderBody}>
    <a href="#">my popover opener</a>
</Popover>

Bind onto child

The component should bind onto the child and pass it through transparently.

Popover should lay itself out as a child of its child. The advantage of this approach is that using Popover should probably have no affect on elements it appears to wrap.

Build lost module.exports

Now have to do Popover = require('react-popover').default

If this was intended, it should be a major release.

Bad state with quick toggles

Currently animations cannot be safely interrupted. If they are, then the state of isOpen gets weird and can no longer toggle correctly.

Requires further investigation.

Disable close animation ?

Is it possible to disable the close animation ? I'm getting some weird animation flashes when closing from inside a pretty complicated table, would be good to just instantly hide in this case.

Infinite Loop Recalculation

It is possible for the popover to fall into a deadlock position where it bounces between two points forever.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.