Skip to content

Commit 767a0d0

Browse files
authored
fix(components): strictly slot rendering (#972)
* fix(components): strictly slot rendering related #968 * updates
1 parent f2714cb commit 767a0d0

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

packages/vue-i18n-core/src/components/formatRenderer.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { isString, isObject, isArray, assign } from '@intlify/shared'
55
import type {
66
RenderFunction,
77
SetupContext,
8+
VNode,
89
VNodeChild,
910
VNodeArrayChildren
1011
} from 'vue'
@@ -40,6 +41,10 @@ type FormatOverrideOptions =
4041
| Intl.NumberFormatOptions
4142
| Intl.DateTimeFormatOptions
4243

44+
function isVNode(target: unknown): target is VNode[] {
45+
return isArray(target) && !isString(target[0])
46+
}
47+
4348
export function renderFormatter<
4449
Props extends FormattableProps<Value, Format>,
4550
Value,
@@ -83,9 +88,13 @@ export function renderFormatter<
8388
if (isArray(parts)) {
8489
children = parts.map((part, index) => {
8590
const slot = slots[part.type]
86-
return slot
91+
const node = slot
8792
? slot({ [part.type]: part.value, index, parts })
8893
: [part.value]
94+
if (isVNode(node)) {
95+
node[0].key = `${part.type}-${index}`
96+
}
97+
return node
8998
})
9099
} else if (isString(parts)) {
91100
children = [parts]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`issue #968 1`] = `"<div class=\\"col-auto text-h6\\">£</div><div class=\\"col-auto text-h3\\">1</div><div class=\\"col-auto text-subtitle1 self-end text-amber\\">,</div><div class=\\"col-auto text-h3\\">150</div><div class=\\"col-auto text-subtitle1 self-end text-amber\\">,</div><div class=\\"col-auto text-h3\\">001</div><div class=\\"col-auto text-subtitle2 self-end text-primary\\">.</div><div class=\\"col-auto text-subtitle1 self-end text-red\\">20</div>"`;

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,3 +491,52 @@ test('issue #964', async () => {
491491
expect(defaultMsg).toEqual('foo')
492492
expect(t('bar', defaultMsg)).toEqual('foo')
493493
})
494+
495+
test('issue #968', async () => {
496+
const i18n = createI18n({
497+
locale: 'en-GB',
498+
numberFormats: {
499+
'en-GB': {
500+
currency: {
501+
style: 'currency',
502+
currency: 'GBP',
503+
notation: 'standard',
504+
useGrouping: true
505+
}
506+
}
507+
}
508+
})
509+
510+
const App = defineComponent({
511+
data() {
512+
return { amountFloat: parseFloat('115000120') / 100 }
513+
},
514+
template: `
515+
<i18n-n :value="amountFloat" format="currency">
516+
<template #currency="slotProps">
517+
<div class="col-auto text-h6">{{ slotProps.currency }}</div>
518+
</template>
519+
<template #group="slotProps">
520+
<div class="col-auto text-subtitle1 self-end text-amber">
521+
{{ slotProps.group }}
522+
</div>
523+
</template>
524+
<template #integer="slotProps">
525+
<div class="col-auto text-h3">{{ slotProps.integer }}</div>
526+
</template>
527+
<template #fraction="slotProps">
528+
<div class="col-auto text-subtitle1 self-end text-red">
529+
{{ slotProps.fraction }}
530+
</div>
531+
</template>
532+
<template #decimal="slotProps">
533+
<div class="col-auto text-subtitle2 self-end text-primary">
534+
{{ slotProps.decimal }}
535+
</div>
536+
</template>
537+
</i18n-n>
538+
`
539+
})
540+
const wrapper = await mount(App, i18n)
541+
expect(wrapper.html()).toMatchSnapshot()
542+
})

0 commit comments

Comments
 (0)