In your JSX, I've changed the active class name to the left div. And using it to "push" the right panel when it's expanded instead of hiding the right panel, so we can get the transition working when toggling it.
import React, { useState } from 'react';
import './App.css';
function App() {
const [isActive, setIsActive] = useState(true);
return (
<>
<div className="container">
<div className={isActive ? 'left' : 'left-expanded'}>
<button className="handle" onClick={() => setIsActive(!isActive)}>
Open
</button>
</div>
<div className="right">
<input type="text" />
<br />
<input type="text" />
</div>
</div>
</>
);
}
export default App;
And in your CSS, we now use min-width
on the left div so it grows and shrinks in response to the active state. With overflow: hidden
set on the container div, the right panel will be invisible when the left div is fully expanded. See the comments in the following CSS code for more explanation.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
padding: 2rem;
}
.container {
height: 100px;
display: flex;
/* Ensure the right div is complete invisible when left div is expanded */
overflow: hidden;
}
.left {
height: 100%;
/* Use this to push the right div */
min-width: 70%;
background-color: red;
/* We only want the transition to take effect for the `min-width` property */
transition: min-width 0.5s ease-in-out;
}
.left-expanded {
height: 100%;
min-width: 100%;
background-color: red;
transition: min-width 0.5s ease-in-out;
}
.right {
height: 100%;
min-width: 30%;
background-color: blue;
}
.right input {
width: 100%;
}
.handle {
position: relative;
top: 50%;
/* Center the handle with translate, see this great answer on SO: https://stackoverflow.com/a/16801578/1727948 */
transform-origin: left;
transform: translate(50%, 50%) rotate(270deg);
/* Ensure the handle stay in the left div, you can tweak the `-30px` to your desired position */
left: calc(100% - 30px);
}
Here is a working codepen