Reputation: 5235
I would like to apply a class on a specific element of loop map.
const items = [
{
key: 'Menu1key',
content: 'Menu 1',
},
{
key: 'Menu2',
content: 'Menu2key'
},
{
key: 'Menu3Key',
content: 'Menu3',
children: [{
key: 'SubMenu3Key',
content: 'SubMenu3',
},
{
key: 'SubMenu5Key',
content: 'SubMenu5'
}]
},
{
key: 'Menu4Key',
content: 'Meu4',
children: [{
key: 'SubMenu4Key',
content: 'SubMenu4',
},
{
key: 'SubMenu5Key',
content: 'SubMenu5'
}]
}
]
const StackedMenu = (props) => {
let [chevronRotation, setChevronRotation] = useState('')
let [itemClicked, setItemClicked] = useState(props.itemClicked);
let [depth, setDepth] = useState(props.depth)
return (<Menu primary defaultActiveIndex={0} activeIndex={itemClicked} vertical pointing style={{ width: '100%' }}>
{props.items.map((item, index) => {
return (<>
<MenuItem onClick={(e, data) => { setItemClicked(data.index); setChevronRotation(`rotate`) }} index={index} key={index} pointing="start" >
<Menu.ItemContent style={depth > 0 ? { paddingLeft: '0.5em' } : null} >{item.content}</Menu.ItemContent>
{item.children ?
(<Menu.ItemIcon id={index} style={{ right: "0px", position: "absolute" }} className={props.itemClicked === index && item.children ? 'rotate' : ''}>
<ChevronEndMediumIcon />
</Menu.ItemIcon>) : null}
</MenuItem>
{itemClicked === index && item.children ? <div><StackedMenu items={item.children} depth={depth + 1} itemClicked={0} /></div> : null}
</>)
})}
</Menu>)
}
I using a recursive component to create children sub menu.
Actually when I open a menu all chevrons get expanded , what I'm looking for is that only the chevron of the clicked item get expanded.
Upvotes: 0
Views: 822
Reputation: 313
using "Code Splitting". Just create a separate component and place the state inside that component. This creates a separate state for each item n the list so that the onclick obeys for that item only.
<div>
<Mycomponent />
</div>
const Mycomponent = ()=>{
const [active, setactive] = useState(false);
return (
<div>
<div
key={i}
style={{
boxShadow: active
? "4px 3px 8px 0px rgba(1, 156, 48, 0.3)"
: "initial"
}}
onClick={() => setactive(!active)}
>
{message.content}
</div>
<div>
);
Upvotes: 0
Reputation: 4173
You should use the component's state to check if menu item is opened or not.
Also, I've removed unnecessary depth
state. Hope this could help.
const StackedMenu = ({items, depth, ...otherProps}) => {
let [chevronRotation, setChevronRotation] = useState('');
let [itemClicked, setItemClicked] = useState(otherProps.itemClicked);
return (
<Menu
primary
defaultActiveIndex={0}
activeIndex={itemClicked}
vertical
pointing
style={{width: '100%'}}>
{items.map((item, index) => {
return (
<>
<MenuItem
onClick={(e, data) => {
setItemClicked(data.index);
setChevronRotation(`rotate`);
}}
index={index}
key={index}
pointing="start">
<Menu.ItemContent
style={depth > 0 ? {paddingLeft: '0.5em'} : null}>
{item.content}
</Menu.ItemContent>
{item.children ? (
<Menu.ItemIcon
id={index}
style={{right: '0px', position: 'absolute'}}
className={itemClicked === index ? 'rotate' : ''}>
<ChevronEndMediumIcon />
</Menu.ItemIcon>
) : null}
</MenuItem>
{itemClicked === index && item.children ? (
<div>
<StackedMenu
items={item.children}
depth={depth + 1}
itemClicked={0}
/>
</div>
) : null}
</>
);
})}
</Menu>
);
};
Upvotes: 1
Reputation: 2932
Your problem is that you're setting a local state to control whether it should be open, but then checks on the props for the clicked item.
Change this line:
// I removed props from props.itemClicked
<Menu.ItemIcon id={index} style={{ right: "0px", position: "absolute" }} className={itemClicked === index && item.children ? 'rotate' : ''}>
Upvotes: 1