react-intl 3.9.3 → 3.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/dist/components/createFormattedComponent.d.ts +2 -1
  3. package/dist/components/createFormattedComponent.js +7 -2
  4. package/dist/components/html-message.js +1 -1
  5. package/dist/components/injectIntl.d.ts +1 -1
  6. package/dist/components/message.js +13 -4
  7. package/dist/components/plural.d.ts +1 -1
  8. package/dist/components/provider.js +14 -9
  9. package/dist/components/relative.js +3 -10
  10. package/dist/formatters/dateTime.js +2 -2
  11. package/dist/formatters/displayName.d.ts +2 -0
  12. package/dist/formatters/displayName.js +25 -0
  13. package/dist/formatters/message.d.ts +1 -0
  14. package/dist/formatters/message.js +19 -18
  15. package/dist/index.d.ts +7 -3
  16. package/dist/index.js +5 -2
  17. package/dist/react-intl.api.md +22 -5
  18. package/dist/react-intl.d.ts +64 -15
  19. package/dist/react-intl.js +5821 -5655
  20. package/dist/react-intl.js.map +1 -1
  21. package/dist/react-intl.min.js +1 -1
  22. package/dist/react-intl.min.js.map +1 -1
  23. package/dist/types.d.ts +6 -1
  24. package/dist/utils.d.ts +1 -1
  25. package/dist/utils.js +5 -7
  26. package/lib/components/createFormattedComponent.d.ts +2 -1
  27. package/lib/components/createFormattedComponent.js +7 -2
  28. package/lib/components/html-message.js +1 -1
  29. package/lib/components/injectIntl.d.ts +1 -1
  30. package/lib/components/message.js +5 -3
  31. package/lib/components/plural.d.ts +1 -1
  32. package/lib/components/provider.js +14 -9
  33. package/lib/components/relative.js +3 -10
  34. package/lib/formatters/dateTime.js +2 -2
  35. package/lib/formatters/displayName.d.ts +2 -0
  36. package/lib/formatters/displayName.js +22 -0
  37. package/lib/formatters/message.d.ts +1 -0
  38. package/lib/formatters/message.js +12 -18
  39. package/lib/index.d.ts +7 -3
  40. package/lib/index.js +4 -1
  41. package/lib/react-intl.d.ts +20 -7
  42. package/lib/tsdoc-metadata.json +1 -1
  43. package/lib/types.d.ts +6 -1
  44. package/lib/utils.d.ts +1 -1
  45. package/lib/utils.js +4 -6
  46. package/package.json +38 -39
  47. package/src/components/createFormattedComponent.tsx +5 -0
  48. package/src/components/provider.tsx +26 -11
  49. package/src/components/relative.tsx +6 -15
  50. package/src/formatters/displayName.ts +35 -0
  51. package/src/formatters/message.ts +13 -18
  52. package/src/index.ts +7 -1
  53. package/src/types.ts +16 -5
  54. package/src/utils.ts +5 -7
package/lib/utils.js CHANGED
@@ -11,12 +11,7 @@ file in the root directory of React's source tree.
11
11
  import * as React from 'react';
12
12
  import IntlMessageFormat from 'intl-messageformat';
13
13
  import memoizeIntlConstructor from 'intl-format-cache';
14
- // Since rollup cannot deal with namespace being a function,
15
- // this is to interop with TypeScript since `invariant`
16
- // does not export a default
17
- // https://github.com/rollup/rollup/issues/1267
18
- import * as invariant_ from 'invariant';
19
- const invariant = invariant_.default || invariant_;
14
+ import { invariant } from '@formatjs/intl-utils';
20
15
  const ESCAPED_CHARS = {
21
16
  38: '&',
22
17
  62: '>',
@@ -69,6 +64,7 @@ export function createIntlCache() {
69
64
  relativeTime: {},
70
65
  pluralRules: {},
71
66
  list: {},
67
+ displayNames: {},
72
68
  };
73
69
  }
