Skip to content

Locales ​

Eight languages are built in. English and German are accepted by default; the others are accepted once you pass them in locales. Two props control languages:

  • locales: which unit names and separator words the parser accepts. Default [en, de].
  • locale: the language of the normalized text and the error messages. Defaults to the first of locales.
vue
<script setup lang="ts">
import { de, en } from 'semantic-duration-input'
</script>

<template>
  <DurationInput v-model="minutes" :locales="[de, en]" display-style="long" />
</template>
v-model: 135

Built-in locales ​

ExportLanguageInputNormalized (short / long)
enEnglish2 hours and 15 min2h 15min / 2 hours 15 minutes
deGerman2 Std. und 15 Min.2h 15min / 2 Stunden 15 Minuten
esSpanish2 horas y 15 minutos2h 15min / 2 horas 15 minutos
frFrench1 j et 2 heures1j 2h / 1 jour 2 heures
ptPortuguese2 horas e 15 minutos2h 15min / 2 horas 15 minutos
hiHindi2 घंटे और 15 मिनट2घं 15मि / 2 घंटे 15 मिनट
arArabic2 ساعة و 15 دقيقة, ٢ ساعة و ١٥ دقيقة2س 15د / 2 ساعتان 15 دقيقة
zhChinese (Mandarin)2小时15分钟, 2個小時15分鐘2小时 15分钟 / 2 小时 15 分钟

The unit names of each locale are listed in Syntax. Each built-in locale also accepts h, m, min, s, d and w, and every locale accepts native digits (٣٠, ३०, 30).

  • Portuguese messages use Brazilian wording. Chinese labels and messages are Simplified, and Traditional unit names are accepted too.
  • Bundlers leave out the locales you don't import.
  • Accepting a locale doesn't change the language of the text: set locale, or put that locale first in locales.
vue
<DurationInput v-model="minutes" :locales="[fr, en]" display-style="long" />
v-model: 1590

Right-to-left ​

For Arabic, set dir="rtl" on the page or on an element around the field. dir on <DurationInput> itself only reaches the <input>, not the leading and trailing content or the preview.

vue
<div dir="rtl">
  <DurationInput v-model="minutes" :locales="[ar, en]" />
</div>

Display ​

PropEffect
displayStyle'short': 1d 2h 30min, 'long': 1 day 2 hours 30 minutes
displayUnitsUnits the normalized text is built from. Default: days, hours and minutes (plus seconds with precision="second"). Add 'week' to get 1w 2d, or pass only ['hour'] to get 1.5h.

Custom locales ​

A locale is a plain object with unit aliases, separator words, labels for the normalized text and error messages:

ts
import { defineLocale, en } from 'semantic-duration-input'

const hu = defineLocale({
  ...en,
  code: 'hu',
  aliases: { minute: ['p', 'perc'], hour: ['ó', 'óra'], day: ['nap'], week: ['hét'] },
  separators: ['és'],
  labels: undefined, // use Intl.DurationFormat for the normalized text where available
  messages: { ...en.messages, empty: 'Adj meg egy időtartamot.' },
})
vue
<DurationInput v-model="minutes" :locales="[hu, en]" :locale="hu" />
  • Aliases are matched case-insensitively and in Unicode normal form (NFC), so composed and decomposed letters like फ़ match. Combining marks (Devanagari vowel signs, Arabic diacritics) are part of a name. If two active locales use the same alias for different units, the later locale in locales wins.

  • Separators are extra words that may join parts, like and. The symbols , + & always work.

  • Labels: without labels, the text is formatted with Intl.DurationFormat using code, falling back to English labels where that API isn't available. Make sure the parser can read what the formatter writes: add the words it produces to aliases and separators.

  • Plural forms: a long label is [one, other], picked by the plural rules of code (Intl.PluralRules): French writes 0 minute and 2 minutes. For languages with more forms, pass a PluralLabels object instead. Missing categories use other:

    ts
    long: {
      ...en.labels!.long,
      day: { one: 'diwrnod', two: 'ddiwrnod', other: 'diwrnod' }, // Welsh
    }
  • Messages may use {min}, {max}, {token} and {suggestion}. See Error messages for the keys.

Locales can also name and label custom units.

To add aliases to a built-in language, spread it:

ts
const myEn = defineLocale({ ...en, aliases: { ...en.aliases, hour: [...en.aliases.hour!, 'hs'] } })

Released under the MIT License.