Skip to content

Commit d395b42

Browse files
committed
feat(directive): allow to localize attributes
1 parent ed4ccff commit d395b42

File tree

5 files changed

+67
-8
lines changed

5 files changed

+67
-8
lines changed

src/directive.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ export default {
1313
return
1414
}
1515

16-
el.textContent = vnode.context.$t(binding.arg, binding.value)
16+
const msg = vnode.context.$fluent.getMessage(binding.arg)
17+
18+
if (msg === undefined) {
19+
return
20+
}
21+
22+
el.textContent = vnode.context.$fluent.formatPattern(msg.value, binding.value)
23+
if (vnode.data === undefined || vnode.data.attrs === undefined) {
24+
return
25+
}
26+
27+
for (const [attr] of Object.entries(binding.modifiers)) {
28+
el.setAttribute(
29+
attr,
30+
vnode.context.$fluent.formatPattern(msg.attributes[attr], binding.value)
31+
)
32+
}
1733
}
1834
}

src/fluent-vue.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
1-
import { FluentVueOptions } from '../types'
1+
import { FluentVueObject, FluentVueOptions } from '../types'
22
import { Vue, VueConstructor } from 'vue/types/vue'
33
import { warn } from './util/warn'
4+
import { Pattern } from '@fluent/bundle'
45

5-
export default class FluentVue {
6+
export default class FluentVue implements FluentVueObject {
67
private options: FluentVueOptions
78
static install: (vue: VueConstructor<Vue>) => void
89

910
constructor(options: FluentVueOptions) {
1011
this.options = options
1112
}
1213

13-
format(key: string, value?: object): string {
14+
getMessage(key: string) {
1415
const message = this.options.bundle.getMessage(key)
1516

1617
if (message === undefined) {
1718
warn(false, `Could not find translation for key [${key}]`)
19+
return undefined
20+
}
21+
22+
return message
23+
}
24+
25+
formatPattern(message: Pattern, value?: object, errors?: string[]): string {
26+
return this.options.bundle.formatPattern(message, value, errors)
27+
}
28+
29+
format(key: string, value?: object): string {
30+
const message = this.getMessage(key)
31+
32+
if (message === undefined) {
1833
return key
1934
}
2035

2136
const errors: string[] = []
22-
const result = this.options.bundle.formatPattern(message.value, value, errors)
23-
37+
const result = this.formatPattern(message.value, value, errors)
2438
for (const error of errors) {
2539
warn(false, `Fluent error for key [${key}]: ${error}`)
2640
}

test/__snapshots__/directive.test.ts.snap

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`directive can translate DOM attributes 1`] = `<a href="/foo" aria-label="Localized aria">Hello John</a>`;
4+
35
exports[`directive can use parameters 1`] = `<a href="/foo">Hello John</a>`;
46

57
exports[`directive translates text content 1`] = `<a href="/foo">Link text</a>`;

test/directive.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,27 @@ describe('directive', () => {
8787
// Assert
8888
expect(mounted).toMatchSnapshot()
8989
})
90+
91+
it('can translate DOM attributes', () => {
92+
// Arrange
93+
bundle.addResource(
94+
new FluentResource(ftl`
95+
link = Hello {$name}
96+
.aria-label = Localized aria
97+
`)
98+
)
99+
100+
const component = {
101+
data: () => ({
102+
name: 'John'
103+
}),
104+
template: `<a v-t:link.aria-label="{ name }" href="/foo" aria-label="Fallback aria">Fallback text</a>`
105+
}
106+
107+
// Act
108+
const mounted = mount(component, options)
109+
110+
// Assert
111+
expect(mounted).toMatchSnapshot()
112+
})
90113
})

types/index.d.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { Vue } from 'vue/types/vue'
2-
import { FluentBundle } from '@fluent/bundle'
2+
import { FluentBundle, MessageInfo, Pattern } from '@fluent/bundle'
33

4-
export interface FluentVueObject {}
4+
export interface FluentVueObject {
5+
getMessage(key: string): MessageInfo | undefined
6+
formatPattern(message: Pattern, value?: object, errors?: string[]): string
7+
format(key: string, value?: object): string
8+
}
59

610
export interface FluentVueOptions {
711
bundle: FluentBundle

0 commit comments

Comments
 (0)