react-intl 3.7.0 → 3.9.2
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.
- package/CHANGELOG.md +53 -9
- package/dist/components/plural.d.ts +1 -1
- package/dist/formatters/list.d.ts +1 -2
- package/dist/react-intl.api.md +3 -1
- package/dist/react-intl.d.ts +3 -7
- package/dist/react-intl.js +245 -8
- package/dist/react-intl.js.map +1 -1
- package/dist/react-intl.min.js +1 -1
- package/dist/react-intl.min.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/lib/components/plural.d.ts +1 -1
- package/lib/formatters/list.d.ts +1 -2
- package/lib/react-intl.d.ts +2 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/types.d.ts +1 -0
- package/package.json +28 -27
- package/src/components/createFormattedComponent.tsx +114 -0
- package/src/components/html-message.tsx +68 -0
- package/src/components/injectIntl.tsx +111 -0
- package/src/components/message.tsx +120 -0
- package/src/components/plural.tsx +50 -0
- package/src/components/provider.tsx +183 -0
- package/src/components/relative.tsx +223 -0
- package/src/components/useIntl.ts +10 -0
- package/src/formatters/dateTime.ts +143 -0
- package/src/formatters/list.ts +72 -0
- package/src/formatters/message.ts +241 -0
- package/src/formatters/number.ts +77 -0
- package/src/formatters/plural.ts +31 -0
- package/src/formatters/relativeTime.ts +63 -0
- package/src/index.ts +52 -0
- package/src/tsconfig.cjs.json +8 -0
- package/src/tsconfig.json +8 -0
- package/src/types.ts +160 -0
- package/src/utils.ts +153 -0
- package/src/vendor.d.ts +1 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2015, Yahoo Inc.
|
|
3
|
+
* Copyrights licensed under the New BSD License.
|
|
4
|
+
* See the accompanying LICENSE file for terms.
|
|
5
|
+
*/
|
|
6
|
+
|
|
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_;
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
Formatters,
|
|
17
|
+
IntlConfig,
|
|
18
|
+
MessageDescriptor,
|
|
19
|
+
CustomFormats,
|
|
20
|
+
} from '../types';
|
|
21
|
+
|
|
22
|
+
import {createError, escape} from '../utils';
|
|
23
|
+
import IntlMessageFormat, {
|
|
24
|
+
FormatXMLElementFn,
|
|
25
|
+
PrimitiveType,
|
|
26
|
+
} from 'intl-messageformat';
|
|
27
|
+
|
|
28
|
+
function setTimeZoneInOptions(
|
|
29
|
+
opts: Record<string, Intl.DateTimeFormatOptions>,
|
|
30
|
+
timeZone: string
|
|
31
|
+
): Record<string, Intl.DateTimeFormatOptions> {
|
|
32
|
+
return Object.keys(opts).reduce(
|
|
33
|
+
(all: Record<string, Intl.DateTimeFormatOptions>, k) => {
|
|
34
|
+
all[k] = {
|
|
35
|
+
timeZone,
|
|
36
|
+
...opts[k],
|
|
37
|
+
};
|
|
38
|
+
return all;
|
|
39
|
+
},
|
|
40
|
+
{}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function deepMergeOptions(
|
|
45
|
+
opts1: Record<string, Intl.DateTimeFormatOptions>,
|
|
46
|
+
opts2: Record<string, Intl.DateTimeFormatOptions>
|
|
47
|
+
): Record<string, Intl.DateTimeFormatOptions> {
|
|
48
|
+
const keys = Object.keys({...opts1, ...opts2});
|
|
49
|
+
return keys.reduce((all: Record<string, Intl.DateTimeFormatOptions>, k) => {
|
|
50
|
+
all[k] = {
|
|
51
|
+
...(opts1[k] || {}),
|
|
52
|
+
...(opts2[k] || {}),
|
|
53
|
+
};
|
|
54
|
+
return all;
|
|
55
|
+
}, {});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function deepMergeFormatsAndSetTimeZone(
|
|
59
|
+
f1: CustomFormats,
|
|
60
|
+
timeZone?: string
|
|
61
|
+
): CustomFormats {
|
|
62
|
+
if (!timeZone) {
|
|
63
|
+
return f1;
|
|
64
|
+
}
|
|
65
|
+
const mfFormats = IntlMessageFormat.formats;
|
|
66
|
+
return {
|
|
67
|
+
...mfFormats,
|
|
68
|
+
...f1,
|
|
69
|
+
date: deepMergeOptions(
|
|
70
|
+
setTimeZoneInOptions(mfFormats.date, timeZone),
|
|
71
|
+
setTimeZoneInOptions(f1.date || {}, timeZone)
|
|
72
|
+
),
|
|
73
|
+
time: deepMergeOptions(
|
|
74
|
+
setTimeZoneInOptions(mfFormats.time, timeZone),
|
|
75
|
+
setTimeZoneInOptions(f1.time || {}, timeZone)
|
|
76
|
+
),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function formatMessage(
|
|
81
|
+
{
|
|
82
|
+
locale,
|
|
83
|
+
formats,
|
|
84
|
+
messages,
|
|
85
|
+
defaultLocale,
|
|
86
|
+
defaultFormats,
|
|
87
|
+
onError,
|
|
88
|
+
}: Pick<
|
|
89
|
+
IntlConfig,
|
|
90
|
+
| 'locale'
|
|
91
|
+
| 'formats'
|
|
92
|
+
| 'messages'
|
|
93
|
+
| 'defaultLocale'
|
|
94
|
+
| 'defaultFormats'
|
|
95
|
+
| 'onError'
|
|
96
|
+
>,
|
|
97
|
+
state: Formatters,
|
|
98
|
+
messageDescriptor?: MessageDescriptor,
|
|
99
|
+
values?: Record<string, PrimitiveType>
|
|
100
|
+
): string;
|
|
101
|
+
export function formatMessage(
|
|
102
|
+
{
|
|
103
|
+
locale,
|
|
104
|
+
formats,
|
|
105
|
+
messages,
|
|
106
|
+
defaultLocale,
|
|
107
|
+
defaultFormats,
|
|
108
|
+
onError,
|
|
109
|
+
timeZone,
|
|
110
|
+
}: Pick<
|
|
111
|
+
IntlConfig,
|
|
112
|
+
| 'locale'
|
|
113
|
+
| 'formats'
|
|
114
|
+
| 'messages'
|
|
115
|
+
| 'defaultLocale'
|
|
116
|
+
| 'defaultFormats'
|
|
117
|
+
| 'onError'
|
|
118
|
+
| 'timeZone'
|
|
119
|
+
>,
|
|
120
|
+
state: Formatters,
|
|
121
|
+
messageDescriptor: MessageDescriptor = {id: ''},
|
|
122
|
+
values: Record<
|
|
123
|
+
string,
|
|
124
|
+
PrimitiveType | React.ReactElement | FormatXMLElementFn
|
|
125
|
+
> = {}
|
|
126
|
+
): string | React.ReactNodeArray {
|
|
127
|
+
const {id, defaultMessage} = messageDescriptor;
|
|
128
|
+
|
|
129
|
+
// `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];
|
|
137
|
+
formats = deepMergeFormatsAndSetTimeZone(formats, timeZone);
|
|
138
|
+
defaultFormats = deepMergeFormatsAndSetTimeZone(defaultFormats, timeZone);
|
|
139
|
+
|
|
140
|
+
let formattedMessageParts: Array<string | object> = [];
|
|
141
|
+
|
|
142
|
+
if (message) {
|
|
143
|
+
try {
|
|
144
|
+
const formatter = state.getMessageFormat(message, locale, formats, {
|
|
145
|
+
formatters: state,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
formattedMessageParts = formatter.formatHTMLMessage(values);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
onError(
|
|
151
|
+
createError(
|
|
152
|
+
`Error formatting message: "${id}" for locale: "${locale}"` +
|
|
153
|
+
(defaultMessage ? ', using default message as fallback.' : ''),
|
|
154
|
+
e
|
|
155
|
+
)
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
// This prevents warnings from littering the console in development
|
|
160
|
+
// when no `messages` are passed into the <IntlProvider> for the
|
|
161
|
+
// default locale, and a default message is in the source.
|
|
162
|
+
if (
|
|
163
|
+
!defaultMessage ||
|
|
164
|
+
(locale && locale.toLowerCase() !== defaultLocale.toLowerCase())
|
|
165
|
+
) {
|
|
166
|
+
onError(
|
|
167
|
+
createError(
|
|
168
|
+
`Missing message: "${id}" for locale: "${locale}"` +
|
|
169
|
+
(defaultMessage ? ', using default message as fallback.' : '')
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!formattedMessageParts.length && defaultMessage) {
|
|
176
|
+
try {
|
|
177
|
+
const formatter = state.getMessageFormat(
|
|
178
|
+
defaultMessage,
|
|
179
|
+
defaultLocale,
|
|
180
|
+
defaultFormats
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
formattedMessageParts = formatter.formatHTMLMessage(values);
|
|
184
|
+
} catch (e) {
|
|
185
|
+
onError(
|
|
186
|
+
createError(`Error formatting the default message for: "${id}"`, e)
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!formattedMessageParts.length) {
|
|
192
|
+
onError(
|
|
193
|
+
createError(
|
|
194
|
+
`Cannot format message: "${id}", ` +
|
|
195
|
+
`using message ${
|
|
196
|
+
message || defaultMessage ? 'source' : 'id'
|
|
197
|
+
} as fallback.`
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
if (typeof message === 'string') {
|
|
201
|
+
return message || defaultMessage || id;
|
|
202
|
+
}
|
|
203
|
+
return defaultMessage || id;
|
|
204
|
+
}
|
|
205
|
+
if (
|
|
206
|
+
formattedMessageParts.length === 1 &&
|
|
207
|
+
typeof formattedMessageParts[0] === 'string'
|
|
208
|
+
) {
|
|
209
|
+
return (formattedMessageParts[0] as string) || defaultMessage || id;
|
|
210
|
+
}
|
|
211
|
+
return formattedMessageParts;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function formatHTMLMessage(
|
|
215
|
+
config: Pick<
|
|
216
|
+
IntlConfig,
|
|
217
|
+
| 'locale'
|
|
218
|
+
| 'formats'
|
|
219
|
+
| 'messages'
|
|
220
|
+
| 'defaultLocale'
|
|
221
|
+
| 'defaultFormats'
|
|
222
|
+
| 'onError'
|
|
223
|
+
>,
|
|
224
|
+
state: Formatters,
|
|
225
|
+
messageDescriptor: MessageDescriptor = {id: ''},
|
|
226
|
+
rawValues: Record<string, PrimitiveType> = {}
|
|
227
|
+
): React.ReactNode {
|
|
228
|
+
// Process all the values before they are used when formatting the ICU
|
|
229
|
+
// Message string. Since the formatted message might be injected via
|
|
230
|
+
// `innerHTML`, all String-based values need to be HTML-escaped.
|
|
231
|
+
const escapedValues = Object.keys(rawValues).reduce(
|
|
232
|
+
(escaped: Record<string, any>, name) => {
|
|
233
|
+
const value = rawValues[name];
|
|
234
|
+
escaped[name] = typeof value === 'string' ? escape(value) : value;
|
|
235
|
+
return escaped;
|
|
236
|
+
},
|
|
237
|
+
{}
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
return formatMessage(config, state, messageDescriptor, escapedValues);
|
|
241
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {IntlConfig, Formatters, IntlFormatters} from '../types';
|
|
2
|
+
import {getNamedFormat, filterProps, createError} from '../utils';
|
|
3
|
+
import {UnifiedNumberFormatOptions} from '@formatjs/intl-unified-numberformat';
|
|
4
|
+
|
|
5
|
+
const NUMBER_FORMAT_OPTIONS: Array<keyof UnifiedNumberFormatOptions> = [
|
|
6
|
+
'localeMatcher',
|
|
7
|
+
|
|
8
|
+
'style',
|
|
9
|
+
'currency',
|
|
10
|
+
'currencyDisplay',
|
|
11
|
+
'unit',
|
|
12
|
+
'unitDisplay',
|
|
13
|
+
'useGrouping',
|
|
14
|
+
|
|
15
|
+
'minimumIntegerDigits',
|
|
16
|
+
'minimumFractionDigits',
|
|
17
|
+
'maximumFractionDigits',
|
|
18
|
+
'minimumSignificantDigits',
|
|
19
|
+
'maximumSignificantDigits',
|
|
20
|
+
|
|
21
|
+
// Unified NumberFormat (Stage 3 as of 10/22/19)
|
|
22
|
+
'compactDisplay',
|
|
23
|
+
'currencyDisplay',
|
|
24
|
+
'currencySign',
|
|
25
|
+
'notation',
|
|
26
|
+
'signDisplay',
|
|
27
|
+
'unit',
|
|
28
|
+
'unitDisplay',
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
export function getFormatter(
|
|
32
|
+
{
|
|
33
|
+
locale,
|
|
34
|
+
formats,
|
|
35
|
+
onError,
|
|
36
|
+
}: Pick<IntlConfig, 'locale' | 'formats' | 'onError'>,
|
|
37
|
+
getNumberFormat: Formatters['getNumberFormat'],
|
|
38
|
+
options: Parameters<IntlFormatters['formatNumber']>[1] = {}
|
|
39
|
+
): Intl.NumberFormat {
|
|
40
|
+
const {format} = options;
|
|
41
|
+
const defaults = ((format &&
|
|
42
|
+
getNamedFormat(formats!, 'number', format, onError)) ||
|
|
43
|
+
{}) as UnifiedNumberFormatOptions;
|
|
44
|
+
const filteredOptions = filterProps(options, NUMBER_FORMAT_OPTIONS, defaults);
|
|
45
|
+
|
|
46
|
+
return getNumberFormat(locale, filteredOptions);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function formatNumber(
|
|
50
|
+
config: Pick<IntlConfig, 'locale' | 'formats' | 'onError'>,
|
|
51
|
+
getNumberFormat: Formatters['getNumberFormat'],
|
|
52
|
+
value: Parameters<IntlFormatters['formatNumber']>[0],
|
|
53
|
+
options: Parameters<IntlFormatters['formatNumber']>[1] = {}
|
|
54
|
+
): string {
|
|
55
|
+
try {
|
|
56
|
+
return getFormatter(config, getNumberFormat, options).format(value);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
config.onError(createError('Error formatting number.', e));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return String(value);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function formatNumberToParts(
|
|
65
|
+
config: Pick<IntlConfig, 'locale' | 'formats' | 'onError'>,
|
|
66
|
+
getNumberFormat: Formatters['getNumberFormat'],
|
|
67
|
+
value: Parameters<IntlFormatters['formatNumber']>[0],
|
|
68
|
+
options: Parameters<IntlFormatters['formatNumber']>[1] = {}
|
|
69
|
+
): Intl.NumberFormatPart[] {
|
|
70
|
+
try {
|
|
71
|
+
return getFormatter(config, getNumberFormat, options).formatToParts(value);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
config.onError(createError('Error formatting number.', e));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {IntlConfig, Formatters, IntlFormatters} from '../types';
|
|
2
|
+
import {filterProps, createError} from '../utils';
|
|
3
|
+
|
|
4
|
+
const PLURAL_FORMAT_OPTIONS: Array<keyof Intl.PluralRulesOptions> = [
|
|
5
|
+
'localeMatcher',
|
|
6
|
+
'type',
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
export function formatPlural(
|
|
10
|
+
{locale, onError}: Pick<IntlConfig, 'locale' | 'onError'>,
|
|
11
|
+
getPluralRules: Formatters['getPluralRules'],
|
|
12
|
+
value: Parameters<IntlFormatters['formatPlural']>[0],
|
|
13
|
+
options: Parameters<IntlFormatters['formatPlural']>[1] = {}
|
|
14
|
+
): string {
|
|
15
|
+
if (!Intl.PluralRules) {
|
|
16
|
+
onError(
|
|
17
|
+
createError(`Intl.PluralRules is not available in this environment.
|
|
18
|
+
Try polyfilling it using "@formatjs/intl-pluralrules"
|
|
19
|
+
`)
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
const filteredOptions = filterProps(options, PLURAL_FORMAT_OPTIONS);
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
return getPluralRules(locale, filteredOptions).select(value);
|
|
26
|
+
} catch (e) {
|
|
27
|
+
onError(createError('Error formatting plural.', e));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return 'other';
|
|
31
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {IntlConfig, IntlFormatters, Formatters} from '../types';
|
|
2
|
+
|
|
3
|
+
import {getNamedFormat, filterProps, createError} from '../utils';
|
|
4
|
+
import RelativeTimeFormat, {
|
|
5
|
+
IntlRelativeTimeFormatOptions,
|
|
6
|
+
} from '@formatjs/intl-relativetimeformat';
|
|
7
|
+
|
|
8
|
+
const RELATIVE_TIME_FORMAT_OPTIONS: Array<keyof IntlRelativeTimeFormatOptions> = [
|
|
9
|
+
'numeric',
|
|
10
|
+
'style',
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
function getFormatter(
|
|
14
|
+
{
|
|
15
|
+
locale,
|
|
16
|
+
formats,
|
|
17
|
+
onError,
|
|
18
|
+
}: Pick<IntlConfig, 'locale' | 'formats' | 'onError'>,
|
|
19
|
+
getRelativeTimeFormat: Formatters['getRelativeTimeFormat'],
|
|
20
|
+
options: Parameters<IntlFormatters['formatRelativeTime']>[2] = {}
|
|
21
|
+
): RelativeTimeFormat {
|
|
22
|
+
const {format} = options;
|
|
23
|
+
|
|
24
|
+
const defaults =
|
|
25
|
+
(!!format && getNamedFormat(formats, 'relative', format, onError)) || {};
|
|
26
|
+
const filteredOptions = filterProps(
|
|
27
|
+
options,
|
|
28
|
+
RELATIVE_TIME_FORMAT_OPTIONS,
|
|
29
|
+
defaults as IntlRelativeTimeFormatOptions
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return getRelativeTimeFormat(locale, filteredOptions);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function formatRelativeTime(
|
|
36
|
+
config: Pick<IntlConfig, 'locale' | 'formats' | 'onError'>,
|
|
37
|
+
getRelativeTimeFormat: Formatters['getRelativeTimeFormat'],
|
|
38
|
+
value: Parameters<IntlFormatters['formatRelativeTime']>[0],
|
|
39
|
+
unit?: Parameters<IntlFormatters['formatRelativeTime']>[1],
|
|
40
|
+
options: Parameters<IntlFormatters['formatRelativeTime']>[2] = {}
|
|
41
|
+
): string {
|
|
42
|
+
if (!unit) {
|
|
43
|
+
unit = 'second';
|
|
44
|
+
}
|
|
45
|
+
const RelativeTimeFormat = (Intl as any).RelativeTimeFormat;
|
|
46
|
+
if (!RelativeTimeFormat) {
|
|
47
|
+
config.onError(
|
|
48
|
+
createError(`Intl.RelativeTimeFormat is not available in this environment.
|
|
49
|
+
Try polyfilling it using "@formatjs/intl-relativetimeformat"
|
|
50
|
+
`)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
return getFormatter(config, getRelativeTimeFormat, options).format(
|
|
55
|
+
value,
|
|
56
|
+
unit
|
|
57
|
+
);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
config.onError(createError('Error formatting relative time.', e));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return String(value);
|
|
63
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2015, Yahoo Inc.
|
|
3
|
+
* Copyrights licensed under the New BSD License.
|
|
4
|
+
* See the accompanying LICENSE file for terms.
|
|
5
|
+
*/
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
export * from './types';
|
|
8
|
+
export {defineMessages} from '@formatjs/macro';
|
|
9
|
+
import {
|
|
10
|
+
createFormattedComponent,
|
|
11
|
+
createFormattedDateTimePartsComponent,
|
|
12
|
+
} from './components/createFormattedComponent';
|
|
13
|
+
import {CustomFormatConfig} from './types';
|
|
14
|
+
import {UnifiedNumberFormatOptions} from '@formatjs/intl-unified-numberformat';
|
|
15
|
+
import {IntlListFormatOptions} from '@formatjs/intl-listformat';
|
|
16
|
+
export {
|
|
17
|
+
default as injectIntl,
|
|
18
|
+
Provider as RawIntlProvider,
|
|
19
|
+
Context as IntlContext,
|
|
20
|
+
WithIntlProps,
|
|
21
|
+
WrappedComponentProps,
|
|
22
|
+
} from './components/injectIntl';
|
|
23
|
+
export {default as useIntl} from './components/useIntl';
|
|
24
|
+
export {default as IntlProvider, createIntl} from './components/provider';
|
|
25
|
+
// IMPORTANT: Explicit here to prevent api-extractor from outputing `import('./types').CustomFormatConfig`
|
|
26
|
+
export const FormattedDate: React.FC<Intl.DateTimeFormatOptions &
|
|
27
|
+
CustomFormatConfig & {
|
|
28
|
+
value: string | number | Date | undefined;
|
|
29
|
+
}> = createFormattedComponent('formatDate');
|
|
30
|
+
export const FormattedTime: React.FC<Intl.DateTimeFormatOptions &
|
|
31
|
+
CustomFormatConfig & {
|
|
32
|
+
value: string | number | Date | undefined;
|
|
33
|
+
}> = createFormattedComponent('formatTime');
|
|
34
|
+
export const FormattedNumber: React.FC<UnifiedNumberFormatOptions &
|
|
35
|
+
CustomFormatConfig & {
|
|
36
|
+
value: number;
|
|
37
|
+
}> = createFormattedComponent('formatNumber');
|
|
38
|
+
export const FormattedList: React.FC<IntlListFormatOptions & {
|
|
39
|
+
value: React.ReactNode[];
|
|
40
|
+
}> = createFormattedComponent('formatList');
|
|
41
|
+
export const FormattedDateParts = createFormattedDateTimePartsComponent(
|
|
42
|
+
'formatDate'
|
|
43
|
+
);
|
|
44
|
+
export const FormattedTimeParts = createFormattedDateTimePartsComponent(
|
|
45
|
+
'formatTime'
|
|
46
|
+
);
|
|
47
|
+
export {FormattedNumberParts} from './components/createFormattedComponent';
|
|
48
|
+
export {default as FormattedRelativeTime} from './components/relative';
|
|
49
|
+
export {default as FormattedPlural} from './components/plural';
|
|
50
|
+
export {default as FormattedMessage} from './components/message';
|
|
51
|
+
export {default as FormattedHTMLMessage} from './components/html-message';
|
|
52
|
+
export {createIntlCache} from './utils';
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2015, Yahoo Inc.
|
|
3
|
+
* Copyrights licensed under the New BSD License.
|
|
4
|
+
* See the accompanying LICENSE file for terms.
|
|
5
|
+
*/
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import IntlMessageFormat, {
|
|
8
|
+
Formats,
|
|
9
|
+
PrimitiveType,
|
|
10
|
+
FormatXMLElementFn,
|
|
11
|
+
} from 'intl-messageformat';
|
|
12
|
+
import IntlRelativeTimeFormat, {
|
|
13
|
+
IntlRelativeTimeFormatOptions,
|
|
14
|
+
} from '@formatjs/intl-relativetimeformat';
|
|
15
|
+
import {MessageFormatElement} from 'intl-messageformat-parser';
|
|
16
|
+
import {UnifiedNumberFormatOptions} from '@formatjs/intl-unified-numberformat';
|
|
17
|
+
import IntlListFormat, {IntlListFormatOptions} from '@formatjs/intl-listformat';
|
|
18
|
+
|
|
19
|
+
export interface IntlConfig {
|
|
20
|
+
locale: string;
|
|
21
|
+
timeZone?: string;
|
|
22
|
+
formats: CustomFormats;
|
|
23
|
+
textComponent?: React.ComponentType | keyof React.ReactHTML;
|
|
24
|
+
messages: Record<string, string> | Record<string, MessageFormatElement[]>;
|
|
25
|
+
defaultLocale: string;
|
|
26
|
+
defaultFormats: CustomFormats;
|
|
27
|
+
onError(err: string): void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CustomFormats extends Partial<Formats> {
|
|
31
|
+
relative?: Record<string, IntlRelativeTimeFormatOptions>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface CustomFormatConfig {
|
|
35
|
+
format?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type FormatDateOptions = Exclude<
|
|
39
|
+
Intl.DateTimeFormatOptions,
|
|
40
|
+
'localeMatcher'
|
|
41
|
+
> &
|
|
42
|
+
CustomFormatConfig;
|
|
43
|
+
export type FormatNumberOptions = Exclude<
|
|
44
|
+
UnifiedNumberFormatOptions,
|
|
45
|
+
'localeMatcher'
|
|
46
|
+
> &
|
|
47
|
+
CustomFormatConfig;
|
|
48
|
+
export type FormatRelativeTimeOptions = Exclude<
|
|
49
|
+
IntlRelativeTimeFormatOptions,
|
|
50
|
+
'localeMatcher'
|
|
51
|
+
> &
|
|
52
|
+
CustomFormatConfig;
|
|
53
|
+
export type FormatPluralOptions = Exclude<
|
|
54
|
+
Intl.PluralRulesOptions,
|
|
55
|
+
'localeMatcher'
|
|
56
|
+
> &
|
|
57
|
+
CustomFormatConfig;
|
|
58
|
+
|
|
59
|
+
export type FormatListOptions = Exclude<IntlListFormatOptions, 'localeMatcher'>;
|
|
60
|
+
|
|
61
|
+
export interface IntlFormatters {
|
|
62
|
+
formatDate(
|
|
63
|
+
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
|
|
64
|
+
opts?: FormatDateOptions
|
|
65
|
+
): string;
|
|
66
|
+
formatTime(
|
|
67
|
+
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
|
|
68
|
+
opts?: FormatDateOptions
|
|
69
|
+
): string;
|
|
70
|
+
formatDateToParts(
|
|
71
|
+
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
|
|
72
|
+
opts?: FormatDateOptions
|
|
73
|
+
): Intl.DateTimeFormatPart[];
|
|
74
|
+
formatTimeToParts(
|
|
75
|
+
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
|
|
76
|
+
opts?: FormatDateOptions
|
|
77
|
+
): Intl.DateTimeFormatPart[];
|
|
78
|
+
formatRelativeTime(
|
|
79
|
+
value: Parameters<IntlRelativeTimeFormat['format']>[0],
|
|
80
|
+
unit?: Parameters<IntlRelativeTimeFormat['format']>[1],
|
|
81
|
+
opts?: FormatRelativeTimeOptions
|
|
82
|
+
): string;
|
|
83
|
+
formatNumber(
|
|
84
|
+
value: Parameters<Intl.NumberFormat['format']>[0],
|
|
85
|
+
opts?: FormatNumberOptions
|
|
86
|
+
): string;
|
|
87
|
+
formatNumberToParts(
|
|
88
|
+
value: Parameters<Intl.NumberFormat['format']>[0],
|
|
89
|
+
opts?: FormatNumberOptions
|
|
90
|
+
): Intl.NumberFormatPart[];
|
|
91
|
+
formatPlural(
|
|
92
|
+
value: Parameters<Intl.PluralRules['select']>[0],
|
|
93
|
+
opts?: FormatPluralOptions
|
|
94
|
+
): ReturnType<Intl.PluralRules['select']>;
|
|
95
|
+
formatMessage(
|
|
96
|
+
descriptor: MessageDescriptor,
|
|
97
|
+
values?: Record<string, PrimitiveType>
|
|
98
|
+
): string;
|
|
99
|
+
formatMessage(
|
|
100
|
+
descriptor: MessageDescriptor,
|
|
101
|
+
values?: Record<
|
|
102
|
+
string,
|
|
103
|
+
PrimitiveType | React.ReactElement | FormatXMLElementFn
|
|
104
|
+
>
|
|
105
|
+
): string | React.ReactNodeArray;
|
|
106
|
+
formatHTMLMessage(
|
|
107
|
+
descriptor: MessageDescriptor,
|
|
108
|
+
values?: Record<string, PrimitiveType>
|
|
109
|
+
): React.ReactNode;
|
|
110
|
+
formatList(
|
|
111
|
+
values: Array<string>,
|
|
112
|
+
opts?: FormatListOptions
|
|
113
|
+
): string;
|
|
114
|
+
formatList(
|
|
115
|
+
values: Array<string | React.ReactNode>,
|
|
116
|
+
opts?: FormatListOptions
|
|
117
|
+
): React.ReactNode;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface Formatters {
|
|
121
|
+
getDateTimeFormat(
|
|
122
|
+
...args: ConstructorParameters<typeof Intl.DateTimeFormat>
|
|
123
|
+
): Intl.DateTimeFormat;
|
|
124
|
+
getNumberFormat(
|
|
125
|
+
...args: ConstructorParameters<typeof Intl.NumberFormat>
|
|
126
|
+
): Intl.NumberFormat;
|
|
127
|
+
getMessageFormat(
|
|
128
|
+
...args: ConstructorParameters<typeof IntlMessageFormat>
|
|
129
|
+
): IntlMessageFormat;
|
|
130
|
+
getRelativeTimeFormat(
|
|
131
|
+
...args: ConstructorParameters<typeof IntlRelativeTimeFormat>
|
|
132
|
+
): IntlRelativeTimeFormat;
|
|
133
|
+
getPluralRules(
|
|
134
|
+
...args: ConstructorParameters<typeof Intl.PluralRules>
|
|
135
|
+
): Intl.PluralRules;
|
|
136
|
+
getListFormat(
|
|
137
|
+
...args: ConstructorParameters<typeof IntlListFormat>
|
|
138
|
+
): IntlListFormat;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface IntlShape extends IntlConfig, IntlFormatters {
|
|
142
|
+
formatters: Formatters;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface IntlCache {
|
|
146
|
+
dateTime: Record<string, Intl.DateTimeFormat>;
|
|
147
|
+
number: Record<string, Intl.NumberFormat>;
|
|
148
|
+
message: Record<string, IntlMessageFormat>;
|
|
149
|
+
relativeTime: Record<string, IntlRelativeTimeFormat>;
|
|
150
|
+
pluralRules: Record<string, Intl.PluralRules>;
|
|
151
|
+
list: Record<string, IntlListFormat>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface MessageDescriptor {
|
|
155
|
+
id?: string;
|
|
156
|
+
description?: string | object;
|
|
157
|
+
defaultMessage?: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
|