├── .devcontainer └── devcontainer.json ├── .editorconfig ├── .eslintrc.json ├── .firebaserc ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── documentation.md │ └── feature_request.md ├── .gitignore ├── .npmrc ├── .pnpm-debug.log ├── .prettierignore ├── .prettierrc ├── .tours ├── observe.tour └── onobserver.tour ├── .vscode ├── extensions.json └── launch.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── apps ├── .gitkeep ├── official-site │ ├── .browserslistrc │ ├── .eslintrc.json │ ├── jest.config.ts │ ├── project.json │ ├── src │ │ ├── app │ │ │ ├── app-material.module.ts │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.scss │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── components │ │ │ │ ├── example-list │ │ │ │ │ ├── example-list.component.html │ │ │ │ │ ├── example-list.component.scss │ │ │ │ │ └── example-list.component.ts │ │ │ │ ├── example │ │ │ │ │ ├── example.component.html │ │ │ │ │ ├── example.component.scss │ │ │ │ │ └── example.component.ts │ │ │ │ ├── home │ │ │ │ │ ├── home.component.html │ │ │ │ │ ├── home.component.scss │ │ │ │ │ └── home.component.ts │ │ │ │ ├── library-benefits │ │ │ │ │ ├── library-benefits.component.html │ │ │ │ │ ├── library-benefits.component.scss │ │ │ │ │ └── library-benefits.component.ts │ │ │ │ └── topic │ │ │ │ │ ├── topic.component.html │ │ │ │ │ ├── topic.component.scss │ │ │ │ │ └── topic.component.ts │ │ │ ├── content │ │ │ │ ├── all.ts │ │ │ │ ├── angular-zen-seo │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── 01.getting-started.ts │ │ │ │ │ │ └── all.ts │ │ │ │ │ └── project.ts │ │ │ │ ├── angular-zen-ux │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── 01.getting-started.ts │ │ │ │ │ │ └── all.ts │ │ │ │ │ └── project.ts │ │ │ │ └── angular-zen │ │ │ │ │ ├── examples │ │ │ │ │ ├── 01.core-module.ts │ │ │ │ │ ├── 02.async-module.ts │ │ │ │ │ ├── 03.universal-module.ts │ │ │ │ │ ├── 04.router-x-module.ts │ │ │ │ │ ├── 05.language-integration-module.ts │ │ │ │ │ └── all.ts │ │ │ │ │ └── project.ts │ │ │ ├── services │ │ │ │ └── project.service.ts │ │ │ ├── types │ │ │ │ ├── benefit.ts │ │ │ │ ├── credit.ts │ │ │ │ ├── example.ts │ │ │ │ ├── project.ts │ │ │ │ └── topic.ts │ │ │ └── utils │ │ │ │ └── route-builders.ts │ │ ├── assets │ │ │ ├── .gitkeep │ │ │ ├── angular-zen-seo │ │ │ │ ├── cover.jpg │ │ │ │ ├── logo-icon64x64.png │ │ │ │ ├── logo-icon@0.5x.png │ │ │ │ ├── logo-icon@0.75x.png │ │ │ │ ├── logo-icon@1.25x.png │ │ │ │ ├── logo-icon@1.5x.png │ │ │ │ ├── logo-icon@2x.png │ │ │ │ ├── logo-icon@3x.png │ │ │ │ ├── logo-icon@4x.png │ │ │ │ ├── logo64x64.png │ │ │ │ ├── logo@0.5x.png │ │ │ │ ├── logo@0.75x.png │ │ │ │ ├── logo@1.25x.png │ │ │ │ ├── logo@1.5x.png │ │ │ │ ├── logo@2x.png │ │ │ │ ├── logo@3x.png │ │ │ │ └── logo@4x.png │ │ │ ├── angular-zen-ux │ │ │ │ ├── cover.jpg │ │ │ │ ├── logo-icon64x64.png │ │ │ │ ├── logo-icon@0.5x.png │ │ │ │ ├── logo-icon@0.75x.png │ │ │ │ ├── logo-icon@1.25x.png │ │ │ │ ├── logo-icon@1.5x.png │ │ │ │ ├── logo-icon@2x.png │ │ │ │ ├── logo-icon@3x.png │ │ │ │ ├── logo-icon@4x.png │ │ │ │ ├── logo64x64.png │ │ │ │ ├── logo@0.5x.png │ │ │ │ ├── logo@0.75x.png │ │ │ │ ├── logo@1.25x.png │ │ │ │ ├── logo@1.5x.png │ │ │ │ ├── logo@2x.png │ │ │ │ ├── logo@3x.png │ │ │ │ └── logo@4x.png │ │ │ ├── angular-zen │ │ │ │ ├── cover.jpg │ │ │ │ ├── logo-icon-square64x64.png │ │ │ │ ├── logo-icon-square@0.5x.png │ │ │ │ ├── logo-icon-square@0.75x.png │ │ │ │ ├── logo-icon-square@1.25x.png │ │ │ │ ├── logo-icon-square@1.5x.png │ │ │ │ ├── logo-icon-square@2x.png │ │ │ │ ├── logo-icon-square@3x.png │ │ │ │ ├── logo-icon-square@4x.png │ │ │ │ ├── logo-icon.svg │ │ │ │ ├── logo-icon64x64.png │ │ │ │ ├── logo-icon@0.5x.png │ │ │ │ ├── logo-icon@0.75x.png │ │ │ │ ├── logo-icon@1.25x.png │ │ │ │ ├── logo-icon@1.5x.png │ │ │ │ ├── logo-icon@2x.png │ │ │ │ ├── logo-icon@3x.png │ │ │ │ ├── logo-icon@4x.png │ │ │ │ ├── logo.svg │ │ │ │ ├── logo64x64.png │ │ │ │ ├── logo@0.5x.png │ │ │ │ ├── logo@0.75x.png │ │ │ │ ├── logo@1.25x.png │ │ │ │ ├── logo@1.5x.png │ │ │ │ ├── logo@2x.png │ │ │ │ ├── logo@3x.png │ │ │ │ └── logo@4x.png │ │ │ ├── github.svg │ │ │ └── logo.ai │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.scss │ │ └── test-setup.ts │ ├── tsconfig.app.json │ ├── tsconfig.editor.json │ ├── tsconfig.json │ └── tsconfig.spec.json └── playground │ ├── .browserslistrc │ ├── .eslintrc.json │ ├── jest.config.ts │ ├── project.json │ ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.ts │ │ ├── notifications.service.ts │ │ ├── theater-show │ │ │ ├── model.ts │ │ │ ├── theater-show.component.html │ │ │ ├── theater-show.component.scss │ │ │ ├── theater-show.component.spec.ts │ │ │ └── theater-show.component.ts │ │ └── theater.routes.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test-setup.ts │ ├── tsconfig.app.json │ ├── tsconfig.editor.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── compodoc ├── styles │ └── style.css └── templates │ ├── page.hbs │ └── partials │ ├── additional-page.hbs │ ├── block-accessors.hbs │ ├── block-constructor.hbs │ ├── block-method.hbs │ ├── block-property.hbs │ ├── class.hbs │ ├── index-misc.hbs │ ├── index.hbs │ ├── injectable.hbs │ ├── interface.hbs │ ├── menu.hbs │ └── search-input.hbs ├── decorate-angular-cli.js ├── firebase.json ├── jest.config.ts ├── jest.preset.js ├── libs ├── .gitkeep └── angular-zen │ ├── .compodocrc │ ├── .eslintrc.json │ ├── CHANGELOG.md │ ├── CONTRIBUTING.md │ ├── LICENSE.md │ ├── README.md │ ├── async │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── async.module.ts │ │ ├── index.ts │ │ ├── lazy-loader │ │ ├── lazy-loaded-file.ts │ │ ├── lazy-loader.service.spec.ts │ │ ├── lazy-loader.service.ts │ │ ├── load-options.ts │ │ └── script-load-options.ts │ │ └── utils │ │ ├── promiseLater.ts │ │ └── utils.spec.ts │ ├── core │ ├── README.md │ ├── ng-package.json │ ├── src │ │ ├── core.module.ts │ │ ├── document-ref │ │ │ ├── document-ref.service.spec.ts │ │ │ └── document-ref.service.ts │ │ ├── head │ │ │ ├── element-configs.ts │ │ │ ├── head.service.spec.ts │ │ │ └── head.service.ts │ │ ├── index.ts │ │ ├── rxjs │ │ │ ├── destroyable │ │ │ │ ├── destroyable.spec.ts │ │ │ │ └── destroyable.ts │ │ │ ├── observe │ │ │ │ ├── abstraction │ │ │ │ │ ├── observe-array-base.directive.ts │ │ │ │ │ ├── observe-base.directive.spec.ts │ │ │ │ │ ├── observe-base.directive.ts │ │ │ │ │ ├── observe-map-base.directive.ts │ │ │ │ │ └── types │ │ │ │ │ │ ├── arrays.ts │ │ │ │ │ │ ├── general.ts │ │ │ │ │ │ └── maps.ts │ │ │ │ ├── directives │ │ │ │ │ ├── observe-concat.directive.spec.ts │ │ │ │ │ ├── observe-concat.directive.ts │ │ │ │ │ ├── observe-join.directive.spec.ts │ │ │ │ │ ├── observe-join.directive.ts │ │ │ │ │ ├── observe-latest.directive.spec.ts │ │ │ │ │ ├── observe-latest.directive.ts │ │ │ │ │ ├── observe-merge.directive.spec.ts │ │ │ │ │ ├── observe-merge.directive.ts │ │ │ │ │ ├── observe.directive.spec.ts │ │ │ │ │ └── observe.directive.ts │ │ │ │ └── observe.module.ts │ │ │ └── on-observer │ │ │ │ ├── abstraction │ │ │ │ ├── on-observer-base.directive.ts │ │ │ │ └── types │ │ │ │ │ ├── general.ts │ │ │ │ │ ├── observer-call.ts │ │ │ │ │ ├── on-observer-context.ts │ │ │ │ │ └── view-render-commitment.ts │ │ │ │ ├── directives │ │ │ │ ├── on-observer-active.directive.ts │ │ │ │ ├── on-observer-complete.directive.ts │ │ │ │ ├── on-observer-error.directive.ts │ │ │ │ ├── on-observer-finalized.directive.ts │ │ │ │ ├── on-observer-next.directive.ts │ │ │ │ ├── on-observer-resolving.directive.ts │ │ │ │ └── on-observer.directive.ts │ │ │ │ ├── on-observer.module.ts │ │ │ │ └── utils │ │ │ │ └── time-utils.ts │ │ └── window-ref │ │ │ ├── window-ref.service.spec.ts │ │ │ └── window-ref.service.ts │ └── testing │ │ ├── README.md │ │ ├── ng-package.json │ │ └── src │ │ ├── index.ts │ │ ├── mocks │ │ ├── element.mock.ts │ │ ├── head.mock.ts │ │ ├── link.mock.ts │ │ └── script.mock.ts │ │ └── utils │ │ └── setup.ts │ ├── jest.config.ts │ ├── language │ ├── README.md │ ├── ng-package.json │ ├── src │ │ ├── config │ │ │ ├── language-integration-config.ts │ │ │ ├── language-integration-types.ts │ │ │ └── language-integration.provider.ts │ │ ├── index.ts │ │ ├── language-integration.module.ts │ │ ├── services │ │ │ ├── language-integration.service.spec.ts │ │ │ ├── language-integration.service.ts │ │ │ ├── localized-route-aware.service.spec.ts │ │ │ └── localized-route-aware.service.ts │ │ └── url-localization │ │ │ ├── config │ │ │ ├── url-localization-config.ts │ │ │ ├── url-localization.provider.spec.ts │ │ │ └── url-localization.provider.ts │ │ │ ├── localizers │ │ │ ├── noop-url-localizer.spec.ts │ │ │ ├── noop-url-localizer.ts │ │ │ ├── query-params-url-localizer.spec.ts │ │ │ ├── query-params-url-localizer.ts │ │ │ ├── route-position-url-localizer.spec.ts │ │ │ ├── route-position-url-localizer.ts │ │ │ └── url-localizer.ts │ │ │ └── services │ │ │ ├── url-localization.service.spec.ts │ │ │ └── url-localization.service.ts │ └── testing │ │ ├── README.md │ │ ├── ng-package.json │ │ └── src │ │ ├── index.ts │ │ └── utils │ │ ├── language-integration-config.ts │ │ └── setup.ts │ ├── ng-package.json │ ├── package.json │ ├── project.json │ ├── router-x │ ├── README.md │ ├── navigation │ │ ├── README.md │ │ ├── ng-package.json │ │ └── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── _navigation-x.symbols.ts │ │ │ ├── _utils │ │ │ └── _string-utils.ts │ │ │ ├── navigation-x.injector.ts │ │ │ ├── navigation-x.providers.ts │ │ │ ├── navigation-x.route-creator.ts │ │ │ ├── route-composer │ │ │ ├── _utils.ts │ │ │ └── router-composer.ts │ │ │ └── types │ │ │ ├── ___composer-name-validation.types.ts │ │ │ ├── auto-navigator-methods.types.ts │ │ │ ├── composable-routes.types.ts │ │ │ ├── route-composer.types.ts │ │ │ └── route-paths.types.ts │ ├── ng-package.json │ ├── src │ │ ├── config │ │ │ ├── router-x-config.provider.ts │ │ │ └── router-x-config.ts │ │ ├── index.ts │ │ ├── outlet │ │ │ ├── publish-component.directive.spec.ts │ │ │ ├── publish-component.directive.ts │ │ │ ├── router-outlet-component-bus-service.spec.ts │ │ │ └── router-outlet-component-bus.service.ts │ │ ├── router-x.module.ts │ │ └── services │ │ │ ├── route-aware.service.spec.ts │ │ │ ├── route-aware.service.ts │ │ │ ├── url-reflection.service.spec.ts │ │ │ └── url-reflection.service.ts │ ├── testing │ │ ├── README.md │ │ ├── ng-package.json │ │ └── src │ │ │ ├── index.ts │ │ │ └── utils │ │ │ ├── routes.ts │ │ │ └── setup.ts │ └── utils │ │ ├── README.md │ │ ├── ng-package.json │ │ └── src │ │ ├── index.ts │ │ └── lib │ │ ├── _wrap-in-macro-task.ts │ │ ├── use-activated-route-component-resolves.ts │ │ ├── use-route-deep-scan.ts │ │ ├── use-router-event.ts │ │ ├── use-router-events.ts │ │ └── use-router-outlet-tracker.ts │ ├── src │ ├── index.ts │ └── test-setup.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ ├── universal │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── directives │ │ ├── browser-only.directive.ts │ │ ├── non-browser-only.directive.ts │ │ ├── non-server-only.directive.ts │ │ ├── non-worker-app-only.directive.ts │ │ ├── non-worker-ui-only.directive.ts │ │ ├── platform.directive.ts │ │ ├── server-only.directive.ts │ │ ├── worker-app-only.directive.ts │ │ └── worker-ui-only.directive.ts │ │ ├── index.ts │ │ ├── services │ │ ├── universal.service.spec.ts │ │ └── universal.service.ts │ │ └── universal.module.ts │ └── utils │ ├── README.md │ ├── ng-package.json │ └── src │ ├── access-object.ts │ └── index.ts ├── nx.json ├── package.json ├── pnpm-lock.yaml ├── tools ├── generators │ ├── .gitkeep │ └── generate-wiki-summary.js └── tsconfig.tools.json ├── tsconfig.base.json └── wiki └── angular-zen ├── .attachments ├── Integration-diagram.docx ├── integration-diagram.png ├── logo-icon.svg ├── logo.svg ├── navigation-x-config.png └── navigation-x-usage.png ├── .order ├── AsyncModule.md ├── AsyncModule └── LazyLoaderService.md ├── CoreModule.md ├── CoreModule ├── .order ├── Destroyable-(abstract).md ├── DocumentRef.md ├── DocumentRef │ ├── Internals.md │ └── Mocking.md ├── HeadService.md ├── ObserveModule.md ├── OnObserverModule.md ├── WindowRef.md └── WindowRef │ ├── Internals.md │ └── Mocking.md ├── Getting-Started.md ├── Home.md ├── LanguageIntegrationModule.md ├── LanguageIntegrationModule ├── .order ├── Implementing-in-a-Library.md ├── LocalizedRouteAware-(abstract).md ├── Providing-From-an-App.md └── UrlLocalizationService.md ├── Modules-Overview.md ├── RouterXModule.md ├── RouterXModule ├── .order ├── NavigationX.md ├── RouteAware-(abstract).md ├── RouterOutletComponentBus.md ├── RouterOutletComponentBus │ ├── .order │ └── PublishComponentDirective.md ├── UrlReflectionService.md └── Utils.md ├── UniversalModule.md └── UniversalModule ├── Platform-Directives.md └── UniversalService.md /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | 15 | [*.json] 16 | indent_size = 2 -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "ignorePatterns": ["**/*"], 4 | "plugins": ["@nrwl/nx"], 5 | "overrides": [ 6 | { 7 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 8 | "rules": { 9 | "@nrwl/nx/enforce-module-boundaries": [ 10 | "error", 11 | { 12 | "enforceBuildableLibDependency": true, 13 | "allow": [], 14 | "depConstraints": [ 15 | { 16 | "sourceTag": "*", 17 | "onlyDependOnLibsWithTags": ["*"] 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | }, 24 | { 25 | "files": ["*.ts", "*.tsx"], 26 | "extends": ["plugin:@nrwl/nx/typescript"], 27 | "rules": {} 28 | }, 29 | { 30 | "files": ["*.js", "*.jsx"], 31 | "extends": ["plugin:@nrwl/nx/javascript"], 32 | "rules": {} 33 | }, 34 | { 35 | "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], 36 | "env": { 37 | "jest": true 38 | }, 39 | "rules": {} 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "bespunky-libraries" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: "\U0001F41B Report a bug or an error you've encountered" 4 | title: "\U0001F41B " 5 | labels: "\U0001F41B Bug" 6 | assignees: BeSpunky 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation 3 | about: "\U0001F4C3 Suggest documentation edit and improvements or discuss missing 4 | docs" 5 | title: "\U0001F4C3 " 6 | labels: "\U0001F4C3 Documentation" 7 | assignees: BeSpunky 8 | 9 | --- 10 | 11 | **Topic** 12 | Describe the topic (to be) covered in the documentation. 13 | 14 | > **Example** "How to use the `RouteAware` class with services" 15 | 16 | **What's Missing** 17 | Describe what you would like to see in the documentation. 18 | 19 | **Existing Docs** 20 | If the current documentation covers the topic at least to some extent, add a link to the relevant page(s). 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: "➕ Suggest an idea or request a feature" 4 | title: "➕ " 5 | labels: '' 6 | assignees: BeSpunky 7 | 8 | --- 9 | 10 | 15 | 16 | ***What* Is the Feature** 17 | A clear and concise description of what you want to happen. 18 | 19 | > Examples: 20 | > "A service that will listen to... and automate..." 21 | > "Add a method to ... service that will..." 22 | > "Allow the ... method to receive a param for..." 23 | 24 | ***Why* Is The Feature Needed** 25 | A clear and concise description of what the problem is, and what the use cases are. 26 | 27 | > **Examples** 28 | > "I'm always frustrated when ..." 29 | > "When using the ... service, the it is sometimes necessary to..." 30 | > "Currently, the ... module does not allow ... . If it did, I would use it like this..." 31 | 32 | **Current Alternatives** 33 | A clear and concise description of any alternative solutions or features you've considered. 34 | 35 | **Additional Context** 36 | Add any other context or screenshots about the feature request here. 37 | -------------------------------------------------------------------------------- /.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 | 8 | # dependencies 9 | node_modules 10 | .pnpm-store 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db 41 | 42 | .angular 43 | 44 | \.firebase/ 45 | 46 | chrome-debugging-profile/ 47 | 48 | projects/bespunky/angular-zen/debug.log 49 | 50 | debug.log 51 | 52 | wiki/**/summary.json 53 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | auto-install-peers=true 3 | -------------------------------------------------------------------------------- /.pnpm-debug.log: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | 3 | /dist 4 | /coverage 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "angular.ng-template", 4 | "nrwl.angular-console", 5 | "firsttris.vscode-jest-runner", 6 | "dbaeumer.vscode-eslint", 7 | "vsls-contrib.codetour" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [{ 7 | "name": "Generate wiki summary.json", 8 | "program": "${workspaceFolder}/tools/generators/generate-wiki-summary.js", 9 | "request": "launch", 10 | "skipFiles": [ 11 | "/**" 12 | ], 13 | "args": ["./wiki/angular-zen"], 14 | "type": "pwa-node" 15 | }, 16 | { 17 | "type": "chrome", 18 | "request": "launch", 19 | "name": "ng test", 20 | "url": "http://localhost:9876/debug.html", 21 | "webRoot": "${workspaceFolder}/libs/angular-zen", 22 | "sourceMaps": true, 23 | "sourceMapPathOverrides": { 24 | "ng://@bespunky/angular-zen/*": "${webRoot}/*", 25 | "./*": "${webRoot}/*", 26 | }, 27 | "runtimeArgs": [ 28 | "--headless", 29 | "--user-data-dir=${workspaceFolder}/chrome-debugging-profile", 30 | "--remote-debugging-port=9223" 31 | ], 32 | "port": 9223 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 BeSpunky 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. -------------------------------------------------------------------------------- /apps/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeSpunky/angular-zen/461eaf0faf558b579fcc499e8e7961c059680832/apps/.gitkeep -------------------------------------------------------------------------------- /apps/official-site/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | -------------------------------------------------------------------------------- /apps/official-site/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts"], 7 | "extends": [ 8 | "plugin:@nrwl/nx/angular", 9 | "plugin:@angular-eslint/template/process-inline-templates" 10 | ], 11 | "rules": { 12 | "@angular-eslint/directive-selector": [ 13 | "error", 14 | { 15 | "type": "attribute", 16 | "prefix": "app", 17 | "style": "camelCase" 18 | } 19 | ], 20 | "@angular-eslint/component-selector": [ 21 | "error", 22 | { 23 | "type": "element", 24 | "prefix": "app", 25 | "style": "kebab-case" 26 | } 27 | ] 28 | } 29 | }, 30 | { 31 | "files": ["*.html"], 32 | "extends": ["plugin:@nrwl/nx/angular-template"], 33 | "rules": {} 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /apps/official-site/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'official-site', 4 | preset: '../../jest.preset.js', 5 | setupFilesAfterEnv: ['/src/test-setup.ts'], 6 | globals: { 7 | 'ts-jest': { 8 | tsconfig: '/tsconfig.spec.json', 9 | stringifyContentPathRegex: '\\.(html|svg)$', 10 | }, 11 | }, 12 | coverageDirectory: '../../coverage/apps/official-site', 13 | transform: { 14 | '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular', 15 | }, 16 | transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], 17 | snapshotSerializers: [ 18 | 'jest-preset-angular/build/serializers/no-ng-attributes', 19 | 'jest-preset-angular/build/serializers/ng-snapshot', 20 | 'jest-preset-angular/build/serializers/html-comment', 21 | ], 22 | }; 23 | -------------------------------------------------------------------------------- /apps/official-site/src/app/app-material.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { MatToolbarModule } from '@angular/material/toolbar'; 4 | import { MatCardModule } from '@angular/material/card'; 5 | import { MatButtonModule } from '@angular/material/button'; 6 | import { MatTooltipModule } from '@angular/material/tooltip'; 7 | import { MatIconModule } from '@angular/material/icon'; 8 | import { MatProgressBarModule } from '@angular/material/progress-bar'; 9 | 10 | const exported = [ 11 | MatToolbarModule, 12 | MatCardModule, 13 | MatButtonModule, 14 | MatTooltipModule, 15 | MatIconModule, 16 | MatProgressBarModule 17 | ]; 18 | 19 | @NgModule({ 20 | imports: exported, 21 | exports: exported 22 | }) 23 | export class AppMaterialModule { } -------------------------------------------------------------------------------- /apps/official-site/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { ZenProjects } from './content/all'; 5 | import { project, childProject } from './utils/route-builders'; 6 | 7 | const [MainZenProject, ...ChildZenProjects] = ZenProjects; 8 | 9 | const routes: Routes = [ 10 | // Main zen project at root path along with its topics as root paths (i.e. / + /Core Module + /Async Module ...) 11 | ...project(MainZenProject), 12 | // Child zen projects as project path (e.g. /angular-zen-ux...) 13 | ...ChildZenProjects.map(childProject), 14 | // Anything else go to main zen project homepage 15 | { path: '**', pathMatch: 'full', redirectTo: '' } 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [RouterModule.forRoot(routes, { enableTracing: false })], 20 | exports: [RouterModule] 21 | }) 22 | export class AppRoutingModule { } 23 | -------------------------------------------------------------------------------- /apps/official-site/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{currentProject.strongName}} 5 | 6 | 7 | Docs 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/official-site/src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeSpunky/angular-zen/461eaf0faf558b579fcc499e8e7961c059680832/apps/official-site/src/app/app.component.scss -------------------------------------------------------------------------------- /apps/official-site/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { ProjectService } from './services/project.service'; 4 | 5 | @Component({ 6 | selector : 'app-root', 7 | templateUrl: './app.component.html', 8 | styleUrls : ['./app.component.scss'] 9 | }) 10 | export class AppComponent 11 | { 12 | constructor(public project: ProjectService) { } 13 | } 14 | -------------------------------------------------------------------------------- /apps/official-site/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 3 | import { NgModule } from '@angular/core'; 4 | import { CommonModule } from '@angular/common'; 5 | import { FlexLayoutModule } from '@angular/flex-layout'; 6 | 7 | import { AppRoutingModule } from './app-routing.module'; 8 | import { AppMaterialModule } from './app-material.module'; 9 | import { AppComponent } from './app.component'; 10 | import { LibraryBenefitsComponent } from './components/library-benefits/library-benefits.component'; 11 | import { HomeComponent } from './components/home/home.component'; 12 | import { TopicComponent } from './components/topic/topic.component'; 13 | import { ExampleListComponent } from './components/example-list/example-list.component'; 14 | import { ExampleComponent } from './components/example/example.component'; 15 | 16 | import { CoreModule } from '@bespunky/angular-zen/core'; 17 | 18 | @NgModule({ 19 | declarations: [ 20 | AppComponent, 21 | HomeComponent, 22 | LibraryBenefitsComponent, 23 | TopicComponent, 24 | ExampleListComponent, 25 | ExampleComponent, 26 | ], 27 | imports: [ 28 | BrowserModule, 29 | BrowserAnimationsModule, 30 | CommonModule, 31 | AppRoutingModule, 32 | AppMaterialModule, 33 | FlexLayoutModule, CoreModule 34 | ], 35 | providers: [], 36 | bootstrap: [AppComponent] 37 | }) 38 | export class AppModule { } 39 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/example-list/example-list.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/example-list/example-list.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeSpunky/angular-zen/461eaf0faf558b579fcc499e8e7961c059680832/apps/official-site/src/app/components/example-list/example-list.component.scss -------------------------------------------------------------------------------- /apps/official-site/src/app/components/example-list/example-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | export interface CardInfo 4 | { 5 | title : string; 6 | subtitle?: string; 7 | icon : string; 8 | content : string; 9 | soon? : boolean; 10 | } 11 | 12 | @Component({ 13 | selector : 'app-example-list', 14 | templateUrl: './example-list.component.html', 15 | styleUrls : ['./example-list.component.scss'] 16 | }) 17 | export class ExampleListComponent 18 | { 19 | @Input() public cards: CardInfo[] = []; 20 | } 21 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/example/example.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{example.icon}} {{example.title}} keyboard_arrow_up

4 |

{{example.description}}

5 |

{{example.notes}}

6 |
7 |
8 | 9 |
10 | 11 |
-------------------------------------------------------------------------------- /apps/official-site/src/app/components/example/example.component.scss: -------------------------------------------------------------------------------- 1 | embed, 2 | iframe { 3 | width : 100%; 4 | height : 95vh; 5 | border : none; 6 | box-shadow: 0 0 4px rgba(0, 0, 0, .5); 7 | } 8 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/example/example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; 4 | 5 | import { Example } from '../../types/example'; 6 | 7 | @Component({ 8 | selector : 'app-example', 9 | templateUrl: './example.component.html', 10 | styleUrls : ['./example.component.scss'] 11 | }) 12 | export class ExampleComponent 13 | { 14 | public example : Example; 15 | public safeEmbedUrl: SafeResourceUrl; 16 | public loaded = false; 17 | 18 | constructor(private sanitizer: DomSanitizer, route: ActivatedRoute) 19 | { 20 | this.example = route.snapshot.data as Example; 21 | this.safeEmbedUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.example.embedUrl); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/home/home.component.scss: -------------------------------------------------------------------------------- 1 | .cover-image { 2 | content : ''; 3 | position : absolute; 4 | top : 0; 5 | bottom : 0; 6 | left : 0; 7 | right : 0; 8 | z-index : -1; 9 | background-size : cover; 10 | background-position: center center; 11 | background-repeat : no-repeat; 12 | } 13 | 14 | .project-link { 15 | padding: 10px 25px !important; 16 | } 17 | 18 | .project-link.soon::before { 19 | content : '🚧 Soon'; 20 | padding-top : 0; 21 | padding-bottom: 0; 22 | top : -12px; 23 | right : initial; 24 | left : -10px; 25 | transform : rotate(-7deg); 26 | } 27 | 28 | .demos { 29 | background: rgba(0, 0, 0, 0.14); 30 | } 31 | 32 | .footer a { 33 | color: rgb(71, 71, 71); 34 | } 35 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { Project } from '../../types/project'; 4 | import { CardInfo } from '../example-list/example-list.component'; 5 | import { ActivatedRoute } from '@angular/router'; 6 | 7 | @Component({ 8 | selector : 'app-home', 9 | templateUrl: './home.component.html', 10 | styleUrls : ['./home.component.scss'] 11 | }) 12 | export class HomeComponent 13 | { 14 | public project: Project; 15 | public cards : CardInfo[]; 16 | 17 | constructor(route: ActivatedRoute) 18 | { 19 | this.project = route.snapshot.data as Project; 20 | this.cards = this.project.examplesTopics.map(topic => ({ 21 | title : topic.title, 22 | subtitle: `${topic.examples.length} examples`, 23 | icon : topic.icon, 24 | content : topic.description 25 | })); 26 | } 27 | 28 | public slideTo(element: HTMLElement): void 29 | { 30 | element.scrollIntoView({ behavior: 'smooth', block: 'start' }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/library-benefits/library-benefits.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |

{{benefit.title}}

4 |

{{benefit.description}}

5 |

{{benefit.emoji}}

6 |
7 |
-------------------------------------------------------------------------------- /apps/official-site/src/app/components/library-benefits/library-benefits.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeSpunky/angular-zen/461eaf0faf558b579fcc499e8e7961c059680832/apps/official-site/src/app/components/library-benefits/library-benefits.component.scss -------------------------------------------------------------------------------- /apps/official-site/src/app/components/library-benefits/library-benefits.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Benefit } from '../../types/benefit'; 3 | 4 | @Component({ 5 | selector : 'app-library-benefits', 6 | templateUrl: './library-benefits.component.html', 7 | styleUrls : ['./library-benefits.component.scss'] 8 | }) 9 | export class LibraryBenefitsComponent 10 | { 11 | @Input() public benefits: Benefit[] = []; 12 | } 13 | -------------------------------------------------------------------------------- /apps/official-site/src/app/components/topic/topic.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{topic.title}} keyboard_arrow_up

4 |

{{topic.description}}

5 |
6 | 7 | 8 |
-------------------------------------------------------------------------------- /apps/official-site/src/app/components/topic/topic.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeSpunky/angular-zen/461eaf0faf558b579fcc499e8e7961c059680832/apps/official-site/src/app/components/topic/topic.component.scss -------------------------------------------------------------------------------- /apps/official-site/src/app/components/topic/topic.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | 4 | import { Topic } from '../../types/topic'; 5 | import { CardInfo } from '../example-list/example-list.component'; 6 | 7 | @Component({ 8 | selector : 'app-topic', 9 | templateUrl: './topic.component.html', 10 | styleUrls : ['./topic.component.scss'] 11 | }) 12 | export class TopicComponent 13 | { 14 | public topic: Topic; 15 | public cards: CardInfo[]; 16 | 17 | constructor(route: ActivatedRoute) 18 | { 19 | this.topic = route.snapshot.data as Topic; 20 | this.cards = this.topic.examples.map(example => ({ 21 | title : example.title, 22 | subtitle: '', 23 | icon : example.icon, 24 | content : example.description, 25 | soon : example.soon 26 | })); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /apps/official-site/src/app/content/all.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '../types/project'; 2 | import { ZenProject } from './angular-zen/project'; 3 | import { ZenUxProject } from './angular-zen-ux/project'; 4 | import { ZenSeoProject } from './angular-zen-seo/project'; 5 | 6 | export const ZenProjects: Project[] = [ 7 | ZenProject, 8 | ZenUxProject, 9 | ZenSeoProject 10 | ]; 11 | 12 | // Manually setting linked projects creates circular dependencies between project files. 13 | // Also this saves time in manually going through all the files to modify its linked projects. 14 | function linkProjects() 15 | { 16 | // For each project, add all other projects as linked projects 17 | ZenProjects.forEach((project, index) => 18 | { 19 | const linkedProjects = [...ZenProjects]; // Cloned to preserve original array 20 | 21 | linkedProjects.splice(index, 1); 22 | 23 | project.linkedProjects = linkedProjects; 24 | 25 | return linkedProjects; 26 | }); 27 | } 28 | 29 | linkProjects(); -------------------------------------------------------------------------------- /apps/official-site/src/app/content/angular-zen-seo/examples/01.getting-started.ts: -------------------------------------------------------------------------------- 1 | // import { Example } from '../types/example'; 2 | // import { Topic } from '../types/topic'; 3 | 4 | // export const GettingStartedExamples: Example[] = [ 5 | // { 6 | // title : 'Plug & Play', 7 | // description: 'Have the library import Google Maps API for you and add a simple map.', 8 | // notes : 'You\'ll need to have your own key to Google Maps API. See example for link.', 9 | // icon : 'power', 10 | // embedUrl : 'https://stackblitz.com/edit/bs-google-maps-plug-n-play?embed=1&file=src/app/app.module.ts' 11 | // }, 12 | // { 13 | // title : 'Custom Loader', 14 | // description: 'Implement your own mechanism for loading Google Maps API.', 15 | // notes : 'You\'ll need to have your own key to Google Maps API. See example for link.', 16 | // icon : 'build', 17 | // embedUrl : 'https://stackblitz.com/edit/bs-google-maps-custom-loader?embed=1&file=src/app/app.module.ts' 18 | // }, 19 | // { 20 | // title : 'Manual Loading', 21 | // description: 'Manually add a