'Dynamically Position an Element on webpage

I am trying to use a Emoji picker inside my React application and there are 2 buttons on the page to toggle the picker, I want to show the picker at the position where the Toggle button is clicked. For example there are 2 buttons, At the top and at the bottom, I want to show my picker at the position of click, making sure that the picker doesn't go out of view as well i.e. above/below the height and vice versa.

DOM

<>
    <div className='position-absolute h-100 w-100' id='picker-backdrop' onClick={this.toggleReactions} style={{top:0, left:0, zIndex:99}}>
    </div>
    <Picker set='apple' color={Colors.colorPrimary} autoFocus={true} style={this.state.pickerPosition} onSelect={(emojiObject) => this.sendReaction(emojiObject)} />
</>

Here's my logic:

// Coordinates to get the position of click
    let coordinates = {
        x: e.clientX,
        y: e.clientY
    }
// The picker-backdrop
container = {
            height: container.offsetHeight,
            width: container.offsetWidth
        }

// The picker element to be positioned
picker = {
    height: picker.offsetHeight,
    width: picker.offsetWidth
    }

let bottom = coordinates.y - picker.height
        let left = coordinates.x - picker.width

        if(bottom > 0) {
            bottom = container.height - bottom
            if(container.height - bottom < picker.height) {
                bottom = coordinates.y - picker.height
            }
        }

        if(left > 0) {
            left = container.width - left
            if(container.width - left < picker.width) {
                left = coordinates.x - picker.width
            }
        }

Generating style

if(bottom >= 0 && left >= 0) {
            style['bottom'] = bottom
            style['right'] = left
        }
this.setState({
            pickerPosition: style
        })

and also picker is position: 'absolute'.

Right now I am doing it only for the cases when the calculated values are positive but I can't get it to position correctly. Seeking forward to expert advises on what exactly am I doing wrong.



Solution 1:[1]

You can do it only using css. wrap both the button and the picker with an absolute positioned div, then wrap only the picker with relatively positioned div as I tried to show in the following code snippet:

.wrapper{
position:relative;
}
.toggler{
position:absolute;
top:0px;
left:0px;
...
}
.picker-container{
position:absolute;
top:0px;
left:<button-width>px;
....
}

<div class="wrapper">
<button class="toggler">Choose..</buton>
<div class="picker-container"><Picker/></div>
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1