@haiilo/ngx-intl
Version:
Standalone Angular pipes using the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting.
432 lines (423 loc) • 19.5 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, LOCALE_ID, Pipe, Inject, Optional } from '@angular/core';
const INTL_DATE_OPTIONS = new InjectionToken('IntlDateOptions');
const INTL_DATE_TIMEZONE = new InjectionToken('IntlDateTimezone');
const INTL_DATE_PRESET_SHORT = { dateStyle: 'short', timeStyle: 'short' };
const INTL_DATE_PRESET_MEDIUM = { dateStyle: 'medium', timeStyle: 'medium' };
const INTL_DATE_PRESET_LONG = { dateStyle: 'long', timeStyle: 'long' };
const INTL_DATE_PRESET_FULL = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long', hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'long' };
const INTL_DATE_PRESET_SHORT_DATE = { dateStyle: 'short' };
const INTL_DATE_PRESET_MEDIUM_DATE = { dateStyle: 'medium' };
const INTL_DATE_PRESET_LONG_DATE = { dateStyle: 'long' };
const INTL_DATE_PRESET_FULL_DATE = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' };
const INTL_DATE_PRESET_SHORT_TIME = { timeStyle: 'short' };
const INTL_DATE_PRESET_MEDIUM_TIME = { timeStyle: 'medium' };
const INTL_DATE_PRESET_LONG_TIME = { timeStyle: 'long' };
const INTL_DATE_PRESET_FULL_TIME = { hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'long' };
/**
* A pipe that formats a date using the Intl.DateTimeFormat API.
*/
class IntlDatePipe {
constructor(locale, options, timezone) {
this.locale = locale;
this.options = options;
this.timezone = timezone;
}
transform(value, options, ...locales) {
if (value === null) {
return null;
}
const _locales = this.getLocales(locales);
const _options = this.getOptions(options);
const formatValue = typeof value === 'string' ? new Date(value) : value;
return new Intl.DateTimeFormat(_locales, _options).format(formatValue);
}
getLocales(locales) {
return [...locales, this.locale];
}
getOptions(options) {
const presetStr = typeof options === 'string';
const presetKey = !presetStr
? options?.preset || this.options?.defaultPreset || IntlDatePipe.DEFAULT_OPTIONS.defaultPreset
: options;
const preset = presetKey
? (this.options?.presets?.[presetKey] || IntlDatePipe.DEFAULT_OPTIONS.presets?.[presetKey])
: undefined;
const timezone = this.timezone ? { timeZone: this.timezone } : {};
return { ...timezone, ...preset, ...(!presetStr ? options : undefined) };
}
}
IntlDatePipe.DEFAULT_OPTIONS = {
presets: {
short: INTL_DATE_PRESET_SHORT,
medium: INTL_DATE_PRESET_MEDIUM,
long: INTL_DATE_PRESET_LONG,
full: INTL_DATE_PRESET_FULL,
shortDate: INTL_DATE_PRESET_SHORT_DATE,
mediumDate: INTL_DATE_PRESET_MEDIUM_DATE,
longDate: INTL_DATE_PRESET_LONG_DATE,
fullDate: INTL_DATE_PRESET_FULL_DATE,
shortTime: INTL_DATE_PRESET_SHORT_TIME,
mediumTime: INTL_DATE_PRESET_MEDIUM_TIME,
longTime: INTL_DATE_PRESET_LONG_TIME,
fullTime: INTL_DATE_PRESET_FULL_TIME
}
};
IntlDatePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlDatePipe, deps: [{ token: LOCALE_ID }, { token: INTL_DATE_OPTIONS, optional: true }, { token: INTL_DATE_TIMEZONE, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
IntlDatePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: IntlDatePipe, isStandalone: true, name: "intlDate" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlDatePipe, decorators: [{
type: Pipe,
args: [{
name: 'intlDate',
standalone: true
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [LOCALE_ID]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_DATE_OPTIONS]
}, {
type: Optional
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_DATE_TIMEZONE]
}, {
type: Optional
}] }]; } });
const INTL_NUMBER_OPTIONS = new InjectionToken('IntlNumberOptions');
const INTL_NUMBER_PRESET_SHORT = { useGrouping: false, maximumFractionDigits: 2 };
const INTL_NUMBER_PRESET_LONG = { maximumFractionDigits: 8 };
const INTL_NUMBER_PRESET_CURRENCY = { style: 'currency', currency: 'USD' };
const INTL_NUMBER_PRESET_PERCENT = { style: 'percent' };
/**
* A pipe that formats a number using the Intl.NumberFormat API.
*/
class IntlNumberPipe {
constructor(locale, options) {
this.locale = locale;
this.options = options;
}
transform(value, options, ...locales) {
if (value === null) {
return null;
}
const _locales = this.getLocales(locales);
const _options = this.getOptions(options);
return new Intl.NumberFormat(_locales, _options).format(value);
}
getLocales(locales) {
return [...locales, this.locale];
}
getOptions(options) {
const presetStr = typeof options === 'string';
const presetKey = !presetStr
? options?.preset || this.options?.defaultPreset || IntlNumberPipe.DEFAULT_OPTIONS.defaultPreset
: options;
const preset = presetKey
? (this.options?.presets?.[presetKey] || IntlNumberPipe.DEFAULT_OPTIONS.presets?.[presetKey])
: undefined;
return { ...preset, ...(!presetStr ? options : undefined) };
}
}
IntlNumberPipe.DEFAULT_OPTIONS = {
presets: {
short: INTL_NUMBER_PRESET_SHORT,
long: INTL_NUMBER_PRESET_LONG,
currency: INTL_NUMBER_PRESET_CURRENCY,
percent: INTL_NUMBER_PRESET_PERCENT
}
};
IntlNumberPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlNumberPipe, deps: [{ token: LOCALE_ID }, { token: INTL_NUMBER_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
IntlNumberPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: IntlNumberPipe, isStandalone: true, name: "intlNumber" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlNumberPipe, decorators: [{
type: Pipe,
args: [{
name: 'intlNumber',
standalone: true
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [LOCALE_ID]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_NUMBER_OPTIONS]
}, {
type: Optional
}] }]; } });
const INTL_PLURAL_OPTIONS = new InjectionToken('IntlPluralOptions');
const INTL_PLURAL_PRESET_CARDINAL = { type: 'cardinal' };
const INTL_PLURAL_PRESET_ORDINAL = { type: 'ordinal' };
/**
* A pipe that pluralizes a string using the Intl.PluralRules API.
*/
class IntlPluralPipe {
constructor(locale, options) {
this.locale = locale;
this.options = options;
}
transform(value, options, ...locales) {
if (value === null) {
return null;
}
const _locales = this.getLocales(locales);
const _options = this.getOptions(options);
return new Intl.PluralRules(_locales, _options).select(value);
}
getLocales(locales) {
return [...locales, this.locale];
}
getOptions(options) {
const presetStr = typeof options === 'string';
const presetKey = !presetStr
? options?.preset || this.options?.defaultPreset || IntlPluralPipe.DEFAULT_OPTIONS.defaultPreset
: options;
const preset = presetKey
? (this.options?.presets?.[presetKey] || IntlPluralPipe.DEFAULT_OPTIONS.presets?.[presetKey])
: undefined;
return { ...preset, ...(!presetStr ? options : undefined) };
}
}
IntlPluralPipe.DEFAULT_OPTIONS = {
presets: {
cardinal: INTL_PLURAL_PRESET_CARDINAL,
ordinal: INTL_PLURAL_PRESET_ORDINAL
}
};
IntlPluralPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlPluralPipe, deps: [{ token: LOCALE_ID }, { token: INTL_PLURAL_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
IntlPluralPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: IntlPluralPipe, isStandalone: true, name: "IntlPlural" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlPluralPipe, decorators: [{
type: Pipe,
args: [{
name: 'IntlPlural',
standalone: true
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [LOCALE_ID]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_PLURAL_OPTIONS]
}, {
type: Optional
}] }]; } });
const INTL_SORT_OPTIONS = new InjectionToken('IntlSortOptions');
const INTL_SORT_PRESET_LOWER_FIRST = { caseFirst: 'lower' };
const INTL_SORT_PRESET_UPPER_FIRST = { caseFirst: 'upper' };
/**
* A pipe that sorts an array of strings using the Intl.Collator API.
*/
class IntlSortPipe {
constructor(locale, options) {
this.locale = locale;
this.options = options;
}
transform(value, options, ...locales) {
if (value === null) {
return null;
}
const _locales = this.getLocales(locales);
const _options = this.getOptions(options);
return value.sort(new Intl.Collator(_locales, _options).compare);
}
getLocales(locales) {
return [...locales, this.locale];
}
getOptions(options) {
const presetStr = typeof options === 'string';
const presetKey = !presetStr
? options?.preset || this.options?.defaultPreset || IntlSortPipe.DEFAULT_OPTIONS.defaultPreset
: options;
const preset = presetKey
? (this.options?.presets?.[presetKey] || IntlSortPipe.DEFAULT_OPTIONS.presets?.[presetKey])
: undefined;
return { ...preset, ...(!presetStr ? options : undefined) };
}
}
IntlSortPipe.DEFAULT_OPTIONS = {
presets: {
lowerFirst: INTL_SORT_PRESET_LOWER_FIRST,
upperFirst: INTL_SORT_PRESET_UPPER_FIRST
}
};
IntlSortPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlSortPipe, deps: [{ token: LOCALE_ID }, { token: INTL_SORT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
IntlSortPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: IntlSortPipe, isStandalone: true, name: "IntlSort" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlSortPipe, decorators: [{
type: Pipe,
args: [{
name: 'IntlSort',
standalone: true
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [LOCALE_ID]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_SORT_OPTIONS]
}, {
type: Optional
}] }]; } });
const UNITS = {
year: 1 * 60 * 60 * 24 * 365,
years: 1 * 60 * 60 * 24 * 365,
quarter: 1 * 60 * 60 * 24 * 365 / 4,
quarters: 1 * 60 * 60 * 24 * 365 / 4,
month: 1 * 60 * 60 * 24 * 365 / 12,
months: 1 * 60 * 60 * 24 * 365 / 12,
week: 1 * 60 * 60 * 24 * 7,
weeks: 1 * 60 * 60 * 24 * 7,
day: 1 * 60 * 60 * 24,
days: 1 * 60 * 60 * 24,
hour: 1 * 60 * 60,
hours: 1 * 60 * 60,
minute: 1 * 60,
minutes: 1 * 60,
second: 1,
seconds: 1
};
const INTL_TIMEAGO_OPTIONS = new InjectionToken('IntlTimeagoOptions');
const INTL_TIMEAGO_PRESET_SHORT = { numeric: 'auto', style: 'short', dateOptions: 'shortDate' };
const INTL_TIMEAGO_PRESET_LONG = { numeric: 'auto', style: 'long', dateOptions: 'mediumDate' };
/**
* A pipe that formats a date value to a human-readable relative-timeago string
* using the Intl.RelativeTimeFormat API.
*/
class IntlTimeagoPipe {
constructor(cdRef, ngZone, locale, options, dateOptions, dateTimezone) {
this.cdRef = cdRef;
this.ngZone = ngZone;
this.locale = locale;
this.options = options;
this.lastLocales = [];
this.text = null;
this.intlDatePipe = new IntlDatePipe(locale, dateOptions, dateTimezone);
}
ngOnDestroy() {
this.removeTimer();
}
transform(value, options, ...locales) {
if (value !== this.lastValue || options !== this.lastOptions || locales.join() !== this.lastLocales.join()) {
this.lastValue = value;
this.lastOptions = options;
this.lastLocales = locales;
this.process();
this.removeTimer();
this.createTimer();
}
else {
this.createTimer();
}
return this.text;
}
process() {
if (this.lastValue == null) {
this.text = null;
this.update = undefined;
return;
}
const _locales = this.getLocales(this.lastLocales);
const _options = this.getOptions(this.lastOptions);
const now = new Date(_options.reference ?? new Date());
const then = new Date(this.lastValue);
const seconds = Math.abs(Math.round((then.getTime() - now.getTime()) / 1000));
const minRelative = _options.minRelative ?? IntlTimeagoPipe.DEFAULT_OPTIONS.minRelative ?? -1;
const maxRelative = _options.maxRelative ?? IntlTimeagoPipe.DEFAULT_OPTIONS.maxRelative ?? Number.MAX_SAFE_INTEGER;
if (seconds < minRelative) {
this.text = _options.now ?? IntlTimeagoPipe.DEFAULT_OPTIONS.now ?? '';
this.update = minRelative - seconds;
}
else if (seconds >= maxRelative) {
this.text = this.intlDatePipe.transform(then, _options.dateOptions, ..._locales);
this.update = undefined;
}
else {
const allowed = _options.units ?? IntlTimeagoPipe.DEFAULT_OPTIONS.units;
const unit = this.getUnit(seconds, allowed);
const diff = this.getDiff(now, then, unit);
this.text = new Intl.RelativeTimeFormat(_locales, _options).format(diff, unit);
this.update = UNITS[unit] - (seconds % UNITS[unit]);
}
}
getUnit(seconds, allowed) {
const units = Object.entries(UNITS)
.sort(([, a], [, b]) => a - b)
.filter(([u, v]) => seconds >= v && (allowed?.includes(u) ?? true))
.reverse();
return units?.[0]?.[0] ?? allowed?.sort((a, b) => UNITS[a] - UNITS[b])?.[0] ?? 'second';
}
getDiff(now, then, unit) {
return Math.ceil((then.getTime() - now.getTime()) / 1000 / UNITS[unit]);
}
getLocales(locales) {
return [...locales, this.locale];
}
getOptions(options) {
const presetStr = typeof options === 'string';
const presetKey = !presetStr
? options?.preset || this.options?.defaultPreset || IntlTimeagoPipe.DEFAULT_OPTIONS.defaultPreset
: options;
const preset = presetKey
? (this.options?.presets?.[presetKey] || IntlTimeagoPipe.DEFAULT_OPTIONS.presets?.[presetKey])
: undefined;
return { ...preset, ...(!presetStr ? options : undefined) };
}
createTimer() {
if (this.timer || !this.update) {
return;
}
const update = this.update;
this.timer = this.ngZone.runOutsideAngular(() => window.setTimeout(() => {
this.process();
this.timer = undefined;
this.ngZone.run(() => this.cdRef.markForCheck());
}, update * 1000));
}
removeTimer() {
if (this.timer) {
window.clearTimeout(this.timer);
this.timer = undefined;
}
}
}
IntlTimeagoPipe.DEFAULT_OPTIONS = {
presets: {
short: INTL_TIMEAGO_PRESET_SHORT,
long: INTL_TIMEAGO_PRESET_LONG,
}
};
IntlTimeagoPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlTimeagoPipe, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: LOCALE_ID }, { token: INTL_TIMEAGO_OPTIONS, optional: true }, { token: INTL_DATE_OPTIONS, optional: true }, { token: INTL_DATE_TIMEZONE, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
IntlTimeagoPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: IntlTimeagoPipe, isStandalone: true, name: "intlTimeago", pure: false });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntlTimeagoPipe, decorators: [{
type: Pipe,
args: [{
name: 'intlTimeago',
standalone: true,
pure: false
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
type: Inject,
args: [LOCALE_ID]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_TIMEAGO_OPTIONS]
}, {
type: Optional
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_DATE_OPTIONS]
}, {
type: Optional
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INTL_DATE_TIMEZONE]
}, {
type: Optional
}] }]; } });
/*
* Public API Surface of ngx-intl
*/
/**
* Generated bundle index. Do not edit.
*/
export { INTL_DATE_OPTIONS, INTL_DATE_PRESET_FULL, INTL_DATE_PRESET_FULL_DATE, INTL_DATE_PRESET_FULL_TIME, INTL_DATE_PRESET_LONG, INTL_DATE_PRESET_LONG_DATE, INTL_DATE_PRESET_LONG_TIME, INTL_DATE_PRESET_MEDIUM, INTL_DATE_PRESET_MEDIUM_DATE, INTL_DATE_PRESET_MEDIUM_TIME, INTL_DATE_PRESET_SHORT, INTL_DATE_PRESET_SHORT_DATE, INTL_DATE_PRESET_SHORT_TIME, INTL_DATE_TIMEZONE, INTL_NUMBER_OPTIONS, INTL_NUMBER_PRESET_CURRENCY, INTL_NUMBER_PRESET_LONG, INTL_NUMBER_PRESET_PERCENT, INTL_NUMBER_PRESET_SHORT, INTL_PLURAL_OPTIONS, INTL_PLURAL_PRESET_CARDINAL, INTL_PLURAL_PRESET_ORDINAL, INTL_SORT_OPTIONS, INTL_SORT_PRESET_LOWER_FIRST, INTL_SORT_PRESET_UPPER_FIRST, INTL_TIMEAGO_OPTIONS, INTL_TIMEAGO_PRESET_LONG, INTL_TIMEAGO_PRESET_SHORT, IntlDatePipe, IntlNumberPipe, IntlPluralPipe, IntlSortPipe, IntlTimeagoPipe };
//# sourceMappingURL=haiilo-ngx-intl.mjs.map