@stencil/router
Version:
347 lines (346 loc) • 11.4 kB
JavaScript
import { h } from '@stencil/core';
import { matchPath, matchesAreEqual } from '../../utils/match-path';
import ActiveRouter from '../../global/active-router';
/**
* @name Route
* @module ionic
* @description
*/
export class Route {
constructor() {
this.group = null;
this.match = null;
this.componentProps = {};
this.exact = false;
this.scrollOnNextRender = false;
this.previousMatch = null;
}
// Identify if the current route is a match.
computeMatch(newLocation) {
const isGrouped = this.group != null || (this.el.parentElement != null && this.el.parentElement.tagName.toLowerCase() === 'stencil-route-switch');
if (!newLocation || isGrouped) {
return;
}
this.previousMatch = this.match;
return this.match = matchPath(newLocation.pathname, {
path: this.url,
exact: this.exact,
strict: true
});
}
async loadCompleted() {
let routeViewOptions = {};
if (this.history && this.history.location.hash) {
routeViewOptions = {
scrollToId: this.history.location.hash.substr(1)
};
}
else if (this.scrollTopOffset) {
routeViewOptions = {
scrollTopOffset: this.scrollTopOffset
};
}
// After all children have completed then tell switch
// the provided callback will get executed after this route is in view
if (typeof this.componentUpdated === 'function') {
this.componentUpdated(routeViewOptions);
// If this is an independent route and it matches then routes have updated.
// If the only change to location is a hash change then do not scroll.
}
else if (this.match && !matchesAreEqual(this.match, this.previousMatch) && this.routeViewsUpdated) {
this.routeViewsUpdated(routeViewOptions);
}
}
async componentDidUpdate() {
await this.loadCompleted();
}
async componentDidLoad() {
await this.loadCompleted();
}
render() {
// If there is no activeRouter then do not render
// Check if this route is in the matching URL (for example, a parent route)
if (!this.match || !this.history) {
return null;
}
// component props defined in route
// the history api
// current match data including params
const childProps = Object.assign({}, this.componentProps, { history: this.history, match: this.match });
// If there is a routerRender defined then use
// that and pass the component and component props with it.
if (this.routeRender) {
return this.routeRender(Object.assign({}, childProps, { component: this.component }));
}
if (this.component) {
const ChildComponent = this.component;
return (h(ChildComponent, Object.assign({}, childProps)));
}
}
static get is() { return "stencil-route"; }
static get originalStyleUrls() { return {
"$": ["route.css"]
}; }
static get styleUrls() { return {
"$": ["route.css"]
}; }
static get properties() { return {
"group": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string | null",
"resolved": "null | string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"attribute": "group",
"reflect": true,
"defaultValue": "null"
},
"componentUpdated": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "(options: RouteViewOptions) => void",
"resolved": "((options: RouteViewOptions) => void) | undefined",
"references": {
"RouteViewOptions": {
"location": "import",
"path": "../../global/interfaces"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
}
},
"match": {
"type": "unknown",
"mutable": true,
"complexType": {
"original": "MatchResults | null",
"resolved": "MatchResults | null",
"references": {
"MatchResults": {
"location": "import",
"path": "../../global/interfaces"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"defaultValue": "null"
},
"url": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string | string[]",
"resolved": "string | string[] | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"attribute": "url",
"reflect": false
},
"component": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"attribute": "component",
"reflect": false
},
"componentProps": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "{ [key: string]: any }",
"resolved": "undefined | { [key: string]: any; }",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"defaultValue": "{}"
},
"exact": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"attribute": "exact",
"reflect": false,
"defaultValue": "false"
},
"routeRender": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "(props: RouteRenderProps) => any",
"resolved": "((props: RouteRenderProps) => any) | undefined",
"references": {
"RouteRenderProps": {
"location": "import",
"path": "../../global/interfaces"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
}
},
"scrollTopOffset": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"attribute": "scroll-top-offset",
"reflect": false
},
"routeViewsUpdated": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "(options: RouteViewOptions) => void",
"resolved": "((options: RouteViewOptions) => void) | undefined",
"references": {
"RouteViewOptions": {
"location": "import",
"path": "../../global/interfaces"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
}
},
"location": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "LocationSegments",
"resolved": "LocationSegments | undefined",
"references": {
"LocationSegments": {
"location": "import",
"path": "../../global/interfaces"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
}
},
"history": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "RouterHistory",
"resolved": "RouterHistory | undefined",
"references": {
"RouterHistory": {
"location": "import",
"path": "../../global/interfaces"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
}
},
"historyType": {
"type": "string",
"mutable": false,
"complexType": {
"original": "HistoryType",
"resolved": "\"browser\" | \"hash\" | undefined",
"references": {
"HistoryType": {
"location": "import",
"path": "../../global/interfaces"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"attribute": "history-type",
"reflect": false
}
}; }
static get elementRef() { return "el"; }
static get watchers() { return [{
"propName": "location",
"methodName": "computeMatch"
}]; }
}
ActiveRouter.injectProps(Route, [
'location',
'history',
'historyType',
'routeViewsUpdated'
]);