mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(angular): ship Ionic components as Angular standalone components (#28311)
Issue number: N/A --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> **1. Bundle Size Reductions** All Ionic UI components and Ionicons are added to the final bundle of an Ionic Angular application. This is because all components and icons are lazily loaded as needed. This prevents the compiler from properly tree shaking applications. This does not cause all components and icons to be loaded on application start, but it does increase the size of the final app output that all users need to download. **Related Issues** https://github.com/ionic-team/ionicons/issues/910 https://github.com/ionic-team/ionicons/issues/536 https://github.com/ionic-team/ionic-framework/issues/27280 https://github.com/ionic-team/ionic-framework/issues/24352 **2. Standalone Component Support** Standalone Components are a stable API as of Angular 15. The Ionic starter apps on the CLI have NgModule and Standalone options, but all of the Ionic components are still lazily/dynamically loaded using `IonicModule`. Standalone components in Ionic also enable support for new Angular features such as bundling with ESBuild instead of Webpack. ESBuild does not work in Ionic Angular right now because components cannot be statically analyzed since they are dynamically imported. We added preliminary support for standalone components in Ionic v6.3.0. This enabled developers to use their own custom standalone components when routing with `ion-router-outlet`. However, we did not ship standalone components for Ionic's UI components. **Related Issues** https://github.com/ionic-team/ionic-framework/issues/25404 https://github.com/ionic-team/ionic-framework/issues/27251 https://github.com/ionic-team/ionic-framework/issues/27387 **3. Faster Component Load Times** Since Ionic Angular components are lazily loaded, they also need to be hydrated. However, this hydration does not happen immediately which prevents components from being usable for multiple frames. **Related Issues** https://github.com/ionic-team/ionic-framework/issues/24352 https://github.com/ionic-team/ionic-framework/issues/26474 ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Ionic components and directives are accessible as Angular standalone components/directives ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Associated documentation branch: https://github.com/ionic-team/ionic-docs/tree/feature-7.5 --------- Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com> Co-authored-by: Sean Perkins <sean@ionic.io> Co-authored-by: Amanda Johnston <90629384+amandaejohnston@users.noreply.github.com> Co-authored-by: Maria Hutt <maria@ionic.io> Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com>
This commit is contained in:
@@ -70,6 +70,14 @@ If you want to add a version-specific change, add the change inside of the appro
|
||||
|
||||
If you need to add E2E tests that are only run on a specific version of the JS Framework, replicate the `VersionTest` component on each partial application. This ensures that tests for framework version X do not get run for framework version Y.
|
||||
|
||||
### Testing Lazy Loaded Ionic Components
|
||||
|
||||
Tests for lazy loaded Ionic UI components should only be added under the `/lazy` route. This ensures the `IonicModule` is added.
|
||||
|
||||
### Testing Standalone Ionic Components
|
||||
|
||||
Tests for standalone Ionic UI components should only be added under the `/standalone` route. This allows for an isolated environment where the lazy loaded `IonicModule` is not initialized. The standalone components use Stencil's custom element bundle instead of the lazy loaded bundle. If `IonicModule` is initialized then the Stencil components will fall back to using the lazy loaded implementation instead of the custom elements bundle implementation.
|
||||
|
||||
## Adding New Test Apps
|
||||
|
||||
As we add support for new versions of Angular, we will also need to update this directory to test against new applications. The following steps can serve as a guide for adding new apps:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
it("should be on Angular 14", () => {
|
||||
cy.visit('/');
|
||||
cy.visit('/lazy');
|
||||
|
||||
cy.get('ion-title').contains('Angular 14');
|
||||
});
|
||||
55
packages/angular/test/apps/ng14/package-lock.json
generated
55
packages/angular/test/apps/ng14/package-lock.json
generated
@@ -22,7 +22,7 @@
|
||||
"@ionic/angular-server": "^6.1.15",
|
||||
"core-js": "^2.6.11",
|
||||
"express": "^4.15.2",
|
||||
"ionicons": "^6.0.4",
|
||||
"ionicons": "^7.2.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"typescript-eslint-language-service": "^4.1.5",
|
||||
@@ -2937,6 +2937,14 @@
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/ionicons": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz",
|
||||
"integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
@@ -9955,11 +9963,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ionicons": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.4.tgz",
|
||||
"integrity": "sha512-uDNOkBo0OVYV+kIhb51g9mb7r3Z0b+78GPZQBsjXuaetNmrB/mNTqN/uFtO+vxL/rQySKjzk8qeKJI5NWL9Ueg==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.0.tgz",
|
||||
"integrity": "sha512-gmG6A50iem/wR10K+rJeiYlBu8SjG1lxZ6brPYEI2WYjEw8s6T+bj///C6yjRIDtj+qIgqrQmQAgNvNdgyG7ng==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
"@stencil/core": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/ionicons/node_modules/@stencil/core": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ip": {
|
||||
@@ -18576,6 +18596,16 @@
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ionicons": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz",
|
||||
"integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
@@ -23759,11 +23789,18 @@
|
||||
"dev": true
|
||||
},
|
||||
"ionicons": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.4.tgz",
|
||||
"integrity": "sha512-uDNOkBo0OVYV+kIhb51g9mb7r3Z0b+78GPZQBsjXuaetNmrB/mNTqN/uFtO+vxL/rQySKjzk8qeKJI5NWL9Ueg==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.0.tgz",
|
||||
"integrity": "sha512-gmG6A50iem/wR10K+rJeiYlBu8SjG1lxZ6brPYEI2WYjEw8s6T+bj///C6yjRIDtj+qIgqrQmQAgNvNdgyG7ng==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
"@stencil/core": "^4.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ip": {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"@ionic/angular-server": "^6.1.15",
|
||||
"core-js": "^2.6.11",
|
||||
"express": "^4.15.2",
|
||||
"ionicons": "^6.0.4",
|
||||
"ionicons": "^7.2.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"typescript-eslint-language-service": "^4.1.5",
|
||||
|
||||
23
packages/angular/test/apps/ng14/src/main-standalone.ts
Normal file
23
packages/angular/test/apps/ng14/src/main-standalone.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { importProvidersFrom } from '@angular/core';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { RouteReuseStrategy } from '@angular/router';
|
||||
import { provideIonicAngular, IonicRouteStrategy } from '@ionic/angular/standalone';
|
||||
|
||||
import { AppComponentStandalone } from './app/app-standalone.component';
|
||||
import { AppRoutingModule } from './app/app-routing.module';
|
||||
|
||||
import { routes } from './app/app.routes';
|
||||
|
||||
export const bootstrapStandalone = () => {
|
||||
bootstrapApplication(AppComponentStandalone, {
|
||||
providers: [
|
||||
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
|
||||
/**
|
||||
* provideRouter is not available in Angular 14, so
|
||||
* we fallback to using AppRoutingModule
|
||||
*/
|
||||
importProvidersFrom(AppRoutingModule),
|
||||
provideIonicAngular({ keyboardHeight: 12345 })
|
||||
],
|
||||
});
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
it("should be on Angular 15", () => {
|
||||
cy.visit('/');
|
||||
cy.visit('/lazy');
|
||||
|
||||
cy.get('ion-title').contains('Angular 15');
|
||||
});
|
||||
55
packages/angular/test/apps/ng15/package-lock.json
generated
55
packages/angular/test/apps/ng15/package-lock.json
generated
@@ -23,7 +23,7 @@
|
||||
"@nguniversal/express-engine": "^15.0.0",
|
||||
"core-js": "^2.6.11",
|
||||
"express": "^4.15.2",
|
||||
"ionicons": "^6.0.4",
|
||||
"ionicons": "^7.2.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"typescript-eslint-language-service": "^4.1.5",
|
||||
@@ -2662,6 +2662,14 @@
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/ionicons": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz",
|
||||
"integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
@@ -9538,11 +9546,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ionicons": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.4.tgz",
|
||||
"integrity": "sha512-uDNOkBo0OVYV+kIhb51g9mb7r3Z0b+78GPZQBsjXuaetNmrB/mNTqN/uFtO+vxL/rQySKjzk8qeKJI5NWL9Ueg==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.0.tgz",
|
||||
"integrity": "sha512-gmG6A50iem/wR10K+rJeiYlBu8SjG1lxZ6brPYEI2WYjEw8s6T+bj///C6yjRIDtj+qIgqrQmQAgNvNdgyG7ng==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
"@stencil/core": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/ionicons/node_modules/@stencil/core": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ip": {
|
||||
@@ -17555,6 +17575,16 @@
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ionicons": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz",
|
||||
"integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
@@ -22624,11 +22654,18 @@
|
||||
"dev": true
|
||||
},
|
||||
"ionicons": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.4.tgz",
|
||||
"integrity": "sha512-uDNOkBo0OVYV+kIhb51g9mb7r3Z0b+78GPZQBsjXuaetNmrB/mNTqN/uFtO+vxL/rQySKjzk8qeKJI5NWL9Ueg==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.0.tgz",
|
||||
"integrity": "sha512-gmG6A50iem/wR10K+rJeiYlBu8SjG1lxZ6brPYEI2WYjEw8s6T+bj///C6yjRIDtj+qIgqrQmQAgNvNdgyG7ng==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
"@stencil/core": "^4.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ip": {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"@nguniversal/express-engine": "^15.0.0",
|
||||
"core-js": "^2.6.11",
|
||||
"express": "^4.15.2",
|
||||
"ionicons": "^6.0.4",
|
||||
"ionicons": "^7.2.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"typescript-eslint-language-service": "^4.1.5",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
it("should be on Angular 16", () => {
|
||||
cy.visit('/');
|
||||
cy.visit('/lazy');
|
||||
|
||||
cy.get('ion-title').contains('Angular 16');
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
it("binding route data to inputs should work", () => {
|
||||
cy.visit('/version-test/bind-route/test?query=test');
|
||||
cy.visit('/lazy/version-test/bind-route/test?query=test');
|
||||
|
||||
cy.get('#route-params').contains('test');
|
||||
cy.get('#query-params').contains('test');
|
||||
@@ -1,7 +1,7 @@
|
||||
describe('Modal Nav Params', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/version-test/modal-nav-params');
|
||||
cy.visit('/lazy/version-test/modal-nav-params');
|
||||
});
|
||||
|
||||
it('should assign the rootParams when presented in a modal multiple times', () => {
|
||||
34
packages/angular/test/apps/ng16/package-lock.json
generated
34
packages/angular/test/apps/ng16/package-lock.json
generated
@@ -22,7 +22,7 @@
|
||||
"@nguniversal/express-engine": "^16.0.0",
|
||||
"core-js": "^2.6.11",
|
||||
"express": "^4.15.2",
|
||||
"ionicons": "^7.0.4",
|
||||
"ionicons": "^7.2.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"typescript-eslint-language-service": "^4.1.5",
|
||||
@@ -3986,15 +3986,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "2.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.19.2.tgz",
|
||||
"integrity": "sha512-TK3sHqyQAACwcac4fWntypFtN9c/y+y9ioZojeCnNDY3dxF33Ax70lL9ZLDyQnWWR+aTh1WFoqB5sYOnZIUKMA==",
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
@@ -10126,11 +10126,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ionicons": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.1.0.tgz",
|
||||
"integrity": "sha512-iE4GuEdEHARJpp0sWL7WJZCzNCf5VxpNRhAjW0fLnZPnNL5qZOJUcfup2Z2Ty7Jk8Q5hacrHfGEB1lCwOdXqGg==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.0.tgz",
|
||||
"integrity": "sha512-gmG6A50iem/wR10K+rJeiYlBu8SjG1lxZ6brPYEI2WYjEw8s6T+bj///C6yjRIDtj+qIgqrQmQAgNvNdgyG7ng==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
"@stencil/core": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/ip": {
|
||||
@@ -19664,9 +19664,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "2.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.19.2.tgz",
|
||||
"integrity": "sha512-TK3sHqyQAACwcac4fWntypFtN9c/y+y9ioZojeCnNDY3dxF33Ax70lL9ZLDyQnWWR+aTh1WFoqB5sYOnZIUKMA=="
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA=="
|
||||
},
|
||||
"@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
@@ -24282,11 +24282,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"ionicons": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.1.0.tgz",
|
||||
"integrity": "sha512-iE4GuEdEHARJpp0sWL7WJZCzNCf5VxpNRhAjW0fLnZPnNL5qZOJUcfup2Z2Ty7Jk8Q5hacrHfGEB1lCwOdXqGg==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.0.tgz",
|
||||
"integrity": "sha512-gmG6A50iem/wR10K+rJeiYlBu8SjG1lxZ6brPYEI2WYjEw8s6T+bj///C6yjRIDtj+qIgqrQmQAgNvNdgyG7ng==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.18.0"
|
||||
"@stencil/core": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"ip": {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"@nguniversal/express-engine": "^16.0.0",
|
||||
"core-js": "^2.6.11",
|
||||
"express": "^4.15.2",
|
||||
"ionicons": "^7.0.4",
|
||||
"ionicons": "^7.2.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"typescript-eslint-language-service": "^4.1.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Accordion', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/accordions');
|
||||
cy.visit('/lazy/accordions');
|
||||
});
|
||||
|
||||
it('should correctly expand on multiple modal opens', () => {
|
||||
@@ -1,7 +1,7 @@
|
||||
describe('Form Controls: Range', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/form-controls/range');
|
||||
cy.visit('/lazy/form-controls/range');
|
||||
});
|
||||
|
||||
it('should have form control initial value', () => {
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Form', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/form');
|
||||
cy.visit('/lazy/form');
|
||||
})
|
||||
|
||||
describe('status updates', () => {
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Overlays: Inline', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/overlays-inline');
|
||||
cy.visit('/lazy/overlays-inline');
|
||||
});
|
||||
|
||||
describe('Alert', () => {
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Inputs', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/inputs');
|
||||
cy.visit('/lazy/inputs');
|
||||
})
|
||||
|
||||
it('should have default value', () => {
|
||||
@@ -1,19 +1,19 @@
|
||||
describe('overlays - keepContentsMounted', () => {
|
||||
describe('modal', () => {
|
||||
it('should not mount component if false', () => {
|
||||
cy.visit('/modal-inline');
|
||||
cy.visit('/lazy/modal-inline');
|
||||
|
||||
cy.get('ion-modal ion-content').should('not.exist');
|
||||
});
|
||||
|
||||
it('should mount component if true', () => {
|
||||
cy.visit('/keep-contents-mounted');
|
||||
cy.visit('/lazy/keep-contents-mounted');
|
||||
|
||||
cy.get('ion-modal ion-content').should('exist');
|
||||
});
|
||||
|
||||
it('should keep component mounted after dismissing if true', () => {
|
||||
cy.visit('/keep-contents-mounted');
|
||||
cy.visit('/lazy/keep-contents-mounted');
|
||||
|
||||
cy.get('#open-modal').click();
|
||||
|
||||
@@ -29,26 +29,26 @@ describe('overlays - keepContentsMounted', () => {
|
||||
});
|
||||
|
||||
it('should has ion-delegate-host on mount', () => {
|
||||
cy.visit('/keep-contents-mounted');
|
||||
cy.visit('/lazy/keep-contents-mounted');
|
||||
|
||||
cy.get('ion-modal .ion-delegate-host').should('exist');
|
||||
});
|
||||
})
|
||||
describe('popover', () => {
|
||||
it('should not mount component if false', () => {
|
||||
cy.visit('/popover-inline');
|
||||
cy.visit('/lazy/popover-inline');
|
||||
|
||||
cy.get('ion-popover ion-content').should('not.exist');
|
||||
});
|
||||
|
||||
it('should mount component if true', () => {
|
||||
cy.visit('/keep-contents-mounted');
|
||||
cy.visit('/lazy/keep-contents-mounted');
|
||||
|
||||
cy.get('ion-popover ion-content').should('exist');
|
||||
});
|
||||
|
||||
it('should keep component mounted after dismissing if true', () => {
|
||||
cy.visit('/keep-contents-mounted');
|
||||
cy.visit('/lazy/keep-contents-mounted');
|
||||
|
||||
cy.get('#open-popover').click();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Modals', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/modals');
|
||||
cy.visit('/lazy/modals');
|
||||
})
|
||||
|
||||
it('should open standalone modal and close', () => {
|
||||
@@ -45,7 +45,7 @@ describe('Modals', () => {
|
||||
|
||||
describe('Modals: Inline', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/modal-inline');
|
||||
cy.visit('/lazy/modal-inline');
|
||||
});
|
||||
|
||||
it('should initially have no items', () => {
|
||||
@@ -95,7 +95,7 @@ describe('Modals: Inline', () => {
|
||||
describe('when in a modal', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/modals');
|
||||
cy.visit('/lazy/modals');
|
||||
cy.get('#action-button').click();
|
||||
cy.get('#close-modal').click();
|
||||
cy.get('#action-button').click();
|
||||
@@ -1,10 +1,10 @@
|
||||
describe('Navigation', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/navigation');
|
||||
cy.visit('/lazy/navigation');
|
||||
})
|
||||
|
||||
it('should navigate correctly', () => {
|
||||
cy.visit('/navigation/page1');
|
||||
cy.visit('/lazy/navigation/page1');
|
||||
cy.wait(2000);
|
||||
cy.testStack('ion-router-outlet', ['app-navigation-page2', 'app-navigation-page1']);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Nested Outlet', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/nested-outlet/page');
|
||||
cy.visit('/lazy/nested-outlet/page');
|
||||
})
|
||||
|
||||
it('should navigate correctly', () => {
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Popovers: Inline', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/popover-inline');
|
||||
cy.visit('/lazy/popover-inline');
|
||||
});
|
||||
|
||||
it('should initially have no items', () => {
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Providers', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/providers');
|
||||
cy.visit('/lazy/providers');
|
||||
})
|
||||
|
||||
it('should load all providers', () => {
|
||||
@@ -17,13 +17,13 @@ describe('Providers', () => {
|
||||
});
|
||||
|
||||
it('should detect testing mode', () => {
|
||||
cy.visit('/providers?ionic:_testing=true');
|
||||
cy.visit('/lazy/providers?ionic:_testing=true');
|
||||
|
||||
cy.get('#is-testing').should('have.text', 'true');
|
||||
});
|
||||
|
||||
it('should get query params', () => {
|
||||
cy.visit('/providers?firstParam=abc&secondParam=true');
|
||||
cy.visit('/lazy/providers?firstParam=abc&secondParam=true');
|
||||
|
||||
cy.get('#query-params').should('have.text', 'firstParam: abc, firstParam: true');
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Router Link', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/router-link');
|
||||
cy.visit('/lazy/router-link');
|
||||
});
|
||||
|
||||
describe('router-link params and fragments', () => {
|
||||
@@ -9,7 +9,7 @@ describe('Router Link', () => {
|
||||
const id = 'MyPageID==';
|
||||
|
||||
it('should go to a page with properly encoded values', () => {
|
||||
cy.visit('/router-link?ionic:_testing=true');
|
||||
cy.visit('/lazy/router-link?ionic:_testing=true');
|
||||
cy.get('#queryParamsFragment').click();
|
||||
|
||||
const expectedPath = `${encodeURIComponent(id)}`;
|
||||
@@ -24,7 +24,7 @@ describe('Router Link', () => {
|
||||
});
|
||||
|
||||
it('should return to a page with preserved query param and fragment', () => {
|
||||
cy.visit('/router-link?ionic:_testing=true');
|
||||
cy.visit('/lazy/router-link?ionic:_testing=true');
|
||||
cy.get('#queryParamsFragment').click();
|
||||
cy.get('#goToPage3').click();
|
||||
|
||||
@@ -46,7 +46,7 @@ describe('Router Link', () => {
|
||||
});
|
||||
|
||||
it('should preserve query param and fragment with defaultHref string', () => {
|
||||
cy.visit('/router-link-page3?ionic:_testing=true');
|
||||
cy.visit('/lazy/router-link-page3?ionic:_testing=true');
|
||||
|
||||
cy.get('#goBackFromPage3').click();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Routing', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/router-link?ionic:mode=ios');
|
||||
cy.visit('/lazy/router-link?ionic:mode=ios');
|
||||
})
|
||||
|
||||
it('should swipe and abort', () => {
|
||||
@@ -1,5 +1,5 @@
|
||||
describe('Searchbar', () => {
|
||||
beforeEach(() => cy.visit('/searchbar'));
|
||||
beforeEach(() => cy.visit('/lazy/searchbar'));
|
||||
|
||||
it('should become valid', () => {
|
||||
cy.get('#status').should('have.text', 'INVALID');
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Routing with Standalone Components', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone');
|
||||
cy.visit('/lazy/standalone');
|
||||
});
|
||||
|
||||
it('should render the component', () => {
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('Tabs', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/tabs');
|
||||
cy.visit('/lazy/tabs');
|
||||
})
|
||||
|
||||
describe('entry url - /tabs', () => {
|
||||
@@ -214,7 +214,7 @@ describe('Tabs', () => {
|
||||
describe('entry tab contains navigation extras', () => {
|
||||
const expectNestedTabUrlToContain = 'search=hello#fragment';
|
||||
const rootUrlParams = 'test=123#rootFragment';
|
||||
const rootUrl = `/tabs/account?${rootUrlParams}`;
|
||||
const rootUrl = `/lazy/tabs/account?${rootUrlParams}`;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit(rootUrl);
|
||||
@@ -288,7 +288,7 @@ describe('Tabs', () => {
|
||||
|
||||
describe('entry url - /tabs/account', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/tabs/account');
|
||||
cy.visit('/lazy/tabs/account');
|
||||
});
|
||||
it('should pop to previous view when leaving tabs outlet', () => {
|
||||
|
||||
@@ -322,7 +322,7 @@ describe('Tabs', () => {
|
||||
|
||||
describe('entry url - /', () => {
|
||||
it('should pop to the root outlet from the tabs outlet', () => {
|
||||
cy.visit('/');
|
||||
cy.visit('/lazy/');
|
||||
|
||||
cy.get('ion-title').should('contain.text', 'Test App');
|
||||
|
||||
@@ -356,7 +356,7 @@ describe('Tabs', () => {
|
||||
|
||||
describe('entry url - /tabs/account/nested/1', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/tabs/account/nested/1');
|
||||
cy.visit('/lazy/tabs/account/nested/1');
|
||||
})
|
||||
|
||||
it('should only display the back-button when there is a page in the stack', () => {
|
||||
@@ -401,7 +401,7 @@ describe('Tabs', () => {
|
||||
|
||||
describe('entry url - /tabs/lazy', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/tabs/lazy');
|
||||
cy.visit('/lazy/tabs/lazy');
|
||||
});
|
||||
|
||||
it('should not display the back-button if coming from a different stack', () => {
|
||||
@@ -419,7 +419,7 @@ describe('Tabs', () => {
|
||||
|
||||
describe('enter url - /tabs/contact/one', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/tabs/contact/one');
|
||||
cy.visit('/lazy/tabs/contact/one');
|
||||
});
|
||||
|
||||
it('should return to correct tab after going to page in different outlet', () => {
|
||||
@@ -436,7 +436,7 @@ describe('Tabs', () => {
|
||||
})
|
||||
|
||||
it('Tabs should support conditional slots', () => {
|
||||
cy.visit('/tabs-slots');
|
||||
cy.visit('/lazy/tabs-slots');
|
||||
|
||||
cy.get('ion-tabs .tabs-inner + ion-tab-bar').should('have.length', 1);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
describe('Textarea', () => {
|
||||
beforeEach(() => cy.visit('/textarea'));
|
||||
beforeEach(() => cy.visit('/lazy/textarea'));
|
||||
|
||||
it('should become valid', () => {
|
||||
cy.get('#status').should('have.text', 'INVALID');
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('View Child', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/view-child');
|
||||
cy.visit('/lazy/view-child');
|
||||
})
|
||||
|
||||
it('should get a reference to all children', () => {
|
||||
@@ -0,0 +1,14 @@
|
||||
describe('Back Button', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/back-button');
|
||||
})
|
||||
|
||||
it('should be visible and navigate back to page', () => {
|
||||
cy.ionPageVisible('app-back-button');
|
||||
|
||||
cy.get('ion-back-button').click();
|
||||
|
||||
cy.ionPageDoesNotExist('app-back-button');
|
||||
cy.ionPageVisible('app-router-outlet');
|
||||
});
|
||||
})
|
||||
20
packages/angular/test/base/e2e/src/standalone/icon.spec.ts
Normal file
20
packages/angular/test/base/e2e/src/standalone/icon.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
describe('Icons', () => {
|
||||
it('should render an icon', () => {
|
||||
cy.visit('/standalone/icon');
|
||||
|
||||
cy.get('ion-icon#icon-string').shadow().find('svg').should('exist');
|
||||
cy.get('ion-icon#icon-binding').shadow().find('svg').should('exist');
|
||||
});
|
||||
|
||||
it('should render an icon on iOS mode', () => {
|
||||
cy.visit('/standalone/icon?ionic:mode=ios');
|
||||
|
||||
cy.get('ion-icon#icon-mode').shadow().find('svg').should('exist');
|
||||
});
|
||||
|
||||
it('should render an icon on MD mode', () => {
|
||||
cy.visit('/standalone/icon?ionic:mode=md');
|
||||
|
||||
cy.get('ion-icon#icon-mode').shadow().find('svg').should('exist');
|
||||
});
|
||||
});
|
||||
12
packages/angular/test/base/e2e/src/standalone/modal.spec.ts
Normal file
12
packages/angular/test/base/e2e/src/standalone/modal.spec.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
describe('Modals: Inline', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/modal');
|
||||
});
|
||||
|
||||
it('should render modal', () => {
|
||||
cy.get('button#open-modal').click();
|
||||
|
||||
cy.get('ion-modal').should('be.visible');
|
||||
cy.get('ion-modal #modal-content').should('exist');
|
||||
});
|
||||
});
|
||||
11
packages/angular/test/base/e2e/src/standalone/nav.spec.ts
Normal file
11
packages/angular/test/base/e2e/src/standalone/nav.spec.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
describe('Nav', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/nav');
|
||||
})
|
||||
|
||||
it('should mount the root component', () => {
|
||||
cy.ionPageVisible('app-nav');
|
||||
|
||||
cy.contains('Page One');
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,17 @@
|
||||
describe('Overlay Controllers', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/overlay-controllers');
|
||||
})
|
||||
|
||||
it('should present a modal', () => {
|
||||
cy.get('button#open-modal').click();
|
||||
|
||||
cy.get('ion-modal app-dialog-content').should('be.visible');
|
||||
});
|
||||
|
||||
it('should present a popover', () => {
|
||||
cy.get('button#open-popover').click();
|
||||
|
||||
cy.get('ion-popover app-dialog-content').should('be.visible');
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,12 @@
|
||||
describe('Popovers: Inline', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/popover');
|
||||
});
|
||||
|
||||
it('should render popover', () => {
|
||||
cy.get('button#open-popover').click();
|
||||
|
||||
cy.get('ion-popover').should('be.visible');
|
||||
cy.get('ion-popover #popover-content').should('exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
describe('Providers', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/providers');
|
||||
})
|
||||
|
||||
it('provideIonicAngular should initialize Ionic and set config correctly', () => {
|
||||
cy.ionPageVisible('app-providers');
|
||||
|
||||
cy.get('#keyboard-height').should('have.text', '12345');
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
describe('RouterLink', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/router-link');
|
||||
});
|
||||
|
||||
it('should mount the root component', () => {
|
||||
cy.ionPageVisible('app-router-link');
|
||||
|
||||
cy.contains('I\'m a link');
|
||||
});
|
||||
|
||||
it('should go to /standalone/popover using an anchor', () => {
|
||||
// click on the anchor
|
||||
cy.get('a').contains('I\'m a link').click();
|
||||
|
||||
cy.url().should('include', '/standalone/popover');
|
||||
});
|
||||
|
||||
it('should go to /standalone/popover using a button', () => {
|
||||
cy.get('button').contains('I\'m a button').click();
|
||||
|
||||
cy.url().should('include', '/standalone/popover');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
describe('Router Outlet', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/router-outlet');
|
||||
})
|
||||
|
||||
it('should render a as a child page of the router outlet', () => {
|
||||
cy.ionPageVisible('ion-router-outlet app-router-outlet');
|
||||
});
|
||||
})
|
||||
16
packages/angular/test/base/e2e/src/standalone/tabs.spec.ts
Normal file
16
packages/angular/test/base/e2e/src/standalone/tabs.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
describe('Tabs', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/standalone/tabs');
|
||||
});
|
||||
|
||||
it('should redirect to the default tab', () => {
|
||||
cy.get('app-tab-one').should('be.visible');
|
||||
cy.contains('Tab 1');
|
||||
});
|
||||
|
||||
it('should render new content when switching tabs', () => {
|
||||
cy.get('#tab-button-tab-two').click();
|
||||
cy.get('app-tab-two').should('be.visible');
|
||||
cy.contains('Tab 2');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,132 @@
|
||||
|
||||
describe('Value Accessors', () => {
|
||||
|
||||
describe('Checkbox', () => {
|
||||
beforeEach(() => cy.visit('/standalone/value-accessors/checkbox'));
|
||||
|
||||
it('should update the form value', () => {
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ checkbox: false }, null, 2));
|
||||
cy.get('ion-checkbox').should('have.class', 'ion-pristine');
|
||||
|
||||
cy.get('ion-checkbox').click();
|
||||
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ checkbox: true }, null, 2));
|
||||
cy.get('ion-checkbox').should('have.class', 'ion-dirty');
|
||||
cy.get('ion-checkbox').should('have.class', 'ion-valid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Input', () => {
|
||||
beforeEach(() => cy.visit('/standalone/value-accessors/input'));
|
||||
|
||||
it('should update the form value', () => {
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({
|
||||
inputString: '',
|
||||
inputNumber: ''
|
||||
}, null, 2));
|
||||
cy.get('ion-input[formControlName="inputString"]').should('have.class', 'ion-pristine');
|
||||
cy.get('ion-input[formControlName="inputNumber"]').should('have.class', 'ion-pristine');
|
||||
|
||||
cy.get('ion-input[formControlName="inputString"]').should('have.class', 'ion-invalid');
|
||||
cy.get('ion-input[formControlName="inputNumber"]').should('have.class', 'ion-invalid');
|
||||
|
||||
cy.get('ion-input[formControlName="inputString"] input').type('test');
|
||||
cy.get('ion-input[formControlName="inputString"] input').blur();
|
||||
|
||||
cy.get('ion-input[formControlName="inputNumber"] input').type(1);
|
||||
cy.get('ion-input[formControlName="inputNumber"] input').blur();
|
||||
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({
|
||||
inputString: 'test',
|
||||
inputNumber: 1
|
||||
}, null, 2));
|
||||
|
||||
cy.get('ion-input[formControlName="inputString"]').should('have.class', 'ion-dirty');
|
||||
cy.get('ion-input[formControlName="inputNumber"]').should('have.class', 'ion-dirty');
|
||||
|
||||
cy.get('ion-input[formControlName="inputString"]').should('have.class', 'ion-valid');
|
||||
cy.get('ion-input[formControlName="inputNumber"]').should('have.class', 'ion-valid');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Radio Group', () => {
|
||||
beforeEach(() => cy.visit('/standalone/value-accessors/radio-group'));
|
||||
|
||||
it('should update the form value', () => {
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ radioGroup: '1' }, null, 2));
|
||||
cy.get('ion-radio-group').should('have.class', 'ion-pristine');
|
||||
|
||||
cy.get('ion-radio').contains('Two').click();
|
||||
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ radioGroup: '2' }, null, 2));
|
||||
cy.get('ion-radio-group').should('have.class', 'ion-dirty');
|
||||
cy.get('ion-radio-group').should('have.class', 'ion-valid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Searchbar', () => {
|
||||
beforeEach(() => cy.visit('/standalone/value-accessors/searchbar'));
|
||||
|
||||
it('should update the form value', () => {
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ searchbar: '' }, null, 2));
|
||||
cy.get('ion-searchbar').should('have.class', 'ion-pristine');
|
||||
cy.get('ion-searchbar').should('have.class', 'ion-invalid');
|
||||
|
||||
cy.get('ion-searchbar').type('test');
|
||||
cy.get('ion-searchbar input').blur();
|
||||
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ searchbar: 'test' }, null, 2));
|
||||
cy.get('ion-searchbar').should('have.class', 'ion-dirty');
|
||||
cy.get('ion-searchbar').should('have.class', 'ion-valid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Segment', () => {
|
||||
beforeEach(() => cy.visit('/standalone/value-accessors/segment'));
|
||||
|
||||
it('should update the form value', () => {
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ segment: 'Paid' }, null, 2));
|
||||
cy.get('ion-segment').should('have.class', 'ion-pristine');
|
||||
|
||||
cy.get('ion-segment-button').eq(1).click();
|
||||
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ segment: 'Free' }, null, 2));
|
||||
cy.get('ion-segment').should('have.class', 'ion-dirty');
|
||||
cy.get('ion-segment').should('have.class', 'ion-valid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Textarea', () => {
|
||||
beforeEach(() => cy.visit('/standalone/value-accessors/textarea'));
|
||||
|
||||
it('should update the form value', () => {
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ textarea: '' }, null, 2));
|
||||
cy.get('ion-textarea').should('have.class', 'ion-pristine');
|
||||
cy.get('ion-textarea').should('have.class', 'ion-invalid');
|
||||
|
||||
cy.get('ion-textarea').click();
|
||||
cy.get('ion-textarea').type('test');
|
||||
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ textarea: 'test' }, null, 2));
|
||||
cy.get('ion-textarea').should('have.class', 'ion-dirty');
|
||||
cy.get('ion-textarea').should('have.class', 'ion-valid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Toggle', () => {
|
||||
beforeEach(() => cy.visit('/standalone/value-accessors/toggle'));
|
||||
|
||||
it('should update the form value', () => {
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ toggle: false }, null, 2));
|
||||
cy.get('ion-toggle').should('have.class', 'ion-pristine');
|
||||
|
||||
cy.get('ion-toggle').click();
|
||||
|
||||
cy.get('#formValue').should('have.text', JSON.stringify({ toggle: true }, null, 2));
|
||||
cy.get('ion-toggle').should('have.class', 'ion-dirty');
|
||||
cy.get('ion-toggle').should('have.class', 'ion-valid');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
standalone: true,
|
||||
imports: [RouterModule]
|
||||
})
|
||||
export class AppComponentStandalone {
|
||||
}
|
||||
@@ -1,3 +1 @@
|
||||
<ion-app>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
</ion-app>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@@ -2,8 +2,7 @@ import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
templateUrl: './app.component.html'
|
||||
})
|
||||
export class AppComponent {
|
||||
}
|
||||
|
||||
@@ -1,66 +1,27 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouteReuseStrategy } from '@angular/router';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { InputsComponent } from './inputs/inputs.component';
|
||||
import { ModalComponent } from './modal/modal.component';
|
||||
import { ModalExampleComponent } from './modal-example/modal-example.component';
|
||||
import { RouterLinkComponent } from './router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from './router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from './nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from './nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { NavComponent } from './nav/nav.component';
|
||||
import { ViewChildComponent } from './view-child/view-child.component';
|
||||
import { ProvidersComponent } from './providers/providers.component';
|
||||
import { FormComponent } from './form/form.component';
|
||||
import { NavigationPage1Component } from './navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from './navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from './navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from './alert/alert.component';
|
||||
import { AccordionComponent } from './accordion/accordion.component';
|
||||
import { AccordionModalComponent } from './accordion/accordion-modal/accordion-modal.component';
|
||||
|
||||
const isLazy = window.location.href.includes('lazy');
|
||||
|
||||
const imports = [
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
AppRoutingModule,
|
||||
];
|
||||
|
||||
if (isLazy) {
|
||||
imports.push(IonicModule.forRoot({ keyboardHeight: 12345 }));
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
InputsComponent,
|
||||
ModalComponent,
|
||||
ModalExampleComponent,
|
||||
RouterLinkComponent,
|
||||
RouterLinkPageComponent,
|
||||
RouterLinkPage2Component,
|
||||
RouterLinkPage3Component,
|
||||
HomePageComponent,
|
||||
NestedOutletComponent,
|
||||
NestedOutletPageComponent,
|
||||
NestedOutletPage2Component,
|
||||
NavComponent,
|
||||
ViewChildComponent,
|
||||
ProvidersComponent,
|
||||
FormComponent,
|
||||
NavigationPage1Component,
|
||||
NavigationPage2Component,
|
||||
NavigationPage3Component,
|
||||
AlertComponent,
|
||||
AccordionComponent,
|
||||
AccordionModalComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
AppRoutingModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
IonicModule.forRoot({ keyboardHeight: 12345 }),
|
||||
],
|
||||
imports,
|
||||
providers: [
|
||||
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
|
||||
],
|
||||
|
||||
@@ -1,82 +1,16 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { InputsComponent } from './inputs/inputs.component';
|
||||
import { ModalComponent } from './modal/modal.component';
|
||||
import { RouterLinkComponent } from './router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from './router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from './nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from './nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { ViewChildComponent } from './view-child/view-child.component';
|
||||
import { ProvidersComponent } from './providers/providers.component';
|
||||
import { FormComponent } from './form/form.component';
|
||||
import { NavigationPage1Component } from './navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from './navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from './navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from './alert/alert.component';
|
||||
import { AccordionComponent } from './accordion/accordion.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '', component: HomePageComponent },
|
||||
{ path: 'version-test', loadChildren: () => import('./version-test').then(m => m.VersionTestModule) },
|
||||
{ path: 'accordions', component: AccordionComponent },
|
||||
{ path: 'alerts', component: AlertComponent },
|
||||
{ path: 'inputs', component: InputsComponent },
|
||||
{ path: 'textarea', loadChildren: () => import('./textarea/textarea.module').then(m => m.TextareaModule) },
|
||||
{ path: 'searchbar', loadChildren: () => import('./searchbar/searchbar.module').then(m => m.SearchbarModule) },
|
||||
{ path: 'form', component: FormComponent },
|
||||
{ path: 'modals', component: ModalComponent },
|
||||
{ path: 'modal-inline', loadChildren: () => import('./modal-inline').then(m => m.ModalInlineModule) },
|
||||
{ path: 'view-child', component: ViewChildComponent },
|
||||
{ path: 'keep-contents-mounted', loadChildren: () => import('./keep-contents-mounted').then(m => m.OverlayAutoMountModule) },
|
||||
{ path: 'overlays-inline', loadChildren: () => import('./overlays-inline').then(m => m.OverlaysInlineModule) },
|
||||
{ path: 'popover-inline', loadChildren: () => import('./popover-inline').then(m => m.PopoverInlineModule) },
|
||||
{ path: 'providers', component: ProvidersComponent },
|
||||
{ path: 'router-link', component: RouterLinkComponent },
|
||||
{ path: 'router-link-page', component: RouterLinkPageComponent },
|
||||
{ path: 'router-link-page2/:id', component: RouterLinkPage2Component },
|
||||
{ path: 'router-link-page3', component: RouterLinkPage3Component },
|
||||
{ path: 'standalone', loadComponent: () => import('./standalone/standalone.component').then(c => c.StandaloneComponent) },
|
||||
{ path: 'tabs', redirectTo: '/tabs/account', pathMatch: 'full' },
|
||||
{
|
||||
path: 'navigation',
|
||||
children: [
|
||||
{ path: 'page1', component: NavigationPage1Component },
|
||||
{ path: 'page2', component: NavigationPage2Component },
|
||||
{ path: 'page3', component: NavigationPage3Component }
|
||||
]
|
||||
path: '',
|
||||
pathMatch: 'full',
|
||||
/**
|
||||
* Omit the slash at the beginning
|
||||
* so query params are preserved.
|
||||
* https://github.com/angular/angular/issues/13315#issuecomment-427254639
|
||||
*/
|
||||
redirectTo: 'lazy'
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-global',
|
||||
loadChildren: () => import('./tabs-global/tabs-global.module').then(m => m.TabsGlobalModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-slots',
|
||||
loadComponent: () => import('./tabs-slots.component').then(c => c.TabsSlotsComponent)
|
||||
},
|
||||
{
|
||||
path: 'nested-outlet',
|
||||
component: NestedOutletComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'page',
|
||||
component: NestedOutletPageComponent
|
||||
},
|
||||
{
|
||||
path: 'page2',
|
||||
component: NestedOutletPage2Component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'form-controls/range',
|
||||
loadChildren: () => import('./form-controls/range/range.module').then(m => m.RangeModule)
|
||||
}
|
||||
{ path: 'lazy', loadChildren: () => import('./lazy/app-lazy/app.module').then(m => m.AppModule) },
|
||||
{ path: 'standalone', loadChildren: () => import('./standalone/app-standalone/app.routes').then(m => m.routes) }
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
@@ -0,0 +1,3 @@
|
||||
<ion-app>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
</ion-app>
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html'
|
||||
})
|
||||
export class AppComponent {
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { InputsComponent } from '../inputs/inputs.component';
|
||||
import { ModalComponent } from '../modal/modal.component';
|
||||
import { ModalExampleComponent } from '../modal-example/modal-example.component';
|
||||
import { RouterLinkComponent } from '../router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from '../router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from '../router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from '../router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from '../home-page/home-page.component';
|
||||
import { NestedOutletComponent } from '../nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from '../nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from '../nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { NavComponent } from '../nav/nav.component';
|
||||
import { ViewChildComponent } from '../view-child/view-child.component';
|
||||
import { ProvidersComponent } from '../providers/providers.component';
|
||||
import { FormComponent } from '../form/form.component';
|
||||
import { NavigationPage1Component } from '../navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from '../navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from '../navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from '../alert/alert.component';
|
||||
import { AccordionComponent } from '../accordion/accordion.component';
|
||||
import { AccordionModalComponent } from '../accordion/accordion-modal/accordion-modal.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
InputsComponent,
|
||||
ModalComponent,
|
||||
ModalExampleComponent,
|
||||
RouterLinkComponent,
|
||||
RouterLinkPageComponent,
|
||||
RouterLinkPage2Component,
|
||||
RouterLinkPage3Component,
|
||||
HomePageComponent,
|
||||
NestedOutletComponent,
|
||||
NestedOutletPageComponent,
|
||||
NestedOutletPage2Component,
|
||||
NavComponent,
|
||||
ViewChildComponent,
|
||||
ProvidersComponent,
|
||||
FormComponent,
|
||||
NavigationPage1Component,
|
||||
NavigationPage2Component,
|
||||
NavigationPage3Component,
|
||||
AlertComponent,
|
||||
AccordionComponent,
|
||||
AccordionModalComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
AppRoutingModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
IonicModule.forRoot({ keyboardHeight: 12345 }),
|
||||
]
|
||||
})
|
||||
export class AppModule { }
|
||||
@@ -0,0 +1,89 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { AppComponent } from './app.component';
|
||||
import { InputsComponent } from '../inputs/inputs.component';
|
||||
import { ModalComponent } from '../modal/modal.component';
|
||||
import { RouterLinkComponent } from '../router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from '../router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from '../router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from '../router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from '../home-page/home-page.component';
|
||||
import { NestedOutletComponent } from '../nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from '../nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from '../nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { ViewChildComponent } from '../view-child/view-child.component';
|
||||
import { ProvidersComponent } from '../providers/providers.component';
|
||||
import { FormComponent } from '../form/form.component';
|
||||
import { NavigationPage1Component } from '../navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from '../navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from '../navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from '../alert/alert.component';
|
||||
import { AccordionComponent } from '../accordion/accordion.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: AppComponent,
|
||||
children: [
|
||||
{ path: '', component: HomePageComponent },
|
||||
{ path: 'version-test', loadChildren: () => import('../version-test').then(m => m.VersionTestModule) },
|
||||
{ path: 'accordions', component: AccordionComponent },
|
||||
{ path: 'alerts', component: AlertComponent },
|
||||
{ path: 'inputs', component: InputsComponent },
|
||||
{ path: 'textarea', loadChildren: () => import('../textarea/textarea.module').then(m => m.TextareaModule) },
|
||||
{ path: 'searchbar', loadChildren: () => import('../searchbar/searchbar.module').then(m => m.SearchbarModule) },
|
||||
{ path: 'form', component: FormComponent },
|
||||
{ path: 'modals', component: ModalComponent },
|
||||
{ path: 'modal-inline', loadChildren: () => import('../modal-inline').then(m => m.ModalInlineModule) },
|
||||
{ path: 'view-child', component: ViewChildComponent },
|
||||
{ path: 'keep-contents-mounted', loadChildren: () => import('../keep-contents-mounted').then(m => m.OverlayAutoMountModule) },
|
||||
{ path: 'overlays-inline', loadChildren: () => import('../overlays-inline').then(m => m.OverlaysInlineModule) },
|
||||
{ path: 'popover-inline', loadChildren: () => import('../popover-inline').then(m => m.PopoverInlineModule) },
|
||||
{ path: 'providers', component: ProvidersComponent },
|
||||
{ path: 'router-link', component: RouterLinkComponent },
|
||||
{ path: 'router-link-page', component: RouterLinkPageComponent },
|
||||
{ path: 'router-link-page2/:id', component: RouterLinkPage2Component },
|
||||
{ path: 'router-link-page3', component: RouterLinkPage3Component },
|
||||
{ path: 'standalone', loadComponent: () => import('../routing-standalone/standalone.component').then(c => c.StandaloneComponent) },
|
||||
{ path: 'tabs', redirectTo: '/lazy/tabs/account', pathMatch: 'full' },
|
||||
{
|
||||
path: 'navigation',
|
||||
children: [
|
||||
{ path: 'page1', component: NavigationPage1Component },
|
||||
{ path: 'page2', component: NavigationPage2Component },
|
||||
{ path: 'page3', component: NavigationPage3Component }
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
loadChildren: () => import('../tabs/tabs.module').then(m => m.TabsPageModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-global',
|
||||
loadChildren: () => import('../tabs-global/tabs-global.module').then(m => m.TabsGlobalModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-slots',
|
||||
loadComponent: () => import('../tabs-slots.component').then(c => c.TabsSlotsComponent)
|
||||
},
|
||||
{
|
||||
path: 'nested-outlet',
|
||||
component: NestedOutletComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'page',
|
||||
component: NestedOutletPageComponent
|
||||
},
|
||||
{
|
||||
path: 'page2',
|
||||
component: NestedOutletPage2Component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'form-controls/range',
|
||||
loadChildren: () => import('../form-controls/range/range.module').then(m => m.RangeModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
@@ -7,52 +7,52 @@
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item routerLink="/alerts" [routerAnimation]="routerAnimation">
|
||||
<ion-item routerLink="/lazy/alerts" [routerAnimation]="routerAnimation">
|
||||
<ion-label>
|
||||
Alerts test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/inputs">
|
||||
<ion-item routerLink="/lazy/inputs">
|
||||
<ion-label>
|
||||
Inputs test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/form">
|
||||
<ion-item routerLink="/lazy/form">
|
||||
<ion-label>
|
||||
Form test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/modals">
|
||||
<ion-item routerLink="/lazy/modals">
|
||||
<ion-label>
|
||||
Modals test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/router-link">
|
||||
<ion-item routerLink="/lazy/router-link">
|
||||
<ion-label>
|
||||
Router link test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/tabs">
|
||||
<ion-item routerLink="/lazy/tabs">
|
||||
<ion-label>
|
||||
Tabs test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/nested-outlet/page">
|
||||
<ion-item routerLink="/lazy/nested-outlet/page">
|
||||
<ion-label>
|
||||
Nested ion-router-outlet
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/view-child">
|
||||
<ion-item routerLink="/lazy/view-child">
|
||||
<ion-label>
|
||||
ViewChild()
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/providers">
|
||||
<ion-item routerLink="/lazy/providers">
|
||||
<ion-label>
|
||||
Providers
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/accordions">
|
||||
<ion-item routerLink="/lazy/accordions">
|
||||
<ion-label>
|
||||
Accordions Test
|
||||
</ion-label>
|
||||
@@ -13,7 +13,7 @@ export class NavigationPage1Component {
|
||||
|
||||
ionViewDidEnter() {
|
||||
if (count < 1) {
|
||||
this.navController.navigateBack('/navigation/page2');
|
||||
this.navController.navigateBack('/lazy/navigation/page2');
|
||||
}
|
||||
count++;
|
||||
}
|
||||
@@ -12,6 +12,6 @@ export class NavigationPage2Component {
|
||||
) {}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this.navController.navigateForward('/navigation/page1');
|
||||
this.navController.navigateForward('/lazy/navigation/page1');
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,6 @@ export class NavigationPage3Component {
|
||||
) {}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this.navController.navigateRoot('/navigation/page2');
|
||||
this.navController.navigateRoot('/lazy/navigation/page2');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<ion-content>
|
||||
<h1>Nested page 1</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/lazy/tabs" id="goto-tabs">Go To Tabs</ion-button>
|
||||
<ion-button routerLink="/lazy/nested-outlet/page2" id="goto-nested-page2">Go To SECOND</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
||||
@@ -0,0 +1,6 @@
|
||||
<ion-content>
|
||||
<h1>Nested page 2</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/lazy/nested-outlet/page" id="goto-nested-page1">Go To FIRST</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user