-
Notifications
You must be signed in to change notification settings - Fork 51
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
feat(typescript): declare View, Lifecycle, NavigationTrigger #426
Conversation
How should works? Like this? @customElement('page-home')
export class PageHome extends LitElement implements VaadinRouterView {
// ...
} |
@abdonrd for import {Router} from '@vaadin/router';
class MyView extends HTMLElement {
connectedCallback() {
this.location;
}
}
interface MyView extends Router.View {} or class MyView extends HTMLElement {
connectedCallback() {
(this as Router.View).location;
}
} for lifecycle there is an interface: class MyViewWithBeforeEnter extends HTMLElement implements Router.Lifecycle {
onBeforeEnter(
location: Router.Location,
commands: Router.PreventAndRedirectCommands,
router: Router
) {
location.pathname;
return commands.redirect(router.urlForName('home'));
}
} |
Thanks for the info, @platosha! And if I need both? I need to merge + interface? @customElement('page-home')
export class PageHome extends LitElement implements Router.Lifecycle {
// ...
}
interface PageHome extends Router.View {} |
@abdonrd yes, you can combine them as needed. Note, that in lifecycle callbacks you could use |
I'm not a TS expert, so, why this difference? |
Essentially there are two opposite ways of interaction between the view component and the Router:
class MyView extends HTMLElement {
connectedCallback() {
this.location;
}
}
interface MyView extends Router.View {} In the PR, Then, we need to declare that I have to apologise, I understand that this usage might feel a bit awkward. This comes down to the fact that the Router runtime adds a property to the component, and from the component’s author standpoint the |
I have understood! Thank you very much for the detailed explanation, @platosha! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 5 files reviewed, 1 unresolved discussion (waiting on @platosha)
interfaces.d.ts, line 143 at r1 (raw file):
Lifecycle
Instead of having one Lifecycle interface, would it make sense to align with Flow navigation APIs? i.e. have 3 interfaces BeforeLeaveObserver, BeforeEnterObserver and AfterNavigationObserver?
26f540f
to
fe3ca2c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 5 files reviewed, 1 unresolved discussion (waiting on @haijian-vaadin)
interfaces.d.ts, line 143 at r1 (raw file):
Previously, haijian-vaadin (Haijian Wang) wrote…
Lifecycle
Instead of having one Lifecycle interface, would it make sense to align with Flow navigation APIs? i.e. have 3 interfaces BeforeLeaveObserver, BeforeEnterObserver and AfterNavigationObserver?
Done. Also, now that I’ve discovered how to do that, exported new types as module-level, so that users don’t have to use Router.Something
namespace with them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 3 of 5 files at r1, 2 of 2 files at r2.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @haijian-vaadin)
fe3ca2c
to
d50a13f
Compare
d50a13f
to
47eca51
Compare
Hm-m, maybe the weird Now after trying using it with LitElement, I realise that you might actually want to declare So, exporting just the Then, it could be either declared as optional: import {RouterLocation} from '@vaadin/router';
@customElement('my-view')
class MyView extends LitElement {
@property({type: Object}) location?: RouterLocation;
render() {
return html`Current path: ${this.location ? this.location.pathname : ''}`;
}
} Or, could take the initial value from the import {router} from './router';
@customElement('my-view')
class MyView extends LitElement {
@property({type: Object}) location = router.location;
render() {
return html`Current path: ${this.location.pathname}`;
}
} @abdonrd any thoughts? |
I honestly imagined something like: export class PageElement extends RouterView(LitElement) {
// ...
} And then create the pages like: @customElement('page-home')
export class PageHome extends PageElement {
// ...
}
@customElement('page-about')
export class PageAbout extends PageElement {
// ...
} Because really all pages have access to But it's true that this logic is given in runtime, and not by the mixin itself. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 2 files at r3.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @haijian-vaadin)
Same changes were merged from #427 |
Fixes #422
This change is