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
package/src/utils.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*
|
|
2
|
+
HTML escaping is the same as React's
|
|
3
|
+
(on purpose.) Therefore, it has the following Copyright and Licensing:
|
|
4
|
+
|
|
5
|
+
Copyright 2013-2014, Facebook, Inc.
|
|
6
|
+
All rights reserved.
|
|
7
|
+
|
|
8
|
+
This source code is licensed under the BSD-style license found in the LICENSE
|
|
9
|
+
file in the root directory of React's source tree.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {IntlConfig, IntlCache, CustomFormats, Formatters} from './types';
|
|
13
|
+
import * as React from 'react';
|
|
14
|
+
import IntlMessageFormat from 'intl-messageformat';
|
|
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';
|
|
21
|
+
import {IntlRelativeTimeFormatOptions} from '@formatjs/intl-relativetimeformat';
|
|
22
|
+
const invariant: typeof invariant_ = (invariant_ as any).default || invariant_;
|
|
23
|
+
|
|
24
|
+
const ESCAPED_CHARS: Record<number, string> = {
|
|
25
|
+
38: '&',
|
|
26
|
+
62: '>',
|
|
27
|
+
60: '<',
|
|
28
|
+
34: '"',
|
|
29
|
+
39: ''',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const UNSAFE_CHARS_REGEX = /[&><"']/g;
|
|
33
|
+
|
|
34
|
+
export function escape(str: string): string {
|
|
35
|
+
return ('' + str).replace(
|
|
36
|
+
UNSAFE_CHARS_REGEX,
|
|
37
|
+
match => ESCAPED_CHARS[match.charCodeAt(0)]
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function filterProps<T extends Record<string, any>, K extends string>(
|
|
42
|
+
props: T,
|
|
43
|
+
whitelist: Array<K>,
|
|
44
|
+
defaults: Partial<T> = {}
|
|
45
|
+
): Pick<T, K> {
|
|
46
|
+
return whitelist.reduce((filtered, name) => {
|
|
47
|
+
if (name in props) {
|
|
48
|
+
filtered[name] = props[name];
|
|
49
|
+
} else if (name in defaults) {
|
|
50
|
+
filtered[name] = defaults[name]!;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return filtered;
|
|
54
|
+
}, {} as Pick<T, K>);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function invariantIntlContext(intl?: any): void {
|
|
58
|
+
invariant(
|
|
59
|
+
intl,
|
|
60
|
+
'[React Intl] Could not find required `intl` object. ' +
|
|
61
|
+
'<IntlProvider> needs to exist in the component ancestry.'
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function createError(message: string, exception?: Error): string {
|
|
66
|
+
const eMsg = exception ? `\n${exception.stack}` : '';
|
|
67
|
+
return `[React Intl] ${message}${eMsg}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function defaultErrorHandler(error: string): void {
|
|
71
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
72
|
+
console.error(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const DEFAULT_INTL_CONFIG: Pick<
|
|
77
|
+
IntlConfig,
|
|
78
|
+
| 'formats'
|
|
79
|
+
| 'messages'
|
|
80
|
+
| 'timeZone'
|
|
81
|
+
| 'textComponent'
|
|
82
|
+
| 'defaultLocale'
|
|
83
|
+
| 'defaultFormats'
|
|
84
|
+
| 'onError'
|
|
85
|
+
> = {
|
|
86
|
+
formats: {},
|
|
87
|
+
messages: {},
|
|
88
|
+
timeZone: undefined,
|
|
89
|
+
textComponent: React.Fragment,
|
|
90
|
+
|
|
91
|
+
defaultLocale: 'en',
|
|
92
|
+
defaultFormats: {},
|
|
93
|
+
|
|
94
|
+
onError: defaultErrorHandler,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export function createIntlCache(): IntlCache {
|
|
98
|
+
return {
|
|
99
|
+
dateTime: {},
|
|
100
|
+
number: {},
|
|
101
|
+
message: {},
|
|
102
|
+
relativeTime: {},
|
|
103
|
+
pluralRules: {},
|
|
104
|
+
list: {},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Create intl formatters and populate cache
|
|
110
|
+
* @param cache explicit cache to prevent leaking memory
|
|
111
|
+
*/
|
|
112
|
+
export function createFormatters(
|
|
113
|
+
cache: IntlCache = createIntlCache()
|
|
114
|
+
): Formatters {
|
|
115
|
+
const RelativeTimeFormat = (Intl as any).RelativeTimeFormat;
|
|
116
|
+
const ListFormat = (Intl as any).ListFormat;
|
|
117
|
+
return {
|
|
118
|
+
getDateTimeFormat: memoizeIntlConstructor(
|
|
119
|
+
Intl.DateTimeFormat,
|
|
120
|
+
cache.dateTime
|
|
121
|
+
),
|
|
122
|
+
getNumberFormat: memoizeIntlConstructor(Intl.NumberFormat, cache.number),
|
|
123
|
+
getMessageFormat: memoizeIntlConstructor(IntlMessageFormat, cache.message),
|
|
124
|
+
getRelativeTimeFormat: memoizeIntlConstructor(
|
|
125
|
+
RelativeTimeFormat,
|
|
126
|
+
cache.relativeTime
|
|
127
|
+
),
|
|
128
|
+
getPluralRules: memoizeIntlConstructor(Intl.PluralRules, cache.pluralRules),
|
|
129
|
+
getListFormat: memoizeIntlConstructor(ListFormat, cache.list),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function getNamedFormat<T extends keyof CustomFormats>(
|
|
134
|
+
formats: CustomFormats,
|
|
135
|
+
type: T,
|
|
136
|
+
name: string,
|
|
137
|
+
onError: (err: string) => void
|
|
138
|
+
):
|
|
139
|
+
| Intl.NumberFormatOptions
|
|
140
|
+
| Intl.DateTimeFormatOptions
|
|
141
|
+
| IntlRelativeTimeFormatOptions
|
|
142
|
+
| undefined {
|
|
143
|
+
const formatType = formats && formats[type];
|
|
144
|
+
let format;
|
|
145
|
+
if (formatType) {
|
|
146
|
+
format = formatType[name];
|
|
147
|
+
}
|
|
148
|
+
if (format) {
|
|
149
|
+
return format;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
onError(createError(`No ${type} format named: ${name}`));
|
|
153
|
+
}
|
package/src/vendor.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'shallow-equal/objects';
|