
The existing intl.ts file is not a facade but rather a set of utils used by i18n-related pipes only. As such moving it back to common module so those utils are not used accidently from other places.
165 lines
5.6 KiB
TypeScript
165 lines
5.6 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {Inject, LOCALE_ID, Pipe, PipeTransform, Type} from '@angular/core';
|
|
|
|
import {NumberWrapper, isBlank, isPresent} from '../facade/lang';
|
|
|
|
import {NumberFormatStyle, NumberFormatter} from './intl';
|
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
|
|
|
const _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
|
|
|
|
function formatNumber(
|
|
pipe: Type<any>, locale: string, value: number | string, style: NumberFormatStyle,
|
|
digits: string, currency: string = null, currencyAsSymbol: boolean = false): string {
|
|
if (isBlank(value)) return null;
|
|
|
|
// Convert strings to numbers
|
|
value = typeof value === 'string' && NumberWrapper.isNumeric(value) ? +value : value;
|
|
if (typeof value !== 'number') {
|
|
throw new InvalidPipeArgumentError(pipe, value);
|
|
}
|
|
|
|
let minInt: number;
|
|
let minFraction: number;
|
|
let maxFraction: number;
|
|
if (style !== NumberFormatStyle.Currency) {
|
|
// rely on Intl default for currency
|
|
minInt = 1;
|
|
minFraction = 0;
|
|
maxFraction = 3;
|
|
}
|
|
|
|
if (digits) {
|
|
const parts = digits.match(_NUMBER_FORMAT_REGEXP);
|
|
if (parts === null) {
|
|
throw new Error(`${digits} is not a valid digit info for number pipes`);
|
|
}
|
|
if (isPresent(parts[1])) { // min integer digits
|
|
minInt = NumberWrapper.parseIntAutoRadix(parts[1]);
|
|
}
|
|
if (isPresent(parts[3])) { // min fraction digits
|
|
minFraction = NumberWrapper.parseIntAutoRadix(parts[3]);
|
|
}
|
|
if (isPresent(parts[5])) { // max fraction digits
|
|
maxFraction = NumberWrapper.parseIntAutoRadix(parts[5]);
|
|
}
|
|
}
|
|
|
|
return NumberFormatter.format(value as number, locale, style, {
|
|
minimumIntegerDigits: minInt,
|
|
minimumFractionDigits: minFraction,
|
|
maximumFractionDigits: maxFraction,
|
|
currency: currency,
|
|
currencyAsSymbol: currencyAsSymbol,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @ngModule CommonModule
|
|
* @whatItDoes Formats a number according to locale rules.
|
|
* @howToUse `number_expression | number[:digitInfo]`
|
|
*
|
|
* Formats a number as text. Group sizing and separator and other locale-specific
|
|
* configurations are based on the active locale.
|
|
*
|
|
* where `expression` is a number:
|
|
* - `digitInfo` is a `string` which has a following format: <br>
|
|
* <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>
|
|
* - `minIntegerDigits` is the minimum number of integer digits to use. Defaults to `1`.
|
|
* - `minFractionDigits` is the minimum number of digits after fraction. Defaults to `0`.
|
|
* - `maxFractionDigits` is the maximum number of digits after fraction. Defaults to `3`.
|
|
*
|
|
* For more information on the acceptable range for each of these numbers and other
|
|
* details see your native internationalization library.
|
|
*
|
|
* WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
|
|
* and may require a polyfill. See {@linkDocs guide/browser-support} for details.
|
|
*
|
|
* ### Example
|
|
*
|
|
* {@example common/pipes/ts/number_pipe.ts region='NumberPipe'}
|
|
*
|
|
* @stable
|
|
*/
|
|
@Pipe({name: 'number'})
|
|
export class DecimalPipe implements PipeTransform {
|
|
constructor(@Inject(LOCALE_ID) private _locale: string) {}
|
|
|
|
transform(value: any, digits: string = null): string {
|
|
return formatNumber(DecimalPipe, this._locale, value, NumberFormatStyle.Decimal, digits);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ngModule CommonModule
|
|
* @whatItDoes Formats a number as a percentage according to locale rules.
|
|
* @howToUse `number_expression | percent[:digitInfo]`
|
|
*
|
|
* @description
|
|
*
|
|
* Formats a number as percentage.
|
|
*
|
|
* - `digitInfo` See {@link DecimalPipe} for detailed description.
|
|
*
|
|
* WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
|
|
* and may require a polyfill. See {@linkDocs guide/browser-support} for details.
|
|
*
|
|
* ### Example
|
|
*
|
|
* {@example common/pipes/ts/number_pipe.ts region='PercentPipe'}
|
|
*
|
|
* @stable
|
|
*/
|
|
@Pipe({name: 'percent'})
|
|
export class PercentPipe implements PipeTransform {
|
|
constructor(@Inject(LOCALE_ID) private _locale: string) {}
|
|
|
|
transform(value: any, digits: string = null): string {
|
|
return formatNumber(PercentPipe, this._locale, value, NumberFormatStyle.Percent, digits);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ngModule CommonModule
|
|
* @whatItDoes Formats a number as currency using locale rules.
|
|
* @howToUse `number_expression | currency[:currencyCode[:symbolDisplay[:digitInfo]]]`
|
|
* @description
|
|
*
|
|
* Use `currency` to format a number as currency.
|
|
*
|
|
* - `currencyCode` is the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code, such
|
|
* as `USD` for the US dollar and `EUR` for the euro.
|
|
* - `symbolDisplay` is a boolean indicating whether to use the currency symbol or code.
|
|
* - `true`: use symbol (e.g. `$`).
|
|
* - `false`(default): use code (e.g. `USD`).
|
|
* - `digitInfo` See {@link DecimalPipe} for detailed description.
|
|
*
|
|
* WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
|
|
* and may require a polyfill. See {@linkDocs guide/browser-support} for details.
|
|
*
|
|
* ### Example
|
|
*
|
|
* {@example common/pipes/ts/number_pipe.ts region='CurrencyPipe'}
|
|
*
|
|
* @stable
|
|
*/
|
|
@Pipe({name: 'currency'})
|
|
export class CurrencyPipe implements PipeTransform {
|
|
constructor(@Inject(LOCALE_ID) private _locale: string) {}
|
|
|
|
transform(
|
|
value: any, currencyCode: string = 'USD', symbolDisplay: boolean = false,
|
|
digits: string = null): string {
|
|
return formatNumber(
|
|
CurrencyPipe, this._locale, value, NumberFormatStyle.Currency, digits, currencyCode,
|
|
symbolDisplay);
|
|
}
|
|
}
|