74
70
  /**
@@ -78,6 +74,7 @@ export function createIntlCache() {
78
74
  export function createFormatters(cache = createIntlCache()) {
79
75
  const RelativeTimeFormat = Intl.RelativeTimeFormat;
80
76
  const ListFormat = Intl.ListFormat;
77
+ const DisplayNames = Intl.DisplayNames;
81
78
  return {
82
79
  getDateTimeFormat: memoizeIntlConstructor(Intl.DateTimeFormat, cache.dateTime),
83
80
  getNumberFormat: memoizeIntlConstructor(Intl.NumberFormat, cache.number),
@@ -85,6 +82,7 @@ export function createFormatters(cache = createIntlCache()) {
85
82
  getRelativeTimeFormat: memoizeIntlConstructor(RelativeTimeFormat, cache.relativeTime),
86
83
  getPluralRules: memoizeIntlConstructor(Intl.PluralRules, cache.pluralRules),
87
84
  getListFormat: memoizeIntlConstructor(ListFormat, cache.list),
85
+ getDisplayNames: memoizeIntlConstructor(DisplayNames, cache.displayNames),
88
86
  };
89
87
  }
90
88
  export function getNamedFormat(formats, type, name, onError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-intl",
3
- "version": "3.9.3",
3
+ "version": "3.12.1",
4
4
  "description": "Internationalize React apps. This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.",
5
5
  "keywords": [
6
6
  "intl",
@@ -131,50 +131,49 @@
131
131
  "types": "./lib/react-intl.d.ts",
132
132
  "sideEffects": false,
133
133
  "dependencies": {
134
- "@formatjs/intl-listformat": "1.3.1",
135
- "@formatjs/intl-relativetimeformat": "4.5.1",
136
- "@formatjs/intl-unified-numberformat": "2.2.0",
137
- "@formatjs/macro": "0.2.6",
134
+ "@formatjs/intl-displaynames": "^1.2.0",
135
+ "@formatjs/intl-listformat": "^1.4.1",
136
+ "@formatjs/intl-relativetimeformat": "^4.5.9",
137
+ "@formatjs/intl-unified-numberformat": "^3.2.0",
138
+ "@formatjs/intl-utils": "^2.2.0",
138
139
  "@types/hoist-non-react-statics": "^3.3.1",
139
- "@types/invariant": "^2.2.30",
140
- "hoist-non-react-statics": "^3.3.1",
141
- "intl-format-cache": "4.2.13",
142
- "intl-locales-supported": "1.8.4",
143
- "intl-messageformat": "7.7.2",
144
- "intl-messageformat-parser": "3.5.1",
145
- "invariant": "^2.1.1",
140
+ "@types/invariant": "^2.2.31",
141
+ "hoist-non-react-statics": "^3.3.2",
142
+ "intl-format-cache": "^4.2.21",
143
+ "intl-messageformat": "^7.8.4",
144
+ "intl-messageformat-parser": "^3.6.4",
146
145
  "shallow-equal": "^1.2.1"
147
146
  },
148
147
  "peerDependencies": {
149
148
  "react": "^16.3.0"
150
149
  },
151
150
  "devDependencies": {
152
- "@babel/core": "^7.7.5",
153
- "@babel/node": "^7.7.4",
154
- "@babel/plugin-proposal-class-properties": "^7.7.4",
155
- "@babel/plugin-transform-modules-commonjs": "^7.7.5",
156
- "@babel/preset-env": "^7.7.6",
157
- "@babel/preset-react": "^7.7.4",
158
- "@formatjs/intl-pluralrules": "^1.3.9",
159
- "@microsoft/api-documenter": "^7.7.2",
160
- "@microsoft/api-extractor": "^7.7.0",
151
+ "@babel/core": "^7.8.4",
152
+ "@babel/node": "^7.8.4",
153
+ "@babel/plugin-proposal-class-properties": "^7.8.3",
154
+ "@babel/plugin-transform-modules-commonjs": "^7.8.3",
155
+ "@babel/preset-env": "^7.8.4",
156
+ "@babel/preset-react": "^7.8.3",
157
+ "@formatjs/intl-pluralrules": "^1.5.2",
158
+ "@microsoft/api-documenter": "^7.7.12",
159
+ "@microsoft/api-extractor": "^7.7.8",
161
160
  "@types/benchmark": "^1.0.31",
162
161
  "@types/enzyme": "^3.10.4",
163
- "@types/jest": "^24.0.23",
162
+ "@types/jest": "^24.9.1",
164
163
  "@types/prop-types": "^15.7.3",
165
- "@types/react": "^16.9.16",
166
- "@types/react-dom": "^16.9.4",
167
- "@typescript-eslint/eslint-plugin": "^2.11.0",
168
- "@typescript-eslint/parser": "^2.11.0",
164
+ "@types/react": "^16.9.19",
165
+ "@types/react-dom": "^16.9.5",
166
+ "@typescript-eslint/eslint-plugin": "^2.19.0",
167
+ "@typescript-eslint/parser": "^2.19.0",
169
168
  "babel-jest": "^24.9.0",
170
169
  "benchmark": "^2.1.0",
171
- "core-js": "^3.4.8",
170
+ "core-js": "^3.6.4",
172
171
  "cross-env": "^6.0.3",
173
- "enzyme": "^3.6.0",
174
- "enzyme-adapter-react-16": "^1.15.1",
175
- "enzyme-to-json": "^3.4.3",
176
- "eslint": "^6.7.2",
177
- "eslint-plugin-react": "^7.17.0",
172
+ "enzyme": "^3.11.0",
173
+ "enzyme-adapter-react-16": "^1.15.2",
174
+ "enzyme-to-json": "^3.4.4",
175
+ "eslint": "^6.8.0",
176
+ "eslint-plugin-react": "^7.18.3",
178
177
  "fs-extra": "^8.1.0",
179
178
  "full-icu": "^1.3.0",
180
179
  "glob": "^7.1.6",
@@ -186,19 +185,19 @@
186
185
  "prettier": "^1.19.1",
187
186
  "react": "^16.12.0",
188
187
  "react-dom": "^16.12.0",
189
- "rimraf": "^3.0.0",
190
- "rollup": "^1.27.9",
188
+ "rimraf": "^3.0.1",
189
+ "rollup": "^1.31.0",
191
190
  "rollup-plugin-babel": "^4.3.3",
192
191
  "rollup-plugin-commonjs": "^10.1.0",
193
192
  "rollup-plugin-node-resolve": "^5.2.0",
194
193
  "rollup-plugin-replace": "^2.0.0",
195
194
  "rollup-plugin-typescript2": "^0.25.3",
196
- "rollup-plugin-uglify": "^6.0.3",
197
- "standard-version": "^7.0.1",
198
- "ts-jest": "^24.2.0",
199
- "ts-node": "^8.5.4",
195
+ "rollup-plugin-uglify": "^6.0.4",
196
+ "standard-version": "^7.1.0",
197
+ "ts-jest": "^24.3.0",
198
+ "ts-node": "^8.6.2",
200
199
  "tslib": "^1.9.3",
201
- "typescript": "~3.3.0"
200
+ "typescript": "^3.7.5"
202
201
  },
203
202
  "scripts": {
204
203
  "benchmark": "cross-env NODE_ENV=production TS_NODE_PROJECT=./tsconfig.cjs.json ts-node test/perf/index.tsx",
@@ -5,6 +5,7 @@ import {
5
5
  FormatDateOptions,
6
6
  FormatNumberOptions,
7
7
  FormatListOptions,
8
+ FormatDisplayNameOptions,
8
9
  } from '../types';
9
10
  import {Context} from './injectIntl';
10
11
 
@@ -13,6 +14,9 @@ enum DisplayName {
13
14
  formatTime = 'FormattedTime',
14
15
  formatNumber = 'FormattedNumber',
15
16
  formatList = 'FormattedList',
17
+ // Note that this DisplayName is the locale display name, not to be confused with
18
+ // the name of the enum, which is for React component display name in dev tools.
19
+ formatDisplayName = 'FormattedDisplayName',
16
20
  }
17
21
 
18
22
  enum DisplayNameParts {
@@ -27,6 +31,7 @@ type Formatter = {
27
31
  formatTime: FormatDateOptions;
28
32
  formatNumber: FormatNumberOptions;
29
33
  formatList: FormatListOptions;
34
+ formatDisplayName: FormatDisplayNameOptions;
30
35
  };
31
36
 
32
37
  export const FormattedNumberParts: React.FC<Formatter['formatNumber'] & {
@@ -14,7 +14,6 @@ import {
14
14
  createIntlCache,
15
15
  } from '../utils';
16
16
  import {IntlConfig, IntlShape, Omit, IntlCache} from '../types';
17
- import areIntlLocalesSupported from 'intl-locales-supported';
18
17
  import {formatNumber, formatNumberToParts} from '../formatters/number';
19
18
  import {formatRelativeTime} from '../formatters/relativeTime';
20
19
  import {
@@ -27,6 +26,7 @@ import {formatPlural} from '../formatters/plural';
27
26
  import {formatMessage, formatHTMLMessage} from '../formatters/message';
28
27
  import * as shallowEquals_ from 'shallow-equal/objects';
29
28
  import {formatList} from '../formatters/list';
29
+ import {formatDisplayName} from '../formatters/displayName';
30
30
  const shallowEquals: typeof shallowEquals_ =
31
31
  (shallowEquals_ as any).default || shallowEquals_;
32
32
 
@@ -79,26 +79,36 @@ export function createIntl(
79
79
  ): IntlShape {
80
80
  const formatters = createFormatters(cache);
81
81
  const resolvedConfig = {...DEFAULT_INTL_CONFIG, ...config};
82
- if (
83
- !resolvedConfig.locale ||
84
- !areIntlLocalesSupported(resolvedConfig.locale)
85
- ) {
86
- const {locale, defaultLocale, onError} = resolvedConfig;
87
- if (typeof onError === 'function') {
82
+ const {locale, defaultLocale, onError} = resolvedConfig;
83
+ if (!locale) {
84
+ if (onError) {
88
85
  onError(
89
86
  createError(
90
- `Missing locale data for locale: "${locale}". ` +
91
- `Using default locale: "${defaultLocale}" as fallback.`
87
+ `"locale" was not configured, using "${defaultLocale}" as fallback. See https://github.com/formatjs/react-intl/blob/master/docs/API.md#intlshape for more details`
92
88
  )
93
89
  );
94
90
  }
95
-
96
91
  // Since there's no registered locale data for `locale`, this will
97
92
  // fallback to the `defaultLocale` to make sure things can render.
98
93
  // The `messages` are overridden to the `defaultProps` empty object
99
94
  // to maintain referential equality across re-renders. It's assumed
100
95
  // each <FormattedMessage> contains a `defaultMessage` prop.
101
96
  resolvedConfig.locale = resolvedConfig.defaultLocale || 'en';
97
+ } else if (!Intl.NumberFormat.supportedLocalesOf(locale).length && onError) {
98
+ onError(
99
+ createError(
100
+ `Missing locale data for locale: "${locale}" in Intl.NumberFormat. Using default locale: "${defaultLocale}" as fallback. See https://github.com/formatjs/react-intl/blob/master/docs/Getting-Started.md#runtime-requirements for more details`
101
+ )
102
+ );
103
+ } else if (
104
+ !Intl.DateTimeFormat.supportedLocalesOf(locale).length &&
105
+ onError
106
+ ) {
107
+ onError(
108
+ createError(
109
+ `Missing locale data for locale: "${locale}" in Intl.DateTimeFormat. Using default locale: "${defaultLocale}" as fallback. See https://github.com/formatjs/react-intl/blob/master/docs/Getting-Started.md#runtime-requirements for more details`
110
+ )
111
+ );
102
112
  }
103
113
  return {
104
114
  ...resolvedConfig,
@@ -146,6 +156,11 @@ export function createIntl(
146
156
  formatMessage: formatMessage.bind(null, resolvedConfig, formatters),
147
157
  formatHTMLMessage: formatHTMLMessage.bind(null, resolvedConfig, formatters),
148
158
  formatList: formatList.bind(null, resolvedConfig, formatters.getListFormat),
159
+ formatDisplayName: formatDisplayName.bind(
160
+ null,
161
+ resolvedConfig,
162
+ formatters.getDisplayNames
163
+ ),
149
164
  };
150
165
  }
151
166
 
@@ -178,6 +193,6 @@ export default class IntlProvider extends React.PureComponent<
178
193
 
179
194
  render(): JSX.Element {
180
195
  invariantIntlContext(this.state.intl);
181
- return <Provider value={this.state.intl!}>{this.props.children}</Provider>;
196
+ return <Provider value={this.state.intl}>{this.props.children}</Provider>;
182
197
  }
183
198
  }
@@ -8,13 +8,7 @@ import {Context} from './injectIntl';
8
8
  import {FormatRelativeTimeOptions} from '../types';
9
9
  import {Unit} from '@formatjs/intl-relativetimeformat';
10
10
  import {invariantIntlContext} from '../utils';
11
-
12
- // Since rollup cannot deal with namespace being a function,
13
- // this is to interop with TypeScript since `invariant`
14
- // does not export a default
15
- // https://github.com/rollup/rollup/issues/1267
16
- import * as invariant_ from 'invariant';
17
- const invariant: typeof invariant_ = (invariant_ as any).default || invariant_;
11
+ import {invariant} from '@formatjs/intl-utils';
18
12
  const MINUTE = 60;
19
13
  const HOUR = 60 * 60;
20
14
  const DAY = 60 * 60 * 24;
@@ -82,13 +76,6 @@ function canIncrement(unit: Unit = 'second'): boolean {
82
76
  return INCREMENTABLE_UNITS.includes(unit);
83
77
  }
84
78
 
85
- function verifyProps(updateIntervalInSeconds?: number, unit?: Unit): void {
86
- invariant(
87
- !updateIntervalInSeconds || (updateIntervalInSeconds && canIncrement(unit)),
88
- 'Cannot schedule update with unit longer than hour'
89
- );
90
- }
91
-
92
79
  export class FormattedRelativeTime extends React.PureComponent<Props, State> {
93
80
  // Public for testing
94
81
  _updateTimer: any = null;
@@ -107,7 +94,11 @@ export class FormattedRelativeTime extends React.PureComponent<Props, State> {
107
94
 
108
95
  constructor(props: Props) {
109
96
  super(props);
110
- verifyProps(props.updateIntervalInSeconds, props.unit);
97
+ invariant(
98
+ !props.updateIntervalInSeconds ||
99
+ !!(props.updateIntervalInSeconds && canIncrement(props.unit)),
100
+ 'Cannot schedule update with unit longer than hour'
101
+ );
111
102
  }
112
103
 
113
104
  scheduleNextUpdate(
@@ -0,0 +1,35 @@
1
+ import {IntlConfig, Formatters, IntlFormatters} from '../types';
2
+ import {filterProps, createError} from '../utils';
3
+ import {
4
+ DisplayNamesOptions,
5
+ DisplayNames as IntlDisplayNames,
6
+ } from '@formatjs/intl-displaynames';
7
+
8
+ const DISPLAY_NAMES_OPTONS: Array<keyof DisplayNamesOptions> = [
9
+ 'localeMatcher',
10
+ 'style',
11
+ 'type',
12
+ 'fallback',
13
+ ];
14
+
15
+ export function formatDisplayName(
16
+ {locale, onError}: Pick<IntlConfig, 'locale' | 'onError'>,
17
+ getDisplayNames: Formatters['getDisplayNames'],
18
+ value: Parameters<IntlFormatters['formatDisplayName']>[0],
19
+ options: Parameters<IntlFormatters['formatDisplayName']>[1] = {}
20
+ ): string | undefined {
21
+ const DisplayNames: typeof IntlDisplayNames = (Intl as any).DisplayNames;
22
+ if (!DisplayNames) {
23
+ onError(
24
+ createError(`Intl.DisplayNames is not available in this environment.
25
+ Try polyfilling it using "@formatjs/intl-displaynames"
26
+ `)
27
+ );
28
+ }
29
+ const filteredOptions = filterProps(options, DISPLAY_NAMES_OPTONS);
30
+ try {
31
+ return getDisplayNames(locale, filteredOptions).of(value);
32
+ } catch (e) {
33
+ onError(createError('Error formatting display name.', e));
34
+ }
35
+ }
@@ -5,12 +5,7 @@
5
5
  */
