react-intl 2.2.0 → 2.3.0

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.
@@ -1,163 +0,0 @@
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 React, {Component, PropTypes} from 'react';
8
- import {intlShape, relativeFormatPropTypes} from '../types';
9
- import {invariantIntlContext, shouldIntlComponentUpdate} from '../utils';
10
-
11
- const SECOND = 1000;
12
- const MINUTE = 1000 * 60;
13
- const HOUR = 1000 * 60 * 60;
14
- const DAY = 1000 * 60 * 60 * 24;
15
-
16
- // The maximum timer delay value is a 32-bit signed integer.
17
- // See: https://mdn.io/setTimeout
18
- const MAX_TIMER_DELAY = 2147483647;
19
-
20
- function selectUnits(delta) {
21
- let absDelta = Math.abs(delta);
22
-
23
- if (absDelta < MINUTE) {
24
- return 'second';
25
- }
26
-
27
- if (absDelta < HOUR) {
28
- return 'minute';
29
- }
30
-
31
- if (absDelta < DAY) {
32
- return 'hour';
33
- }
34
-
35
- // The maximum scheduled delay will be measured in days since the maximum
36
- // timer delay is less than the number of milliseconds in 25 days.
37
- return 'day';
38
- }
39
-
40
- function getUnitDelay(units) {
41
- switch (units) {
42
- case 'second': return SECOND;
43
- case 'minute': return MINUTE;
44
- case 'hour' : return HOUR;
45
- case 'day' : return DAY;
46
- default : return MAX_TIMER_DELAY;
47
- }
48
- }
49
-
50
- function isSameDate(a, b) {
51
- if (a === b) {
52
- return true;
53
- }
54
-
55
- let aTime = new Date(a).getTime();
56
- let bTime = new Date(b).getTime();
57
-
58
- return isFinite(aTime) && isFinite(bTime) && aTime === bTime;
59
- }
60
-
61
- export default class FormattedRelative extends Component {
62
- static displayName = 'FormattedRelative';
63
-
64
- static contextTypes = {
65
- intl: intlShape,
66
- };
67
-
68
- static propTypes = {
69
- ...relativeFormatPropTypes,
70
- value : PropTypes.any.isRequired,
71
- format : PropTypes.string,
72
- updateInterval: PropTypes.number,
73
- initialNow : PropTypes.any,
74
- children : PropTypes.func,
75
- };
76
-
77
- static defaultProps = {
78
- updateInterval: 1000 * 10,
79
- };
80
-
81
- constructor(props, context) {
82
- super(props, context);
83
- invariantIntlContext(context);
84
-
85
- let now = isFinite(props.initialNow) ?
86
- Number(props.initialNow) : context.intl.now();
87
-
88
- // `now` is stored as state so that `render()` remains a function of
89
- // props + state, instead of accessing `Date.now()` inside `render()`.
90
- this.state = {now};
91
- }
92
-
93
- scheduleNextUpdate(props, state) {
94
- const {updateInterval} = props;
95
-
96
- // If the `updateInterval` is falsy, including `0`, then auto updates
97
- // have been turned off, so we bail and skip scheduling an update.
98
- if (!updateInterval) {
99
- return;
100
- }
101
-
102
- let time = new Date(props.value).getTime();
103
- let delta = time - state.now;
104
- let units = props.units || selectUnits(delta);
105
-
106
- let unitDelay = getUnitDelay(units);
107
- let unitRemainder = Math.abs(delta % unitDelay);
108
-
109
- // We want the largest possible timer delay which will still display
110
- // accurate information while reducing unnecessary re-renders. The delay
111
- // should be until the next "interesting" moment, like a tick from
112
- // "1 minute ago" to "2 minutes ago" when the delta is 120,000ms.
113
- let delay = delta < 0 ?
114
- Math.max(updateInterval, unitDelay - unitRemainder) :
115
- Math.max(updateInterval, unitRemainder);
116
-
117
- clearTimeout(this._timer);
118
-
119
- this._timer = setTimeout(() => {
120
- this.setState({now: this.context.intl.now()});
121
- }, delay);
122
- }
123
-
124
- componentDidMount() {
125
- this.scheduleNextUpdate(this.props, this.state);
126
- }
127
-
128
- componentWillReceiveProps({value: nextValue}) {
129
- // When the `props.value` date changes, `state.now` needs to be updated,
130
- // and the next update can be rescheduled.
131
- if (!isSameDate(nextValue, this.props.value)) {
132
- this.setState({now: this.context.intl.now()});
133
- }
134
- }
135
-
136
- shouldComponentUpdate(...next) {
137
- return shouldIntlComponentUpdate(this, ...next);
138
- }
139
-
140
- componentWillUpdate(nextProps, nextState) {
141
- this.scheduleNextUpdate(nextProps, nextState);
142
- }
143
-
144
- componentWillUnmount() {
145
- clearTimeout(this._timer);
146
- }
147
-
148
- render() {
149
- const {formatRelative, textComponent: Text} = this.context.intl;
150
- const {value, children} = this.props;
151
-
152
- let formattedRelative = formatRelative(value, {
153
- ...this.props,
154
- ...this.state,
155
- });
156
-
157
- if (typeof children === 'function') {
158
- return children(formattedRelative);
159
- }
160
-
161
- return <Text>{formattedRelative}</Text>;
162
- }
163
- }
@@ -1,46 +0,0 @@
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 React, {Component, PropTypes} from 'react';
8
- import {intlShape, dateTimeFormatPropTypes} from '../types';
9
- import {invariantIntlContext, shouldIntlComponentUpdate} from '../utils';
10
-
11
- export default class FormattedTime extends Component {
12
- static displayName = 'FormattedTime';
13
-
14
- static contextTypes = {
15
- intl: intlShape,
16
- };
17
-
18
- static propTypes = {
19
- ...dateTimeFormatPropTypes,
20
- value : PropTypes.any.isRequired,
21
- format : PropTypes.string,
22
- children: PropTypes.func,
23
- };
24
-
25
- constructor(props, context) {
26
- super(props, context);
27
- invariantIntlContext(context);
28
- }
29
-
30
- shouldComponentUpdate(...next) {
31
- return shouldIntlComponentUpdate(this, ...next);
32
- }
33
-
34
- render() {
35
- const {formatTime, textComponent: Text} = this.context.intl;
36
- const {value, children} = this.props;
37
-
38
- let formattedTime = formatTime(value, this.props);
39
-
40
- if (typeof children === 'function') {
41
- return children(formattedTime);
42
- }
43
-
44
- return <Text>{formattedTime}</Text>;
45
- }
46
- }
@@ -1,11 +0,0 @@
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
- export default function defineMessages(messageDescriptors) {
8
- // This simply returns what's passed-in because it's meant to be a hook for
9
- // babel-plugin-react-intl.
10
- return messageDescriptors;
11
- }
package/src/en.js DELETED
@@ -1,2 +0,0 @@
1
- // GENERATED FILE
2
- export default {"locale":"en","pluralRuleFunction":function (n,ord){var s=String(n).split("."),v0=!s[1],t0=Number(s[0])==n,n10=t0&&s[0].slice(-1),n100=t0&&s[0].slice(-2);if(ord)return n10==1&&n100!=11?"one":n10==2&&n100!=12?"two":n10==3&&n100!=13?"few":"other";return n==1&&v0?"one":"other"},"fields":{"year":{"displayName":"year","relative":{"0":"this year","1":"next year","-1":"last year"},"relativeTime":{"future":{"one":"in {0} year","other":"in {0} years"},"past":{"one":"{0} year ago","other":"{0} years ago"}}},"month":{"displayName":"month","relative":{"0":"this month","1":"next month","-1":"last month"},"relativeTime":{"future":{"one":"in {0} month","other":"in {0} months"},"past":{"one":"{0} month ago","other":"{0} months ago"}}},"day":{"displayName":"day","relative":{"0":"today","1":"tomorrow","-1":"yesterday"},"relativeTime":{"future":{"one":"in {0} day","other":"in {0} days"},"past":{"one":"{0} day ago","other":"{0} days ago"}}},"hour":{"displayName":"hour","relativeTime":{"future":{"one":"in {0} hour","other":"in {0} hours"},"past":{"one":"{0} hour ago","other":"{0} hours ago"}}},"minute":{"displayName":"minute","relativeTime":{"future":{"one":"in {0} minute","other":"in {0} minutes"},"past":{"one":"{0} minute ago","other":"{0} minutes ago"}}},"second":{"displayName":"second","relative":{"0":"now"},"relativeTime":{"future":{"one":"in {0} second","other":"in {0} seconds"},"past":{"one":"{0} second ago","other":"{0} seconds ago"}}}}};
package/src/format.js DELETED
@@ -1,275 +0,0 @@
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 invariant from 'invariant';
8
- import IntlRelativeFormat from 'intl-relativeformat';
9
-
10
- import {
11
- dateTimeFormatPropTypes,
12
- numberFormatPropTypes,
13
- relativeFormatPropTypes,
14
- pluralFormatPropTypes,
15
- } from './types';
16
-
17
- import {
18
- escape,
19
- filterProps,
20
- } from './utils';
21
-
22
- const DATE_TIME_FORMAT_OPTIONS = Object.keys(dateTimeFormatPropTypes);
23
- const NUMBER_FORMAT_OPTIONS = Object.keys(numberFormatPropTypes);
24
- const RELATIVE_FORMAT_OPTIONS = Object.keys(relativeFormatPropTypes);
25
- const PLURAL_FORMAT_OPTIONS = Object.keys(pluralFormatPropTypes);
26
-
27
- const RELATIVE_FORMAT_THRESHOLDS = {
28
- second: 60, // seconds to minute
29
- minute: 60, // minutes to hour
30
- hour : 24, // hours to day
31
- day : 30, // days to month
32
- month : 12, // months to year
33
- };
34
-
35
- function updateRelativeFormatThresholds(newThresholds) {
36
- const {thresholds} = IntlRelativeFormat;
37
- ({
38
- second: thresholds.second,
39
- minute: thresholds.minute,
40
- hour : thresholds.hour,
41
- day : thresholds.day,
42
- month : thresholds.month,
43
- } = newThresholds);
44
- }
45
-
46
- function getNamedFormat(formats, type, name) {
47
- let format = formats && formats[type] && formats[type][name];
48
- if (format) {
49
- return format;
50
- }
51
-
52
- if (process.env.NODE_ENV !== 'production') {
53
- console.error(
54
- `[React Intl] No ${type} format named: ${name}`
55
- );
56
- }
57
- }
58
-
59
- export function formatDate(config, state, value, options = {}) {
60
- const {locale, formats} = config;
61
- const {format} = options;
62
-
63
- let date = new Date(value);
64
- let defaults = format && getNamedFormat(formats, 'date', format);
65
- let filteredOptions = filterProps(options, DATE_TIME_FORMAT_OPTIONS, defaults);
66
-
67
- try {
68
- return state.getDateTimeFormat(locale, filteredOptions).format(date);
69
- } catch (e) {
70
- if (process.env.NODE_ENV !== 'production') {
71
- console.error(
72
- `[React Intl] Error formatting date.\n${e}`
73
- );
74
- }
75
- }
76
-
77
- return String(date);
78
- }
79
-
80
- export function formatTime(config, state, value, options = {}) {
81
- const {locale, formats} = config;
82
- const {format} = options;
83
-
84
- let date = new Date(value);
85
- let defaults = format && getNamedFormat(formats, 'time', format);
86
- let filteredOptions = filterProps(options, DATE_TIME_FORMAT_OPTIONS, defaults);
87
-
88
- if (!filteredOptions.hour && !filteredOptions.minute && !filteredOptions.second) {
89
- // Add default formatting options if hour, minute, or second isn't defined.
90
- filteredOptions = { ...filteredOptions, hour: 'numeric', minute: 'numeric'};
91
- }
92
-
93
- try {
94
- return state.getDateTimeFormat(locale, filteredOptions).format(date);
95
- } catch (e) {
96
- if (process.env.NODE_ENV !== 'production') {
97
- console.error(
98
- `[React Intl] Error formatting time.\n${e}`
99
- );
100
- }
101
- }
102
-
103
- return String(date);
104
- }
105
-
106
- export function formatRelative(config, state, value, options = {}) {
107
- const {locale, formats} = config;
108
- const {format} = options;
109
-
110
- let date = new Date(value);
111
- let now = new Date(options.now);
112
- let defaults = format && getNamedFormat(formats, 'relative', format);
113
- let filteredOptions = filterProps(options, RELATIVE_FORMAT_OPTIONS, defaults);
114
-
115
- // Capture the current threshold values, then temporarily override them with
116
- // specific values just for this render.
117
- const oldThresholds = {...IntlRelativeFormat.thresholds};
118
- updateRelativeFormatThresholds(RELATIVE_FORMAT_THRESHOLDS);
119
-
120
- try {
121
- return state.getRelativeFormat(locale, filteredOptions).format(date, {
122
- now: isFinite(now) ? now : state.now(),
123
- });
124
- } catch (e) {
125
- if (process.env.NODE_ENV !== 'production') {
126
- console.error(
127
- `[React Intl] Error formatting relative time.\n${e}`
128
- );
129
- }
130
- } finally {
131
- updateRelativeFormatThresholds(oldThresholds);
132
- }
133
-
134
- return String(date);
135
- }
136
-
137
- export function formatNumber(config, state, value, options = {}) {
138
- const {locale, formats} = config;
139
- const {format} = options;
140
-
141
- let defaults = format && getNamedFormat(formats, 'number', format);
142
- let filteredOptions = filterProps(options, NUMBER_FORMAT_OPTIONS, defaults);
143
-
144
- try {
145
- return state.getNumberFormat(locale, filteredOptions).format(value);
146
- } catch (e) {
147
- if (process.env.NODE_ENV !== 'production') {
148
- console.error(
149
- `[React Intl] Error formatting number.\n${e}`
150
- );
151
- }
152
- }
153
-
154
- return String(value);
155
- }
156
-
157
- export function formatPlural(config, state, value, options = {}) {
158
- const {locale} = config;
159
-
160
- let filteredOptions = filterProps(options, PLURAL_FORMAT_OPTIONS);
161
-
162
- try {
163
- return state.getPluralFormat(locale, filteredOptions).format(value);
164
- } catch (e) {
165
- if (process.env.NODE_ENV !== 'production') {
166
- console.error(
167
- `[React Intl] Error formatting plural.\n${e}`
168
- );
169
- }
170
- }
171
-
172
- return 'other';
173
- }
174
-
175
- export function formatMessage(config, state, messageDescriptor = {}, values = {}) {
176
- const {
177
- locale,
178
- formats,
179
- messages,
180
- defaultLocale,
181
- defaultFormats,
182
- } = config;
183
-
184
- const {
185
- id,
186
- defaultMessage,
187
- } = messageDescriptor;
188
-
189
- // `id` is a required field of a Message Descriptor.
190
- invariant(id, '[React Intl] An `id` must be provided to format a message.');
191
-
192
- const message = messages && messages[id];
193
- const hasValues = Object.keys(values).length > 0;
194
-
195
- // Avoid expensive message formatting for simple messages without values. In
196
- // development messages will always be formatted in case of missing values.
197
- if (!hasValues && process.env.NODE_ENV === 'production') {
198
- return message || defaultMessage || id;
199
- }
200
-
201
- let formattedMessage;
202
-
203
- if (message) {
204
- try {
205
- let formatter = state.getMessageFormat(
206
- message, locale, formats
207
- );
208
-
209
- formattedMessage = formatter.format(values);
210
- } catch (e) {
211
- if (process.env.NODE_ENV !== 'production') {
212
- console.error(
213
- `[React Intl] Error formatting message: "${id}" for locale: "${locale}"` +
214
- (defaultMessage ? ', using default message as fallback.' : '') +
215
- `\n${e}`
216
- );
217
- }
218
- }
219
- } else {
220
- if (process.env.NODE_ENV !== 'production') {
221
- // This prevents warnings from littering the console in development
222
- // when no `messages` are passed into the <IntlProvider> for the
223
- // default locale, and a default message is in the source.
224
- if (!defaultMessage ||
225
- (locale && locale.toLowerCase() !== defaultLocale.toLowerCase())) {
226
-
227
- console.error(
228
- `[React Intl] Missing message: "${id}" for locale: "${locale}"` +
229
- (defaultMessage ? ', using default message as fallback.' : '')
230
- );
231
- }
232
- }
233
- }
234
-
235
- if (!formattedMessage && defaultMessage) {
236
- try {
237
- let formatter = state.getMessageFormat(
238
- defaultMessage, defaultLocale, defaultFormats
239
- );
240
-
241
- formattedMessage = formatter.format(values);
242
- } catch (e) {
243
- if (process.env.NODE_ENV !== 'production') {
244
- console.error(
245
- `[React Intl] Error formatting the default message for: "${id}"` +
246
- `\n${e}`
247
- );
248
- }
249
- }
250
- }
251
-
252
- if (!formattedMessage) {
253
- if (process.env.NODE_ENV !== 'production') {
254
- console.error(
255
- `[React Intl] Cannot format message: "${id}", ` +
256
- `using message ${message || defaultMessage ? 'source' : 'id'} as fallback.`
257
- );
258
- }
259
- }
260
-
261
- return formattedMessage || message || defaultMessage || id;
262
- }
263
-
264
- export function formatHTMLMessage(config, state, messageDescriptor, rawValues = {}) {
265
- // Process all the values before they are used when formatting the ICU
266
- // Message string. Since the formatted message might be injected via
267
- // `innerHTML`, all String-based values need to be HTML-escaped.
268
- let escapedValues = Object.keys(rawValues).reduce((escaped, name) => {
269
- let value = rawValues[name];
270
- escaped[name] = typeof value === 'string' ? escape(value) : value;
271
- return escaped;
272
- }, {});
273
-
274
- return formatMessage(config, state, messageDescriptor, escapedValues);
275
- }
package/src/index.js DELETED
@@ -1,12 +0,0 @@
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 allLocaleData from '../locale-data/index';
8
- import {addLocaleData} from './react-intl';
9
-
10
- export * from './react-intl';
11
-
12
- addLocaleData(allLocaleData);
package/src/inject.js DELETED
@@ -1,61 +0,0 @@
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
- // Inspired by react-redux's `connect()` HOC factory function implementation:
8
- // https://github.com/rackt/react-redux
9
-
10
- import React, {Component} from 'react';
11
- import invariant from 'invariant';
12
- import {intlShape} from './types';
13
- import {invariantIntlContext} from './utils';
14
-
15
- function getDisplayName(Component) {
16
- return Component.displayName || Component.name || 'Component';
17
- }
18
-
19
- export default function injectIntl(WrappedComponent, options = {}) {
20
- const {
21
- intlPropName = 'intl',
22
- withRef = false,
23
- } = options;
24
-
25
- class InjectIntl extends Component {
26
- static displayName = `InjectIntl(${getDisplayName(WrappedComponent)})`;
27
-
28
- static contextTypes = {
29
- intl: intlShape,
30
- };
31
-
32
- static WrappedComponent = WrappedComponent;
33
-
34
- constructor(props, context) {
35
- super(props, context);
36
- invariantIntlContext(context);
37
- }
38
-
39
- getWrappedInstance() {
40
- invariant(withRef,
41
- '[React Intl] To access the wrapped instance, ' +
42
- 'the `{withRef: true}` option must be set when calling: ' +
43
- '`injectIntl()`'
44
- );
45
-
46
- return this.refs.wrappedInstance;
47
- }
48
-
49
- render() {
50
- return (
51
- <WrappedComponent
52
- {...this.props}
53
- {...{[intlPropName]: this.context.intl}}
54
- ref={withRef ? 'wrappedInstance' : null}
55
- />
56
- );
57
- }
58
- }
59
-
60
- return InjectIntl;
61
- }
@@ -1,42 +0,0 @@
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 IntlMessageFormat from 'intl-messageformat';
8
- import IntlRelativeFormat from 'intl-relativeformat';
9
-
10
- export function addLocaleData(data = []) {
11
- let locales = Array.isArray(data) ? data : [data];
12
-
13
- locales.forEach((localeData) => {
14
- if (localeData && localeData.locale) {
15
- IntlMessageFormat.__addLocaleData(localeData);
16
- IntlRelativeFormat.__addLocaleData(localeData);
17
- }
18
- });
19
- }
20
-
21
- export function hasLocaleData(locale) {
22
- let localeParts = (locale || '').split('-');
23
-
24
- while (localeParts.length > 0) {
25
- if (hasIMFAndIRFLocaleData(localeParts.join('-'))) {
26
- return true;
27
- }
28
-
29
- localeParts.pop();
30
- }
31
-
32
- return false;
33
- }
34
-
35
- function hasIMFAndIRFLocaleData(locale) {
36
- let normalizedLocale = locale && locale.toLowerCase();
37
-
38
- return !!(
39
- IntlMessageFormat.__localeData__[normalizedLocale] &&
40
- IntlRelativeFormat.__localeData__[normalizedLocale]
41
- );
42
- }
package/src/plural.js DELETED
@@ -1,28 +0,0 @@
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
- // This is a "hack" until a proper `intl-pluralformat` package is created.
8
-
9
- import IntlMessageFormat from 'intl-messageformat';
10
-
11
- function resolveLocale(locales) {
12
- // IntlMessageFormat#_resolveLocale() does not depend on `this`.
13
- return IntlMessageFormat.prototype._resolveLocale(locales);
14
- }
15
-
16
- function findPluralFunction(locale) {
17
- // IntlMessageFormat#_findPluralFunction() does not depend on `this`.
18
- return IntlMessageFormat.prototype._findPluralRuleFunction(locale);
19
- }
20
-
21
- export default class IntlPluralFormat {
22
- constructor(locales, options = {}) {
23
- let useOrdinal = options.style === 'ordinal';
24
- let pluralFn = findPluralFunction(resolveLocale(locales));
25
-
26
- this.format = (value) => pluralFn(value, useOrdinal);
27
- }
28
- }
package/src/react-intl.js DELETED
@@ -1,24 +0,0 @@
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 defaultLocaleData from './en';
8
- import {addLocaleData} from './locale-data-registry';
9
-
10
- addLocaleData(defaultLocaleData);
11
-
12
- export {addLocaleData};
13
- export {intlShape} from './types';
14
- export {default as injectIntl} from './inject';
15
- export {default as defineMessages} from './define-messages';
16
-
17
- export {default as IntlProvider} from './components/provider';
18
- export {default as FormattedDate} from './components/date';
19
- export {default as FormattedTime} from './components/time';
20
- export {default as FormattedRelative} from './components/relative';
21
- export {default as FormattedNumber} from './components/number';
22
- export {default as FormattedPlural} from './components/plural';
23
- export {default as FormattedMessage} from './components/message';
24
- export {default as FormattedHTMLMessage} from './components/html-message';