Localize Vaadin date pickers with moment.js
How to configure Vaadin’s i18n object with moment.js data
Vaadin provides one of the best web components for date pickers. The Vaadin component used to dependent on moment.js, a huge dependency from which it utilized only a tiny bit. Smartly, the Vaadin guys replaced the moment.js dependency with an interface to localize the date picker.
This is great news if you use a smaller, less powerful localization library: one dependency less! Yet, if your app depends on moment.js anyway: How to wire up the Vaadin localization?
[Optional] Typescript support
First, we defined the Typescript interfaces to describe the Vaadin i18n object (skip this if you use pure Javascript):
interface VaadinDate {
day: number;
month: number;
year: number;
}interface VaadinDatePickerI18n {
week: string;
calendar?: string;
clear: string;
today: string;
cancel: string;
firstDayOfWeek: number;
monthNames: string[];
weekdays: string[];
weekdaysShort: string[];
formatDate: (date: VaadinDate) => string;
formatTitle: (monthName: string, fullYear: string) => string;
parseDate: (dateString: string) => VaadinDate;
}
Vaadin i18n object creation
Next, we add a function to create the Vaadin i18n object for a specific locale:
import moment from 'moment';const DATE_FORMAT = 'l';function createI18n(locale: string): VaadinDatePickerI18n {
const localeData = moment.localeData(locale);
return {
cancel: 'Cancel',
clear: 'Clear',
firstDayOfWeek: localeData.firstDayOfWeek(),
monthNames: localeData.months(),
today: 'Today',
week: 'Week',
weekdays: localeData.weekdays(),
weekdaysShort: localeData.weekdaysShort(), formatDate: (date: VaadinDate) => {
return moment({
date: date.day,
month: date.month,
year: date.year,
})
.locale(locale!)
.format(DATE_FORMAT);
},
formatTitle: (monthName: string, fullYear: string) => `${monthName} ${fullYear}`,
parseDate: (dateString: string) => {
const date = moment(dateString, DATE_FORMAT, locale);
return {
day: date.date(),
month: date.month(),
year: date.year(),
};
},
};
}
Basically, we use moment.js localeData
to get the weekdays, month names, and the likes. For the conversion between formatted dates and Vaadin dates, we rely on moment.js date formatting and parsing.
There are two pitfalls to watch out for:
- Moment.js date parsing requires to use a format that moment.js can actually parse, e.g.
L
(like04/09/1986
) instead ofLL
(likeSeptember 4 1986
). - Moment.js calls the day of the month
date
while Vaadin calls itday
. Watch out!
Assign i18n object to Vaadin data picker
Assigning the Vaadin i18n object to the date picker is straight forward:
const datepicker = document.querySelector('vaadin-date-picker');
datepicker.i18n = createI18n('fr-FR');
To fully localize the app, listen to changes of your locale and then update the i18n object accordingly. For example, with LitElement this would look like:
protected updated(changedProperties: Map<string, any>) {
if (changedProperties.has('locale') && this.locale) {
const dp = this.shadowRoot!.querySelector('vaadin-date-picker');
dp.i18n = createI18n(this.locale);
}
}
Happy coding!