-1

So I have this sidebar which have routes to different pages of the app. On hover I'm styling the li with a right border and the icon with the same color. Now I have been trying to add active class to the currently active path with the same styling as the li (right border and icon color). But I'm unable to do so.

I have already tried the solutions from this post but nothing seems to be working. I tried with NavLink from react-router-dom and added activeClassName but it doesn't work.

This is the current state of the code:

const Sidebar = () => {
    return (
        <div className={style.sidebarContainer} >

            <li className={style.navItem} >
                  <Link to='/' activeClassName="active" >
                        <PersonIcon />
                  </Link>
            </li>

            <li className={style.navItem}>
                  <Link to='/example1' activeClassName="active" >
                        <SettingsIcon />
                  </Link>
            </li>

            <li className={style.navItem}>
                  <Link to='/example2' activeClassName="active" >
                        <LightModeIcon />
                  </Link>
            </li>

        </div>
    )
}

This is the stylesheet:

.sidebarContainer{
    background: black;
}

.sidebarContainer a{
    text-decoration: none;
    color: gray;
    width: 100%;
} 

.navItem {
    width: 100%;
    padding: 1rem 0;
    cursor: pointer;
    border-right: 4px solid transparent;
    transition: all 0.3s ease 0s !important;
    list-style: none;
    padding-left: 1.3rem;
    display: flex;
    align-items: center;
}

.navItem:hover {
    border-right: 4px solid red;
}

.navItem:hover svg {
    color: red;
}

.navItem svg {
    font-size: 1.6rem !important;
    transition: all 0.3s ease 0s !important;
}

Here's how it looks:

enter image description here

isherwood
  • 58,414
  • 16
  • 114
  • 157
s.khan
  • 297
  • 1
  • 7
  • 24

2 Answers2

1

The Link or NavLink components return an a HTML tag. So when you are writing the following codes,

<Link to="/home">Home</Link>

It turns out to the following markup on the DOM,

<a href="/home">Home</a>

So the active class is actually added with the a tag, not the li tag.

<a href="/home" class="active">Home</a>

We have to style our CSS considering this approach.

But here we have a gotcha! Since we are using css-modules, our classes on the styles file will be converted by the library for ensuring local scopes. so .navItem class will be converted to something like _src_app_module__navLink. So we have to pass our active class to the NavLink component as style.active,

<NavLink to='/' activeClassName={style.active} >
   <PersonIcon />
</NavLink>

Please use NavLink instead Link component

The following updates on your css should work.

.navItem a{
    width: 100%;
    padding: 1rem 0;
    cursor: pointer;
    border-right: 4px solid transparent;
    transition: all 0.3s ease 0s !important;
    list-style: none;
    padding-left: 1.3rem;
    display: flex;
    align-items: center;
}

.navItem a:hover,
.navItem a.active {
    border-right: 4px solid red;
}

.navItem a:hover svg,
.navItem a.active svg {
    color: red;
}

Here I replicated your code as much as possible - https://codesandbox.io/s/pedantic-field-kwj1t

  • If I dont use ```activeClassName``` then I have to manually add ```active``` class with the help of conditionals, right? Cause I just removed ```activeClassName``` and added your code. It didn't work. But then I added active to one of the ```Link```, then it worked. But it won't change if I go to another path. – s.khan Sep 27 '21 at 17:30
  • Now I tried with ```NavLink``` and removed the manual ```active``` class. It doesn't work. – s.khan Sep 27 '21 at 17:32
  • When you use `NavLink` component the `active` class is added as default by React Router. If you want to use a different class e.g. `selected` then you can use the `activeClassName` prop. Did you update the css following my answer? It might fail but the idea is you have to target the a tag to show active page on the navigation. – Md. Rubayet Hossain Sep 27 '21 at 18:55
  • I did. It didnt work – s.khan Sep 27 '21 at 20:18
  • Okay, I have found the actual problem. Since we are using css modules, there is actually no `active` class available in our stylesheet. Because css modules convert it to local scope class names. So we have to pass the active class name to this prop `activeClassName` in this way `style.active`. I have tried to replicate your codes as much as possible here - https://codesandbox.io/s/loving-williams-l4n7i . Check the codes and you will get the idea. – Md. Rubayet Hossain Sep 28 '21 at 04:08
  • I have updated my answer. Please check again! – Md. Rubayet Hossain Sep 28 '21 at 14:57
  • `` adding the active class name as `{style.active}` did the trick for me! – Jestino Sam May 21 '22 at 15:24
1

you need to replace Link with NavLink . NavLink will add styling attributes to the rendered element when it matches the current URL.

like

           <li className={style.navItem} >
                  <NavLink to='/' activeClassName="active" >
                        <PersonIcon />
                  </NavLink>
            </li>

            <li className={style.navItem}>
                  <NavLink to='/example1' activeClassName="active" >
                        <SettingsIcon />
                  </NavLink>
            </li>

            <li className={style.navItem}>
                  <NavLink to='/example2' activeClassName="active" >
                        <LightModeIcon />
                  </NavLink>
            </li>

here is the documentation link