Sangeet Agarwal
Sangeet Agarwal

Reputation: 1825

Styled components React router v6

const StyledNavLink = styled(NavLink)`
  text-decoration: ${(props) => {
    console.log(props.style);
    return props.style ? (isActive) => (isActive ? "underline" : "none") : "none";
  }};
  &:hover {
    text-decoration: underline;
  }
`;

export default function BasicExample() {
  return (
    <Router>
      <Navbar>
        <NavItems>
          <NavItem>
            <NavLink
              to="/"
              end={true}
              style={({ isActive }) => {
                console.log(isActive + "About");
                return { textDecoration: isActive ? "underline" : "none" };
              }}
            >
              Home
            </NavLink>
          </NavItem>
          <NavItem>
            <NavLink
              to="/about"
              style={({ isActive }) => {
                console.log(isActive + "About");
                return { textDecoration: isActive ? "underline" : "none" };
              }}
            >
              About
            </NavLink>
          </NavItem>
          <NavItem>
            <NavLink
              to="/dashboard"
              style={({ isActive }) => {
                console.log(isActive + "Dashboard");
                return { textDecoration: isActive ? "underline" : "none" };
              }}
            >
              Dashboard
            </NavLink>
          </NavItem>
        </NavItems>
      </Navbar>
      <Routes>
        <Route path="/" caseSensitive={false} element={<Home />}></Route>
        <Route path="/about" caseSensitive={false} element={<About />}></Route>
        <Route path="/dashboard" caseSensitive={false} element={<Dashboard />}></Route>
      </Routes>
    </Router>
  );
}

How can I abstract out the logic for styling an active link to say the StyledNavLink styled component, I tried using StyledNavLink in place of Navlink but it doesn't work. I'm not sure what I might be missing. If I console out props.style within the StyledNavLink then it is always undefined.

Upvotes: 5

Views: 3003

Answers (2)

Sangeet Agarwal
Sangeet Agarwal

Reputation: 1825

const StyledNavLink = styled(NavLink)`
  text-decoration: ${(props) => {
    console.log(props.style);
    return props.style ? (isActive) => (isActive ? "underline" : "none") : "none";
  }};
  &:hover {
    text-decoration: underline;
  }
 &[aria-current] {
    color: red;
  }
`;

I just had to check if aria-current attribute was present and now if I replace NavLink with StyledNavLink every thing works as expected

Or, as shown below, one can check for existence of the active class

const StyledNavLink = styled(NavLink)`
    text-decoration: ${(props) => {
    console.log(props);
    return props.style ? (isActive) => (isActive ? "underline" : "none") : "none";
  }}; 
  &:hover {
    text-decoration: underline;
  }
 &[class*="active"] {
    color: red;
  }
`;

Upvotes: 4

Himanshu Singh
Himanshu Singh

Reputation: 1953

I am not so sure about this, but similar problem I have faced while styling Link of NextJS using styled-components. So maybe that can also work here.


Workaround

You can create a LinkWrapper styled component which wrap the link with any default component like div, span, etc, which does not create any other issue to what you are trying to do, and then style the Navlik which in reality will become an a tag, so you can nested style the a tag (NavLink) using that LinkWrapper.

const LinkWrapper= styled.div`
  a {
    display: flex;
    justify-content: ${props => props.propToPass ? 'flex-start' : 'center'};
    align-items: center;
  }
`;

function App(props) {
  return(
    <LinkWrapper propToPass={/**/}>
      <Link to={props.link}>
        {props.name}
      </Link>
    </LinkWrapper>
  );
}

Try this, I think this can be a solution

Upvotes: 0

Related Questions