Overview
app-datepicker uses the native Intl.DateTimeFormat API for internationalization, providing automatic localization for over 100 locales without requiring additional language packs.
The component leverages the browser’s built-in internationalization capabilities, ensuring consistent formatting across your application.
Setting the Locale
Basic Locale Configuration
Set the locale property to any valid BCP 47 language tag:
// American English (default)
picker . locale = 'en-US' ;
// British English
picker . locale = 'en-GB' ;
// Traditional Chinese (Taiwan)
picker . locale = 'zh-TW' ;
// German (Germany)
picker . locale = 'de-DE' ;
// Japanese
picker . locale = 'ja-JP' ;
// Arabic (Saudi Arabia)
picker . locale = 'ar-SA' ;
Auto-Detection
If no locale is specified, the component automatically uses the browser’s locale:
// From src/mixins/date-picker-mixin.ts:20
// Default: DateTimeFormat().resolvedOptions().locale
Lit Template
JavaScript
HTML Attribute
import { html } from 'lit' ;
const template = html `
<app-date-picker locale="fr-FR"></app-date-picker>
` ;
const picker = document . querySelector ( 'app-date-picker' );
picker . locale = 'es-ES' ;
< app-date-picker locale = "it-IT" ></ app-date-picker >
The locale affects how dates are displayed throughout the component:
// American English
picker . locale = 'en-US' ;
// Selected: Mar 15, 2024
// Month/Year: March 2024
// Weekday: Mon, Tue, Wed...
The component creates multiple Intl.DateTimeFormat instances for different parts of the UI. Here’s how they’re configured:
View formatter implementation
The component uses these formatters internally:
Formatter Purpose Example (en-US) Example (ja-JP) dateFormatCalendar day cells Mar 15, Fri 3月15日(金) dayFormatDay number only 15 15 fullDateFormatFull date with year Mar 15, 2024 2024年3月15日 longMonthYearFormatHeader display March 2024 2024年3月 longWeekdayFormatAccessibility labels Friday 金曜日 narrowWeekdayFormatWeekday headers F 金 yearFormatYear grid 2024 2024年
First Day of Week
Customize which day starts the week:
// Sunday (default: 0)
picker . firstDayOfWeek = 0 ;
// Monday (common in Europe)
picker . firstDayOfWeek = 1 ;
// Saturday (common in Middle East)
picker . firstDayOfWeek = 6 ;
Sunday Start
Monday Start
Saturday Start
// American convention
picker . firstDayOfWeek = 0 ;
// Week: Sun Mon Tue Wed Thu Fri Sat
// ISO 8601 / European convention
picker . firstDayOfWeek = 1 ;
// Week: Mon Tue Wed Thu Fri Sat Sun
// Middle Eastern convention
picker . firstDayOfWeek = 6 ;
// Week: Sat Sun Mon Tue Wed Thu Fri
The value is 0 for Sunday through 6 for Saturday, matching JavaScript’s Date.getDay() convention.
Customizing Labels
Override default UI labels for complete localization:
Navigation Labels
picker . nextMonthLabel = 'Nächster Monat' ; // Default: 'Next month'
picker . previousMonthLabel = 'Vorheriger Monat' ; // Default: 'Previous month'
picker . chooseMonthLabel = 'Monat wählen' ; // Default: 'Choose month'
picker . chooseYearLabel = 'Jahr wählen' ; // Default: 'Choose year'
View default label constants
From src/constants.ts:6-14: export const labelChooseMonth = 'Choose month' as const ;
export const labelChooseYear = 'Choose year' as const ;
export const labelNextMonth = 'Next month' as const ;
export const labelPreviousMonth = 'Previous month' as const ;
export const labelSelectedDate = 'Selected date' as const ;
export const labelSelectedYear = 'Selected year' as const ;
export const labelShortWeek = 'Wk' as const ;
export const labelToday = 'Today' as const ;
export const labelToyear = 'Toyear' as const ;
export const labelWeek = 'Week' as const ;
Date Labels
picker . todayLabel = 'Aujourd \' hui' ; // Default: 'Today'
picker . selectedDateLabel = 'Date sélectionnée' ; // Default: 'Selected date'
picker . selectedYearLabel = 'Année sélectionnée' ; // Default: 'Selected year'
Week Number Labels
picker . weekLabel = 'Semaine' ; // Default: 'Week'
picker . shortWeekLabel = 'Sem' ; // Default: 'Wk'
picker . weekNumberTemplate = 'Semaine %s' ; // Default: 'Week %s'
Complete Localization Example
Here’s a fully localized French date picker:
import { LitElement , html } from 'lit' ;
import { customElement } from 'lit/decorators.js' ;
import 'app-datepicker/dist/date-picker/app-date-picker.js' ;
@ customElement ( 'french-date-picker' )
export class FrenchDatePicker extends LitElement {
render () {
return html `
<app-date-picker
locale="fr-FR"
.firstDayOfWeek= ${ 1 }
.showWeekNumber= ${ true }
nextMonthLabel="Mois suivant"
previousMonthLabel="Mois précédent"
chooseMonthLabel="Choisir le mois"
chooseYearLabel="Choisir l'année"
todayLabel="Aujourd'hui"
selectedDateLabel="Date sélectionnée"
selectedYearLabel="Année sélectionnée"
weekLabel="Semaine"
shortWeekLabel="Sem"
weekNumberTemplate="Semaine %s"
></app-date-picker>
` ;
}
}
Localization with Dialog
The dialog component includes additional labels for action buttons:
import { html } from 'lit' ;
const germanDialog = html `
<app-date-picker-dialog
locale="de-DE"
confirmLabel="Bestätigen"
dismissLabel="Abbrechen"
resetLabel="Zurücksetzen"
chooseMonthLabel="Monat wählen"
chooseYearLabel="Jahr wählen"
></app-date-picker-dialog>
` ;
The input component includes a clear button label:
import { html } from 'lit' ;
const spanishInput = html `
<app-date-picker-input
locale="es-ES"
label="Seleccionar fecha"
clearLabel="Limpiar"
></app-date-picker-input>
` ;
From src/date-picker-input/constants.ts:3: export const appDatePickerInputClearLabel = 'Clear' as const ;
Dynamic Locale Switching
Change locale dynamically at runtime:
import { LitElement , html } from 'lit' ;
import { customElement , state } from 'lit/decorators.js' ;
@ customElement ( 'multi-locale-picker' )
export class MultiLocalePicker extends LitElement {
@ state ()
private locale = 'en-US' ;
private locales = [
{ code: 'en-US' , name: 'English (US)' },
{ code: 'zh-TW' , name: '繁體中文' },
{ code: 'ja-JP' , name: '日本語' },
{ code: 'de-DE' , name: 'Deutsch' },
];
render () {
return html `
<select @change= ${ this . handleLocaleChange } >
${ this . locales . map ( l => html `
<option value= ${ l . code } ?selected= ${ l . code === this . locale } >
${ l . name }
</option>
` ) }
</select>
<app-date-picker
.locale= ${ this . locale }
.firstDayOfWeek= ${ this . getFirstDayOfWeek () }
></app-date-picker>
` ;
}
private handleLocaleChange ( e : Event ) {
this . locale = ( e . target as HTMLSelectElement ). value ;
}
private getFirstDayOfWeek () : number {
// Monday for most European locales
if ([ 'de-DE' , 'fr-FR' , 'it-IT' ]. includes ( this . locale )) {
return 1 ;
}
// Sunday for US and others
return 0 ;
}
}
Testing Localization
Here’s an example from the test suite showing locale behavior:
From src/__tests__/date-picker/app-date-picker.test.ts:109-141: it . each <{
$_locale : string ,
$_yearMonthLabel : string ;
locale : string | undefined ,
}>([
{
$_locale: Intl . DateTimeFormat (). resolvedOptions (). locale ,
$_yearMonthLabel: 'February 2020' ,
locale: undefined ,
},
{
$_locale: 'zh-TW' ,
$_yearMonthLabel: '2020年2月' ,
locale: 'zh-TW' ,
},
])(\ `renders (locale=$locale) \` , async ({
$_locale,
$_yearMonthLabel,
locale,
}) => {
const testValue = '2020-02-02';
const el = await fixture<AppDatePicker>(
html \` <app-date-picker .locale= \$ {locale as never} min="1970-01-01" value= \$ {testValue}></app-date-picker> \`
);
const selectedYearMonth = el.query<HTMLParagraphElement>(
elementSelectors.selectedYearMonth
);
expect(el.locale).toBe($_locale);
expect(el.value).toBe(testValue);
expect(selectedYearMonth).toHaveTextContent($_yearMonthLabel);
});
Best Practices
Always specify locale explicitly for consistent behavior across different browsers and user settings.
Match firstDayOfWeek to locale conventions for the best user experience (e.g., Monday for European locales).
Changing the locale after component initialization will re-render the calendar. Avoid frequent locale changes for better performance.
Next Steps
Styling Customize the visual appearance of the date picker
Advanced Features Configure week numbers, disabled dates, and more