From dee6eb30df370047bbc872b00ab6d801dd11fa81 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 6 Apr 2021 09:53:26 -0400 Subject: [PATCH 01/18] fix(react): overlays now correctly unmount any child components after dismissing (#23149) resolves #23140 --- packages/react/src/components/createOverlayComponent.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/react/src/components/createOverlayComponent.tsx b/packages/react/src/components/createOverlayComponent.tsx index 7cd3c83498..6dc1d69e3a 100644 --- a/packages/react/src/components/createOverlayComponent.tsx +++ b/packages/react/src/components/createOverlayComponent.tsx @@ -94,6 +94,13 @@ export const createOverlayComponent = < if (this.overlay && prevProps.isOpen !== this.props.isOpen && this.props.isOpen === false) { await this.overlay.dismiss(); isDismissing = false; + + /** + * Now that the overlay is dismissed + * we need to render again so that any + * inner components will be unmounted + */ + this.forceUpdate(); } } From 42e6c90c4632423386b165dddc4b94a55c075e2e Mon Sep 17 00:00:00 2001 From: William Martin Date: Tue, 6 Apr 2021 09:54:29 -0400 Subject: [PATCH 02/18] fix(toggle): prevent click event from firing twice (#23146) resolves #23041 --- core/src/components/toggle/test/basic/index.html | 10 ++++++++++ core/src/components/toggle/toggle.scss | 2 ++ 2 files changed, 12 insertions(+) diff --git a/core/src/components/toggle/test/basic/index.html b/core/src/components/toggle/test/basic/index.html index 815245d35c..32394af0b7 100644 --- a/core/src/components/toggle/test/basic/index.html +++ b/core/src/components/toggle/test/basic/index.html @@ -76,6 +76,11 @@ + + Stop Immediate Event Propagation + + + @@ -121,6 +126,11 @@ var isTrue = el[prop] ? false : true; el[prop] = isTrue; } + + document.getElementById('eventPropagation').addEventListener('click', (evt) => { + evt.stopImmediatePropagation(); + console.log('clicked'); + }); diff --git a/core/src/components/toggle/toggle.scss b/core/src/components/toggle/toggle.scss index 2ab8b0ab3a..943f442f18 100644 --- a/core/src/components/toggle/toggle.scss +++ b/core/src/components/toggle/toggle.scss @@ -53,6 +53,8 @@ label { align-items: center; opacity: 0; + + pointer-events: none; } input { From 72031902347dc279045e2e099f69852a23dd8436 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 6 Apr 2021 10:16:23 -0400 Subject: [PATCH 03/18] fix(react, vue): correct view now chosen when going back inside tabs (#23154) resolves #23087 resolves #23101 --- .../src/ReactRouter/IonRouter.tsx | 14 ++- .../test-app/cypress/integration/tabs.js | 46 +++++++++ packages/react-router/test-app/src/App.tsx | 4 + .../test-app/src/pages/tabs/Tabs.tsx | 95 +++++++++++++++++++ .../test-app/src/pages/tabs/TabsSecondary.tsx | 78 +++++++++++++++ packages/vue-router/src/router.ts | 14 ++- packages/vue/test-app/tests/e2e/specs/tabs.js | 44 +++++++++ 7 files changed, 293 insertions(+), 2 deletions(-) create mode 100644 packages/react-router/test-app/cypress/integration/tabs.js create mode 100644 packages/react-router/test-app/src/pages/tabs/Tabs.tsx create mode 100644 packages/react-router/test-app/src/pages/tabs/TabsSecondary.tsx diff --git a/packages/react-router/src/ReactRouter/IonRouter.tsx b/packages/react-router/src/ReactRouter/IonRouter.tsx index f131145473..61a57a303a 100644 --- a/packages/react-router/src/ReactRouter/IonRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonRouter.tsx @@ -243,7 +243,19 @@ class IonRouterInner extends React.PureComponent { routeDirection: 'back', routeAnimation: routeAnimation || routeInfo.routeAnimation, }; - if (routeInfo.lastPathname === routeInfo.pushedByRoute || prevInfo.pathname === routeInfo.pushedByRoute) { + if ( + routeInfo.lastPathname === routeInfo.pushedByRoute || + ( + /** + * We need to exclude tab switches/tab + * context changes here because tabbed + * navigation is not linear, but router.back() + * will go back in a linear fashion. + */ + prevInfo.pathname === routeInfo.pushedByRoute && + routeInfo.tab === '' && prevInfo.tab === '' + ) + ) { this.props.history.goBack(); } else { this.handleNavigate(prevInfo.pathname + (prevInfo.search || ''), 'pop', 'back'); diff --git a/packages/react-router/test-app/cypress/integration/tabs.js b/packages/react-router/test-app/cypress/integration/tabs.js new file mode 100644 index 0000000000..f0719090ae --- /dev/null +++ b/packages/react-router/test-app/cypress/integration/tabs.js @@ -0,0 +1,46 @@ +const port = 3000; + +describe('Tabs', () => { + // Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23101 + it('should return to previous tab instance when using the ion-back-button', () => { + cy.visit(`http://localhost:${port}/tabs/tab1`); + + cy.get('#tabs-secondary').click(); + cy.ionPageVisible('tab1-secondary'); + + cy.get('ion-tab-button#tab-button-tab2-secondary').click(); + cy.ionPageHidden('tab1-secondary'); + cy.ionPageVisible('tab2-secondary'); + + cy.get('ion-tab-button#tab-button-tab1-secondary').click(); + cy.ionPageHidden('tab2-secondary'); + cy.ionPageVisible('tab1-secondary'); + + cy.ionBackClick('tab1-secondary'); + cy.ionPageDoesNotExist('tabs-secondary'); + cy.ionPageVisible('tab1'); + }); + + // Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23087 + it('should return to correct view and url when going back from child page after switching tabs', () => { + cy.visit(`http://localhost:${port}/tabs/tab1`); + + cy.get('#child-one').click(); + cy.ionPageHidden('tab1'); + cy.ionPageVisible('tab1child1'); + + cy.get('ion-tab-button#tab-button-tab2').click(); + cy.ionPageHidden('tab1child1'); + cy.ionPageVisible('tab2'); + + cy.get('ion-tab-button#tab-button-tab1').click(); + cy.ionPageHidden('tab2'); + cy.ionPageVisible('tab1child1'); + + cy.ionBackClick('tab1child1'); + cy.ionPageDoesNotExist('tab1child1'); + cy.ionPageVisible('tab1'); + + cy.url().should('include', '/tabs/tab1'); + }); +}); diff --git a/packages/react-router/test-app/src/App.tsx b/packages/react-router/test-app/src/App.tsx index 75ef0f0398..7a4915eba5 100644 --- a/packages/react-router/test-app/src/App.tsx +++ b/packages/react-router/test-app/src/App.tsx @@ -34,6 +34,8 @@ import { OutletRef } from './pages/outlet-ref/OutletRef'; import { SwipeToGoBack } from './pages/swipe-to-go-back/SwipToGoBack'; import Refs from './pages/refs/Refs'; import DynamicIonpageClassnames from './pages/dynamic-ionpage-classnames/DynamicIonpageClassnames'; +import Tabs from './pages/tabs/Tabs'; +import TabsSecondary from './pages/tabs/TabsSecondary'; debugger; const App: React.FC = () => { return ( @@ -51,6 +53,8 @@ const App: React.FC = () => { + + diff --git a/packages/react-router/test-app/src/pages/tabs/Tabs.tsx b/packages/react-router/test-app/src/pages/tabs/Tabs.tsx new file mode 100644 index 0000000000..3b5d04ac66 --- /dev/null +++ b/packages/react-router/test-app/src/pages/tabs/Tabs.tsx @@ -0,0 +1,95 @@ +import React from 'react'; +import { + IonTabs, + IonRouterOutlet, + IonTabBar, + IonTabButton, + IonIcon, + IonLabel, + IonPage, + IonHeader, + IonToolbar, + IonButtons, + IonBackButton, + IonTitle, + IonContent, + IonButton, +} from '@ionic/react'; +import { Route, Redirect } from 'react-router'; +import { triangle, square } from 'ionicons/icons'; + +interface Tabs {} + +const Tabs: React.FC = () => { + return ( + + + + + + + + + + + Tab1 + + + + Tab2 + + + + ); +}; + +const Tab1 = () => { + return ( + + + + Tab1 + + + + Go to Tab1Child1 + Go to Secondary Tabs + + + ); +}; + +const Tab1Child1 = () => { + return ( + + + + + + + Tab1 + + + + + + + ); +}; + +const Tab2 = () => { + return ( + + + + Tab2 + + + + Tab 2 + + + ); +}; + +export default Tabs; diff --git a/packages/react-router/test-app/src/pages/tabs/TabsSecondary.tsx b/packages/react-router/test-app/src/pages/tabs/TabsSecondary.tsx new file mode 100644 index 0000000000..ef6197e08b --- /dev/null +++ b/packages/react-router/test-app/src/pages/tabs/TabsSecondary.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import { + IonTabs, + IonRouterOutlet, + IonTabBar, + IonTabButton, + IonIcon, + IonLabel, + IonPage, + IonHeader, + IonToolbar, + IonButtons, + IonBackButton, + IonTitle, + IonContent, + IonButton, +} from '@ionic/react'; +import { Route, Redirect } from 'react-router'; +import { triangle, square } from 'ionicons/icons'; + +interface TabsSecondary {} + +const TabsSecondary: React.FC = () => { + return ( + + + + + + + + + + Tab1 + + + + Tab2 + + + + ); +}; + +const Tab1 = () => { + return ( + + + + Tab1 + + + + + + + Tab 1 + + + ); +}; + +const Tab2 = () => { + return ( + + + + Tab2 + + + + Tab 2 + + + ); +}; + +export default TabsSecondary; diff --git a/packages/vue-router/src/router.ts b/packages/vue-router/src/router.ts index 7f939b58c7..3fd1ec43f0 100644 --- a/packages/vue-router/src/router.ts +++ b/packages/vue-router/src/router.ts @@ -88,7 +88,19 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) => const prevInfo = locationHistory.findLastLocation(routeInfo); if (prevInfo) { incomingRouteParams = { ...prevInfo, routerAction: 'pop', routerDirection: 'back', routerAnimation: routerAnimation || routeInfo.routerAnimation }; - if (routeInfo.lastPathname === routeInfo.pushedByRoute || prevInfo.pathname === routeInfo.pushedByRoute) { + if ( + routeInfo.lastPathname === routeInfo.pushedByRoute || + ( + /** + * We need to exclude tab switches/tab + * context changes here because tabbed + * navigation is not linear, but router.back() + * will go back in a linear fashion. + */ + prevInfo.pathname === routeInfo.pushedByRoute && + routeInfo.tab === '' && prevInfo.tab === '' + ) + ) { router.back(); } else { router.replace({ path: prevInfo.pathname, query: parseQuery(prevInfo.search) }); diff --git a/packages/vue/test-app/tests/e2e/specs/tabs.js b/packages/vue/test-app/tests/e2e/specs/tabs.js index 5bb3205c1b..d11c1d5bf9 100644 --- a/packages/vue/test-app/tests/e2e/specs/tabs.js +++ b/packages/vue/test-app/tests/e2e/specs/tabs.js @@ -220,6 +220,50 @@ describe('Tabs', () => { cy.get('ion-tab-button#tab-button-tab1').should('not.have.class', 'tab-selected'); }); + + // Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23101 + it('should return to previous tab instance when using the ion-back-button', () => { + cy.visit('http://localhost:8080/tabs/tab1'); + + cy.get('#tabs-secondary').click(); + cy.ionPageHidden('tabs'); + cy.ionPageVisible('tab1-secondary'); + + cy.get('ion-tab-button#tab-button-tab2-secondary').click(); + cy.ionPageHidden('tab1-secondary'); + cy.ionPageVisible('tab2-secondary'); + + cy.get('ion-tab-button#tab-button-tab1-secondary').click(); + cy.ionPageHidden('tab2-secondary'); + cy.ionPageVisible('tab1-secondary'); + + cy.ionBackClick('tab1-secondary'); + cy.ionPageDoesNotExist('tabs-secondary'); + cy.ionPageVisible('tab1'); + }); + + // Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23087 + it('should return to correct view and url when going back from child page after switching tabs', () => { + cy.visit('http://localhost:8080/tabs/tab1'); + + cy.get('#child-one').click(); + cy.ionPageHidden('tab1'); + cy.ionPageVisible('tab1childone'); + + cy.get('ion-tab-button#tab-button-tab2').click(); + cy.ionPageHidden('tab1childone'); + cy.ionPageVisible('tab2'); + + cy.get('ion-tab-button#tab-button-tab1').click(); + cy.ionPageHidden('tab2'); + cy.ionPageVisible('tab1childone'); + + cy.ionBackClick('tab1childone'); + cy.ionPageDoesNotExist('tab1childone'); + cy.ionPageVisible('tab1'); + + cy.url().should('include', '/tabs/tab1'); + }); }) describe('Tabs - Swipe to Go Back', () => { From 8739c9b16d319660c8b115c3d6cb101fa2ce81c7 Mon Sep 17 00:00:00 2001 From: Ikko Ashimine Date: Wed, 7 Apr 2021 22:42:17 +0900 Subject: [PATCH 04/18] test(slides): fix typo in test (#23158) --- core/src/components/slides/test/basic/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/components/slides/test/basic/index.html b/core/src/components/slides/test/basic/index.html index a21c09fb3d..1755f66fbb 100644 --- a/core/src/components/slides/test/basic/index.html +++ b/core/src/components/slides/test/basic/index.html @@ -148,7 +148,7 @@ console.log('slide transition start', e) }); slides.addEventListener('ionSlideTransitionEnd', function (e) { - console.log('slide transistion end', e) + console.log('slide transition end', e) }); slides.addEventListener('ionSlideDrag', function (e) { console.log('slide drag', e) From 61f094d30665c9afec428028883a5d9a085892d8 Mon Sep 17 00:00:00 2001 From: William Martin Date: Wed, 7 Apr 2021 14:44:03 -0400 Subject: [PATCH 05/18] fix(input): inherit aria-label to input (#23159) --- core/src/components/input/input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/components/input/input.tsx b/core/src/components/input/input.tsx index 8615969850..b749e719b5 100644 --- a/core/src/components/input/input.tsx +++ b/core/src/components/input/input.tsx @@ -234,7 +234,7 @@ export class Input implements ComponentInterface { } componentWillLoad() { - this.inheritedAttributes = inheritAttributes(this.el, ['tabindex', 'title']); + this.inheritedAttributes = inheritAttributes(this.el, ['aria-label', 'tabindex', 'title']); } connectedCallback() { From 0e1cb1bb0ce94bb01811482c0aa303681773d9fd Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Thu, 8 Apr 2021 12:49:11 -0400 Subject: [PATCH 06/18] 5.6.4 --- CHANGELOG.md | 15 +++++++++ angular/package-lock.json | 34 +++++++++++++------- angular/package.json | 4 +-- core/package-lock.json | 4 +-- core/package.json | 2 +- docs/package.json | 2 +- packages/angular-server/package-lock.json | 36 ++++++++++++++------- packages/angular-server/package.json | 4 +-- packages/react-router/package.json | 10 +++--- packages/react/package.json | 4 +-- packages/vue-router/package-lock.json | 10 +++--- packages/vue-router/package.json | 2 +- packages/vue/package-lock.json | 38 +++++++++++++++-------- packages/vue/package.json | 4 +-- 14 files changed, 111 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9088bdd77e..8ed5e55e4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +## [5.6.4](https://github.com/ionic-team/ionic/compare/v5.6.3...v5.6.4) (2021-04-08) + + +### Bug Fixes + +* **angular:** swiping back quickly no longer causes app to get stuck ([#23125](https://github.com/ionic-team/ionic/issues/23125)) ([28c52fd](https://github.com/ionic-team/ionic/commit/28c52fd4e3df3d96b4ec83075a322e110e938a1a)), closes [#15154](https://github.com/ionic-team/ionic/issues/15154) +* **input:** inherit aria-label to input ([#23159](https://github.com/ionic-team/ionic/issues/23159)) ([61f094d](https://github.com/ionic-team/ionic/commit/61f094d30665c9afec428028883a5d9a085892d8)) +* **react:** overlays now correctly unmount any child components after dismissing ([#23149](https://github.com/ionic-team/ionic/issues/23149)) ([dee6eb3](https://github.com/ionic-team/ionic/commit/dee6eb30df370047bbc872b00ab6d801dd11fa81)), closes [#23140](https://github.com/ionic-team/ionic/issues/23140) +* **react, vue:** correct view now chosen when going back inside tabs ([#23154](https://github.com/ionic-team/ionic/issues/23154)) ([7203190](https://github.com/ionic-team/ionic/commit/72031902347dc279045e2e099f69852a23dd8436)), closes [#23087](https://github.com/ionic-team/ionic/issues/23087) [#23101](https://github.com/ionic-team/ionic/issues/23101) +* **toggle:** prevent click event from firing twice ([#23146](https://github.com/ionic-team/ionic/issues/23146)) ([42e6c90](https://github.com/ionic-team/ionic/commit/42e6c90c4632423386b165dddc4b94a55c075e2e)), closes [#23041](https://github.com/ionic-team/ionic/issues/23041) +* **vue:** account for event name changes in vue 3.0.6+ for overlay components ([#23100](https://github.com/ionic-team/ionic/issues/23100)) ([27318cf](https://github.com/ionic-team/ionic/commit/27318cf58563c4b38d0b7045fb61451f45954a8f)) +* **vue:** components now integrate properly with vee-validate ([#23114](https://github.com/ionic-team/ionic/issues/23114)) ([ba51daf](https://github.com/ionic-team/ionic/commit/ba51daf17c4438aea6826882f82a04ebf8d6a5d8)), closes [#22886](https://github.com/ionic-team/ionic/issues/22886) + + + ## [5.6.3](https://github.com/ionic-team/ionic/compare/v5.6.2...v5.6.3) (2021-03-23) diff --git a/angular/package-lock.json b/angular/package-lock.json index e80b316dbc..a7e653162b 100644 --- a/angular/package-lock.json +++ b/angular/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular", - "version": "5.6.3", + "version": "5.6.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular", - "version": "5.6.3", + "version": "5.6.4", "license": "MIT", "dependencies": { - "@ionic/core": "5.6.2", + "@ionic/core": "5.6.3", "tslib": "^1.9.3" }, "devDependencies": { @@ -204,15 +204,20 @@ } }, "node_modules/@ionic/core": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.2.tgz", - "integrity": "sha512-hnwd6ln0IZUVfFu2ilZK03b6EdQFqEWiTkL5kayq2gjB3BK/u1IEtV3C9fdwc8NJKopGwdbdQnujj6VhYPzV3Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.3.tgz", + "integrity": "sha512-RPugxDcCwB5rgEh6yR2QDTzblT8BRBktsW6y+VBt62yHRzgEAENEfVyvkADz+CkGAsmZuPmC8OQC2jJrx/fJFA==", "dependencies": { "@stencil/core": "^2.4.0", "ionicons": "^5.5.1", - "tslib": "^1.10.0" + "tslib": "^2.1.0" } }, + "node_modules/@ionic/core/node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + }, "node_modules/@rollup/plugin-commonjs": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz", @@ -5151,13 +5156,20 @@ } }, "@ionic/core": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.2.tgz", - "integrity": "sha512-hnwd6ln0IZUVfFu2ilZK03b6EdQFqEWiTkL5kayq2gjB3BK/u1IEtV3C9fdwc8NJKopGwdbdQnujj6VhYPzV3Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.3.tgz", + "integrity": "sha512-RPugxDcCwB5rgEh6yR2QDTzblT8BRBktsW6y+VBt62yHRzgEAENEfVyvkADz+CkGAsmZuPmC8OQC2jJrx/fJFA==", "requires": { "@stencil/core": "^2.4.0", "ionicons": "^5.5.1", - "tslib": "^1.10.0" + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } } }, "@rollup/plugin-commonjs": { diff --git a/angular/package.json b/angular/package.json index cf9ac0d335..6a79eb2be3 100644 --- a/angular/package.json +++ b/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular", - "version": "5.6.3", + "version": "5.6.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.6.3", + "@ionic/core": "5.6.4", "tslib": "^1.9.3" }, "peerDependencies": { diff --git a/core/package-lock.json b/core/package-lock.json index 867a94b262..9f5c5a82d5 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/core", - "version": "5.6.3", + "version": "5.6.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/core", - "version": "5.6.3", + "version": "5.6.4", "license": "MIT", "dependencies": { "@stencil/core": "^2.4.0", diff --git a/core/package.json b/core/package.json index 5185aa810b..94fa265a07 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "5.6.3", + "version": "5.6.4", "description": "Base components for Ionic", "keywords": [ "ionic", diff --git a/docs/package.json b/docs/package.json index b278476b08..1958d60a00 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/docs", - "version": "5.6.3", + "version": "5.6.4", "description": "Pre-packaged API documentation for the Ionic docs.", "main": "core.json", "types": "core.d.ts", diff --git a/packages/angular-server/package-lock.json b/packages/angular-server/package-lock.json index df7fc54258..81095f6f95 100644 --- a/packages/angular-server/package-lock.json +++ b/packages/angular-server/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/angular-server", - "version": "5.6.3", + "version": "5.6.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular-server", - "version": "5.6.3", + "version": "5.6.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.6.2", + "@ionic/core": "5.6.3", "ng-packagr": "5.7.1", "tslint": "^5.12.1", "tslint-ionic-rules": "0.0.21", @@ -137,16 +137,22 @@ } }, "node_modules/@ionic/core": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.2.tgz", - "integrity": "sha512-hnwd6ln0IZUVfFu2ilZK03b6EdQFqEWiTkL5kayq2gjB3BK/u1IEtV3C9fdwc8NJKopGwdbdQnujj6VhYPzV3Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.3.tgz", + "integrity": "sha512-RPugxDcCwB5rgEh6yR2QDTzblT8BRBktsW6y+VBt62yHRzgEAENEfVyvkADz+CkGAsmZuPmC8OQC2jJrx/fJFA==", "dev": true, "dependencies": { "@stencil/core": "^2.4.0", "ionicons": "^5.5.1", - "tslib": "^1.10.0" + "tslib": "^2.1.0" } }, + "node_modules/@ionic/core/node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -5418,14 +5424,22 @@ } }, "@ionic/core": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.2.tgz", - "integrity": "sha512-hnwd6ln0IZUVfFu2ilZK03b6EdQFqEWiTkL5kayq2gjB3BK/u1IEtV3C9fdwc8NJKopGwdbdQnujj6VhYPzV3Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.3.tgz", + "integrity": "sha512-RPugxDcCwB5rgEh6yR2QDTzblT8BRBktsW6y+VBt62yHRzgEAENEfVyvkADz+CkGAsmZuPmC8OQC2jJrx/fJFA==", "dev": true, "requires": { "@stencil/core": "^2.4.0", "ionicons": "^5.5.1", - "tslib": "^1.10.0" + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + } } }, "@sindresorhus/is": { diff --git a/packages/angular-server/package.json b/packages/angular-server/package.json index a90a58b419..821a3779a7 100644 --- a/packages/angular-server/package.json +++ b/packages/angular-server/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular-server", - "version": "5.6.3", + "version": "5.6.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.6.3", + "@ionic/core": "5.6.4", "ng-packagr": "5.7.1", "tslint": "^5.12.1", "tslint-ionic-rules": "0.0.21", diff --git a/packages/react-router/package.json b/packages/react-router/package.json index a350eeaacf..ea9d14ce9a 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react-router", - "version": "5.6.3", + "version": "5.6.4", "description": "React Router wrapper for @ionic/react", "keywords": [ "ionic", @@ -39,16 +39,16 @@ "tslib": "*" }, "peerDependencies": { - "@ionic/core": "5.6.3", - "@ionic/react": "5.6.3", + "@ionic/core": "5.6.4", + "@ionic/react": "5.6.4", "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.3", - "@ionic/react": "5.6.3", + "@ionic/core": "5.6.4", + "@ionic/react": "5.6.4", "@rollup/plugin-node-resolve": "^8.1.0", "@testing-library/jest-dom": "^5.11.6", "@testing-library/react": "^11.2.2", diff --git a/packages/react/package.json b/packages/react/package.json index 1d86ba7deb..dc57b46259 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react", - "version": "5.6.3", + "version": "5.6.4", "description": "React specific wrapper for @ionic/core", "keywords": [ "ionic", @@ -39,7 +39,7 @@ "css/" ], "dependencies": { - "@ionic/core": "5.6.3", + "@ionic/core": "5.6.4", "ionicons": "^5.1.2", "tslib": "*" }, diff --git a/packages/vue-router/package-lock.json b/packages/vue-router/package-lock.json index 75c43bb09c..af7fa8637d 100644 --- a/packages/vue-router/package-lock.json +++ b/packages/vue-router/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/vue-router", - "version": "5.6.3", + "version": "5.6.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue-router", - "version": "5.6.3", + "version": "5.6.4", "license": "MIT", "devDependencies": { "@ionic/vue": "5.4.1", @@ -23,7 +23,7 @@ }, "../../core": { "name": "@ionic/core", - "version": "5.6.2", + "version": "5.6.3", "dev": true, "license": "MIT", "dependencies": { @@ -36,7 +36,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.1", + "@stencil/vue-output-target": "^0.4.2", "@types/jest": "^26.0.20", "@types/node": "^14.6.0", "@types/puppeteer": "5.4.3", @@ -8246,7 +8246,7 @@ "@rollup/plugin-virtual": "^2.0.3", "@stencil/core": "^2.4.0", "@stencil/sass": "1.3.2", - "@stencil/vue-output-target": "^0.4.1", + "@stencil/vue-output-target": "^0.4.2", "@types/jest": "^26.0.20", "@types/node": "^14.6.0", "@types/puppeteer": "5.4.3", diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index 1cea887fc5..e139fef64c 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue-router", - "version": "5.6.3", + "version": "5.6.4", "description": "Vue Router integration for @ionic/vue", "scripts": { "test.spec": "jest", diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index b5107c41a7..3c15baf995 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue", - "version": "5.6.3", + "version": "5.6.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue", - "version": "5.6.3", + "version": "5.6.4", "license": "MIT", "dependencies": { - "@ionic/core": "5.6.2", + "@ionic/core": "5.6.3", "ionicons": "^5.1.2" }, "devDependencies": { @@ -53,13 +53,13 @@ } }, "node_modules/@ionic/core": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.2.tgz", - "integrity": "sha512-hnwd6ln0IZUVfFu2ilZK03b6EdQFqEWiTkL5kayq2gjB3BK/u1IEtV3C9fdwc8NJKopGwdbdQnujj6VhYPzV3Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.3.tgz", + "integrity": "sha512-RPugxDcCwB5rgEh6yR2QDTzblT8BRBktsW6y+VBt62yHRzgEAENEfVyvkADz+CkGAsmZuPmC8OQC2jJrx/fJFA==", "dependencies": { "@stencil/core": "^2.4.0", "ionicons": "^5.5.1", - "tslib": "^1.10.0" + "tslib": "^2.1.0" } }, "node_modules/@ionic/core/node_modules/@stencil/core": { @@ -74,6 +74,11 @@ "npm": ">=6.0.0" } }, + "node_modules/@ionic/core/node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + }, "node_modules/@stencil/core": { "version": "1.17.3", "resolved": "https://registry.npmjs.org/@stencil/core/-/core-1.17.3.tgz", @@ -536,7 +541,8 @@ "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/typescript": { "version": "4.0.5", @@ -627,19 +633,24 @@ } }, "@ionic/core": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.2.tgz", - "integrity": "sha512-hnwd6ln0IZUVfFu2ilZK03b6EdQFqEWiTkL5kayq2gjB3BK/u1IEtV3C9fdwc8NJKopGwdbdQnujj6VhYPzV3Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.6.3.tgz", + "integrity": "sha512-RPugxDcCwB5rgEh6yR2QDTzblT8BRBktsW6y+VBt62yHRzgEAENEfVyvkADz+CkGAsmZuPmC8OQC2jJrx/fJFA==", "requires": { "@stencil/core": "^2.4.0", "ionicons": "^5.5.1", - "tslib": "^1.10.0" + "tslib": "^2.1.0" }, "dependencies": { "@stencil/core": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.4.0.tgz", "integrity": "sha512-gU6+Yyd6O0KrCSS/O6j8KKqmRo+/Dcs2fI0+APCpbAWK+nqhwDISpdnSEfGDCLMoAC08XOZCycBRk2K1VGnEcg==" + }, + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" } } }, @@ -1050,7 +1061,8 @@ "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "typescript": { "version": "4.0.5", diff --git a/packages/vue/package.json b/packages/vue/package.json index 4029f036af..d4a2b8c518 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue", - "version": "5.6.3", + "version": "5.6.4", "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.3", + "@ionic/core": "5.6.4", "ionicons": "^5.1.2" }, "vetur": { From 669d24c5510896343e089be6c006f9f6827e226a Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Thu, 8 Apr 2021 14:00:07 -0400 Subject: [PATCH 07/18] tests(vue): improve reliability of e2e tests (#23168) --- packages/vue/test-app/cypress.json | 3 ++- packages/vue/test-app/tests/e2e/specs/nested.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/vue/test-app/cypress.json b/packages/vue/test-app/cypress.json index 8ef00134d0..5c73b90b28 100644 --- a/packages/vue/test-app/cypress.json +++ b/packages/vue/test-app/cypress.json @@ -2,5 +2,6 @@ "pluginsFile": "tests/e2e/plugins/index.js", "includeShadowDom": true, "video": false, - "screenshotOnRunFailure": false + "screenshotOnRunFailure": false, + "defaultCommandTimeout": 10000 } diff --git a/packages/vue/test-app/tests/e2e/specs/nested.js b/packages/vue/test-app/tests/e2e/specs/nested.js index 5e6f73cbe3..33770dedfb 100644 --- a/packages/vue/test-app/tests/e2e/specs/nested.js +++ b/packages/vue/test-app/tests/e2e/specs/nested.js @@ -1,6 +1,7 @@ describe('Nested', () => { beforeEach(() => { cy.visit('http://localhost:8080/nested'); + cy.ionPageVisible('nestedchild'); }); it('should show first page', () => { From 91ac340ae7e8928f7b0972a093dd9dd7fa727671 Mon Sep 17 00:00:00 2001 From: William Martin Date: Mon, 12 Apr 2021 09:20:59 -0400 Subject: [PATCH 08/18] fix(segment, segment-button): use correct tablist and tab roles for screen readers (#23145) * fix(segment, segment-button): change aria attributes for segment and segment-button * add axe test * Add tests, screen reader doc * add updated screen reader * fix(segment-button): move aria tags to host * verify nvda and talkback behavior * fix(segment-button): remove outline on focus * Update core/src/components/segment/test/basic/index.html Co-authored-by: Liam DeBeasi --- core/package-lock.json | 40 +++++++++++++++++++ core/package.json | 1 + .../segment-button/segment-button.scss | 4 ++ .../segment-button/segment-button.tsx | 19 ++++++++- core/src/components/segment/segment.tsx | 1 + core/src/components/segment/test/a11y/e2e.ts | 11 +++++ .../components/segment/test/a11y/index.html | 31 ++++++++++++++ .../segment/test/a11y/screen-readers.md | 24 +++++++++++ 8 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 core/src/components/segment/test/a11y/e2e.ts create mode 100644 core/src/components/segment/test/a11y/index.html create mode 100644 core/src/components/segment/test/a11y/screen-readers.md diff --git a/core/package-lock.json b/core/package-lock.json index 9f5c5a82d5..62be248676 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -14,6 +14,7 @@ "tslib": "^2.1.0" }, "devDependencies": { + "@axe-core/puppeteer": "^4.1.1", "@jest/core": "^26.6.3", "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", @@ -43,6 +44,21 @@ "typescript": "^4.0.5" } }, + "node_modules/@axe-core/puppeteer": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@axe-core/puppeteer/-/puppeteer-4.1.1.tgz", + "integrity": "sha512-Ao9N7HL//s26hdasx3Ba18tlJgxpoO+1SmIN6eSx5vC50dqYhiRU0xp6wBKWqzo10u1jpzl/s4RFsOAuolFMBA==", + "dev": true, + "dependencies": { + "axe-core": "^4.1.1" + }, + "engines": { + "node": ">=6.4.0" + }, + "peerDependencies": { + "puppeteer": ">=1.10.0 < 6" + } + }, "node_modules/@babel/code-frame": { "version": "7.10.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", @@ -2029,6 +2045,15 @@ "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, + "node_modules/axe-core": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.4.tgz", + "integrity": "sha512-Pdgfv6iP0gNx9ejRGa3zE7Xgkj/iclXqLfe7BnatdZz0QnLZ3jrRHUVH8wNSdN68w05Sk3ShGTb3ydktMTooig==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/babel-plugin-istanbul": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", @@ -13802,6 +13827,15 @@ } }, "dependencies": { + "@axe-core/puppeteer": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@axe-core/puppeteer/-/puppeteer-4.1.1.tgz", + "integrity": "sha512-Ao9N7HL//s26hdasx3Ba18tlJgxpoO+1SmIN6eSx5vC50dqYhiRU0xp6wBKWqzo10u1jpzl/s4RFsOAuolFMBA==", + "dev": true, + "requires": { + "axe-core": "^4.1.1" + } + }, "@babel/code-frame": { "version": "7.10.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", @@ -15481,6 +15515,12 @@ "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, + "axe-core": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.4.tgz", + "integrity": "sha512-Pdgfv6iP0gNx9ejRGa3zE7Xgkj/iclXqLfe7BnatdZz0QnLZ3jrRHUVH8wNSdN68w05Sk3ShGTb3ydktMTooig==", + "dev": true + }, "babel-plugin-istanbul": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", diff --git a/core/package.json b/core/package.json index 94fa265a07..61d18545f2 100644 --- a/core/package.json +++ b/core/package.json @@ -36,6 +36,7 @@ "tslib": "^2.1.0" }, "devDependencies": { + "@axe-core/puppeteer": "^4.1.1", "@jest/core": "^26.6.3", "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", diff --git a/core/src/components/segment-button/segment-button.scss b/core/src/components/segment-button/segment-button.scss index 2c6d1a1ef2..7342a9337a 100644 --- a/core/src/components/segment-button/segment-button.scss +++ b/core/src/components/segment-button/segment-button.scss @@ -166,6 +166,10 @@ } } +:host(:focus) { + outline: none; +} + // Segment Button: Hover // -------------------------------------------------- diff --git a/core/src/components/segment-button/segment-button.tsx b/core/src/components/segment-button/segment-button.tsx index a030f0c3d9..92468d0977 100644 --- a/core/src/components/segment-button/segment-button.tsx +++ b/core/src/components/segment-button/segment-button.tsx @@ -86,13 +86,28 @@ export class SegmentButton implements ComponentInterface, ButtonInterface { } } + private get tabIndex() { + if (this.disabled) { return -1; } + + const hasTabIndex = this.el.hasAttribute('tabindex'); + + if (hasTabIndex) { + return this.el.getAttribute('tabindex'); + } + + return 0; + } + render() { - const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl } = this; + const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl, tabIndex } = this; const mode = getIonMode(this); const hasSegmentColor = () => segmentEl !== null && segmentEl.color !== undefined; return (