react-intl 4.4.0 → 4.5.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.
- package/CHANGELOG.md +7 -0
- package/dist/components/createFormattedComponent.js +3 -1
- package/dist/error.d.ts +1 -1
- package/dist/formatters/relativeTime.js +1 -4
- package/dist/react-intl.d.ts +2 -1
- package/dist/react-intl.js +31 -17
- 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/lib/components/createFormattedComponent.js +3 -1
- package/lib/error.d.ts +1 -1
- package/lib/formatters/relativeTime.js +1 -4
- package/package.json +14 -21
- package/src/components/createFormattedComponent.tsx +50 -48
- package/src/components/injectIntl.tsx +32 -32
- package/src/components/message.tsx +29 -29
- package/src/components/plural.tsx +22 -22
- package/src/components/provider.tsx +36 -36
- package/src/components/relative.tsx +70 -70
- package/src/components/useIntl.ts +7 -7
- package/src/error.ts +25 -16
- package/src/formatters/dateTime.ts +25 -33
- package/src/formatters/displayName.ts +11 -11
- package/src/formatters/list.ts +29 -29
- package/src/formatters/message.ts +36 -36
- package/src/formatters/number.ts +15 -15
- package/src/formatters/plural.ts +10 -10
- package/src/formatters/relativeTime.ts +18 -19
- package/src/index.ts +47 -37
- package/src/tsconfig.cjs.json +8 -8
- package/src/tsconfig.json +7 -7
- package/src/types.ts +57 -57
- package/src/utils.ts +29 -24
- package/src/vendor.d.ts +1 -1
|
@@ -4,54 +4,54 @@
|
|
|
4
4
|
* See the accompanying LICENSE file for terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import * as React from 'react'
|
|
8
|
-
import {Provider} from './injectIntl'
|
|
7
|
+
import * as React from 'react'
|
|
8
|
+
import {Provider} from './injectIntl'
|
|
9
9
|
import {
|
|
10
10
|
DEFAULT_INTL_CONFIG,
|
|
11
11
|
createFormatters,
|
|
12
12
|
invariantIntlContext,
|
|
13
13
|
createIntlCache,
|
|
14
|
-
} from '../utils'
|
|
15
|
-
import {IntlConfig, IntlShape, Omit, IntlCache} from '../types'
|
|
16
|
-
import {formatNumber, formatNumberToParts} from '../formatters/number'
|
|
17
|
-
import {formatRelativeTime} from '../formatters/relativeTime'
|
|
14
|
+
} from '../utils'
|
|
15
|
+
import {IntlConfig, IntlShape, Omit, IntlCache} from '../types'
|
|
16
|
+
import {formatNumber, formatNumberToParts} from '../formatters/number'
|
|
17
|
+
import {formatRelativeTime} from '../formatters/relativeTime'
|
|
18
18
|
import {
|
|
19
19
|
formatDate,
|
|
20
20
|
formatTime,
|
|
21
21
|
formatDateToParts,
|
|
22
22
|
formatTimeToParts,
|
|
23
|
-
} from '../formatters/dateTime'
|
|
24
|
-
import {formatPlural} from '../formatters/plural'
|
|
25
|
-
import {formatMessage} from '../formatters/message'
|
|
26
|
-
import * as shallowEquals_ from 'shallow-equal/objects'
|
|
27
|
-
import {formatList} from '../formatters/list'
|
|
28
|
-
import {formatDisplayName} from '../formatters/displayName'
|
|
29
|
-
import {ReactIntlError, ReactIntlErrorCode} from '../error'
|
|
23
|
+
} from '../formatters/dateTime'
|
|
24
|
+
import {formatPlural} from '../formatters/plural'
|
|
25
|
+
import {formatMessage} from '../formatters/message'
|
|
26
|
+
import * as shallowEquals_ from 'shallow-equal/objects'
|
|
27
|
+
import {formatList} from '../formatters/list'
|
|
28
|
+
import {formatDisplayName} from '../formatters/displayName'
|
|
29
|
+
import {ReactIntlError, ReactIntlErrorCode} from '../error'
|
|
30
30
|
const shallowEquals: typeof shallowEquals_ =
|
|
31
|
-
(shallowEquals_ as any).default || shallowEquals_
|
|
31
|
+
(shallowEquals_ as any).default || shallowEquals_
|
|
32
32
|
|
|
33
33
|
interface State {
|
|
34
34
|
/**
|
|
35
35
|
* Explicit intl cache to prevent memory leaks
|
|
36
36
|
*/
|
|
37
|
-
cache: IntlCache
|
|
37
|
+
cache: IntlCache
|
|
38
38
|
/**
|
|
39
39
|
* Intl object we created
|
|
40
40
|
*/
|
|
41
|
-
intl?: IntlShape
|
|
41
|
+
intl?: IntlShape
|
|
42
42
|
/**
|
|
43
43
|
* list of memoized config we care about.
|
|
44
44
|
* This is important since creating intl is
|
|
45
45
|
* very expensive
|
|
46
46
|
*/
|
|
47
|
-
prevConfig: OptionalIntlConfig
|
|
47
|
+
prevConfig: OptionalIntlConfig
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export type OptionalIntlConfig = Omit<
|
|
51
51
|
IntlConfig,
|
|
52
52
|
keyof typeof DEFAULT_INTL_CONFIG
|
|
53
53
|
> &
|
|
54
|
-
Partial<typeof DEFAULT_INTL_CONFIG
|
|
54
|
+
Partial<typeof DEFAULT_INTL_CONFIG>
|
|
55
55
|
|
|
56
56
|
function processIntlConfig<P extends OptionalIntlConfig = OptionalIntlConfig>(
|
|
57
57
|
config: P
|
|
@@ -65,7 +65,7 @@ function processIntlConfig<P extends OptionalIntlConfig = OptionalIntlConfig>(
|
|
|
65
65
|
defaultLocale: config.defaultLocale,
|
|
66
66
|
defaultFormats: config.defaultFormats,
|
|
67
67
|
onError: config.onError,
|
|
68
|
-
}
|
|
68
|
+
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -77,9 +77,9 @@ export function createIntl(
|
|
|
77
77
|
config: OptionalIntlConfig,
|
|
78
78
|
cache?: IntlCache
|
|
79
79
|
): IntlShape {
|
|
80
|
-
const formatters = createFormatters(cache)
|
|
81
|
-
const resolvedConfig = {...DEFAULT_INTL_CONFIG, ...config}
|
|
82
|
-
const {locale, defaultLocale, onError} = resolvedConfig
|
|
80
|
+
const formatters = createFormatters(cache)
|
|
81
|
+
const resolvedConfig = {...DEFAULT_INTL_CONFIG, ...config}
|
|
82
|
+
const {locale, defaultLocale, onError} = resolvedConfig
|
|
83
83
|
if (!locale) {
|
|
84
84
|
if (onError) {
|
|
85
85
|
onError(
|
|
@@ -87,21 +87,21 @@ export function createIntl(
|
|
|
87
87
|
ReactIntlErrorCode.INVALID_CONFIG,
|
|
88
88
|
`"locale" was not configured, using "${defaultLocale}" as fallback. See https://github.com/formatjs/react-intl/blob/master/docs/API.md#intlshape for more details`
|
|
89
89
|
)
|
|
90
|
-
)
|
|
90
|
+
)
|
|
91
91
|
}
|
|
92
92
|
// Since there's no registered locale data for `locale`, this will
|
|
93
93
|
// fallback to the `defaultLocale` to make sure things can render.
|
|
94
94
|
// The `messages` are overridden to the `defaultProps` empty object
|
|
95
95
|
// to maintain referential equality across re-renders. It's assumed
|
|
96
96
|
// each <FormattedMessage> contains a `defaultMessage` prop.
|
|
97
|
-
resolvedConfig.locale = resolvedConfig.defaultLocale || 'en'
|
|
97
|
+
resolvedConfig.locale = resolvedConfig.defaultLocale || 'en'
|
|
98
98
|
} else if (!Intl.NumberFormat.supportedLocalesOf(locale).length && onError) {
|
|
99
99
|
onError(
|
|
100
100
|
new ReactIntlError(
|
|
101
101
|
ReactIntlErrorCode.MISSING_DATA,
|
|
102
102
|
`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`
|
|
103
103
|
)
|
|
104
|
-
)
|
|
104
|
+
)
|
|
105
105
|
} else if (
|
|
106
106
|
!Intl.DateTimeFormat.supportedLocalesOf(locale).length &&
|
|
107
107
|
onError
|
|
@@ -111,7 +111,7 @@ export function createIntl(
|
|
|
111
111
|
ReactIntlErrorCode.MISSING_DATA,
|
|
112
112
|
`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`
|
|
113
113
|
)
|
|
114
|
-
)
|
|
114
|
+
)
|
|
115
115
|
}
|
|
116
116
|
return {
|
|
117
117
|
...resolvedConfig,
|
|
@@ -163,38 +163,38 @@ export function createIntl(
|
|
|
163
163
|
resolvedConfig,
|
|
164
164
|
formatters.getDisplayNames
|
|
165
165
|
),
|
|
166
|
-
}
|
|
166
|
+
}
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
export default class IntlProvider extends React.PureComponent<
|
|
170
170
|
OptionalIntlConfig,
|
|
171
171
|
State
|
|
172
172
|
> {
|
|
173
|
-
static displayName = 'IntlProvider'
|
|
174
|
-
static defaultProps = DEFAULT_INTL_CONFIG
|
|
175
|
-
private cache: IntlCache = createIntlCache()
|
|
173
|
+
static displayName = 'IntlProvider'
|
|
174
|
+
static defaultProps = DEFAULT_INTL_CONFIG
|
|
175
|
+
private cache: IntlCache = createIntlCache()
|
|
176
176
|
state: State = {
|
|
177
177
|
cache: this.cache,
|
|
178
178
|
intl: createIntl(processIntlConfig(this.props), this.cache),
|
|
179
179
|
prevConfig: processIntlConfig(this.props),
|
|
180
|
-
}
|
|
180
|
+
}
|
|
181
181
|
|
|
182
182
|
static getDerivedStateFromProps(
|
|
183
183
|
props: OptionalIntlConfig,
|
|
184
184
|
{prevConfig, cache}: State
|
|
185
185
|
): Partial<State> | null {
|
|
186
|
-
const config = processIntlConfig(props)
|
|
186
|
+
const config = processIntlConfig(props)
|
|
187
187
|
if (!shallowEquals(prevConfig, config)) {
|
|
188
188
|
return {
|
|
189
189
|
intl: createIntl(config, cache),
|
|
190
190
|
prevConfig: config,
|
|
191
|
-
}
|
|
191
|
+
}
|
|
192
192
|
}
|
|
193
|
-
return null
|
|
193
|
+
return null
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
render(): JSX.Element {
|
|
197
|
-
invariantIntlContext(this.state.intl)
|
|
198
|
-
return <Provider value={this.state.intl}>{this.props.children}</Provider
|
|
197
|
+
invariantIntlContext(this.state.intl)
|
|
198
|
+
return <Provider value={this.state.intl}>{this.props.children}</Provider>
|
|
199
199
|
}
|
|
200
200
|
}
|
|
@@ -3,132 +3,132 @@
|
|
|
3
3
|
* Copyrights licensed under the New BSD License.
|
|
4
4
|
* See the accompanying LICENSE file for terms.
|
|
5
5
|
*/
|
|
6
|
-
import * as React from 'react'
|
|
7
|
-
import {Context} from './injectIntl'
|
|
8
|
-
import {FormatRelativeTimeOptions} from '../types'
|
|
9
|
-
import {Unit} from '@formatjs/intl-relativetimeformat'
|
|
10
|
-
import {invariantIntlContext} from '../utils'
|
|
11
|
-
import {invariant} from '@formatjs/intl-utils'
|
|
12
|
-
const MINUTE = 60
|
|
13
|
-
const HOUR = 60 * 60
|
|
14
|
-
const DAY = 60 * 60 * 24
|
|
6
|
+
import * as React from 'react'
|
|
7
|
+
import {Context} from './injectIntl'
|
|
8
|
+
import {FormatRelativeTimeOptions} from '../types'
|
|
9
|
+
import {Unit} from '@formatjs/intl-relativetimeformat'
|
|
10
|
+
import {invariantIntlContext} from '../utils'
|
|
11
|
+
import {invariant} from '@formatjs/intl-utils'
|
|
12
|
+
const MINUTE = 60
|
|
13
|
+
const HOUR = 60 * 60
|
|
14
|
+
const DAY = 60 * 60 * 24
|
|
15
15
|
|
|
16
16
|
function selectUnit(seconds: number): Unit {
|
|
17
|
-
const absValue = Math.abs(seconds)
|
|
17
|
+
const absValue = Math.abs(seconds)
|
|
18
18
|
|
|
19
19
|
if (absValue < MINUTE) {
|
|
20
|
-
return 'second'
|
|
20
|
+
return 'second'
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (absValue < HOUR) {
|
|
24
|
-
return 'minute'
|
|
24
|
+
return 'minute'
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
if (absValue < DAY) {
|
|
28
|
-
return 'hour'
|
|
28
|
+
return 'hour'
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
return 'day'
|
|
31
|
+
return 'day'
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function getDurationInSeconds(unit?: Unit): number {
|
|
35
35
|
switch (unit) {
|
|
36
36
|
case 'second':
|
|
37
|
-
return 1
|
|
37
|
+
return 1
|
|
38
38
|
case 'minute':
|
|
39
|
-
return MINUTE
|
|
39
|
+
return MINUTE
|
|
40
40
|
case 'hour':
|
|
41
|
-
return HOUR
|
|
41
|
+
return HOUR
|
|
42
42
|
default:
|
|
43
|
-
return DAY
|
|
43
|
+
return DAY
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
function valueToSeconds(value?: number, unit?: Unit): number {
|
|
48
48
|
if (!value) {
|
|
49
|
-
return 0
|
|
49
|
+
return 0
|
|
50
50
|
}
|
|
51
51
|
switch (unit) {
|
|
52
52
|
case 'second':
|
|
53
|
-
return value
|
|
53
|
+
return value
|
|
54
54
|
case 'minute':
|
|
55
|
-
return value * MINUTE
|
|
55
|
+
return value * MINUTE
|
|
56
56
|
default:
|
|
57
|
-
return value * HOUR
|
|
57
|
+
return value * HOUR
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
export interface Props extends FormatRelativeTimeOptions {
|
|
62
|
-
value?: number
|
|
63
|
-
unit?: Unit
|
|
64
|
-
updateIntervalInSeconds?: number
|
|
65
|
-
children?(value: string): React.ReactChild
|
|
62
|
+
value?: number
|
|
63
|
+
unit?: Unit
|
|
64
|
+
updateIntervalInSeconds?: number
|
|
65
|
+
children?(value: string): React.ReactChild
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
interface State {
|
|
69
|
-
prevUnit?: Unit
|
|
70
|
-
prevValue?: number
|
|
71
|
-
currentValueInSeconds: number
|
|
69
|
+
prevUnit?: Unit
|
|
70
|
+
prevValue?: number
|
|
71
|
+
currentValueInSeconds: number
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const INCREMENTABLE_UNITS: Unit[] = ['second', 'minute', 'hour']
|
|
74
|
+
const INCREMENTABLE_UNITS: Unit[] = ['second', 'minute', 'hour']
|
|
75
75
|
function canIncrement(unit: Unit = 'second'): boolean {
|
|
76
|
-
return INCREMENTABLE_UNITS.includes(unit)
|
|
76
|
+
return INCREMENTABLE_UNITS.includes(unit)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export class FormattedRelativeTime extends React.PureComponent<Props, State> {
|
|
80
80
|
// Public for testing
|
|
81
|
-
_updateTimer: any = null
|
|
82
|
-
static displayName = 'FormattedRelativeTime'
|
|
81
|
+
_updateTimer: any = null
|
|
82
|
+
static displayName = 'FormattedRelativeTime'
|
|
83
83
|
static defaultProps: Pick<Props, 'unit' | 'value'> = {
|
|
84
84
|
value: 0,
|
|
85
85
|
unit: 'second',
|
|
86
|
-
}
|
|
86
|
+
}
|
|
87
87
|
state: State = {
|
|
88
88
|
prevUnit: this.props.unit,
|
|
89
89
|
prevValue: this.props.value,
|
|
90
90
|
currentValueInSeconds: canIncrement(this.props.unit)
|
|
91
91
|
? valueToSeconds(this.props.value, this.props.unit)
|
|
92
92
|
: 0,
|
|
93
|
-
}
|
|
93
|
+
}
|
|
94
94
|
|
|
95
95
|
constructor(props: Props) {
|
|
96
|
-
super(props)
|
|
96
|
+
super(props)
|
|
97
97
|
invariant(
|
|
98
98
|
!props.updateIntervalInSeconds ||
|
|
99
99
|
!!(props.updateIntervalInSeconds && canIncrement(props.unit)),
|
|
100
100
|
'Cannot schedule update with unit longer than hour'
|
|
101
|
-
)
|
|
101
|
+
)
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
scheduleNextUpdate(
|
|
105
105
|
{updateIntervalInSeconds, unit}: Props,
|
|
106
106
|
{currentValueInSeconds}: State
|
|
107
107
|
): void {
|
|
108
|
-
clearTimeout(this._updateTimer)
|
|
109
|
-
this._updateTimer = null
|
|
108
|
+
clearTimeout(this._updateTimer)
|
|
109
|
+
this._updateTimer = null
|
|
110
110
|
// If there's no interval and we cannot increment this unit, do nothing
|
|
111
111
|
if (!updateIntervalInSeconds || !canIncrement(unit)) {
|
|
112
|
-
return
|
|
112
|
+
return
|
|
113
113
|
}
|
|
114
114
|
// Figure out the next interesting time
|
|
115
|
-
const nextValueInSeconds = currentValueInSeconds - updateIntervalInSeconds
|
|
116
|
-
const nextUnit = selectUnit(nextValueInSeconds)
|
|
115
|
+
const nextValueInSeconds = currentValueInSeconds - updateIntervalInSeconds
|
|
116
|
+
const nextUnit = selectUnit(nextValueInSeconds)
|
|
117
117
|
// We've reached the max auto incrementable unit, don't schedule another update
|
|
118
118
|
if (nextUnit === 'day') {
|
|
119
|
-
return
|
|
119
|
+
return
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
const unitDuration = getDurationInSeconds(nextUnit)
|
|
123
|
-
const remainder = nextValueInSeconds % unitDuration
|
|
124
|
-
const prevInterestingValueInSeconds = nextValueInSeconds - remainder
|
|
122
|
+
const unitDuration = getDurationInSeconds(nextUnit)
|
|
123
|
+
const remainder = nextValueInSeconds % unitDuration
|
|
124
|
+
const prevInterestingValueInSeconds = nextValueInSeconds - remainder
|
|
125
125
|
const nextInterestingValueInSeconds =
|
|
126
126
|
prevInterestingValueInSeconds >= currentValueInSeconds
|
|
127
127
|
? prevInterestingValueInSeconds - unitDuration
|
|
128
|
-
: prevInterestingValueInSeconds
|
|
128
|
+
: prevInterestingValueInSeconds
|
|
129
129
|
const delayInSeconds = Math.abs(
|
|
130
130
|
nextInterestingValueInSeconds - currentValueInSeconds
|
|
131
|
-
)
|
|
131
|
+
)
|
|
132
132
|
|
|
133
133
|
this._updateTimer = setTimeout(
|
|
134
134
|
() =>
|
|
@@ -136,20 +136,20 @@ export class FormattedRelativeTime extends React.PureComponent<Props, State> {
|
|
|
136
136
|
currentValueInSeconds: nextInterestingValueInSeconds,
|
|
137
137
|
}),
|
|
138
138
|
delayInSeconds * 1e3
|
|
139
|
-
)
|
|
139
|
+
)
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
componentDidMount(): void {
|
|
143
|
-
this.scheduleNextUpdate(this.props, this.state)
|
|
143
|
+
this.scheduleNextUpdate(this.props, this.state)
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
componentDidUpdate(): void {
|
|
147
|
-
this.scheduleNextUpdate(this.props, this.state)
|
|
147
|
+
this.scheduleNextUpdate(this.props, this.state)
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
componentWillUnmount(): void {
|
|
151
|
-
clearTimeout(this._updateTimer)
|
|
152
|
-
this._updateTimer = null
|
|
151
|
+
clearTimeout(this._updateTimer)
|
|
152
|
+
this._updateTimer = null
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
static getDerivedStateFromProps(
|
|
@@ -163,31 +163,31 @@ export class FormattedRelativeTime extends React.PureComponent<Props, State> {
|
|
|
163
163
|
currentValueInSeconds: canIncrement(props.unit)
|
|
164
164
|
? valueToSeconds(props.value, props.unit)
|
|
165
165
|
: 0,
|
|
166
|
-
}
|
|
166
|
+
}
|
|
167
167
|
}
|
|
168
|
-
return null
|
|
168
|
+
return null
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
render(): JSX.Element {
|
|
172
172
|
return (
|
|
173
173
|
<Context.Consumer>
|
|
174
174
|
{(intl): React.ReactNode => {
|
|
175
|
-
invariantIntlContext(intl)
|
|
175
|
+
invariantIntlContext(intl)
|
|
176
176
|
|
|
177
|
-
const {formatRelativeTime, textComponent: Text} = intl
|
|
178
|
-
const {children, value, unit, updateIntervalInSeconds} = this.props
|
|
179
|
-
const {currentValueInSeconds} = this.state
|
|
180
|
-
let currentValue = value || 0
|
|
181
|
-
let currentUnit = unit
|
|
177
|
+
const {formatRelativeTime, textComponent: Text} = intl
|
|
178
|
+
const {children, value, unit, updateIntervalInSeconds} = this.props
|
|
179
|
+
const {currentValueInSeconds} = this.state
|
|
180
|
+
let currentValue = value || 0
|
|
181
|
+
let currentUnit = unit
|
|
182
182
|
|
|
183
183
|
if (
|
|
184
184
|
canIncrement(unit) &&
|
|
185
185
|
typeof currentValueInSeconds === 'number' &&
|
|
186
186
|
updateIntervalInSeconds
|
|
187
187
|
) {
|
|
188
|
-
currentUnit = selectUnit(currentValueInSeconds)
|
|
189
|
-
const unitDuration = getDurationInSeconds(currentUnit)
|
|
190
|
-
currentValue = Math.round(currentValueInSeconds / unitDuration)
|
|
188
|
+
currentUnit = selectUnit(currentValueInSeconds)
|
|
189
|
+
const unitDuration = getDurationInSeconds(currentUnit)
|
|
190
|
+
currentValue = Math.round(currentValueInSeconds / unitDuration)
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
const formattedRelativeTime = formatRelativeTime(
|
|
@@ -196,19 +196,19 @@ export class FormattedRelativeTime extends React.PureComponent<Props, State> {
|
|
|
196
196
|
{
|
|
197
197
|
...this.props,
|
|
198
198
|
}
|
|
199
|
-
)
|
|
199
|
+
)
|
|
200
200
|
|
|
201
201
|
if (typeof children === 'function') {
|
|
202
|
-
return children(formattedRelativeTime)
|
|
202
|
+
return children(formattedRelativeTime)
|
|
203
203
|
}
|
|
204
204
|
if (Text) {
|
|
205
|
-
return <Text>{formattedRelativeTime}</Text
|
|
205
|
+
return <Text>{formattedRelativeTime}</Text>
|
|
206
206
|
}
|
|
207
|
-
return formattedRelativeTime
|
|
207
|
+
return formattedRelativeTime
|
|
208
208
|
}}
|
|
209
209
|
</Context.Consumer>
|
|
210
|
-
)
|
|
210
|
+
)
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
export default FormattedRelativeTime
|
|
214
|
+
export default FormattedRelativeTime
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {useContext} from 'react'
|
|
2
|
-
import {Context} from './injectIntl'
|
|
3
|
-
import {invariantIntlContext} from '../utils'
|
|
4
|
-
import {IntlShape} from '../types'
|
|
1
|
+
import {useContext} from 'react'
|
|
2
|
+
import {Context} from './injectIntl'
|
|
3
|
+
import {invariantIntlContext} from '../utils'
|
|
4
|
+
import {IntlShape} from '../types'
|
|
5
5
|
|
|
6
6
|
export default function useIntl(): IntlShape {
|
|
7
|
-
const intl = useContext(Context)
|
|
8
|
-
invariantIntlContext(intl)
|
|
9
|
-
return intl
|
|
7
|
+
const intl = useContext(Context)
|
|
8
|
+
invariantIntlContext(intl)
|
|
9
|
+
return intl
|
|
10
10
|
}
|
package/src/error.ts
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {MessageDescriptor} from './types'
|
|
2
2
|
|
|
3
3
|
export const enum ReactIntlErrorCode {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
FORMAT_ERROR = 'FORMAT_ERROR',
|
|
5
|
+
UNSUPPORTED_FORMATTER = 'UNSUPPORTED_FORMATTER',
|
|
6
|
+
INVALID_CONFIG = 'INVALID_CONFIG',
|
|
7
|
+
MISSING_DATA = 'MISSING_DATA',
|
|
8
|
+
MISSING_TRANSLATION = 'MISSING_TRANSLATION',
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export class ReactIntlError extends Error {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
public readonly code: ReactIntlErrorCode
|
|
13
|
+
public readonly descriptor?: MessageDescriptor
|
|
14
|
+
constructor(
|
|
15
|
+
code: ReactIntlErrorCode,
|
|
16
|
+
message: string,
|
|
17
|
+
descriptor?: MessageDescriptor,
|
|
18
|
+
exception?: Error
|
|
19
|
+
) {
|
|
20
|
+
super(
|
|
21
|
+
`[React Intl Error ${code}] ${message} ${
|
|
22
|
+
exception ? `\n${exception.stack}` : ''
|
|
23
|
+
}`
|
|
24
|
+
)
|
|
25
|
+
this.code = code
|
|
26
|
+
this.descriptor = descriptor
|
|
27
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
28
|
+
Error.captureStackTrace(this, ReactIntlError)
|
|
21
29
|
}
|
|
22
|
-
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* See the accompanying LICENSE file for terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {Formatters, IntlConfig, IntlFormatters} from '../types'
|
|
7
|
+
import {Formatters, IntlConfig, IntlFormatters} from '../types'
|
|
8
8
|
|
|
9
|
-
import {filterProps, getNamedFormat} from '../utils'
|
|
10
|
-
import {ReactIntlError, ReactIntlErrorCode} from '../error'
|
|
9
|
+
import {filterProps, getNamedFormat} from '../utils'
|
|
10
|
+
import {ReactIntlError, ReactIntlErrorCode} from '../error'
|
|
11
11
|
|
|
12
12
|
const DATE_TIME_FORMAT_OPTIONS: Array<keyof Intl.DateTimeFormatOptions> = [
|
|
13
13
|
'localeMatcher',
|
|
@@ -25,7 +25,7 @@ const DATE_TIME_FORMAT_OPTIONS: Array<keyof Intl.DateTimeFormatOptions> = [
|
|
|
25
25
|
'minute',
|
|
26
26
|
'second',
|
|
27
27
|
'timeZoneName',
|
|
28
|
-
]
|
|
28
|
+
]
|
|
29
29
|
|
|
30
30
|
export function getFormatter(
|
|
31
31
|
{
|
|
@@ -38,17 +38,13 @@ export function getFormatter(
|
|
|
38
38
|
getDateTimeFormat: Formatters['getDateTimeFormat'],
|
|
39
39
|
options: Parameters<IntlFormatters['formatDate']>[1] = {}
|
|
40
40
|
): Intl.DateTimeFormat {
|
|
41
|
-
const {format} = options
|
|
41
|
+
const {format} = options
|
|
42
42
|
const defaults = {
|
|
43
43
|
...(timeZone && {timeZone}),
|
|
44
44
|
...(format && getNamedFormat(formats!, type, format, onError)),
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
|
|
47
|
-
let filteredOptions = filterProps(
|
|
48
|
-
options,
|
|
49
|
-
DATE_TIME_FORMAT_OPTIONS,
|
|
50
|
-
defaults
|
|
51
|
-
);
|
|
47
|
+
let filteredOptions = filterProps(options, DATE_TIME_FORMAT_OPTIONS, defaults)
|
|
52
48
|
|
|
53
49
|
if (
|
|
54
50
|
type === 'time' &&
|
|
@@ -57,10 +53,10 @@ export function getFormatter(
|
|
|
57
53
|
!filteredOptions.second
|
|
58
54
|
) {
|
|
59
55
|
// Add default formatting options if hour, minute, or second isn't defined.
|
|
60
|
-
filteredOptions = {...filteredOptions, hour: 'numeric', minute: 'numeric'}
|
|
56
|
+
filteredOptions = {...filteredOptions, hour: 'numeric', minute: 'numeric'}
|
|
61
57
|
}
|
|
62
58
|
|
|
63
|
-
return getDateTimeFormat(locale, filteredOptions)
|
|
59
|
+
return getDateTimeFormat(locale, filteredOptions)
|
|
64
60
|
}
|
|
65
61
|
|
|
66
62
|
export function formatDate(
|
|
@@ -69,11 +65,9 @@ export function formatDate(
|
|
|
69
65
|
value?: Parameters<IntlFormatters['formatDate']>[0],
|
|
70
66
|
options: Parameters<IntlFormatters['formatDate']>[1] = {}
|
|
71
67
|
): string {
|
|
72
|
-
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
68
|
+
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
73
69
|
try {
|
|
74
|
-
return getFormatter(config, 'date', getDateTimeFormat, options).format(
|
|
75
|
-
date
|
|
76
|
-
);
|
|
70
|
+
return getFormatter(config, 'date', getDateTimeFormat, options).format(date)
|
|
77
71
|
} catch (e) {
|
|
78
72
|
config.onError(
|
|
79
73
|
new ReactIntlError(
|
|
@@ -81,10 +75,10 @@ export function formatDate(
|
|
|
81
75
|
'Error formatting date.',
|
|
82
76
|
e
|
|
83
77
|
)
|
|
84
|
-
)
|
|
78
|
+
)
|
|
85
79
|
}
|
|
86
80
|
|
|
87
|
-
return String(date)
|
|
81
|
+
return String(date)
|
|
88
82
|
}
|
|
89
83
|
|
|
90
84
|
export function formatTime(
|
|
@@ -93,12 +87,10 @@ export function formatTime(
|
|
|
93
87
|
value?: Parameters<IntlFormatters['formatTime']>[0],
|
|
94
88
|
options: Parameters<IntlFormatters['formatTime']>[1] = {}
|
|
95
89
|
): string {
|
|
96
|
-
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
90
|
+
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
97
91
|
|
|
98
92
|
try {
|
|
99
|
-
return getFormatter(config, 'time', getDateTimeFormat, options).format(
|
|
100
|
-
date
|
|
101
|
-
);
|
|
93
|
+
return getFormatter(config, 'time', getDateTimeFormat, options).format(date)
|
|
102
94
|
} catch (e) {
|
|
103
95
|
config.onError(
|
|
104
96
|
new ReactIntlError(
|
|
@@ -106,10 +98,10 @@ export function formatTime(
|
|
|
106
98
|
'Error formatting time.',
|
|
107
99
|
e
|
|
108
100
|
)
|
|
109
|
-
)
|
|
101
|
+
)
|
|
110
102
|
}
|
|
111
103
|
|
|
112
|
-
return String(date)
|
|
104
|
+
return String(date)
|
|
113
105
|
}
|
|
114
106
|
|
|
115
107
|
export function formatDateToParts(
|
|
@@ -118,14 +110,14 @@ export function formatDateToParts(
|
|
|
118
110
|
value?: Parameters<IntlFormatters['formatDate']>[0],
|
|
119
111
|
options: Parameters<IntlFormatters['formatDate']>[1] = {}
|
|
120
112
|
): Intl.DateTimeFormatPart[] {
|
|
121
|
-
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
113
|
+
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
122
114
|
try {
|
|
123
115
|
return getFormatter(
|
|
124
116
|
config,
|
|
125
117
|
'date',
|
|
126
118
|
getDateTimeFormat,
|
|
127
119
|
options
|
|
128
|
-
).formatToParts(date)
|
|
120
|
+
).formatToParts(date)
|
|
129
121
|
} catch (e) {
|
|
130
122
|
config.onError(
|
|
131
123
|
new ReactIntlError(
|
|
@@ -133,10 +125,10 @@ export function formatDateToParts(
|
|
|
133
125
|
'Error formatting date.',
|
|
134
126
|
e
|
|
135
127
|
)
|
|
136
|
-
)
|
|
128
|
+
)
|
|
137
129
|
}
|
|
138
130
|
|
|
139
|
-
return []
|
|
131
|
+
return []
|
|
140
132
|
}
|
|
141
133
|
|
|
142
134
|
export function formatTimeToParts(
|
|
@@ -145,7 +137,7 @@ export function formatTimeToParts(
|
|
|
145
137
|
value?: Parameters<IntlFormatters['formatTime']>[0],
|
|
146
138
|
options: Parameters<IntlFormatters['formatTime']>[1] = {}
|
|
147
139
|
): Intl.DateTimeFormatPart[] {
|
|
148
|
-
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
140
|
+
const date = typeof value === 'string' ? new Date(value || 0) : value
|
|
149
141
|
|
|
150
142
|
try {
|
|
151
143
|
return getFormatter(
|
|
@@ -153,7 +145,7 @@ export function formatTimeToParts(
|
|
|
153
145
|
'time',
|
|
154
146
|
getDateTimeFormat,
|
|
155
147
|
options
|
|
156
|
-
).formatToParts(date)
|
|
148
|
+
).formatToParts(date)
|
|
157
149
|
} catch (e) {
|
|
158
150
|
config.onError(
|
|
159
151
|
new ReactIntlError(
|
|
@@ -161,8 +153,8 @@ export function formatTimeToParts(
|
|
|
161
153
|
'Error formatting time.',
|
|
162
154
|
e
|
|
163
155
|
)
|
|
164
|
-
)
|
|
156
|
+
)
|
|
165
157
|
}
|
|
166
158
|
|
|
167
|
-
return []
|
|
159
|
+
return []
|
|
168
160
|
}
|