Skip to content

Commit 855e272

Browse files
committed
fix: fix tests & add corresponding formatToParts fns
1 parent 7811ccc commit 855e272

File tree

11 files changed

+129
-169
lines changed

11 files changed

+129
-169
lines changed

src/components/createFormattedComponent.tsx

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,8 @@ export const FormattedNumberParts: React.FC<
3333
<Context.Consumer>
3434
{intl => {
3535
invariantIntlContext(intl);
36-
const {value, children} = props;
37-
let formattedParts: Intl.NumberFormatPart[] = [];
38-
try {
39-
formattedParts = getNumberFormatter(
40-
intl,
41-
intl.formatters.getNumberFormat,
42-
props
43-
).formatToParts(value);
44-
} catch (e) {
45-
intl.onError(createError(`Error formatting number.`, e));
46-
}
47-
return children(formattedParts);
36+
const {value, children, ...formatProps} = props;
37+
return children(intl.formatNumberToParts(value, formatProps));
4838
}}
4939
</Context.Consumer>
5040
);
@@ -63,24 +53,12 @@ export function createFormattedDateTimePartsComponent<
6353
<Context.Consumer>
6454
{intl => {
6555
invariantIntlContext(intl);
66-
const {value, children} = props;
56+
const {value, children, ...formatProps} = props;
6757
const date = typeof value === 'string' ? new Date(value || 0) : value;
68-
let formattedParts: Intl.DateTimeFormatPart[] = [];
69-
try {
70-
formattedParts = getDateTimeFormatter(
71-
intl,
72-
name === 'formatDate' ? 'date' : 'time',
73-
intl.formatters.getDateTimeFormat,
74-
props
75-
).formatToParts(date as Date);
76-
} catch (e) {
77-
intl.onError(
78-
createError(
79-
`Error formatting ${name === 'formatDate' ? 'date' : 'time'}.`,
80-
e
81-
)
82-
);
83-
}
58+
const formattedParts: Intl.DateTimeFormatPart[] =
59+
name === 'formatDate'
60+
? intl.formatDateToParts(date, formatProps)
61+
: intl.formatTimeToParts(date, formatProps);
8462

8563
return children(formattedParts);
8664
}}
@@ -103,8 +81,8 @@ export function createFormattedComponent<Name extends keyof Formatter>(
10381
<Context.Consumer>
10482
{intl => {
10583
invariantIntlContext(intl);
106-
const {value, children} = props;
107-
const formattedValue = intl[name](value as any, props);
84+
const {value, children, ...formatProps} = props;
85+
const formattedValue = intl[name](value as any, formatProps);
10886

10987
if (typeof children === 'function') {
11088
return children(formattedValue as any);

src/components/provider.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ import {
1515
} from '../utils';
1616
import {IntlConfig, IntlShape, Omit, IntlCache} from '../types';
1717
import areIntlLocalesSupported from 'intl-locales-supported';
18-
import {formatNumber} from '../formatters/number';
18+
import {formatNumber, formatNumberToParts} from '../formatters/number';
1919
import {formatRelativeTime} from '../formatters/relativeTime';
20-
import {formatDate, formatTime} from '../formatters/dateTime';
20+
import {
21+
formatDate,
22+
formatTime,
23+
formatDateToParts,
24+
formatTimeToParts,
25+
} from '../formatters/dateTime';
2126
import {formatPlural} from '../formatters/plural';
2227
import {formatMessage, formatHTMLMessage} from '../formatters/message';
2328
import * as shallowEquals_ from 'shallow-equal/objects';
@@ -135,6 +140,11 @@ export function createIntl(
135140
resolvedConfig,
136141
formatters.getNumberFormat
137142
),
143+
formatNumberToParts: formatNumberToParts.bind(
144+
null,
145+
resolvedConfig,
146+
formatters.getNumberFormat
147+
),
138148
formatRelativeTime: formatRelativeTime.bind(
139149
null,
140150
resolvedConfig,
@@ -145,11 +155,21 @@ export function createIntl(
145155
resolvedConfig,
146156
formatters.getDateTimeFormat
147157
),
158+
formatDateToParts: formatDateToParts.bind(
159+
null,
160+
resolvedConfig,
161+
formatters.getDateTimeFormat
162+
),
148163
formatTime: formatTime.bind(
149164
null,
150165
resolvedConfig,
151166
formatters.getDateTimeFormat
152167
),
168+
formatTimeToParts: formatTimeToParts.bind(
169+
null,
170+
resolvedConfig,
171+
formatters.getDateTimeFormat
172+
),
153173
formatPlural: formatPlural.bind(
154174
null,
155175
resolvedConfig,

src/formatters/dateTime.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,46 @@ export function formatTime(
9898

9999
return String(date);
100100
}
101+
102+
export function formatDateToParts(
103+
config: Pick<IntlConfig, 'locale' | 'formats' | 'onError' | 'timeZone'>,
104+
getDateTimeFormat: Formatters['getDateTimeFormat'],
105+
value?: Parameters<IntlFormatters['formatDate']>[0],
106+
options: Parameters<IntlFormatters['formatDate']>[1] = {}
107+
) {
108+
const date = typeof value === 'string' ? new Date(value || 0) : value;
109+
try {
110+
return getFormatter(
111+
config,
112+
'date',
113+
getDateTimeFormat,
114+
options
115+
).formatToParts(date);
116+
} catch (e) {
117+
config.onError(createError('Error formatting date.', e));
118+
}
119+
120+
return [];
121+
}
122+
123+
export function formatTimeToParts(
124+
config: Pick<IntlConfig, 'locale' | 'formats' | 'onError' | 'timeZone'>,
125+
getDateTimeFormat: Formatters['getDateTimeFormat'],
126+
value?: Parameters<IntlFormatters['formatTime']>[0],
127+
options: Parameters<IntlFormatters['formatTime']>[1] = {}
128+
) {
129+
const date = typeof value === 'string' ? new Date(value || 0) : value;
130+
131+
try {
132+
return getFormatter(
133+
config,
134+
'time',
135+
getDateTimeFormat,
136+
options
137+
).formatToParts(date);
138+
} catch (e) {
139+
config.onError(createError('Error formatting time.', e));
140+
}
141+
142+
return [];
143+
}

src/formatters/number.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,18 @@ export function formatNumber(
4747

4848
return String(value);
4949
}
50+
51+
export function formatNumberToParts(
52+
config: Pick<IntlConfig, 'locale' | 'formats' | 'onError'>,
53+
getNumberFormat: Formatters['getNumberFormat'],
54+
value: Parameters<IntlFormatters['formatNumber']>[0],
55+
options: Parameters<IntlFormatters['formatNumber']>[1] = {}
56+
) {
57+
try {
58+
return getFormatter(config, getNumberFormat, options).formatToParts(value);
59+
} catch (e) {
60+
config.onError(createError('Error formatting number.', e));
61+
}
62+
63+
return [];
64+
}

src/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ export interface IntlFormatters {
6363
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
6464
opts?: FormatDateOptions
6565
): string;
66+
formatDateToParts(
67+
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
68+
opts?: FormatDateOptions
69+
): Intl.DateTimeFormatPart[];
70+
formatTimeToParts(
71+
value: Parameters<Intl.DateTimeFormat['format']>[0] | string,
72+
opts?: FormatDateOptions
73+
): Intl.DateTimeFormatPart[];
6674
formatRelativeTime(
6775
value: Parameters<IntlRelativeTimeFormat['format']>[0],
6876
unit?: Parameters<IntlRelativeTimeFormat['format']>[1],
@@ -72,6 +80,10 @@ export interface IntlFormatters {
7280
value: Parameters<Intl.NumberFormat['format']>[0],
7381
opts?: FormatNumberOptions
7482
): string;
83+
formatNumberToParts(
84+
value: Parameters<Intl.NumberFormat['format']>[0],
85+
opts?: FormatNumberOptions
86+
): Intl.NumberFormatPart[];
7587
formatPlural(
7688
value: Parameters<Intl.PluralRules['select']>[0],
7789
opts?: FormatPluralOptions

test/unit/components/__snapshots__/date.tsx.snap

Lines changed: 0 additions & 35 deletions
This file was deleted.

test/unit/components/__snapshots__/number.tsx.snap

Lines changed: 0 additions & 43 deletions
This file was deleted.

test/unit/components/__snapshots__/time.tsx.snap

Lines changed: 0 additions & 43 deletions
This file was deleted.

test/unit/components/date.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,19 @@ describe('<FormattedDateParts>', () => {
162162

163163
mountPartsWithProvider({value: date, ...options}, intl);
164164

165-
expect(children.mock.calls).toMatchSnapshot();
165+
expect(children.mock.calls[0][0]).toEqual(
166+
intl.formatDateToParts(date, options)
167+
);
166168
});
167169

168170
it('falls back and warns on invalid Intl.DateTimeFormat options', () => {
169171
const date = new Date(1567130870626);
170172
mountPartsWithProvider({value: date, year: 'invalid', children}, intl);
171173

172-
expect(children.mock.calls).toMatchSnapshot();
173-
expect(console.error).toHaveBeenCalledTimes(1);
174+
expect(children.mock.calls[0][0]).toEqual(
175+
intl.formatDateToParts(date, {year: 'invalid'})
176+
);
177+
expect(console.error).toHaveBeenCalledTimes(2);
174178
expect(console.error).toHaveBeenCalledWith(
175179
expect.stringMatching(
176180
/Error formatting date.\nRangeError: Value invalid out of range for (.*) options property year/
@@ -193,6 +197,8 @@ describe('<FormattedDateParts>', () => {
193197

194198
mountPartsWithProvider({value: date, format, children}, intl);
195199

196-
expect(children.mock.calls).toMatchSnapshot();
200+
expect(children.mock.calls[0][0]).toEqual(
201+
intl.formatDateToParts(date, {format})
202+
);
197203
});
198204
});

test/unit/components/number.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ describe('<FormattedNumberParts>', function() {
145145

146146
mountPartsWithProvider({value: num, ...options}, intl);
147147

148-
expect(children.mock.calls).toMatchSnapshot();
148+
expect(children.mock.calls[0][0]).toEqual(
149+
intl.formatNumberToParts(num, options)
150+
);
149151
});
150152

151153
it('accepts `format` prop', () => {
@@ -165,6 +167,8 @@ describe('<FormattedNumberParts>', function() {
165167
const format = 'percent';
166168

167169
mountPartsWithProvider({value: num, format, children}, intl);
168-
expect(children.mock.calls).toMatchSnapshot();
170+
expect(children.mock.calls[0][0]).toEqual(
171+
intl.formatNumberToParts(num, {format})
172+
);
169173
});
170174
});

0 commit comments

Comments
 (0)