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

Expose some way to manually handle <Link /> press #7566

Open
cprussin opened this issue Jan 5, 2025 · 3 comments
Open

Expose some way to manually handle <Link /> press #7566

cprussin opened this issue Jan 5, 2025 · 3 comments
Labels
enhancement New feature or request

Comments

@cprussin
Copy link

cprussin commented Jan 5, 2025

Provide a general summary of the feature here

I have a use case for a link which, for accessibility and UX reasons, I want to be rendered as an anchor with a href (i.e. I want it to semantically appear as a link and I want all the context menu / middle click behaviors of a link). However, if pressing the link within the SPA, I want to perform some animations before I actually trigger the route change.

I currently cannot do this with react-aria-components because there is no way to preventDefault on the event passed to the onPress handler.

Note this isn't specific to just Links, it also applies to other items that have navigation functionality and render anchors, e.g. tabs, etc

🤔 Expected Behavior?

Some way to override the client navigation behavior -- or at least defer the execution of it

😯 Current Behavior

No way to override client navigation behavior / defer execution

💁 Possible Solution

  1. Do not use a <Link />; use a <Button /> instead. This sucks though because it's semantically incorrect and prevents the browser from giving you things like the right-click context menu and ctrl-click to open in a new tab.
  2. Do not use react-aria-components for this link, maybe drop down to the react-aria hooks directly; that feels like an unnecessarily painful solution to something that could easily be solved with any of a number of possible API tweaks to the link component.

🔦 Context

I think it's all provided above.

💻 Examples

I have a few possible ideas for solutions:

  1. If onPress returns a promise, then await it before triggering client-side navigation:
<Link
  href="https://google.com"
  onPress={async () => { await doSomethingAsync(); }}
/>
  1. Classic preventDefault:
<Link
  href="https://google.com"
  onPress={(e) => {
    e.preventDefault();
    doSomethingAsync().then(() => /* I can do my own navigation here */);
  }}
/>
  1. Add a callback to the event that triggers the navigation. I'd expect this one is tricky to implement without it being a breaking change though:
<Link
  href="https://google.com"
  onPress={(e) => {
    doSomethingAsync().then(() => e.performNavigation());
  }}
/>

🧢 Your Company/Team

Douro Labs

🕷 Tracking Issue

No response

@cprussin
Copy link
Author

cprussin commented Jan 5, 2025

For any react-aria maintainers: I'm more than happy to contribute a PR to fix this if you all would help advise me on which solution would be accepted!

@LFDanLu
Copy link
Member

LFDanLu commented Jan 8, 2025

The team will need to discuss this further as to what direction we'll want to go as a whole, but for a workaround now if you provide your own navigate handling via RouterProvider does that work? Alternatively, perhaps you can wrap your Link in a span and preventDefault from there?

@cprussin
Copy link
Author

cprussin commented Jan 9, 2025

@LFDanLu thanks for the reply, and great idea! Wrapping the link in a RouterProvider to override the global RouterProvider is a great solution and far better than the other workarounds I had come up with. Works great.

This is totally good as a stopgap but I'm still more than happy to contribute the feature if you'd like the contribution once you all decide how you'd like it to work.

@LFDanLu LFDanLu added the enhancement New feature or request label Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants