Localize Vaadin date pickers with moment.js

How to configure Vaadin’s i18n object with moment.js data

Ronny Roeller
NEXT Engineering
2 min readSep 5, 2019

--

Localized Vaadin date picker

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 (like 04/09/1986) instead of LL (like September 4 1986).
  • Moment.js calls the day of the month date while Vaadin calls it day. 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!

--

--

Ronny Roeller
NEXT Engineering

CTO at nextapp.co # Product discovery platform for high performing teams that bring their customers into every decision