Skip to content

Commit 7b3c170

Browse files
authored
fix: i18n component not working with message overrides (#236)
1 parent 6196db8 commit 7b3c170

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

packages/fluent-vue/__tests__/vue/component.spec.ts

+51
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,57 @@ describe('component', () => {
4848
expect(mounted.html()).toEqual(`<span>Inner data</span>`)
4949
})
5050

51+
it('works with grandparent translations', () => {
52+
// Arrange
53+
bundle.addResource(
54+
new FluentResource(ftl`
55+
key = Inner data
56+
`)
57+
)
58+
59+
const child = {
60+
template: '<b><slot /></b>',
61+
}
62+
63+
const component = {
64+
components: {
65+
child,
66+
},
67+
template: '<div><child><i18n path="key"></i18n></child></div>',
68+
}
69+
70+
// Act
71+
const mounted = mount(component, options)
72+
73+
// Assert
74+
expect(mounted.html()).toEqual(`<div><b><span>Inner data</span></b></div>`)
75+
})
76+
77+
it('works with local component messages', () => {
78+
// Arrange
79+
const child = {
80+
template: '<b><slot /></b>',
81+
}
82+
83+
const component = {
84+
components: {
85+
child,
86+
},
87+
template: '<div><child><i18n path="i18n-key"></i18n></child></div>',
88+
fluent: {
89+
'en-US': new FluentResource(ftl`
90+
i18n-key = Inner data
91+
`),
92+
},
93+
}
94+
95+
// Act
96+
const mounted = mount(component, options)
97+
98+
// Assert
99+
expect(mounted.html()).toEqual(`<div><b><span>Inner data</span></b></div>`)
100+
})
101+
51102
it('interpolates components', () => {
52103
// Arrange
53104
bundle.addResource(

packages/fluent-vue/src/composition.ts

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { inheritBundle } from './inheritBundle'
77
import { RootContextSymbol } from './symbols'
88

99
export function getContext(rootContext: TranslationContext, instance: any): TranslationContext {
10+
if (instance == null) {
11+
return rootContext
12+
}
13+
1014
const target = instance.$options ?? instance.type
1115
if (target._fluent != null) {
1216
return target._fluent

packages/fluent-vue/src/vue/component.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@ import { defineComponent, h, getCurrentInstance, Vue, inject, computed } from 'v
22
import { getContext } from '../composition'
33
import { RootContextSymbol } from '../symbols'
44

5-
function getParent(instance: Vue | null): Vue {
6-
return instance?.$parent ?? (instance as any)?.parent.proxy
5+
function getParentWithFluent(instance: Vue | null): Vue {
6+
const parent = instance?.$parent ?? (instance as any)?.parent?.proxy
7+
const target = parent?.$options ?? parent?.type
8+
9+
if (target != null && target.fluent == null) {
10+
return getParentWithFluent(parent)
11+
}
12+
13+
return parent
714
}
815

916
export default defineComponent({
@@ -27,7 +34,7 @@ export default defineComponent({
2734
const translation = computed(() => {
2835
const rootContext = inject(RootContextSymbol)!
2936
const instance = getCurrentInstance()
30-
const parent = getParent(instance)
37+
const parent = getParentWithFluent(instance)
3138
const fluent = getContext(rootContext, parent)
3239
return fluent.format(props.path, params)
3340
})

0 commit comments

Comments
 (0)