diff --git a/CHANGELOG.md b/CHANGELOG.md index e5ff33f..a8f8eff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,14 @@ # Changelog -## 12.0.0-beta.0 +## 12.0.0 - Upgrade to Angular 18 (still compatible v17.3.0 and above). -- feat: Introduce CSS variables for more flexible customization. +- feat: Introduce CSS variables for more flexible customization, see [styling](https://github.com/MurhafSousli/ngx-progressbar/wiki/styling). - feat: Provide `provideNgProgressOptions()` to override global options. - feat: Provide `provideNgProgressHttp()` to override http related options. - feat: Provide `provideNgProgressRouter()` to override router related options. - feat: Ability to use boolean inputs as attributes. -- refactor: Utilize signals approach. +- refactor: Utilize signals API. ### Breaking changes diff --git a/README.md b/README.md index 30ebf4e..80c7ee6 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![npm](https://img.shields.io/badge/stackblitz-online-orange.svg)](https://stackblitz.com/edit/ngx-progressbar) [![npm](https://img.shields.io/npm/v/ngx-progressbar.svg?maxAge=2592000?style=plastic)](https://www.npmjs.com/package/ngx-progressbar) [![tests](https://github.com/MurhafSousli/ngx-progressbar/workflows/tests/badge.svg)](https://github.com/MurhafSousli/ngx-progressbar/actions?query=workflow%3Atests) +[![codecov](https://codecov.io/gh/MurhafSousli/ngx-progressbar/graph/badge.svg?token=hIKXnJRikz)](https://codecov.io/gh/MurhafSousli/ngx-progressbar) [![npm](https://img.shields.io/npm/dt/ngx-progressbar.svg?maxAge=2592000?style=plastic)](https://www.npmjs.com/package/ngx-progressbar) [![npm](https://img.shields.io/npm/dm/ngx-progressbar.svg)](https://www.npmjs.com/package/ngx-progressbar) [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/ngx-progressbar.svg)](https://bundlephobia.com/result?p=ngx-progressbar) diff --git a/projects/ngx-progressbar/README.md b/projects/ngx-progressbar/README.md index 30ebf4e..80c7ee6 100644 --- a/projects/ngx-progressbar/README.md +++ b/projects/ngx-progressbar/README.md @@ -7,6 +7,7 @@ [![npm](https://img.shields.io/badge/stackblitz-online-orange.svg)](https://stackblitz.com/edit/ngx-progressbar) [![npm](https://img.shields.io/npm/v/ngx-progressbar.svg?maxAge=2592000?style=plastic)](https://www.npmjs.com/package/ngx-progressbar) [![tests](https://github.com/MurhafSousli/ngx-progressbar/workflows/tests/badge.svg)](https://github.com/MurhafSousli/ngx-progressbar/actions?query=workflow%3Atests) +[![codecov](https://codecov.io/gh/MurhafSousli/ngx-progressbar/graph/badge.svg?token=hIKXnJRikz)](https://codecov.io/gh/MurhafSousli/ngx-progressbar) [![npm](https://img.shields.io/npm/dt/ngx-progressbar.svg?maxAge=2592000?style=plastic)](https://www.npmjs.com/package/ngx-progressbar) [![npm](https://img.shields.io/npm/dm/ngx-progressbar.svg)](https://www.npmjs.com/package/ngx-progressbar) [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/ngx-progressbar.svg)](https://bundlephobia.com/result?p=ngx-progressbar) diff --git a/projects/ngx-progressbar/http/README.md b/projects/ngx-progressbar/http/README.md index c4fc5ae..5a59fbe 100644 --- a/projects/ngx-progressbar/http/README.md +++ b/projects/ngx-progressbar/http/README.md @@ -4,7 +4,7 @@ The `ngProgressHttp` directive allows you to easily integrate the progress bar w ### Usage -To use the `ngProgressHttp` directive, simply add it to your component: +To use the `ngProgressHttp` directive, simply add it to your component along with the `NgProgressbar` component: ```typescript import { Component } from '@angular/core'; @@ -85,9 +85,9 @@ bootstrapApplication(AppComponent, { **Result:** -* https://prod.domain.com/users: Ignored -* https://example.com/users: Ignored -* https://domain.com/reviews: Not ignored +> https://prod.domain.com/users: Ignored +> https://example.com/users: Ignored +> https://domain.com/reviews: Not ignored **3. Ignore requests using a regular expression**: @@ -108,9 +108,9 @@ bootstrapApplication(AppComponent, { **Result:** -* https://api.domain.com/places: Ignored -* https://prod.domain.com/users: Ignored -* https://domain.com/reviews/v1/test: Ignored +> https://api.domain.com/places: Ignored +> https://prod.domain.com/users: Ignored +> https://domain.com/reviews/v1/test: Ignored You can also use the `matcher` option in combination with the `silentApis` option to create more complex rules for ignoring requests. @@ -130,9 +130,9 @@ bootstrapApplication(AppComponent, { **Result:** -* https://api.domain.com/places: Not ignored -* https://prod.domain.com/users: Ignored -* https://domain.com/reviews/v1/test: Ignored +> https://api.domain.com/places: Not ignored +> https://prod.domain.com/users: Ignored +> https://domain.com/reviews/v1/test: Ignored ### NgProgressHttp API diff --git a/projects/ngx-progressbar/package.json b/projects/ngx-progressbar/package.json index 8f1ec41..ae57d13 100644 --- a/projects/ngx-progressbar/package.json +++ b/projects/ngx-progressbar/package.json @@ -1,6 +1,6 @@ { "name": "ngx-progressbar", - "version": "12.0.0-beta.0", + "version": "12.0.0", "author": { "name": "Murhaf Sousli", "url": "https://github.com/MurhafSousli", diff --git a/projects/ngx-progressbar/router/RAEDME.md b/projects/ngx-progressbar/router/RAEDME.md index 0403d6c..17b7702 100644 --- a/projects/ngx-progressbar/router/RAEDME.md +++ b/projects/ngx-progressbar/router/RAEDME.md @@ -1,33 +1,23 @@ -## NgProgress + Router +## NgProgress + Router + +The `NgProgressRouter` directive allows you to easily integrate a progress bar with your Angular router navigation. ### Usage -Use the directive `ngProgressRouter` to start and complete the progress bar with your router navigation. +To use the `NgProgressRouter` directive, simply add it to your component along with the `NgProgressbar` component: -**Example:** +```html + + +``` -```ts -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; -import { NgProgressbar } from 'ngx-progressbar'; -import { NgProgressRouter } from 'ngx-progressbar/router'; +This will automatically start the progress bar on navigation start and complete it when the navigation finishes. -@Component({ - standalone: true, - selector: 'app-root', - imports: [NgProgressbar, NgProgressRouter, RouterOutlet], - template: ` - - - ` -}) -export class AppComponent { -} -``` +### Custom Router Events -### Custom router events +If you need more control over when the progress bar should start and complete, you can use the `provideNgProgressRouter` function to configure the directive: -```ts +```typescript import { GuardsCheckEnd, NavigationEnd } from '@angular/router'; import { provideNgProgressRouter } from '@ngx-progressbar/router'; @@ -42,13 +32,16 @@ bootstrapApplication(AppComponent, { }) ``` +In this example, the progress bar will start on the `GuardsCheckEnd` event and complete on the `NavigationEnd` event. Additionally, the progress bar will run for a minimum of 1000 milliseconds (1 second) before completing. + ### NgProgressRouter API -| Name | Default | Description | -| ------------------ | :------------------------------------------------: |-------------------------------------------------------------------------------| -| **minDuration** | 0 | *The minimum duration (in ms) the progress bar should run before completing.* | -| **startEvents** | [NavigationStart] | *Router events that starts the progressbar.* | -| **completeEvents** | [NavigationEnd, NavigationCancel, NavigationError] | *Router events that completes the progressbar.* | +The `provideNgProgressRouter` function accepts the following configuration options: +| Name | Type | Default | Description | +| ------------------ | :-----------------------------------------------: | :------------------------------------------------: |-------------------------------------------------------------------------------| +| **minDuration** | `number` | `0` | The minimum duration (in ms) the progress bar should run before completing. | +| **startEvents** | `RouterEvent[]` | `[NavigationStart]` | Router events that start the progress bar. | +| **completeEvents** | `RouterEvent[]` | `[NavigationEnd, NavigationCancel, NavigationError]` | Router events that complete the progress bar. | -A list of available router events can be found [https://angular.dev/guide/routing/router-reference#router-events](https://angular.dev/guide/routing/router-reference#router-events) +You can find a list of available router events in the [Angular Router Reference documentation](https://angular.dev/guide/routing/router-reference#router-events). diff --git a/projects/ngx-progressbar/INTEGRATION.md b/projects/ngx-progressbar/src/lib/docs/INTEGRATION.md similarity index 100% rename from projects/ngx-progressbar/INTEGRATION.md rename to projects/ngx-progressbar/src/lib/docs/INTEGRATION.md diff --git a/projects/ngx-progressbar/src/lib/docs/OPTIONS.md b/projects/ngx-progressbar/src/lib/docs/OPTIONS.md new file mode 100644 index 0000000..b48357a --- /dev/null +++ b/projects/ngx-progressbar/src/lib/docs/OPTIONS.md @@ -0,0 +1,36 @@ +## Global options + +You can customize the default configuration for all progress bars using the `provideNgProgressOptions` function. + +**Example:** + +```ts +import { provideNgProgressOptions } from '@ngx-progressbar'; + +bootstrapApplication(AppComponent, { + providers: [ + provideNgProgressOptions({ + trickleSpeed: 200, + min: 20, + flat: true + }) + ] +}) +``` + +**NgProgressOptions API** + +| Name | Default | Description | +|---------------------|:--------:|------------------------------------------------------------| +| **direction** | ltr+ | *Progress bar direction (`ltr+`, `ltr-`, `rtl+`, `rtl-`).* | +| **trickleSpeed** | 300 | *Progress trickling speed in ms.* | +| **trickleFunc** | Function | *A **function** that returns the trickling amount.* | +| **debounceTime** | 0 | *Debounce time before starting the progress bar in ms.* | +| **speed** | 200 | *Transition speed in ms.* | +| **min** | 8 | *Progress initial starting value.* | +| **max** | 100 | *Progress maximum value.* | +| **ease** | linear | *Progress [ease function](http://easings.net/).* | +| **spinner** | false | *Display spinner.* | +| **spinnerPosition** | right | *Spinner position. (`right`, `left`).* | +| **relative** | false | *Position the progress bar relative to parent.* | +| **flat** | false | *Flat style (disables meteor style).* | diff --git a/projects/ngx-progressbar/src/lib/docs/STYLING.md b/projects/ngx-progressbar/src/lib/docs/STYLING.md new file mode 100644 index 0000000..ffd6a97 --- /dev/null +++ b/projects/ngx-progressbar/src/lib/docs/STYLING.md @@ -0,0 +1,29 @@ +## Styling + +To customize the appearance of the progress bar, you can use the following CSS variables / classes + +### CSS variables + +| Variable name | Default value | +|-----------------------------------|:--------------| +| `--ng-progress-thickness` | 2 | +| `--ng-progress-color` | #1B95E0 | +| `--ng-progress-holder-color` | transparent | +| `--ng-progress-ease` | linear | +| `--ng-progress-spinner-thickness` | 2 | +| `--ng-progress-spinner-spacing` | 15 | +| `--ng-progress-spinner-size` | 18 | + + +### CSS classes + +| Class name | Description | +|------------------------------|:----------------------------------------------------------------------------------------------| +| **.ng-progress-bar** | This class is applied to the host element of the progress bar. | +| **.ng-progress-bar-active** | This class is applied to the host element when the progress bar is running. | +| **.ng-progress-bar-wrapper** | This class is applied to the overall wrapper element that wraps the bar and the spinner. | +| **.ng-bar-placeholder** | This class is applied to the direct wrapper of the progress bar. | +| **.ng-bar** | This class is applied to the actual bar element that translates when the progress increments. | +| **.ng-spinner** | This class is applied to the spinner wrapper element. | +| **.ng-spinner-icon** | This class is applied to the spinner icon element. | + diff --git a/projects/ngx-progressbar/USAGE.md b/projects/ngx-progressbar/src/lib/docs/USAGE.md similarity index 99% rename from projects/ngx-progressbar/USAGE.md rename to projects/ngx-progressbar/src/lib/docs/USAGE.md index 62a77e6..53ff6b6 100644 --- a/projects/ngx-progressbar/USAGE.md +++ b/projects/ngx-progressbar/src/lib/docs/USAGE.md @@ -88,7 +88,7 @@ Here is an example of how to use the `` component with some of the ``` - > More info on customizing `ngProgressHttp` can be found in http guide. + > More info on customizing `ngProgressHttp` can be found in http requests guide. #### Use `ngProgressRouter` to start/complete the progress bar with router events. @@ -96,4 +96,4 @@ Here is an example of how to use the `` component with some of the ``` -> More info on customizing `ngProgressRouter` can be found in router guide. +> More info on customizing `ngProgressRouter` can be found in router events guide. diff --git a/projects/ngx-progressbar/src/lib/ng-progress-ref.ts b/projects/ngx-progressbar/src/lib/ng-progress-ref.ts index d656fb8..3249668 100644 --- a/projects/ngx-progressbar/src/lib/ng-progress-ref.ts +++ b/projects/ngx-progressbar/src/lib/ng-progress-ref.ts @@ -132,7 +132,7 @@ export class NgProgressRef implements OnDestroy { */ private onTrickling(config: NgProgressOptions): Observable { if (!this.active()) { - this.set(this.config().min); + this.set(config.min); } return timer(0, config.trickleSpeed).pipe(tap(() => this.inc())); } diff --git a/projects/ngx-progressbar/src/lib/tests/ng-progress-ref.spec.ts b/projects/ngx-progressbar/src/lib/tests/ng-progress-ref.spec.ts index 43c65b4..2ab02be 100644 --- a/projects/ngx-progressbar/src/lib/tests/ng-progress-ref.spec.ts +++ b/projects/ngx-progressbar/src/lib/tests/ng-progress-ref.spec.ts @@ -33,9 +33,9 @@ describe('NgProgressRef', () => { expect(directive.active()).toBeTrue(); expect(directive.progress()).toBe(0); - directive.inc(); + await afterTimeout(350); fixture.detectChanges(); - expect(directive.progress()).toBeGreaterThan(0); + expect(directive.progress()).toBeGreaterThan(10); directive.complete(); fixture.detectChanges(); @@ -46,6 +46,27 @@ describe('NgProgressRef', () => { expect(directive.active()).toBeFalse(); }); + it('should start and complete the progress', (done: DoneFn) => { + const setSpy: jasmine.Spy = spyOn(directive, 'set'); + // Assume active state is off + directive['_active'].set(false); + // Mock onTrickling call + directive['onTrickling']({ min: 5 }).subscribe(() => { + expect(setSpy).toHaveBeenCalledWith(5 as any); + done(); + }); + }); + + + it('should increment the progress when inc function is called', async () => { + directive.inc(); + + fixture.detectChanges(); + await afterTimeout(20); + expect(directive.active()).toBeTrue(); + expect(directive.progress()).toBeGreaterThan(0); + }); + it('should emit the started and completed events', async () => { let startedEmitted: boolean = false; let completedEmitted: boolean = false; diff --git a/projects/ngx-progressbar/src/lib/tests/ng-progress.component.spec.ts b/projects/ngx-progressbar/src/lib/tests/ng-progress.component.spec.ts index 6fad517..a461043 100644 --- a/projects/ngx-progressbar/src/lib/tests/ng-progress.component.spec.ts +++ b/projects/ngx-progressbar/src/lib/tests/ng-progress.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NgProgressbar, NgProgressRef } from 'ngx-progressbar'; +import { afterTimeout } from './ng-progress-ref.spec'; describe('NgProgress Component', () => { let fixture: ComponentFixture; @@ -20,6 +21,20 @@ describe('NgProgress Component', () => { expect(component).toBeDefined(); }); + it('should set minimum value to 0 when given a value smaller than 0', async () => { + fixture.componentRef.setInput('min', -10); + fixture.detectChanges(); + await afterTimeout(20); + expect(component.progressRef.config().min).toBe(0); + }); + + it('should set maximum value to 100 when given a value greater than 100', async () => { + fixture.componentRef.setInput('max', 200); + fixture.detectChanges(); + await afterTimeout(20); + expect(component.progressRef.config().max).toBe(100); + }); + it('should start/complete the progress using the start/complete functions', (done: DoneFn) => { const startSpy: jasmine.Spy = spyOn(progressRef, 'start'); const completeSpy: jasmine.Spy = spyOn(progressRef, 'complete');