Making scrollable div in CSS - javascript

I am making React project but I faced error with css.
Is there any possible way to leave parent and child component same and just make scroll on the left side for the div where are shopping items. I tried with overwflow-y: scroll but it just creates scroll and doesn't make scrollable even if I put some random height. There is way I know but unfortunately at the moment I cant find it.
Parent html
const CartModal = () => {
const { totalPrice, totalAmount } = useSelector((state) => state.cart);
return (
<div className={classes["cart-modal"]}>
<div className={classes["cart-modal__navbar"]}></div>
<div className={classes["cart-modal__body"]}>
<div className={classes["body__left-side"]}>
<h1>ORDERS</h1>
<CartModalFoodList />
</div>
<div className={classes["body__right-side"]}>
<div>
<img src={BigCart} />
</div>
<div>
<h2>Total price:</h2>
<h2>{totalPrice}$</h2>
</div>
<div>
<h2>Total amount:</h2>
<h2>{totalAmount}</h2>
</div>
</div>
</div>
</div>
);
};
.cart-modal {
z-index: 100;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 65vw;
height: 75vh;
background-color: var(--main-bg-color);
border-radius: 10px;
box-shadow: 1px 2px 5px;
overflow: hidden;
}
.cart-modal__navbar {
width: 100%;
height: 15vh;
background: radial-gradient(
50% 50% at 50% 50%,
var(--gradient-color-one) 0%,
var(--gradient-color-two) 100%
);
}
.cart-modal__body {
display: flex;
height: 100%;
}
.body__left-side {
height: 100%;
width: 55%;
background-color: white;
padding: 0 3.5%;
}
.body__left-side h1 {
color: var(--strong-yellow);
text-align: center;
border-bottom: 1px solid var(--weak-yellow);
padding-bottom: 2%;
}
.body__right-side {
width: 45%;
height: 100%;
display: flex;
flex-direction: column;
}
.body__right-side div:first-child {
height: 50%;
width: 100%;
}
.body__right-side div:first-child img {
height: 100%;
width: 100%;
}
.body__right-side *:not(:first-child) {
display: flex;
justify-content: space-around;
}
.body__right-side *:not(:first-child) h2 {
font-size: 2vw;
margin: 2.5% 0;
}
Left side div
const MenuList = (props) => {
const page = props.page;
const dispatch = useDispatch();
const foodArray = props.foodList;
const navigate = useNavigate();
const location = useLocation();
const params = useParams();
const [foodList, setFoodList] = useState([]);
useEffect(() => {
setFoodList(formatArray(foodArray));
}, [foodArray]);
const queryPrams = new URLSearchParams(location.search);
const sort = queryPrams.get("sort");
const onNextPageHandler = () => {
dispatch(uiSliceActions.updatePage("forward"));
};
const onPreviousPageHandler = () => {
dispatch(uiSliceActions.updatePage("backward"));
};
const onSortPageHandler = () => {
navigate(
`/menu/${params.foodId ? params.foodId + "/" : ""}?sort=${
sort === "asc" ? "desc" : "asc"
}`
);
let foodListPart = foodList[page];
let foodListSort = foodList;
const sortFoodList = (sort) => {
foodListPart = foodListPart.sort((a, b) =>
sort === "asc" ? a.foodPrice - b.foodPrice : b.foodPrice - a.foodPrice
);
foodListSort[page] = foodListPart;
setFoodList(foodListSort);
};
sort === "asc" ? sortFoodList("asc") : sortFoodList("desc");
};
return (
<Fragment>
<div className={classes["menu-list"]}>
{foodList[page]
? foodList[page].map((foodObj) => (
<MenuItem key={foodObj.id} foodObj={foodObj} />
))
: ""}
</div>
<div className={classes["menu-list__buttons"]}>
{page >= 1 && (
<Button type="button" onClick={onPreviousPageHandler}>
Page {page}
</Button>
)}
<Button
type="button"
onClick={onSortPageHandler}
className={classes["sort-button"]}
>
{sort === "asc" ? `Descending` : `Ascending`}
</Button>
<Button type="button" onClick={onNextPageHandler}>
Page {page + 2}
</Button>
</div>
</Fragment>
);
};
And css for that div
.menu-list {
overflow-y: scroll;
}
Thank you.

Define the height of the div, then add overflow: auto;

You just need to add overflow-y: scroll to "body__left-side" class
.body__left-side {
height: 100%;
width: 55%;
background-color: white;
padding: 0 3.5%;
overflow-y: scroll;
}

