Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isPartiallyCurrent error in matching #488

Open
andreasottosson opened this issue Sep 13, 2021 · 1 comment
Open

isPartiallyCurrent error in matching #488

andreasottosson opened this issue Sep 13, 2021 · 1 comment

Comments

@andreasottosson
Copy link

andreasottosson commented Sep 13, 2021

Hi!

The following code produces a match for /pro when on /products using isPartiallyCurrent, is this correct? We are trying to use this to add active styling to top level Links when on subpages. So /products/product1 should not match /pro but it should match /products. Perhaps isPartiallyCurrent is not what we are looking for?

import React from "react";
import { render } from "react-dom";
import { Router, Link, Match } from "@reach/router";

const NavLink = (props) => (
  <Link
    {...props}
    getProps={({ isPartiallyCurrent }) => {
      // the object returned here is passed to the
      // anchor element's props
      return {
        style: {
          color: isPartiallyCurrent ? "red" : "blue"
        }
      };
    }}
  />
);

const App = (props) => (
  <div>
    <h1>Active Links</h1>
    <nav>
      <NavLink to="/products">Products</NavLink>
      <NavLink to="/pro">Professional</NavLink>
    </nav>
    {props.children}
  </div>
);

const Products = () => (
  <div>
    <h2>Products</h2>
    <NavLink to="/products/product1">Product 1</NavLink>
  </div>
);

const Product1 = () => (
  <div>
    <h2>Product 1</h2>
    <p>My fancy product.</p>
  </div>
);

const Professional = () => (
  <div>
    <h2>Professional</h2>
  </div>
);

render(
  <Router>
    <App path="/">
      <Products path="/products" />
      <Product1 path="/products/product1" />
      <Professional path="/pro" />
    </App>
  </Router>,
  document.getElementById("root")
);

You can run this easily by pasting this code over index.js in this example https://reach.tech/router/example/active-links :)

Best regards,
Andreas

@andreasottosson
Copy link
Author

andreasottosson commented Sep 14, 2021

So to give some more constructive feedback this is how I solved it,

const isPartiallyActiveExact = (props) => {
  const currentLocation = props.location.pathname
  const toProp = props.href
  const regex = new RegExp(`${toProp}/`, 'i')
  if (regex.test(currentLocation) || currentLocation === toProp) {
    return { className: 'active' }
  }
}

and used getProps={isPartiallyActiveExact} on the Link's that needed this. This makes sure that /pro does not match /products etc. but /pro/someotherpage will match as partially active which to me is more correct. Perhaps this could be implemented as isPartiallyActiveExact or something like that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant