mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
feat(nav-link): merge nav-push/pop/set-root into a single component (#18909)
This commit is contained in:
20
core/src/components/nav-link/nav-link-utils.ts
Normal file
20
core/src/components/nav-link/nav-link-utils.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { ComponentProps, NavComponent } from '../../interface';
|
||||
import { RouterDirection } from '../router/utils/interface';
|
||||
|
||||
export const navLink = (el: HTMLElement, routerDirection: RouterDirection, component?: NavComponent, componentProps?: ComponentProps) => {
|
||||
const nav = el.closest('ion-nav');
|
||||
if (nav) {
|
||||
if (routerDirection === 'forward') {
|
||||
if (component !== undefined) {
|
||||
return nav.push(component, componentProps, { skipIfBusy: true });
|
||||
}
|
||||
} else if (routerDirection === 'root') {
|
||||
if (component !== undefined) {
|
||||
return nav.setRoot(component, componentProps, { skipIfBusy: true });
|
||||
}
|
||||
} else if (routerDirection === 'back') {
|
||||
return nav.pop({ skipIfBusy: true });
|
||||
}
|
||||
}
|
||||
return Promise.resolve(false);
|
||||
};
|
||||
37
core/src/components/nav-link/nav-link.tsx
Normal file
37
core/src/components/nav-link/nav-link.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { Component, ComponentInterface, Element, Host, Prop, h } from '@stencil/core';
|
||||
|
||||
import { ComponentProps, NavComponent, RouterDirection } from '../../interface';
|
||||
|
||||
import { navLink } from './nav-link-utils';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-nav-link'
|
||||
})
|
||||
export class NavLink implements ComponentInterface {
|
||||
@Element() el!: HTMLElement;
|
||||
|
||||
/**
|
||||
* Component to navigate to. Only used if the `routerDirection` is `"forward"` or `"root"`.
|
||||
*/
|
||||
@Prop() component?: NavComponent;
|
||||
|
||||
/**
|
||||
* Data you want to pass to the component as props. Only used if the `"routerDirection"` is `"forward"` or `"root"`.
|
||||
*/
|
||||
@Prop() componentProps?: ComponentProps;
|
||||
|
||||
/**
|
||||
* The transition direction when navigating to another page.
|
||||
*/
|
||||
@Prop() routerDirection: RouterDirection = 'forward';
|
||||
|
||||
private onClick = () => {
|
||||
return navLink(this.el, this.routerDirection, this.component, this.componentProps);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Host onClick={this.onClick}></Host>
|
||||
);
|
||||
}
|
||||
}
|
||||
22
core/src/components/nav-link/readme.md
Normal file
22
core/src/components/nav-link/readme.md
Normal file
@ -0,0 +1,22 @@
|
||||
# ion-nav-link
|
||||
|
||||
A navigation link is used to navigate to a specified component. The component can be navigated to by going `forward`, `back` or as a `root` component.
|
||||
|
||||
It is the element form of calling the `push()`, `pop()`, and `setRoot()` methods on the navigation controller.
|
||||
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ----------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ----------- |
|
||||
| `component` | `component` | Component to navigate to. Only used if the `routerDirection` is `"forward"` or `"root"`. | `Function \| HTMLElement \| ViewController \| null \| string \| undefined` | `undefined` |
|
||||
| `componentProps` | -- | Data you want to pass to the component as props. Only used if the `"routerDirection"` is `"forward"` or `"root"`. | `undefined \| { [key: string]: any; }` | `undefined` |
|
||||
| `routerDirection` | `router-direction` | The transition direction when navigating to another page. | `"back" \| "forward" \| "root"` | `'forward'` |
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
106
core/src/components/nav-link/test/basic/index.html
Normal file
106
core/src/components/nav-link/test/basic/index.html
Normal file
@ -0,0 +1,106 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Nav Push</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
|
||||
|
||||
<body onload="loadFirstPage()">
|
||||
<ion-app>
|
||||
<ion-nav></ion-nav>
|
||||
</ion-app>
|
||||
<style>
|
||||
f {
|
||||
display: block;
|
||||
margin: 15px auto;
|
||||
max-width: 150px;
|
||||
height: 150px;
|
||||
background: blue;
|
||||
}
|
||||
|
||||
f:last-of-type {
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
</style>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
|
||||
class FirstPage extends HTMLElement {
|
||||
async connectedCallback() {
|
||||
this.innerHTML = `
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Page One</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Page One</h1>
|
||||
<ion-nav-push component="page-two">
|
||||
<ion-button class="next">Go to Page Two</ion-button>
|
||||
</ion-nav-push>
|
||||
</ion-content>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
class SecondPage extends HTMLElement {
|
||||
async connectedCallback() {
|
||||
this.innerHTML = `
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Page Two</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Page Two</h1>
|
||||
<ion-nav-push component="page-three">
|
||||
<ion-button class="next">Go to Page Three</ion-button>
|
||||
</ion-nav-push>
|
||||
<ion-nav-pop>
|
||||
<ion-button class="back">Go Back</ion-button>
|
||||
</ion-nav-pop>
|
||||
</ion-content>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
class ThirdPage extends HTMLElement {
|
||||
async connectedCallback() {
|
||||
this.innerHTML = `
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Page Three</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Page Three</h1>
|
||||
<ion-nav-pop>
|
||||
<ion-button class="back">Go Back</ion-button>
|
||||
</ion-nav-pop>
|
||||
</ion-content>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('page-one', FirstPage);
|
||||
customElements.define('page-two', SecondPage);
|
||||
customElements.define('page-three', ThirdPage);
|
||||
|
||||
async function loadFirstPage() {
|
||||
const nav = document.querySelector('ion-nav');
|
||||
await nav.setRoot('page-one');
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user