├── .nxignore ├── e2e ├── .gitkeep ├── capacitor-e2e │ ├── tsconfig.json │ ├── tsconfig.spec.json │ ├── jest.config.ts │ ├── eslint.config.js │ └── project.json ├── ionic-react-e2e │ ├── tsconfig.json │ ├── tsconfig.spec.json │ ├── jest.config.ts │ ├── eslint.config.js │ └── project.json └── ionic-angular-e2e │ ├── tsconfig.json │ ├── tsconfig.spec.json │ ├── jest.config.ts │ ├── eslint.config.js │ └── project.json ├── .husky ├── .gitignore ├── post-checkout ├── post-merge └── pre-push ├── .node-version ├── docs ├── docs │ ├── ionic-angular │ │ ├── executors.md │ │ ├── overview.md │ │ └── migrating-from-nxtend.md │ ├── ionic-react │ │ ├── executors.md │ │ ├── overview.md │ │ └── migrating-from-nxtend.md │ ├── nxext │ │ ├── community.md │ │ ├── overview.md │ │ └── contributing.md │ └── capacitor │ │ ├── executors.md │ │ ├── migrating-from-nxtend.md │ │ └── overview.md ├── guide │ ├── index.md │ ├── vite │ │ └── environment-variables.md │ └── articles.md ├── .vitepress │ └── theme │ │ ├── index.js │ │ └── vars.css ├── public │ └── _headers └── project.json ├── packages ├── ionic-angular │ ├── src │ │ ├── index.ts │ │ ├── generators │ │ │ ├── page │ │ │ │ ├── files │ │ │ │ │ ├── __name__.page.scss.template │ │ │ │ │ ├── __name__.page.html.template │ │ │ │ │ ├── __name__.page.ts.template │ │ │ │ │ ├── __name__-routing.module.ts.template │ │ │ │ │ ├── __name__.module.ts.template │ │ │ │ │ └── __name__.page.spec.ts.template │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ └── application │ │ │ │ ├── files │ │ │ │ ├── base │ │ │ │ │ ├── src │ │ │ │ │ │ ├── app │ │ │ │ │ │ │ ├── app.component.scss.template │ │ │ │ │ │ │ ├── app.component.html.template │ │ │ │ │ │ │ ├── app.component.ts.template │ │ │ │ │ │ │ ├── app.module.ts.template │ │ │ │ │ │ │ └── app.component.spec.ts.template │ │ │ │ │ │ ├── assets │ │ │ │ │ │ │ ├── icon │ │ │ │ │ │ │ │ └── favicon.png │ │ │ │ │ │ │ └── shapes.svg │ │ │ │ │ │ ├── styles.scss.template │ │ │ │ │ │ └── index.html.template │ │ │ │ │ └── ionic.config.json.template │ │ │ │ ├── list │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── home │ │ │ │ │ │ ├── home.page.scss.template │ │ │ │ │ │ ├── home-routing.module.ts.template │ │ │ │ │ │ ├── home.module.ts.template │ │ │ │ │ │ ├── home.page.ts.template │ │ │ │ │ │ ├── home.page.html.template │ │ │ │ │ │ └── home.spec.ts.template │ │ │ │ │ │ ├── app.component.html.template │ │ │ │ │ │ ├── services │ │ │ │ │ │ └── data.service.spec.ts.template │ │ │ │ │ │ ├── view-message │ │ │ │ │ │ ├── view-message-routing.module.ts.template │ │ │ │ │ │ ├── view-message.module.ts.template │ │ │ │ │ │ ├── view-message.page.scss.template │ │ │ │ │ │ ├── view-message.page.ts.template │ │ │ │ │ │ ├── vierw-message.page.spec.ts.template │ │ │ │ │ │ └── view-message.page.html.template │ │ │ │ │ │ ├── message │ │ │ │ │ │ ├── message.module.ts.template │ │ │ │ │ │ ├── message.component.ts.template │ │ │ │ │ │ ├── message.component.spec.ts.template │ │ │ │ │ │ ├── message.component.html.template │ │ │ │ │ │ └── message.component.scss.template │ │ │ │ │ │ ├── app.module.ts.template │ │ │ │ │ │ └── app-routing.module.ts.template │ │ │ │ ├── tabs │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── tab1 │ │ │ │ │ │ ├── tab1.page.scss.template │ │ │ │ │ │ ├── tab1.page.ts.template │ │ │ │ │ │ ├── tab1-routing.module.ts.template │ │ │ │ │ │ ├── tab1.page.html.template │ │ │ │ │ │ ├── tab1.module.ts.template │ │ │ │ │ │ └── tab1.page.spec.ts.template │ │ │ │ │ │ ├── tab2 │ │ │ │ │ │ ├── tab2.page.scss.template │ │ │ │ │ │ ├── tab2.page.ts.template │ │ │ │ │ │ ├── tab2-routing.module.ts.template │ │ │ │ │ │ ├── tab2.page.html.template │ │ │ │ │ │ ├── tab2.module.ts.template │ │ │ │ │ │ └── tab2.page.spec.ts.template │ │ │ │ │ │ ├── tab3 │ │ │ │ │ │ ├── tab3.page.scss.template │ │ │ │ │ │ ├── tab3.page.ts.template │ │ │ │ │ │ ├── tab3-routing.module.ts.template │ │ │ │ │ │ ├── tab3.page.html.template │ │ │ │ │ │ ├── tab3.module.ts.template │ │ │ │ │ │ └── tab3.page.spec.ts.template │ │ │ │ │ │ ├── tabs │ │ │ │ │ │ ├── tabs.page.scss.template │ │ │ │ │ │ ├── tabs.page.ts.template │ │ │ │ │ │ ├── tabs.module.ts.template │ │ │ │ │ │ ├── tabs.page.html.template │ │ │ │ │ │ ├── tabs.page.spec.ts.template │ │ │ │ │ │ └── tabs-routing.module.ts.template │ │ │ │ │ │ ├── app.component.html.template │ │ │ │ │ │ ├── explore-container │ │ │ │ │ │ ├── explore-container.component.html.template │ │ │ │ │ │ ├── explore-container.component.ts.template │ │ │ │ │ │ ├── explore-container.component.scss.template │ │ │ │ │ │ ├── explore-container.module.ts.template │ │ │ │ │ │ └── explore-container.component.spec.ts.template │ │ │ │ │ │ ├── app-routing.module.ts.template │ │ │ │ │ │ └── app.module.ts.template │ │ │ │ ├── blank │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── app.component.html.template │ │ │ │ │ │ ├── home │ │ │ │ │ │ ├── home.page.ts.template │ │ │ │ │ │ ├── home-routing.module.ts.template │ │ │ │ │ │ ├── home.page.scss.template │ │ │ │ │ │ ├── home.module.ts.template │ │ │ │ │ │ └── home.page.html.template │ │ │ │ │ │ ├── app-routing.module.ts.template │ │ │ │ │ │ └── app.module.ts.template │ │ │ │ ├── tabs-standalone │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── app.component.html.template │ │ │ │ │ │ ├── app.routes.ts.template │ │ │ │ │ │ ├── tab1 │ │ │ │ │ │ ├── tab1.routes.ts.template │ │ │ │ │ │ ├── tab1.page.spec.ts.template │ │ │ │ │ │ └── tab1.page.ts.template │ │ │ │ │ │ ├── tab2 │ │ │ │ │ │ ├── tab2.routes.ts.template │ │ │ │ │ │ ├── tab2.page.spec.ts.template │ │ │ │ │ │ └── tab2.page.ts.template │ │ │ │ │ │ ├── tab3 │ │ │ │ │ │ ├── tab3.routes.ts.template │ │ │ │ │ │ ├── tab3.page.spec.ts.template │ │ │ │ │ │ └── tab3.page.ts.template │ │ │ │ │ │ ├── app.config.ts.template │ │ │ │ │ │ ├── app.component.ts.template │ │ │ │ │ │ ├── tabs │ │ │ │ │ │ ├── tabs.page.spec.ts.template │ │ │ │ │ │ ├── tabs.routes.ts.template │ │ │ │ │ │ └── tabs.page.ts.template │ │ │ │ │ │ └── explore-container │ │ │ │ │ │ ├── explore-container.component.spec.ts.template │ │ │ │ │ │ └── explore-container.component.ts.template │ │ │ │ ├── base-standalone │ │ │ │ │ ├── ionic.config.json.template │ │ │ │ │ └── src │ │ │ │ │ │ ├── assets │ │ │ │ │ │ ├── icon │ │ │ │ │ │ │ └── favicon.png │ │ │ │ │ │ └── shapes.svg │ │ │ │ │ │ ├── app │ │ │ │ │ │ ├── app.component.ts.template │ │ │ │ │ │ └── app.component.spec.ts.template │ │ │ │ │ │ ├── styles.scss.template │ │ │ │ │ │ └── index.html.template │ │ │ │ ├── list-standalone │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── home │ │ │ │ │ │ ├── home.routes.ts.template │ │ │ │ │ │ └── home.spec.ts.template │ │ │ │ │ │ ├── view-message │ │ │ │ │ │ ├── view-message.routes.ts.template │ │ │ │ │ │ └── vierw-message.page.spec.ts.template │ │ │ │ │ │ ├── services │ │ │ │ │ │ └── data.service.spec.ts.template │ │ │ │ │ │ ├── app.config.ts.template │ │ │ │ │ │ ├── app.routes.ts.template │ │ │ │ │ │ ├── app.component.ts.template │ │ │ │ │ │ └── message │ │ │ │ │ │ └── message.component.spec.ts.template │ │ │ │ ├── sidemenu-standalone │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── folder │ │ │ │ │ │ └── folder.routes.ts.template │ │ │ │ │ │ ├── app.routes.ts.template │ │ │ │ │ │ └── app.config.ts.template │ │ │ │ ├── blank-standalone │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── home │ │ │ │ │ │ └── home.routes.ts.template │ │ │ │ │ │ ├── app.routes.ts.template │ │ │ │ │ │ ├── app.config.ts.template │ │ │ │ │ │ └── app.component.ts.template │ │ │ │ └── sidemenu │ │ │ │ │ └── src │ │ │ │ │ └── app │ │ │ │ │ ├── folder │ │ │ │ │ ├── folder-routing.module.ts.template │ │ │ │ │ ├── folder.page.scss.template │ │ │ │ │ ├── folder.module.ts.template │ │ │ │ │ ├── folder.page.ts.template │ │ │ │ │ └── folder.page.html.template │ │ │ │ │ ├── app-routing.module.ts.template │ │ │ │ │ ├── app.module.ts.template │ │ │ │ │ ├── app.component.ts.template │ │ │ │ │ └── app.component.html.template │ │ │ │ ├── schema.d.ts │ │ │ │ ├── lib │ │ │ │ ├── add-capacitor.ts │ │ │ │ ├── add-dependencies.ts │ │ │ │ ├── add-angular.ts │ │ │ │ └── normalize-options.ts │ │ │ │ └── generator.ts │ │ └── utils │ │ │ └── versions.ts │ ├── executors.json │ ├── tsconfig.spec.json │ ├── tsconfig.lib.json │ ├── tsconfig.json │ ├── jest.config.ts │ ├── README.md │ ├── generators.json │ ├── package.json │ └── eslint.config.js ├── capacitor │ ├── src │ │ ├── generators │ │ │ ├── application │ │ │ │ ├── files │ │ │ │ │ ├── src │ │ │ │ │ │ ├── assets │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ │ ├── main.ts__template__ │ │ │ │ │ │ ├── styles.__style__ │ │ │ │ │ │ └── app │ │ │ │ │ │ │ └── app.element.spec.ts__template__ │ │ │ │ │ ├── public │ │ │ │ │ │ └── favicon.ico │ │ │ │ │ ├── tsconfig.app.json │ │ │ │ │ ├── index.html__template__ │ │ │ │ │ └── tsconfig.json__tmpl__ │ │ │ │ ├── schema.d.ts │ │ │ │ ├── generator.spec.ts │ │ │ │ ├── schema.json │ │ │ │ └── generator.ts │ │ │ └── capacitor-project │ │ │ │ ├── files │ │ │ │ ├── package-json │ │ │ │ │ └── package.json__template__ │ │ │ │ └── capacitor-config │ │ │ │ │ └── capacitor.config.ts__template__ │ │ │ │ ├── schema.d.ts │ │ │ │ ├── lib │ │ │ │ ├── add-dependencies.ts │ │ │ │ ├── normalize-options.ts │ │ │ │ ├── add-capacitor-config.ts │ │ │ │ ├── update-project-gitignore.ts │ │ │ │ └── add-project.ts │ │ │ │ ├── schema.json │ │ │ │ └── generator.ts │ │ ├── utils │ │ │ └── versions.ts │ │ ├── executors │ │ │ └── cap │ │ │ │ ├── schema.d.ts │ │ │ │ ├── compat.ts │ │ │ │ └── schema.json │ │ └── index.ts │ ├── README.md │ ├── tsconfig.spec.json │ ├── tsconfig.lib.json │ ├── tsconfig.json │ ├── jest.config.ts │ ├── executors.json │ ├── generators.json │ ├── migrations.json │ ├── package.json │ ├── eslint.config.js │ └── MIGRATION.md └── ionic-react │ ├── src │ ├── generators │ │ └── application │ │ │ ├── files │ │ │ ├── blank │ │ │ │ └── src │ │ │ │ │ ├── pages │ │ │ │ │ ├── Home.css.template │ │ │ │ │ └── Home.tsx.template │ │ │ │ │ ├── App.test.tsx.template │ │ │ │ │ ├── components │ │ │ │ │ ├── ExploreContainer.css.template │ │ │ │ │ └── ExploreContainer.tsx.template │ │ │ │ │ └── App.tsx.template │ │ │ ├── list │ │ │ │ └── src │ │ │ │ │ ├── pages │ │ │ │ │ ├── Home.css.template │ │ │ │ │ └── ViewMessage.css.template │ │ │ │ │ ├── App.test.tsx.template │ │ │ │ │ └── components │ │ │ │ │ ├── MessageListItem.css.template │ │ │ │ │ └── MessageListItem.tsx.template │ │ │ ├── tabs │ │ │ │ └── src │ │ │ │ │ ├── pages │ │ │ │ │ ├── Tab1.css.template │ │ │ │ │ ├── Tab2.css.template │ │ │ │ │ ├── Tab3.css.template │ │ │ │ │ ├── Tab1.tsx.template │ │ │ │ │ ├── Tab2.tsx.template │ │ │ │ │ └── Tab3.tsx.template │ │ │ │ │ ├── App.test.tsx.template │ │ │ │ │ └── components │ │ │ │ │ ├── ExploreContainer.css.template │ │ │ │ │ └── ExploreContainer.tsx.template │ │ │ ├── sidemenu │ │ │ │ └── src │ │ │ │ │ ├── pages │ │ │ │ │ ├── Page.css.template │ │ │ │ │ └── Page.tsx.template │ │ │ │ │ ├── App.test.tsx.template │ │ │ │ │ └── components │ │ │ │ │ ├── ExploreContainer.css.template │ │ │ │ │ └── ExploreContainer.tsx.template │ │ │ └── base │ │ │ │ ├── ionic.config.json.template │ │ │ │ └── src │ │ │ │ ├── assets │ │ │ │ └── icon │ │ │ │ │ └── favicon.png │ │ │ │ ├── App.spec.tsx.template │ │ │ │ ├── main.tsx.template │ │ │ │ ├── manifest.json.template │ │ │ │ ├── setupTests.ts.template │ │ │ │ ├── App.tsx.template │ │ │ │ └── index.html.template │ │ │ ├── lib │ │ │ ├── remove-plain-reactapp.ts │ │ │ ├── add-capacitor.ts │ │ │ ├── change-react-router.ts │ │ │ ├── add-react.ts │ │ │ ├── normalize-options.ts │ │ │ ├── update-workspace.ts │ │ │ └── add-dependencies.ts │ │ │ └── schema.d.ts │ ├── index.ts │ └── utils │ │ └── versions.ts │ ├── executors.json │ ├── tsconfig.spec.json │ ├── tsconfig.lib.json │ ├── tsconfig.json │ ├── jest.config.ts │ ├── generators.json │ ├── README.md │ ├── package.json │ └── eslint.config.js ├── .prettierrc ├── jest.config.ts ├── .prettierignore ├── tools ├── scripts │ ├── tsconfig.scripts.json │ ├── stop-local-registry.ts │ ├── notify-lockfile-changes.js │ ├── start-local-registry.ts │ ├── update-package-json-nx-versions.ts │ ├── utils.ts │ ├── mock-project-graph.ts │ └── documentation │ │ └── documentation.ts └── tsconfig.tools.json ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── documentation.md │ ├── guides.md │ ├── bug_report.md │ └── feature_request.md ├── FUNDING.yml ├── workflows │ └── ci.yml └── disabled_workflows │ └── ci-checks-windows.yml ├── .editorconfig ├── project.json ├── jest.preset.js ├── tsconfig.base.json ├── .verdaccio └── config.yml ├── .gitignore ├── LICENSE └── CODE_OF_CONDUCT.md /.nxignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /e2e/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 18.14.2 2 | -------------------------------------------------------------------------------- /docs/docs/ionic-angular/executors.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/docs/ionic-react/executors.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/files/__name__.page.scss.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/capacitor/src/utils/versions.ts: -------------------------------------------------------------------------------- 1 | export const capacitorVersion = '^5.0.3'; 2 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/blank/src/pages/Home.css.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/list/src/pages/Home.css.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/pages/Tab1.css.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/pages/Tab2.css.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/pages/Tab3.css.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/sidemenu/src/pages/Page.css.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/app/app.component.scss.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/home/home.page.scss.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab1/tab1.page.scss.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab2/tab2.page.scss.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab3/tab3.page.scss.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tabs/tabs.page.scss.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/src/main.ts__template__: -------------------------------------------------------------------------------- 1 | import './app/app.element'; 2 | -------------------------------------------------------------------------------- /docs/guide/index.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | This is the place to collect specialzed guides for specific topics. 4 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import { getJestProjects } from '@nx/jest'; 2 | 3 | export default { 4 | projects: getJestProjects(), 5 | }; 6 | -------------------------------------------------------------------------------- /packages/ionic-angular/executors.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "executors": {}, 4 | "builders": {} 5 | } 6 | -------------------------------------------------------------------------------- /packages/ionic-react/executors.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "executors": {}, 4 | "builders": {} 5 | } 6 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/src/styles.__style__: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.js: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme'; 2 | import './vars.css'; 3 | 4 | export default { 5 | ...DefaultTheme, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/capacitor/src/executors/cap/schema.d.ts: -------------------------------------------------------------------------------- 1 | export interface CommandExecutorSchema { 2 | cmd: string; 3 | preserveProjectNodeModules?: boolean; 4 | } 5 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/files/package-json/package.json__template__: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= project %>", 3 | "dependencies": {} 4 | } 5 | -------------------------------------------------------------------------------- /.husky/post-checkout: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | changedFiles="$(git diff-tree -r --name-only --no-commit-id $1 $2)" 3 | node ./tools/scripts/notify-lockfile-changes.js $changedFiles 4 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/app/app.component.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/app.component.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/app.component.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/app.component.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.husky/post-merge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | changedFiles="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)" 3 | node ./tools/scripts/notify-lockfile-changes.js $changedFiles 4 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/app.component.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/schema.d.ts: -------------------------------------------------------------------------------- 1 | export interface AppGeneratorSchema { 2 | name: string; 3 | appId: string; 4 | unitTestRunner: 'vitest' | 'none'; 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/nxext/community.md: -------------------------------------------------------------------------------- 1 | # Community 2 | 3 | You can find us on [Discord](https://discord.gg/SWyp4xfGjn) or [Github discussions](https://github.com/nxext/nx-extensions/discussions). 4 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/utils/versions.ts: -------------------------------------------------------------------------------- 1 | export const ionicAngularVersion = '^7.0.0'; 2 | export const ioniconsVersion = '^7.0.0'; 3 | export const capacitorPluginVersion = '^5.0.0'; 4 | -------------------------------------------------------------------------------- /packages/capacitor/src/executors/cap/compat.ts: -------------------------------------------------------------------------------- 1 | import { convertNxExecutor } from '@nx/devkit'; 2 | import runExecutor from './executor'; 3 | 4 | export default convertNxExecutor(runExecutor); 5 | -------------------------------------------------------------------------------- /packages/ionic-react/src/index.ts: -------------------------------------------------------------------------------- 1 | export { applicationGenerator } from './generators/application/generator'; 2 | export { ApplicationGeneratorSchema } from './generators/application/schema'; 3 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nxext/nx-extensions-ionic/HEAD/packages/capacitor/src/generators/application/files/public/favicon.ico -------------------------------------------------------------------------------- /packages/capacitor/src/index.ts: -------------------------------------------------------------------------------- 1 | export { capacitorProjectGenerator } from './generators/capacitor-project/generator'; 2 | export { CapacitorGeneratorSchema } from './generators/capacitor-project/schema'; 3 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/ionic.config.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= appName %>", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "react" 7 | } 8 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/ionic.config.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= name %>", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "angular" 7 | } 8 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | 3 | /dist 4 | /coverage 5 | /tmp 6 | .docusaurus/ 7 | /build 8 | 9 | /.nx/cache 10 | pnpm-lock.yaml 11 | 12 | /.nx/workspace-data -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base-standalone/ionic.config.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= name %>", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "angular" 7 | } 8 | -------------------------------------------------------------------------------- /e2e/capacitor-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.spec.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /e2e/ionic-react-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.spec.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/src/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nxext/nx-extensions-ionic/HEAD/packages/ionic-react/src/generators/application/files/base/src/assets/icon/favicon.png -------------------------------------------------------------------------------- /e2e/ionic-angular-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.spec.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nxext/nx-extensions-ionic/HEAD/packages/ionic-angular/src/generators/application/files/base/src/assets/icon/favicon.png -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | pnpm format:check || { 5 | echo "Make sure to run \`pnpm format\` before pushing." >&2; 6 | exit 1; 7 | } 8 | pnpm documentation 9 | pnpm check-lock-files 10 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/files/__name__.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= className %> 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base-standalone/src/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nxext/nx-extensions-ionic/HEAD/packages/ionic-angular/src/generators/application/files/base-standalone/src/assets/icon/favicon.png -------------------------------------------------------------------------------- /tools/scripts/tsconfig.scripts.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../scripts/tools-out", 5 | "module": "commonjs", 6 | "types": ["node"] 7 | }, 8 | "include": ["**/*.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /docs/public/_headers: -------------------------------------------------------------------------------- 1 | /assets/* 2 | cache-control: max-age=31536000 3 | cache-control: immutable 4 | 5 | /*.svg 6 | cache-control: max-age=604800 7 | cache-control: immutable 8 | 9 | /*.png 10 | cache-control: max-age=604800 11 | cache-control: immutable 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Want to start a discussion? 4 | about: Want to start a thread to discuss an idea? Use the discussions feature provided by GitHub. 5 | url: https://github.com/nxext/nx-extensions/discussions 6 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/home/home.routes.ts.template: -------------------------------------------------------------------------------- 1 | import {Routes} from '@angular/router'; 2 | 3 | export const routes: Routes = [ 4 | { 5 | path: '', 6 | loadComponent: () => import('./home.page').then(p => p.HomePage) 7 | } 8 | ]; 9 | -------------------------------------------------------------------------------- /tools/tsconfig.tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../dist/out-tsc/tools", 5 | "rootDir": ".", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": ["node"] 9 | }, 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/schema.d.ts: -------------------------------------------------------------------------------- 1 | export interface PageGeneratorSchema { 2 | name: string; 3 | project: string; 4 | directory?: string; 5 | } 6 | 7 | export interface NormalizedSchema extends PageGeneratorSchema { 8 | projectRoot: string; 9 | prefix: string; 10 | } 11 | -------------------------------------------------------------------------------- /tools/scripts/stop-local-registry.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This script stops the local registry for e2e testing purposes. 3 | * It is meant to be called in jest's globalTeardown. 4 | */ 5 | 6 | export default () => { 7 | if (global.stopLocalRegistry) { 8 | global.stopLocalRegistry(); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /e2e/capacitor-e2e/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /e2e/ionic-react-e2e/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/capacitor/README.md: -------------------------------------------------------------------------------- 1 | # capacitor 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Building 6 | 7 | Run `nx build capacitor` to build the library. 8 | 9 | ## Running unit tests 10 | 11 | Run `nx test capacitor` to execute the unit tests via [Jest](https://jestjs.io). 12 | -------------------------------------------------------------------------------- /packages/capacitor/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/ionic-react/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /e2e/ionic-angular-e2e/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu-standalone/src/app/folder/folder.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const routes: Routes = [ 4 | { 5 | path: '', 6 | loadComponent: () => import('./folder.page').then(p => p.FolderPage) 7 | } 8 | ]; 9 | -------------------------------------------------------------------------------- /packages/ionic-angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /packages/capacitor/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["**/*.ts"], 9 | "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank-standalone/src/app/home/home.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const routes: Routes = [ 4 | { 5 | path: '', 6 | loadComponent: () => import('./home.page').then(p => p.HomePage) 7 | } 8 | ]; 9 | 10 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/explore-container/explore-container.component.html.template: -------------------------------------------------------------------------------- 1 |
2 | {{ name }} 3 |

Explore UI Components

4 |
-------------------------------------------------------------------------------- /packages/ionic-angular/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["**/*.ts"], 9 | "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ionic-react/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["**/*.ts"], 9 | "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: '📄 Documentation' 3 | about: Suggest an idea for the docs 4 | title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: ' 5 | labels: documentation 6 | assignees: '' 7 | --- 8 | 9 | ** describe what you'd like to see in the docs ** 10 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "<%= offsetFromRoot %>dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"], 8 | "include": ["src/**/*.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/view-message/view-message.routes.ts.template: -------------------------------------------------------------------------------- 1 | import {Routes} from '@angular/router'; 2 | 3 | export const routes: Routes = [ 4 | { 5 | path: '', 6 | loadComponent: () => import('./view-message.page').then(p => p.ViewMessagePage) 7 | } 8 | ]; 9 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/src/App.spec.tsx.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/list/src/App.test.tsx.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/App.test.tsx.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/blank/src/App.test.tsx.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/sidemenu/src/App.test.tsx.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/lib/remove-plain-reactapp.ts: -------------------------------------------------------------------------------- 1 | import { joinPathFragments, Tree } from '@nx/devkit'; 2 | import { NormalizedSchema } from '../schema'; 3 | 4 | export function removePlainReactapp(host: Tree, options: NormalizedSchema) { 5 | host.delete(joinPathFragments(options.appProjectRoot, 'src/app')); 6 | } 7 | -------------------------------------------------------------------------------- /packages/capacitor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | }, 6 | "files": [], 7 | "include": [], 8 | "references": [ 9 | { 10 | "path": "./tsconfig.lib.json" 11 | }, 12 | { 13 | "path": "./tsconfig.spec.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/app/app.component.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-root', 5 | templateUrl: 'app.component.html', 6 | styleUrls: ['app.component.scss'], 7 | }) 8 | export class AppComponent { 9 | constructor() {} 10 | } 11 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab1/tab1.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-tab1', 5 | templateUrl: 'tab1.page.html', 6 | styleUrls: ['tab1.page.scss'] 7 | }) 8 | export class Tab1Page { 9 | 10 | constructor() {} 11 | 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab2/tab2.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-tab2', 5 | templateUrl: 'tab2.page.html', 6 | styleUrls: ['tab2.page.scss'] 7 | }) 8 | export class Tab2Page { 9 | 10 | constructor() {} 11 | 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab3/tab3.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-tab3', 5 | templateUrl: 'tab3.page.html', 6 | styleUrls: ['tab3.page.scss'] 7 | }) 8 | export class Tab3Page { 9 | 10 | constructor() {} 11 | 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tabs/tabs.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-tabs', 5 | templateUrl: 'tabs.page.html', 6 | styleUrls: ['tabs.page.scss'] 7 | }) 8 | export class TabsPage { 9 | 10 | constructor() {} 11 | 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/home/home.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-home', 5 | templateUrl: 'home.page.html', 6 | styleUrls: ['home.page.scss'], 7 | }) 8 | export class HomePage { 9 | 10 | constructor() {} 11 | 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/app.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import {Routes} from '@angular/router'; 3 | 4 | export const appRoutes: Routes = [ 5 | { 6 | path: '', 7 | loadChildren: () => import('./tabs/tabs.routes').then(r => r.routes) 8 | } 9 | ]; 10 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab1/tab1.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { Tab1Page } from './tab1.page'; 2 | import {Routes} from '@angular/router'; 3 | 4 | export const routes: Routes = [ 5 | { 6 | path: '', 7 | loadComponent: () => import('./tab1.page').then(p => p.Tab1Page) 8 | } 9 | ]; 10 | 11 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab2/tab2.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { Tab2Page } from './tab2.page'; 2 | import {Routes} from '@angular/router'; 3 | 4 | export const routes: Routes = [ 5 | { 6 | path: '', 7 | loadComponent: () => import('./tab2.page').then(p => p.Tab2Page), 8 | } 9 | ]; 10 | 11 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab3/tab3.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { Tab3Page } from './tab3.page'; 2 | import {Routes} from '@angular/router'; 3 | 4 | export const routes: Routes = [ 5 | { 6 | path: '', 7 | loadComponent: () => import('./tab3.page').then(p => p.Tab3Page) 8 | } 9 | ]; 10 | 11 | -------------------------------------------------------------------------------- /packages/ionic-angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | }, 6 | "files": [], 7 | "include": [], 8 | "references": [ 9 | { 10 | "path": "./tsconfig.lib.json" 11 | }, 12 | { 13 | "path": "./tsconfig.spec.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/ionic-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | }, 6 | "files": [], 7 | "include": [], 8 | "references": [ 9 | { 10 | "path": "./tsconfig.lib.json" 11 | }, 12 | { 13 | "path": "./tsconfig.spec.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/schema.d.ts: -------------------------------------------------------------------------------- 1 | export interface CapacitorGeneratorSchema { 2 | project: string; 3 | appId: string; 4 | appName?: string; 5 | webDir?: string; 6 | skipFormat: boolean; 7 | } 8 | 9 | export interface NormalizedSchema extends CapacitorGeneratorSchema { 10 | projectRoot: string; 11 | pathToRoot: string; 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-react/src/utils/versions.ts: -------------------------------------------------------------------------------- 1 | export const ionicReactVersion = '^7.0.0'; 2 | export const ionicReactRouterVersion = '^7.0.0'; 3 | export const webVitalsVersion = '^0.2.4'; 4 | export const workboxVersion = '^5.1.4'; 5 | export const reactRouterDomVersion = '5.3.3'; 6 | export const typesReactRouterDomVersion = '5.3.3'; 7 | export const capacitorPluginVersion = '5.0.2'; 8 | -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nxext", 3 | "$schema": "node_modules/nx/schemas/project-schema.json", 4 | "targets": { 5 | "local-registry": { 6 | "executor": "@nx/js:verdaccio", 7 | "options": { 8 | "port": 4873, 9 | "config": ".verdaccio/config.yml", 10 | "storage": "tmp/local-registry/storage" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/files/__name__.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-<%= fileName %>', 5 | templateUrl: './<%= fileName %>.page.html', 6 | styleUrls: ['./<%= fileName %>.page.scss'], 7 | }) 8 | export class <%= className %>Page { 9 | 10 | constructor() { } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/vars.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --vp-c-brand: rgb(215, 110, 5); 3 | --vp-c-brand-light: rgb(205, 136, 86); 4 | --vp-button-brand-bg: rgb(205, 110, 5); 5 | --vp-button-brand-active-bg: rgb(205, 110, 5); 6 | --vp-button-brand-hover-bg: rgb(205, 110, 5); 7 | --vp-button-brand-hover-border: rgb(205, 110, 5); 8 | --vp-button-brand-active-border: rgb(205, 110, 5); 9 | } 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/guides.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: '⚙️ Guides' 3 | about: Suggest an idea for the guides 4 | title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: ' 5 | labels: guides 6 | assignees: '' 7 | --- 8 | 9 | ** describe what you'd like to see in the guides ** 10 | 11 | Use the guides for more complex examples that are not covered or too long for the docs. 12 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank-standalone/src/app/app.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const appRoutes: Routes = [ 4 | { 5 | path: 'home', 6 | loadChildren: () => import('./home/home.routes').then(r => r.routes) 7 | }, 8 | { 9 | path: '', 10 | redirectTo: 'home', 11 | pathMatch: 'full' 12 | }, 13 | ]; 14 | 15 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/files/capacitor-config/capacitor.config.ts__template__: -------------------------------------------------------------------------------- 1 | import { CapacitorConfig } from '@capacitor/cli'; 2 | 3 | const config: CapacitorConfig = { 4 | appId: '<%= appId %>', 5 | appName: '<%= appName %>', 6 | webDir: '<%= webDir %>', 7 | bundledWebRuntime: false, 8 | server: { 9 | androidScheme: 'https' 10 | } 11 | } 12 | 13 | export default config; 14 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu-standalone/src/app/app.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const appRoutes: Routes = [ 4 | { 5 | path: '', 6 | redirectTo: 'folder/Inbox', 7 | pathMatch: 'full' 8 | }, 9 | { 10 | path: 'folder/:id', 11 | loadChildren: () => import('./folder/folder.routes').then( r => r.routes) 12 | } 13 | ]; 14 | -------------------------------------------------------------------------------- /packages/capacitor/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | displayName: 'capacitor', 4 | preset: '../../jest.preset.js', 5 | globals: {}, 6 | transform: { 7 | '^.+\\.[tj]s$': [ 8 | 'ts-jest', 9 | { 10 | tsconfig: '/tsconfig.spec.json', 11 | }, 12 | ], 13 | }, 14 | moduleFileExtensions: ['ts', 'js', 'html'], 15 | coverageDirectory: '../../coverage/packages/capacitor', 16 | }; 17 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/src/main.tsx.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App'; 4 | 5 | const container = document.getElementById('root'); 6 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 7 | const root = createRoot(container!); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/explore-container/explore-container.component.ts.template: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: '<%= prefix %>-explore-container', 5 | templateUrl: './explore-container.component.html', 6 | styleUrls: ['./explore-container.component.scss'], 7 | }) 8 | export class ExploreContainerComponent { 9 | 10 | @Input() name?: string; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | displayName: 'ionic-angular', 4 | preset: '../../jest.preset.js', 5 | globals: {}, 6 | transform: { 7 | '^.+\\.[tj]s$': [ 8 | 'ts-jest', 9 | { 10 | tsconfig: '/tsconfig.spec.json', 11 | }, 12 | ], 13 | }, 14 | moduleFileExtensions: ['ts', 'js', 'html'], 15 | coverageDirectory: '../../coverage/packages/ionic-angular', 16 | }; 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/services/data.service.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { DataService } from './data.service'; 4 | 5 | describe('DataService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: DataService = TestBed.get(DataService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/services/data.service.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { DataService } from './data.service'; 4 | 5 | describe('DataService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: DataService = TestBed.get(DataService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/ionic-react/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | displayName: 'ionic-react', 4 | preset: '../../jest.preset.js', 5 | globals: {}, 6 | transform: { 7 | '^.+\\.[tj]s$': [ 8 | 'ts-jest', 9 | { 10 | tsconfig: '/tsconfig.spec.json', 11 | }, 12 | ], 13 | }, 14 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'], 15 | coverageDirectory: '../../coverage/packages/ionic-react', 16 | }; 17 | -------------------------------------------------------------------------------- /e2e/capacitor-e2e/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'capacitor-e2e', 4 | preset: '../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../coverage/e2e/capacitor-e2e', 10 | globalSetup: '../../tools/scripts/start-local-registry.ts', 11 | globalTeardown: '../../tools/scripts/stop-local-registry.ts', 12 | }; 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/home/home-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { HomePage } from './home.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: HomePage, 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class HomePageRoutingModule {} 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab1/tab1-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { Tab1Page } from './tab1.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: Tab1Page, 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class Tab1PageRoutingModule {} 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab2/tab2-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { Tab2Page } from './tab2.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: Tab2Page, 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class Tab2PageRoutingModule {} 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab3/tab3-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { Tab3Page } from './tab3.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: Tab3Page, 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class Tab3PageRoutingModule {} 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/home/home-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { HomePage } from './home.page'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: HomePage 10 | } 11 | ]; 12 | 13 | @NgModule({ 14 | imports: [RouterModule.forChild(routes)], 15 | exports: [RouterModule], 16 | }) 17 | export class HomePageRoutingModule {} 18 | -------------------------------------------------------------------------------- /e2e/ionic-react-e2e/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'ionic-react-e2e', 4 | preset: '../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../coverage/e2e/ionic-react-e2e', 10 | globalSetup: '../../tools/scripts/start-local-registry.ts', 11 | globalTeardown: '../../tools/scripts/stop-local-registry.ts', 12 | }; 13 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/components/ExploreContainer.css.template: -------------------------------------------------------------------------------- 1 | .container { 2 | text-align: center; 3 | position: absolute; 4 | left: 0; 5 | right: 0; 6 | top: 50%; 7 | transform: translateY(-50%); 8 | } 9 | 10 | .container strong { 11 | font-size: 20px; 12 | line-height: 26px; 13 | } 14 | 15 | .container p { 16 | font-size: 16px; 17 | line-height: 22px; 18 | color: #8c8c8c; 19 | margin: 0; 20 | } 21 | 22 | .container a { 23 | text-decoration: none; 24 | } -------------------------------------------------------------------------------- /e2e/ionic-angular-e2e/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'ionic-angular-e2e', 4 | preset: '../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../coverage/e2e/ionic-angular-e2e', 10 | globalSetup: '../../tools/scripts/start-local-registry.ts', 11 | globalTeardown: '../../tools/scripts/stop-local-registry.ts', 12 | }; 13 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/lib/add-capacitor.ts: -------------------------------------------------------------------------------- 1 | import { Tree } from '@nx/devkit'; 2 | import { capacitorProjectGenerator } from '@nxext/capacitor'; 3 | import { NormalizedSchema } from '../schema'; 4 | 5 | export async function addCapacitor(host: Tree, options: NormalizedSchema) { 6 | return await capacitorProjectGenerator(host, { 7 | project: options.appProjectName, 8 | appName: options.appName, 9 | appId: 'io.ionic.starter', 10 | skipFormat: options.skipFormat, 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base-standalone/src/app/app.component.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {IonicModule} from '@ionic/angular'; 3 | 4 | @Component({ 5 | selector: '<%= prefix %>-root', 6 | standalone: true, 7 | imports: [IonicModule], 8 | template: ` 9 | 10 | 11 | 12 | `, 13 | styles: ` 14 | 15 | ` 16 | }) 17 | export class AppComponent { 18 | constructor() {} 19 | } 20 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank-standalone/src/app/app.config.ts.template: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, importProvidersFrom } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | import { appRoutes } from './app.routes'; 4 | import {IonicModule} from '@ionic/angular'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [ 8 | provideRouter(appRoutes), 9 | importProvidersFrom( 10 | IonicModule.forRoot() 11 | ) 12 | 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/app.config.ts.template: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, importProvidersFrom } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | import { appRoutes } from './app.routes'; 4 | import {IonicModule} from '@ionic/angular'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [ 8 | provideRouter(appRoutes), 9 | importProvidersFrom( 10 | IonicModule.forRoot() 11 | ) 12 | 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu-standalone/src/app/app.config.ts.template: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, importProvidersFrom } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | import { appRoutes } from './app.routes'; 4 | import {IonicModule} from '@ionic/angular'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [ 8 | provideRouter(appRoutes), 9 | importProvidersFrom( 10 | IonicModule.forRoot() 11 | ) 12 | 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/folder/folder-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { FolderPage } from './folder.page'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: FolderPage 10 | } 11 | ]; 12 | 13 | @NgModule({ 14 | imports: [RouterModule.forChild(routes)], 15 | exports: [RouterModule], 16 | }) 17 | export class FolderPageRoutingModule {} 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/app.config.ts.template: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, importProvidersFrom } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | import { appRoutes } from './app.routes'; 4 | import {IonicModule} from '@ionic/angular'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [ 8 | provideRouter(appRoutes), 9 | importProvidersFrom( 10 | IonicModule.forRoot() 11 | ) 12 | 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/blank/src/components/ExploreContainer.css.template: -------------------------------------------------------------------------------- 1 | .container { 2 | text-align: center; 3 | position: absolute; 4 | left: 0; 5 | right: 0; 6 | top: 50%; 7 | transform: translateY(-50%); 8 | } 9 | 10 | .container strong { 11 | font-size: 20px; 12 | line-height: 26px; 13 | } 14 | 15 | .container p { 16 | font-size: 16px; 17 | line-height: 22px; 18 | color: #8c8c8c; 19 | margin: 0; 20 | } 21 | 22 | .container a { 23 | text-decoration: none; 24 | } 25 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/sidemenu/src/components/ExploreContainer.css.template: -------------------------------------------------------------------------------- 1 | #container { 2 | text-align: center; 3 | position: absolute; 4 | left: 0; 5 | right: 0; 6 | top: 50%; 7 | transform: translateY(-50%); 8 | } 9 | 10 | #container strong { 11 | font-size: 20px; 12 | line-height: 26px; 13 | } 14 | 15 | #container p { 16 | font-size: 16px; 17 | line-height: 22px; 18 | color: #8c8c8c; 19 | margin: 0; 20 | } 21 | 22 | #container a { 23 | text-decoration: none; 24 | } 25 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/home/home.page.scss.template: -------------------------------------------------------------------------------- 1 | #container { 2 | text-align: center; 3 | 4 | position: absolute; 5 | left: 0; 6 | right: 0; 7 | top: 50%; 8 | transform: translateY(-50%); 9 | } 10 | 11 | #container strong { 12 | font-size: 20px; 13 | line-height: 26px; 14 | } 15 | 16 | #container p { 17 | font-size: 16px; 18 | line-height: 22px; 19 | 20 | color: #8c8c8c; 21 | 22 | margin: 0; 23 | } 24 | 25 | #container a { 26 | text-decoration: none; 27 | } -------------------------------------------------------------------------------- /docs/docs/capacitor/executors.md: -------------------------------------------------------------------------------- 1 | ## @nxext/capacitor:cap 2 | 3 | Run a Capacitor command 4 | 5 | Options can be configured in the 'project.json' when defining the executor, or when invoking it. Read more about how to configure targets and executors here: https://nx.dev/configuration/projectjson#targets. 6 | 7 | ### Options 8 | 9 | #### cmd 10 | 11 | Type: `string` 12 | 13 | The Capacitor command. 14 | 15 | #### preserveProjectNodeModules 16 | 17 | Type: `boolean` 18 | 19 | Preserve the node_modules folder inside the project dir. 20 | -------------------------------------------------------------------------------- /packages/capacitor/executors.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "executors": { 4 | "cap": { 5 | "implementation": "./src/executors/cap/executor", 6 | "schema": "./src/executors/cap/schema.json", 7 | "description": "Run a Capacitor command" 8 | } 9 | }, 10 | "builders": { 11 | "cap": { 12 | "implementation": "./src/executors/cap/compat", 13 | "schema": "./src/executors/cap/schema.json", 14 | "description": "Run a Capacitor command" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/files/__name__-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { <%= className %>Page } from './<%= fileName %>.page'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: <%= className %>Page 10 | } 11 | ]; 12 | 13 | @NgModule({ 14 | imports: [RouterModule.forChild(routes)], 15 | exports: [RouterModule], 16 | }) 17 | export class <%= className %>PageRoutingModule {} 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank-standalone/src/app/app.component.ts.template: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {IonicModule} from '@ionic/angular'; 4 | 5 | @Component({ 6 | selector: '<%= prefix %>-root', 7 | standalone: true, 8 | imports: [CommonModule, IonicModule], 9 | template: ` 10 | 11 | 12 | 13 | `, 14 | styles: `` 15 | }) 16 | 17 | export class AppComponent {} -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/app.routes.ts.template: -------------------------------------------------------------------------------- 1 | import {Routes} from '@angular/router'; 2 | 3 | export const appRoutes: Routes = [ 4 | { 5 | path: 'home', 6 | loadChildren: () => import('./home/home.routes').then( r => r.routes) 7 | }, 8 | { 9 | path: 'message/:id', 10 | loadChildren: () => import('./view-message/view-message.routes').then( r => r.routes) 11 | }, 12 | { 13 | path: '', 14 | redirectTo: 'home', 15 | pathMatch: 'full' 16 | }, 17 | ]; 18 | 19 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/app.component.ts.template: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {IonicModule} from '@ionic/angular'; 4 | 5 | @Component({ 6 | selector: '<%= prefix %>-root', 7 | standalone: true, 8 | imports: [CommonModule, IonicModule], 9 | template: ` 10 | 11 | 12 | 13 | `, 14 | styles: `` 15 | }) 16 | 17 | export class AppComponent {} 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/app.component.ts.template: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {IonicModule} from '@ionic/angular'; 4 | 5 | @Component({ 6 | selector: '<%= prefix %>-root', 7 | standalone: true, 8 | imports: [CommonModule, IonicModule], 9 | template: ` 10 | 11 | 12 | 13 | `, 14 | styles: ` 15 | ` 16 | }) 17 | export class AppComponent { 18 | } 19 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/view-message/view-message-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { ViewMessagePage } from './view-message.page'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: ViewMessagePage 10 | } 11 | ]; 12 | 13 | @NgModule({ 14 | imports: [RouterModule.forChild(routes)], 15 | exports: [RouterModule], 16 | }) 17 | export class ViewMessagePageRoutingModule {} 18 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/lib/add-dependencies.ts: -------------------------------------------------------------------------------- 1 | import { addDependenciesToPackageJson, Tree } from '@nx/devkit'; 2 | import { capacitorVersion } from '../../../utils/versions'; 3 | 4 | export function addDependencies(host: Tree) { 5 | return addDependenciesToPackageJson( 6 | host, 7 | { 8 | '@capacitor/core': capacitorVersion, 9 | }, 10 | { 11 | '@capacitor/android': capacitorVersion, 12 | '@capacitor/ios': capacitorVersion, 13 | '@capacitor/cli': capacitorVersion, 14 | } 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/explore-container/explore-container.component.scss.template: -------------------------------------------------------------------------------- 1 | #container { 2 | text-align: center; 3 | 4 | position: absolute; 5 | left: 0; 6 | right: 0; 7 | top: 50%; 8 | transform: translateY(-50%); 9 | } 10 | 11 | #container strong { 12 | font-size: 20px; 13 | line-height: 26px; 14 | } 15 | 16 | #container p { 17 | font-size: 16px; 18 | line-height: 22px; 19 | 20 | color: #8c8c8c; 21 | 22 | margin: 0; 23 | } 24 | 25 | #container a { 26 | text-decoration: none; 27 | } -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab1/tab1.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tab 1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Tab 1 13 | 14 | 15 | 16 | <<%= prefix %>-explore-container name="Tab 1 page">-explore-container> 17 | 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab2/tab2.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tab 2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Tab 2 13 | 14 | 15 | 16 | <<%= prefix %>-explore-container name="Tab 2 page">-explore-container> 17 | 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab3/tab3.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tab 3 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Tab 3 13 | 14 | 15 | 16 | <<%= prefix %>-explore-container name="Tab 3 page">-explore-container> 17 | 18 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/sidemenu/src/components/ExploreContainer.tsx.template: -------------------------------------------------------------------------------- 1 | import './ExploreContainer.css'; 2 | 3 | interface ContainerProps { 4 | name: string; 5 | } 6 | 7 | const ExploreContainer: React.FC = ({ name }) => { 8 | return ( 9 |
10 | {name} 11 |

Explore UI Components

12 |
13 | ); 14 | }; 15 | 16 | export default ExploreContainer; 17 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/components/ExploreContainer.tsx.template: -------------------------------------------------------------------------------- 1 | import './ExploreContainer.css'; 2 | 3 | interface ContainerProps { 4 | name: string; 5 | } 6 | 7 | const ExploreContainer: React.FC = ({ name }) => { 8 | return ( 9 |
10 | {name} 11 |

Explore UI Components

12 |
13 | ); 14 | }; 15 | 16 | export default ExploreContainer; 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/app-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; 3 | 4 | const routes: Routes = [ 5 | { 6 | path: '', 7 | loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule) 8 | } 9 | ]; 10 | @NgModule({ 11 | imports: [ 12 | RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) 13 | ], 14 | exports: [RouterModule] 15 | }) 16 | export class AppRoutingModule {} 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: '🐞 Bug Report' 3 | about: Create a report to help us improve 4 | title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: ' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | **Expected behavior** 16 | A clear and concise description of what you expected to happen. 17 | 18 | **Additional context** 19 | Add any other context about the problem here. 20 | -------------------------------------------------------------------------------- /docs/guide/vite/environment-variables.md: -------------------------------------------------------------------------------- 1 | # Environment variables 2 | 3 | ## Vite way to go 4 | 5 | First add a file named `env.d.ts` to your src directory with the following content: 6 | 7 | ```typescript 8 | interface ImportMeta { 9 | readonly env: ImportMetaEnv; 10 | } 11 | ``` 12 | 13 | Now you're ready to use the `.env` file in your workspace: 14 | 15 | ``` 16 | VITE_API_URL=http://localhost:3000/ 17 | ``` 18 | 19 | After that, you can use the `import.meta.env` property to access the environment variables: 20 | 21 | ``` 22 | baseUrl: import.meta.env['VITE_API_URL'], 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "$schema": "../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "packages/docs", 5 | "projectType": "library", 6 | "targets": { 7 | "build": { 8 | "executor": "nx:run-commands", 9 | "options": { 10 | "command": "npx vitepress build", 11 | "cwd": "docs" 12 | } 13 | }, 14 | "serve": { 15 | "executor": "nx:run-commands", 16 | "options": { 17 | "command": "npx vitepress dev", 18 | "cwd": "docs" 19 | } 20 | } 21 | }, 22 | "tags": [] 23 | } 24 | -------------------------------------------------------------------------------- /e2e/capacitor-e2e/eslint.config.js: -------------------------------------------------------------------------------- 1 | const baseConfig = require('../../eslint.config.js'); 2 | module.exports = [ 3 | ...baseConfig, 4 | { 5 | files: [ 6 | 'e2e/capacitor-e2e/**/*.ts', 7 | 'e2e/capacitor-e2e/**/*.tsx', 8 | 'e2e/capacitor-e2e/**/*.js', 9 | 'e2e/capacitor-e2e/**/*.jsx', 10 | ], 11 | rules: {}, 12 | }, 13 | { 14 | files: ['e2e/capacitor-e2e/**/*.ts', 'e2e/capacitor-e2e/**/*.tsx'], 15 | rules: {}, 16 | }, 17 | { 18 | files: ['e2e/capacitor-e2e/**/*.js', 'e2e/capacitor-e2e/**/*.jsx'], 19 | rules: {}, 20 | }, 21 | ]; 22 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/src/app/app.element.spec.ts__template__: -------------------------------------------------------------------------------- 1 | import { AppElement } from './app.element'; 2 | 3 | describe('AppElement', () => { 4 | let app: AppElement; 5 | 6 | beforeEach(() => { 7 | app = new AppElement(); 8 | }); 9 | 10 | it('should create successfully', () => { 11 | expect(app).toBeTruthy(); 12 | }); 13 | 14 | it('should have a greeting', () => { 15 | app.connectedCallback(); 16 | 17 | expect(app.querySelector('h1').innerHTML).toContain( 18 | 'Welcome <%= projectName %>' 19 | ); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /tools/scripts/notify-lockfile-changes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Originally from the Nx repo: https://github.com/nrwl/nx 3 | */ 4 | 5 | if (process.argv.slice(2).some((arg) => arg.includes('pnpm-lock.yaml'))) { 6 | console.warn( 7 | [ 8 | '⚠️ ----------------------------------------------------------------------------------------- ⚠️', 9 | '⚠️ pnpm-lock.yaml changed, please run `pnpm install` to ensure your packages are up to date. ⚠️', 10 | '⚠️ ----------------------------------------------------------------------------------------- ⚠️', 11 | ].join('\n') 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /packages/capacitor/src/executors/cap/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "outputCapture": "direct-nodejs", 4 | "$schema": "http://json-schema.org/schema", 5 | "title": "Command executor", 6 | "description": "Run a Capacitor command.", 7 | "type": "object", 8 | "properties": { 9 | "cmd": { 10 | "description": "The Capacitor command.", 11 | "type": "string" 12 | }, 13 | "preserveProjectNodeModules": { 14 | "description": "Preserve the node_modules folder inside the project dir.", 15 | "type": "boolean" 16 | } 17 | }, 18 | "required": [] 19 | } 20 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/styles.scss.template: -------------------------------------------------------------------------------- 1 | /* 2 | * App Global CSS 3 | * ---------------------------------------------------------------------------- 4 | * Put style rules here that you want to apply globally. These styles are for 5 | * the entire app and not just one component. Additionally, this file can be 6 | * used as an entry point to import other CSS/Sass files to be included in the 7 | * output CSS. 8 | * For more information on global stylesheets, visit the documentation: 9 | * https://ionicframework.com/docs/layout/global-stylesheets 10 | */ 11 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/folder/folder.page.scss.template: -------------------------------------------------------------------------------- 1 | ion-menu-button { 2 | color: var(--ion-color-primary); 3 | } 4 | 5 | #container { 6 | text-align: center; 7 | position: absolute; 8 | left: 0; 9 | right: 0; 10 | top: 50%; 11 | transform: translateY(-50%); 12 | } 13 | 14 | #container strong { 15 | font-size: 20px; 16 | line-height: 26px; 17 | } 18 | 19 | #container p { 20 | font-size: 16px; 21 | line-height: 22px; 22 | color: #8c8c8c; 23 | margin: 0; 24 | } 25 | 26 | #container a { 27 | text-decoration: none; 28 | } 29 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/index.html__template__: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= className %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | <<%= prefix %>-root>-root> 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /e2e/ionic-react-e2e/eslint.config.js: -------------------------------------------------------------------------------- 1 | const baseConfig = require('../../eslint.config.js'); 2 | module.exports = [ 3 | ...baseConfig, 4 | { 5 | files: [ 6 | 'e2e/ionic-react-e2e/**/*.ts', 7 | 'e2e/ionic-react-e2e/**/*.tsx', 8 | 'e2e/ionic-react-e2e/**/*.js', 9 | 'e2e/ionic-react-e2e/**/*.jsx', 10 | ], 11 | rules: {}, 12 | }, 13 | { 14 | files: ['e2e/ionic-react-e2e/**/*.ts', 'e2e/ionic-react-e2e/**/*.tsx'], 15 | rules: {}, 16 | }, 17 | { 18 | files: ['e2e/ionic-react-e2e/**/*.js', 'e2e/ionic-react-e2e/**/*.jsx'], 19 | rules: {}, 20 | }, 21 | ]; 22 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/schema.d.ts: -------------------------------------------------------------------------------- 1 | export interface ApplicationGeneratorSchema { 2 | name: string; 3 | directory?: string; 4 | unitTestRunner: 'jest' | 'none'; 5 | e2eTestRunner: 'cypress' | 'none'; 6 | tags?: string; 7 | template: 'blank' | 'list' | 'sidemenu' | 'tabs'; 8 | capacitor: boolean; 9 | skipFormat: boolean; 10 | standaloneConfig?: boolean; 11 | bundler?: 'webpack' | 'vite'; 12 | } 13 | 14 | export interface NormalizedSchema extends ApplicationGeneratorSchema { 15 | appName: string; 16 | appProjectName: string; 17 | appProjectRoot: string; 18 | } 19 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base-standalone/src/styles.scss.template: -------------------------------------------------------------------------------- 1 | /* 2 | * App Global CSS 3 | * ---------------------------------------------------------------------------- 4 | * Put style rules here that you want to apply globally. These styles are for 5 | * the entire app and not just one component. Additionally, this file can be 6 | * used as an entry point to import other CSS/Sass files to be included in the 7 | * output CSS. 8 | * For more information on global stylesheets, visit the documentation: 9 | * https://ionicframework.com/docs/layout/global-stylesheets 10 | */ 11 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/src/manifest.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "<%= className %>", 3 | "name": "<%= className %>", 4 | "icons": [ 5 | { 6 | "src": "assets/icon/favicon.png", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "assets/icon/icon.png", 12 | "type": "image/png", 13 | "sizes": "512x512", 14 | "purpose": "maskable" 15 | } 16 | ], 17 | "start_url": ".", 18 | "display": "standalone", 19 | "theme_color": "#ffffff", 20 | "background_color": "#ffffff" 21 | } 22 | -------------------------------------------------------------------------------- /e2e/ionic-angular-e2e/eslint.config.js: -------------------------------------------------------------------------------- 1 | const baseConfig = require('../../eslint.config.js'); 2 | module.exports = [ 3 | ...baseConfig, 4 | { 5 | files: [ 6 | 'e2e/ionic-angular-e2e/**/*.ts', 7 | 'e2e/ionic-angular-e2e/**/*.tsx', 8 | 'e2e/ionic-angular-e2e/**/*.js', 9 | 'e2e/ionic-angular-e2e/**/*.jsx', 10 | ], 11 | rules: {}, 12 | }, 13 | { 14 | files: ['e2e/ionic-angular-e2e/**/*.ts', 'e2e/ionic-angular-e2e/**/*.tsx'], 15 | rules: {}, 16 | }, 17 | { 18 | files: ['e2e/ionic-angular-e2e/**/*.js', 'e2e/ionic-angular-e2e/**/*.jsx'], 19 | rules: {}, 20 | }, 21 | ]; 22 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/schema.d.ts: -------------------------------------------------------------------------------- 1 | import { E2eTestRunner, UnitTestRunner } from '@nx/angular'; 2 | 3 | export interface ApplicationGeneratorSchema { 4 | name: string; 5 | directory?: string; 6 | unitTestRunner: UnitTestRunner; 7 | e2eTestRunner: E2eTestRunner; 8 | tags?: string; 9 | template: string; 10 | capacitor: boolean; 11 | skipFormat: boolean; 12 | standalone?: boolean; 13 | } 14 | 15 | export interface NormalizedSchema extends ApplicationGeneratorSchema { 16 | appName: string; 17 | prefix: string; 18 | appProjectName: string; 19 | appProjectRoot: string; 20 | } 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/home/home.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { IonicModule } from '@ionic/angular'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { HomePage } from './home.page'; 6 | 7 | import { HomePageRoutingModule } from './home-routing.module'; 8 | 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | FormsModule, 14 | IonicModule, 15 | HomePageRoutingModule 16 | ], 17 | declarations: [HomePage] 18 | }) 19 | export class HomePageModule {} 20 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tabs/tabs.module.ts.template: -------------------------------------------------------------------------------- 1 | import { IonicModule } from '@ionic/angular'; 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { FormsModule } from '@angular/forms'; 5 | 6 | import { TabsPageRoutingModule } from './tabs-routing.module'; 7 | 8 | import { TabsPage } from './tabs.page'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | IonicModule, 13 | CommonModule, 14 | FormsModule, 15 | TabsPageRoutingModule 16 | ], 17 | declarations: [TabsPage] 18 | }) 19 | export class TabsPageModule {} 20 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/message/message.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { RouterModule } from '@angular/router'; 5 | 6 | import { IonicModule } from '@ionic/angular'; 7 | 8 | import { MessageComponent } from './message.component'; 9 | 10 | @NgModule({ 11 | imports: [ CommonModule, FormsModule, IonicModule, RouterModule], 12 | declarations: [MessageComponent], 13 | exports: [MessageComponent] 14 | }) 15 | export class MessageComponentModule {} 16 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/explore-container/explore-container.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule } from '@angular/forms'; 4 | 5 | import { IonicModule } from '@ionic/angular'; 6 | 7 | import { ExploreContainerComponent } from './explore-container.component'; 8 | 9 | @NgModule({ 10 | imports: [ CommonModule, FormsModule, IonicModule], 11 | declarations: [ExploreContainerComponent], 12 | exports: [ExploreContainerComponent] 13 | }) 14 | export class ExploreContainerComponentModule {} 15 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/blank/src/components/ExploreContainer.tsx.template: -------------------------------------------------------------------------------- 1 | import './ExploreContainer.css'; 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-empty-interface 4 | interface ContainerProps { } 5 | 6 | const ExploreContainer: React.FC = () => { 7 | return ( 8 |
9 | Ready to create an app? 10 |

Start with Ionic UI Components

11 |
12 | ); 13 | }; 14 | 15 | export default ExploreContainer; 16 | -------------------------------------------------------------------------------- /packages/ionic-angular/README.md: -------------------------------------------------------------------------------- 1 | # @nxext/ionic-angular 2 | 3 | [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) 4 | 5 | An Nx plugin for developing [Ionic](https://ionicframework.com/docs) Angular applications and libraries. 6 | 7 | For more complete documentation, visit [nxext.github.io](https://nxext.github.io/nx-extensions-ionic/docs/ionic-angular/overview.html). 8 | 9 | ## Usage 10 | 11 | Visit the official [Getting Started](https://nxext.github.io/nx-extensions-ionic/docs/ionic-angular/getting-started.html) documentation. 12 | -------------------------------------------------------------------------------- /packages/ionic-angular/generators.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "name": "Nxext Ionic Angular", 4 | "version": "0.0.1", 5 | "generators": { 6 | "application": { 7 | "factory": "./src/generators/application/generator", 8 | "schema": "./src/generators/application/schema.json", 9 | "aliases": ["app"], 10 | "description": "Create an Ionic Angular application." 11 | }, 12 | "page": { 13 | "factory": "./src/generators/page/generator", 14 | "schema": "./src/generators/page/schema.json", 15 | "description": "Generate an Ionic page component" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/capacitor/generators.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "name": "nxextCapacitor", 4 | "version": "0.0.1", 5 | "generators": { 6 | "capacitor-project": { 7 | "factory": "./src/generators/capacitor-project/generator", 8 | "schema": "./src/generators/capacitor-project/schema.json", 9 | "description": "Add a Capacitor project" 10 | }, 11 | "application": { 12 | "factory": "./src/generators/application/generator", 13 | "schema": "./src/generators/application/schema.json", 14 | "description": "application generator", 15 | "aliases": ["app"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/folder/folder.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule } from '@angular/forms'; 4 | 5 | import { IonicModule } from '@ionic/angular'; 6 | 7 | import { FolderPageRoutingModule } from './folder-routing.module'; 8 | 9 | import { FolderPage } from './folder.page'; 10 | 11 | @NgModule({ 12 | imports: [ 13 | CommonModule, 14 | FormsModule, 15 | IonicModule, 16 | FolderPageRoutingModule 17 | ], 18 | declarations: [FolderPage] 19 | }) 20 | export class FolderPageModule {} 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/app-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; 3 | 4 | const routes: Routes = [ 5 | { 6 | path: 'home', 7 | loadChildren: () => import('./home/home.module').then( m => m.HomePageModule) 8 | }, 9 | { 10 | path: '', 11 | redirectTo: 'home', 12 | pathMatch: 'full' 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) 19 | ], 20 | exports: [RouterModule] 21 | }) 22 | export class AppRoutingModule { } 23 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/folder/folder.page.ts.template: -------------------------------------------------------------------------------- 1 | 2 | import { Component, OnInit } from '@angular/core'; 3 | import { ActivatedRoute } from '@angular/router'; 4 | 5 | @Component({ 6 | selector: '<%= prefix %>-folder', 7 | templateUrl: './folder.page.html', 8 | styleUrls: ['./folder.page.scss'], 9 | }) 10 | export class FolderPage implements OnInit { 11 | public folder!: string; 12 | 13 | constructor(private activatedRoute: ActivatedRoute) { } 14 | 15 | ngOnInit() { 16 | const id = this.activatedRoute.snapshot.paramMap.get('id'); 17 | 18 | if (id) { 19 | this.folder = id; 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/lib/add-capacitor.ts: -------------------------------------------------------------------------------- 1 | import { Tree } from '@nx/devkit'; 2 | import { capacitorProjectGenerator } from '@nxext/capacitor'; 3 | import { NormalizedSchema } from '../schema'; 4 | 5 | export async function addCapacitor(host: Tree, options: NormalizedSchema) { 6 | if (options.capacitor) { 7 | return await capacitorProjectGenerator(host, { 8 | project: options.appProjectName, 9 | appName: options.appName, 10 | appId: 'io.ionic.starter', 11 | skipFormat: options.skipFormat, 12 | }); 13 | } else { 14 | // eslint-disable-next-line @typescript-eslint/no-empty-function 15 | return () => {}; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/lib/add-dependencies.ts: -------------------------------------------------------------------------------- 1 | import { addDependenciesToPackageJson, Tree } from '@nx/devkit'; 2 | import { 3 | ionicAngularVersion, 4 | ioniconsVersion, 5 | capacitorPluginVersion, 6 | } from '../../../utils/versions'; 7 | 8 | export function addDependencies(host: Tree) { 9 | return addDependenciesToPackageJson( 10 | host, 11 | { 12 | '@ionic/angular': ionicAngularVersion, 13 | ionicons: ioniconsVersion, 14 | '@capacitor/haptics': capacitorPluginVersion, 15 | '@capacitor/keyboard': capacitorPluginVersion, 16 | '@capacitor/status-bar': capacitorPluginVersion, 17 | }, 18 | {} 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/message/message.component.ts.template: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core'; 2 | import { Platform } from '@ionic/angular'; 3 | import { Message } from '../services/data.service'; 4 | 5 | @Component({ 6 | selector: '<%= prefix %>-message', 7 | templateUrl: './message.component.html', 8 | styleUrls: ['./message.component.scss'], 9 | changeDetection: ChangeDetectionStrategy.OnPush, 10 | }) 11 | export class MessageComponent { 12 | private platform = inject(Platform); 13 | @Input() message?: Message; 14 | isIos() { 15 | return this.platform.is('ios') 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/view-message/view-message.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { ViewMessagePage } from './view-message.page'; 5 | 6 | import { IonicModule } from '@ionic/angular'; 7 | 8 | import { ViewMessagePageRoutingModule } from './view-message-routing.module'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | FormsModule, 14 | IonicModule, 15 | ViewMessagePageRoutingModule 16 | ], 17 | declarations: [ViewMessagePage] 18 | }) 19 | export class ViewMessagePageModule {} 20 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/files/__name__.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule } from '@angular/forms'; 4 | 5 | import { IonicModule } from '@ionic/angular'; 6 | 7 | import { <%= className %>PageRoutingModule } from './<%= fileName %>-routing.module'; 8 | 9 | import { <%= className %>Page } from './<%= fileName %>.page'; 10 | 11 | @NgModule({ 12 | imports: [ 13 | CommonModule, 14 | FormsModule, 15 | IonicModule, 16 | <%= className %>PageRoutingModule 17 | ], 18 | declarations: [<%= className %>Page] 19 | }) 20 | export class <%= className %>PageModule {} 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/app-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; 3 | 4 | const routes: Routes = [ 5 | { 6 | path: '', 7 | redirectTo: 'folder/Inbox', 8 | pathMatch: 'full' 9 | }, 10 | { 11 | path: 'folder/:id', 12 | loadChildren: () => import('./folder/folder.module').then( m => m.FolderPageModule) 13 | } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) 19 | ], 20 | exports: [RouterModule] 21 | }) 22 | export class AppRoutingModule {} 23 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tabs/tabs.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Tab 1 7 | 8 | 9 | 10 | 11 | Tab 2 12 | 13 | 14 | 15 | 16 | Tab 3 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/ionic-react/generators.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "name": "IonicReact", 4 | "version": "0.0.1", 5 | "generators": { 6 | "application": { 7 | "factory": "./src/generators/application/generator", 8 | "schema": "./src/generators/application/schema.json", 9 | "aliases": ["app"], 10 | "description": "Create an Ionic React application." 11 | } 12 | }, 13 | "schematics": { 14 | "application": { 15 | "factory": "./src/generators/application/generator", 16 | "schema": "./src/generators/application/schema.json", 17 | "aliases": ["app"], 18 | "description": "Create an Ionic React application." 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /e2e/capacitor-e2e/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "capacitor-e2e", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "projectType": "application", 5 | "sourceRoot": "e2e/capacitor-e2e/src", 6 | "targets": { 7 | "e2e": { 8 | "executor": "@nx/jest:jest", 9 | "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], 10 | "options": { 11 | "jestConfig": "e2e/capacitor-e2e/jest.config.ts", 12 | "runInBand": true 13 | }, 14 | "dependsOn": ["^build"] 15 | }, 16 | "lint": { 17 | "executor": "@nx/eslint:lint", 18 | "outputs": ["{options.outputFile}"] 19 | } 20 | }, 21 | "tags": [], 22 | "implicitDependencies": ["capacitor"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/capacitor/migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "generators": {}, 3 | "packageJsonUpdates": { 4 | "18.0.4": { 5 | "version": "18.0.4", 6 | "packages": { 7 | "@capacitor/core": { 8 | "version": "^5.7.0", 9 | "alwaysAddToPackageJson": true 10 | }, 11 | "@capacitor/cli": { 12 | "version": "^5.7.0", 13 | "alwaysAddToPackageJson": true 14 | }, 15 | "@capacitor/ios": { 16 | "version": "^5.7.0", 17 | "alwaysAddToPackageJson": false 18 | }, 19 | "@capacitor/android": { 20 | "version": "^5.7.0", 21 | "alwaysAddToPackageJson": false 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/src/setupTests.ts.template: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | 7 | // Mock matchmedia 8 | window.matchMedia = window.matchMedia || function() { 9 | return { 10 | matches: false, 11 | // eslint-disable-next-line @typescript-eslint/no-empty-function 12 | addListener: function() {}, 13 | // eslint-disable-next-line @typescript-eslint/no-empty-function 14 | removeListener: function() {} 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /docs/guide/articles.md: -------------------------------------------------------------------------------- 1 | # Stencil 2 | 3 | | Article | 4 | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 5 | | [Building React and Angular Component Libraries with Stencil and Nx](https://ionicframework.com/blog/building-react-and-angular-component-libraries-with-stencil-and-nx/) | 6 | | [Framework agnostic component libraries with StencilJs and Nx](https://dev.to/dominikpieper/framework-agnostic-component-libraries-with-stenciljs-and-nx-8mb) | 7 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/app/app.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { RouteReuseStrategy } from '@angular/router'; 4 | 5 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; 6 | 7 | import { AppRoutingModule } from './app-routing.module'; 8 | import { AppComponent } from './app.component'; 9 | 10 | @NgModule({ 11 | declarations: [AppComponent], 12 | imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], 13 | providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], 14 | bootstrap: [AppComponent], 15 | }) 16 | export class AppModule {} 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/app.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { RouteReuseStrategy } from '@angular/router'; 4 | 5 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; 6 | 7 | import { AppRoutingModule } from './app-routing.module'; 8 | import { AppComponent } from './app.component'; 9 | 10 | @NgModule({ 11 | declarations: [AppComponent], 12 | imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], 13 | providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], 14 | bootstrap: [AppComponent], 15 | }) 16 | export class AppModule {} 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/app.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { RouteReuseStrategy } from '@angular/router'; 4 | 5 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; 6 | 7 | import { AppComponent } from './app.component'; 8 | import { AppRoutingModule } from './app-routing.module'; 9 | 10 | @NgModule({ 11 | declarations: [AppComponent], 12 | imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], 13 | providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], 14 | bootstrap: [AppComponent], 15 | }) 16 | export class AppModule {} 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/home/home.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { IonicModule } from '@ionic/angular'; 4 | import { FormsModule } from '@angular/forms'; 5 | 6 | import { HomePage } from './home.page'; 7 | import { HomePageRoutingModule } from './home-routing.module'; 8 | import { MessageComponentModule } from '../message/message.module'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | FormsModule, 14 | IonicModule, 15 | MessageComponentModule, 16 | HomePageRoutingModule 17 | ], 18 | declarations: [HomePage] 19 | }) 20 | export class HomePageModule {} 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/app.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { RouteReuseStrategy } from '@angular/router'; 4 | 5 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; 6 | 7 | import { AppRoutingModule } from './app-routing.module'; 8 | import { AppComponent } from './app.component'; 9 | 10 | @NgModule({ 11 | declarations: [AppComponent], 12 | imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], 13 | providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], 14 | bootstrap: [AppComponent], 15 | }) 16 | export class AppModule {} 17 | -------------------------------------------------------------------------------- /e2e/ionic-react-e2e/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-react-e2e", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "projectType": "application", 5 | "sourceRoot": "e2e/ionic-react-e2e/src", 6 | "targets": { 7 | "e2e": { 8 | "executor": "@nx/jest:jest", 9 | "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], 10 | "options": { 11 | "jestConfig": "e2e/ionic-react-e2e/jest.config.ts", 12 | "runInBand": true 13 | }, 14 | "dependsOn": ["^build"] 15 | }, 16 | "lint": { 17 | "executor": "@nx/eslint:lint", 18 | "outputs": ["{options.outputFile}"] 19 | } 20 | }, 21 | "tags": [], 22 | "implicitDependencies": ["ionic-react"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/app/app.component.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { TestBed } from '@angular/core/testing'; 3 | 4 | import { AppComponent } from './app.component'; 5 | 6 | describe('AppComponent', () => { 7 | 8 | beforeEach(async () => { 9 | await TestBed.configureTestingModule({ 10 | declarations: [AppComponent], 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | }).compileComponents(); 13 | }); 14 | 15 | it('should create the app', () => { 16 | const fixture = TestBed.createComponent(AppComponent); 17 | const app = fixture.componentInstance; 18 | expect(app).toBeTruthy(); 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/app.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { RouteReuseStrategy } from '@angular/router'; 4 | 5 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; 6 | 7 | import { AppComponent } from './app.component'; 8 | import { AppRoutingModule } from './app-routing.module'; 9 | 10 | @NgModule({ 11 | declarations: [AppComponent], 12 | imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], 13 | providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], 14 | bootstrap: [AppComponent], 15 | }) 16 | export class AppModule {} 17 | -------------------------------------------------------------------------------- /e2e/ionic-angular-e2e/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-angular-e2e", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "projectType": "application", 5 | "sourceRoot": "e2e/ionic-angular-e2e/src", 6 | "targets": { 7 | "e2e": { 8 | "executor": "@nx/jest:jest", 9 | "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], 10 | "options": { 11 | "jestConfig": "e2e/ionic-angular-e2e/jest.config.ts", 12 | "runInBand": true 13 | }, 14 | "dependsOn": ["^build"] 15 | }, 16 | "lint": { 17 | "executor": "@nx/eslint:lint", 18 | "outputs": ["{options.outputFile}"] 19 | } 20 | }, 21 | "tags": [], 22 | "implicitDependencies": ["ionic-angular"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base-standalone/src/app/app.component.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { TestBed } from '@angular/core/testing'; 3 | 4 | import { AppComponent } from './app.component'; 5 | 6 | describe('AppComponent', () => { 7 | 8 | beforeEach(async () => { 9 | await TestBed.configureTestingModule({ 10 | declarations: [AppComponent], 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | }).compileComponents(); 13 | }); 14 | 15 | it('should create the app', () => { 16 | const fixture = TestBed.createComponent(AppComponent); 17 | const app = fixture.componentInstance; 18 | expect(app).toBeTruthy(); 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/home/home.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { RefresherCustomEvent } from '@ionic/angular'; 3 | 4 | import { DataService, Message } from '../services/data.service'; 5 | 6 | @Component({ 7 | selector: '<%= prefix %>-home', 8 | templateUrl: 'home.page.html', 9 | styleUrls: ['home.page.scss'], 10 | }) 11 | export class HomePage { 12 | private data = inject(DataService); 13 | constructor() {} 14 | 15 | refresh(ev: any) { 16 | setTimeout(() => { 17 | (ev as RefresherCustomEvent).detail.complete(); 18 | }, 3000); 19 | } 20 | 21 | getMessages(): Message[] { 22 | return this.data.getMessages(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/blank/src/app/home/home.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Blank 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Blank 13 | 14 | 15 | 16 |
17 |

Welcome <%= appProjectName %>!

18 | Ready to create an app? 19 |

Start with Ionic UI Components

20 |
21 |
22 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab1/tab1.module.ts.template: -------------------------------------------------------------------------------- 1 | import { IonicModule } from '@ionic/angular'; 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { Tab1Page } from './tab1.page'; 6 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 7 | 8 | import { Tab1PageRoutingModule } from './tab1-routing.module'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | IonicModule, 13 | CommonModule, 14 | FormsModule, 15 | ExploreContainerComponentModule, 16 | Tab1PageRoutingModule 17 | ], 18 | declarations: [Tab1Page] 19 | }) 20 | export class Tab1PageModule {} 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab2/tab2.module.ts.template: -------------------------------------------------------------------------------- 1 | import { IonicModule } from '@ionic/angular'; 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { Tab2Page } from './tab2.page'; 6 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 7 | 8 | import { Tab2PageRoutingModule } from './tab2-routing.module'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | IonicModule, 13 | CommonModule, 14 | FormsModule, 15 | ExploreContainerComponentModule, 16 | Tab2PageRoutingModule 17 | ], 18 | declarations: [Tab2Page] 19 | }) 20 | export class Tab2PageModule {} 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab3/tab3.module.ts.template: -------------------------------------------------------------------------------- 1 | import { IonicModule } from '@ionic/angular'; 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { Tab3Page } from './tab3.page'; 6 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 7 | 8 | import { Tab3PageRoutingModule } from './tab3-routing.module'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | IonicModule, 13 | CommonModule, 14 | FormsModule, 15 | ExploreContainerComponentModule, 16 | Tab3PageRoutingModule 17 | ], 18 | declarations: [Tab3Page] 19 | }) 20 | export class Tab3PageModule {} 21 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/view-message/view-message.page.scss.template: -------------------------------------------------------------------------------- 1 | ion-item { 2 | --inner-padding-end: 0; 3 | --background: transparent; 4 | } 5 | 6 | ion-label { 7 | margin-top: 12px; 8 | margin-bottom: 12px; 9 | } 10 | 11 | ion-item h2 { 12 | font-weight: 600; 13 | } 14 | 15 | ion-item .date { 16 | float: right; 17 | align-items: center; 18 | display: flex; 19 | } 20 | 21 | ion-item ion-icon { 22 | font-size: 42px; 23 | margin-right: 8px; 24 | } 25 | 26 | ion-item ion-note { 27 | font-size: 15px; 28 | margin-right: 12px; 29 | font-weight: normal; 30 | } 31 | 32 | h1 { 33 | margin: 0; 34 | font-weight: bold; 35 | font-size: 22px; 36 | } 37 | 38 | p { 39 | line-height: 22px; 40 | } 41 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/generator.spec.ts: -------------------------------------------------------------------------------- 1 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; 2 | import { Tree } from '@nx/devkit'; 3 | 4 | import generator from './generator'; 5 | import { AppGeneratorSchema } from './schema'; 6 | 7 | describe('app generator', () => { 8 | let tree: Tree; 9 | const options: AppGeneratorSchema = { 10 | name: 'test', 11 | appId: 'com.test.app', 12 | unitTestRunner: 'vitest', 13 | }; 14 | 15 | beforeEach(() => { 16 | tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); 17 | }); 18 | 19 | it('should run successfully', async () => { 20 | await generator(tree, options); 21 | 22 | expect(tree.exists('apps/test/src/main.ts')).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /docs/docs/ionic-react/overview.md: -------------------------------------------------------------------------------- 1 | [Ionic](https://ionicframework.com/docs/components) is a collection of high-quality components for developing cross-platform applications. When paired with [Capacitor](https://capacitorjs.com/docs), developers can make high-quality cross-platform applications with web technology. 2 | 3 | The goal of `@nxext/ionic-react` is to enabled developers to create and maintain cross-platform applications in an Nx monorepo with Ionic and React. The ability to develop cross-platform applications from a single codebase along with a monorepo that enables easy and effective sharing can be a powerful combination. 4 | 5 | Updates to `@nxext/ionic-react` will include migrations that will update the dependencies included with this plugin, as well as any code migrations if possible. 6 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/files/tsconfig.json__tmpl__: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "<%= rootTsConfigPath %>", 3 | "files": [], 4 | "compilerOptions": { 5 | "target": "ESNext", 6 | "useDefineForClassFields": true, 7 | "module": "ESNext", 8 | "lib": ["ESNext", "DOM"], 9 | "moduleResolution": "Node", 10 | "strict": true, 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "esModuleInterop": true, 14 | "noEmit": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "noImplicitReturns": true, 18 | "skipLibCheck": true, 19 | "types": ["vite/client"] 20 | }, 21 | "include": ["src"], 22 | "references": [ 23 | { 24 | "path": "./tsconfig.app.json" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/lib/change-react-router.ts: -------------------------------------------------------------------------------- 1 | import { 2 | addDependenciesToPackageJson, 3 | removeDependenciesFromPackageJson, 4 | Tree, 5 | runTasksInSerial, 6 | } from '@nx/devkit'; 7 | import { 8 | reactRouterDomVersion, 9 | typesReactRouterDomVersion, 10 | } from '../../../utils/versions'; 11 | 12 | export function changeReactRouter(host: Tree) { 13 | const removeTask = removeDependenciesFromPackageJson( 14 | host, 15 | ['react-router-dom'], 16 | [] 17 | ); 18 | 19 | const routerTask = addDependenciesToPackageJson( 20 | host, 21 | { 'react-router-dom': reactRouterDomVersion }, 22 | { '@types/react-router-dom': typesReactRouterDomVersion } 23 | ); 24 | 25 | return runTasksInSerial(removeTask, routerTask); 26 | } 27 | -------------------------------------------------------------------------------- /docs/docs/ionic-angular/overview.md: -------------------------------------------------------------------------------- 1 | [Ionic](https://ionicframework.com/docs/components) is a collection of high-quality components for developing cross-platform applications. When paired with [Capacitor](https://capacitorjs.com/docs), developers can make high-quality cross-platform applications with web technology. 2 | 3 | The goal of `@nxext/ionic-angular` is to enabled developers to create and maintain cross-platform applications in an Nx monorepo with Ionic and Angular. The ability to develop cross-platform applications from a single codebase along with a monorepo that enables easy and effective sharing can be a powerful combination. 4 | 5 | Updates to `@nxext/ionic-angular` will include migrations that will update the dependencies included with this plugin, as well as any code migrations if possible. 6 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/home/home.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Inbox 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Inbox 18 | 19 | 20 | 21 | 22 | 23 | <<%= prefix %>-message *ngFor="let message of getMessages()" [message]="message">-message> 24 | 25 | 26 | -------------------------------------------------------------------------------- /jest.preset.js: -------------------------------------------------------------------------------- 1 | const nxPreset = require('@nx/jest/preset').default; 2 | module.exports = { 3 | ...nxPreset, 4 | testTimeout: 500000, 5 | /* TODO: Update to latest Jest snapshotFormat 6 | * By default Nx has kept the older style of Jest Snapshot formats 7 | * to prevent breaking of any existing tests with snapshots. 8 | * It's recommend you update to the latest format. 9 | * You can do this by removing snapshotFormat property 10 | * and running tests with --update-snapshot flag. 11 | * Example: "nx affected --targets= --update-snapshot" 12 | * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format 13 | */ 14 | snapshotFormat: { escapeString: true, printBasicPrototype: true }, 15 | setupFiles: ['/../../tools/scripts/mock-project-graph.ts'], 16 | }; 17 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/folder/folder.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ folder }} 7 | 8 | 9 | 10 | 11 | 12 | 13 | {{ folder }} 14 | 15 | 16 | 17 |
18 | {{ folder }} 19 |

Explore UI Components

20 |
21 |
22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 Feature Request" 3 | about: Suggest an idea for this project 4 | title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: ' 5 | labels: feature request 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/blank/src/pages/Home.tsx.template: -------------------------------------------------------------------------------- 1 | import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; 2 | import ExploreContainer from '../components/ExploreContainer'; 3 | import './Home.css'; 4 | 5 | const Home: React.FC = () => { 6 | return ( 7 | 8 | 9 | 10 | Blank 11 | 12 | 13 | 14 | 15 | 16 | Blank 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default Home; 26 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/lib/normalize-options.ts: -------------------------------------------------------------------------------- 1 | import { 2 | joinPathFragments, 3 | offsetFromRoot, 4 | readProjectConfiguration, 5 | Tree, 6 | } from '@nx/devkit'; 7 | import { CapacitorGeneratorSchema, NormalizedSchema } from '../schema'; 8 | 9 | export function normalizeOptions( 10 | host: Tree, 11 | options: CapacitorGeneratorSchema 12 | ): NormalizedSchema { 13 | const appName = options.appName ? options.appName : options.project; 14 | const { root } = readProjectConfiguration(host, options.project); 15 | const webDir = options.webDir 16 | ? options.webDir 17 | : joinPathFragments(`dist/${root}`); 18 | 19 | return { 20 | ...options, 21 | appName, 22 | webDir, 23 | projectRoot: root, 24 | pathToRoot: offsetFromRoot(root), 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/lib/add-capacitor-config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | generateFiles, 3 | joinPathFragments, 4 | names, 5 | normalizePath, 6 | offsetFromRoot, 7 | Tree, 8 | } from '@nx/devkit'; 9 | import { NormalizedSchema } from '../schema'; 10 | 11 | export function addCapacitorConfig(host: Tree, options: NormalizedSchema) { 12 | const templateOptions = { 13 | ...options, 14 | ...names(options.project), 15 | offsetFromRoot: offsetFromRoot(options.projectRoot), 16 | webDir: normalizePath( 17 | joinPathFragments(options.pathToRoot, options.webDir) 18 | ), 19 | template: '', 20 | }; 21 | 22 | generateFiles( 23 | host, 24 | normalizePath(__dirname + '/../files/capacitor-config'), 25 | options.projectRoot, 26 | templateOptions 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/lib/update-project-gitignore.ts: -------------------------------------------------------------------------------- 1 | import { Tree } from '@nx/devkit'; 2 | import { NormalizedSchema } from '../schema'; 3 | import ignore from 'ignore'; 4 | 5 | export function updateProjectGitignore(host: Tree, options: NormalizedSchema) { 6 | if (!host.exists(`${options.projectRoot}/.gitignore`)) { 7 | return host.write(`${options.projectRoot}/.gitignore`, '/node_modules\n'); 8 | } 9 | 10 | const ig = ignore(); 11 | ig.add(host.read(`${options.projectRoot}/.gitignore`).toString()); 12 | 13 | if (!ig.ignores('node_modules')) { 14 | const content = `${host 15 | .read(`${options.projectRoot}/.gitignore`) 16 | .toString('utf-8') 17 | .trimRight()}\n/node_modules\n`; 18 | host.write(`${options.projectRoot}/.gitignore`, content); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/pages/Tab1.tsx.template: -------------------------------------------------------------------------------- 1 | import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; 2 | import ExploreContainer from '../components/ExploreContainer'; 3 | import './Tab1.css'; 4 | 5 | const Tab1: React.FC = () => { 6 | return ( 7 | 8 | 9 | 10 | Tab 1 11 | 12 | 13 | 14 | 15 | 16 | Tab 1 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default Tab1; 26 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/pages/Tab2.tsx.template: -------------------------------------------------------------------------------- 1 | import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; 2 | import ExploreContainer from '../components/ExploreContainer'; 3 | import './Tab2.css'; 4 | 5 | const Tab2: React.FC = () => { 6 | return ( 7 | 8 | 9 | 10 | Tab 2 11 | 12 | 13 | 14 | 15 | 16 | Tab 2 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default Tab2; 26 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/tabs/src/pages/Tab3.tsx.template: -------------------------------------------------------------------------------- 1 | import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; 2 | import ExploreContainer from '../components/ExploreContainer'; 3 | import './Tab3.css'; 4 | 5 | const Tab3: React.FC = () => { 6 | return ( 7 | 8 | 9 | 10 | Tab 3 11 | 12 | 13 | 14 | 15 | 16 | Tab 3 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default Tab3; 26 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/app-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; 3 | 4 | const routes: Routes = [ 5 | { 6 | path: 'home', 7 | loadChildren: () => import('./home/home.module').then( m => m.HomePageModule) 8 | }, 9 | { 10 | path: 'message/:id', 11 | loadChildren: () => import('./view-message/view-message.module').then( m => m.ViewMessagePageModule) 12 | }, 13 | { 14 | path: '', 15 | redirectTo: 'home', 16 | pathMatch: 'full' 17 | }, 18 | ]; 19 | 20 | @NgModule({ 21 | imports: [ 22 | RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) 23 | ], 24 | exports: [RouterModule] 25 | }) 26 | export class AppRoutingModule { } 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/app.component.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | @Component({ 3 | selector: '<%= prefix %>-root', 4 | templateUrl: 'app.component.html', 5 | styleUrls: ['app.component.scss'], 6 | }) 7 | export class AppComponent { 8 | public appPages = [ 9 | { title: 'Inbox', url: '/folder/inbox', icon: 'mail' }, 10 | { title: 'Outbox', url: '/folder/outbox', icon: 'paper-plane' }, 11 | { title: 'Favorites', url: '/folder/favorites', icon: 'heart' }, 12 | { title: 'Archived', url: '/folder/archived', icon: 'archive' }, 13 | { title: 'Trash', url: '/folder/trash', icon: 'trash' }, 14 | { title: 'Spam', url: '/folder/spam', icon: 'warning' }, 15 | ]; 16 | public labels = ['Family', 'Friends', 'Notes', 'Work', 'Travel', 'Reminders']; 17 | constructor() {} 18 | } 19 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tabs/tabs.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 3 | 4 | import { TabsPage } from './tabs.page'; 5 | 6 | describe('TabsPage', () => { 7 | let component: TabsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async () => { 11 | await TestBed.configureTestingModule({ 12 | declarations: [TabsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | }); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(TabsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tabs/tabs.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 3 | 4 | import { TabsPage } from './tabs.page'; 5 | 6 | describe('TabsPage', () => { 7 | let component: TabsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async () => { 11 | await TestBed.configureTestingModule({ 12 | declarations: [TabsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | }); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(TabsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/list/src/pages/ViewMessage.css.template: -------------------------------------------------------------------------------- 1 | #view-message-page ion-item { 2 | --inner-padding-end: 0; 3 | --background: transparent; 4 | } 5 | 6 | #view-message-page ion-label { 7 | margin-top: 12px; 8 | margin-bottom: 12px; 9 | } 10 | 11 | #view-message-page ion-item h2 { 12 | font-weight: 600; 13 | } 14 | 15 | #view-message-page ion-item .date { 16 | float: right; 17 | align-items: center; 18 | display: flex; 19 | } 20 | 21 | #view-message-page ion-item ion-icon { 22 | font-size: 42px; 23 | margin-right: 8px; 24 | } 25 | 26 | #view-message-page ion-item ion-note { 27 | font-size: 15px; 28 | margin-right: 12px; 29 | font-weight: normal; 30 | } 31 | 32 | #view-message-page h1 { 33 | margin: 0; 34 | font-weight: bold; 35 | font-size: 22px; 36 | } 37 | 38 | #view-message-page p { 39 | line-height: 22px; 40 | } -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "importHelpers": true, 11 | "target": "es2015", 12 | "module": "esnext", 13 | "typeRoots": ["node_modules/@types"], 14 | "lib": ["es2017", "dom", "es2020"], 15 | "skipLibCheck": true, 16 | "skipDefaultLibCheck": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@nxext/capacitor": ["packages/capacitor/src/index.ts"], 20 | "@nxext/e2e-utils": ["e2e/utils/index.ts"], 21 | "@nxext/ionic-angular": ["packages/ionic-angular/src/index.ts"], 22 | "@nxext/ionic-react": ["packages/ionic-react/src/index.ts"] 23 | } 24 | }, 25 | "exclude": ["node_modules", "tmp"] 26 | } 27 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "$id": "App", 4 | "title": "", 5 | "type": "object", 6 | "properties": { 7 | "name": { 8 | "type": "string", 9 | "description": "", 10 | "$default": { 11 | "$source": "argv", 12 | "index": 0 13 | }, 14 | "x-prompt": "What name would you like to use?" 15 | }, 16 | "unitTestRunner": { 17 | "type": "string", 18 | "enum": ["vitest", "none"], 19 | "description": "Test runner to use for unit tests.", 20 | "default": "vitest" 21 | }, 22 | "appId": { 23 | "type": "string", 24 | "description": "The app ID for the project.", 25 | "default": "io.ionic.starter", 26 | "x-prompt": "What app ID would you like to use?" 27 | } 28 | }, 29 | "required": ["name", "appId"] 30 | } 31 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/files/__name__.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { <%= className %>Page } from './<%= fileName %>.page'; 5 | 6 | describe('<%= className %>Page', () => { 7 | let component: <%= className %>Page; 8 | let fixture: ComponentFixture<<%= className %>Page>; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ <%= className %>Page ], 13 | imports: [IonicModule.forRoot()] 14 | }).compileComponents(); 15 | 16 | fixture = TestBed.createComponent(<%= className %>Page); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | })); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /tools/scripts/start-local-registry.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This script starts a local registry for e2e testing purposes. 3 | * It is meant to be called in jest's globalSetup. 4 | */ 5 | import { startLocalRegistry } from '@nx/js/plugins/jest/local-registry'; 6 | import { execFileSync } from 'child_process'; 7 | 8 | export default async () => { 9 | // local registry target to run 10 | const localRegistryTarget = 'nxext:local-registry'; 11 | // storage folder for the local registry 12 | const storage = './tmp/local-registry/storage'; 13 | 14 | global.stopLocalRegistry = await startLocalRegistry({ 15 | localRegistryTarget, 16 | storage, 17 | verbose: false, 18 | }); 19 | const nx = require.resolve('nx'); 20 | execFileSync( 21 | nx, 22 | ['run-many', '--targets', 'publish', '--ver', '999.99.99', '--tag', 'e2e'], 23 | { env: process.env, stdio: 'inherit' } 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/lib/add-angular.ts: -------------------------------------------------------------------------------- 1 | import { ensurePackage, NX_VERSION, Tree } from '@nx/devkit'; 2 | import { Linter } from '@nx/eslint'; 3 | import { ApplicationGeneratorSchema } from '../schema'; 4 | 5 | export async function addAngular( 6 | host: Tree, 7 | options: ApplicationGeneratorSchema 8 | ) { 9 | ensurePackage('@nx/angular', NX_VERSION); 10 | const { applicationGenerator } = await import('@nx/angular/generators'); 11 | return await applicationGenerator(host, { 12 | ...options, 13 | name: options.name, 14 | directory: options.directory, 15 | skipFormat: true, 16 | routing: true, 17 | style: 'scss', 18 | linter: Linter.EsLint, 19 | unitTestRunner: options.unitTestRunner, 20 | e2eTestRunner: options.e2eTestRunner, 21 | standalone: options.standalone, 22 | minimal: true, 23 | bundler: 'webpack', 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/page/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "$id": "Page", 4 | "title": "", 5 | "type": "object", 6 | "properties": { 7 | "project": { 8 | "type": "string", 9 | "description": "The name of the project.", 10 | "alias": "p", 11 | "$default": { 12 | "$source": "projectName" 13 | }, 14 | "x-prompt": "What is the name of the project for this page?" 15 | }, 16 | "name": { 17 | "type": "string", 18 | "description": "", 19 | "$default": { 20 | "$source": "argv", 21 | "index": 0 22 | }, 23 | "x-prompt": "What name would you like to use?" 24 | }, 25 | "directory": { 26 | "type": "string", 27 | "description": "A directory where the page is created", 28 | "alias": "d" 29 | } 30 | }, 31 | "required": ["project", "name"] 32 | } 33 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/lib/add-react.ts: -------------------------------------------------------------------------------- 1 | import { Tree, ensurePackage, NX_VERSION } from '@nx/devkit'; 2 | import { Linter } from '@nx/eslint'; 3 | import { ApplicationGeneratorSchema } from '../schema'; 4 | 5 | export async function addReact( 6 | host: Tree, 7 | options: ApplicationGeneratorSchema 8 | ) { 9 | ensurePackage('@nx/react', NX_VERSION); 10 | const { applicationGenerator } = await import('@nx/react'); 11 | return await applicationGenerator(host, { 12 | ...options, 13 | name: options.name, 14 | style: 'css', 15 | skipFormat: options.skipFormat, 16 | directory: options.directory, 17 | unitTestRunner: options.unitTestRunner, 18 | e2eTestRunner: options.e2eTestRunner, 19 | linter: Linter.EsLint, 20 | pascalCaseFiles: true, 21 | classComponent: false, 22 | routing: true, 23 | globalCss: true, 24 | bundler: options.bundler, 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/index.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ionic App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | <<%= prefix %>-root>-root> 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base-standalone/src/index.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ionic App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | <<%= prefix %>-root>-root> 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab1/tab1.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 5 | 6 | import { Tab1Page } from './tab1.page'; 7 | 8 | describe('Tab1Page', () => { 9 | let component: Tab1Page; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [Tab1Page], 15 | imports: [IonicModule.forRoot(), ExploreContainerComponentModule] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(Tab1Page); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab2/tab2.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 5 | 6 | import { Tab2Page } from './tab2.page'; 7 | 8 | describe('Tab2Page', () => { 9 | let component: Tab2Page; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [Tab2Page], 15 | imports: [IonicModule.forRoot(), ExploreContainerComponentModule] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(Tab2Page); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tab3/tab3.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 5 | 6 | import { Tab3Page } from './tab3.page'; 7 | 8 | describe('Tab3Page', () => { 9 | let component: Tab3Page; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [Tab3Page], 15 | imports: [IonicModule.forRoot(), ExploreContainerComponentModule] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(Tab3Page); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/message/message.component.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { RouterModule } from '@angular/router'; 3 | import { IonicModule } from '@ionic/angular'; 4 | 5 | import { MessageComponent } from './message.component'; 6 | 7 | describe('MessageComponent', () => { 8 | let component: MessageComponent; 9 | let fixture: ComponentFixture; 10 | 11 | beforeEach(async () => { 12 | await TestBed.configureTestingModule({ 13 | declarations: [MessageComponent], 14 | imports: [IonicModule.forRoot(), RouterModule.forRoot([])] 15 | }).compileComponents(); 16 | 17 | fixture = TestBed.createComponent(MessageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab1/tab1.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 5 | 6 | import { Tab1Page } from './tab1.page'; 7 | 8 | describe('Tab1Page', () => { 9 | let component: Tab1Page; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [Tab1Page], 15 | imports: [IonicModule.forRoot(), ExploreContainerComponentModule] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(Tab1Page); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab2/tab2.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 5 | 6 | import { Tab2Page } from './tab2.page'; 7 | 8 | describe('Tab2Page', () => { 9 | let component: Tab2Page; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [Tab2Page], 15 | imports: [IonicModule.forRoot(), ExploreContainerComponentModule] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(Tab2Page); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab3/tab3.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; 5 | 6 | import { Tab3Page } from './tab3.page'; 7 | 8 | describe('Tab3Page', () => { 9 | let component: Tab3Page; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [Tab3Page], 15 | imports: [IonicModule.forRoot(), ExploreContainerComponentModule] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(Tab3Page); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/explore-container/explore-container.component.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponent } from './explore-container.component'; 5 | 6 | describe('ExploreContainerComponent', () => { 7 | let component: ExploreContainerComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async () => { 11 | await TestBed.configureTestingModule({ 12 | declarations: [ExploreContainerComponent], 13 | imports: [IonicModule.forRoot()] 14 | }).compileComponents(); 15 | 16 | fixture = TestBed.createComponent(ExploreContainerComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/lib/normalize-options.ts: -------------------------------------------------------------------------------- 1 | import { getWorkspaceLayout, names, normalizePath, Tree } from '@nx/devkit'; 2 | import { ApplicationGeneratorSchema, NormalizedSchema } from '../schema'; 3 | 4 | export function normalizeOptions( 5 | host: Tree, 6 | options: ApplicationGeneratorSchema 7 | ): NormalizedSchema { 8 | const appName = options.name; 9 | 10 | const appDirectory = options.directory 11 | ? `${names(options.directory).fileName}/${names(options.name).fileName}` 12 | : names(options.name).fileName; 13 | 14 | const appProjectName = appDirectory.replace(new RegExp('/', 'g'), '-'); 15 | 16 | const { appsDir } = getWorkspaceLayout(host); 17 | const appProjectRoot = normalizePath(`${appsDir}/${appDirectory}`); 18 | 19 | return { 20 | ...options, 21 | appName, 22 | name: names(options.name).fileName, 23 | appProjectName, 24 | appProjectRoot, 25 | bundler: 'webpack', 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /docs/docs/capacitor/migrating-from-nxtend.md: -------------------------------------------------------------------------------- 1 | # Migrating from Nxtend to Nxext 2 | 3 | The Nxext Ionic plugins support Nx 14, while the Nxtend plugins support Nx 13. In order to migrate to Nxext you must first upgrade your workspace to Nx 14. If you are using npm 6+ you will need to `npm install --legacy-peer-deps` in order to get passed npm errors. Once the workspace has been updated, the Ionic plugins will not work until they have been migrated to Nxext. 4 | 5 | ## Install Nxext Package 6 | 7 | First, install the Nxext Capacitor package using your package manager of choice. 8 | 9 | ``` 10 | npm install -D @nxext/capacitor 11 | ``` 12 | 13 | ## Update Project Configurations 14 | 15 | Next, update all references to `@nxtend/capacitor` to `@nxext/capacitor` in your `workspace.json`, or any app-level `project.json` files. 16 | 17 | ## Remove Nxtend Package 18 | 19 | Finally, remove the Nxtend Capacitor package. 20 | 21 | ``` 22 | npm uninstall @nxtend/capacitor 23 | ``` 24 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/message/message.component.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { RouterModule } from '@angular/router'; 3 | import { IonicModule } from '@ionic/angular'; 4 | 5 | import { MessageComponent } from './message.component'; 6 | 7 | describe('MessageComponent', () => { 8 | let component: MessageComponent; 9 | let fixture: ComponentFixture; 10 | 11 | beforeEach(async () => { 12 | await TestBed.configureTestingModule({ 13 | declarations: [MessageComponent], 14 | imports: [IonicModule.forRoot(), RouterModule.forRoot([])] 15 | }).compileComponents(); 16 | 17 | fixture = TestBed.createComponent(MessageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/explore-container/explore-container.component.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | 4 | import { ExploreContainerComponent } from './explore-container.component'; 5 | 6 | describe('ExploreContainerComponent', () => { 7 | let component: ExploreContainerComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async () => { 11 | await TestBed.configureTestingModule({ 12 | declarations: [ExploreContainerComponent], 13 | imports: [IonicModule.forRoot()] 14 | }).compileComponents(); 15 | 16 | fixture = TestBed.createComponent(ExploreContainerComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.verdaccio/config.yml: -------------------------------------------------------------------------------- 1 | # path to a directory with all packages 2 | storage: ../tmp/local-registry/storage 3 | 4 | listen: localhost:4872 5 | 6 | auth: 7 | auth-memory: 8 | users: 9 | verdacciouser: 10 | name: verdacciouser 11 | password: passw0rd 12 | 13 | # a list of other known repositories we can talk to 14 | uplinks: 15 | npmjs: 16 | url: https://registry.npmjs.org/ 17 | max_fails: 100 18 | maxage: 30m 19 | fail_timeout: 10m 20 | timeout: 600s 21 | cache: false 22 | yarn: 23 | url: https://registry.yarnpkg.com 24 | max_fails: 100 25 | maxage: 30m 26 | fail_timeout: 10m 27 | timeout: 600s 28 | cache: false 29 | 30 | packages: 31 | '@*/*': 32 | access: $all 33 | publish: $all 34 | unpublish: $all 35 | proxy: npmjs 36 | 37 | '**': 38 | access: $all 39 | publish: $all 40 | unpublish: $all 41 | proxy: npmjs 42 | 43 | logs: 44 | - { type: stdout, format: pretty, level: warn } 45 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/home/home.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { RouterModule } from '@angular/router'; 3 | import { IonicModule } from '@ionic/angular'; 4 | 5 | import { MessageComponentModule } from '../message/message.module'; 6 | 7 | import { HomePage } from './home.page'; 8 | 9 | describe('HomePage', () => { 10 | let component: HomePage; 11 | let fixture: ComponentFixture; 12 | 13 | beforeEach(async () => { 14 | await TestBed.configureTestingModule({ 15 | declarations: [HomePage], 16 | imports: [IonicModule.forRoot(), MessageComponentModule, RouterModule.forRoot([])] 17 | }).compileComponents(); 18 | 19 | fixture = TestBed.createComponent(HomePage); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it('should create', () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/home/home.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { RouterModule } from '@angular/router'; 3 | import { IonicModule } from '@ionic/angular'; 4 | 5 | import { MessageComponentModule } from '../message/message.module'; 6 | 7 | import { HomePage } from './home.page'; 8 | 9 | describe('HomePage', () => { 10 | let component: HomePage; 11 | let fixture: ComponentFixture; 12 | 13 | beforeEach(async () => { 14 | await TestBed.configureTestingModule({ 15 | declarations: [HomePage], 16 | imports: [IonicModule.forRoot(), MessageComponentModule, RouterModule.forRoot([])] 17 | }).compileComponents(); 18 | 19 | fixture = TestBed.createComponent(HomePage); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it('should create', () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tabs/tabs.routes.ts.template: -------------------------------------------------------------------------------- 1 | import { TabsPage } from './tabs.page'; 2 | import {Routes} from '@angular/router'; 3 | 4 | export const routes: Routes = [ 5 | { 6 | path: 'tabs', 7 | loadComponent: () => import('./tabs.page').then(p => p.TabsPage), 8 | children: [ 9 | { 10 | path: 'tab1', 11 | loadChildren: () => import('../tab1/tab1.routes').then(r => r.routes) 12 | }, 13 | { 14 | path: 'tab2', 15 | loadChildren: () => import('../tab2/tab2.routes').then(r => r.routes) 16 | }, 17 | { 18 | path: 'tab3', 19 | loadChildren: () => import('../tab3/tab3.routes').then(r => r.routes) 20 | }, 21 | { 22 | path: '', 23 | redirectTo: '/tabs/tab1', 24 | pathMatch: 'full' 25 | } 26 | ] 27 | }, 28 | { 29 | path: '', 30 | redirectTo: '/tabs/tab1', 31 | pathMatch: 'full' 32 | } 33 | ]; 34 | 35 | -------------------------------------------------------------------------------- /docs/docs/ionic-react/migrating-from-nxtend.md: -------------------------------------------------------------------------------- 1 | # Migrating from Nxtend to Nxext 2 | 3 | The Nxext Ionic plugins support Nx 14, while the Nxtend plugins support Nx 13. In order to migrate to Nxext you must first upgrade your workspace to Nx 14. If you are using npm 6+ you will need to `npm install --legacy-peer-deps` in order to get passed npm errors. Once the workspace has been updated, the Ionic plugins will not work until they have been migrated to Nxext. 4 | 5 | ## Install Nxext Package 6 | 7 | First, install the Nxext Ionic React package using your package manager of choice. 8 | 9 | ``` 10 | npm install -D @nxext/ionic-react 11 | ``` 12 | 13 | ## Remove Nxtend Package 14 | 15 | Finally, remove the Nxtend Ionic React package. 16 | 17 | ``` 18 | npm uninstall @nxtend/ionic-react 19 | ``` 20 | 21 | ## Migrate Capacitor Plugin 22 | 23 | If you are utilizing Capacitor in your application then you will need to migrate that plugin as well. See the [migration guide](../capacitor/migrating-from-nxtend.md). 24 | -------------------------------------------------------------------------------- /docs/docs/ionic-angular/migrating-from-nxtend.md: -------------------------------------------------------------------------------- 1 | # Migrating from Nxtend to Nxext 2 | 3 | The Nxext Ionic plugins support Nx 14, while the Nxtend plugins support Nx 13. In order to migrate to Nxext you must first upgrade your workspace to Nx 14. If you are using npm 6+ you will need to `npm install --legacy-peer-deps` in order to get passed npm errors. Once the workspace has been updated, the Ionic plugins will not work until they have been migrated to Nxext. 4 | 5 | ## Install Nxext Package 6 | 7 | First, install the Nxext Ionic Angular package using your package manager of choice. 8 | 9 | ``` 10 | npm install -D @nxext/ionic-angular 11 | ``` 12 | 13 | ## Remove Nxtend Package 14 | 15 | Finally, remove the Nxtend Ionic Angular package. 16 | 17 | ``` 18 | npm uninstall @nxtend/ionic-angular 19 | ``` 20 | 21 | ## Migrate Capacitor Plugin 22 | 23 | If you are utilizing Capacitor in your application then you will need to migrate that plugin as well. See the [migration guide](../capacitor/migrating-from-nxtend.md). 24 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/src/App.tsx.template: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | /* Core CSS required for Ionic components to work properly */ 3 | import '@ionic/react/css/core.css'; 4 | 5 | /* Basic CSS for apps built with Ionic */ 6 | import '@ionic/react/css/normalize.css'; 7 | import '@ionic/react/css/structure.css'; 8 | import '@ionic/react/css/typography.css'; 9 | 10 | /* Optional CSS utils that can be commented out */ 11 | import '@ionic/react/css/padding.css'; 12 | import '@ionic/react/css/float-elements.css'; 13 | import '@ionic/react/css/text-alignment.css'; 14 | import '@ionic/react/css/text-transformation.css'; 15 | import '@ionic/react/css/flex-utils.css'; 16 | import '@ionic/react/css/display.css'; 17 | 18 | /* Theme variables */ 19 | import './theme/variables.css'; 20 | 21 | const App: React.FunctionComponent = () => { 22 | return ( 23 |
24 |
25 |
26 |
27 | ); 28 | } 29 | 30 | export default App; 31 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/view-message/view-message.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | import { DataService, Message } from '../services/data.service'; 4 | 5 | @Component({ 6 | selector: '<%= prefix %>-view-message', 7 | templateUrl: './view-message.page.html', 8 | styleUrls: ['./view-message.page.scss'], 9 | }) 10 | export class ViewMessagePage implements OnInit { 11 | public message!: Message; 12 | 13 | constructor( 14 | private data: DataService, 15 | private activatedRoute: ActivatedRoute 16 | ) { } 17 | 18 | ngOnInit() { 19 | const id = this.activatedRoute.snapshot.paramMap.get('id'); 20 | 21 | if (id) { 22 | this.message = this.data.getMessageById(parseInt(id, 10)); 23 | } 24 | } 25 | 26 | getBackButtonText() { 27 | const win = window as any; 28 | const mode = win && win.Ionic && win.Ionic.mode; 29 | return mode === 'ios' ? 'Inbox' : ''; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/capacitor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nxext/capacitor", 3 | "version": "19.0.0", 4 | "description": "An Nx plugin for developing cross-platform applications using Capacitor", 5 | "author": { 6 | "name": "Devin Shoemaker", 7 | "email": "devinshoe@gmail.com" 8 | }, 9 | "homepage": "https://nxext.github.io/nx-extensions-ionic/docs/capacitor/getting-started.html", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/nxext/nx-extensions-ionic", 13 | "directory": "packages/capacitor" 14 | }, 15 | "license": "MIT", 16 | "main": "src/index.js", 17 | "generators": "./generators.json", 18 | "executors": "./executors.json", 19 | "nx-migrations": { 20 | "migrations": "./migrations.json" 21 | }, 22 | "schematics": "./generators.json", 23 | "builders": "./executors.json", 24 | "dependencies": { 25 | "@nx/devkit": "^19.0.0", 26 | "nx": "^19.0.0", 27 | "@nx/web": "^19.0.0", 28 | "ignore": "^5.3.1", 29 | "tslib": "^2.3.0" 30 | }, 31 | "peerDependencies": {} 32 | } 33 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/view-message/vierw-message.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | import { RouterModule } from '@angular/router'; 4 | 5 | import { ViewMessagePageRoutingModule } from './view-message-routing.module'; 6 | import { ViewMessagePage } from './view-message.page'; 7 | 8 | describe('ViewMessagePage', () => { 9 | let component: ViewMessagePage; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ViewMessagePage], 15 | imports: [IonicModule.forRoot(), ViewMessagePageRoutingModule, RouterModule.forRoot([])] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(ViewMessagePage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /**/tmp/ 8 | .env 9 | # dependencies 10 | /node_modules 11 | /**/node_modules 12 | 13 | # IDEs and editors 14 | /.idea 15 | .project 16 | .classpath 17 | .c9/ 18 | *.launch 19 | .settings/ 20 | *.sublime-workspace 21 | 22 | # IDE - VSCode 23 | .vscode/* 24 | !.vscode/settings.json 25 | !.vscode/tasks.json 26 | !.vscode/launch.json 27 | !.vscode/extensions.json 28 | 29 | # misc 30 | /.sass-cache 31 | /connect.lock 32 | /coverage 33 | /libpeerconnection.log 34 | npm-debug.log 35 | yarn-error.log 36 | testem.log 37 | /typings 38 | /.yarn 39 | /.yarnrc 40 | 41 | # System Files 42 | .DS_Store 43 | Thumbs.db 44 | 45 | e2e/stencil-e2e/tests/dev.test.ts 46 | 47 | # Generated Docusaurus files 48 | .docusaurus/ 49 | .cache-loader/ 50 | 51 | # Generated Sveltekit files 52 | /**/.svelte/ 53 | 54 | # verdaccio 55 | /build 56 | /.verdaccio/htpasswd 57 | 58 | # Vitepress 59 | /docs/.vitepress/cache 60 | 61 | .nx/cache 62 | .nx/workspace-data -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/sidemenu/src/pages/Page.tsx.template: -------------------------------------------------------------------------------- 1 | import { IonButtons, IonContent, IonHeader, IonMenuButton, IonPage, IonTitle, IonToolbar } from '@ionic/react'; 2 | import { useParams } from 'react-router'; 3 | import ExploreContainer from '../components/ExploreContainer'; 4 | import './Page.css'; 5 | 6 | const Page: React.FC = () => { 7 | 8 | const { name } = useParams<{ name: string; }>(); 9 | 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | {name} 18 | 19 | 20 | 21 | 22 | 23 | 24 | {name} 25 | 26 | 27 | 28 | 29 | 30 | ); 31 | }; 32 | 33 | export default Page; 34 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list-standalone/src/app/view-message/vierw-message.page.spec.ts.template: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { IonicModule } from '@ionic/angular'; 3 | import { RouterModule } from '@angular/router'; 4 | 5 | import { ViewMessagePageRoutingModule } from './view-message-routing.module'; 6 | import { ViewMessagePage } from './view-message.page'; 7 | 8 | describe('ViewMessagePage', () => { 9 | let component: ViewMessagePage; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ViewMessagePage], 15 | imports: [IonicModule.forRoot(), ViewMessagePageRoutingModule, RouterModule.forRoot([])] 16 | }).compileComponents(); 17 | 18 | fixture = TestBed.createComponent(ViewMessagePage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tools/scripts/update-package-json-nx-versions.ts: -------------------------------------------------------------------------------- 1 | // Updating the version in "package.json" before publishing 2 | import { join } from 'path'; 3 | import * as glob from 'glob'; 4 | import { readFileSync, writeFileSync } from 'fs'; 5 | import { NX_VERSION } from '@nx/devkit'; 6 | 7 | try { 8 | const pkgDir = join(process.cwd(), 'packages'); 9 | const pkgFiles = glob.sync(join(pkgDir, '/**/package.json')); 10 | const version = `^${NX_VERSION}`; 11 | 12 | pkgFiles.forEach((p) => { 13 | const content = JSON.parse(readFileSync(p).toString()); 14 | for (const key in content.dependencies) { 15 | if (key.startsWith(`@nx/`) || key == 'nx') { 16 | content.dependencies[key] = version; 17 | } 18 | } 19 | for (const key in content.peerDependencies) { 20 | if (key.startsWith(`@nx/`) || key == 'nx') { 21 | content.peerDependencies[key] = version; 22 | } 23 | } 24 | writeFileSync(p, JSON.stringify(content, null, 2)); 25 | }); 26 | } catch (e) { 27 | console.error(`Error reading package.json file from library build output.`); 28 | } 29 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/message/message.component.html.template: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |

5 | {{ message.fromName }} 6 | 7 | {{ message.date }} 8 | 9 | 10 |

11 |

{{ message.subject }}

12 |

13 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 14 |

15 |
16 |
17 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/base/src/index.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= className %> 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/list/src/components/MessageListItem.css.template: -------------------------------------------------------------------------------- 1 | ion-item { 2 | --padding-start: 0; 3 | --inner-padding-end: 0; 4 | } 5 | 6 | ion-label { 7 | margin-top: 12px; 8 | margin-bottom: 12px; 9 | } 10 | 11 | ion-item h2 { 12 | font-weight: 600; 13 | margin: 0; 14 | } 15 | 16 | ion-item p { 17 | text-overflow: ellipsis; 18 | overflow: hidden; 19 | white-space: nowrap; 20 | width: 95%; 21 | } 22 | 23 | ion-item .date { 24 | float: right; 25 | align-items: center; 26 | display: flex; 27 | } 28 | 29 | ion-item ion-icon { 30 | color: #c9c9ca; 31 | } 32 | 33 | ion-item ion-note { 34 | font-size: 15px; 35 | margin-right: 8px; 36 | font-weight: normal; 37 | } 38 | 39 | ion-item ion-note.md { 40 | margin-right: 14px; 41 | } 42 | 43 | .dot { 44 | display: block; 45 | height: 12px; 46 | width: 12px; 47 | border-radius: 50%; 48 | align-self: start; 49 | margin: 16px 10px 16px 16px; 50 | } 51 | 52 | .dot-unread { 53 | background: var(--ion-color-primary); 54 | } 55 | 56 | ion-footer ion-title { 57 | font-size: 11px; 58 | font-weight: normal; 59 | } -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/message/message.component.scss.template: -------------------------------------------------------------------------------- 1 | ion-item { 2 | --padding-start: 0; 3 | --inner-padding-end: 0; 4 | } 5 | 6 | ion-label { 7 | margin-top: 12px; 8 | margin-bottom: 12px; 9 | } 10 | 11 | ion-item h2 { 12 | font-weight: 600; 13 | margin: 0; 14 | } 15 | 16 | ion-item p { 17 | text-overflow: ellipsis; 18 | overflow: hidden; 19 | white-space: nowrap; 20 | width: 95%; 21 | } 22 | 23 | ion-item .date { 24 | float: right; 25 | align-items: center; 26 | display: flex; 27 | } 28 | 29 | ion-item ion-icon { 30 | color: #c9c9ca; 31 | } 32 | 33 | ion-item ion-note { 34 | font-size: 15px; 35 | margin-right: 8px; 36 | font-weight: normal; 37 | } 38 | 39 | ion-item ion-note.md { 40 | margin-right: 14px; 41 | } 42 | 43 | .dot { 44 | display: block; 45 | height: 12px; 46 | width: 12px; 47 | border-radius: 50%; 48 | align-self: start; 49 | margin: 16px 10px 16px 16px; 50 | } 51 | 52 | .dot-unread { 53 | background: var(--ion-color-primary); 54 | } 55 | 56 | ion-footer ion-title { 57 | font-size: 11px; 58 | font-weight: normal; 59 | } 60 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs/src/app/tabs/tabs-routing.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { TabsPage } from './tabs.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: 'tabs', 8 | component: TabsPage, 9 | children: [ 10 | { 11 | path: 'tab1', 12 | loadChildren: () => import('../tab1/tab1.module').then(m => m.Tab1PageModule) 13 | }, 14 | { 15 | path: 'tab2', 16 | loadChildren: () => import('../tab2/tab2.module').then(m => m.Tab2PageModule) 17 | }, 18 | { 19 | path: 'tab3', 20 | loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule) 21 | }, 22 | { 23 | path: '', 24 | redirectTo: '/tabs/tab1', 25 | pathMatch: 'full' 26 | } 27 | ] 28 | }, 29 | { 30 | path: '', 31 | redirectTo: '/tabs/tab1', 32 | pathMatch: 'full' 33 | } 34 | ]; 35 | 36 | @NgModule({ 37 | imports: [RouterModule.forChild(routes)], 38 | }) 39 | export class TabsPageRoutingModule {} 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Dominik Pieper 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/docs/nxext/overview.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | [Nx](https://nx.dev/) is a set of extensible dev tools for monorepos and allows 4 | for [third-party plugins](https://nx.dev/nx-community) to add support for other 5 | technologies. [Nxext](https://github.com/nxext/nx-extensions) is a collection of plugins for an Nx workspace. 6 | 7 | | Package | Description | 8 | | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- | 9 | | [`@nxext/ionic-angular`](../ionic-angular/overview.md) | An Nx plugin for developing [Ionic](https://ionicframework.com/docs) Angular applications and libraries. | 10 | | [`@nxext/ionic-react`](../ionic-react/overview.md) | An Nx plugin for developing [Ionic](https://ionicframework.com/docs) React applications and libraries. | 11 | | [`@nxext/capacitor`](../capacitor/overview.md) | An Nx plugin for developing cross-platform applications using [Capacitor](https://capacitorjs.com/docs). | 12 | -------------------------------------------------------------------------------- /tools/scripts/utils.ts: -------------------------------------------------------------------------------- 1 | import { existsSync, lstatSync, copySync, renameSync } from 'fs-extra'; 2 | import { workspaceRoot } from '@nx/devkit'; 3 | import { Workspaces } from 'nx/src/config/workspaces'; 4 | 5 | export function getPublishableLibNames( 6 | workspaceJson = new Workspaces(workspaceRoot).readWorkspaceConfiguration() 7 | ) { 8 | const { projects } = workspaceJson; 9 | 10 | return Object.keys(projects).filter( 11 | (key) => 12 | projects[key].projectType === 'library' && 13 | projects[key].targets?.build?.executor === '@nx/js:tsc' && 14 | projects[key].sourceRoot !== 'e2e/e2e/src' 15 | ); 16 | } 17 | 18 | export function tmpProjPath(path?: string) { 19 | return path 20 | ? `${process.cwd()}/tmp/nx-playground/proj/${path}` 21 | : `${process.cwd()}/tmp/nx-playground/proj`; 22 | } 23 | 24 | export function copyAndRename(path: string, newPath: string) { 25 | if (existsSync(newPath)) { 26 | throw new Error('Already exists'); 27 | } 28 | 29 | if (lstatSync(path).isDirectory()) { 30 | copySync(path, newPath); 31 | } else if (lstatSync(path).isFile()) { 32 | renameSync(path, newPath); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/lib/update-workspace.ts: -------------------------------------------------------------------------------- 1 | import { 2 | normalizePath, 3 | readProjectConfiguration, 4 | Tree, 5 | updateProjectConfiguration, 6 | } from '@nx/devkit'; 7 | import { NormalizedSchema } from '../schema'; 8 | export function updateWorkspace(host: Tree, options: NormalizedSchema) { 9 | const project = readProjectConfiguration(host, options.appProjectName); 10 | project.targets.build.options.assets = [ 11 | ...project.targets.build.options.assets.filter( 12 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 13 | (asset: any) => !asset.toString().includes('src/favicon.ico') 14 | ), 15 | options.appProjectRoot + '/src/manifest.json', 16 | { 17 | glob: '**/*.svg', 18 | input: 'node_modules/ionicons/dist/ionicons/svg', 19 | output: './svg', 20 | }, 21 | ]; 22 | 23 | project.targets.build.options.styles = [ 24 | ...project.targets.build.options.styles, 25 | { 26 | input: normalizePath(`${options.appProjectRoot}/src/theme/variables.css`), 27 | }, 28 | ]; 29 | 30 | updateProjectConfiguration(host, options.appProjectName, project); 31 | } 32 | -------------------------------------------------------------------------------- /packages/ionic-react/README.md: -------------------------------------------------------------------------------- 1 | # @nxext/ionic-react 2 | 3 | [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) 4 | 5 | An Nx plugin for developing [Ionic](https://ionicframework.com/docs) React applications and libraries. 6 | 7 | For more complete documentation, visit [nxext.github.io](https://nxext.github.io/nx-extensions-ionic/docs/ionic-react/overview.html). 8 | 9 | ## Table of Contents 10 | 11 | - [Usage](#usage) 12 | - [Maintainers](#maintainers) 13 | - [Contributing](#contributing) 14 | - [License](#license) 15 | 16 | ## Usage 17 | 18 | Visit the official [Getting Started](https://nxext.github.io/nx-extensions-ionic/docs/ionic-react/getting-started.html) documentation. 19 | 20 | ## Maintainers 21 | 22 | [@devinshoemaker](https://github.com/devinshoemaker) 23 | 24 | ## Contributing 25 | 26 | See [the contributing file](../../contributing.md)! 27 | 28 | PRs accepted. 29 | 30 | Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. 31 | 32 | ## License 33 | 34 | MIT © 2020 Devin Shoemaker 35 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/lib/add-project.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Tree, 3 | readProjectConfiguration, 4 | updateProjectConfiguration, 5 | } from '@nx/devkit'; 6 | import { NormalizedSchema } from '../schema'; 7 | 8 | export function addProject(host: Tree, options: NormalizedSchema) { 9 | const projectConfig = readProjectConfiguration(host, options.project); 10 | const commands = ['add', 'copy', 'open', 'run', 'sync', 'update']; 11 | const platforms = ['ios', 'android']; 12 | 13 | projectConfig.targets.cap = { 14 | executor: '@nxext/capacitor:cap', 15 | options: { 16 | cmd: '--help', 17 | }, 18 | }; 19 | 20 | let command: string, platform: string; 21 | 22 | for (command of commands) { 23 | projectConfig.targets[command] = { 24 | executor: `@nxext/capacitor:cap`, 25 | options: { 26 | cmd: `${command}`, 27 | }, 28 | configurations: {}, 29 | }; 30 | 31 | for (platform of platforms) { 32 | projectConfig.targets[command].configurations[platform] = { 33 | cmd: `${command} ${platform}`, 34 | }; 35 | } 36 | } 37 | updateProjectConfiguration(host, options.project, projectConfig); 38 | } 39 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base/src/assets/shapes.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/docs/capacitor/overview.md: -------------------------------------------------------------------------------- 1 | [Capacitor](https://capacitorjs.com/docs) is a cross-platform native runtime for web applications developed by [Ionic](https://ionicframework.com/). 2 | 3 | While Ionic apps generate a Capacitor project by default, Capacitor is framework agnostic and should work with any application generated in an Nx workspace. 4 | 5 | "Capacitor provides a consistent, web-focused set of APIs that enable an app to stay as close to web standards as possible, while accessing rich native device features on platforms that support them. Adding native functionality is easy with a simple Plugin API for Swift on iOS, Java on Android, and JavaScript for the web. 6 | 7 | Capacitor is a spiritual successor to Apache Cordova and Adobe PhoneGap, with inspiration from other popular cross-platform tools like React Native and Turbolinks, but focused entirely on enabling modern web apps to run on all major platforms with ease. Capacitor is backward-compatible with many existing Cordova plugins." 8 | 9 | To learn more about Capacitor, visit https://capacitorjs.com/docs 10 | 11 | Updates to `@nxext/capacitor` will include migrations that will update the dependencies included with this plugin, as well as any code migrations if possible. 12 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/base-standalone/src/assets/shapes.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/ionic-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nxext/ionic-react", 3 | "version": "19.0.0", 4 | "description": "An Nx plugin for developing Ionic React applications and libraries", 5 | "author": { 6 | "name": "Devin Shoemaker", 7 | "email": "devinshoe@gmail.com" 8 | }, 9 | "homepage": "https://nxext.github.io/nx-extensions-ionic/docs/ionic-react/overview.html", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/nxext/nx-extensions-ionic", 13 | "directory": "packages/ionic-react" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/nxext/nx-extensions-ionic/issues" 17 | }, 18 | "license": "MIT", 19 | "main": "src/index.js", 20 | "generators": "./generators.json", 21 | "executors": "./executors.json", 22 | "nx-migrations": { 23 | "migrations": "./migrations.json" 24 | }, 25 | "schematics": "./generators.json", 26 | "builders": "./executors.json", 27 | "dependencies": { 28 | "@nxext/capacitor": "^19.0.0", 29 | "@nx/devkit": "^19.0.0", 30 | "@nx/eslint": "^19.0.0", 31 | "@nx/react": "^19.0.0", 32 | "typescript": "5.5.4", 33 | "@phenomnomnominal/tsquery": "~5.0.1", 34 | "tslib": "^2.3.0" 35 | }, 36 | "peerDependencies": {} 37 | } 38 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab3/tab3.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {FormsModule} from '@angular/forms'; 4 | import {IonicModule} from '@ionic/angular'; 5 | import {ExploreContainerComponent} from '../explore-container/explore-container.component'; 6 | 7 | @Component({ 8 | selector: '<%= prefix %>-tab3', 9 | standalone: true, 10 | imports: [ 11 | IonicModule, 12 | CommonModule, 13 | FormsModule, 14 | ExploreContainerComponent, 15 | ], 16 | template: ` 17 | 18 | 19 | 20 | Tab 3 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Tab 3 29 | 30 | 31 | 32 | <<%= prefix %>-explore-container name="Tab 3 page">-explore-container> 33 | 34 | `, 35 | styles: `` 36 | }) 37 | export class Tab3Page { 38 | 39 | constructor() {} 40 | 41 | } 42 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab2/tab2.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {FormsModule} from '@angular/forms'; 4 | import {IonicModule} from '@ionic/angular'; 5 | import {ExploreContainerComponent} from '../explore-container/explore-container.component'; 6 | 7 | @Component({ 8 | selector: '<%= prefix %>-tab2', 9 | standalone: true, 10 | imports: [ 11 | IonicModule, 12 | CommonModule, 13 | FormsModule, 14 | ExploreContainerComponent, 15 | ], 16 | template: ` 17 | 18 | 19 | 20 | Tab 2 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Tab 2 29 | 30 | 31 | 32 | <<%= prefix %>-explore-container name="Tab 2 page">-explore-container> 33 | 34 | 35 | `, 36 | styles: `` 37 | }) 38 | export class Tab2Page { 39 | 40 | constructor() {} 41 | 42 | } 43 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tab1/tab1.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {FormsModule} from '@angular/forms'; 4 | import {IonicModule} from '@ionic/angular'; 5 | import {ExploreContainerComponent} from '../explore-container/explore-container.component'; 6 | 7 | @Component({ 8 | selector: '<%= prefix %>-tab1', 9 | standalone: true, 10 | imports: [ 11 | IonicModule, 12 | CommonModule, 13 | FormsModule, 14 | ExploreContainerComponent 15 | ], 16 | template: ` 17 | 18 | 19 | 20 | Tab 1 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Tab 1 29 | 30 | 31 | 32 | <<%= prefix %>-explore-container name="Tab 1 page">-explore-container> 33 | 34 | `, 35 | styles: ` 36 | 37 | ` 38 | }) 39 | export class Tab1Page { 40 | 41 | constructor() {} 42 | 43 | } 44 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/tabs/tabs.page.ts.template: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {FormsModule} from '@angular/forms'; 4 | import {IonicModule} from '@ionic/angular'; 5 | 6 | @Component({ 7 | selector: '<%= prefix %>-tabs', 8 | standalone: true, 9 | imports: [ 10 | IonicModule, 11 | CommonModule, 12 | FormsModule 13 | ], 14 | template: ` 15 | 16 | 17 | 18 | 19 | 20 | Tab 1 21 | 22 | 23 | 24 | 25 | Tab 2 26 | 27 | 28 | 29 | 30 | Tab 3 31 | 32 | 33 | 34 | 35 | 36 | `, 37 | styles: `` 38 | }) 39 | export class TabsPage { 40 | 41 | constructor() {} 42 | 43 | } 44 | -------------------------------------------------------------------------------- /packages/ionic-angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nxext/ionic-angular", 3 | "version": "19.0.0", 4 | "description": "An Nx plugin for developing Ionic React applications and libraries", 5 | "author": { 6 | "name": "Devin Shoemaker", 7 | "email": "devinshoe@gmail.com" 8 | }, 9 | "homepage": "https://nxext.github.io/nx-extensions-ionic/docs/ionic-angular/overview.html", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/nxext/nx-extensions-ionic", 13 | "directory": "packages/ionic-angular" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/nxext/nx-extensions-ionic/issues" 17 | }, 18 | "license": "MIT", 19 | "main": "src/index.js", 20 | "generators": "./generators.json", 21 | "executors": "./executors.json", 22 | "nx-migrations": { 23 | "migrations": "./migrations.json" 24 | }, 25 | "schematics": "./generators.json", 26 | "builders": "./executors.json", 27 | "dependencies": { 28 | "@nxext/capacitor": "^19.0.0", 29 | "@nx/devkit": "^19.0.0", 30 | "@nx/eslint": "^19.0.0", 31 | "@nx/angular": "^19.0.0", 32 | "@nx/js": "^19.0.0", 33 | "@phenomnomnominal/tsquery": "~5.0.1", 34 | "typescript": "5.5.4", 35 | "tslib": "^2.3.0" 36 | }, 37 | "peerDependencies": {} 38 | } 39 | -------------------------------------------------------------------------------- /packages/capacitor/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { FlatCompat } = require('@eslint/eslintrc'); 2 | const baseConfig = require('../../eslint.config.js'); 3 | const js = require('@eslint/js'); 4 | const compat = new FlatCompat({ 5 | baseDirectory: __dirname, 6 | recommendedConfig: js.configs.recommended, 7 | }); 8 | module.exports = [ 9 | ...baseConfig, 10 | { 11 | files: [ 12 | 'packages/capacitor/**/*.ts', 13 | 'packages/capacitor/**/*.tsx', 14 | 'packages/capacitor/**/*.js', 15 | 'packages/capacitor/**/*.jsx', 16 | ], 17 | rules: {}, 18 | }, 19 | { 20 | files: ['packages/capacitor/**/*.ts', 'packages/capacitor/**/*.tsx'], 21 | rules: {}, 22 | }, 23 | { 24 | files: ['packages/capacitor/**/*.js', 'packages/capacitor/**/*.jsx'], 25 | rules: {}, 26 | }, 27 | ...compat.config({ parser: 'jsonc-eslint-parser' }).map((config) => ({ 28 | ...config, 29 | files: [ 30 | 'packages/capacitor/package.json', 31 | 'packages/capacitor/generators.json', 32 | 'packages/capacitor/executors.json', 33 | 'packages/capacitor/generators.json', 34 | 'packages/capacitor/executors.json', 35 | 'packages/capacitor/migrations.json', 36 | ], 37 | rules: { '@nx/nx-plugin-checks': 'error' }, 38 | })), 39 | ]; 40 | -------------------------------------------------------------------------------- /packages/capacitor/MIGRATION.md: -------------------------------------------------------------------------------- 1 | # Migration 2 | 3 | # 1.x.x - 2.0.0 4 | 5 | ## Move Capacitor Configs 6 | 7 | With `@nxext/capacitor` 2.0+, Capacitor configurations will be added to the associated frontend project instead of creating a dedicated Capacitor project. Migrating to this new paradigm is trivial and takes just a few steps. 8 | 9 | First, add a new set of Capacitor configs to your frontend project. 10 | 11 | ``` 12 | nx g @nxext/capacitor:capacitor-project --project my-app 13 | ``` 14 | 15 | Move `capacitor.config.json` from the Capacitor project to the root of the associated frontend project. You will have to overwrite the `capacitor.config.json` that was just generated. 16 | 17 | Move all platform folders (`android`, `ios`, `electron`) from the Capacitor project to the root of the frontend project. 18 | 19 | You should now test the Capacitor commands for the frontend project and ensure the project works as expected. 20 | 21 | ``` 22 | nx run my-app:sync --platform ios 23 | nx run my-app:open --platform ios 24 | ``` 25 | 26 | If everything works as expected then you can safely remove the Capacitor project. 27 | 28 | ``` 29 | nx g @nx/workspace:remove my-app 30 | ``` 31 | 32 | The `@capacitor/cli` dependency in the root `package.json` is also no longer needed and can be removed. 33 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/lib/normalize-options.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ensurePackage, 3 | getWorkspaceLayout, 4 | names, 5 | normalizePath, 6 | NX_VERSION, 7 | Tree, 8 | } from '@nx/devkit'; 9 | import { ApplicationGeneratorSchema, NormalizedSchema } from '../schema'; 10 | 11 | export async function normalizeOptions( 12 | host: Tree, 13 | options: ApplicationGeneratorSchema 14 | ): Promise { 15 | ensurePackage('@nx/js', NX_VERSION); 16 | const { getNpmScope } = await import( 17 | '@nx/js/src/utils/package-json/get-npm-scope' 18 | ); 19 | 20 | const appName = options.name; 21 | 22 | const appDirectory = options.directory 23 | ? `${names(options.directory).fileName}/${names(options.name).fileName}` 24 | : names(options.name).fileName; 25 | 26 | const appProjectName = appDirectory.replace(new RegExp('/', 'g'), '-'); 27 | 28 | const { appsDir } = getWorkspaceLayout(host); 29 | const appProjectRoot = normalizePath(`${appsDir}/${appDirectory}`); 30 | const npmScope = getNpmScope(host); 31 | 32 | return { 33 | ...options, 34 | appName, 35 | name: names(options.name).fileName, 36 | prefix: npmScope, 37 | appProjectName, 38 | appProjectRoot, 39 | standalone: options.standalone, 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "$id": "CapacitorProject", 4 | "title": "Create a Capacitor project for an Nx application", 5 | "type": "object", 6 | "properties": { 7 | "project": { 8 | "type": "string", 9 | "description": "The name of the frontend project for Capacitor.", 10 | "alias": "p", 11 | "$default": { 12 | "$source": "projectName" 13 | }, 14 | "x-prompt": "What is the name of the frontend project for Capacitor?" 15 | }, 16 | "appId": { 17 | "type": "string", 18 | "description": "The app ID for the project.", 19 | "default": "io.ionic.starter", 20 | "x-prompt": "What app ID would you like to use?" 21 | }, 22 | "appName": { 23 | "type": "string", 24 | "description": "The application name for the project.", 25 | "x-prompt": "What app name would you like to use?" 26 | }, 27 | "webDir": { 28 | "type": "string", 29 | "description": "The directory of your projects built web assets." 30 | }, 31 | "skipFormat": { 32 | "description": "Skip formatting files.", 33 | "type": "boolean", 34 | "default": false 35 | } 36 | }, 37 | "required": ["project"] 38 | } 39 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/capacitor-project/generator.ts: -------------------------------------------------------------------------------- 1 | import { convertNxGenerator, formatFiles, Tree } from '@nx/devkit'; 2 | import { addCapacitorConfig } from './lib/add-capacitor-config'; 3 | import { addDependencies } from './lib/add-dependencies'; 4 | import { addProject } from './lib/add-project'; 5 | import { normalizeOptions } from './lib/normalize-options'; 6 | import { updateProjectGitignore } from './lib/update-project-gitignore'; 7 | import { updateProjectPackageJson } from './lib/update-project-package-json'; 8 | import { CapacitorGeneratorSchema } from './schema'; 9 | 10 | export async function capacitorProjectGenerator( 11 | host: Tree, 12 | options: CapacitorGeneratorSchema 13 | ) { 14 | const normalizedOptions = normalizeOptions(host, options); 15 | const installTask = addDependencies(host); 16 | addCapacitorConfig(host, normalizedOptions); 17 | updateProjectGitignore(host, normalizedOptions); 18 | addProject(host, normalizedOptions); 19 | updateProjectPackageJson(host, normalizedOptions); 20 | 21 | if (!options.skipFormat) { 22 | await formatFiles(host); 23 | } 24 | 25 | return installTask; 26 | } 27 | 28 | export default capacitorProjectGenerator; 29 | export const capacitorProjectSchematic = convertNxGenerator( 30 | capacitorProjectGenerator 31 | ); 32 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | permissions: 10 | actions: read 11 | contents: read 12 | 13 | jobs: 14 | main: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | 21 | - uses: pnpm/action-setup@v2 22 | with: 23 | version: 8 24 | # Cache node_modules 25 | - uses: actions/setup-node@v3 26 | with: 27 | node-version: 20 28 | cache: 'pnpm' 29 | - uses: actions/cache@v4 30 | with: 31 | lookup-only: true 32 | path: '**/node_modules' 33 | key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} 34 | # Connect your workspace on nx.app and uncomment this to enable task distribution. 35 | # The "--stop-agents-after" is optional, but allows idle agents to shut down once the "build" targets have been requested 36 | - run: pnpm install --no-frozen-lockfile 37 | - uses: nrwl/nx-set-shas@v4 38 | #- run: pnpm exec nx-cloud start-ci-run --distribute-on="5 linux-medium-js" --stop-agents-after="build" 39 | 40 | - run: pnpm exec nx-cloud record -- nx format:check 41 | - run: pnpm exec nx affected -t lint test build 42 | -------------------------------------------------------------------------------- /packages/ionic-react/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { FlatCompat } = require('@eslint/eslintrc'); 2 | const baseConfig = require('../../eslint.config.js'); 3 | const js = require('@eslint/js'); 4 | const compat = new FlatCompat({ 5 | baseDirectory: __dirname, 6 | recommendedConfig: js.configs.recommended, 7 | }); 8 | module.exports = [ 9 | ...baseConfig, 10 | { 11 | files: [ 12 | 'packages/ionic-react/**/*.ts', 13 | 'packages/ionic-react/**/*.tsx', 14 | 'packages/ionic-react/**/*.js', 15 | 'packages/ionic-react/**/*.jsx', 16 | ], 17 | rules: {}, 18 | }, 19 | { 20 | files: ['packages/ionic-react/**/*.ts', 'packages/ionic-react/**/*.tsx'], 21 | rules: {}, 22 | }, 23 | { 24 | files: ['packages/ionic-react/**/*.js', 'packages/ionic-react/**/*.jsx'], 25 | rules: {}, 26 | }, 27 | ...compat.config({ parser: 'jsonc-eslint-parser' }).map((config) => ({ 28 | ...config, 29 | files: [ 30 | 'packages/ionic-react/package.json', 31 | 'packages/ionic-react/generators.json', 32 | 'packages/ionic-react/executors.json', 33 | 'packages/ionic-react/generators.json', 34 | 'packages/ionic-react/executors.json', 35 | 'packages/ionic-react/migrations.json', 36 | ], 37 | rules: { '@nx/nx-plugin-checks': 'error' }, 38 | })), 39 | ]; 40 | -------------------------------------------------------------------------------- /.github/disabled_workflows/ci-checks-windows.yml: -------------------------------------------------------------------------------- 1 | name: Nx Windows CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | build: 11 | runs-on: windows-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [16.x] 16 | env: 17 | NX_CLOUD_AUTH_TOKEN: ${{ secrets.NX_CLOUD_AUTH_TOKEN }} 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v3 21 | with: 22 | fetch-depth: 0 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v3 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | cache: 'yarn' 28 | - run: git fetch --no-tags --prune --depth=5 origin main 29 | shell: powershell 30 | - run: yarn install --prefer-offline --frozen-lockfile --non-interactive 31 | shell: powershell 32 | - run: yarn affected:build --base=origin/main --head=HEAD 33 | shell: powershell 34 | - run: yarn affected:lint --base=origin/main --head=HEAD --parallel 35 | shell: powershell 36 | - run: yarn affected:test --base=origin/main --head=HEAD --parallel 37 | shell: powershell 38 | - run: yarn affected:e2e --base=origin/main --head=HEAD 39 | shell: powershell 40 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/generator.ts: -------------------------------------------------------------------------------- 1 | import { 2 | convertNxGenerator, 3 | formatFiles, 4 | runTasksInSerial, 5 | Tree, 6 | } from '@nx/devkit'; 7 | import { addAngular } from './lib/add-angular'; 8 | import { addCapacitor } from './lib/add-capacitor'; 9 | import { addDependencies } from './lib/add-dependencies'; 10 | import { addFiles, removeFiles } from './lib/files'; 11 | import { normalizeOptions } from './lib/normalize-options'; 12 | import { updateWorkspace } from './lib/update-workspace'; 13 | import { ApplicationGeneratorSchema } from './schema'; 14 | 15 | export async function applicationGenerator( 16 | host: Tree, 17 | schema: ApplicationGeneratorSchema 18 | ) { 19 | const options = await normalizeOptions(host, schema); 20 | 21 | const installTask = addDependencies(host); 22 | const angularTask = await addAngular(host, options); 23 | addFiles(host, options); 24 | removeFiles(host, options); 25 | updateWorkspace(host, options); 26 | 27 | const capacitorTask = await addCapacitor(host, options); 28 | 29 | if (!options.skipFormat) { 30 | await formatFiles(host); 31 | } 32 | 33 | return runTasksInSerial(installTask, angularTask, capacitorTask); 34 | } 35 | 36 | export default applicationGenerator; 37 | export const applicationSchematic = convertNxGenerator(applicationGenerator); 38 | -------------------------------------------------------------------------------- /packages/capacitor/src/generators/application/generator.ts: -------------------------------------------------------------------------------- 1 | import { 2 | convertNxGenerator, 3 | ensurePackage, 4 | formatFiles, 5 | NX_VERSION, 6 | runTasksInSerial, 7 | Tree, 8 | } from '@nx/devkit'; 9 | import { AppGeneratorSchema } from './schema'; 10 | import { capacitorProjectGenerator } from '../capacitor-project/generator'; 11 | 12 | export async function applicationGenerator( 13 | tree: Tree, 14 | options: AppGeneratorSchema 15 | ) { 16 | const viteTask = await createDefaultViteApp(tree, options); 17 | 18 | const capacitorTask = await capacitorProjectGenerator(tree, { 19 | project: options.name, 20 | appName: options.name, 21 | appId: options.appId, 22 | skipFormat: true, 23 | }); 24 | 25 | await formatFiles(tree); 26 | 27 | return runTasksInSerial(viteTask, capacitorTask); 28 | } 29 | 30 | async function createDefaultViteApp(tree: Tree, options: AppGeneratorSchema) { 31 | const { applicationGenerator } = ensurePackage( 32 | '@nx/web', 33 | NX_VERSION 34 | ); 35 | 36 | return await applicationGenerator(tree, { 37 | name: options.name, 38 | bundler: 'vite', 39 | unitTestRunner: options.unitTestRunner, 40 | skipFormat: true, 41 | }); 42 | } 43 | 44 | export default applicationGenerator; 45 | export const applicationSchematic = convertNxGenerator(applicationGenerator); 46 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/tabs-standalone/src/app/explore-container/explore-container.component.ts.template: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {FormsModule} from '@angular/forms'; 4 | import {IonicModule} from '@ionic/angular'; 5 | 6 | @Component({ 7 | selector: '<%= prefix %>-explore-container', 8 | standalone: true, 9 | imports: [ CommonModule, FormsModule, IonicModule ], 10 | template: ` 11 |
12 | {{ name }} 13 |

Explore UI Components

14 |
15 | `, 16 | styles: ` 17 | #container { 18 | text-align: center; 19 | 20 | position: absolute; 21 | left: 0; 22 | right: 0; 23 | top: 50%; 24 | transform: translateY(-50%); 25 | } 26 | 27 | #container strong { 28 | font-size: 20px; 29 | line-height: 26px; 30 | } 31 | 32 | #container p { 33 | font-size: 16px; 34 | line-height: 22px; 35 | 36 | color: #8c8c8c; 37 | 38 | margin: 0; 39 | } 40 | 41 | #container a { 42 | text-decoration: none; 43 | } 44 | ` 45 | }) 46 | export class ExploreContainerComponent { 47 | 48 | @Input() name?: string; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /tools/scripts/mock-project-graph.ts: -------------------------------------------------------------------------------- 1 | module.exports = () => { 2 | /** 3 | * When the daemon is enabled during unit tests, 4 | * and the daemon is already running, the daemon-client.ts 5 | * code will be used, but it will hit the already running 6 | * daemon which is from the installed version of Nx. 7 | * 8 | * In the vast majority of cases, this is fine. However, 9 | * if a new message type has been added to the daemon in 10 | * the source code, and isn't yet in the installed version, 11 | * any test that hits that codepath will fail. This is because 12 | * the installed version of the daemon doesn't know how to 13 | * handle the new message type. 14 | * 15 | * To prevent this, we disable the daemon during unit tests. 16 | */ 17 | process.env.NX_DAEMON = 'false'; 18 | 19 | /** 20 | * When `createProjectGraphAsync` is called during tests, 21 | * if its not mocked, it will return the Nx repo's project 22 | * graph. We don't want any unit tests to depend on the structure 23 | * of the Nx repo, so we mock it to return an empty project graph. 24 | */ 25 | jest.doMock('@nx/devkit', () => ({ 26 | ...jest.requireActual('@nx/devkit'), 27 | createProjectGraphAsync: jest.fn().mockImplementation(async () => { 28 | return { 29 | nodes: {}, 30 | dependencies: {}, 31 | }; 32 | }), 33 | })); 34 | }; 35 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/lib/add-dependencies.ts: -------------------------------------------------------------------------------- 1 | import { addDependenciesToPackageJson, Tree } from '@nx/devkit'; 2 | import { 3 | ionicReactRouterVersion, 4 | ionicReactVersion, 5 | webVitalsVersion, 6 | workboxVersion, 7 | capacitorPluginVersion, 8 | } from '../../../utils/versions'; 9 | 10 | export function addDependencies(host: Tree) { 11 | return addDependenciesToPackageJson( 12 | host, 13 | { 14 | '@ionic/react': ionicReactVersion, 15 | '@ionic/react-router': ionicReactRouterVersion, 16 | 'web-vitals': webVitalsVersion, 17 | '@capacitor/haptics': capacitorPluginVersion, 18 | '@capacitor/keyboard': capacitorPluginVersion, 19 | '@capacitor/status-bar': capacitorPluginVersion, 20 | 'workbox-background-sync': workboxVersion, 21 | 'workbox-broadcast-update': workboxVersion, 22 | 'workbox-cacheable-response': workboxVersion, 23 | 'workbox-core': workboxVersion, 24 | 'workbox-expiration': workboxVersion, 25 | 'workbox-google-analytics': workboxVersion, 26 | 'workbox-navigation-preload': workboxVersion, 27 | 'workbox-precaching': workboxVersion, 28 | 'workbox-range-requests': workboxVersion, 29 | 'workbox-routing': workboxVersion, 30 | 'workbox-strategies': workboxVersion, 31 | 'workbox-streams': workboxVersion, 32 | }, 33 | {} 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /docs/docs/nxext/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | PR's, ideas and discussions are welcome. 4 | 5 | ## Project Structure 6 | 7 | This project uses the Nx CLI with pnpm. 8 | 9 | This project is built with Nx and follows the OSS project structure. The [Getting Started](https://nx.dev/angular/getting-started/what-is-nx) guide shows how to work with Nx workspaces. 10 | 11 | ## Build 12 | 13 | After cloning the project, to install the dependencies, run: 14 | 15 | ``` 16 | pnpm install 17 | ``` 18 | 19 | To build a plugin, run: 20 | 21 | ``` 22 | pnpm build [plugin] 23 | ``` 24 | 25 | ## Run the Unit Tests 26 | 27 | Run unit tests for a specific plugin with: 28 | 29 | ``` 30 | pnpm test [plugin] 31 | ``` 32 | 33 | ## Run the e2e Tests 34 | 35 | Run e2e tests for a specific plugin with: 36 | 37 | ``` 38 | pnpm e2e [plugin] 39 | ``` 40 | 41 | ## Test Locally 42 | 43 | Create a playground Nx repository: 44 | 45 | ``` 46 | pnpm create-playground 47 | ``` 48 | 49 | This will create a playground repository inside the Nxext repository directory. You'll find it here: 50 | 51 | > tmp/nx-playground/proj/ 52 | 53 | It is a regular Nx repository and you're able to do everything like create projects and libraries. 54 | 55 | To update the playground with changes on the plugins without rebuilding a new playground, run: 56 | 57 | ``` 58 | pnpm update-playground 59 | ``` 60 | 61 | **Happy coding :-)** 62 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/list/src/app/view-message/view-message.page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 | {{ message.fromName }} 15 | 16 | {{ message.date }} 17 | 18 |

19 |

To: Me

20 |
21 |
22 | 23 |
24 |

{{ message.subject }}

25 |

26 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 27 |

28 |
29 |
30 | -------------------------------------------------------------------------------- /tools/scripts/documentation/documentation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Originally from the Nx repo: https://github.com/nrwl/nx 3 | */ 4 | import * as chalk from 'chalk'; 5 | import { execSync } from 'child_process'; 6 | 7 | import { generateExecutorsDocumentation } from './generate-executors-data'; 8 | import { generateGeneratorsDocumentation } from './generate-generators-data'; 9 | 10 | async function generate() { 11 | try { 12 | console.log(`${chalk.blue('i')} Generating Documentation`); 13 | await generateGeneratorsDocumentation(); 14 | await generateExecutorsDocumentation(); 15 | 16 | console.log(`\n${chalk.green('✓')} Generated Documentation\n`); 17 | } catch (e) { 18 | console.error(e); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | function checkDocumentation() { 24 | const output = execSync('git status --porcelain ./docs').toString('utf-8'); 25 | 26 | if (output) { 27 | console.log( 28 | `${chalk.red( 29 | '!' 30 | )} 📄 Documentation has been modified, you need to commit the changes. ${chalk.red( 31 | '!' 32 | )} ` 33 | ); 34 | 35 | console.log('\nChanged Docs:'); 36 | execSync('git status --porcelain ./docs', { stdio: 'inherit' }); 37 | 38 | process.exit(1); 39 | } else { 40 | console.log('📄 Documentation not modified'); 41 | } 42 | } 43 | 44 | generate().then(() => { 45 | checkDocumentation(); 46 | }); 47 | -------------------------------------------------------------------------------- /packages/ionic-angular/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { FlatCompat } = require('@eslint/eslintrc'); 2 | const baseConfig = require('../../eslint.config.js'); 3 | const js = require('@eslint/js'); 4 | const compat = new FlatCompat({ 5 | baseDirectory: __dirname, 6 | recommendedConfig: js.configs.recommended, 7 | }); 8 | module.exports = [ 9 | ...baseConfig, 10 | { 11 | files: [ 12 | 'packages/ionic-angular/**/*.ts', 13 | 'packages/ionic-angular/**/*.tsx', 14 | 'packages/ionic-angular/**/*.js', 15 | 'packages/ionic-angular/**/*.jsx', 16 | ], 17 | rules: {}, 18 | }, 19 | { 20 | files: [ 21 | 'packages/ionic-angular/**/*.ts', 22 | 'packages/ionic-angular/**/*.tsx', 23 | ], 24 | rules: {}, 25 | }, 26 | { 27 | files: [ 28 | 'packages/ionic-angular/**/*.js', 29 | 'packages/ionic-angular/**/*.jsx', 30 | ], 31 | rules: {}, 32 | }, 33 | ...compat.config({ parser: 'jsonc-eslint-parser' }).map((config) => ({ 34 | ...config, 35 | files: [ 36 | 'packages/ionic-angular/package.json', 37 | 'packages/ionic-angular/generators.json', 38 | 'packages/ionic-angular/executors.json', 39 | 'packages/ionic-angular/generators.json', 40 | 'packages/ionic-angular/executors.json', 41 | 'packages/ionic-angular/migrations.json', 42 | ], 43 | rules: { '@nx/nx-plugin-checks': 'error' }, 44 | })), 45 | ]; 46 | -------------------------------------------------------------------------------- /packages/ionic-angular/src/generators/application/files/sidemenu/src/app/app.component.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Inbox 7 | hi@ionicframework.com 8 | 9 | 10 | 11 | 12 | {{ p.title }} 13 | 14 | 15 | 16 | 17 | 18 | Labels 19 | 20 | 21 | 22 | {{ label }} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/list/src/components/MessageListItem.tsx.template: -------------------------------------------------------------------------------- 1 | import { 2 | IonItem, 3 | IonLabel, 4 | IonNote 5 | } from '@ionic/react'; 6 | import { Message } from '../data/messages'; 7 | import './MessageListItem.css'; 8 | 9 | interface MessageListItemProps { 10 | message: Message; 11 | } 12 | 13 | const MessageListItem: React.FC = ({ message }) => { 14 | return ( 15 | 16 |
17 | 18 |

19 | {message.fromName} 20 | 21 | {message.date} 22 | 23 |

24 |

{message.subject}

25 |

26 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 27 |

28 |
29 |
30 | ); 31 | }; 32 | 33 | export default MessageListItem; 34 | -------------------------------------------------------------------------------- /packages/ionic-react/src/generators/application/files/blank/src/App.tsx.template: -------------------------------------------------------------------------------- 1 | import { Redirect, Route } from 'react-router-dom'; 2 | import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react'; 3 | import { IonReactRouter } from '@ionic/react-router'; 4 | import Home from './pages/Home'; 5 | 6 | /* Core CSS required for Ionic components to work properly */ 7 | import '@ionic/react/css/core.css'; 8 | 9 | /* Basic CSS for apps built with Ionic */ 10 | import '@ionic/react/css/normalize.css'; 11 | import '@ionic/react/css/structure.css'; 12 | import '@ionic/react/css/typography.css'; 13 | 14 | /* Optional CSS utils that can be commented out */ 15 | import '@ionic/react/css/padding.css'; 16 | import '@ionic/react/css/float-elements.css'; 17 | import '@ionic/react/css/text-alignment.css'; 18 | import '@ionic/react/css/text-transformation.css'; 19 | import '@ionic/react/css/flex-utils.css'; 20 | import '@ionic/react/css/display.css'; 21 | 22 | /* Theme variables */ 23 | import './theme/variables.css'; 24 | 25 | setupIonicReact(); 26 | 27 | const App: React.FC = () => ( 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | ); 41 | 42 | export default App; 43 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. 10 | 11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 12 | 13 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 14 | --------------------------------------------------------------------------------