Skip to content

Commit

Permalink
update documentations; enable cypress e2e and component tests;
Browse files Browse the repository at this point in the history
  • Loading branch information
tony21921 committed Dec 2, 2024
1 parent 920a079 commit 0cbaf5d
Show file tree
Hide file tree
Showing 21 changed files with 12,514 additions and 16,175 deletions.
80 changes: 73 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
<!-- markdownlint-disable-next-line -->
<p align="center">
<a href="https://github.com/tony21921/ngx-material-nested-nav" rel="noopener" target="_blank"><img width="150" height="150" src="./projects/nested-nav-list/logo.svg" alt="Material Nested Navigation List logo"></a>
</p>

# NgxMaterialNestedNav

NgxMaterialNestedNav is an Angular Material component that supports nested navigation lists with multiple types of icons (Material, Font, SVG) and links (route, URL). The SVG icons can either use their original color or be overridden with the theme icon color.

## NestedNavList Component

### Features
## Features

- Nested navigation lists with expandable/collapsible items
- Supports different types of icons: Material, Font, SVG
- Route and URL links
- Divider support

## Installation

To install the package, run:

```sh
npm install @tony21921/ngx-nested-nav-list
```

## NestedNavList Component

### Defining the Data

The data for the navigation list is defined using the `NavData` interface. Here is an example:
Expand Down Expand Up @@ -68,19 +81,25 @@ navData: NavData[] = [
displayName: 'Repo',
iconType: 'svg',
svgUrl: 'github.svg',
url: 'https://github.com'
},
];
```

### How to Register Font for Material Icon

To register a font for Material Icon, you can use the `MatIconRegistry` service. Here is an example:
To register a font for Material Icon, you can use the `MatIconRegistry` service as introduced in [Material](https://material.angular.io/components/icon/overview#registering-icons) documentation. Here is an example:

```ts
import { MatIconRegistry } from '@angular/material/icon';

const matIconRegistry = TestBed.inject(MatIconRegistry);
matIconRegistry.registerFontClassAlias('fontawesome', 'fa');
...
export class AppComponent {
constructor(matIconRegistry: MatIconRegistry) {
matIconRegistry.registerFontClassAlias('fontawesome', 'fa');
}
...
}
```

### Divider
Expand All @@ -93,6 +112,45 @@ You can add a divider in the navigation list by setting the `type` property to `
}
```

## Usage

To use the `NestedNavListComponent`, you need to import it in your Angular module or standalone component. Here is an example:

### In a Module

```ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { NestedNavListComponent } from '@tony21921/ngx-nested-nav-list';

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, NestedNavListComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
```

### In a Standalone Component

```ts
import { Component } from '@angular/core';
import { NestedNavListComponent } from '@tony21921/ngx-nested-nav-list';

