Open bennypowers opened 4 years ago
raised the possibility of adding that metadata to location as well, which could be useful for components
I'm not saying it should be there, that was just an idea on where to place it.
So the use case you are trying to achieve seems to be mostly about filtering routes? That sounds like a valid use case to me. Maybe we could think about more cases.
mostly about filtering routes
But also about providing other data, in this case icon.
One might imagine having metadata like requiredRoles
or badgeContent
as well
I have a similar use case where fields are added at the route definition and used before or on rendering. The purpose, for now, is to know if a route requires authentication checking (i.e. not all require that) and what parent layout to use.
Technically, any arbitrary properties can be added to the route object.
So I assume this is mostly about type definitions support, right?
In my case, yes.
Yeah. I'd rather not slather on a bunch of // @ts-ignore
As a user, I want to know what is and is not the intended use of the API.
Is a generic metadata
better than creating an app specific type variant to use, e.g.
interface MetadataRouteWithAction extends RouteWithAction {
icon: string,
isNavRoute: boolean
}
@bennypowers, what do you think of the custom Route
type extension approach described above?
Can you please try it out in your app and see what are the pros and cons of each approach? That would be helpful!
I anticipate that with metadata
the application code would look like:
const routes = router.getRoutes();
...
<mwc-list>${this.routes.map(routeTemplate)}</mwc-list>
...
funciton routeTemplate(route: Route) {
const meta = route.metadata as { icon: string, isNavRoute: boolean };
return meta.isNavRoute
? html`<my-icon icon=${meta.icon}>...</my-icon>`
: html``;
}
With a custom Route
type extension the application code would look like:
type MyRoute = Route & {
icon: string,
isNavRoute: boolean
}
...
const routes = router.getRoutes() as MyRoute[];
...
<mwc-list>${this.routes.map(routeTemplate)}</mwc-list>
...
funciton routeTemplate(route: MyRoute) {
const meta = route.metadata;
return meta.isNavRoute
? html`<my-icon icon=${meta.icon}>...</my-icon>`
: html``;
}
Side note: I think it would be possible to get rid of the type cast if the Router
type is generic and has the extended Route
type as a type parameter.
Indeed, that's a better solution. here's my app code:
declare module '@vaadin/router/dist/vaadin-router' {
export interface RouteMetadata {
icon?: Icon;
stage?: Stage;
label?: string;
}
export interface BaseRoute {
metadata?: RouteMetadata;
}
}
I'm unavailable to do it today, but I'll redo this PR to be a docs-only PR that adds an example like this.
it would be nice if (in a later PR) these types were exported from @vaadin/router
instead of @vaadin/router/dist/vaadin-router
Let's say we're implementing a material design nav drawer:
In such a case, I might want to keep a record of nav items something like this:
Currently, I would have to keep some of this information in two places at once - here in my record of nav routes, as well as in vaadin-router's route config.
I propose adding a
metadata: Record<string, any>
field to theRoute
interface, which would allow users to add arbitrary metadata (like icon and whether or not to include this route in the nav bar) to their routing table.Before:
After:
@web-padawan , in discussion on Polymer Slack, raised the possibility of adding that metadata to
location
as well, which could be useful for components