Ways to have a list component smoothly descend when a dropdown menu is activated

I have a situation where I have a list with two buttons, and each button triggers the same dropdown content in a sidebar component. The issue is that when I click on one button to open the dropdown, the second button does not move down to make space for it. How can I ensure that the second button slides down after the dropdown content is opened?

Here is my current approach:

MenuBarGame.js

     import React , {useState} from 'react'
     import css from '../components/css/MenuBarGame.css'
     import Logo from '../logo.png'

     function MenuBarGame(props){
      const [click, setClick] = useState(false);

     function handleDropdown() {
       if(click == false){
       setClick(true); 
       }
       else{
       setClick(false)
    }
  }

return(
    <>
    <div>
            <li>
                 <button className="gameButton" onClick={handleDropdown}><img src={Logo}/> {props.data.name}</button>
                 {click?
                 <div class="dropdown-content">
                    <button>* Duel</button>
                    <button>* Events</button>
                    <button>* Leaderboard</button>
                 </div>:null}
            </li> 
    </div>

    </>
)

}
export default MenuBarGame

MenuBarGame.css

.MenuBarGame{ 
margin-top: 10px;
display: flex;
justify-content: center;
align-content: center;
color: white;
}

.MenuBarGame ul{ /*Styles for the area containing the game tabs*/
padding: 0px 1.5em 0px 1.5em;
height: 15px;
}

.MenuBarGame ul li { /*Individual styles for each game tab*/
display:flex;
margin-bottom: 10px;
}

.MenuBarGame ul li img { /*Styling for images*/
border: 1px solid #0ab74c;
border-radius: 100%;
width:2em;
height:2em;
margin-right: 15px;
vertical-align: middle;
}

.gameButton { /*Styles for game buttons*/
color: white;
border: 1px solid transparent;
height: fit-content;
width: 150px;
padding: 10px;
cursor: pointer;
display: table-cell;
font-size: 14px;
background-color: #1c3527;
position: relative;
}

.dropdown-content {
display: flex;
position: absolute;
margin-top: 60px; 
width: 100%;   
background-color:#343438;
flex-flow: column nowrap;
}

.dropdown-content  a{
display: flex;
color: white;
padding: 16px 4px;
text-decoration: none;
flex-flow: column nowrap;
align-items: center;
}

.dropdown-content button {
text-align: left;
margin-left: 15px;
}


.dropdown-content a:hover {cursor: pointer;}

Implementation in the dashboard component:

Dashboard.js

 <div className="MenuBarGame">
        <ul>
          <MenuBarGame data={{name:"Game1"}}></MenuBarGame>
          <MenuBarGame data={{name:"Game2"}}></MenuBarGame>
        </ul>
      </div>

Answer №1

If you need assistance with your request, simply copy and paste the code provided below into your MenuBarGame.js file. Make sure to import useRef and useEffect:

function MenuBarGame(props) {
  const [click, setClick] = useState(false);
  const dropdown = useRef();
  const btn = useRef();

  useEffect(() => {
    if (click)
      btn.current.style.marginBottom = `${dropdown.current.offsetHeight}px`;
    else btn.current.style.marginBottom = 0;
  }, [click]);

  function handleDropdown() {
    setClick(!click);
  }

  return (
    <>
      <div>
        <li>
          <button className="gameButton" onClick={handleDropdown} ref={btn}>
            <img src={Logo} /> {props.data.name}
          </button>
          {click ? (
            <div className="dropdown-content" ref={dropdown}>
              <button>* Duel</button>
              <button>* Events</button>
              <button>* Leaderboard</button>
            </div>
          ) : null}
        </li>
      </div>
    </>
  );
}
export default MenuBarGame;

Check out a live demo on codesandbox.

The issue of the second button covering the first dropdown was due to setting position: absolute on the dropdown content. This caused other elements to ignore its height and overlap it. In my solution, I applied bottom margin to the first button based on the height of the first dropdown.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a more concise method for accepting a collection of interfaces in TypeScript?

