From dbfe373733445a3d6acffa91bc6c78d269bdbbf7 Mon Sep 17 00:00:00 2001 From: Barney Carroll Date: Tue, 10 May 2022 17:23:10 +0100 Subject: [PATCH] Clean up m.route.Link (#2768) * Simpler m.route.Link documentation. Fixes #2767 * Remove redundant HTML encoding from markdown docs * Warn about m.route.Link immunity to event handler API. * Integrate @JAForbes review corrections * Example code typo in docs/route.md Co-authored-by: Matias Kinnunen Co-authored-by: Matias Kinnunen --- docs/route.md | 102 +++++++++++++------------------------------------- 1 file changed, 27 insertions(+), 75 deletions(-) diff --git a/docs/route.md b/docs/route.md index 91c5fa35..ff0e52f5 100644 --- a/docs/route.md +++ b/docs/route.md @@ -64,7 +64,7 @@ Argument | Type | Required | D ---------------------- | ---------------------------------------- | -------- | --- `root` | `Element` | Yes | A DOM element that will be the parent node to the subtree `defaultRoute` | `String` | Yes | The route to redirect to if the current URL does not match a route. Note, this is not the initial route. Initial route will be your address bar's url. -`routes` | Object<String,Component|RouteResolver> | Yes | An object whose keys are route strings and values are either components or a [RouteResolver](#routeresolver) +`routes` | `Object` | Yes | An object whose keys are route strings and values are either components or a [RouteResolver](#routeresolver) **returns** | | | Returns `undefined` [How to read signatures](signatures.md) @@ -125,94 +125,46 @@ This is a simple property, so you can both read it and write to it. ##### m.route.Link -This component can create a dynamic routable link: +This component creates a dynamic routed link. Its essential function is to produce `a` links with local `href`s transformed to take account of the [route prefix](#mrouteprefix). ```javascript -m(m.route.Link, {href: "/test"}) +m(m.route.Link, {href: "/foo"}, "foo") + +// Unless m.route.prefix has changed from the default strategy, render to: +// foo ``` -Using `m.route.Link` causes the link to behave as a router link - clicking it navigates to the route specified in `href`, instead of navigating away from the current page to the URL specified in `href`. +Links accept a selection of special attributes: +* `selector` is what would be passed as the first argument to [`m`](hyperscript.md): any selector is valid, including non-`a` elements. +* `params` & `options` are the arguments with the same names as defined in [`m.route.set`](#mrouteset). +* `disabled`, if true, disables routing behaviour and any bound `onclick` handler, and attaches a `data-disabled="true"` attribute for accessibility hints; if the element is an `a`, the `href` is removed. -You can also set the `options` passed to `m.route.set` when the link is clicked by passing the `options` attribute: - -```javascript -m(m.route.Link, {href: "/test", options: {replace: true}}) -``` - -You can pass other attributes, too, and you can also specify the tag name used. +*Routing behaviour cannot be prevented using the event handling API: use `disabled` instead.* ```javascript m(m.route.Link, { - // Any hyperscript selector is valid here - it's literally passed as the - // first parameter to `m`. - selector: "span", - options: {replace: true}, + href: "/foo", + selector: "button.large", + disabled: true, params: {key: "value"}, - href: "/test", - disabled: false, - class: "nav-link", - "data-foo": 1, - // and other attributes + options: {replace: true}, }, "link name") + +// Renders to: +// ``` -Magic attributes used by this selector (except `href` and `disabled`) *are* removed while proxying, so you won't have an odd `selector="span"` or `options="[object Object]"` attribute show up in your link's DOM node. The above vnode renders to this hyperscript, assuming the prefix is the default `#!`: - -```javascript -m("span", { - href: "#!/test", - onclick: function(e) { - // ... - }, - disabled: false, // Only if you specify it - class: "nav-link", - "data-foo": 1, - // and other attributes -}) -``` - -You can also prevent navigation by, in an `onclick` handler, invoking `e.preventDefault()` or returning `false`. This is the same way you block other events, so it's pretty natural. - -```javascript -m(m.route.Link, { - href: "/test", - onclick: function(e) { - // Do things... - if (notReady()) e.preventDefault() - } -}, "link name") -``` - -This supports full accessibility for both `a` and `button`, via a `disabled` attribute. This ensures [no `href` attribute or `onclick` handler is set](https://css-tricks.com/how-to-disable-links/) and that an `"aria-disabled": "true"` attribute *is* set. If you are passing an `onclick` handler already, that's dropped. (You can work around this by adding it directly in a [lifecycle hook](lifecycle-methods.md).) The `disabled` attribute is itself proxied to the element or component, so you can disable routed `