From f37403793fd5a1c9e8527ac74cdfa6061c51f780 Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Thu, 16 Jun 2022 17:18:38 -0700 Subject: [PATCH] feat(common): make the `CommonModule` pipes standalone This commit updates the pipes presents in the `CommonModule` and annotates them with the `standalone: true` flag. With that flag, the pipes can now be imported individually, as well as imported via the `CommonModule`. --- goldens/public-api/common/index.md | 28 ++++----- packages/common/src/common_module.ts | 3 +- packages/common/src/pipes/async_pipe.ts | 6 +- .../common/src/pipes/case_conversion_pipes.ts | 15 ++++- packages/common/src/pipes/date_pipe.ts | 6 +- packages/common/src/pipes/i18n_plural_pipe.ts | 6 +- packages/common/src/pipes/i18n_select_pipe.ts | 7 ++- packages/common/src/pipes/json_pipe.ts | 6 +- packages/common/src/pipes/keyvalue_pipe.ts | 6 +- packages/common/src/pipes/number_pipe.ts | 15 ++++- packages/common/src/pipes/slice_pipe.ts | 7 ++- .../common/test/pipes/number_pipe_spec.ts | 57 ++++++++++++++++++- packages/common/test/pipes/slice_pipe_spec.ts | 18 ++++++ 13 files changed, 151 insertions(+), 29 deletions(-) diff --git a/goldens/public-api/common/index.md b/goldens/public-api/common/index.md index f9675dd74f572..ef74915281b2a 100644 --- a/goldens/public-api/common/index.md +++ b/goldens/public-api/common/index.md @@ -45,7 +45,7 @@ export class AsyncPipe implements OnDestroy, PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -55,7 +55,7 @@ export class CommonModule { // (undocumented) static ɵinj: i0.ɵɵInjectorDeclaration; // (undocumented) - static ɵmod: i0.ɵɵNgModuleDeclaration; + static ɵmod: i0.ɵɵNgModuleDeclaration; } // @public @@ -70,7 +70,7 @@ export class CurrencyPipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -88,7 +88,7 @@ export class DatePipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -103,7 +103,7 @@ export class DecimalPipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -241,7 +241,7 @@ export class I18nPluralPipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -253,7 +253,7 @@ export class I18nSelectPipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -275,7 +275,7 @@ export class JsonPipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -306,7 +306,7 @@ export class KeyValuePipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -392,7 +392,7 @@ export class LowerCasePipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -673,7 +673,7 @@ export class PercentPipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -761,7 +761,7 @@ export class SlicePipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -781,7 +781,7 @@ export class TitleCasePipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public @@ -803,7 +803,7 @@ export class UpperCasePipe implements PipeTransform { // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) - static ɵpipe: i0.ɵɵPipeDeclaration; + static ɵpipe: i0.ɵɵPipeDeclaration; } // @public (undocumented) diff --git a/packages/common/src/common_module.ts b/packages/common/src/common_module.ts index 91d31727d847f..1b8265b7799a2 100644 --- a/packages/common/src/common_module.ts +++ b/packages/common/src/common_module.ts @@ -29,7 +29,8 @@ import {COMMON_PIPES} from './pipes/index'; * @publicApi */ @NgModule({ - declarations: [COMMON_DIRECTIVES, COMMON_PIPES], + imports: [COMMON_PIPES], + declarations: [COMMON_DIRECTIVES], exports: [COMMON_DIRECTIVES, COMMON_PIPES], }) export class CommonModule { diff --git a/packages/common/src/pipes/async_pipe.ts b/packages/common/src/pipes/async_pipe.ts index 29c8f943bde84..31c21eb416778 100644 --- a/packages/common/src/pipes/async_pipe.ts +++ b/packages/common/src/pipes/async_pipe.ts @@ -73,7 +73,11 @@ const _subscribableStrategy = new SubscribableStrategy(); * * @publicApi */ -@Pipe({name: 'async', pure: false}) +@Pipe({ + name: 'async', + pure: false, + standalone: true, +}) export class AsyncPipe implements OnDestroy, PipeTransform { private _ref: ChangeDetectorRef|null; private _latestValue: any = null; diff --git a/packages/common/src/pipes/case_conversion_pipes.ts b/packages/common/src/pipes/case_conversion_pipes.ts index 4ec24a362fd06..e9cefb089380a 100644 --- a/packages/common/src/pipes/case_conversion_pipes.ts +++ b/packages/common/src/pipes/case_conversion_pipes.ts @@ -25,7 +25,10 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error'; * @ngModule CommonModule * @publicApi */ -@Pipe({name: 'lowercase'}) +@Pipe({ + name: 'lowercase', + standalone: true, +}) export class LowerCasePipe implements PipeTransform { /** * @param value The string to transform to lower case. @@ -71,7 +74,10 @@ const unicodeWordMatch = * @ngModule CommonModule * @publicApi */ -@Pipe({name: 'titlecase'}) +@Pipe({ + name: 'titlecase', + standalone: true, +}) export class TitleCasePipe implements PipeTransform { /** * @param value The string to transform to title case. @@ -98,7 +104,10 @@ export class TitleCasePipe implements PipeTransform { * @ngModule CommonModule * @publicApi */ -@Pipe({name: 'uppercase'}) +@Pipe({ + name: 'uppercase', + standalone: true, +}) export class UpperCasePipe implements PipeTransform { /** * @param value The string to transform to upper case. diff --git a/packages/common/src/pipes/date_pipe.ts b/packages/common/src/pipes/date_pipe.ts index 088a9fcc216e4..aacb939eee39a 100644 --- a/packages/common/src/pipes/date_pipe.ts +++ b/packages/common/src/pipes/date_pipe.ts @@ -177,7 +177,11 @@ export const DATE_PIPE_DEFAULT_TIMEZONE = new InjectionToken('DATE_PIPE_ * @publicApi */ // clang-format on -@Pipe({name: 'date', pure: true}) +@Pipe({ + name: 'date', + pure: true, + standalone: true, +}) export class DatePipe implements PipeTransform { constructor( @Inject(LOCALE_ID) private locale: string, diff --git a/packages/common/src/pipes/i18n_plural_pipe.ts b/packages/common/src/pipes/i18n_plural_pipe.ts index 252da96c3e82d..2f5c6479a6cd2 100644 --- a/packages/common/src/pipes/i18n_plural_pipe.ts +++ b/packages/common/src/pipes/i18n_plural_pipe.ts @@ -28,7 +28,11 @@ const _INTERPOLATION_REGEXP: RegExp = /#/g; * * @publicApi */ -@Pipe({name: 'i18nPlural', pure: true}) +@Pipe({ + name: 'i18nPlural', + pure: true, + standalone: true, +}) export class I18nPluralPipe implements PipeTransform { constructor(private _localization: NgLocalization) {} diff --git a/packages/common/src/pipes/i18n_select_pipe.ts b/packages/common/src/pipes/i18n_select_pipe.ts index d5fac44493163..f39cfe691729a 100644 --- a/packages/common/src/pipes/i18n_select_pipe.ts +++ b/packages/common/src/pipes/i18n_select_pipe.ts @@ -7,6 +7,7 @@ */ import {Pipe, PipeTransform} from '@angular/core'; + import {invalidPipeArgumentError} from './invalid_pipe_argument_error'; /** @@ -26,7 +27,11 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error'; * * @publicApi */ -@Pipe({name: 'i18nSelect', pure: true}) +@Pipe({ + name: 'i18nSelect', + pure: true, + standalone: true, +}) export class I18nSelectPipe implements PipeTransform { /** * @param value a string to be internationalized. diff --git a/packages/common/src/pipes/json_pipe.ts b/packages/common/src/pipes/json_pipe.ts index 5a4515a0e6741..aff4747e9dccc 100644 --- a/packages/common/src/pipes/json_pipe.ts +++ b/packages/common/src/pipes/json_pipe.ts @@ -23,7 +23,11 @@ import {Pipe, PipeTransform} from '@angular/core'; * * @publicApi */ -@Pipe({name: 'json', pure: false}) +@Pipe({ + name: 'json', + pure: false, + standalone: true, +}) export class JsonPipe implements PipeTransform { /** * @param value A value of any type to convert into a JSON-format string. diff --git a/packages/common/src/pipes/keyvalue_pipe.ts b/packages/common/src/pipes/keyvalue_pipe.ts index a287bb6e5a6a4..8fdeed227323a 100644 --- a/packages/common/src/pipes/keyvalue_pipe.ts +++ b/packages/common/src/pipes/keyvalue_pipe.ts @@ -43,7 +43,11 @@ export interface KeyValue { * * @publicApi */ -@Pipe({name: 'keyvalue', pure: false}) +@Pipe({ + name: 'keyvalue', + pure: false, + standalone: true, +}) export class KeyValuePipe implements PipeTransform { constructor(private readonly differs: KeyValueDiffers) {} diff --git a/packages/common/src/pipes/number_pipe.ts b/packages/common/src/pipes/number_pipe.ts index fd379910d2a27..fc3c02ea0e6be 100644 --- a/packages/common/src/pipes/number_pipe.ts +++ b/packages/common/src/pipes/number_pipe.ts @@ -77,7 +77,10 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error'; * * @publicApi */ -@Pipe({name: 'number'}) +@Pipe({ + name: 'number', + standalone: true, +}) export class DecimalPipe implements PipeTransform { constructor(@Inject(LOCALE_ID) private _locale: string) {} @@ -126,7 +129,10 @@ export class DecimalPipe implements PipeTransform { * * @publicApi */ -@Pipe({name: 'percent'}) +@Pipe({ + name: 'percent', + standalone: true, +}) export class PercentPipe implements PipeTransform { constructor(@Inject(LOCALE_ID) private _locale: string) {} @@ -202,7 +208,10 @@ export class PercentPipe implements PipeTransform { * * @publicApi */ -@Pipe({name: 'currency'}) +@Pipe({ + name: 'currency', + standalone: true, +}) export class CurrencyPipe implements PipeTransform { constructor( @Inject(LOCALE_ID) private _locale: string, diff --git a/packages/common/src/pipes/slice_pipe.ts b/packages/common/src/pipes/slice_pipe.ts index 90bf602f923eb..bdf33ae446f35 100644 --- a/packages/common/src/pipes/slice_pipe.ts +++ b/packages/common/src/pipes/slice_pipe.ts @@ -7,6 +7,7 @@ */ import {Pipe, PipeTransform} from '@angular/core'; + import {invalidPipeArgumentError} from './invalid_pipe_argument_error'; /** @@ -44,7 +45,11 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error'; * * @publicApi */ -@Pipe({name: 'slice', pure: false}) +@Pipe({ + name: 'slice', + pure: false, + standalone: true, +}) export class SlicePipe implements PipeTransform { /** * @param value a list or a string to be sliced. diff --git a/packages/common/test/pipes/number_pipe_spec.ts b/packages/common/test/pipes/number_pipe_spec.ts index 3aa7306b82ef0..1d449994b0ee7 100644 --- a/packages/common/test/pipes/number_pipe_spec.ts +++ b/packages/common/test/pipes/number_pipe_spec.ts @@ -13,7 +13,8 @@ import localeDeAt from '@angular/common/locales/de-AT'; import localeEn from '@angular/common/locales/en'; import localeEsUS from '@angular/common/locales/es-US'; import localeFr from '@angular/common/locales/fr'; -import {ɵregisterLocaleData, ɵunregisterLocaleData} from '@angular/core'; +import {Component, ɵregisterLocaleData, ɵunregisterLocaleData} from '@angular/core'; +import {TestBed} from '@angular/core/testing'; { describe('Number pipes', () => { @@ -77,6 +78,24 @@ import {ɵregisterLocaleData, ɵunregisterLocaleData} from '@angular/core'; expect(pipe.transform('9999999.99', '1.2-2')).toEqual('9,999,999.99'); }); }); + + it('should be available as a standalone pipe', () => { + @Component({ + selector: 'test-component', + imports: [DecimalPipe], + template: '{{ value | number }}', + standalone: true, + }) + class TestComponent { + value = 12345; + } + + const fixture = TestBed.createComponent(TestComponent); + fixture.detectChanges(); + + const content = fixture.nativeElement.textContent; + expect(content).toBe('12,345'); + }); }); describe('PercentPipe', () => { @@ -112,6 +131,24 @@ import {ɵregisterLocaleData, ɵunregisterLocaleData} from '@angular/core'; `NG02100: InvalidPipeArgument: '[object Object] is not a number' for pipe 'PercentPipe'`); }); }); + + it('should be available as a standalone pipe', () => { + @Component({ + selector: 'test-component', + imports: [PercentPipe], + template: '{{ value | percent }}', + standalone: true, + }) + class TestComponent { + value = 15; + } + + const fixture = TestBed.createComponent(TestComponent); + fixture.detectChanges(); + + const content = fixture.nativeElement.textContent; + expect(content).toBe('1,500%'); + }); }); describe('CurrencyPipe', () => { @@ -179,6 +216,24 @@ import {ɵregisterLocaleData, ɵunregisterLocaleData} from '@angular/core'; `Warning: the currency pipe has been changed in Angular v5. The symbolDisplay option (third parameter) is now a string instead of a boolean. The accepted values are "code", "symbol" or "symbol-narrow".`); }); }); + + it('should be available as a standalone pipe', () => { + @Component({ + selector: 'test-component', + imports: [CurrencyPipe], + template: '{{ value | currency }}', + standalone: true, + }) + class TestComponent { + value = 15; + } + + const fixture = TestBed.createComponent(TestComponent); + fixture.detectChanges(); + + const content = fixture.nativeElement.textContent; + expect(content).toBe('$15.00'); + }); }); }); } diff --git a/packages/common/test/pipes/slice_pipe_spec.ts b/packages/common/test/pipes/slice_pipe_spec.ts index c0172e6278033..28ef56ee5fd2c 100644 --- a/packages/common/test/pipes/slice_pipe_spec.ts +++ b/packages/common/test/pipes/slice_pipe_spec.ts @@ -117,5 +117,23 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; expect(fixture.nativeElement).toHaveText('2,3'); })); }); + + it('should be available as a standalone pipe', () => { + @Component({ + selector: 'test-component', + imports: [SlicePipe], + template: '{{ title | slice:0:5 }}', + standalone: true, + }) + class TestComponent { + title = 'Hello World!'; + } + + const fixture = TestBed.createComponent(TestComponent); + fixture.detectChanges(); + + const content = fixture.nativeElement.textContent; + expect(content).toBe('Hello'); + }); }); }