just add over-flow: "auto" to cart-modal__body class

I have fixed this issue by correcting .body__left-side
.body__left-side {
height: 100%;
width: 55%;
background-color: white;
padding: 0 3.5%;
overflow-y: scroll;
}
And also by correcting .menu-list
.menu-list {
height: auto;
padding-bottom: 25%;
}
Thanks to everyone for help.

Related

Netflix kind of carousel ui button recreating divs using getComputedStyle css

I am trying to recreate netflix kind of carousel ui using this wds tutorial (https://www.youtube.com/watch?v=yq4BeRtUHbk) for movie cast details using Reactjs and running through a problem.
I am fetching data from moviedb database and trying to achieve netflix like carousel effect.
the problem is when i click button for changing the slider index using getComputedStyle in css,
I get entire div recreated again several times.
I Fetch the data in the MovieDetails component and pass it to MovieDetailsPage component
export default function MovieDetails() {
const [MovieDetail, setMovieDetail] = useState([])
const [CastDetails, setCastDetails] = useState([])
const { id } = useParams();
const API_Key = '4ee812b6fb59e5f8fc44beff6b8647ed';
console.log('this is id', id);
useEffect(() => {
getDetail();
getCastDetails();
console.log('main');
}, [id])
const getDetail = useCallback(() => {
fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=${API_Key}&language=en-US`)
.then(res => res.json())
.then(data => {
console.log(data, 'data');
setMovieDetail(data)
})
}, [id])
const getCastDetails = useCallback(() => {
fetch(`https://api.themoviedb.org/3/movie/${id}/credits?api_key=${API_Key}&language=en-
US`)
.then(res => res.json())
.then(data => {
setCastDetails(data.cast)
}
)
console.log('get cast details rendered');
}, [id])
useEffect(() => {
console.log(MovieDetail, 'Moviedetils')
}, [MovieDetail])
return (
<div>
<MoviesDetailsPage {...MovieDetail} CastDetails={CastDetails} API_Key={API_Key} />
</div>
)
}
MovieDetailsPage.jsx
export default function MoviesDetailsPage({ id, poster_path, backdrop_path, API_Key,
CastDetails }) {
const API_image = 'https://image.tmdb.org/t/p/w500/';
document.addEventListener('click', e => {
e.preventDefault();
let handle;
if(e.target.matches(".handle")){
handle = e.target
}else{
handle = e.target.closest(".handle")
}
if(handle != null) onHandleClick(handle)
})
function onHandleClick(handle){
const slider = handle.closest(".MovieCastContainer").querySelector(".slider")
console.log(slider, 'sliderindex')
const sliderIndex = parseInt(getComputedStyle(slider).getPropertyValue("--slider-index"))
if(handle.classList.contains("left-handle")){
slider.style.setProperty("--slider-index", sliderIndex - 1)
}
if(handle.classList.contains("right-handle")){
slider.style.setProperty("--slider-index", sliderIndex + 1)
}
}
const castInfo = CastDetails && CastDetails.map(data => <img src={API_image+data.profile_path}
alt={data.name} />)
console.log(CastDetails, 'Castdetails')
return (
<div className="MovieDetailsPageCont">
<div className='MovieDetailsContainer'>
<div className="headerImg"><img src={API_image + backdrop_path}
alt='backdrop_path' style={{ width: '100%', borderRadius: '10px' }} /></div>
<div className="movieid">{id}</div>
</div>
<div className='MovieCastContainer'>
<button className="handle left-handle">
<div className="text">‹</div>
</button>
<div className='slider'>
{
castInfo ? castInfo : '...Loading'
}
</div>
<button className="handle right-handle">
<div className="text">›</div>
</button>
</div>
</div>
)
}
My css page where change the slider index to transfrom to next set of values
*, *::after, *::before{
box-sizing: border-box;
}
:root{
--slider-padding: 5rem;
}
.MovieCastContainer{
display: flex;
justify-content: center;
overflow: hidden;
}
.slider{
--slider-index: 0;
display: flex;
flex-grow: 1;
margin: 0 .25rem;
transform: translateX(calc(var(--slider-index) * -100%));
transition: transform 250ms ease-in-out;
}
.slider > img {
flex: 0 0 25%;
max-width: 25%;
aspect-ratio: 16 / 9;
padding: .25rem;
border-radius: 1rem;
overflow: hidden;
}
.handle{
border: none;
border-radius: 1rem;
flex-grow: 0;
background-color: rgba(0, 0, 0, .25);
z-index: 10;
margin: .25rem 0;
padding: 0 .5rem;
cursor: pointer;
font-size: 5rem;
display: flex;
align-items: center;
justify-content: center;
color: white;
line-height: 0;
transition: font-size 150ms ease-in-out;
}
.left-handle{
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.right-handle{
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.handle:hover,
.handle:focus {
background-color: rgba(0, 0, 0, .5);
}
.handle:hover .text,
.handle:focus .text{
transform: scale(1.2)
}
Everytime I click next button in ui the I get this
please if you can help out with this any help would be appreciated.

If statement is working but I dont know why | React.js + styled-Components

I want to make a plus symbol ("+") with two <div>s. If you click on the parent container you toggle the viability of the <Vertical /> div from true to false (viable to not-viable) so it becomes a minus ("-").
I have the following code and it works but I don't know why:
function Nav() {
const [visability, setVisability] = useState(true); /* <--it first renders "+", changes to "-"
const changeVisability = () => {
setVisability(!visability)
console.log("Visability=", visability);
};
return (
<Button onClick={changeVisability}>
<ListItemsNoRightSpace>More</ListItemsNoRightSpace>
<Plus>
<Horizontal />
{visability ? (<Vertical />) : (<Vertical />, <Horizontal />)}
</Plus>
</Button>
)
};
const Plus = styled.div`
display: block;
grid-column: 1;
grid-row: 1;
position: relative;
width: 30px;
height: 30px;
margin-left: -2px;
`
const Horizontal = styled.div`
position: absolute;
top: 14px;
left: 9px;
width: 12px;
height: 2px;
background-color: black;
`
const Vertical = styled.div`
position: absolute;
left: 14px;
top: 9px;
width: 2px;
height: 12px;
background-color: black;
`
/* and why does this not work?
<Plus>
<Horizontal />
{visability ? (<Vertical />) : ()} // in other words: () = "render nothing"
</Plus>
*/
or is there a better way to write this function?
from true to false (Mehr = More in German)

The way to optimize react and Typescript codes

In this case, I used React + TypeScript and ant-design. The following code works perfectly but I want the codes to be summarized as much as possible. This is about starting a site that has 3 pages. For example, how can I write this part (const { id, title, description, background } = splash;) so that I don't need to define (splashs[index].background , splashs[index].title, splashs[index].description) all the time.
Thank you in advance for your cooperation.
.splash {
height: 100vh;
position: relative;
overflow: hidden;
}
.bg {
background-color: var(--cjp);
}
.BgGradiant {
background: linear-gradient(107.78deg, rgba(80, 21, 100, 0) 1.87%, rgba(80, 21, 100, 0.05) 18.6%, rgba(80, 21, 100, 0.51) 25.79%, #1C3396 99.02%, #1C3396 51.08%);
}
.context{
width: 80%;
}
.content {
text-align: center;
}
.content h1,
.content p {
color: var(--cwh);
}
.backgroundImage>img {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -1;
-o-object-fit: cover;
object-fit: cover;
}
.logo {
width: 100%;
text-align: center;
}
.btns {
display: flex !important;
align-items: center;
justify-content: space-between;
-webkit-margin-start: auto;
margin-inline-start: auto;
-webkit-margin-end: auto;
margin-inline-end: auto;
-webkit-margin-before: 2rem;
margin-block-start: 7rem;
}
.btns :global(.ant-btn){
background-color: var(--cwh);
border-radius: var(--borderRadius12);
position: relative;
padding: 4px 10px !important;
}
.btns :global(.ant-btn)::after{
content: "";
position: absolute;
width: 125%;
height: 125%;
top: 50%;
left: 50%;
border: 1px solid var(--chb);
border-radius: var(--borderRadius14);
transform: translate(-50%, -50%);
}
.btns :global(.ant-btn > span){
margin-left: 0 !important;
}
.btns :global(.ant-btn > span > svg){
fill: var(--cal);
}
.btnSkip {
background-color: unset;
outline: none;
border: none;
color: var(--cca);
}
.btnLogin{
-webkit-margin-before: 2rem;
margin-block-start: 7rem;
}
.btnLogin :global(.ant-btn){
border-radius: var(--borderRadius10);
background-color: var(--cwh);
color: var(--cjp);
}
.btnLogin :global(.ant-btn > span){
font-family: "Display-Bold";
}
.dots {
position: absolute;
bottom: 17%;
display: flex !important;
align-items: center;
justify-content: center;
left: 50%;
transform: translateX(-50%);
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.dotActive {
background-color: var(--cwh);
}
.dotDeActive {
background-color: var(--cca);
}
.dot:not(:last-child) {
-webkit-margin-end: 0.5rem;
margin-inline-end: 0.5rem;
}
.contentInner{
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
-webkit-padding-before: 2rem;
padding-block-start: 2rem;
-webkit-padding-after: 3rem;
padding-block-end: 3rem;
}
.contentInner1{
justify-content: space-between;
}
.contentInner2{
justify-content: flex-end;
}
import React, { useState } from 'react';
import { useNavigate } from "react-router-dom";
import { Row, Col, Button } from 'antd';
import { ArrowRightOutlined } from '#ant-design/icons';
import Container from '../../Components/UI/Container/Container'
import classes from './Splash.module.css';
import { backgroundSplash1, backgroundSplash2, logoImage } from '../../Assets/index';
const Splash = () => {
let navigate = useNavigate();
const [index, setIndex] = useState<number>(0);
const {
splash,
bg,
BgGradiant,
context,
content,
backgroundImage,
logo,
btns,
btnLogin,
btnSkip,
dots,
dot,
dotActive,
dotDeActive,
contentInner,
contentInner1,
contentInner2,
} = classes
const splashs = [
{
id: 0,
title: 'Page 1 : title 1',
desctiption: '1- Lorem ipsum 1 ',
background: logoImage,
},
{
id: 1,
title: 'Page 2 : title 2',
desctiption: '2- Lorem ipsum 2 ',
background: backgroundSplash1,
},
{
id: 2,
title: 'Page 3 : title3',
desctiption: '3- Lorem ipsum 3',
background: backgroundSplash2,
}
];
const nextBnt = () => {
setIndex(index + 1);
if (index === splashs.length - 1) {
return navigate("/login");
}
}
const skipBtn = () => {
console.log('skip ');
return navigate("/login");
}
const loginBtn = () => {
return navigate("/login");
}
return (
<>
<Row>
<Col xs={24}>
<section
className={`${index === 0 ? bg : BgGradiant} ${splash}`}>
{
splashs.map((splash) => {
const { id, title, desctiption, background } = splash;
console.log(title, "title");
return (
<>
{
index !== 0 && (
<div className={backgroundImage}>
<img src={splashs[index].background} />
</div>
)
}
<Container key={id} className={backgroundImage}>
<div className={`${index === 0 ? contentInner1 : contentInner2} ${contentInner}`}>
{
index === 0 && (
<div className={logo}>
<img src={logoImage} alt="logoImage" />
</div>
)
}
<div className={context}>
<div className={content}>
<h1>{splashs[index].title}</h1>
<p>{splashs[index].desctiption}</p>
</div>
{/* BTNS */}
{
index === splashs.length - 1 ? (
<div className={btnLogin}>
<Button block onClick={loginBtn}>Login</Button>
</div>
) : (
<div className={btns}>
<button className={btnSkip} onClick={skipBtn}>skip</button>
<Button onClick={nextBnt}> <ArrowRightOutlined /></Button>
</div>
)
}
</div>
</div>
</Container>
</>
)
})
}
<div className={dots}>
{
Array.from({ length: 3 }).map((item, idx) => {
return (
<div key={idx} className={`${dot} ${index === idx ? dotActive : dotDeActive}`}></div>
)
})
}
</div>
</section>
</Col>
</Row>
</>
)
}
export default Splash;
Just an advice, your question isn't really well formulated so it's hard to understand what are you trying to accomplish. Try to keep the questions clear and remove any redundant code so the community can better understand it.
If I'm assuming correctly that you don't want to use splash[index] then you should change splash[index].title to title, same for the other props.
Since you already destructured the splash object with const { id, title, description, background } = splash; all these will be available.
Another thing here is, .map method returns the item in the array so I don't see the point in you using the index inside the loop to access the item from the array.

how to make a vertical slide of text in React

I am trying to make a vertical text slide. Having not found help in reactjs, I try to do it myself and I'm pretty happy with the result but a slight bug appears at the end of each word slide.
I imagine that there are several ways to create this animation but it is the only one that comes to me with my knowledge in JS.
Here my code:
import React, { useEffect, useRef, useState } from 'react'
const Version1 = () => {
const [ words, setWords ] = useState(['Victor', 'Alex', 'Lucie'])
const wrapperRef = useRef()
const handleAnim = () => {
setTimeout(() => {
const copyWords = [ ...words ];
const firstElem = copyWords.splice(1)
wrapperRef.current.style.transition = 'none';
wrapperRef.current.style.top = '0px'
setWords([ ...firstElem.concat(copyWords) ])
},1000);
wrapperRef.current.style.transition = '0.5s';
wrapperRef.current.style.top = '-70px'
}
useEffect(() => {
setTimeout(() => {
handleAnim()
}, 2000);
})
return (
<>
<div className="test-container">
<div className='test-title'>Hello</div>
<div className='text-container-word'>
<div ref={wrapperRef} className='text-container-word-wrapper'>
<span className='text-word'>{words[0]}</span>
<span className='text-word'>{words[1]}</span>
</div>
</div>
</div>
<style jsx>
{`
.test-container {
padding: 100px 0;
width: 100%;
display: flex;
}
.test-title {
font-size: 48px;
font-weight: bold;
color: blue;
}
.text-container-word {
position: relative;
width: 200px;
height: 70px;
background-color: green;
display: inline-block;
overflow: hidden;
margin-top: -7px;
}
.text-container-word-wrapper {
height: auto;
position: relative;
top: 0px;
}
.test-container h1 {
position: relative;
display: inline;
padding: 10px;
}
.text-word {
height: 70px;
font-size: 48px;
font-weight: bold;
display: block;
transition: 0.5s;
line-height: 70px;
}
`}
</style>
</>
)
}
export default Version1
Here is a pure css based solution that uses words from state without the useEffect hacks.
const {useState} = React;
function App() {
const [words, setWords] = useState(["Victor", "Alex", "Lucie", "Michael"]);
return (
<div className="App">
<div className="scroller">
<span>
{words[0]}
<br />
{words[1]}
<br />
{words[2]}
<br />
{words[3]}
</span>
</div>
</div>
);
}
ReactDOM.render(
<App/>,
document.getElementById("react")
);
.App {
font-family: sans-serif;
text-align: center;
}
.scroller {
height: 1.2em;
line-height: 1.2em;
position: relative;
overflow: hidden;
font-size: 40px;
text-align: center;
}
.scroller > span {
position: absolute;
top: 0;
animation: slide 6s infinite;
font-weight: bold;
background-color: green;
}
#keyframes slide {
0% {
top: 0;
}
25% {
top: -1.2em;
}
50% {
top: -2.4em;
}
75% {
top: -3.6em;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react">
set height and width with overflow-f:scroll
overflow-y: scroll;
you can also see this: https://www.w3schools.com/cssref/tryit.asp?filename=trycss3_overflow-y

create an expand content or show more content button in react app

So i am trying to basically add a expand button to my react app that will reveal more information and i would prefer that the app expand the div size to reveal the additional content, so the its basically an expand button, i understand i need to utilize the usestate property and a function however i am having a hard time figuring out how do i update the css of the student div to expand and reveal the added information. The added information is the grades portion (FYI).
UPDATE: I have found a way to display the changes the problem i am facing is to get the state to start as isExpanded false so when a user clicks the plus button it expands to reveal the class hidden information again
here is my App.js file
import React, { useState } from "react";
import "./App.css";
export default function App() {
const [students, setStudents] = useState(null);
const [filterData, setFilterData ] = useState(null);
const [isExpanded, setIsExpanded] = useState(false);
const studentdata = 'https://www.hatchways.io/api/assessment/students';
function getStudents(){
fetch(studentdata)
.then(resp => resp.json())
.then(data => {
setFilterData(data.students);
setStudents(data.students);
setIsExpanded(false);
})
}
const searchByName = (event) => {
event.persist();
// Get the search term
const searchItem = event.target.value.toLowerCase().trim();
// If search term is empty fill with full students data
if(!searchItem.trim()) {
setFilterData(students);
}
// Search the name and if it found retun the same array
const serachIn = (firstName, lastName) => {
if(firstName.indexOf(searchItem) !== -1 || lastName.indexOf(searchItem) !== -1) {
return true;
}
let fullName = firstName.toLowerCase()+" "+lastName.toLowerCase();
if(fullName.indexOf(searchItem) !== -1) {
return true;
}
return false;
};
// Filter the array
const filteredData = students.filter((item) => {
return serachIn(item.firstName, item.lastName);
});
// Set the state with filtered data
setFilterData(filteredData);
}
function exp() {
if(isExpanded){
setIsExpanded(true);
}
}
return (
<div className="App">
<h1>Students</h1>
<div>
<button className="fetch-button" onClick={getStudents}>
Get Students
</button>
<br />
</div>
<div className="search" id="search">
<input type="text" name="serachByName" id="searchbar" placeholder="Search by name" onChange={(e) => searchByName(e)} ></input>
</div>
{filterData && filterData.map((student, index) => {
var total = 0;
for(var i = 0; i < student.grades.length; i++) {
var grade = parseInt(student.grades[i]);
total += grade;
}
const avg = total / student.grades.length;
const average = avg.toString();
const grade1 = student.grades[0];
const grade2 = student.grades[1];
const grade3 = student.grades[2];
const grade4 = student.grades[3];
const grade5 = student.grades[4];
const grade6 = student.grades[5];
const grade7 = student.grades[6];
const grade8 = student.grades[7];
return(
<div className={'student' + isExpanded ? 'expanded' : '' } key={index}>
<div className="image">
<img src={student.pic} id="icon"></img>
</div>
<div className="text">
<h3 id="name">{student.firstName} {student.lastName}</h3>
<p id="detail"><strong>EMAIL:</strong> {student.email}</p>
<p id="detail"><strong>COMPANY:</strong> {student.company}</p>
<p id="detail"><strong>SKILL:</strong> {student.skill}</p>
<p id="detail"><strong>AVERAGE:</strong>: {average}%</p>
<p id="detail" className="hidden">
<br></br>Test 1 :{grade1}
<br></br>Test 2 :{grade2}
<br></br>Test 3 :{grade3}
<br></br>Test 4 :{grade4}
<br></br>Test 5 :{grade5}
<br></br>Test 6 :{grade6}
<br></br>Test 7 :{grade7}
<br></br>Test 8 :{grade8}
</p>
</div>
<div className="expand">
<button className="expand_btn" onClick={exp()} id="expand_btn">+</button>
</div>
</div>
)}
)}
</div>
);
}
and my css file
#import url('https://fonts.googleapis.com/css?family=Bebas+Neue&display=swap');
#import url('https://fonts.googleapis.com/css?family=Roboto:300,400&display=swap');
.root{
width: 100vw;
height: 100vh;
background-color: black;
}
.App {
text-align: center;
width: 1000px;
height: 750px;
background-color: aliceblue;
border: 4px solid black;
border-radius: 5%;
margin-top: 75px;
margin-left: auto;
margin-right: auto;
overflow: scroll;
}
.student{
width: 80%;
height: 200px;
background-color: white;
display: flex;
align-items: center;
padding-top: 3%;
padding-bottom: 3%;
border: 2px solid lightblue;
margin-left: auto;
margin-right: auto;
}
.text{
text-align: left;
padding-left: 7%;
width: 300px;
}
.image{
padding-left: 15%;
}
#icon{
border-radius: 50%;
width: 150px;
height: 150px;
border: 2px solid black;
}
#name{
text-transform: capitalize;
font-family: 'Bebas Neue';
letter-spacing: 4px;
font-size: 40px;
margin-bottom: 10px;
margin-top: 10px;
}
#detail {
font-family: 'Roboto';
font-weight: 300;
line-height: normal;
margin: 0;
}
.search {
width: 80%;
height: 20px;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
margin-bottom: 20px;
}
#searchbar {
width: 100%;
height: 30px;
font-family: 'Roboto';
font-size: 18px;
font-weight: 300;
}
.expand {
width: 100px;
height: 100px;
padding-left: 3%;
margin-bottom: 5%;
}
#expand_btn {
font-family: 'Bebas Neue';
font-size: 50px;
color: lightskyblue;
background-color: transparent;
border: none;
}
.hidden {
display: none;
}
.expanded{
width: 80%;
height: 300px;
background-color: white;
display: flex;
align-items: center;
padding-top: 3%;
padding-bottom: 3%;
border: 2px solid lightblue;
margin-left: auto;
margin-right: auto;
}
I have fixed the issue in this codesandbox - https://codesandbox.io/s/purple-bird-j5vrm
Check and let me know if this helps.
There are many ways to solve your problem. One way is adding isExpanded flag to each object in the students array so that each student object would know if that is expanded or not. And I have used the flag like this
className={"student " + student.isExpanded ? "expanded" : " "}
As per your implementation, isExpanded was being set globally so every student item would be set as Expanded and there was no way to know which item was expanded.
Note: I have implemented only for getStudents and not filterStudents.

Categories

Resources