React based Popover not working in Safari



  • Hey all. I’m trying to use the Popover component with React in Onsen 2, with mixed results.

    I’m using the Popover in conjunction with the react-google-maps component. When a user clicks on a pin on the map, a Popover is supposed to show.

    My code looks like the following:

    
    getTarget()
    {
        return this.state.selectedCluster;
    }
    
    maybeRenderPopover()
    {
        if ( this.state.showPopover )
        {
            return (
                <Popover 
                    isOpen={true}
                    onPostHide={this.didHidePopover.bind(this)}
                    getTarget={this.getTarget.bind(this)}
                >
                    <ServiceList
                        selectable={true}
                        services={this.state.selectedServices}
                        onSelect={this.handleServiceSelection.bind( this )}
                    />
                </Popover>
            );
        }
        else
        {
            return null;
        }
    }
    
    
    render()
    {
        return (
    <Page
       renderModal={this.renderModal.bind( this )}
    >
         <Splitter> 
            <SplitterSide
            side='left'
            width={200}
            collapse={true}
            isOpen={this.state.showMenu}
            onOpen={this.showMenu.bind(this)}
            onClose={this.hideMenu.bind(this)}
        >
            {this.renderMenu()}
        </SplitterSide>
        <SplitterContent>
            <Page
                renderToolbar={this.renderToolbar.bind(this)}
            >
                <Map
                    style={styles.map}
                    zoom={this.props.map.zoom}
                    center={this.props.map.center}
                    objects={this.props.sync.services}
                    cluster={true}
                    onZoomChanged={this.props.changeZoom}
                    onCenterChanged={this.props.changeCenter}
                    onClusterClick={this.handleClusterClick.bind( this )}
                />
                {this.maybeRenderPopover()}
            </Page>
        </SplitterContent>
       </Splitter>
    </Page>
    );
    }
    

    Because the Popover’s target is a pin on the map, which can move if the user pans, I was having trouble with setting it’s isOpen property to this.state.showPopover. If I panned the map, the Popover wouldn’t render in the correct position.

    The way I’m doing it now works perfectly on Chrome based browsers. But on Safari, both on macOS and iOS, the Popover never displays.

    Any chance someone might know what I’m doing wrong?

    Thanks,

    Scott



  • Found a workaround for anyone who is interested.

    If you want to immediately display a popover, it does not seem to work to set the isOpen property to “true”. At least it doesn’t work in every browser.

    However, you can create an additional property that will initially be set to false, and in the postHide handler, set it to true and the Popover will work in every browser that I’ve tried it in.

    In other words:

    if ( this.state.showPopover )
    {
       return (
          <Popover
               isOpen={this.state.reallyShowPopover}
               ...
               onPostHide={ () =>
               {
                    if ( this.state.reallyShowPopover )
                    {
                        this.setState(
                        {
                            showPopover: false,
                            reallyShowPopover: false
                       } );
                   }
                   else
                   {
                       this.setState(
                       {
                           reallyShowPopover: true
                       } );
                   }
               } }
    

    I looked at the source code of the React Onsen components and perhaps there is an ordering issue when the isOpen property is true initially.


Log in to reply