├── .browserslistrc ├── .github └── workflows │ └── main.yml ├── .gitignore ├── LICENSE ├── README.md ├── additional-doc ├── actions.md ├── actions │ ├── creation.md │ ├── delete.md │ ├── edition.md │ └── status.md ├── edition.md ├── introduction.md └── summary.json ├── angular.json ├── package-lock.json ├── package.json ├── screenshots ├── about.png ├── actions │ ├── creation.png │ ├── delete.png │ ├── edition.png │ └── update-status.png ├── components │ ├── footer-list.png │ ├── footer.png │ ├── header.png │ └── list.png ├── home.png └── todo │ └── todo.png ├── src ├── app │ ├── about │ │ ├── about.component.html │ │ ├── about.component.ts │ │ ├── about.module.md │ │ ├── about.module.ts │ │ ├── about.routes.ts │ │ ├── compodoc │ │ │ ├── compodoc.component.html │ │ │ └── compodoc.component.ts │ │ ├── index.ts │ │ └── todomvc │ │ │ ├── todomvc.component.html │ │ │ └── todomvc.component.ts │ ├── app-routes.enum.ts │ ├── app-routing.module.ts │ ├── app.component-ext.css │ ├── app.component.css │ ├── app.component.html │ ├── app.component.ts │ ├── app.module.ts │ ├── file-to-exclude.ts │ ├── footer │ │ ├── footer.component.html │ │ ├── footer.component.ts │ │ ├── footer.module.ts │ │ └── index.ts │ ├── header │ │ ├── header.component.html │ │ ├── header.component.ts │ │ ├── header.module.ts │ │ └── index.ts │ ├── home │ │ ├── home-routing.module.ts │ │ ├── home.component.html │ │ ├── home.component.ts │ │ ├── home.module.ts │ │ └── index.ts │ ├── index.ts │ ├── list │ │ ├── index.ts │ │ ├── list.component.html │ │ ├── list.component.md │ │ ├── list.component.ts │ │ ├── list.module.ts │ │ └── todo │ │ │ ├── index.ts │ │ │ ├── todo.component.html │ │ │ ├── todo.component.md │ │ │ ├── todo.component.ts │ │ │ └── todo.module.ts │ └── shared │ │ ├── components │ │ ├── empty-component.ts │ │ └── empty-parent-component.ts │ │ ├── decorators │ │ └── log.decorator.ts │ │ ├── directives │ │ ├── border.directive.ts │ │ ├── do-nothing.directive.md │ │ ├── do-nothing.directive.ts │ │ ├── highlight-and-border.directive.ts │ │ └── highlight.directive.ts │ │ ├── enums │ │ └── enum.ts │ │ ├── guards │ │ └── noopguard.guard.ts │ │ ├── interceptors │ │ └── noopinterceptor.interceptor.ts │ │ ├── interfaces │ │ ├── clock.interface.md │ │ ├── clock.interface.ts │ │ ├── interfaces.ts │ │ └── time.interface.ts │ │ ├── miscellaneous │ │ ├── miscellaneous-types.ts │ │ └── miscellaneous.ts │ │ ├── models │ │ ├── todo.model.md │ │ └── todo.model.ts │ │ ├── pipes │ │ ├── first-upper.pipe.md │ │ ├── first-upper.pipe.ts │ │ └── standalone.pipe.ts │ │ └── services │ │ ├── emitter.service.ts │ │ ├── empty.service.ts │ │ ├── todo.store.md │ │ └── todo.store.ts ├── assets │ └── .gitkeep ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts └── styles.css ├── tsconfig.app.json ├── tsconfig.doc.json ├── tsconfig.json └── tslint.json /.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 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | push: 9 | branches: [ master ] 10 | pull_request: 11 | branches: [ master ] 12 | 13 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 14 | jobs: 15 | # This workflow contains a single job called "build" 16 | build: 17 | # The type of runner that the job will run on 18 | runs-on: ubuntu-latest 19 | 20 | # Steps represent a sequence of tasks that will be executed as part of the job 21 | steps: 22 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 23 | - uses: actions/checkout@v2 24 | 25 | - name: Cache node modules 26 | uses: actions/cache@v1 27 | with: 28 | path: node_modules 29 | key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} 30 | restore-keys: | 31 | ${{ runner.OS }}-build-${{ env.cache-name }}- 32 | ${{ runner.OS }}-build- 33 | ${{ runner.OS }}- 34 | 35 | - name: Install Dependencies 36 | run: npm ci 37 | - name: Build doc 38 | run: npm run doc 39 | - name: Archive www Artifact 40 | uses: actions/upload-artifact@master 41 | with: 42 | name: documentation 43 | path: documentation 44 | deploy: 45 | name : Deploy 🚀 46 | needs: [build] 47 | runs-on: ubuntu-latest 48 | steps: 49 | - name: Checkout Repo 50 | uses: actions/checkout@master 51 | - name: Download Artifact 52 | uses: actions/download-artifact@master 53 | with: 54 | name: documentation 55 | path: documentation 56 | - name: Deploy to github pages 57 | uses: JamesIves/github-pages-deploy-action@3.6.2 58 | with: 59 | GITHUB_TOKEN: ${{ secrets.COMPODOC_GITHUB_PAGES_TOKEN }} 60 | BRANCH: gh-pages # The branch the action should deploy to. 61 | FOLDER: documentation # The folder the action should deploy. 62 | CLEAN: true # Automatically remove deleted files from the deploy branch 63 | -------------------------------------------------------------------------------- /.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 | .angular 8 | # Only exists if Bazel was run 9 | /bazel-out 10 | 11 | # dependencies 12 | /node_modules 13 | 14 | # profiling files 15 | chrome-profiler-events.json 16 | speed-measure-plugin.json 17 | 18 | # IDEs and editors 19 | /.idea 20 | .project 21 | .classpath 22 | .c9/ 23 | *.launch 24 | .settings/ 25 | *.sublime-workspace 26 | 27 | # IDE - VSCode 28 | .vscode/* 29 | !.vscode/settings.json 30 | !.vscode/tasks.json 31 | !.vscode/launch.json 32 | !.vscode/extensions.json 33 | .history/* 34 | 35 | # misc 36 | /.sass-cache 37 | /connect.lock 38 | /coverage 39 | /libpeerconnection.log 40 | npm-debug.log 41 | yarn-error.log 42 | testem.log 43 | /typings 44 | 45 | # System Files 46 | .DS_Store 47 | Thumbs.db 48 | 49 | documentation -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 compodoc 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Compodoc Demo TodoMVC Angular 2 | 3 | This project was generated with [angular-cli](https://github.com/angular/angular-cli). 4 | 5 | It is a demo project for demonstrating Compodoc features : 6 | 7 | - architecture 8 | - components documentation 9 | - embedding images 10 | - documentating methods and properties of components, classes, interfaces, etc... 11 | 12 | ## Development server 13 | 14 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 15 | 16 | ## Code scaffolding 17 | 18 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`. 19 | 20 | ## Build 21 | 22 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. 23 | 24 | ## Further help 25 | 26 | To get more help on the `angular-cli` use `ng --help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 27 | 28 | ## Compodoc supports syntax highlighting 29 | 30 | ```javascript 31 | function hello() { 32 | console.log('hello world !'); 33 | } 34 | ``` 35 | 36 | ## Screenshots of the application - (for assets embedding demo) 37 | 38 | | Home page | About page | 39 | | ------------------------------------- | -------------------------------------- | 40 | | ![Screenshot-1](screenshots/home.png) | ![Screenshot-2](screenshots/about.png) | 41 | -------------------------------------------------------------------------------- /additional-doc/actions.md: -------------------------------------------------------------------------------- 1 | # All actions 2 | 3 | - [creation](./actions/creation-of-a-todo.html) 4 | - [edition](./actions/edition-of-a-todo.html) 5 | - [delete](./actions/delete-a-todo.html) 6 | - [change status](./actions/update-the-status-of-a-todo.html) 7 | -------------------------------------------------------------------------------- /additional-doc/actions/creation.md: -------------------------------------------------------------------------------- 1 | # Creation of a todo 2 | 3 | Just use the top input to create a todo. 4 | 5 | ![Screenshot](../../screenshots/actions/creation.png) 6 | -------------------------------------------------------------------------------- /additional-doc/actions/delete.md: -------------------------------------------------------------------------------- 1 | # Delete a todo 2 | 3 | Just click on the right arrow to delete a todo. 4 | 5 | ![Screenshot](../../screenshots/actions/delete.png) 6 | -------------------------------------------------------------------------------- /additional-doc/actions/edition.md: -------------------------------------------------------------------------------- 1 | # Edition of a todo 2 | 3 | Just double click on the todo label to edit a todo. 4 | 5 | ![Screenshot](../../screenshots/actions/edition.png) 6 | -------------------------------------------------------------------------------- /additional-doc/actions/status.md: -------------------------------------------------------------------------------- 1 | # Status of a todo 2 | 3 | Just click on the left arrow to edit the status of a todo. 4 | 5 | ![Screenshot](../../screenshots/actions/update-status.png) 6 | -------------------------------------------------------------------------------- /additional-doc/edition.md: -------------------------------------------------------------------------------- 1 | # All edition actions 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /additional-doc/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This app is a simple todo list application 4 | 5 | ## Main features 6 | 7 | - add a todo 8 | - edit a todo 9 | - delete a todo 10 | - update status of a todo 11 | - filter displayed todos 12 | 13 | ## A todo 14 | 15 | A todo is displayed using todo component [TodoComponent](../components/TodoComponent.html). 16 | -------------------------------------------------------------------------------- /additional-doc/summary.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Introduction", 4 | "file": "introduction.md" 5 | }, 6 | { 7 | "title": "Actions", 8 | "file": "actions.md", 9 | "children": [ 10 | { 11 | "title": "Creation of a todo", 12 | "file": "actions/creation.md" 13 | }, 14 | { 15 | "title": "Edition of a todo", 16 | "file": "actions/edition.md" 17 | }, 18 | { 19 | "title": "Delete a todo", 20 | "file": "actions/delete.md" 21 | }, 22 | { 23 | "title": "Update the status of a todo", 24 | "file": "actions/status.md" 25 | } 26 | ] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "compodoc-demo-todomvc-angular": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:class": { 10 | "skipTests": true 11 | }, 12 | "@schematics/angular:component": { 13 | "skipTests": true 14 | }, 15 | "@schematics/angular:directive": { 16 | "skipTests": true 17 | }, 18 | "@schematics/angular:guard": { 19 | "skipTests": true 20 | }, 21 | "@schematics/angular:module": { 22 | "skipTests": true 23 | }, 24 | "@schematics/angular:pipe": { 25 | "skipTests": true 26 | }, 27 | "@schematics/angular:service": { 28 | "skipTests": true 29 | } 30 | }, 31 | "root": "", 32 | "sourceRoot": "src", 33 | "prefix": "app", 34 | "architect": { 35 | "build": { 36 | "builder": "@angular-devkit/build-angular:browser", 37 | "options": { 38 | "outputPath": "dist/compodoc-demo-todomvc-angular", 39 | "index": "src/index.html", 40 | "main": "src/main.ts", 41 | "polyfills": ["zone.js"], 42 | "tsConfig": "tsconfig.app.json", 43 | "aot": true, 44 | "assets": ["src/favicon.ico", "src/assets"], 45 | "styles": ["src/styles.css", "node_modules/todomvc-common/base.css", "node_modules/todomvc-app-css/index.css"], 46 | "scripts": [] 47 | }, 48 | "configurations": { 49 | "production": { 50 | "fileReplacements": [ 51 | { 52 | "replace": "src/environments/environment.ts", 53 | "with": "src/environments/environment.prod.ts" 54 | } 55 | ], 56 | "optimization": true, 57 | "outputHashing": "all", 58 | "sourceMap": false, 59 | "extractCss": true, 60 | "namedChunks": false, 61 | "aot": true, 62 | "extractLicenses": true, 63 | "vendorChunk": false, 64 | "buildOptimizer": true, 65 | "budgets": [ 66 | { 67 | "type": "initial", 68 | "maximumWarning": "2mb", 69 | "maximumError": "5mb" 70 | } 71 | ] 72 | } 73 | } 74 | }, 75 | "serve": { 76 | "builder": "@angular-devkit/build-angular:dev-server", 77 | "options": { 78 | "browserTarget": "compodoc-demo-todomvc-angular:build" 79 | }, 80 | "configurations": { 81 | "production": { 82 | "browserTarget": "compodoc-demo-todomvc-angular:build:production" 83 | } 84 | } 85 | }, 86 | "extract-i18n": { 87 | "builder": "@angular-devkit/build-angular:extract-i18n", 88 | "options": { 89 | "browserTarget": "compodoc-demo-todomvc-angular:build" 90 | } 91 | } 92 | } 93 | } 94 | }, 95 | "defaultProject": "compodoc-demo-todomvc-angular" 96 | } 97 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compodoc-demo-todomvc-angular", 3 | "version": "0.0.0", 4 | "url": "https://github.com/compodoc/compodoc-demo-todomvc-angular", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build", 9 | "lint": "ng lint", 10 | "doc": "./node_modules/.bin/compodoc -p tsconfig.doc.json -a screenshots -n \"TodoMVC Angular documentation\" --includes additional-doc" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/common": "^17.3.5", 15 | "@angular/compiler": "^17.3.5", 16 | "@angular/core": "^17.3.5", 17 | "@angular/forms": "^17.3.5", 18 | "@angular/platform-browser": "^17.3.5", 19 | "@angular/platform-browser-dynamic": "^17.3.5", 20 | "@angular/router": "^17.3.5", 21 | "rxjs": "~7.8.1", 22 | "todomvc-app-css": "^2.4.3", 23 | "todomvc-common": "^1.0.5", 24 | "tslib": "^2.6.2", 25 | "zone.js": "~0.14.4" 26 | }, 27 | "devDependencies": { 28 | "@angular-devkit/build-angular": "^17.3.5", 29 | "@angular/cli": "~17.3.5", 30 | "@angular/compiler-cli": "^17.3.5", 31 | "@angular/language-service": "~17.3.5", 32 | "@compodoc/compodoc": "1.1.24", 33 | "@types/node": "~20.12.7", 34 | "ts-node": "~10.9.2", 35 | "tslint": "~6.1.3", 36 | "typescript": "~5.4.5" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /screenshots/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/about.png -------------------------------------------------------------------------------- /screenshots/actions/creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/actions/creation.png -------------------------------------------------------------------------------- /screenshots/actions/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/actions/delete.png -------------------------------------------------------------------------------- /screenshots/actions/edition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/actions/edition.png -------------------------------------------------------------------------------- /screenshots/actions/update-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/actions/update-status.png -------------------------------------------------------------------------------- /screenshots/components/footer-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/components/footer-list.png -------------------------------------------------------------------------------- /screenshots/components/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/components/footer.png -------------------------------------------------------------------------------- /screenshots/components/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/components/header.png -------------------------------------------------------------------------------- /screenshots/components/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/components/list.png -------------------------------------------------------------------------------- /screenshots/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/home.png -------------------------------------------------------------------------------- /screenshots/todo/todo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/screenshots/todo/todo.png -------------------------------------------------------------------------------- /src/app/about/about.component.html: -------------------------------------------------------------------------------- 1 |

