I have this component where there is a button and a div containing an input element. When the button is clicked the div is supposed to slide down opening the container and show the input field and if it is clicked again then it will close sliding up.
Right now when the button is clicked, it is working in the opposite way. That is opening sliding up but closing sliding down.
I'm using max-height
and will-change
css properties to make it work. How can I fix it?
Here's the CodeSandbox.
Here's the Component:
import { useState } from "react";
import "./styles.css";
export default function App() {
const [ isOpen, setIsOpen ] = useState( false );
const handleOpen = () => {
setIsOpen( !isOpen );
};
return (
<div className="App">
<button onClick={handleOpen}>Open</button>
<div className={`container ${isOpen ? "containerOpened" : "containerClosed"}`}>
<input type="text" />
</div>
</div>
);
}
Here's CSS:
.App {
font-family: sans-serif;
text-align: center;
position: relative;
}
.container {
position: absolute;
bottom: -46px;
right: 0;
margin-right: 30px;
padding: 10px 20px;
background: #fff;
border: 1px solid #e2e2e2;
transition: all 0.3s ease-in-out;
}
.containerClosed {
overflow: hidden;
max-height: 0;
transition: all 0.3s ease;
will-change: transform;
}
.containerOpened {
max-height: 100px;
overflow: hidden;
transition: all 0.3s ease;
will-change: transform;
}
.container input {
border: none;
outline: none;
border-bottom: 1px solid #e2e2e2;
width: 200px;
}
Please note that I need to use absolute positioning as well as margin padding to the container.
CodePudding user response:
Try this:
.App {
font-family: sans-serif;
text-align: center;
position: relative;
}
.container {
position: absolute;
top: 46px;
right: 0;
margin-right: 30px;
padding: 0;
background: #fff;
border: 1px solid #e2e2e2;
transition: all 0.3s ease-in-out;
}
.containerClosed {
overflow: hidden;
height: 0;
}
.containerOpened {
max-height: 100px;
overflow: hidden;
height: 100px
}
.container input {
border: none;
outline: none;
border: 1px solid #e2e2e2;
width: 200px;
}