I have cards with categories, clicking on which opens hidden content. I need the card to close when switching between them and if a click occurs behind the content.
import React, { useRef } from "react";
import s from "./Shop.module.css";
import { useState } from "react";
export const Shop = () => {
const card = [
{
name: "Brands",
cat: ["Adidas", "Nike", "Reebok", "Puma", "Vans", "New Balance"],
show: false,
id: 0,
},
{
name: "Size",
cat: ["43", "43,5"],
show: false,
id: 1,
},
{
name: "Type",
cat: ["Sneakers ", "Slippers"],
show: false,
id: 2,
},
];
const [active, setActive] = useState({});
const handleActive = (id) => {
setActive({ ...active, [id]: !active[id] });
};
const handleDisable = (index) => {
setActive(index);
};
return (
<div className={s.container}>
<div className={s.brandInner}>
{card.map((i, index) => {
return (
<div className={s.brandCard} key={i.id}>
<button
className={`${s.brandBtn} `}
onClick={() => handleActive(i.id, index)}
onBlur={() => handleDisable(index)}
>
<p className={`${active[i.id] ? `${s.brandBtnActive}` : ``}`}>
{i.name}
</p>
</button>
<div
className={`${s.openCard} ${active[i.id] ? "" : `${s.dNone}`}`}
>
<ul className={s.brandList}>
{i.cat.map((elem) => {
return (
<li key={elem} className={s.brandItem}>
{elem}
</li>
);
})}
</ul>
<button className={s.brandOpenBtn}>Apply</button>
</div>
</div>
);
})}
</div>
</div>
);
};
I tried to do it through onBlur, but this way I can't interact with the content that appears when opening the card, please help
You could do this a few different ways, here are two.
Array version
You can do this by using a array to keep track of the ids that are active.
For the event handler we will creata a new
toggleActivefunction which replaces the others. This will check if theidis already in the array and if so remove it, else add it.Then in the return of the component we need to updated some logic as well. Then handlers only take in the
idof thei. To check if theidis in the array with can useincludes.Object version
This version is to do it with a object.
The handler, this will toggle the value of the
idstarting with false if there is no value for the id yet.The elements
Edit: toggle with closing others
First we declare the state with a initial value of
nullWe create the toggleActive function which checks if the
idto toggle is the previous id, if so return null else return the new active idFor the rendering it is quite simple, add the
toggleActivefunction to the button and check if theactiveis the same id