2 | This application is a TodoMVC example written using Angular, with code documented, and ready for compodoc. 3 |

4 | 5 | -------------------------------------------------------------------------------- /src/app/about/about.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, HostListener } from '@angular/core'; 2 | 3 | import { EmptyService } from '../shared/services/empty.service'; 4 | import { DoNothingDirective } from '../shared/directives/do-nothing.directive'; 5 | 6 | /** 7 | * The about component 8 | * 9 | * Display some text with links for details about TodoMVC & Compodoc. 10 | */ 11 | @Component({ 12 | selector: 'about', 13 | templateUrl: './about.component.html', 14 | providers: [EmptyService], 15 | hostDirectives: [DoNothingDirective], 16 | }) 17 | export class AboutComponent implements OnInit { 18 | ngOnInit() {} 19 | 20 | /** 21 | * HostListener mouseup description 22 | */ 23 | @HostListener('mouseup') 24 | onMouseup(): void {} 25 | } 26 | -------------------------------------------------------------------------------- /src/app/about/about.module.md: -------------------------------------------------------------------------------- 1 | # About module 2 | -------------------------------------------------------------------------------- /src/app/about/about.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import { AboutComponent } from './about.component'; 5 | import { TodoMVCComponent } from './todomvc/todomvc.component'; 6 | import { CompodocComponent } from './compodoc/compodoc.component'; 7 | 8 | import { ABOUT_ROUTES } from './about.routes'; 9 | 10 | /** 11 | * The about module 12 | * 13 | * Just embedding component and it's routing definition in {@link AboutRoutingModule} 14 | */ 15 | @NgModule({ 16 | declarations: [AboutComponent, TodoMVCComponent, CompodocComponent], 17 | imports: [RouterModule.forChild(ABOUT_ROUTES)] 18 | }) 19 | export class AboutModule {} 20 | -------------------------------------------------------------------------------- /src/app/about/about.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | import { AboutComponent } from './about.component'; 4 | import { TodoMVCComponent } from './todomvc/todomvc.component'; 5 | import { CompodocComponent } from './compodoc/compodoc.component'; 6 | 7 | /** 8 | * About Routing module 9 | * 10 | * Exposing just two routes, one for Compodoc, the other one for TodoMVC 11 | */ 12 | export const ABOUT_ROUTES: Routes = [ 13 | { 14 | path: '', component: AboutComponent, 15 | children: [ 16 | { path: '', redirectTo: 'todomvc', pathMatch: 'full' }, 17 | { path: 'todomvc', component: TodoMVCComponent }, 18 | { path: 'compodoc', component: CompodocComponent } 19 | ] 20 | } 21 | ]; 22 | -------------------------------------------------------------------------------- /src/app/about/compodoc/compodoc.component.html: -------------------------------------------------------------------------------- 1 | Compodoc is a great Angular documentation tool : Github repository 2 | -------------------------------------------------------------------------------- /src/app/about/compodoc/compodoc.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | /** 4 | * The compodoc component 5 | */ 6 | @Component({ 7 | selector: 'compodoc', 8 | templateUrl: './compodoc.component.html' 9 | }) 10 | export class CompodocComponent { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/app/about/index.ts: -------------------------------------------------------------------------------- 1 | export * from './about.module'; 2 | export * from './about.component'; 3 | -------------------------------------------------------------------------------- /src/app/about/todomvc/todomvc.component.html: -------------------------------------------------------------------------------- 1 | TodoMVC is a great project helping you select an MV* framework : website 2 | -------------------------------------------------------------------------------- /src/app/about/todomvc/todomvc.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | /** 4 | * The todomvc component 5 | */ 6 | @Component({ 7 | selector: 'todomvc', 8 | templateUrl: './todomvc.component.html' 9 | }) 10 | export class TodoMVCComponent { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/app/app-routes.enum.ts: -------------------------------------------------------------------------------- 1 | export enum APP_ENUMS { 2 | home = 'home' 3 | } 4 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { AboutModule } from './about'; 4 | 5 | import { APP_ENUMS } from './app-routes.enum'; 6 | 7 | enum APP_ENUM { 8 | home = 'home', 9 | } 10 | 11 | export const APP_ROUTES: Routes = [ 12 | { 13 | path: 'about', 14 | loadChildren: () => import('./about/about.module').then((m) => m.AboutModule), 15 | }, 16 | //{ path: 'about', loadChildren: './about/about.module#AboutModule' }, 17 | { path: '', redirectTo: APP_ENUMS.home, pathMatch: 'full' }, 18 | { path: '**', redirectTo: APP_ENUM.home, pathMatch: 'full' }, 19 | ]; 20 | 21 | @NgModule({ 22 | imports: [RouterModule.forRoot(APP_ROUTES)], 23 | exports: [RouterModule], 24 | }) 25 | export class AppRoutingModule {} 26 | -------------------------------------------------------------------------------- /src/app/app.component-ext.css: -------------------------------------------------------------------------------- 1 | .links a { 2 | font-size: 14px; 3 | } -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .links a { 2 | font-weight: bold; 3 | } -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css', './app.component-ext.css'] 7 | }) 8 | export class AppComponent {} 9 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { HTTP_INTERCEPTORS } from '@angular/common/http'; 4 | 5 | import { HomeModule } from './home/'; 6 | 7 | import { AppRoutingModule } from './app-routing.module'; 8 | import { AppComponent } from './app.component'; 9 | 10 | import { TodoStore } from './shared/services/todo.store'; 11 | import { NoopInterceptor } from './shared/interceptors/noopinterceptor.interceptor'; 12 | 13 | @NgModule({ 14 | declarations: [AppComponent], 15 | imports: [BrowserModule, HomeModule, AppRoutingModule], 16 | providers: [ 17 | TodoStore, 18 | { 19 | provide: HTTP_INTERCEPTORS, 20 | useClass: NoopInterceptor, 21 | multi: true 22 | } 23 | ], 24 | bootstrap: [AppComponent] 25 | }) 26 | export class AppModule {} 27 | -------------------------------------------------------------------------------- /src/app/file-to-exclude.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/src/app/file-to-exclude.ts -------------------------------------------------------------------------------- /src/app/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /src/app/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { TodoStore } from '../shared/services/todo.store'; 4 | 5 | import { EmitterService } from '../shared/services/emitter.service'; 6 | 7 | import { LogMethod, LogProperty, LogPropertyWithArgs, LogClass } from '../shared/decorators/log.decorator'; 8 | 9 | /** 10 | * The footer component 11 | */ 12 | @LogClass 13 | @Component({ 14 | selector: 'footer', 15 | providers: [], 16 | templateUrl: './footer.component.html' 17 | }) 18 | export class FooterComponent { 19 | /** 20 | * Local reference of TodoStore 21 | */ 22 | todoStore: TodoStore; 23 | /** 24 | * Local id for EmitterService 25 | */ 26 | @LogProperty 27 | id = 'FooterComponent'; 28 | /** 29 | * Starting filter param 30 | */ 31 | @LogPropertyWithArgs('theCurrentFilter') 32 | currentFilter = 'all'; 33 | 34 | /** 35 | * The "constructor" 36 | * 37 | * @param {TodoStore} todoStore A TodoStore 38 | */ 39 | constructor(todoStore: TodoStore) { 40 | this.todoStore = todoStore; 41 | } 42 | 43 | /** 44 | * Removes all the completed todos 45 | */ 46 | @LogMethod 47 | removeCompleted() { 48 | this.todoStore.removeCompleted(); 49 | switch (this.currentFilter) { 50 | case 'completed': 51 | EmitterService.get(this.id).emit('displayCompleted'); 52 | break; 53 | case 'remaining': 54 | EmitterService.get(this.id).emit('displayRemaining'); 55 | break; 56 | case 'all': 57 | EmitterService.get(this.id).emit('displayAll'); 58 | break; 59 | } 60 | } 61 | 62 | /** 63 | * Display only completed todos 64 | */ 65 | displayCompleted() { 66 | this.currentFilter = 'completed'; 67 | EmitterService.get(this.id).emit('displayCompleted'); 68 | } 69 | 70 | /** 71 | * Display only remaining todos 72 | */ 73 | displayRemaining() { 74 | this.currentFilter = 'remaining'; 75 | EmitterService.get(this.id).emit('displayRemaining'); 76 | } 77 | 78 | /** 79 | * Display all todos 80 | */ 81 | displayAll() { 82 | this.currentFilter = 'all'; 83 | EmitterService.get(this.id).emit('displayAll'); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/app/footer/footer.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | 4 | import { FooterComponent } from './footer.component'; 5 | 6 | /** 7 | * The footer module 8 | */ 9 | @NgModule({ 10 | imports: [ 11 | BrowserModule 12 | ], 13 | declarations: [ 14 | FooterComponent 15 | ], 16 | exports: [FooterComponent] 17 | }) 18 | export class FooterModule { } 19 | -------------------------------------------------------------------------------- /src/app/footer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './footer.module'; 2 | -------------------------------------------------------------------------------- /src/app/header/header.component.html: -------------------------------------------------------------------------------- 1 |

