Skip to content

Commit

Permalink
feat: add formatList & ListFormat
Browse files Browse the repository at this point in the history
  • Loading branch information
Long Ho authored and longlho committed Oct 24, 2019
1 parent a098369 commit 686507b
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 1 deletion.
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@
"types": "./dist/index.d.ts",
"sideEffects": false,
"dependencies": {
"@formatjs/intl-listformat": "^1.1.1",
"@formatjs/intl-relativetimeformat": "^4.2.1",
"@formatjs/intl-unified-numberformat": "^2.1.0",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/invariant": "^2.2.30",
"hoist-non-react-statics": "^3.3.0",
"intl-format-cache": "^4.2.3",
"intl-locales-supported": "^1.6.0",
"intl-messageformat": "^7.3.3",
"intl-messageformat-parser": "^3.2.2",
"intl-messageformat": "^7.3.3",
"invariant": "^2.1.1",
"shallow-equal": "^1.1.0"
},
Expand Down
2 changes: 2 additions & 0 deletions src/components/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import {formatPlural} from '../formatters/plural';
import {formatMessage, formatHTMLMessage} from '../formatters/message';
import * as shallowEquals_ from 'shallow-equal/objects';
import {formatList} from '../formatters/list';
const shallowEquals: typeof shallowEquals_ =
(shallowEquals_ as any).default || shallowEquals_;

Expand Down Expand Up @@ -177,5 +178,6 @@ export function createIntl(
),
formatMessage: formatMessage.bind(null, resolvedConfig, formatters),
formatHTMLMessage: formatHTMLMessage.bind(null, resolvedConfig, formatters),
formatList: formatList.bind(null, resolvedConfig, formatters.getListFormat),
};
}
66 changes: 66 additions & 0 deletions src/formatters/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as React from 'react';
import {IntlConfig, Formatters, IntlFormatters} from '../types';
import {filterProps, createError} from '../utils';
import IntlListFormat, {IntlListFormatOptions} from '@formatjs/intl-listformat';

const LIST_FORMAT_OPTIONS: Array<keyof IntlListFormatOptions> = [
'localeMatcher',
'type',
'style',
];

const now = Date.now();

function generateToken(i: number) {
return `${now}_${i}_${now}`;
}

export function formatList(
{locale, onError}: Pick<IntlConfig, 'locale' | 'onError'>,
getListFormat: Formatters['getListFormat'],
values: Parameters<IntlFormatters['formatList']>[0],
options: Parameters<IntlFormatters['formatList']>[1] = {}
) {
const ListFormat: typeof IntlListFormat = (Intl as any).ListFormat;
if (!ListFormat) {
onError(
createError(`Intl.ListFormat is not available in this environment.
Try polyfilling it using "@formatjs/intl-listformat"
`)
);
}
let filteredOptions = filterProps(options, LIST_FORMAT_OPTIONS);

try {
const richValues: Record<string, React.ReactNode> = {};
const serializedValues = values.map((v, i) => {
if (typeof v === 'object') {
const id = generateToken(i);
richValues[id] = v;
return id;
}
return String(v);
});
if (!Object.keys(richValues).length) {
return getListFormat(locale, filteredOptions).format(serializedValues);
}
const parts = getListFormat(locale, filteredOptions).formatToParts(
serializedValues
);
return parts.reduce((all: Array<string | React.ReactNode>, el) => {
const val = el.value;
if (richValues[val]) {
all.push(richValues[val]);
} else if (typeof all[all.length - 1] === 'string') {
all[all.length - 1] += val;
} else {
all.push(val);
}
return all;
}, []);
} catch (e) {
onError(createError('Error formatting list.', e));
}

return values;
}
11 changes: 11 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import IntlRelativeTimeFormat, {
} from '@formatjs/intl-relativetimeformat';
import {MessageFormatElement} from 'intl-messageformat-parser';
import {UnifiedNumberFormatOptions} from '@formatjs/intl-unified-numberformat';
import IntlListFormat, {IntlListFormatOptions} from '@formatjs/intl-listformat';

export interface IntlConfig {
locale: string;
Expand Down Expand Up @@ -55,6 +56,8 @@ export type FormatPluralOptions = Exclude<
> &
CustomFormatConfig;

export type FormatListOptions = Exclude<IntlListFormatOptions, 'localeMatcher'>;

export interface IntlFormatters {
formatDate(
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
Expand Down Expand Up @@ -104,6 +107,10 @@ export interface IntlFormatters {
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType>
): string;
formatList(
values: Array<string | React.ReactNode>,
opts?: FormatListOptions
): string | Array<string | React.ReactNode>;
}

export interface Formatters {
Expand All @@ -122,6 +129,9 @@ export interface Formatters {
getPluralRules(
...args: ConstructorParameters<typeof Intl.PluralRules>
): Intl.PluralRules;
getListFormat(
...args: ConstructorParameters<typeof IntlListFormat>
): IntlListFormat;
}

export interface IntlShape extends IntlConfig, IntlFormatters {
Expand All @@ -134,6 +144,7 @@ export interface IntlCache {
message: Record<string, IntlMessageFormat>;
relativeTime: Record<string, IntlRelativeTimeFormat>;
pluralRules: Record<string, Intl.PluralRules>;
list: Record<string, IntlListFormat>;
}

export interface MessageDescriptor {
Expand Down
3 changes: 3 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export function createIntlCache(): IntlCache {
message: {},
relativeTime: {},
pluralRules: {},
list: {},
};
}

Expand All @@ -112,6 +113,7 @@ export function createIntlCache(): IntlCache {
*/
export function createFormatters(cache: IntlCache = createIntlCache()) {
const RelativeTimeFormat = (Intl as any).RelativeTimeFormat;
const ListFormat = (Intl as any).ListFormat;
return {
getDateTimeFormat: memoizeIntlConstructor(
Intl.DateTimeFormat,
Expand All @@ -124,6 +126,7 @@ export function createFormatters(cache: IntlCache = createIntlCache()) {
cache.relativeTime
),
getPluralRules: memoizeIntlConstructor(Intl.PluralRules, cache.pluralRules),
getListFormat: memoizeIntlConstructor(ListFormat, cache.list),
};
}

Expand Down

0 comments on commit 686507b

Please sign in to comment.