Skip to content

Commit 16580b4

Browse files
committed
fix: allow labels to be localized with names closes #4268
1 parent 675c63f commit 16580b4

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

.changeset/real-dryers-drop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@vee-validate/i18n': patch
3+
---
4+
5+
fix: allow labels to be localized with names closes #4268

packages/i18n/src/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,18 @@ class Dictionary {
3333
return this.container[locale]?.fields?.[field]?._default || this.container[locale]?.messages?._default;
3434
}
3535

36+
public resolveLabel(locale: string, name: string, label?: string): string {
37+
if (label) {
38+
return this.container[locale]?.names?.[label] || label;
39+
}
40+
41+
return this.container[locale]?.names?.[name] || name;
42+
}
43+
3644
public format(locale: string, ctx: FieldValidationMetaInfo) {
3745
let message!: ValidationMessageTemplate | undefined;
3846
const { rule, form, label, name } = ctx;
39-
const fieldName = label || this.container[locale]?.names?.[name] || name;
47+
const fieldName = this.resolveLabel(locale, name, label);
4048

4149
if (!rule) {
4250
message = this.getLocaleDefault(locale, name) || `${fieldName} is not valid`;

packages/i18n/tests/index.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,41 @@ test('can define labels or names for fields', async () => {
193193
expect(errors[1].textContent).toContain('Second test is required');
194194
});
195195

196+
test('can define localized labels for fields', async () => {
197+
configure({
198+
generateMessage: localize('en', {
199+
messages: { required: '{field} is required' },
200+
names: {
201+
first: 'First test',
202+
second: 'Second test',
203+
},
204+
}),
205+
});
206+
207+
const wrapper = mountWithHoc({
208+
template: `
209+
<div>
210+
<Field name="first.value" label="first" :validateOnMount="true" rules="required" v-slot="{ field, errors }">
211+
<input v-bind="field" type="text">
212+
<span class="error">{{ errors[0] }}</span>
213+
</Field>
214+
215+
<Field name="second.value" label="second" :validateOnMount="true" rules="required" v-slot="{ field, errors }">
216+
<input v-bind="field" type="text">
217+
<span class="error">{{ errors[0] }}</span>
218+
</Field>
219+
</div>
220+
`,
221+
});
222+
223+
await flushPromises();
224+
const errors = wrapper.$el.querySelectorAll('.error');
225+
expect(errors).toHaveLength(2);
226+
227+
expect(errors[0].textContent).toContain('First test is required');
228+
expect(errors[1].textContent).toContain('Second test is required');
229+
});
230+
196231
// #4164
197232
test('can define labels or names for fields with useField', async () => {
198233
let errorMessage!: Ref<string | undefined>;

0 commit comments

Comments
 (0)