6
6
 
7
7
  import * as React from 'react';
8
- // Since rollup cannot deal with namespace being a function,
9
- // this is to interop with TypeScript since `invariant`
10
- // does not export a default
11
- // https://github.com/rollup/rollup/issues/1267
12
- import * as invariant_ from 'invariant';
13
- const invariant: typeof invariant_ = (invariant_ as any).default || invariant_;
8
+ import {invariant} from '@formatjs/intl-utils';
14
9
 
15
10
  import {
16
11
  Formatters,
@@ -77,6 +72,10 @@ function deepMergeFormatsAndSetTimeZone(
77
72
  };
78
73
  }
79
74
 
75
+ export const prepareIntlMessageFormatHtmlOutput = (
76
+ chunks: (string | object)[]
77
+ ): React.ReactElement => React.createElement(React.Fragment, null, ...chunks);
78
+
80
79
  export function formatMessage(
81
80
  {
82
81
  locale,
@@ -123,17 +122,12 @@ export function formatMessage(
123
122
  string,
124
123
  PrimitiveType | React.ReactElement | FormatXMLElementFn
125
124
  > = {}
126
- ): string | React.ReactNodeArray {
125
+ ): string | React.ReactNodeArray | React.ReactElement {
127
126
  const {id, defaultMessage} = messageDescriptor;
128
127
 
129
128
  // `id` is a required field of a Message Descriptor.
130
- invariant(id, '[React Intl] An `id` must be provided to format a message.');
131
- if (!id) {
132
- throw new Error(
133
- '[React Intl] An `id` must be provided to format a message.'
134
- );
135
- }
136
- const message = messages && messages[id];
129
+ invariant(!!id, '[React Intl] An `id` must be provided to format a message.');
130
+ const message = messages && messages[String(id)];
137
131
  formats = deepMergeFormatsAndSetTimeZone(formats, timeZone);
138
132
  defaultFormats = deepMergeFormatsAndSetTimeZone(defaultFormats, timeZone);
139
133
 
@@ -198,17 +192,18 @@ export function formatMessage(
198
192
  )
199
193
  );
200
194
  if (typeof message === 'string') {
201
- return message || defaultMessage || id;
195
+ return message || defaultMessage || String(id);
202
196
  }
203
- return defaultMessage || id;
197
+ return defaultMessage || String(id);
204
198
  }
205
199
  if (
206
200
  formattedMessageParts.length === 1 &&
207
201
  typeof formattedMessageParts[0] === 'string'
208
202
  ) {
209
- return (formattedMessageParts[0] as string) || defaultMessage || id;
203
+ return (formattedMessageParts[0] as string) || defaultMessage || String(id);
210
204
  }
211
- return formattedMessageParts;
205
+
206
+ return prepareIntlMessageFormatHtmlOutput(formattedMessageParts);
212
207
  }
