Skip to content

Commit 1251f3a

Browse files
authored
fix: number & datetime format options (#1017)
closes #992
1 parent 58e8d4a commit 1251f3a

File tree

5 files changed

+83
-10
lines changed

5 files changed

+83
-10
lines changed

packages/core-base/src/datetime.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ import type { CoreContext, CoreInternalContext } from './context'
6262
* datetime(context, value, { key: 'short', part: true })
6363
*
6464
* // orverride context.datetimeFormats[locale] options with functino options
65-
* datetime(cnotext, value, 'short', { currency: 'EUR' })
66-
* datetime(cnotext, value, 'short', 'ja-JP', { currency: 'EUR' })
67-
* datetime(context, value, { key: 'short', part: true }, { currency: 'EUR'})
65+
* datetime(cnotext, value, 'short', { year: '2-digit' })
66+
* datetime(cnotext, value, 'short', 'ja-JP', { year: '2-digit' })
67+
* datetime(context, value, { key: 'short', part: true, year: '2-digit' })
6868
*/
6969

7070
/**
@@ -75,7 +75,8 @@ import type { CoreContext, CoreInternalContext } from './context'
7575
*
7676
* @VueI18nGeneral
7777
*/
78-
export interface DateTimeOptions<Key = string, Locales = Locale> {
78+
export interface DateTimeOptions<Key = string, Locales = Locale>
79+
extends Intl.DateTimeFormatOptions {
7980
/**
8081
* @remarks
8182
* The target format key
@@ -295,12 +296,35 @@ export function datetime<
295296
return !part ? formatter.format(value) : formatter.formatToParts(value)
296297
}
297298

299+
const DATETIME_FORMAT_OPTIONS_KEYS = [
300+
'localeMatcher',
301+
'weekday',
302+
'era',
303+
'year',
304+
'month',
305+
'day',
306+
'hour',
307+
'minute',
308+
'second',
309+
'timeZoneName',
310+
'formatMatcher',
311+
'hour12',
312+
'timeZone',
313+
'dateStyle',
314+
'timeStyle',
315+
'calendar',
316+
'dayPeriod',
317+
'numberingSystem',
318+
'hourCycle',
319+
'fractionalSecondDigits'
320+
]
321+
298322
/** @internal */
299323
export function parseDateTimeArgs(
300324
...args: unknown[]
301325
): [string, number | Date, DateTimeOptions, Intl.DateTimeFormatOptions] {
302326
const [arg1, arg2, arg3, arg4] = args
303-
let options = {} as DateTimeOptions
327+
const options = {} as DateTimeOptions
304328
let overrides = {} as Intl.DateTimeFormatOptions
305329

306330
let value: number | Date
@@ -340,7 +364,15 @@ export function parseDateTimeArgs(
340364
if (isString(arg2)) {
341365
options.key = arg2
342366
} else if (isPlainObject(arg2)) {
343-
options = arg2
367+
Object.keys(arg2).forEach(key => {
368+
if (DATETIME_FORMAT_OPTIONS_KEYS.includes(key)) {
369+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
370+
;(overrides as any)[key] = (arg2 as any)[key]
371+
} else {
372+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
373+
;(options as any)[key] = (arg2 as any)[key]
374+
}
375+
})
344376
}
345377

346378
if (isString(arg3)) {

packages/core-base/src/number.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ import type { CoreContext, CoreInternalContext } from './context'
6262
* // orverride context.numberFormats[locale] options with functino options
6363
* number(cnotext, value, 'currency', { year: '2-digit' })
6464
* number(cnotext, value, 'currency', 'ja-JP', { year: '2-digit' })
65-
* number(context, value, { key: 'currenty', part: true }, { year: '2-digit'})
65+
* number(context, value, { key: 'currenty', locale: 'ja-JP', part: true, year: '2-digit'})
6666
*/
6767

6868
/**
@@ -73,7 +73,8 @@ import type { CoreContext, CoreInternalContext } from './context'
7373
*
7474
* @VueI18nGeneral
7575
*/
76-
export interface NumberOptions<Key = string, Locales = Locale> {
76+
export interface NumberOptions<Key = string, Locales = Locale>
77+
extends Intl.NumberFormatOptions {
7778
/**
7879
* @remarks
7980
* The target format key
@@ -290,12 +291,31 @@ export function number<
290291
return !part ? formatter.format(value) : formatter.formatToParts(value)
291292
}
292293

294+
const NUMBER_FORMAT_OPTIONS_KEYS = [
295+
'localeMatcher',
296+
'style',
297+
'currency',
298+
'currencyDisplay',
299+
'currencySign',
300+
'useGrouping',
301+
'minimumIntegerDigits',
302+
'minimumFractionDigits',
303+
'maximumFractionDigits',
304+
'minimumSignificantDigits',
305+
'maximumSignificantDigits',
306+
'compactDisplay',
307+
'notation',
308+
'signDisplay',
309+
'unit',
310+
'unitDisplay'
311+
]
312+
293313
/** @internal */
294314
export function parseNumberArgs(
295315
...args: unknown[]
296316
): [string, number, NumberOptions, Intl.NumberFormatOptions] {
297317
const [arg1, arg2, arg3, arg4] = args
298-
let options = {} as NumberOptions
318+
const options = {} as NumberOptions
299319
let overrides = {} as Intl.NumberFormatOptions
300320

301321
if (!isNumber(arg1)) {
@@ -306,7 +326,15 @@ export function parseNumberArgs(
306326
if (isString(arg2)) {
307327
options.key = arg2
308328
} else if (isPlainObject(arg2)) {
309-
options = arg2
329+
Object.keys(arg2).forEach(key => {
330+
if (NUMBER_FORMAT_OPTIONS_KEYS.includes(key)) {
331+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
332+
;(overrides as any)[key] = (arg2 as any)[key]
333+
} else {
334+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
335+
;(options as any)[key] = (arg2 as any)[key]
336+
}
337+
})
310338
}
311339

312340
if (isString(arg3)) {

packages/core-base/test/datetime.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ test('override format options with number function options', () => {
188188
expect(
189189
datetime(ctx, dt, { key: 'short', locale: 'ja-JP' }, { year: '2-digit' })
190190
).toEqual('12/12/20 12:00')
191+
expect(
192+
datetime(ctx, dt, { key: 'short', locale: 'ja-JP', year: '2-digit' })
193+
).toEqual('12/12/20 12:00')
191194
})
192195

193196
test('fallback', () => {

packages/core-base/test/number.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ test('override format options with number function options', () => {
155155
{ currency: 'EUR' }
156156
)
157157
).toEqual('€10,100.00')
158+
expect(
159+
number(ctx, 10100, { key: 'currency', locale: 'ja-JP', currency: 'EUR' })
160+
).toEqual('€10,100.00')
158161
})
159162

160163
test('fallback', () => {

packages/vue-i18n-core/test/composer.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,9 @@ describe('d', () => {
801801
expect(d(dt, { key: 'long', fallbackWarn: false })).toEqual(
802802
'2012/12/20 12:00:00'
803803
)
804+
expect(d(dt, { key: 'short', locale: 'ja-JP', year: '2-digit' })).toEqual(
805+
'12/12/20 12:00'
806+
)
804807
})
805808

806809
test('missing', () => {
@@ -871,6 +874,10 @@ describe('n', () => {
871874
}
872875
})
873876
expect(n(0.99, { key: 'percent', fallbackWarn: false })).toEqual('99%')
877+
// overrides
878+
expect(
879+
n(10100, { key: 'currency', locale: 'ja-JP', currency: 'EUR' })
880+
).toEqual('€10,100.00')
874881
})
875882

876883
test('minimumFractionDigits, maximumFractionDigits', () => {

0 commit comments

Comments
 (0)