Skip to content

Commit fa4c22a

Browse files
authored
feat: backport build-in components to vue-i18n-bridge from vue-i18n-next (#811)
* feat: backport build-in components from vue-i18n-next * updates
1 parent 68985fe commit fa4c22a

File tree

23 files changed

+584
-156
lines changed

23 files changed

+584
-156
lines changed

docs/guide/migration/ways.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ Vue.use(VueI18n, { bridge: true })
164164
### Limitations
165165
- In Legacy API mode, You **cannot use [new message format syntax](https://vue-i18n.intlify.dev/guide/essentials/syntax.html)** by porting from `vue-i18n-next`
166166
- it use possible only Composition API mode
167-
- In Composition API mode, If you can use the following components, these can be referenced i18n resources, **only globally**
168-
- i18n functional component `<i18n>`
169-
- i18n-n functional component `<i18n-n>`
167+
- In Legacy API mode, You **cannot use back-ported components that are following components** by porting from `vue-i18n-next`
168+
- Translation components: `<i18n-t>`
169+
- DateTime format components: `<i18n-d>`
170+
- Number format components: `<i18n-n>`
170171

171172
### Explanation of Different Builds
172173
In the [dist/ directory of the npm package](https://unpkg.com/browse/[email protected]/dist/) you will find many different builds of `vue-i18n-bridge`. Here is an overview of which dist file should be used depending on the use-case.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
describe(`bridge: datetime format component`, () => {
2+
beforeAll(async () => {
3+
await page.goto(
4+
`http://localhost:8080/examples/bridge/composition/components/datetime-format.html`
5+
)
6+
})
7+
8+
test('rendering', async () => {
9+
await expect(page).toMatch(
10+
/([1-9]|1[0-2])\/([1-9]|[12]\d|3[01])\/([12]\d{3})/
11+
)
12+
await expect(page).toMatch(
13+
/(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/([12]\d{3}), (0[0-9]|1[0-2]):([0-5][0-9]):([0-5][0-9]) (AM|PM)/
14+
)
15+
await expect(page).toMatch(
16+
/([1-9]|1[0-2])([1-9]|1[0-2])([1-9]|[1-3][0-9])(||||||) (|)([0-9]|1[0-2]):([0-5][0-9]):([0-5][0-9]) /
17+
)
18+
await expect(page).toMatch(
19+
/R([1-9]|1[0-2])([1-9]|1[0-2])([1-9]|[1-3][0-9])(||||||) (|)([0-9]|1[0-2]):([0-5][0-9]):([0-5][0-9]) /
20+
)
21+
})
22+
})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
describe(`bridge: number format component`, () => {
2+
beforeAll(async () => {
3+
await page.goto(
4+
`http://localhost:8080/examples/bridge/composition/components/number-format.html`
5+
)
6+
})
7+
8+
test('rendering', async () => {
9+
await expect(page).toMatch('100')
10+
await expect(page).toMatch('$100.00')
11+
await expect(page).toMatch('¥100')
12+
await expect(page).toMatch('€1,234.00')
13+
})
14+
})
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
describe(`bridge: translation component`, () => {
2+
beforeAll(async () => {
3+
await page.goto(
4+
`http://localhost:8080/examples/bridge/composition/components/translation.html`
5+
)
6+
})
7+
8+
test('rendering', async () => {
9+
await expect(page).toMatch('こんにちは、kazupon!')
10+
await expect(page).toMatch('hello, English!')
11+
await expect(page).toMatch('こんにちは、かずぽん! ごきげんいかが?')
12+
await expect(page).toMatch('no bananas')
13+
})
14+
15+
test('change quantity', async () => {
16+
await page.select('#app select', '1')
17+
await expect(page).toMatch('1 banana')
18+
await page.select('#app select', '2')
19+
await expect(page).toMatch('2 bananas')
20+
await page.select('#app select', '0')
21+
await expect(page).toMatch('no bananas')
22+
})
23+
})
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>DatetimeFormat component examples</title>
6+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
7+
<script src="https://unpkg.com/vue-i18n@8/dist/vue-i18n.js"></script>
8+
<script src="https://cdn.jsdelivr.net/npm/@vue/[email protected]"></script>
9+
<script src="../../../../packages/vue-i18n-bridge/dist/vue-i18n-bridge.global.js"></script>
10+
</head>
11+
<body>
12+
<h1>DatetimeFormat component examples</h1>
13+
14+
<div id="app">
15+
<h2>basic usages:</h2>
16+
<i18n-d tag="p" :value="new Date()"></i18n-d>
17+
<i18n-d tag="p" :value="new Date()" format="long"></i18n-d>
18+
<i18n-d
19+
tag="p"
20+
:value="new Date()"
21+
format="long"
22+
locale="ja-JP-u-ca-japanese"
23+
></i18n-d>
24+
25+
<h2>slot usages:</h2>
26+
<i18n-d
27+
:value="new Date()"
28+
locale="ja-JP-u-ca-japanese"
29+
:format="{ key: 'long', era: 'narrow' }"
30+
>
31+
<template #era="props"
32+
><span style="color: green">{{ props.era }}</span></template
33+
>
34+
</i18n-d>
35+
</div>
36+
<script>
37+
const { createApp, ref } = VueCompositionAPI
38+
const { createI18n, useI18n } = VueI18nBridge
39+
40+
Vue.use(VueCompositionAPI)
41+
Vue.use(VueI18n, { bridge: true })
42+
43+
const i18n = createI18n(
44+
{
45+
legacy: false,
46+
locale: 'en-US',
47+
datetimeFormats: {
48+
'en-US': {
49+
long: {
50+
year: 'numeric',
51+
month: '2-digit',
52+
day: '2-digit',
53+
hour: '2-digit',
54+
minute: '2-digit',
55+
second: '2-digit'
56+
}
57+
},
58+
'ja-JP-u-ca-japanese': {
59+
long: {
60+
era: 'long',
61+
year: 'numeric',
62+
month: 'numeric',
63+
day: 'numeric',
64+
hour: 'numeric',
65+
minute: 'numeric',
66+
second: 'numeric',
67+
weekday: 'long',
68+
hour12: true,
69+
timeZoneName: 'long'
70+
}
71+
}
72+
}
73+
},
74+
VueI18n
75+
)
76+
77+
const app = createApp({})
78+
app.use(i18n)
79+
app.mount('#app')
80+
</script>
81+
</body>
82+
</html>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>NumberFormat component examples</title>
6+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
7+
<script src="https://unpkg.com/vue-i18n@8/dist/vue-i18n.js"></script>
8+
<script src="https://cdn.jsdelivr.net/npm/@vue/[email protected]"></script>
9+
<script src="../../../../packages/vue-i18n-bridge/dist/vue-i18n-bridge.global.js"></script>
10+
</head>
11+
<body>
12+
<h1>NumberFormat component examples</h1>
13+
14+
<div id="app">
15+
<h2>basic usages:</h2>
16+
<i18n-n tag="p" :value="100"></i18n-n>
17+
<i18n-n tag="p" :value="100" format="currency"></i18n-n>
18+
<i18n-n tag="p" :value="100" format="currency" locale="ja-JP"></i18n-n>
19+
20+
<h2>slot usages:</h2>
21+
<i18n-n :value="1234" :format="{ key: 'currency', currency: 'EUR' }">
22+
<template #currency="props"
23+
><span style="color: green">{{ props.currency }}</span></template
24+
>
25+
<template #integer="props"
26+
><span style="font-weight: bold">{{ props.integer }}</span></template
27+
>
28+
<template #group="props"
29+
><span style="font-weight: bold">{{ props.group }}</span></template
30+
>
31+
<template #fraction="props"
32+
><span style="font-size: small">{{ props.fraction }}</span></template
33+
>
34+
</i18n-n>
35+
</div>
36+
<script>
37+
const { createApp, ref } = VueCompositionAPI
38+
const { createI18n, useI18n } = VueI18nBridge
39+
40+
Vue.use(VueCompositionAPI)
41+
Vue.use(VueI18n, { bridge: true })
42+
43+
const i18n = createI18n(
44+
{
45+
legacy: false,
46+
locale: 'en-US',
47+
numberFormats: {
48+
'en-US': {
49+
currency: {
50+
style: 'currency',
51+
currency: 'USD',
52+
currencyDisplay: 'symbol'
53+
},
54+
decimal: {
55+
style: 'decimal',
56+
useGrouping: false
57+
}
58+
},
59+
'ja-JP': {
60+
currency: {
61+
style: 'currency',
62+
currency: 'JPY',
63+
currencyDisplay: 'symbol'
64+
},
65+
numeric: {
66+
style: 'decimal',
67+
useGrouping: false
68+
},
69+
percent: {
70+
style: 'percent',
71+
useGrouping: false
72+
}
73+
}
74+
}
75+
},
76+
VueI18n
77+
)
78+
79+
const app = createApp({})
80+
app.use(i18n)
81+
app.mount('#app')
82+
</script>
83+
</body>
84+
</html>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Translation component example</title>
6+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
7+
<script src="https://unpkg.com/vue-i18n@8/dist/vue-i18n.js"></script>
8+
<script src="https://cdn.jsdelivr.net/npm/@vue/[email protected]"></script>
9+
<script src="../../../../packages/vue-i18n-bridge/dist/vue-i18n-bridge.global.js"></script>
10+
</head>
11+
<body>
12+
<h1>Translation component example</h1>
13+
14+
<div id="app">
15+
<h2>localize with slot contents:</h2>
16+
<i18n-t tag="p" class="name" keypath="message.named">
17+
<template #name>
18+
<span>kazupon</span>
19+
</template>
20+
</i18n-t>
21+
22+
<h2>localize with DOM contents:</h2>
23+
<i18n-t keypath="message.list" locale="en">
24+
<span class="lang"
25+
>{{ t('message.language', {}, { locale: 'en' }) }}</span
26+
>
27+
</i18n-t>
28+
29+
<h2>localize with using linked:</h2>
30+
<i18n-t keypath="message.linked">
31+
<template #name>
32+
<span>かずぽん</span>
33+
</template>
34+
</i18n-t>
35+
36+
<h2>localize with using plural:</h2>
37+
<form>
38+
<label for="locale-select"
39+
>{{ t('message.quantity', {}, { locale: 'en' }) }}</label
40+
>
41+
<select id="locale-select" v-model="count">
42+
<option value="0">0</option>
43+
<option value="1">1</option>
44+
<option value="2">2</option>
45+
</select>
46+
</form>
47+
<i18n-t keypath="message.plural" locale="en" :plural="count">
48+
<template #n>
49+
<b>{{ count }}</b>
50+
</template>
51+
</i18n-t>
52+
</div>
53+
<script>
54+
const { createApp, ref } = VueCompositionAPI
55+
const { createI18n, useI18n } = VueI18nBridge
56+
57+
Vue.use(VueCompositionAPI)
58+
Vue.use(VueI18n, { bridge: true })
59+
60+
const i18n = createI18n(
61+
{
62+
legacy: false,
63+
locale: 'ja',
64+
messages: {
65+
en: {
66+
message: {
67+
language: 'English',
68+
quantity: 'Quantity',
69+
list: 'hello, {0}!',
70+
named: 'hello, {name}!',
71+
linked: '@:message.named How are you?',
72+
plural: 'no bananas | {n} banana | {n} bananas'
73+
}
74+
},
75+
ja: {
76+
message: {
77+
language: '日本語',
78+
list: 'こんにちは、{0}!',
79+
named: 'こんにちは、{name}!',
80+
linked: '@:message.named ごきげんいかが?'
81+
}
82+
}
83+
}
84+
},
85+
VueI18n
86+
)
87+
88+
const app = createApp({
89+
setup() {
90+
const { t } = useI18n()
91+
const count = ref(0)
92+
return { count, t }
93+
}
94+
})
95+
app.use(i18n)
96+
app.mount('#app')
97+
</script>
98+
</body>
99+
</html>

packages/vue-i18n-bridge/src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ export {
9595
UseI18nOptions,
9696
ExportedGlobalComposer
9797
} from '../../vue-i18n-core/src/i18n'
98+
export {
99+
Translation,
100+
TranslationProps,
101+
BaseFormatProps,
102+
DatetimeFormat,
103+
DatetimeFormatProps,
104+
NumberFormat,
105+
NumberFormatProps
106+
} from '../../vue-i18n-core/src/components'
98107
export { I18nPluginOptions } from '../../vue-i18n-core/src/plugin'
99108
export { VERSION } from './../../vue-i18n-core/src/misc'
100109

packages/vue-i18n-bridge/src/runtime.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ export {
9090
UseI18nOptions,
9191
ExportedGlobalComposer
9292
} from '../../vue-i18n-core/src/i18n'
93+
export {
94+
Translation,
95+
TranslationProps,
96+
BaseFormatProps,
97+
DatetimeFormat,
98+
DatetimeFormatProps,
99+
NumberFormat,
100+
NumberFormatProps
101+
} from '../../vue-i18n-core/src/components'
93102
export { I18nPluginOptions } from '../../vue-i18n-core/src/plugin'
94103
export { VERSION } from './../../vue-i18n-core/src/misc'
95104

0 commit comments

Comments
 (0)