{{title}}

2 | 3 | -------------------------------------------------------------------------------- /src/app/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | import { TodoStore } from '../shared/services/todo.store'; 4 | 5 | /** 6 | * The header component 7 | */ 8 | @Component({ 9 | selector: 'header', 10 | templateUrl: './header.component.html', 11 | styles: [ 12 | `h1 { 13 | margin-top: 75px; 14 | }` 15 | ] 16 | }) 17 | export class HeaderComponent { 18 | /** 19 | * Application main title 20 | */ 21 | title = 'todos'; 22 | 23 | /** 24 | * Local reference of TodoStore 25 | */ 26 | todoStore: TodoStore; 27 | 28 | /** 29 | * The data-binding value of the input tag, added on enter to the todo store 30 | */ 31 | @Input() 32 | newTodoText = ''; 33 | 34 | constructor(todoStore: TodoStore) { 35 | this.todoStore = todoStore; 36 | } 37 | 38 | /** 39 | * Ad a todo to the list 40 | */ 41 | addTodo() { 42 | if (this.newTodoText.trim().length) { 43 | this.todoStore.add(this.newTodoText); 44 | this.newTodoText = ''; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/header/header.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ModuleWithProviders } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | 4 | import { HeaderComponent } from './header.component'; 5 | 6 | /** 7 | * The header module 8 | */ 9 | @NgModule({ 10 | imports: [FormsModule], 11 | declarations: [HeaderComponent], 12 | exports: [HeaderComponent], 13 | }) 14 | export class HeaderModule { 15 | public static forRoot(): ModuleWithProviders { 16 | return { ngModule: HeaderModule, providers: [] }; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/header/index.ts: -------------------------------------------------------------------------------- 1 | export * from './header.module'; 2 | -------------------------------------------------------------------------------- /src/app/home/home-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { HomeComponent } from './home.component'; 5 | 6 | const HOME_ROUTES: Routes = [ 7 | { path: 'home', component: HomeComponent } 8 | ]; 9 | 10 | @NgModule({ 11 | imports: [RouterModule.forChild(HOME_ROUTES)], 12 | exports: [RouterModule] 13 | }) 14 | export class HomeRoutingModule {} 15 | -------------------------------------------------------------------------------- /src/app/home/home.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | -------------------------------------------------------------------------------- /src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | /** 4 | * The home component 5 | */ 6 | @Component({ 7 | selector: 'home', 8 | templateUrl: './home.component.html' 9 | }) 10 | export class HomeComponent { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/app/home/home.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { HttpClientModule } from '@angular/common/http'; 5 | 6 | import { HomeComponent } from './home.component'; 7 | import { HomeRoutingModule } from './home-routing.module'; 8 | 9 | import { HeaderModule } from '../header/'; 10 | import { ListModule } from '../list/'; 11 | import { FooterModule } from '../footer/'; 12 | 13 | /** 14 | * The header module 15 | * 16 | * Just embedding component and it's routing definition in {@link HomeRoutingModule} 17 | */ 18 | @NgModule({ 19 | declarations: [HomeComponent], 20 | imports: [ 21 | BrowserModule, 22 | FormsModule, 23 | HttpClientModule, 24 | 25 | HeaderModule.forRoot(), 26 | ListModule, 27 | FooterModule, 28 | HomeRoutingModule 29 | ], 30 | exports: [HomeComponent] 31 | }) 32 | export class HomeModule {} 33 | -------------------------------------------------------------------------------- /src/app/home/index.ts: -------------------------------------------------------------------------------- 1 | export * from './home.module'; 2 | export * from './home.component'; 3 | -------------------------------------------------------------------------------- /src/app/index.ts: -------------------------------------------------------------------------------- 1 | export * from './app.module'; 2 | -------------------------------------------------------------------------------- /src/app/list/index.ts: -------------------------------------------------------------------------------- 1 | export * from './list.module'; 2 | -------------------------------------------------------------------------------- /src/app/list/list.component.html: -------------------------------------------------------------------------------- 1 | 5 |
6 |
    7 | 8 |
9 |
10 | -------------------------------------------------------------------------------- /src/app/list/list.component.md: -------------------------------------------------------------------------------- 1 | # List component 2 | 3 | It display the lines of todos. 4 | -------------------------------------------------------------------------------- /src/app/list/list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { of } from 'rxjs'; 3 | 4 | import { TodoStore } from '../shared/services/todo.store'; 5 | 6 | import { EmitterService } from '../shared/services/emitter.service'; 7 | 8 | import { Todo } from '../shared/models/todo.model'; 9 | 10 | /** 11 | * The list of todos component 12 | * 13 | * Can filter types of todos : 14 | * 15 | * | Type | API | 16 | * | --- | --- | 17 | * | completed | displayCompleted | 18 | * | all | displayAll | 19 | * | remaining | displayRemaining | 20 | */ 21 | @Component({ 22 | selector: 'list', 23 | providers: [], 24 | templateUrl: './list.component.html' 25 | }) 26 | export class ListComponent { 27 | /** 28 | * Local reference of TodoStore 29 | */ 30 | todoStore: TodoStore; 31 | todos: Array; 32 | watchTest; 33 | 34 | constructor(todoStore: TodoStore) { 35 | const that = this; 36 | this.todoStore = todoStore; 37 | this.todos = todoStore.getAll(); 38 | this.watchTest = of(todoStore.todos); 39 | EmitterService.get('FooterComponent').subscribe(value => { 40 | console.log(value); 41 | switch (value) { 42 | case 'displayCompleted': 43 | that.todos = todoStore.getCompleted(); 44 | break; 45 | case 'displayAll': 46 | that.todos = todoStore.getAll(); 47 | break; 48 | case 'displayRemaining': 49 | that.todos = todoStore.getRemaining(); 50 | break; 51 | } 52 | }); 53 | this.watchTest.subscribe(data => { 54 | console.log(data); 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/app/list/list.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | 4 | import { ListComponent } from './list.component'; 5 | 6 | import { TodoModule } from './todo/'; 7 | import { TodoComponent } from './todo/todo.component'; 8 | 9 | /** 10 | * @ignore 11 | */ 12 | const MODULES = [TodoModule, BrowserModule]; 13 | 14 | /** 15 | * The list of todos module 16 | * 17 | * Contains list component which can filter types of todos : 18 | * 19 | * | Type | API | 20 | * | --- | --- | 21 | * | completed | displayCompleted | 22 | * | all | displayAll | 23 | * | remaining | displayRemaining | 24 | */ 25 | @NgModule({ 26 | imports: [MODULES, TodoComponent], 27 | declarations: [ListComponent], 28 | exports: [ListComponent], 29 | }) 30 | export class ListModule {} 31 | -------------------------------------------------------------------------------- /src/app/list/todo/index.ts: -------------------------------------------------------------------------------- 1 | export * from './todo.module'; 2 | -------------------------------------------------------------------------------- /src/app/list/todo/todo.component.html: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 | 4 | 5 | 6 |
    7 | 10 |
  • -------------------------------------------------------------------------------- /src/app/list/todo/todo.component.md: -------------------------------------------------------------------------------- 1 | # Todo component 2 | 3 | This is the core component of the application. 4 | 5 | ![Screenshot-1](/screenshots/todo/todo.png) 6 | 7 | It display the line of one todo task, and APIs for edition & delete 8 | 9 | This is an extract of these APIs 10 | 11 | ```typescript 12 | export class TodoComponent { 13 | ... 14 | editTodo(todo: Todo) { 15 | todo.editing = true; 16 | } 17 | ... 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /src/app/list/todo/todo.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | import { Todo } from '../../shared/models/todo.model'; 4 | 5 | import { TodoStore } from '../../shared/services/todo.store'; 6 | import { DoNothingDirective } from 'src/app/shared/directives/do-nothing.directive'; 7 | 8 | /** 9 | * The todo component 10 | * ```html 11 | * 12 | * [todo]="todo" 13 | * 14 | * ``` 15 | * ../screenshots/todo/todo.png 16 | */ 17 | @Component({ 18 | selector: 'todo', 19 | templateUrl: './todo.component.html', 20 | standalone: true, 21 | imports: [DoNothingDirective], 22 | }) 23 | export class TodoComponent { 24 | /** 25 | * The entry todo from the parent list 26 | */ 27 | @Input({ 28 | required: true, 29 | alias: 'todo', 30 | }) 31 | todo: Todo; 32 | 33 | /** 34 | * Local reference of TodoStore 35 | */ 36 | todoStore: TodoStore; 37 | 38 | constructor(todoStore: TodoStore) { 39 | this.todoStore = todoStore; 40 | } 41 | 42 | remove(todo: Todo) { 43 | this.todoStore.remove(todo); 44 | } 45 | 46 | toggleCompletion(todo: Todo) { 47 | this.todoStore.toggleCompletion(todo); 48 | } 49 | 50 | editTodo(todo: Todo) { 51 | todo.editing = true; 52 | } 53 | 54 | stopEditing(todo: Todo, editedTitle: string) { 55 | todo.title = editedTitle; 56 | todo.editing = false; 57 | } 58 | 59 | cancelEditingTodo(todo: Todo) { 60 | todo.editing = false; 61 | } 62 | 63 | updateEditingTodo(todo: Todo, editedTitle: string) { 64 | editedTitle = editedTitle.trim(); 65 | todo.editing = false; 66 | 67 | if (editedTitle.length === 0) { 68 | return this.todoStore.remove(todo); 69 | } 70 | 71 | todo.title = editedTitle; 72 | 73 | this.todoStore.update(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/app/list/todo/todo.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | 4 | import { FirstUpperPipe } from '../../shared/pipes/first-upper.pipe'; 5 | 6 | const PIPES_AND_DIRECTIVES = [FirstUpperPipe]; 7 | 8 | /** 9 | * The todo module 10 | * 11 | * Contains the {@link TodoComponent} 12 | */ 13 | @NgModule({ 14 | imports: [BrowserModule], 15 | declarations: [PIPES_AND_DIRECTIVES], 16 | }) 17 | export class TodoModule {} 18 | -------------------------------------------------------------------------------- /src/app/shared/components/empty-component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | import { EmptyParentComponent } from './empty-parent-component'; 4 | 5 | /** 6 | * Empty component for inheritance demo 7 | */ 8 | @Component({ 9 | selector: 'cp-empty', 10 | template: 'empty component' 11 | }) 12 | export class EmptyComponent extends EmptyParentComponent { 13 | @Input() public emptyInput: string; 14 | } 15 | -------------------------------------------------------------------------------- /src/app/shared/components/empty-parent-component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, OnInit } from '@angular/core'; 2 | 3 | /** 4 | * Empty parent component for inheritance demo 5 | */ 6 | @Component({ 7 | selector: 'empty-parent', 8 | template: 'empty parent' 9 | }) 10 | export class EmptyParentComponent implements OnInit { 11 | @Input() public parentInput: string; 12 | 13 | @Output() public parentoutput; 14 | 15 | public parentProperty; 16 | 17 | ngOnInit() {} 18 | } 19 | -------------------------------------------------------------------------------- /src/app/shared/decorators/log.decorator.ts: -------------------------------------------------------------------------------- 1 | export function LogMethod(target: any, key: string) { 2 | console.log('LogMethod: ' + key); 3 | } 4 | 5 | export function LogProperty(target: any, key: string) { 6 | console.log('LogProperty: ', key); 7 | } 8 | 9 | export function LogPropertyWithArgs(alias: string): any { 10 | console.log('LogPropertyWithArgs: ', alias); 11 | } 12 | 13 | export function LogClass(target: any) { 14 | console.log('LogClass: ', target); 15 | } 16 | -------------------------------------------------------------------------------- /src/app/shared/directives/border.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, HostListener, Input, OnInit } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appBorder]', 5 | standalone: true, 6 | }) 7 | export class BorderDirective implements OnInit { 8 | @Input() color: string = 'red'; 9 | 10 | constructor(private el: ElementRef) {} 11 | 12 | ngOnInit() { 13 | this.border(''); 14 | } 15 | 16 | @HostListener('mouseenter') onMouseEnter() { 17 | this.border(this.color); 18 | } 19 | 20 | @HostListener('mouseleave') onMouseLeave() { 21 | this.border(''); 22 | } 23 | 24 | private border(color: string) { 25 | this.el.nativeElement.style.border = `2px solid ${color || 'transparent'}`; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/app/shared/directives/do-nothing.directive.md: -------------------------------------------------------------------------------- 1 | # Do-nothing 2 | -------------------------------------------------------------------------------- /src/app/shared/directives/do-nothing.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostBinding, HostListener } from '@angular/core'; 2 | import { BorderDirective } from './border.directive'; 3 | 4 | /** 5 | * This directive does nothing ! 6 | */ 7 | @Directive({ 8 | selector: '[donothing]', 9 | standalone: true, 10 | hostDirectives: [BorderDirective], 11 | }) 12 | export class DoNothingDirective { 13 | protected popover: string; 14 | 15 | /** 16 | * constructor description 17 | */ 18 | constructor() { 19 | console.log('Do nothing directive'); 20 | } 21 | 22 | /** 23 | * HostBinding description 24 | */ 25 | @HostBinding('style.color') color: string; 26 | 27 | /** 28 | * HostListener description 1 29 | */ 30 | @HostListener('mouseup', ['$event.clientX', '$event.clientY']) 31 | onMouseup(mouseX: number, mouseY: number): void {} 32 | /** 33 | * HostListener description 2 34 | */ 35 | @HostListener('mousedown', ['$event.clientX', '$event.clientY']) 36 | onMousedown(mouseX: number, mouseY: number): void {} 37 | /** 38 | * HostListener description 3 39 | */ 40 | @HostListener('focus', ['$event']) 41 | @HostListener('click', ['$event']) 42 | onClick(e: Event): void {} 43 | } 44 | -------------------------------------------------------------------------------- /src/app/shared/directives/highlight-and-border.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { BorderDirective } from './border.directive'; 3 | import { HighlightDirective } from './highlight.directive'; 4 | 5 | @Directive({ 6 | selector: '[appHighlightAndBorder]', 7 | hostDirectives: [ 8 | { 9 | directive: HighlightDirective, 10 | inputs: ['color'], 11 | }, 12 | { 13 | directive: BorderDirective, 14 | inputs: ['color'], 15 | outputs: ['tat', 'tit'], 16 | }, 17 | ], 18 | standalone: true, 19 | }) 20 | export class HighlightAndBorderDirective {} 21 | -------------------------------------------------------------------------------- /src/app/shared/directives/highlight.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, HostListener, Input } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appHighlight]', 5 | standalone: true, 6 | }) 7 | export class HighlightDirective { 8 | @Input() color = 'yellow'; 9 | 10 | constructor(private el: ElementRef) {} 11 | 12 | @HostListener('mouseenter') onMouseEnter() { 13 | this.highlight(this.color); 14 | } 15 | 16 | @HostListener('mouseleave') onMouseLeave() { 17 | this.highlight(''); 18 | } 19 | 20 | private highlight(color: string) { 21 | this.el.nativeElement.style.backgroundColor = color; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/app/shared/enums/enum.ts: -------------------------------------------------------------------------------- 1 | export enum PopupEffect { 2 | fadeIn, fadeOut, bubbleIn, bubbleOut 3 | } 4 | 5 | /** 6 | * Directions of the app 7 | */ 8 | export enum Direction { 9 | Up, 10 | Down, 11 | Left, 12 | Right 13 | } 14 | -------------------------------------------------------------------------------- /src/app/shared/guards/noopguard.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { CanActivate } from '@angular/router'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class NoopGuard implements CanActivate { 8 | 9 | /** 10 | * Decide if a route can be activated 11 | */ 12 | canActivate (): boolean { 13 | return true; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/interceptors/noopinterceptor.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | @Injectable() 6 | export class NoopInterceptor implements HttpInterceptor { 7 | intercept(req: HttpRequest, next: HttpHandler): Observable> { 8 | return next.handle(req); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/app/shared/interfaces/clock.interface.md: -------------------------------------------------------------------------------- 1 | # Clock interface 2 | -------------------------------------------------------------------------------- /src/app/shared/interfaces/clock.interface.ts: -------------------------------------------------------------------------------- 1 | import { TimeInterface } from './time.interface'; 2 | 3 | /** 4 | * A class interface just for documentation purpose 5 | * 6 | * ```typescript 7 | * class Clock implements ClockInterface { 8 | * currentTime: Date; 9 | * constructor(h: number, m: number) { } 10 | * } 11 | * ``` 12 | */ 13 | interface ClockInterface extends TimeInterface { 14 | /** 15 | * The current time 16 | * @type {Date} 17 | * @deprecated The current time property is deprecated 18 | */ 19 | currentTime: Date; 20 | /** 21 | * A simple reset method 22 | */ 23 | reset(): void; 24 | } 25 | -------------------------------------------------------------------------------- /src/app/shared/interfaces/interfaces.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Just for Compodoc feature demo 3 | */ 4 | export interface superString { 5 | name: string; 6 | } 7 | 8 | /** 9 | * An interface just for documentation purpose 10 | * @deprecated This interface is deprecated 11 | */ 12 | export interface LabelledTodo { 13 | title: string; 14 | completed: boolean; 15 | editing?: boolean; 16 | readonly x: number; 17 | } 18 | 19 | /** 20 | * A function type interface just for documentation purpose 21 | * ```typescript 22 | * let mySearch: SearchFunc; 23 | * mySearch = function(source: string, subString: string) { 24 | * let result = source.search(subString); 25 | * if (result == -1) { 26 | * return false; 27 | * } 28 | * else { 29 | * return true; 30 | * } 31 | * } 32 | * ``` 33 | */ 34 | interface SearchFunc { 35 | (source: string, subString: string): boolean; 36 | } 37 | 38 | /** 39 | * A indexable interface just for documentation purpose 40 | * ```typescript 41 | * let myArray: StringArray; 42 | * myArray = ["Bob", "Fred"]; 43 | * ``` 44 | */ 45 | interface StringArray { 46 | [index: number]: string; 47 | } 48 | -------------------------------------------------------------------------------- /src/app/shared/interfaces/time.interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A time interface just for documentation purpose 3 | */ 4 | export interface TimeInterface { 5 | /** 6 | * The zone 7 | */ 8 | zone: string; 9 | } 10 | -------------------------------------------------------------------------------- /src/app/shared/miscellaneous/miscellaneous-types.ts: -------------------------------------------------------------------------------- 1 | export type Something = number | string; // 166 - UnionType + types 2 | 3 | export type Name = string; // 136 - StringKeyword + rien 4 | 5 | /** 6 | * Some flags 7 | */ 8 | export type Flags = { 9 | option1: boolean; 10 | option2: boolean; 11 | }; // 163 - TypeLiteral + members 12 | 13 | export type NameResolver = () => string; // 160 - FunctionType + type (string) + 14 | -------------------------------------------------------------------------------- /src/app/shared/miscellaneous/miscellaneous.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * PI constant 3 | * See {@link Todo} for service using it 4 | */ 5 | export const PI = 3.14; 6 | 7 | /** 8 | * PIT let 9 | * See {@link Todo} for service using it 10 | */ 11 | export let PIT = 4; 12 | 13 | /** 14 | * A foo bar function 15 | * 16 | * @param {string} status A status 17 | */ 18 | export function foo(status: string) { 19 | console.log('bar'); 20 | } 21 | 22 | export class StringIndexedItems { 23 | [index: string]: T; 24 | } 25 | 26 | export interface InterfaceWithIndexable { 27 | [yala: string]: T; 28 | } 29 | 30 | export let yo: { [index: string]: { message: string } } = {}; 31 | -------------------------------------------------------------------------------- /src/app/shared/models/todo.model.md: -------------------------------------------------------------------------------- 1 | # Todo class 2 | -------------------------------------------------------------------------------- /src/app/shared/models/todo.model.ts: -------------------------------------------------------------------------------- 1 | import { superString } from '../interfaces/interfaces'; 2 | 3 | import { Direction } from '../enums/enum'; 4 | 5 | /** 6 | * The todo class 7 | * 8 | * See {@link TodoStore} for service using it 9 | */ 10 | export class Todo { 11 | /** 12 | * Completed status 13 | */ 14 | completed: boolean; 15 | /** 16 | * Editing status 17 | */ 18 | editing: boolean; 19 | 20 | /** 21 | * Just for Compodoc feature demo 22 | */ 23 | oneProperty: superString; 24 | 25 | dir: Direction = Direction.Left; 26 | 27 | /** 28 | * Another private property 29 | */ 30 | #newprivateproperty: boolean = false; 31 | 32 | #clicked() { 33 | this.editing = true; 34 | } 35 | 36 | /** 37 | * Title 38 | */ 39 | private _title: string; 40 | get title() { 41 | return this._title; 42 | } 43 | set title(value: string) { 44 | this._title = value.trim(); 45 | } 46 | 47 | static classMethod() { 48 | return 'hello'; 49 | } 50 | 51 | constructor(title: string) { 52 | this.completed = false; 53 | this.editing = false; 54 | this.title = title.trim(); 55 | } 56 | 57 | /** 58 | * fakeMethod !! 59 | */ 60 | fakeMethod(): boolean { 61 | return true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/app/shared/pipes/first-upper.pipe.md: -------------------------------------------------------------------------------- 1 | # First upper pipe 2 | -------------------------------------------------------------------------------- /src/app/shared/pipes/first-upper.pipe.ts: -------------------------------------------------------------------------------- 1 | import { PipeTransform, Pipe } from '@angular/core'; 2 | 3 | /** 4 | * Uppercase the first letter of the string 5 | * 6 | * __Usage :__ 7 | * value | firstUpper:exponent 8 | * 9 | * __Example :__ 10 | * {{ car | firstUpper}} 11 | * formats to: Car 12 | */ 13 | @Pipe({ 14 | name: 'firstUpper' 15 | }) 16 | export class FirstUpperPipe implements PipeTransform { 17 | transform(value, args) { 18 | return value.charAt(0).toUpperCase() + value.slice(1); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/shared/pipes/standalone.pipe.ts: -------------------------------------------------------------------------------- 1 | import { PipeTransform, Pipe } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'standalone', 5 | standalone: true, 6 | }) 7 | export class StandAlonePipe implements PipeTransform { 8 | transform(value, args) { 9 | return 'StandAlone Pipe ;)'; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/app/shared/services/emitter.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, EventEmitter } from '@angular/core'; 2 | 3 | /** 4 | * A simple pubsub service using EventEmitter 5 | */ 6 | @Injectable() 7 | export class EmitterService { 8 | private static _emitters: { [ID: string]: EventEmitter } = {}; 9 | 10 | static get(ID: string): EventEmitter { 11 | if (!this._emitters[ID]) { 12 | this._emitters[ID] = new EventEmitter(); 13 | } 14 | return this._emitters[ID]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/services/empty.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, EventEmitter } from '@angular/core'; 2 | 3 | /** 4 | * A simple empty service for disaplying providers in main graph 5 | */ 6 | @Injectable() 7 | export class EmptyService {} 8 | -------------------------------------------------------------------------------- /src/app/shared/services/todo.store.md: -------------------------------------------------------------------------------- 1 | # Todo store 2 | -------------------------------------------------------------------------------- /src/app/shared/services/todo.store.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { Todo } from '../models/todo.model'; 4 | 5 | import { LabelledTodo } from '../interfaces/interfaces'; 6 | 7 | /** 8 | * This service is a todo store 9 | * 10 | * See {@link Todo} for details about the main data of this store 11 | */ 12 | @Injectable() 13 | export class TodoStore { 14 | /** 15 | * Local array of Todos 16 | * 17 | * See {@link Todo} 18 | */ 19 | todos: Array; 20 | 21 | constructor() { 22 | let persistedTodos = JSON.parse( 23 | localStorage.getItem('angular2-todos') || '[]' 24 | ); 25 | // Normalize back into classes 26 | this.todos = persistedTodos.map( 27 | (todo: { _title: string; completed: boolean }) => { 28 | let ret = new Todo(todo._title); 29 | ret.completed = todo.completed; 30 | return ret; 31 | } 32 | ); 33 | } 34 | 35 | private updateStore() { 36 | localStorage.setItem('angular2-todos', JSON.stringify(this.todos)); 37 | } 38 | 39 | private getWithCompleted(completed: Boolean) { 40 | return this.todos.filter((todo: Todo) => todo.completed === completed); 41 | } 42 | 43 | /** 44 | * All the todos are they __completed__ ? 45 | * 46 | * @returns {boolean} All completed ? 47 | */ 48 | allCompleted(): boolean { 49 | return this.todos.length === this.getCompleted().length; 50 | } 51 | 52 | /** 53 | * Set all todos status (completed or not) 54 | * 55 | * @example 56 | * // set all at completed 57 | * TodoStore.setAllTo(true); 58 | * 59 | * @example 60 | * // set all at not completed 61 | * TodoStore.setAllTo(false); 62 | * 63 | * @param {boolean} completed Status of all todos 64 | */ 65 | setAllTo(completed: boolean) { 66 | this.todos.forEach((t: Todo) => (t.completed = completed)); 67 | this.updateStore(); 68 | } 69 | 70 | /** 71 | * Remove completed todos 72 | */ 73 | removeCompleted() { 74 | this.todos = this.getWithCompleted(false); 75 | this.updateStore(); 76 | } 77 | 78 | /** 79 | * Get remaining todos 80 | * 81 | * @returns {Array} All remaining todos 82 | */ 83 | getRemaining() { 84 | return this.getWithCompleted(false); 85 | } 86 | 87 | /** 88 | * Get all todos 89 | * 90 | * @returns {Array} All todos 91 | */ 92 | getAll() { 93 | return this.todos; 94 | } 95 | 96 | /** 97 | * Get completed todos 98 | * 99 | * @returns {Array} All completed todos 100 | */ 101 | getCompleted() { 102 | return this.getWithCompleted(true); 103 | } 104 | 105 | /** 106 | * Toggle completed todo status 107 | * 108 | * @param {Todo} todo Todo which change status 109 | */ 110 | toggleCompletion(todo: Todo) { 111 | todo.completed = !todo.completed; 112 | this.updateStore(); 113 | } 114 | 115 | /** 116 | * Remove todo 117 | * 118 | * See {@link Todo} 119 | * 120 | * @param {Todo} todo Todo to remove 121 | * @param {any[]} theArgs the rest of arguments 122 | */ 123 | remove(todo: Todo, ...theArgs) { 124 | this.todos.splice(this.todos.indexOf(todo), 1); 125 | this.updateStore(); 126 | } 127 | 128 | /** 129 | * Update store 130 | */ 131 | update() { 132 | this.updateStore(); 133 | } 134 | 135 | /** 136 | * Add todo 137 | * 138 | * @param {string} title Title of todo 139 | */ 140 | add(title: string) { 141 | this.todos.push(new Todo(title)); 142 | this.updateStore(); 143 | } 144 | 145 | /** 146 | * Stop monitoring the todo 147 | * 148 | * @param {LabelledTodo} theTodo A todo 149 | * @returns {Promise} promise resolved once we stop monitoring the todo or it is rejected 150 | */ 151 | stopMonitoring(theTodo?: LabelledTodo): Promise { 152 | return new Promise((resolve, reject) => { 153 | // TODO 154 | }); 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compodoc/compodoc-demo-todomvc-angular/6e89b1746dd6965037f26cdd163a0bba4488dac9/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Angular • TodoMVC • Compodoc ready 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Loading... 15 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | app-root { 4 | text-align: center; 5 | margin: 65px auto 0; 6 | display: block; 7 | } 8 | 9 | .todoapp { 10 | text-align: left; 11 | } 12 | 13 | .info { 14 | margin: 0 auto 0 !important; 15 | } 16 | .links { 17 | margin: 65px auto 0 !important; 18 | } 19 | 20 | .btn-filter { 21 | cursor: pointer; 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": ["src/main.ts"], 9 | "include": ["src/**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.doc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "include": ["src/**/*.ts"], 8 | "exclude": ["src/test.ts", "src/**/*.spec.ts", "src/app/file-to-exclude.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "moduleResolution": "node", 11 | "importHelpers": true, 12 | "target": "ES2022", 13 | "module": "ES2022", 14 | "lib": ["ES2022", "dom"] 15 | }, 16 | "angularCompilerOptions": { 17 | "fullTemplateTypeCheck": true, 18 | "strictInjectionParameters": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-redundant-jsdoc": false, 69 | "no-shadowed-variable": true, 70 | "no-string-literal": false, 71 | "no-string-throw": true, 72 | "no-switch-case-fall-through": true, 73 | "no-trailing-whitespace": true, 74 | "no-unnecessary-initializer": true, 75 | "no-unused-expression": true, 76 | "no-use-before-declare": true, 77 | "no-var-keyword": true, 78 | "object-literal-sort-keys": false, 79 | "one-line": [ 80 | true, 81 | "check-open-brace", 82 | "check-catch", 83 | "check-else", 84 | "check-whitespace" 85 | ], 86 | "prefer-const": true, 87 | "quotemark": [ 88 | true, 89 | "single" 90 | ], 91 | "radix": true, 92 | "semicolon": [ 93 | true, 94 | "always" 95 | ], 96 | "triple-equals": [ 97 | true, 98 | "allow-null-check" 99 | ], 100 | "typedef-whitespace": [ 101 | true, 102 | { 103 | "call-signature": "nospace", 104 | "index-signature": "nospace", 105 | "parameter": "nospace", 106 | "property-declaration": "nospace", 107 | "variable-declaration": "nospace" 108 | } 109 | ], 110 | "unified-signatures": true, 111 | "variable-name": false, 112 | "whitespace": [ 113 | true, 114 | "check-branch", 115 | "check-decl", 116 | "check-operator", 117 | "check-separator", 118 | "check-type" 119 | ], 120 | "no-output-on-prefix": true, 121 | "use-input-property-decorator": true, 122 | "use-output-property-decorator": true, 123 | "use-host-property-decorator": true, 124 | "no-input-rename": true, 125 | "no-output-rename": true, 126 | "use-life-cycle-interface": true, 127 | "use-pipe-transform-interface": true, 128 | "component-class-suffix": true, 129 | "directive-class-suffix": true 130 | } 131 | } --------------------------------------------------------------------------------