mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
chore(): sync with master
This commit is contained in:
37
.github/COMPONENT-GUIDE.md
vendored
37
.github/COMPONENT-GUIDE.md
vendored
@@ -17,6 +17,7 @@
|
||||
* [Example Components](#example-components-1)
|
||||
* [Component Structure](#component-structure-1)
|
||||
- [Converting Scoped to Shadow](#converting-scoped-to-shadow)
|
||||
- [RTL](#rtl)
|
||||
|
||||
## Button States
|
||||
|
||||
@@ -717,3 +718,39 @@ There will be some CSS issues when converting to shadow. Below are some of the d
|
||||
/* IN SHADOW*/
|
||||
:host-context(ion-toolbar:not(.ion-color)):host(:not(.ion-color)) ::slotted(ion-segment-button) {
|
||||
```
|
||||
|
||||
## RTL
|
||||
|
||||
When you need to support both LTR and RTL modes, try to avoid using values such as `left` and `right`. For certain CSS properties, you can use the appropriate mixin to have this handled for you automatically.
|
||||
|
||||
For example, if you wanted `transform-origin` to be RTL-aware, you would use the `transform-origin` mixin:
|
||||
|
||||
```css
|
||||
@include transform-origin(start, center);
|
||||
```
|
||||
|
||||
This would output `transform-origin: left center` in LTR mode and `transform-origin: right center` in RTL mode.
|
||||
|
||||
These mixins depend on the `:host-context` pseudo-class when used inside of shadow components, which is not supported in WebKit. As a result, these mixins will not work in Safari for macOS and iOS when applied to shadow components.
|
||||
|
||||
To work around this, you should set an RTL class on the host of your component and set your RTL styles by targeting that class:
|
||||
|
||||
```tsx
|
||||
<Host
|
||||
class={{
|
||||
'my-cmp-rtl': document.dir === 'rtl'
|
||||
})
|
||||
>
|
||||
...
|
||||
</Host>
|
||||
```
|
||||
|
||||
```css
|
||||
:host {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
:host(.my-cmp-rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
```
|
||||
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,3 +1,33 @@
|
||||
## [5.6.9](https://github.com/ionic-team/ionic/compare/v5.6.8...v5.6.9) (2021-06-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **modal:** swipe to close modal is no longer swipeable on footer ([#23401](https://github.com/ionic-team/ionic/issues/23401)) ([ae96563](https://github.com/ionic-team/ionic/commit/ae96563fb3c4612cb8585292b389ee746f5759f7)), closes [#23398](https://github.com/ionic-team/ionic/issues/23398)
|
||||
* **title:** inherit padding for iOS title in a toolbar ([#23343](https://github.com/ionic-team/ionic/issues/23343)) ([82cfa55](https://github.com/ionic-team/ionic/commit/82cfa5565347704b0e9f7dac792ed2aa6dd30505)), closes [#23072](https://github.com/ionic-team/ionic/issues/23072)
|
||||
* **vue:** improve v-model integration for Vue 3.1.0+ ([#23420](https://github.com/ionic-team/ionic/issues/23420)) ([f008628](https://github.com/ionic-team/ionic/commit/f0086288512bd7f7d1929d79bfd8bf702efc732e))
|
||||
* **vue:** prevent error from being thrown when testing on certain jest runners ([#23421](https://github.com/ionic-team/ionic/issues/23421)) ([60bedb5](https://github.com/ionic-team/ionic/commit/60bedb5599b286bffccfc54c4861a269d9b8df73)), closes [#23397](https://github.com/ionic-team/ionic/issues/23397)
|
||||
|
||||
|
||||
|
||||
## [5.6.8](https://github.com/ionic-team/ionic/compare/v5.6.7...v5.6.8) (2021-05-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **action-sheet:** subheader no longer overlaps action sheet buttons ([#23318](https://github.com/ionic-team/ionic/issues/23318)) ([d473a53](https://github.com/ionic-team/ionic/commit/d473a5385108ef5f39d7c9a2b2924e89fec631de)), closes [#23316](https://github.com/ionic-team/ionic/issues/23316)
|
||||
* **all:** reflect color property as an attribute for vue ([#23345](https://github.com/ionic-team/ionic/issues/23345)) ([dc430af](https://github.com/ionic-team/ionic/commit/dc430af906c608f948c8d404ad73ae0e0ac36076)), closes [#23323](https://github.com/ionic-team/ionic/issues/23323)
|
||||
* **range:** knob can now have an accessible name ([#23338](https://github.com/ionic-team/ionic/issues/23338)) ([881dcff](https://github.com/ionic-team/ionic/commit/881dcff40b8bdcb07b27d4ee812ce4ee64b6ea9a)), closes [#23295](https://github.com/ionic-team/ionic/issues/23295)
|
||||
* **react:** remove @ionic/core dependency in @ionic/react-router to resolve yarn install warning ([#23351](https://github.com/ionic-team/ionic/issues/23351)) ([36bfa33](https://github.com/ionic-team/ionic/commit/36bfa3350354e09be6c62f4e4bee0c553c5981a3)), closes [#23346](https://github.com/ionic-team/ionic/issues/23346)
|
||||
* **react:** support history@5 in preparation for react router 6 ([#23297](https://github.com/ionic-team/ionic/issues/23297)) ([4da5216](https://github.com/ionic-team/ionic/commit/4da5216b4f65f3d893cc81ebee77261835218f7f)), closes [#23294](https://github.com/ionic-team/ionic/issues/23294)
|
||||
* **router:** guards are now triggered on initial navigation ([#23123](https://github.com/ionic-team/ionic/issues/23123)) ([56f6f56](https://github.com/ionic-team/ionic/commit/56f6f56c6665f40ea6bf41be463cd416883359f7)), closes [#22936](https://github.com/ionic-team/ionic/issues/22936)
|
||||
* **router:** redirects now account for query string ([#23337](https://github.com/ionic-team/ionic/issues/23337)) ([08a9f3a](https://github.com/ionic-team/ionic/commit/08a9f3ac94685c5782dd2fa6b56bf3448729a768)), closes [#23136](https://github.com/ionic-team/ionic/issues/23136)
|
||||
* **skeleton-text:** animation no longer jumps on large skeleton text elements ([#22697](https://github.com/ionic-team/ionic/issues/22697)) ([1a36922](https://github.com/ionic-team/ionic/commit/1a36922f41f2890c778feedbad9c5b74a72a3907)), closes [#22694](https://github.com/ionic-team/ionic/issues/22694)
|
||||
* **slides:** resolve prototype pollution in swiper v5 ([#23344](https://github.com/ionic-team/ionic/issues/23344)) ([a708c41](https://github.com/ionic-team/ionic/commit/a708c412625cba475ec7863468dcc2146b8feb7a)), closes [#23342](https://github.com/ionic-team/ionic/issues/23342)
|
||||
* **title:** large title scale animation is now correct in rtl mode ([#23372](https://github.com/ionic-team/ionic/issues/23372)) ([3d474ec](https://github.com/ionic-team/ionic/commit/3d474ec67ff4192fa3d08e370e20fecbee99a6aa)), closes [#23371](https://github.com/ionic-team/ionic/issues/23371)
|
||||
|
||||
|
||||
|
||||
## [5.6.7](https://github.com/ionic-team/ionic/compare/v5.6.6...v5.6.7) (2021-05-13)
|
||||
|
||||
|
||||
|
||||
18
angular/package-lock.json
generated
18
angular/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "5.6.6",
|
||||
"@ionic/core": "5.6.8",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -204,9 +204,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "5.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.6.tgz",
|
||||
"integrity": "sha512-EbVIXOTVVPxBo7hsarBpRSFNsQ22wBFtWkKmrmliieknG5LUkf5WZBpj4EENQhzYA6c+//7/nfhcD9pWgtAofA==",
|
||||
"version": "5.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.8.tgz",
|
||||
"integrity": "sha512-JWrRGzw4SyyemjycPEh516fAkgFVtLp6RMPTH3uzK8L+DLfqJ/QU4Uccu89QqdcG/TBD75r3wkUtbKL2YlL8PQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
"ionicons": "^5.5.1",
|
||||
@@ -5156,9 +5156,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "5.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.6.tgz",
|
||||
"integrity": "sha512-EbVIXOTVVPxBo7hsarBpRSFNsQ22wBFtWkKmrmliieknG5LUkf5WZBpj4EENQhzYA6c+//7/nfhcD9pWgtAofA==",
|
||||
"version": "5.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.8.tgz",
|
||||
"integrity": "sha512-JWrRGzw4SyyemjycPEh516fAkgFVtLp6RMPTH3uzK8L+DLfqJ/QU4Uccu89QqdcG/TBD75r3wkUtbKL2YlL8PQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
"ionicons": "^5.5.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -42,7 +42,7 @@
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "5.6.7",
|
||||
"@ionic/core": "5.6.9",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -209,7 +209,7 @@ export class Platform {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if the app is in portait mode.
|
||||
* Returns `true` if the app is in portrait mode.
|
||||
*/
|
||||
isPortrait(): boolean {
|
||||
return this.win.matchMedia && this.win.matchMedia('(orientation: portrait)').matches;
|
||||
|
||||
4
core/package-lock.json
generated
4
core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "5.7.0-dev.202106081605.0bc250e",
|
||||
"version": "5.6.9",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "5.7.0-dev.202106081605.0bc250e",
|
||||
"version": "5.6.9",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.6.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
|
||||
@@ -129,30 +129,29 @@
|
||||
// Material Design Button: Hover
|
||||
// --------------------------------------------------
|
||||
|
||||
/**
|
||||
* Only allow overriding of opacity here
|
||||
* as developers should not be overriding
|
||||
* colors when using the color prop.
|
||||
*/
|
||||
|
||||
:host(.button-solid.ion-color.ion-focused) .button-native::after {
|
||||
background: #{current-color(contrast)};
|
||||
|
||||
opacity: .24;
|
||||
}
|
||||
|
||||
:host(.button-clear.ion-color.ion-focused) .button-native::after,
|
||||
:host(.button-outline.ion-color.ion-focused) .button-native::after {
|
||||
background: #{current-color(base)};
|
||||
|
||||
opacity: .12;
|
||||
}
|
||||
|
||||
|
||||
@media (any-hover: hover) {
|
||||
:host(.button-solid.ion-color:hover) .button-native::after {
|
||||
background: #{current-color(contrast)};
|
||||
|
||||
opacity: .08;
|
||||
}
|
||||
|
||||
:host(.button-clear.ion-color:hover) .button-native::after,
|
||||
:host(.button-outline.ion-color:hover) .button-native::after {
|
||||
background: #{current-color(base)};
|
||||
|
||||
opacity: .04;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
<ion-button fill="outline" class="ion-focused" color="dark">Dark.focused</ion-button>
|
||||
<ion-button fill="outline" class="ion-activated ion-focused" color="dark">Dark.activated.focused</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button fill="outline" disabled>Disabled</ion-button>
|
||||
<ion-button fill="outline" color="secondary" disabled>Secondary Disabled</ion-button>
|
||||
|
||||
@@ -89,6 +89,31 @@
|
||||
<ion-button class="custom ion-activated" color="warning" fill="outline">Outline</ion-button>
|
||||
<ion-button class="custom ion-activated" color="dark" fill="clear">Clear</ion-button>
|
||||
</p>
|
||||
|
||||
<div class="custom-variables">
|
||||
<ion-button>Button</ion-button>
|
||||
<ion-button fill="clear">Button</ion-button>
|
||||
<ion-button fill="outline">Button</ion-button>
|
||||
|
||||
<br>
|
||||
|
||||
<ion-button class="ion-focused">Button</ion-button>
|
||||
<ion-button class="ion-focused" fill="clear">Button</ion-button>
|
||||
<ion-button class="ion-focused" fill="outline">Button</ion-button>
|
||||
|
||||
<br>
|
||||
|
||||
<ion-button color="tertiary">Button</ion-button>
|
||||
<ion-button color="tertiary" fill="clear">Button</ion-button>
|
||||
<ion-button color="tertiary" fill="outline">Button</ion-button>
|
||||
|
||||
<br>
|
||||
|
||||
<ion-button color="tertiary" class="ion-focused">Button</ion-button>
|
||||
<ion-button color="tertiary" class="ion-focused" fill="clear">Button</ion-button>
|
||||
<ion-button color="tertiary" class="ion-focused" fill="outline">Button</ion-button>
|
||||
</div>
|
||||
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
@@ -110,6 +135,17 @@
|
||||
.custom {
|
||||
--color: red;
|
||||
}
|
||||
|
||||
.custom-variables ion-button {
|
||||
--color: black;
|
||||
|
||||
--background: pink;
|
||||
--background-focused: red;
|
||||
--background-hover: green;
|
||||
|
||||
--background-focused-opacity: .5;
|
||||
--background-hover-opacity: .5;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -207,7 +207,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.setMultipleInputs();
|
||||
raf(() => this.setMultipleInputs());
|
||||
}
|
||||
|
||||
// If the item contains multiple clickable elements and/or inputs, then the item
|
||||
|
||||
@@ -24,11 +24,11 @@ export const createSwipeToCloseGesture = (
|
||||
return true;
|
||||
}
|
||||
|
||||
const content = target.closest('ion-content');
|
||||
if (content === null) {
|
||||
const contentOrFooter = target.closest('ion-content, ion-footer');
|
||||
if (contentOrFooter === null) {
|
||||
return true;
|
||||
}
|
||||
// Target is in the content so we don't start the gesture.
|
||||
// Target is in the content or the footer so do not start the gesture.
|
||||
// We could be more nuanced here and allow it for content that
|
||||
// does not need to scroll.
|
||||
return false;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Modal - Basic</title>
|
||||
<title>Modal - Custom</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">
|
||||
@@ -11,22 +11,27 @@
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<style>
|
||||
.custom-modal {
|
||||
--height: 70%;
|
||||
--border-style: solid;
|
||||
--border-width: 7px 0 0 0;
|
||||
--border-color: #0d51aa;
|
||||
--border-radius: 20px 20px 0 0;
|
||||
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
.custom-modal {
|
||||
--max-width: 98%;
|
||||
--height: 98%;
|
||||
--height: 70%;
|
||||
--border-style: solid;
|
||||
--border-width: 7px 0 0 0;
|
||||
--border-color: #0d51aa;
|
||||
--border-radius: 20px 20px 0 0;
|
||||
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.custom-modal ion-toolbar {
|
||||
--padding-top: 46px;
|
||||
--padding-bottom: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
.custom-modal {
|
||||
--max-width: 98%;
|
||||
--height: 98%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -35,7 +40,7 @@
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Modal - Basic</ion-title>
|
||||
<ion-title>Modal - Custom</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
@@ -55,13 +60,23 @@
|
||||
element.innerHTML = `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button>
|
||||
<ion-icon slot="icon-only" name="add-circle-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Super Modal</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button class="dismiss">
|
||||
Close
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<h1>Content of doom</h1>
|
||||
<div>Here's some more content</div>
|
||||
<ion-button class="dismiss">Dismiss Modal</ion-button>
|
||||
<ion-button class="dismiss" class="dismiss">Dismiss Modal</ion-button>
|
||||
</ion-content>
|
||||
`;
|
||||
|
||||
@@ -72,10 +87,12 @@
|
||||
});
|
||||
|
||||
// listen for close event
|
||||
const button = element.querySelector('ion-button');
|
||||
button.addEventListener('click', () => {
|
||||
modalElement.dismiss();
|
||||
});
|
||||
const buttons = element.querySelectorAll('.dismiss');
|
||||
for (var button of buttons) {
|
||||
button.addEventListener('click', () => {
|
||||
modalElement.dismiss();
|
||||
});
|
||||
}
|
||||
document.body.appendChild(modalElement);
|
||||
return modalElement;
|
||||
}
|
||||
|
||||
@@ -490,8 +490,8 @@ export default defineComponent({
|
||||
setup() {
|
||||
const isOpenRef = ref(false);
|
||||
const event = ref();
|
||||
const setOpen = (state: boolean, event?: Event) => {
|
||||
event.value = event;
|
||||
const setOpen = (state: boolean, ev?: Event) => {
|
||||
event.value = ev;
|
||||
isOpenRef.value = state;
|
||||
}
|
||||
return { isOpenRef, setOpen, event }
|
||||
|
||||
@@ -76,8 +76,8 @@ export default defineComponent({
|
||||
setup() {
|
||||
const isOpenRef = ref(false);
|
||||
const event = ref();
|
||||
const setOpen = (state: boolean, event?: Event) => {
|
||||
event.value = event;
|
||||
const setOpen = (state: boolean, ev?: Event) => {
|
||||
event.value = ev;
|
||||
isOpenRef.value = state;
|
||||
}
|
||||
return { isOpenRef, setOpen, event }
|
||||
|
||||
@@ -107,7 +107,7 @@ export class RadioGroup implements ComponentInterface {
|
||||
|
||||
// Get all radios inside of the radio group and then
|
||||
// filter out disabled radios since we need to skip those
|
||||
const radios = Array.from(this.el.querySelectorAll('ion-radio')).filter(radio => !radio.disabled);
|
||||
const radios = this.getRadios().filter(radio => !radio.disabled);
|
||||
|
||||
// Only move the radio if the current focus is in the radio group
|
||||
if (ev.target && radios.includes(ev.target)) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Me
|
||||
|
||||
import { AnimationBuilder, BackButtonEvent, RouteChain, RouterDirection, RouterEventDetail } from '../../interface';
|
||||
import { debounce } from '../../utils/helpers';
|
||||
import { NavigationHookResult } from '../route/route-interface';
|
||||
|
||||
import { ROUTER_INTENT_BACK, ROUTER_INTENT_FORWARD, ROUTER_INTENT_NONE } from './utils/constants';
|
||||
import { printRedirects, printRoutes } from './utils/debug';
|
||||
@@ -186,6 +187,7 @@ export class Router implements ComponentInterface {
|
||||
return true;
|
||||
}
|
||||
|
||||
// This handler gets called when a `ion-route-redirect` component is added to the DOM or if the from or to property of such node changes.
|
||||
private onRedirectChanged() {
|
||||
const path = this.getPath();
|
||||
if (path && findRouteRedirect(path, readRedirects(this.el))) {
|
||||
@@ -193,6 +195,7 @@ export class Router implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
// This handler gets called when a `ion-route` component is added to the DOM or if the from or to property of such node changes.
|
||||
private onRoutesChanged() {
|
||||
return this.writeNavStateRoot(this.getPath(), ROUTER_INTENT_NONE);
|
||||
}
|
||||
@@ -202,7 +205,7 @@ export class Router implements ComponentInterface {
|
||||
|
||||
if (win.history.state === null) {
|
||||
this.state++;
|
||||
win.history.replaceState(this.state, win.document.title, win.document.location && win.document.location.href);
|
||||
win.history.replaceState(this.state, win.document.title, win.document.location?.href);
|
||||
}
|
||||
|
||||
const state = win.history.state;
|
||||
@@ -211,11 +214,11 @@ export class Router implements ComponentInterface {
|
||||
|
||||
if (state > lastState || (state >= lastState && lastState > 0)) {
|
||||
return ROUTER_INTENT_FORWARD;
|
||||
} else if (state < lastState) {
|
||||
return ROUTER_INTENT_BACK;
|
||||
} else {
|
||||
return ROUTER_INTENT_NONE;
|
||||
}
|
||||
if (state < lastState) {
|
||||
return ROUTER_INTENT_BACK;
|
||||
}
|
||||
return ROUTER_INTENT_NONE;
|
||||
}
|
||||
|
||||
private async writeNavStateRoot(path: string[] | null, direction: RouterDirection, animation?: AnimationBuilder): Promise<boolean> {
|
||||
@@ -281,7 +284,7 @@ export class Router implements ComponentInterface {
|
||||
//
|
||||
// When the beforeLeave hook does not return true (to allow navigating) then that value is returned early and the beforeEnter is executed.
|
||||
// Otherwise the beforeEnterHook hook of the target route is executed.
|
||||
private async runGuards(to: string[] | null = this.getPath(), from?: string[] | null) {
|
||||
private async runGuards(to: string[] | null = this.getPath(), from?: string[] | null): Promise<NavigationHookResult> {
|
||||
if (from === undefined) {
|
||||
from = parsePath(this.previousPath).segments;
|
||||
}
|
||||
|
||||
@@ -88,5 +88,5 @@ const searchNavNode = (root: HTMLElement | undefined): NavOutletElement | undefi
|
||||
return root as NavOutletElement;
|
||||
}
|
||||
const outlet = root.querySelector<NavOutletElement>(QUERY);
|
||||
return outlet ? outlet : undefined;
|
||||
return outlet ?? undefined;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import { RouteChain, RouteNode, RouteRedirect, RouteTree } from './interface';
|
||||
import { parsePath } from './path';
|
||||
|
||||
const readProp = (el: HTMLElement, prop: string): string | null | undefined => {
|
||||
if (prop in el) {
|
||||
return (el as any)[prop];
|
||||
}
|
||||
if (el.hasAttribute(prop)) {
|
||||
return el.getAttribute(prop);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const readRedirects = (root: Element): RouteRedirect[] => {
|
||||
return (Array.from(root.children) as HTMLIonRouteRedirectElement[])
|
||||
.filter(el => el.tagName === 'ION-ROUTE-REDIRECT')
|
||||
@@ -17,46 +27,33 @@ export const readRoutes = (root: Element): RouteChain[] => {
|
||||
return flattenRouterTree(readRouteNodes(root));
|
||||
};
|
||||
|
||||
export const readRouteNodes = (root: Element, node = root): RouteTree => {
|
||||
export const readRouteNodes = (node: Element): RouteTree => {
|
||||
return (Array.from(node.children) as HTMLIonRouteElement[])
|
||||
.filter(el => el.tagName === 'ION-ROUTE' && el.component)
|
||||
.map(el => {
|
||||
const component = readProp(el, 'component');
|
||||
if (component == null) {
|
||||
throw new Error('component missing in ion-route');
|
||||
}
|
||||
const component = readProp(el, 'component') as string;
|
||||
return {
|
||||
path: parsePath(readProp(el, 'url')).segments,
|
||||
id: component.toLowerCase(),
|
||||
params: el.componentProps,
|
||||
beforeLeave: el.beforeLeave,
|
||||
beforeEnter: el.beforeEnter,
|
||||
children: readRouteNodes(root, el)
|
||||
children: readRouteNodes(el)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const readProp = (el: HTMLElement, prop: string): string | null | undefined => {
|
||||
if (prop in el) {
|
||||
return (el as any)[prop];
|
||||
}
|
||||
if (el.hasAttribute(prop)) {
|
||||
return el.getAttribute(prop);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const flattenRouterTree = (nodes: RouteTree): RouteChain[] => {
|
||||
const routes: RouteChain[] = [];
|
||||
const chains: RouteChain[] = [];
|
||||
for (const node of nodes) {
|
||||
flattenNode([], routes, node);
|
||||
flattenNode([], chains, node);
|
||||
}
|
||||
return routes;
|
||||
return chains;
|
||||
};
|
||||
|
||||
const flattenNode = (chain: RouteChain, routes: RouteChain[], node: RouteNode) => {
|
||||
const s = chain.slice();
|
||||
s.push({
|
||||
const flattenNode = (chain: RouteChain, chains: RouteChain[], node: RouteNode) => {
|
||||
chain = chain.slice();
|
||||
chain.push({
|
||||
id: node.id,
|
||||
path: node.path,
|
||||
params: node.params,
|
||||
@@ -65,10 +62,10 @@ const flattenNode = (chain: RouteChain, routes: RouteChain[], node: RouteNode) =
|
||||
});
|
||||
|
||||
if (node.children.length === 0) {
|
||||
routes.push(s);
|
||||
chains.push(chain);
|
||||
return;
|
||||
}
|
||||
for (const sub of node.children) {
|
||||
flattenNode(s, routes, sub);
|
||||
for (const child of node.children) {
|
||||
flattenNode(chain, chains, child);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ROUTER_INTENT_FORWARD } from './constants';
|
||||
import { ParsedRoute, RouteChain, RouterDirection } from './interface';
|
||||
|
||||
// Join the non empty segments with "/".
|
||||
export const generatePath = (segments: string[]): string => {
|
||||
const path = segments
|
||||
.filter(s => s.length > 0)
|
||||
@@ -9,6 +10,26 @@ export const generatePath = (segments: string[]): string => {
|
||||
return '/' + path;
|
||||
};
|
||||
|
||||
const generateUrl = (segments: string[], useHash: boolean, queryString?: string) => {
|
||||
let url = generatePath(segments);
|
||||
if (useHash) {
|
||||
url = '#' + url;
|
||||
}
|
||||
if (queryString !== undefined) {
|
||||
url += '?' + queryString;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
export const writePath = (history: History, root: string, useHash: boolean, path: string[], direction: RouterDirection, state: number, queryString?: string) => {
|
||||
const url = generateUrl([...parsePath(root).segments, ...path], useHash, queryString);
|
||||
if (direction === ROUTER_INTENT_FORWARD) {
|
||||
history.pushState(state, '', url);
|
||||
} else {
|
||||
history.replaceState(state, '', url);
|
||||
}
|
||||
};
|
||||
|
||||
export const chainToPath = (chain: RouteChain): string[] | null => {
|
||||
const path = [];
|
||||
for (const route of chain) {
|
||||
@@ -27,25 +48,12 @@ export const chainToPath = (chain: RouteChain): string[] | null => {
|
||||
return path;
|
||||
};
|
||||
|
||||
export const writePath = (history: History, root: string, useHash: boolean, path: string[], direction: RouterDirection, state: number, queryString?: string) => {
|
||||
let url = generatePath([
|
||||
...parsePath(root).segments,
|
||||
...path
|
||||
]);
|
||||
if (useHash) {
|
||||
url = '#' + url;
|
||||
}
|
||||
if (queryString !== undefined) {
|
||||
url = url + '?' + queryString;
|
||||
}
|
||||
if (direction === ROUTER_INTENT_FORWARD) {
|
||||
history.pushState(state, '', url);
|
||||
} else {
|
||||
history.replaceState(state, '', url);
|
||||
}
|
||||
};
|
||||
|
||||
export const removePrefix = (prefix: string[], path: string[]): string[] | null => {
|
||||
// Remove the prefix segments from the path segments.
|
||||
//
|
||||
// Return:
|
||||
// - null when the path segments do not start with the passed prefix,
|
||||
// - the path segments after the prefix otherwise.
|
||||
const removePrefix = (prefix: string[], path: string[]): string[] | null => {
|
||||
if (prefix.length > path.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -53,7 +61,7 @@ export const removePrefix = (prefix: string[], path: string[]): string[] | null
|
||||
return path;
|
||||
}
|
||||
for (let i = 0; i < prefix.length; i++) {
|
||||
if (prefix[i].length > 0 && prefix[i] !== path[i]) {
|
||||
if (prefix[i] !== path[i]) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -64,15 +72,8 @@ export const removePrefix = (prefix: string[], path: string[]): string[] | null
|
||||
};
|
||||
|
||||
export const readPath = (loc: Location, root: string, useHash: boolean): string[] | null => {
|
||||
let pathname = loc.pathname;
|
||||
if (useHash) {
|
||||
const hash = loc.hash;
|
||||
pathname = (hash[0] === '#')
|
||||
? hash.slice(1)
|
||||
: '';
|
||||
}
|
||||
|
||||
const prefix = parsePath(root).segments;
|
||||
const pathname = useHash ? loc.hash.slice(1) : loc.pathname;
|
||||
const path = parsePath(pathname).segments;
|
||||
return removePrefix(prefix, path);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
:host {
|
||||
@include position(0, null, null, 0);
|
||||
@include padding(0, 90px, 0);
|
||||
@include padding(var(--padding-top), 90px, var(--padding-bottom));
|
||||
|
||||
position: absolute;
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
:host(.title-large) {
|
||||
@include padding(0, 16px);
|
||||
@include transform-origin(start, center);
|
||||
@include transform-origin(left, center);
|
||||
|
||||
bottom: 0;
|
||||
|
||||
@@ -57,6 +57,10 @@
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
:host(.title-large.title-rtl) {
|
||||
@include transform-origin(right, center);
|
||||
}
|
||||
|
||||
:host(.title-large.ion-cloned-element) {
|
||||
--color: #{$text-color};
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ export class ToolbarTitle implements ComponentInterface {
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[`title-${size}`]: true,
|
||||
'title-rtl': document.dir === 'rtl'
|
||||
})}
|
||||
>
|
||||
<div class="toolbar-title">
|
||||
|
||||
@@ -197,7 +197,6 @@ export const setupConfig = (config: IonicConfig) => {
|
||||
const win = window as any;
|
||||
const Ionic = win.Ionic;
|
||||
if (Ionic && Ionic.config && Ionic.config.constructor.name !== 'Object') {
|
||||
console.error('ionic config was already initialized');
|
||||
return;
|
||||
}
|
||||
win.Ionic = win.Ionic || {};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "Pre-packaged API documentation for the Ionic docs.",
|
||||
"main": "core.json",
|
||||
"types": "core.d.ts",
|
||||
|
||||
18
packages/angular-server/package-lock.json
generated
18
packages/angular-server/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@angular/animations": "8.2.13",
|
||||
@@ -16,7 +16,7 @@
|
||||
"@angular/core": "8.2.13",
|
||||
"@angular/platform-browser": "8.2.13",
|
||||
"@angular/platform-server": "8.2.13",
|
||||
"@ionic/core": "5.6.6",
|
||||
"@ionic/core": "5.6.8",
|
||||
"ng-packagr": "5.7.1",
|
||||
"tslint": "^5.12.1",
|
||||
"tslint-ionic-rules": "0.0.21",
|
||||
@@ -137,9 +137,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "5.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.6.tgz",
|
||||
"integrity": "sha512-EbVIXOTVVPxBo7hsarBpRSFNsQ22wBFtWkKmrmliieknG5LUkf5WZBpj4EENQhzYA6c+//7/nfhcD9pWgtAofA==",
|
||||
"version": "5.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.8.tgz",
|
||||
"integrity": "sha512-JWrRGzw4SyyemjycPEh516fAkgFVtLp6RMPTH3uzK8L+DLfqJ/QU4Uccu89QqdcG/TBD75r3wkUtbKL2YlL8PQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
@@ -5424,9 +5424,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "5.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.6.tgz",
|
||||
"integrity": "sha512-EbVIXOTVVPxBo7hsarBpRSFNsQ22wBFtWkKmrmliieknG5LUkf5WZBpj4EENQhzYA6c+//7/nfhcD9pWgtAofA==",
|
||||
"version": "5.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.8.tgz",
|
||||
"integrity": "sha512-JWrRGzw4SyyemjycPEh516fAkgFVtLp6RMPTH3uzK8L+DLfqJ/QU4Uccu89QqdcG/TBD75r3wkUtbKL2YlL8PQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "Angular SSR Module for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -49,7 +49,7 @@
|
||||
"@angular/core": "8.2.13",
|
||||
"@angular/platform-browser": "8.2.13",
|
||||
"@angular/platform-server": "8.2.13",
|
||||
"@ionic/core": "5.6.7",
|
||||
"@ionic/core": "5.6.9",
|
||||
"ng-packagr": "5.7.1",
|
||||
"tslint": "^5.12.1",
|
||||
"tslint-ionic-rules": "0.0.21",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "React Router wrapper for @ionic/react",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -39,15 +39,15 @@
|
||||
"tslib": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ionic/react": "5.6.7",
|
||||
"@ionic/react": "5.6.9",
|
||||
"react": ">=16.8.6",
|
||||
"react-dom": ">=16.8.6",
|
||||
"react-router": "^5.0.1",
|
||||
"react-router-dom": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/core": "5.6.7",
|
||||
"@ionic/react": "5.6.7",
|
||||
"@ionic/core": "5.6.9",
|
||||
"@ionic/react": "5.6.9",
|
||||
"@rollup/plugin-node-resolve": "^8.1.0",
|
||||
"@testing-library/jest-dom": "^5.11.6",
|
||||
"@testing-library/react": "^11.2.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "React specific wrapper for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -39,7 +39,7 @@
|
||||
"css/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/core": "5.6.7",
|
||||
"@ionic/core": "5.6.9",
|
||||
"ionicons": "^5.1.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
|
||||
12
packages/vue-router/package-lock.json
generated
12
packages/vue-router/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@ionic/vue": "5.4.1",
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
"../../core": {
|
||||
"name": "@ionic/core",
|
||||
"version": "5.6.6",
|
||||
"version": "5.6.8",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -37,7 +37,7 @@
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/sass": "1.3.2",
|
||||
"@stencil/vue-output-target": "^0.4.2",
|
||||
"@stencil/vue-output-target": "^0.4.3",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/node": "^14.6.0",
|
||||
"@types/puppeteer": "5.4.3",
|
||||
@@ -45,6 +45,7 @@
|
||||
"aws-sdk": "^2.738.0",
|
||||
"clean-css-cli": "^4.1.11",
|
||||
"domino": "^2.1.6",
|
||||
"execa": "^5.0.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"jest": "^26.4.1",
|
||||
"jest-cli": "^26.4.1",
|
||||
@@ -8248,7 +8249,7 @@
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/core": "^2.4.0",
|
||||
"@stencil/sass": "1.3.2",
|
||||
"@stencil/vue-output-target": "^0.4.2",
|
||||
"@stencil/vue-output-target": "^0.4.3",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/node": "^14.6.0",
|
||||
"@types/puppeteer": "5.4.3",
|
||||
@@ -8256,6 +8257,7 @@
|
||||
"aws-sdk": "^2.738.0",
|
||||
"clean-css-cli": "^4.1.11",
|
||||
"domino": "^2.1.6",
|
||||
"execa": "^5.0.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"ionicons": "^5.5.1",
|
||||
"jest": "^26.4.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "Vue Router integration for @ionic/vue",
|
||||
"scripts": {
|
||||
"test.spec": "jest",
|
||||
|
||||
18
packages/vue/package-lock.json
generated
18
packages/vue/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "5.6.6",
|
||||
"@ionic/core": "5.6.8",
|
||||
"ionicons": "^5.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -53,9 +53,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "5.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.6.tgz",
|
||||
"integrity": "sha512-EbVIXOTVVPxBo7hsarBpRSFNsQ22wBFtWkKmrmliieknG5LUkf5WZBpj4EENQhzYA6c+//7/nfhcD9pWgtAofA==",
|
||||
"version": "5.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.8.tgz",
|
||||
"integrity": "sha512-JWrRGzw4SyyemjycPEh516fAkgFVtLp6RMPTH3uzK8L+DLfqJ/QU4Uccu89QqdcG/TBD75r3wkUtbKL2YlL8PQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
"ionicons": "^5.5.1",
|
||||
@@ -633,9 +633,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "5.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.6.tgz",
|
||||
"integrity": "sha512-EbVIXOTVVPxBo7hsarBpRSFNsQ22wBFtWkKmrmliieknG5LUkf5WZBpj4EENQhzYA6c+//7/nfhcD9pWgtAofA==",
|
||||
"version": "5.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.8.tgz",
|
||||
"integrity": "sha512-JWrRGzw4SyyemjycPEh516fAkgFVtLp6RMPTH3uzK8L+DLfqJ/QU4Uccu89QqdcG/TBD75r3wkUtbKL2YlL8PQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
"ionicons": "^5.5.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "5.6.7",
|
||||
"version": "5.6.9",
|
||||
"description": "Vue specific wrapper for @ionic/core",
|
||||
"scripts": {
|
||||
"lint": "echo add linter",
|
||||
@@ -57,7 +57,7 @@
|
||||
"vue-router": "^4.0.0-rc.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "5.6.7",
|
||||
"@ionic/core": "5.6.9",
|
||||
"ionicons": "^5.1.2"
|
||||
},
|
||||
"vetur": {
|
||||
|
||||
Reference in New Issue
Block a user