Reach-ui: reach/tabs can't be used with react-router

Created on 30 Jun 2020  ·  3Comments  ·  Source: reach/reach-ui

🐛 Bug report

Current Behavior

To be able to have all the browser native features (open in new tab, copy link…) I want to use reach/tabs with Link from react-router. So far I'm failing, and I don't really know why 😕

Expected behavior

I want to have a tab system connected to the router.

Reproducible example

https://codesandbox.io/s/small-cdn-dr1lh?file=/src/App.tsx

Click on one link/tab =>
image

Suggested solution(s)

Additional context

I'm using react-router:4.3.1, all the details are in the repro example 😉

Your environment

| Software | Name(s) | Version |
| ---------------- | ------- | ------- |
| Reach Package | tabs | 0.10.5 |
| React | | 16.12.0 |
| Browser | chrome | latest |
| Assistive tech | | |
| Node | | |
| npm/yarn | | |
| Operating System | | |

Investigation Bug

Most helpful comment

Hi,

Here what i found after some investigation:

  • we call ownRef.current.focus() without checking if the target is a host element with a focus method (aka HTMLElement)
  • we pass the reference into the ref property but the react-router Link component uses innerRef

How can we improve this part?

  • check if the target element has a focus method?
  • add a property to change the property receiving the reference? (<Tab as={Link} asRef="innerRef" to="/three">)

    • this option will allow the developers to use components using innerRef or other "not ref" properties to forward a reference

  • other idea?

In the mean time, (not tested) i guess you can wrap the Link into a CustomLink to forward the ref prop to the react-router innerRef property.

I think i can provide a PR when we'll have chosen an option.

All 3 comments

Hi,

Here what i found after some investigation:

  • we call ownRef.current.focus() without checking if the target is a host element with a focus method (aka HTMLElement)
  • we pass the reference into the ref property but the react-router Link component uses innerRef

How can we improve this part?

  • check if the target element has a focus method?
  • add a property to change the property receiving the reference? (<Tab as={Link} asRef="innerRef" to="/three">)

    • this option will allow the developers to use components using innerRef or other "not ref" properties to forward a reference

  • other idea?

In the mean time, (not tested) i guess you can wrap the Link into a CustomLink to forward the ref prop to the react-router innerRef property.

I think i can provide a PR when we'll have chosen an option.

@ghostd Thanks for your investigation! I've tried quickly on the sandbox to wrap the Link, works! (not totally perfect in term of typesafety, but could be worst)

const CustomLink = React.forwardRef<Link, LinkProps>((props, ref) => <Link {...props} innerRef={ref as any} />)

And if you are using styled components to customize tabs appearance, don't forget to use the forwardedAs prop instead of as 😉

Was this page helpful?
0 / 5 - 0 ratings