213
208
 
214
209
  export function formatHTMLMessage(
package/src/index.ts CHANGED
@@ -5,7 +5,9 @@
5
5
  */
6
6
  import * as React from 'react';
7
7
  export * from './types';
8
- export {defineMessages} from '@formatjs/macro';
8
+ export function defineMessages<T, U extends Record<string, T>>(msgs: U): U {
9
+ return msgs;
10
+ }
9
11
  import {
10
12
  createFormattedComponent,
11
13
  createFormattedDateTimePartsComponent,
@@ -13,6 +15,7 @@ import {
13
15
  import {CustomFormatConfig} from './types';
14
16
  import {UnifiedNumberFormatOptions} from '@formatjs/intl-unified-numberformat';
15
17
  import {IntlListFormatOptions} from '@formatjs/intl-listformat';
18
+ import {DisplayNamesOptions} from '@formatjs/intl-displaynames/lib';
16
19
  export {
17
20
  default as injectIntl,
18
21
  Provider as RawIntlProvider,
@@ -38,6 +41,9 @@ export const FormattedNumber: React.FC<UnifiedNumberFormatOptions &
38
41
  export const FormattedList: React.FC<IntlListFormatOptions & {
39
42
  value: React.ReactNode[];
40
43
  }> = createFormattedComponent('formatList');
44
+ export const FormattedDisplayName: React.FC<DisplayNamesOptions & {
45
+ value: string | number | object;
46
+ }> = createFormattedComponent('formatDisplayName');
41
47
  export const FormattedDateParts = createFormattedDateTimePartsComponent(
42
48
  'formatDate'
43
49
  );
package/src/types.ts CHANGED
@@ -15,6 +15,7 @@ import IntlRelativeTimeFormat, {
15
15
  import {MessageFormatElement} from 'intl-messageformat-parser';
16
16
  import {UnifiedNumberFormatOptions} from '@formatjs/intl-unified-numberformat';
17
17
  import IntlListFormat, {IntlListFormatOptions} from '@formatjs/intl-listformat';
18
+ import {DisplayNames, DisplayNamesOptions} from '@formatjs/intl-displaynames';
18
19
 
19
20
  export interface IntlConfig {
20
21
  locale: string;
@@ -58,6 +59,11 @@ export type FormatPluralOptions = Exclude<
58
59
 
59
60
  export type FormatListOptions = Exclude<IntlListFormatOptions, 'localeMatcher'>;
60
61
 
62
+ export type FormatDisplayNameOptions = Exclude<
63
+ DisplayNamesOptions,
64
+ 'localeMatcher'
65
+ >;
66
+
61
67
  export interface IntlFormatters {
62
68
  formatDate(
63
69
  value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
@@ -107,14 +113,15 @@ export interface IntlFormatters {
107
113
  descriptor: MessageDescriptor,
108
114
  values?: Record<string, PrimitiveType>
109
115
  ): React.ReactNode;
110
- formatList(
111
- values: Array<string>,
112
- opts?: FormatListOptions
113
- ): string;
116
+ formatList(values: Array<string>, opts?: FormatListOptions): string;
114
117
  formatList(
115
118
  values: Array<string | React.ReactNode>,
116
119
  opts?: FormatListOptions
117
120
  ): React.ReactNode;
121
+ formatDisplayName(
122
+ value: Parameters<DisplayNames['of']>[0],
123
+ opts?: FormatDisplayNameOptions
124
+ ): string | undefined;
118
125
  }
119
126
 
120
127
  export interface Formatters {
@@ -136,6 +143,9 @@ export interface Formatters {
136
143
  getListFormat(
137
144
  ...args: ConstructorParameters<typeof IntlListFormat>
138
145
  ): IntlListFormat;
146
+ getDisplayNames(
147
+ ...args: ConstructorParameters<typeof DisplayNames>
148
+ ): DisplayNames;
139
149
  }
140
150
 
141
151
  export interface IntlShape extends IntlConfig, IntlFormatters {
@@ -149,10 +159,11 @@ export interface IntlCache {
149
159
  relativeTime: Record<string, IntlRelativeTimeFormat>;
150
160
  pluralRules: Record<string, Intl.PluralRules>;
151
161
  list: Record<string, IntlListFormat>;
162
+ displayNames: Record<string, DisplayNames>;
152
163
  }
153
164
 
154
165
  export interface MessageDescriptor {
155
- id?: string;
166
+ id?: string | number;
156
167
  description?: string | object;
157
168
  defaultMessage?: string;
158
169
  }
package/src/utils.ts CHANGED
@@ -13,13 +13,8 @@ import {IntlConfig, IntlCache, CustomFormats, Formatters} from './types';
13
13
  import * as React from 'react';
14
14
  import IntlMessageFormat from 'intl-messageformat';
15
15
  import memoizeIntlConstructor from 'intl-format-cache';
16
- // Since rollup cannot deal with namespace being a function,
17
- // this is to interop with TypeScript since `invariant`
18
- // does not export a default
19
- // https://github.com/rollup/rollup/issues/1267
20
- import * as invariant_ from 'invariant';
16
+ import {invariant} from '@formatjs/intl-utils';
21
17
  import {IntlRelativeTimeFormatOptions} from '@formatjs/intl-relativetimeformat';
22
- const invariant: typeof invariant_ = (invariant_ as any).default || invariant_;
23
18
 
24
19
  const ESCAPED_CHARS: Record<number, string> = {
25
20
  38: '&amp;',
@@ -54,7 +49,7 @@ export function filterProps<T extends Record<string, any>, K extends string>(
54
49
  }, {} as Pick<T, K>);
55
50
  }
56
51
 
57
- export function invariantIntlContext(intl?: any): void {
52
+ export function invariantIntlContext(intl?: any): asserts intl {
58
53
  invariant(
59
54
  intl,
60
55
  '[React Intl] Could not find required `intl` object. ' +
@@ -102,6 +97,7 @@ export function createIntlCache(): IntlCache {
102
97
  relativeTime: {},
103
98
  pluralRules: {},
104
99
  list: {},
100
+ displayNames: {},
105
101
  };
106
102
  }
107
103
 
@@ -114,6 +110,7 @@ export function createFormatters(
114
110
  ): Formatters {
115
111
  const RelativeTimeFormat = (Intl as any).RelativeTimeFormat;
116
112
  const ListFormat = (Intl as any).ListFormat;
113
+ const DisplayNames = (Intl as any).DisplayNames;
117
114
  return {
118
115
  getDateTimeFormat: memoizeIntlConstructor(
119
116
  Intl.DateTimeFormat,
@@ -127,6 +124,7 @@ export function createFormatters(
127
124
  ),
128
125
  getPluralRules: memoizeIntlConstructor(Intl.PluralRules, cache.pluralRules),
129
126
  getListFormat: memoizeIntlConstructor(ListFormat, cache.list),
127
+ getDisplayNames: memoizeIntlConstructor(DisplayNames, cache.displayNames),
130
128
  };
131
129
  }
132
130