@Component({
selector: 'app-root',
standalone: true,
imports: [NestedNavListComponent],
template: ` <ngx-nested-nav-list [navData]="navData"></ngx-nested-nav-list> `,
})
export class AppComponent {
navData = [
// your nav data here
];
}
```

## Development server

Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
Expand All @@ -107,4 +165,12 @@ Run `npm run test` to execute the unit tests via [Jest](https://jestjs.io/).

## Running end-to-end tests

Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
Run `ng e2e` to execute the end-to-end tests with [Cypress](https://www.cypress.io/) on the dev-app application.

## Contribution

Contributions are welcome! Please open an issue or submit a pull request.

## License

This project is licensed under the MIT License. See the [LICENSE](https://github.com/tony21921/ngx-material-nested-nav/blob/main/LICENSE) file for more details.
91 changes: 18 additions & 73 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,52 +31,19 @@
"configPath": "jest.config.ts"
}
},
"cypress-run": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "nested-nav-list:serve",
"configFile": "projects/nested-nav-list/cypress.config.js"
},
"configurations": {
"production": {
"devServerTarget": "nested-nav-list:serve:production"
}
}
},
"cypress-open": {
"builder": "@cypress/schematic:cypress",
"options": {
"watch": true,
"headless": false,
"configFile": "projects/nested-nav-list/cypress.config.js"
}
},
"ct": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "nested-nav-list:serve",
"devServerTarget": "dev-app:serve",
"watch": true,
"headless": false,
"testingType": "component",
"specPattern": "projects/nested-nav-list/src/**/*.cy.ts"
"configFile": "cypress.config.ts",
"tsConfig": "tsconfig.cy.json"
},
"configurations": {
"development": {
"devServerTarget": "nested-nav-list:serve:development"
}
}
},
"e2e": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "nested-nav-list:serve",
"watch": true,
"headless": false,
"specPattern": "projects/dev-app/cypress/e2e/**/*.cy.ts"
},
"configurations": {
"production": {
"devServerTarget": "nested-nav-list:serve:production"
"devServerTarget": "dev-app:serve:development"
}
}
}
Expand All @@ -99,9 +66,7 @@
"outputPath": "dist/dev-app",
"index": "projects/dev-app/src/index.html",
"browser": "projects/dev-app/src/main.ts",
"polyfills": [
"zone.js"
],
"polyfills": ["zone.js"],
"tsConfig": "projects/dev-app/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
Expand All @@ -111,13 +76,9 @@
}
],
"stylePreprocessorOptions": {
"includePaths": [
"node_modules"
]
"includePaths": ["node_modules"]
},
"styles": [
"projects/dev-app/src/styles.scss"
],
"styles": ["projects/dev-app/src/styles.scss"],
"scripts": []
},
"configurations": {
Expand Down Expand Up @@ -170,17 +131,15 @@
"input": "projects/dev-app/public"
}
],
"styles": [
"projects/dev-app/src/styles.scss"
],
"styles": ["projects/dev-app/src/styles.scss"],
"scripts": []
}
},
"cypress-run": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "dev-app:serve",
"configFile": "projects/dev-app/cypress.config.js"
"configFile": "cypress.config.ts"
},
"configurations": {
"production": {
Expand All @@ -193,22 +152,7 @@
"options": {
"watch": true,
"headless": false,
"configFile": "projects/dev-app/cypress.config.js"
}
},
"ct": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "dev-app:serve",
"watch": true,
"headless": false,
"testingType": "component",
"specPattern": "projects/nested-nav-list/src/components/**/*.cy.ts"
},
"configurations": {
"development": {
"devServerTarget": "dev-app:serve:development"
}
"configFile": "cypress.config.ts"
}
},
"e2e": {
Expand All @@ -217,7 +161,8 @@
"devServerTarget": "dev-app:serve",
"watch": true,
"headless": false,
"specPattern": "projects/dev-app/cypress/e2e/**/*.cy.ts"
"specPattern": "cypress/e2e/**/*.cy.ts",
"configFile": "cypress.config.ts"
},
"configurations": {
"production": {
Expand All @@ -228,16 +173,16 @@
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["projects/dev-app/**/*.ts", "projects/dev-app/**/*.html"]
"lintFilePatterns": [
"projects/dev-app/**/*.ts",
"projects/dev-app/**/*.html"
]
}
}
}
}
},
"cli": {
"schematicCollections": [
"@cypress/schematic",
"@schematics/angular"
]
"schematicCollections": ["@cypress/schematic", "@schematics/angular"]
}
}
}
9 changes: 5 additions & 4 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { defineConfig } from "cypress";
import { defineConfig } from 'cypress';

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
'baseUrl': 'http://localhost:4200',
'specPattern': 'projects/dev-app/cypress/e2e/**/*.cy.ts',
baseUrl: 'http://localhost:4200',
specPattern: 'cypress/e2e/**/*.cy.ts',
},

component: {
devServer: {
framework: 'angular',
bundler: 'webpack',
},
'specPattern': 'projects/nested-nav-list/cypress/component/**/*.cy.ts',
specPattern: 'projects/nested-nav-list/src/lib/**/*.cy.ts',
supportFile: 'cypress/support/component.ts',
},
});
42 changes: 42 additions & 0 deletions cypress/e2e/spec.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
describe('My First Test', () => {
it('Visits the initial project page', () => {
cy.visit('/');
cy.contains('Angular Material Nested Navigation List');
});

it ('Check if the nested nav list is displayed', () => {
cy.visit('/');
cy.get('mat-nav-list').should('exist');
cy.contains('Home');
cy.contains('Profile').should('not.exist');
cy.contains('Settings').click();
cy.contains('Profile');
cy.contains('Notifications');
cy.contains('Repo');
});

it('Check navigation', () => {
cy.visit('/');
cy.contains('Settings').click();
cy.contains('Profile').click();
cy.url().should('include', '/profile');
cy.contains('Home').click();
cy.url().should('include', '/home');

cy.window().then((win) => {
cy.stub(win, 'open').as('windowOpen');
});
cy.get('mat-list-item:contains("Repo")').click();
cy.get('@windowOpen').should('be.calledWith', 'about:blank', '_blank');
});

it('SVG icon should be displayed', () => {
cy.visit('/');

cy.get('mat-list-item:contains("Repo")').find('mat-icon[matlistitemicon]').find('svg').should('exist');

cy.get('ngx-nested-nav-list').should('have.class', 'override-svg-icon-color');
cy.contains('Keep Svg Icon Color').click();
cy.get('ngx-nested-nav-list').should('not.have.class', 'override-svg-icon-color');
});
});
12 changes: 12 additions & 0 deletions cypress/support/component-index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Components App</title>
</head>
<body>
<div data-cy-root></div>
</body>
</html>
Loading

0 comments on commit 0cbaf5d

Please sign in to comment.