'Hide and show the content of sibling elements on single click among them in ReactJS
Please click on the link https://cdn.dribbble.com/users/2079553/screenshots/6462890/accordion3.gif and see the GIF, which I am trying to create the same UI using ReactJs. Need to hide and show the contents of sibling p elements on basis of single click among them. Please find the code snippet below and result of the same on the following link https://codesandbox.io/s/vkij6. Please help me to create UI like the GIF. Thanks in Advance.
The code snippet:
App.js
import Toggle from './components/Toggle';
const cities = [
{
name: "Mysuru",
about: "Mysore (or Mysuru), a city in India's southwestern Karnataka state, was the capital of the Kingdom of Mysore from 1399 to 1947. In its center is opulent Mysore Palace, seat of the former ruling Wodeyar dynasty."
},
{
name: "Bengaluru",
about: "Bengaluru (also called Bangalore) is the capital of India's southern Karnataka state. The center of India's high-tech industry, the city is also known for its parks and nightlife. By Cubbon Park, Vidhana Soudha is a Neo-Dravidian legislative building."
},
{
name: "Udupi",
about: "Udupi is a city in the southwest Indian state of Karnataka. It's known for its Hindu temples, including the huge, 13th-century Sri Krishna Temple, which houses a statue of Lord Krishna and attracts many pilgrims."
},
{
name: "Mandya",
about: "Mandya is a city in the state of Karnataka. It is the headquarter of Mandya district and is located 45 kilometres from Mysore and 100 kilometres from Bangalore"
},
{
name: "Kodagu",
about: "Kodagu, also known as Coorg, is a rural district in the southwest Indian state of Karnataka. In the area’s north, Madikeri Fort has 2 life-size elephant statues at its entrance, plus a Gothic-style church with a museum on its grounds."
}
]
function App() {
return (
<div className="App">
<div className="toggle-container">
<div className="cities">
{cities.map((city) => (
<Toggle key={city.name.toString()} city={city} />
))}
</div>
</div>
</div>
);
}
export default App;
Toggle.js
export default function Toggle({ city }) {
const [toggle, setToggle] = useState(false);
const handleClick = () => {
setToggle(!toggle)
}
return (
<>
<p className="city-name" onClick={handleClick}>{city.name}</p>
<p className={toggle ? "city-about-show" : "city-about-hide"}>{city.about}</p>
</>
)
}
style.css
margin: 0;
padding: 0;
box-sizing:border-box
}
.App {
/* text-align: center; */
background-color: #000000;
padding-top: 5px;
padding-bottom: 5px;
position: relative;
}
.toggle-container {
background-color: hsla(245, 100%, 87%, 0.521);
transition: background-color 300ms;
width: 800px;
height: 98.3vh;
margin: auto;
padding-top: 70px;
}
.cities {
background-color: rgb(243, 244, 245);
width: 450px;
margin: auto;
border-radius: 3px;
}
.city-name{
font-family: sans-serif;
color: rgb(105, 105, 105);
padding: 15px 0 15px 15px;
letter-spacing: 0.5px;
cursor: pointer;
border-bottom: 1.5px solid rgb(172, 169, 169);
}
.city-name-symbol {
display: inline;
}
.city-about-hide{
display: none;
}
.city-about-show {
display: block;
font-family: sans-serif;
color: rgb(105, 105, 105);
background-color: rgb(214, 231, 247);
letter-spacing: 0.3px;
font-size: 14px;
padding: 20px 15px;
line-height: 1.5;
}
Solution 1:[1]
You use an individual toggle state for each city. I suggest to use a common state object that holds a toggle state for each city and move this state object to a parent component to prevent passing around the props when you want to open a specific city and at the same time close others cities.
import { useState } from 'react';
const cities = [
{
name: "Mysuru",
about: "Mysore (or Mysuru), a city in India's southwestern Karnataka state, was the capital of the Kingdom of Mysore from 1399 to 1947. In its center is opulent Mysore Palace, seat of the former ruling Wodeyar dynasty."
},
{
name: "Bengaluru",
about: "Bengaluru (also called Bangalore) is the capital of India's southern Karnataka state. The center of India's high-tech industry, the city is also known for its parks and nightlife. By Cubbon Park, Vidhana Soudha is a Neo-Dravidian legislative building."
},
{
name: "Udupi",
about: "Udupi is a city in the southwest Indian state of Karnataka. It's known for its Hindu temples, including the huge, 13th-century Sri Krishna Temple, which houses a statue of Lord Krishna and attracts many pilgrims."
},
{
name: "Mandya",
about: "Mandya is a city in the state of Karnataka. It is the headquarter of Mandya district and is located 45 kilometres from Mysore and 100 kilometres from Bangalore"
},
{
name: "Kodagu",
about: "Kodagu, also known as Coorg, is a rural district in the southwest Indian state of Karnataka. In the area’s north, Madikeri Fort has 2 life-size elephant statues at its entrance, plus a Gothic-style church with a museum on its grounds."
}
]
function Toggle({ city, toggle, handleClick }) {
return (
<>
<p className="city-name" onClick={() => handleClick(city.name)}>{city.name}</p>
<p className={toggle[city.name] ? "city city-about-show" : "city city-about-hide"}>{city.about}</p>
</>
)
}
function App() {
const [toggle, setToggle] = useState({
Mysuru: false,
Bengaluru: false,
Udupi: false,
Mandya: false,
Kodagu: false,
});
const handleClick = (city) => {
setToggle({
Mysuru: false,
Bengaluru: false,
Udupi: false,
Mandya: false,
Kodagu: false,
[city]: !toggle[city]
})
}
return (
<div className="App">
<div className="toggle-container">
<div className="cities">
{cities.map((city) => (
<Toggle key={city.name.toString()} city={city} toggle={toggle} handleClick={handleClick} />
))}
</div>
</div>
</div>
);
}
CSS
.city {
transition: height 1s;
overflow: hidden;
}
.city-about-hide{
height: 0;
}
.city-about-show {
height: 100px;
display: block;
font-family: sans-serif;
color: rgb(105, 105, 105);
background-color: rgb(214, 231, 247);
letter-spacing: 0.3px;
font-size: 14px;
padding: 20px 15px;
line-height: 1.5;
}
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 |