Issue I am facing a simplified version of a problem with my model: Here is how my model currently looks: interface Instrument { name: string; // ...more properties shared by all instruments... } interface Guitar extends Instrument { type: &q ...

jQuery Mobile is experiencing page height inaccuracies

My web application, built with jQuery Mobile 1.2.0, is encountering an issue with page height calculations on Windows Phone. While iOS and Android display correctly, there is a gap at the bottom of the page on Windows Phone. Is there a CSS-only solution t ...

Deactivating the submit button after a single click without compromising the form's functionality

In the past, I have posed this question without receiving a satisfactory solution. On my quiz website, I have four radio buttons for answer options. Upon clicking the submit button, a PHP script determines if the answer is accurate. My goal is to disable t ...

Having trouble launching React application on local machine due to missing node modules

I am completely new to React. I recently forked a project on Github and am attempting to run it on my own machine. However, I've noticed that the folder structure is missing the node modules. Does this mean I need to install create-react-app globally ...

Omit certain components from the JQuery ListNav plugin

I recently incorporated the Jquery plugin for record filtration. I obtained this plugin from the following link: After successfully implementing the plugin, I encountered an issue where it was counting the headings along with the alphabet filters in my co ...

"Mastering the art of displaying real-time data on a thermometer using D3.js

Welcome to the sample code for a thermometer created using D3.js. You can view the code on jsfiddle. I've developed a web page displaying a dynamic thermometer with values updating every second. Here's the function: setInterval(function(){ getN ...

How can we implement intricate looping mechanisms in hogan js?

Currently, I am in the process of familiarizing myself with expressjs. In my journey to learn this technology, I have encountered a controller that performs queries on a database and returns a JSON object with certain key-value pairs. An example of such an ...

I'm having issues with my pop method - it doesn't seem

Hello everyone, I am new to core JavaScript and currently learning how to create an array. I have written the following code but for some reason, the pop method is not working as expected. var players=['david','micky','Ryan' ...

A guide on showcasing Python Flask database entries in an HTML table using Jinja 2

I have a database with a table that I need to display in my web application using a specific route. My goal is to present the data from the DB in a clear and easy-to-read table format, similar to an Excel spreadsheet, through the app. Although what I hav ...

Is it possible to dispatch an action that updates the store within the componentDidUpdate() lifecycle method?

As per information from React's documentation, componentDidUpdate() is recommended for handling side effects while caution should be taken when using this.setState() due to potential extra rendering. But what about dispatching an action to update the ...

Trigger a JQuery popup by toggling a class with a button

Hey there! I have a modal popup that utilizes an active class. When this class is present, the modal appears, and when it is removed, the modal disappears. I am trying to create a button that, when pressed, will show the modal, and a close button inside th ...

Converting PPT files to PDF or PNG using Node.js

Are there any options available for converting ppt files to pdf or png without relying on specific operating system dependencies? I need to convert a ppt file to png, but all the current packages I have tried require tools like LibreOffice or ImageMagick ...

Having trouble integrating a custom dialog with DirtyForms plugin

I have successfully implemented DirtyForms, a plugin that triggers a confirmation dialog when a user tries to navigate away from a page. The base functionality of the plugin is working as intended. Now, I am trying to integrate jQuery UI's Dialog for ...

Align navigation bar using Angular Material

Trying to center my navbar has been a struggle for me. I attempted using 'layout-align='space-between center' but it's not taking up 100% width and is acting more like an inline element. I've been following the documentation close ...

Tips for posting images upon clicking a div instead of a submit button

I previously had a code that allowed users to click on the submit button and have the text inside a contenteditable div passed to upload.php using JQuery, inserted into a database, and immediately displayed. Now, I want to modify this code to also handle i ...

The data is successfully being logged in the console but is not appearing on the page in Reactjs

I'm currently working on Reactjs with the Next.js framework. I'm trying to fetch data using axios, but the data isn't showing up on the page. However, when I check the console.log in the getStaticProps section (in blogs), the data is there. ...

Exploring NextJS: Where can I find the exportPathMap page data? It seems to be missing from getStaticProps

After configuring exportPathMap, I am encountering an issue where I receive an empty object when exporting getStaticProps from my component. I am confused about how to access the data properly. Can anyone provide guidance? // next.config.js exportPathMap: ...

Tips for positioning a div alongside its parent div

I have a unique setup with two nested divs that are both draggable. When I move the parent div (moveablecontainer), the child div (box.opened) follows smoothly as programmed. Everything works well in this scenario. However, when I resize the browser windo ...

Is the maxlength attribute malfunctioning in Chrome and Safari for HTML forms?

<input type="number" maxlength="5" class="search-form-input" name="techforge_apartmentbundle_searchformtype[radius]" id="techforge_apartmentbundle_searchformtype_radius"> I found this HTML snippet using the Firebug tool in Chrome. In Chrome and Saf ...

Updates to Providers in the latest release of Angular 2

When working with angular 2.0.0-rc.1, we implemented a Provider using the new Provider method as shown in the code snippet below: var constAccessor = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => EJDefaultValueAccessor), ...