how to create an overlay popup with Reactjs in a event driven code?

I am creating a chrome extension that once clicked, injects the code of a sidebar with a button, that when clicked will start a functionality like inspect from dev-tools. I am using jquery to make force the DOm element to be highlighted on mousemove event and what I am trying to do now is to open a popup right beside the clicked element.

This is my code of the sidebar:

class SidebarLeftOverlay extends Component {

    constructor() {
        super();
        this.state = {isVisible: true};
    }


    buttonOnClick() {
        console.log('cliquei no botao!!!! e o isVisible antes:' + this.state.isVisible);
        this.setState( prevState => ({
            isVisible: !prevState.isVisible
        }));
        console.log('cliquei no botao!!!! e o isVisible depois:' + this.state.isVisible);

        var elements = {
            top: $('#selector-top'),
            left: $('#selector-left'),
            right: $('#selector-right'),
            bottom: $('#selector-bottom')
        };

        $(document).ready(function () {

            $(document).on('mousemove.myNamespace', function(event){

                    if(event.target.id.indexOf('selector') !== -1 || event.target.tagName === 'BODY' || event.target.tagName === 'HTML') return;

                    var $target = $(event.target),
                    targetOffset = $target[0].getBoundingClientRect(),
                        targetHeight = targetOffset.height,
                        targetWidth  = targetOffset.width;
                    //console.log(targetOffset);

                    elements.top.css({
                        left:  (targetOffset.left - 4),
                        top:   (targetOffset.top - 4),
                        width: (targetWidth + 5)
                    });
                    elements.bottom.css({
                        top:   (targetOffset.top + targetHeight + 1),
                        left:  (targetOffset.left  - 3),
                        width: (targetWidth + 4)
                    });
                    elements.left.css({
                        left:   (targetOffset.left  - 5),
                        top:    (targetOffset.top  - 4),
                        height: (targetHeight + 8)
                    });
                    elements.right.css({
                        left:   (targetOffset.left + targetWidth + 1),
                        top:    (targetOffset.top  - 4),
                        height: (targetHeight + 8)
                    });
                }).one('click.myNamespace', function (event) {
                    var $clickedTarget = $(event.target);
                    $(document).off('.myNamespace');
                    event.preventDefault();
                    var selector = document.getElementById('selector');
                    console.log(selector);
                    selector.click();
                    return false;
                }
            );
        });

    };

    render() {
        return (
            <div>
                <Selector />
                <Dock
                    position="left"
                    dimMode="transparent"
                    defaultSize={0.25}
                    isVisible={this.state.isVisible}
                >
                    <button onClick={this.buttonOnClick.bind(this)}>Inspect</button>


                </Dock>
            </div>
        );
    }
}

export default SidebarLeftOverlay;

the css for the divs are:

#selector-top, #selector-bottom {
    background: rgb(2,36,107);
    height:3px;
    position: fixed;

}
#selector-left, #selector-right {
    background: rgb(2,36,107);;
    width:3px;
    position: fixed;

}

and the code for the selector is:

export default class Selector extends Component {

    constructor(){
        super();
        this.state = {
            show: false
        };

        this.handleclick = e => {
            this.setState({ show: !this.state.show });
        };
    }

    render(){

        return(
            <div>
                <div id="selector" onClick={this.handleclick} >
                    <div id="selector-top"></div>
                    <div id="selector-left"></div>
                    <div id="selector-right"></div>
                    <div id="selector-bottom"></div>

                </div>
                <Overlay
                    show={this.state.show}
                    placement="right"
                    container={this}
                    containerPadding={20}
                    target={}
                >
                    <Popover id="popover-contained" title="Popover Test">
                        Testing if the popup is ok.
                    </Popover>
                </Overlay>
            </div>
        );
    }
}

I used the strategy found in this question for the highlights.

I am using react-dock for the sidebar and I thought that using the Overlay/popover elements of react-bootstrap would help me doing this. However, when I click on the element the Popover is at the very top of the page.

1 answer

  • answered 2018-02-13 01:13 Shanon Jackson

    https://jsfiddle.net/69z2wepo/101365/ I made this fiddle with a basic overlay / modal for you to use. Enjoy. I would suggest not using jQuery with react as its a huge anti-pattern

    it should work regardless of where its positioned in the DOM. i.e 5 components deep.

    s