es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Menú vertical en React

Necesito tener un menú vertical como en la siguiente imagen, en react.

enter image description here

Aquí está mi código:

function DropDownMenu({className}) {
    const [isOpen, setIsopen] = useState(false);

    const toggleDropDown = () => {
        setIsopen(isOpen => !isOpen)
    }

    return (
        <nav classname="{styles.nav}">
            <ul>
                <li onclick="{toggleDropDown}"><a href='#settings'>item1</a>
                    {isOpen && <ul>
                        <li><a href='#settings'>sub-item1</a></li>
                        <li><a href='#settings'>sub-item2</a></li>
                        <li><a href='#settings'>sub-item-3</a></li>
                    </ul>}
                </li>
                <li onclick="{toggleDropDown}"><a href='#message'>item3</a>
                    {isOpen &&
                        <ul>
                            <li><a href='#settings'>sub-item1</a></li>
                            <li><a href='#settings'>sub-item2</a></li>
                        </ul>
                    }
                </li>
            </ul>
        </nav>
    );
}

Le falta ocultar/mostrar cada elemento por separado y una flecha con alguna animación cuando se abre/cierra.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para tener un menú vertical como el mostrado en la imagen, se pueden realizar algunas modificaciones en el código existente. Aquí están los pasos:

    1. En primer lugar, el menú debe estar alineado verticalmente. Para ello, agrega el siguiente estilo al elemento padre ul:
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      

      Esto alineará los elementos del menú en el centro del contenedor de manera vertical.

    2. Para agregar una flecha que se anima cuando se abre o se cierra el menú, podemos usar transiciones CSS. Agrega los siguientes estilos a los elementos li que tienen un submenú:

      position: relative;
      &:before {
       content: "";
       position: absolute;
       top: 50%;
       right: 0;
       transform: translateY(-50%);
       width: 0;
       height: 0;
       border-top: 5px solid transparent;
       border-bottom: 5px solid transparent;
       border-left: 5px solid #fff;
       transition: transform 0.3s ease;
      }
      &.open:before {
       transform: translateY(-50%) rotateZ(-90deg);
      }
      

      Esto creará una flecha que apunta hacia la derecha y se sitúa a la derecha del elemento padre del menú. Cuando se abre el submenú, girará para apuntar hacia arriba.

    3. Para ocultar/mostrar cada submenú por separado, agrega una variable de estado para cada submenú. Por ejemplo:

      const [isOpen1, setIsOpen1] = useState(false);
      const [isOpen2, setIsOpen2] = useState(false);
      

      Estas variables de estado se pueden utilizar para controlar la visibilidad de cada submenú. La función onClick del elemento padre del menú se puede actualizar para alternar la variable de estado del submenú correspondiente.

      <li onclick="{()" ==""> {
         setIsOpen1(!isOpen1);
       }}
       className={isOpen1 ? "open" : ""}
      >
       <a href="#settings">item1</a>
       {isOpen1 && (
         <ul>
           <li>
             <a href="#settings">sub-item1</a>
           </li>
           <li>
             <a href="#settings">sub-item2</a>
           </li>
           <li>
             <a href="#settings">sub-item3</a>
           </li>
         </ul>
       )}
      </li>
      

      Esto agregará la clase open al elemento padre del menú cuando el submenú correspondiente esté visible. El submenú se mostrará cuando la variable de estado isOpen sea verdadera.

    Poniéndolo todo junto, el código actualizado se vería algo así:

    function DropDownMenu({ className }) {
      const [isOpen1, setIsOpen1] = useState(false);
      const [isOpen2, setIsOpen2] = useState(false);
    
      return (
        <nav classname="{styles.nav}">
          <ul style="{{" display:="" "flex",="" flexdirection:="" "column",="" justifycontent:="" "center",="" alignitems:="" "center"="" }}="">
            <li onclick="{()" ==""> {
                setIsOpen1(!isOpen1);
              }}
              className={isOpen1 ? "open" : ""}
              style={{ position: "relative" }}
            >
              <a href="#settings">item1</a>
              {isOpen1 && (
                <ul>
                  <li>
                    <a href="#settings">sub-item1</a>
                  </li>
                  <li>
                    <a href="#settings">sub-item2</a>
                  </li>
                  <li>
                    <a href="#settings">sub-item3</a>
                  </li>
                </ul>
              )}
            </li>
            <li onclick="{()" ==""> setIsOpen2(!isOpen2)} className={isOpen2 ? "open" : ""} style={{ position: "relative" }}>
              <a href="#message">item2</a>
              {isOpen2 && (
                <ul>
                  <li>
                    <a href="#settings">sub-item1</a>
                  </li>
                  <li>
                    <a href="#settings">sub-item2</a>
                  </li>
                </ul>
              )}
            </li>
            <li>
              <a href="#setting">item3</a>
            </li>
          </ul>
        </nav>
      );
    }
    

    Nota: Se asume que la variable styles utilizada en el código está definida en otro lugar del módulo.

Comments are closed.