GithubHelp home page GithubHelp logo

sunify / react-relative-portal Goto Github PK

View Code? Open in Web Editor NEW
120.0 3.0 24.0 717 KB

React component for place dropdowns outside overflow: hidden; elements

Home Page: https://sunify.github.io/react-relative-portal/

License: MIT License

JavaScript 100.00%
react overflow dropdowns portal component

react-relative-portal's Introduction

React relative portal

React component for place dropdown-like components outside overflow: hidden; sections

Installation

npm install react-relative-portal --save

Example

import React from 'react';
import RelativePortal from 'react-relative-portal';

export default class DropdownLink extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      show: false,
    };

    this._setShowAsyncTimer = null;

    this._handleShow = () => {
      this._setShowAsync(true);
    };

    this._handleHide = () => {
      this._setShowAsync(false);
    };
  }
  
  componentWillUnmount() {
    // Prevent the asynchronous `setState` call after unmount.
    clearTimeout(this._setShowAsyncTimer);
  }
  
  /**
   * Changes the dropdown show/hide state asynchronously.
   *
   * Need to change the dropdown state asynchronously,
   * otherwise the dropdown gets immediately closed
   * during the dropdown toggle's `onClick` which propagates to `onOutClick`.
   */
  _setShowAsync(show) {
    // Prevent multiple asynchronous `setState` calls, jsut the latest has to happen.
    clearTimeout(this._setShowAsyncTimer);
    this._setShowAsyncTimer = setTimeout(() => {
      this.setState({ show: show });
    }, 0);
  }

  render() {
    const { show } = this.state;

    return (
      <div>
        <button onClick={show ? this._handleHide : this._handleShow}>
          Dropdown toggle
        </button>
        <RelativePortal
          component="div"
          left={0}
          top={10}
          onOutClick={show ? this._handleHide : null}
        >
          {show &&
            <div style={{ padding: 10, backgroundColor: '#FFF' }}>
              Dropdown content
            </div>
          }
        </RelativePortal>
      </div>
    );
  }

}

Props

export default class RelativePortal extends React.Component {
  static propTypes = {
    right: PropTypes.number, // set right offset from current position. If undefined portal positons from left
    left: PropTypes.number, // set left offset from current position. If `right` prop is set, `left` ignores
    fullWidth: PropTypes.bool, // enables you to set both left and right portal positions
    top: PropTypes.number, // set top offset from current position
    children: PropTypes.any.isRequired, // portal content
    onOutClick: PropTypes.func, // called when user click outside portal element
    component: PropTypes.string.isRequired, // dom tagName
  };

  static defaultProps = {
    left: 0,
    top: 0,
    component: 'span',
  };

  ...

}

react-relative-portal's People

Contributors

andreypopp avatar brendonboshell avatar chambo-e avatar dragorww avatar evenchange4 avatar katz12 avatar sompylasar avatar stomita avatar sunify 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

react-relative-portal's Issues

IE11

in IE 11 not calculete left and top for relative portal

Warning: `NaN` is an invalid value for the `top` css style property. Check the render method of `RelativePortal`.

problem in usage window.scrollY read more

Portal: pass event to handleOutClick handler

      this.handleOutClick = (e) => {
        const isOutClick = !this.isInClick;
        this.isInClick = false;

        const { onOutClick } = this.props;
        if (isOutClick && typeof onOutClick === 'function') {
          onOutClick(e);
        }
      };

      document.addEventListener('click', this.handleOutClick);

Support prevent defalut onOutClick

sorry, I forgot to add in #15 commit DragorWW@766917f

bug in this case, if click on other component with handler on click:

class Test extends Component {
  handleClose = (e: MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation(); // not working, event don't stop.
    this.props.onClickOut();
  };
  render() {
    return (<RelativePortal
       onOutClick={this.handleClose}
    >);
}
}

Solution: add useCapture props to
addEventListener

Keyboard focus on child components

I'm unable to use "tab" or keyboard navigation to change my focus to my newly triggered object. I have to tab through the rest of my nav in order to get focus on the object that's positioned closest to my trigger.

Current behavior: I tab to the first main nav item, and then tabbing goes to the next main nav item
Expected behavior: I tab to the first main nav item which triggers my sub nav and I am able to tab to those sub-items.

Require react-relative-portal makes my code crash

Hi there,

I'm having a problem using react-relative-portal. It's kinda weird tbh.

I've got a component written in React and I want to use a Relative Portal in it.

Just by doing var RelativePortal = require('react-relative-portal'); the generated js breaks my app:

Uncaught ReferenceError: Components is not defined

How can I avoid this issue?

RelativePortal unit testing .

can any one suggest how to write unit test for RelativePortal.
challenge - unable to find component or any html tags written inside RelativePortal.
<RelativePortal component="div" > <div><OtherComponent/></div> </RelativePortal>
test :
const wrapper =mount(<MyComponent />); wrapper.find(<OtherComponent/>) or wrapper.find('OtherComponent') tried didn't working out
I am using tape plus, enzyme for testing.

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.