Compare commits

...

28 Commits

Author SHA1 Message Date
Liam DeBeasi
f3fb09ab44 merge release-5.9.4
5.9.4
2022-04-27 11:54:50 -04:00
Liam DeBeasi
7947a26ba4 5.9.4 2022-04-27 11:40:57 -04:00
Sean Perkins
ffb056d50e fix(core): inherit aria attributes on host elements (#25156) (#25169) 2022-04-27 10:59:58 -04:00
Liam DeBeasi
2d9724947d merge release-5.9.3
Release 5.9.3
2021-12-15 10:29:24 -05:00
Liam DeBeasi
02ef5ae179 5.9.3 2021-12-15 10:10:07 -05:00
Sean Perkins
4aab72b061 fix(vue): tabs no longer get unmounted when navigating back to a tabs context (#24337)
resolves #24332

Co-authored-by: Liam DeBeasi <liamdebeasi@icloud.com>
2021-12-15 09:55:29 -05:00
Liam DeBeasi
9c9e28ccc9 perf(content): remove global click listener to improve interaction performance (#24360)
resolves #24359
2021-12-15 09:55:22 -05:00
Liam DeBeasi
1c2875044a fix(vue): improve query params handling in tabs (#24355)
resolves #24353
2021-12-15 09:55:05 -05:00
Liam DeBeasi
d665ace5c4 chore(): create 5.9.x history
chore(): create 5.9.x history
2021-12-08 09:06:27 -05:00
Liam DeBeasi
351c30ce42 merge release-5.8.5
Release 5.8.5
2021-10-27 09:15:12 -04:00
Liam DeBeasi
3b9b9082b8 merge release-5.8.2
Release 5.8.2
2021-10-06 10:24:24 -04:00
Liam DeBeasi
0774cca2cd merge release-5.8.1
Release 5.8.1
2021-09-22 10:48:57 -04:00
Liam DeBeasi
6c366aaf87 merge release-5.8.0
Release 5.8.0
2021-09-15 11:37:12 -04:00
Liam DeBeasi
6876fd089f merge release-5.7.0
Release 5.7.0
2021-09-01 10:07:42 -04:00
Liam DeBeasi
22a8842ac2 merge release-5.6.14
Release 5.6.14
2021-08-18 09:33:30 -04:00
Liam DeBeasi
2d5faa75db merge release-5.6.13
Release 5.6.13
2021-08-04 10:25:37 -04:00
Liam DeBeasi
cab2a5103f merge release-5.6.12
Release 5.6.12
2021-07-21 09:37:04 -04:00
Liam DeBeasi
d36050918a merge release-5.6.11
Release 5.6.11
2021-07-01 12:03:38 -04:00
Liam DeBeasi
64f128be07 merge release-5.6.10
Release 5.6.10
2021-06-22 10:01:58 -04:00
Liam DeBeasi
87999e3c7a merge release-5.6.9
Release 5.6.9
2021-06-08 09:38:37 -04:00
Liam DeBeasi
bb4554211d merge release-5.6.8
Release 5.6.8
2021-05-27 16:01:36 -04:00
Liam DeBeasi
f71109b088 merge release-5.6.7
Release 5.6.7
2021-05-13 10:00:26 -04:00
Liam DeBeasi
44e18bd795 merge release-5.6.6
Release 5.6.6
2021-04-29 10:31:45 -04:00
Liam DeBeasi
f4d265eb60 merge release-5.6.5
Release 5.6.5
2021-04-22 13:37:44 -04:00
Liam DeBeasi
1e8dfb7d85 merge release-5.6.4
Release 5.6.4
2021-04-08 13:14:26 -04:00
Liam DeBeasi
9f023c92c4 merge release-5.6.3
Release 5.6.3
2021-03-23 11:21:16 -04:00
Liam DeBeasi
694d47b794 merge release-5.6.2
Release 5.6.2
2021-03-22 17:07:08 -04:00
Liam DeBeasi
b87c555a6e merge release-5.6.1
Release 5.6.1
2021-03-18 09:36:55 -04:00
29 changed files with 298 additions and 85 deletions

View File

@@ -44,7 +44,7 @@ async function askNpmTag(version) {
type: 'list',
name: 'npmTag',
message: 'Select npm tag or specify a new tag',
choices: ['latest', 'next', 'v4-lts']
choices: ['latest', 'next', 'v4-lts', 'v5-lts']
.concat([
new inquirer.Separator(),
{

View File

@@ -1,3 +1,27 @@
## [5.9.4](https://github.com/ionic-team/ionic/compare/v5.9.3...v5.9.4) (2022-04-27)
### Bug Fixes
* **core:** inherit aria attributes on host elements ([#25156](https://github.com/ionic-team/ionic/issues/25156)) ([#25169](https://github.com/ionic-team/ionic/issues/25169)) ([ffb056d](https://github.com/ionic-team/ionic/commit/ffb056d50e126a1b89f5133de1e7516d0c29a61a))
## [5.9.3](https://github.com/ionic-team/ionic/compare/v5.9.2...v5.9.3) (2021-12-15)
### Bug Fixes
* **vue:** improve query params handling in tabs ([#24355](https://github.com/ionic-team/ionic/issues/24355)) ([1c28750](https://github.com/ionic-team/ionic/commit/1c2875044ad4d93fdca866017159a89f4dc8872d)), closes [#24353](https://github.com/ionic-team/ionic/issues/24353)
* **vue:** tabs no longer get unmounted when navigating back to a tabs context ([#24337](https://github.com/ionic-team/ionic/issues/24337)) ([4aab72b](https://github.com/ionic-team/ionic/commit/4aab72b06159729d2dcd18b2ef0b76f693e5a74e)), closes [#24332](https://github.com/ionic-team/ionic/issues/24332)
### Performance Improvements
* **content:** remove global click listener to improve interaction performance ([#24360](https://github.com/ionic-team/ionic/issues/24360)) ([9c9e28c](https://github.com/ionic-team/ionic/commit/9c9e28ccc9f899c403c757d911ac02d9099415af)), closes [#24359](https://github.com/ionic-team/ionic/issues/24359)
## [5.9.2](https://github.com/ionic-team/ionic/compare/v5.9.1...v5.9.2) (2021-12-07)

View File

@@ -1,15 +1,15 @@
{
"name": "@ionic/angular",
"version": "5.9.2",
"version": "5.9.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular",
"version": "5.9.2",
"version": "5.9.4",
"license": "MIT",
"dependencies": {
"@ionic/core": "5.9.1",
"@ionic/core": "5.9.3",
"tslib": "^1.9.3"
},
"devDependencies": {
@@ -204,9 +204,9 @@
}
},
"node_modules/@ionic/core": {
"version": "5.9.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.1.tgz",
"integrity": "sha512-/jVO0N5ESs/iPFcrFZ/JFvW2Uh0ZV1uLFT2vtbtMfCaOMZK8Bmt36ZR1cDDFTuw14vPOLz/1wI2pbQru48JpkQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
"dependencies": {
"@stencil/core": "^2.4.0",
"ionicons": "^5.5.3",
@@ -5156,9 +5156,9 @@
}
},
"@ionic/core": {
"version": "5.9.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.1.tgz",
"integrity": "sha512-/jVO0N5ESs/iPFcrFZ/JFvW2Uh0ZV1uLFT2vtbtMfCaOMZK8Bmt36ZR1cDDFTuw14vPOLz/1wI2pbQru48JpkQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
"requires": {
"@stencil/core": "^2.4.0",
"ionicons": "^5.5.3",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "5.9.2",
"version": "5.9.4",
"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.9.2",
"@ionic/core": "5.9.4",
"tslib": "^1.9.3"
},
"peerDependencies": {

View File

@@ -1,12 +1,12 @@
{
"name": "@ionic/core",
"version": "5.9.2",
"version": "5.9.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/core",
"version": "5.9.2",
"version": "5.9.4",
"license": "MIT",
"dependencies": {
"@stencil/core": "^2.4.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "5.9.2",
"version": "5.9.4",
"description": "Base components for Ionic",
"keywords": [
"ionic",

View File

@@ -2,9 +2,9 @@ import { Component, ComponentInterface, Element, Host, Prop, h } from '@stencil/
import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
import { AnimationBuilder, Color } from '../../interface';
import { ButtonInterface } from '../../utils/element-interface';
import { inheritAttributes } from '../../utils/helpers';
import type { AnimationBuilder, Color } from '../../interface';
import type { ButtonInterface } from '../../utils/element-interface';
import { inheritAriaAttributes } from '../../utils/helpers';
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
/**
@@ -67,7 +67,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
@Prop() routerAnimation: AnimationBuilder | undefined;
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
this.inheritedAttributes = inheritAriaAttributes(this.el);
if (this.defaultHref === undefined) {
this.defaultHref = config.get('backButtonDefaultHref');

View File

@@ -1,9 +1,9 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Prop, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { AnimationBuilder, Color, RouterDirection } from '../../interface';
import { AnchorInterface, ButtonInterface } from '../../utils/element-interface';
import { hasShadowDom, inheritAttributes } from '../../utils/helpers';
import type { AnimationBuilder, Color, RouterDirection } from '../../interface';
import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface';
import { hasShadowDom, inheritAriaAttributes } from '../../utils/helpers';
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
/**
@@ -135,7 +135,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
this.inToolbar = !!this.el.closest('ion-buttons');
this.inListHeader = !!this.el.closest('ion-list-header');
this.inItem = !!this.el.closest('ion-item') || !!this.el.closest('ion-item-divider');
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
this.inheritedAttributes = inheritAriaAttributes(this.el);
}
private get hasIconOnly() {

View File

@@ -119,14 +119,6 @@ export class Content implements ComponentInterface {
this.resize();
}
@Listen('click', { capture: true })
onClick(ev: Event) {
if (this.isScrolling) {
ev.preventDefault();
ev.stopPropagation();
}
}
private shouldForceOverscroll() {
const { forceOverscroll } = this;
const mode = getIonMode(this);

View File

@@ -1,7 +1,7 @@
import { Component, ComponentInterface, Element, Host, Prop, h, writeTask } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { inheritAttributes } from '../../utils/helpers';
import { inheritAriaAttributes } from '../../utils/helpers';
import { hostContext } from '../../utils/theme';
import { cloneElement, createHeaderIndex, handleContentScroll, handleToolbarIntersection, setHeaderActive, setToolbarBackgroundOpacity } from './header.utils';
@@ -46,7 +46,7 @@ export class Header implements ComponentInterface {
@Prop() translucent = false;
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['role']);
this.inheritedAttributes = inheritAriaAttributes(this.el);
}
async componentDidLoad() {

View File

@@ -1,8 +1,14 @@
import { Build, Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { AutocompleteTypes, Color, InputChangeEventDetail, StyleEventDetail, TextFieldTypes } from '../../interface';
import { debounceEvent, findItemLabel, inheritAttributes } from '../../utils/helpers';
import type {
AutocompleteTypes,
Color,
InputChangeEventDetail,
StyleEventDetail,
TextFieldTypes,
} from '../../interface';
import { debounceEvent, findItemLabel, inheritAriaAttributes, inheritAttributes } from '../../utils/helpers';
import { createColorClasses } from '../../utils/theme';
/**
@@ -234,7 +240,10 @@ export class Input implements ComponentInterface {
}
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label', 'tabindex', 'title']);
this.inheritedAttributes = {
...inheritAriaAttributes(this.el),
...inheritAttributes(this.el, ['tabindex', 'title']),
};
}
connectedCallback() {

View File

@@ -2,9 +2,9 @@ import { Component, ComponentInterface, Element, Host, Listen, Prop, State, h }
import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
import { Color } from '../../interface';
import { ButtonInterface } from '../../utils/element-interface';
import { inheritAttributes } from '../../utils/helpers';
import type { Color } from '../../interface';
import type { ButtonInterface } from '../../utils/element-interface';
import { inheritAriaAttributes } from '../../utils/helpers';
import { menuController } from '../../utils/menu-controller';
import { createColorClasses, hostContext } from '../../utils/theme';
import { updateVisibility } from '../menu-toggle/menu-toggle-util';
@@ -58,7 +58,7 @@ export class MenuButton implements ComponentInterface, ButtonInterface {
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
this.inheritedAttributes = inheritAriaAttributes(this.el);
}
componentDidLoad() {

View File

@@ -5,7 +5,7 @@ import { getIonMode } from '../../global/ionic-global';
import { Animation, Gesture, GestureDetail, MenuChangeEventDetail, MenuI, Side } from '../../interface';
import { getTimeGivenProgression } from '../../utils/animation/cubic-bezier';
import { GESTURE_CONTROLLER } from '../../utils/gesture';
import { assert, clamp, inheritAttributes, isEndSide as isEnd } from '../../utils/helpers';
import { assert, clamp, inheritAriaAttributes, isEndSide as isEnd } from '../../utils/helpers';
import { menuController } from '../../utils/menu-controller';
const iosEasing = 'cubic-bezier(0.32,0.72,0,1)';
@@ -213,7 +213,7 @@ AFTER:
}
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
this.inheritedAttributes = inheritAriaAttributes(this.el);
}
async componentDidLoad() {

View File

@@ -1,8 +1,16 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Prop, State, Watch, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { Color, Gesture, GestureDetail, KnobName, RangeChangeEventDetail, RangeValue, StyleEventDetail } from '../../interface';
import { clamp, debounceEvent, getAriaLabel, inheritAttributes, renderHiddenInput } from '../../utils/helpers';
import type {
Color,
Gesture,
GestureDetail,
KnobName,
RangeChangeEventDetail,
RangeValue,
StyleEventDetail,
} from '../../interface';
import { clamp, debounceEvent, getAriaLabel, inheritAriaAttributes, renderHiddenInput } from '../../utils/helpers';
import { createColorClasses, hostContext } from '../../utils/theme';
/**
@@ -205,7 +213,7 @@ export class Range implements ComponentInterface {
*/
this.rangeId = (this.el.hasAttribute('id')) ? this.el.getAttribute('id')! : `ion-r-${rangeIds++}`;
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
this.inheritedAttributes = inheritAriaAttributes(this.el);
}
componentDidLoad() {

View File

@@ -1,8 +1,8 @@
import { Build, Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h, readTask } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { Color, StyleEventDetail, TextareaChangeEventDetail } from '../../interface';
import { debounceEvent, findItemLabel, inheritAttributes, raf } from '../../utils/helpers';
import type { Color, StyleEventDetail, TextareaChangeEventDetail } from '../../interface';
import { debounceEvent, findItemLabel, inheritAriaAttributes, inheritAttributes, raf } from '../../utils/helpers';
import { createColorClasses } from '../../utils/theme';
/**
@@ -214,7 +214,10 @@ export class Textarea implements ComponentInterface {
}
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['title']);
this.inheritedAttributes = {
...inheritAriaAttributes(this.el),
...inheritAttributes(this.el, ['title']),
};
}
componentDidLoad() {

View File

@@ -51,6 +51,74 @@ export const inheritAttributes = (el: HTMLElement, attributes: string[] = []) =>
return attributeObject;
}
/**
* List of available ARIA attributes + `role`.
* Removed deprecated attributes.
* https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes
*/
const ariaAttributes = [
'role',
'aria-activedescendant',
'aria-atomic',
'aria-autocomplete',
'aria-braillelabel',
'aria-brailleroledescription',
'aria-busy',
'aria-checked',
'aria-colcount',
'aria-colindex',
'aria-colindextext',
'aria-colspan',
'aria-controls',
'aria-current',
'aria-describedby',
'aria-description',
'aria-details',
'aria-disabled',
'aria-errormessage',
'aria-expanded',
'aria-flowto',
'aria-haspopup',
'aria-hidden',
'aria-invalid',
'aria-keyshortcuts',
'aria-label',
'aria-labelledby',
'aria-level',
'aria-live',
'aria-multiline',
'aria-multiselectable',
'aria-orientation',
'aria-owns',
'aria-placeholder',
'aria-posinset',
'aria-pressed',
'aria-readonly',
'aria-relevant',
'aria-required',
'aria-roledescription',
'aria-rowcount',
'aria-rowindex',
'aria-rowindextext',
'aria-rowspan',
'aria-selected',
'aria-setsize',
'aria-sort',
'aria-valuemax',
'aria-valuemin',
'aria-valuenow',
'aria-valuetext',
];
/**
* Returns an array of aria attributes that should be copied from
* the shadow host element to a target within the light DOM.
* @param el The element that the attributes should be copied from.
*/
export const inheritAriaAttributes = (el: HTMLElement) => {
return inheritAttributes(el, ariaAttributes);
};
export const addEventListener = (el: any, eventName: string, callback: any, opts?: any) => {
if (typeof (window as any) !== 'undefined') {
const win = window as any;
@@ -164,8 +232,8 @@ export const getAriaLabel = (componentEl: HTMLElement, inputId: string): { label
labelText = label.textContent;
label.setAttribute('aria-hidden', 'true');
// if there is no label, check to see if the user has provided
// one by setting an id on the component and using the label element
// if there is no label, check to see if the user has provided
// one by setting an id on the component and using the label element
} else if (componentId.trim() !== '') {
label = document.querySelector(`label[for="${componentId}"]`);

View File

@@ -1,4 +1,4 @@
import { inheritAttributes } from '../helpers';
import { inheritAttributes, inheritAriaAttributes } from '../helpers';
describe('inheritAttributes()', () => {
it('should create an attribute inheritance object', () => {
@@ -37,3 +37,29 @@ describe('inheritAttributes()', () => {
});
});
});
describe('inheritAriaAttributes()', () => {
it('should inherit ARIA attributes defined on the HTML element', () => {
const el = document.createElement('div');
el.setAttribute('aria-label', 'myLabel');
el.setAttribute('aria-describedby', 'myDescription');
const attributeObject = inheritAriaAttributes(el);
expect(attributeObject).toEqual({
'aria-label': 'myLabel',
'aria-describedby': 'myDescription',
});
});
it('should inherit the role attribute defined on the HTML element', () => {
const el = document.createElement('div');
el.setAttribute('role', 'button');
const attributeObject = inheritAriaAttributes(el);
expect(attributeObject).toEqual({
role: 'button',
});
});
});

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/docs",
"version": "5.9.2",
"version": "5.9.4",
"description": "Pre-packaged API documentation for the Ionic docs.",
"main": "core.json",
"types": "core.d.ts",

View File

@@ -1,12 +1,12 @@
{
"name": "@ionic/angular-server",
"version": "5.9.2",
"version": "5.9.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular-server",
"version": "5.9.2",
"version": "5.9.4",
"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.9.1",
"@ionic/core": "5.9.3",
"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.9.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.1.tgz",
"integrity": "sha512-/jVO0N5ESs/iPFcrFZ/JFvW2Uh0ZV1uLFT2vtbtMfCaOMZK8Bmt36ZR1cDDFTuw14vPOLz/1wI2pbQru48JpkQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
"dev": true,
"dependencies": {
"@stencil/core": "^2.4.0",
@@ -5424,9 +5424,9 @@
}
},
"@ionic/core": {
"version": "5.9.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.1.tgz",
"integrity": "sha512-/jVO0N5ESs/iPFcrFZ/JFvW2Uh0ZV1uLFT2vtbtMfCaOMZK8Bmt36ZR1cDDFTuw14vPOLz/1wI2pbQru48JpkQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
"dev": true,
"requires": {
"@stencil/core": "^2.4.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular-server",
"version": "5.9.2",
"version": "5.9.4",
"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.9.2",
"@ionic/core": "5.9.4",
"ng-packagr": "5.7.1",
"tslint": "^5.12.1",
"tslint-ionic-rules": "0.0.21",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/react-router",
"version": "5.9.2",
"version": "5.9.4",
"description": "React Router wrapper for @ionic/react",
"keywords": [
"ionic",
@@ -40,14 +40,14 @@
"tslib": "*"
},
"peerDependencies": {
"@ionic/react": "5.9.2",
"@ionic/react": "5.9.4",
"react": ">=16.8.6",
"react-dom": ">=16.8.6",
"react-router": "^5.0.1",
"react-router-dom": "^5.0.1"
},
"devDependencies": {
"@ionic/react": "5.9.2",
"@ionic/react": "5.9.4",
"@rollup/plugin-node-resolve": "^8.1.0",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/react",
"version": "5.9.2",
"version": "5.9.4",
"description": "React specific wrapper for @ionic/core",
"keywords": [
"ionic",
@@ -40,7 +40,7 @@
"css/"
],
"dependencies": {
"@ionic/core": "5.9.2",
"@ionic/core": "5.9.4",
"ionicons": "^5.1.2",
"tslib": "*"
},

View File

@@ -1,12 +1,12 @@
{
"name": "@ionic/vue-router",
"version": "5.9.2",
"version": "5.9.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/vue-router",
"version": "5.9.2",
"version": "5.9.4",
"license": "MIT",
"devDependencies": {
"@ionic/vue": "5.4.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/vue-router",
"version": "5.9.2",
"version": "5.9.4",
"description": "Vue Router integration for @ionic/vue",
"scripts": {
"test.spec": "jest",

View File

@@ -1,15 +1,15 @@
{
"name": "@ionic/vue",
"version": "5.9.2",
"version": "5.9.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/vue",
"version": "5.9.2",
"version": "5.9.4",
"license": "MIT",
"dependencies": {
"@ionic/core": "5.9.1",
"@ionic/core": "5.9.3",
"ionicons": "^5.1.2"
},
"devDependencies": {
@@ -53,9 +53,9 @@
}
},
"node_modules/@ionic/core": {
"version": "5.9.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.1.tgz",
"integrity": "sha512-/jVO0N5ESs/iPFcrFZ/JFvW2Uh0ZV1uLFT2vtbtMfCaOMZK8Bmt36ZR1cDDFTuw14vPOLz/1wI2pbQru48JpkQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
"dependencies": {
"@stencil/core": "^2.4.0",
"ionicons": "^5.5.3",
@@ -633,9 +633,9 @@
}
},
"@ionic/core": {
"version": "5.9.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.1.tgz",
"integrity": "sha512-/jVO0N5ESs/iPFcrFZ/JFvW2Uh0ZV1uLFT2vtbtMfCaOMZK8Bmt36ZR1cDDFTuw14vPOLz/1wI2pbQru48JpkQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
"requires": {
"@stencil/core": "^2.4.0",
"ionicons": "^5.5.3",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/vue",
"version": "5.9.2",
"version": "5.9.4",
"description": "Vue specific wrapper for @ionic/core",
"scripts": {
"lint": "echo add linter",
@@ -59,7 +59,7 @@
"vue-router": "^4.0.0-rc.4"
},
"dependencies": {
"@ionic/core": "5.9.2",
"@ionic/core": "5.9.4",
"ionicons": "^5.1.2"
},
"vetur": {

View File

@@ -14,6 +14,10 @@ import { AnimationBuilder, LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_W
import { matchedRouteKey, routeLocationKey, useRoute } from 'vue-router';
import { fireLifecycle, generateId, getConfig } from '../utils';
const isViewVisible = (enteringEl: HTMLElement) => {
return !enteringEl.classList.contains('ion-page-hidden') && !enteringEl.classList.contains('ion-page-invisible');
}
let viewDepthKey: InjectionKey<0> = Symbol(0);
export const IonRouterOutlet = defineComponent({
name: 'IonRouterOutlet',
@@ -230,13 +234,35 @@ export const IonRouterOutlet = defineComponent({
See https://ionicframework.com/docs/vue/navigation#ionpage for more information.`);
}
if (enteringViewItem === leavingViewItem) return;
if (!leavingViewItem && prevRouteLastPathname) {
leavingViewItem = viewStacks.findViewItemByPathname(prevRouteLastPathname, id, usingDeprecatedRouteSetup);
}
/**
* If the entering view is already
* visible, then no transition is needed.
* This is most common when navigating
* from a tabs page to a non-tabs page
* and then back to the tabs page.
* Even when the tabs context navigated away,
* the inner tabs page was still active.
* This also avoids an issue where
* the previous tabs page is incorrectly
* unmounted since it would automatically
* unmount the previous view.
*
* This should also only apply to entering and
* leaving items in the same router outlet (i.e.
* Tab1 and Tab2), otherwise this will
* return early for swipe to go back when
* going from a non-tabs page to a tabs page.
*/
if (isViewVisible(enteringEl) && leavingViewItem !== undefined && !isViewVisible(leavingViewItem.ionPageElement)) {
return;
}
fireLifecycle(enteringViewItem.vueComponent, enteringViewItem.vueComponentRef, LIFECYCLE_WILL_ENTER);
if (leavingViewItem && enteringViewItem !== leavingViewItem) {

View File

@@ -113,7 +113,14 @@ export const IonTabBar = defineComponent({
* land on /tabs/tab1/child instead of /tabs/tab1.
*/
if (activeTab !== prevActiveTab || (prevHref !== currentRoute.pathname)) {
const search = (currentRoute.search !== undefined) ? `?${currentRoute.search}` : '';
/**
* By default the search is `undefined` in Ionic Vue,
* but Vue Router can set the search to the empty string.
* We check for truthy here because empty string is falsy
* and currentRoute.search cannot ever be a boolean.
*/
const search = (currentRoute.search) ? `?${currentRoute.search}` : '';
tabs[activeTab] = {
...tabs[activeTab],
currentHref: currentRoute.pathname + search

View File

@@ -305,7 +305,57 @@ describe('Tabs', () => {
cy.ionPageHidden('tab2');
cy.url().should('include', '/tabs/tab1/child-one?key=value');
})
});
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24353
it('should handle clicking tab multiple times without query string', () => {
cy.visit('http://localhost:8080/tabs/tab1');
cy.ionPageVisible('tab1');
cy.get('ion-tab-button#tab-button-tab2').click();
cy.ionPageVisible('tab2');
cy.ionPageHidden('tab1');
cy.get('ion-tab-button#tab-button-tab1').click();
cy.ionPageVisible('tab1');
cy.ionPageHidden('tab2');
cy.get('ion-tab-button#tab-button-tab1').click();
cy.ionPageVisible('tab1');
cy.ionPageHidden('tab2');
cy.get('ion-tab-button#tab-button-tab2').click();
cy.ionPageVisible('tab2');
cy.ionPageHidden('tab1');
});
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24332
it('should not unmount tab 1 when leaving tabs context', () => {
cy.visit('http://localhost:8080/tabs');
cy.ionPageVisible('tab1');
// Dynamically add tab 4 because tab 3 redirects to tab 1
cy.get('#add-tab').click();
cy.get('ion-tab-button#tab-button-tab4').click();
cy.ionPageHidden('tab1');
cy.ionPageVisible('tab4');
cy.get('ion-tab-button#tab-button-tab2').click();
cy.ionPageHidden('tab4');
cy.ionPageVisible('tab2');
cy.get('[data-pageid="tab2"] #routing').click();
cy.ionPageVisible('routing');
cy.ionPageHidden('tabs');
cy.ionBackClick('routing');
cy.ionPageDoesNotExist('routing');
cy.ionPageVisible('tabs');
cy.ionPageVisible('tab2');
cy.ionPageHidden('tab1');
});
})
describe('Tabs - Swipe to Go Back', () => {