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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] Handle links clicks without calling href() #125

Open
theo-staizen opened this issue Apr 28, 2021 · 0 comments
Open

[v2] Handle links clicks without calling href() #125

theo-staizen opened this issue Apr 28, 2021 · 0 comments

Comments

@theo-staizen
Copy link

theo-staizen commented Apr 28, 2021

This is a copy of my issue from the separate stencil-router-v2 repo. I moved it here, since it seems that the code has been moved over to this repo


Hi team,

Great work on such a tiny, but deadly router 馃殌 . I do have a concern however:

How do I handle links that are not using the href() function? e.g links generated from .md files or links coming for some 3rd party component that I have no control over?

  • Do I add a global (or some parent) click handler to listen to link clicks and decide what to do afterwards?
  • Do I add a mutation observer and update link hrefs as they are added to the DOM?
  • Do I introduce custom renderers to my markdown files? (although i don't see how that could be achieved during compile time with href(). it will have to be during runtime)
  • Do I do nothing and just let them trigger a full page reload ? 馃槩

Also from what I can see from this code, href() is adding an onClick to the link, which means that we are potentially generating a large number of functions, which could be replaced with a single, global click handler instead.

Would you accept a PR, that introduces a global click handler, that would remove the need of using href(), meaning the router would work on any anchor elements. Here's an example of what I am suggesting (my assumptions about Router.match and Router.push might be wrong, but I hope you get the overall idea) :

import {createRouter, match} from 'stencil-router' //v2 branch

const Router = createRouter();

function setGlobalLinkHandler(enable: Boolean, target: EventTarget = document) {
  if (enable) {
    target.addEventListener('click', linkClicked)
  } else {
    target.removeEventListener('click', linkClicked)
  }
}

function linkClicked(event: MouseEvent) {
  const link = event.target.closest('a');

  if (
    link == null || // ignore click if not on or inside a link
    event.button !== 0 || // ignore non-left clicks
    event.ctrlKey || // ignore ctrl clicks, as it opens in new tab
    event.shiftKey || // ignore ctrl clicks, as it opens in new window
    event.metaKey || // ignore cmd clicks, as it opens in new tab (mac)
    link.hasAttribute('href') === false || // ignore links without href
    (link.target && link.target.toLowerCase() !== '_self') // ignore non default targets
    link.hasAttribute('download') || // ignore download links
    link.rel.indexOf('external') > -1 || // ignore explicit external links
    match(link.href) == null // finally ignore if href does not match a route
  ) {
    return;
  }

  event.preventDefault(); // prevent default to avoid full page reload
  Router.push(link.href); // navigate to route
}

Thank you :)

P.s: For what it's worth, vaadin-router is following a similar approach: https://github.com/vaadin/router/blob/master/src/triggers/click.js#L109

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