modular_l10n 4.0.0
modular_l10n: ^4.0.0 copied to clipboard
Lightweight locale utilities for Flutter with RTL detection, locale parsing, display names for 70+ languages. Works standalone or with Modular Flutter L10n extension.
4.0.0 #
A correctness release for the CLDR data. Several languages were returning the
wrong plural category, and parseLocale could throw on input it documented as
safe. Everything below is now covered by tests — the package previously shipped
none.
Major only because of the PluralRuleGroup rename below. If you call
LocaleUtils.getPluralCategory() (or locale.getPluralCategory()) and never
reference PluralRuleGroup directly, the upgrade is a version bump.
Breaking #
-
PluralRuleGroupmembers renamed and split, so each group names the rule it implements rather than a language family:Removed Replacement slavic3FormslavicRussianslavic3FormAltslavicPolishcelticirishandwelsh— different rules, now separatesemitichebrew— bosnianCroatianSerbian(new)pluralRuleGroupsis remapped to match. Only code that switches onPluralRuleGroupdirectly needs changing. -
Some locales now return a different
PluralCategory. These are the bug fixes below, not behaviour changes — but if you have golden tests or translation tables keyed on the old (incorrect) categories, they will need updating. Affected:hr,sr,bs,ka,az,kk,uz,ky,tk,tg,ga,cy,he, and any fractional count inru,uk,be,pl,cs,sk,ar. -
kuis no longer reported as RTL. Bare Kurdish defaults to Kurmanji, written in Latin script left-to-right; only Sorani (ckb) uses the Arabic script. If you relied onisRtl(Locale('ku')), switch tockb. -
parseLocalereturnsLocale('und')for unparseable input instead of constructing aLocalewith an empty language code (which asserted in debug builds). Three-part tags whose second subtag is not a known script now drop the trailing subtag rather than mis-assigning it.
Fixed — plural rules #
Every correction below is now covered by a table-driven test transcribed from the
CLDR plural-rule charts (test/plurals_test.dart).
- Croatian, Serbian, and Bosnian no longer return
PluralCategory.many. They were mapped to the Russian rule set, whose fallthrough ismany— a category none of the three languages has. They now use a dedicatedbosnianCroatianSerbiangroup with CLDR's one / few / other. - Seven languages are no longer treated as having no plural form.
ka,az,kk,uz,ky,tk, andtgwere grouped with Chinese and Japanese, sogetPluralCategory(locale, 1)returnedotherand callers selected the plural form for a count of one. All seven have CLDR's one / other. - Fractional counts follow the CLDR
voperand. The Slavic and Arabic rules calledn.toInt(), silently truncating.getPluralCategory(Locale('ru'), 1.5)returnedone; CLDR saysother. - Irish and Welsh have their own rules. They shared an approximate "celtic" group. Irish is now one / two / few (3–6) / many (7–10) / other, and Welsh zero / one / two / few (3) / many (6) / other — previously neither could return
many, and Irishfewfired only at exactly 3. - Hebrew returns
twofor 2. It was mapped to a two-form group that only produced one / other.
Fixed — locale parsing #
parseLocaleno longer throws on empty or malformed input.Localeasserts on empty subtags, soparseLocale('')andparseLocale('en__US')crashed in debug builds despite the documented promise to degrade gracefully. Empty segments are dropped and unparseable input returnsLocale('und').- Three-part tags are no longer assumed to be
lang_Script_COUNTRY.en_US_POSIXproducedscriptCode: 'US',countryCode: 'POSIX'. The second subtag is now checked against the known script codes before being treated as one, and UN M.49 numeric regions such ases_419are recognised. normalizeLocaletitle-cases script codes, sozh_hans_cnnormalizes tozh_Hans_CN.
Fixed — RTL #
kuis no longer reported as right-to-left. Bare Kurdish defaults to Kurmanji, written in Latin script LTR; only Sorani (ckb, already listed) uses the Arabic script. Treatingkuas RTL flipped the layout for most Kurdish speakers. Addednqo(N'Ko).
Fixed — docs and packaging #
- Library docs no longer show
ML.current.locale, which the generated class does not expose; the working call isLocalizations.localeOf(context).textDirection. - Removed a dangling dartdoc reference in
rtl_languages.dartthat produced an unresolved-reference warning and cost pub.dev analysis points. - The example is pinned to the same
flutter_lintsmajor as the package (was^3.0.0against the package's^4.0.0) and its generated code has been regenerated — it was still the v2 shape (S,initializeMessages), including the pre-fix plural handling that rendered raw ICU text.
Added #
test/— 57 tests. Plural categories per CLDR, locale parsing and normalization edge cases, best-match resolution, RTL detection, display names, and validation. The package previously shipped none.
3.0.0 #
Major release — expanded language coverage, new metadata APIs, and a modular file structure. Fully backward compatible with v2.0.0.
Language Coverage (Phase 1) #
- Expanded from 75 to 177 languages (English names + native names)
- Added all missing ISO 639-1 languages across European, African, South Asian, Southeast Asian, Pacific, Middle Eastern, Caucasus, and other language groups
- RTL language set expanded from 10 to 16 languages (added Aramaic, Central Kurdish/Sorani, Khowar, Kashmiri, Syriac, Balochi)
- Script code recognition expanded from 15 to 35 script codes (added Gurmukhi, Gujarati, Tamil, Telugu, Kannada, Malayalam, Sinhala, Myanmar, Khmer, Lao, Tibetan, Mongolian, Canadian Syllabics, Cherokee, Tifinagh, N'Ko, Syriac, Thaana, and more)
New Models (Phase 2, 4, 8) #
LocaleInfo— bundlesenglishName,nativeName,textDirection,scriptCode, andcountryCodefor any localeNumberFormatInfo— decimal separator, grouping separator, percent sign, and numeral system per localeWritingSystemInfo—hasUpperCase,isLogographic,usesWordSpaces,isAbugida,isRtl- New enums:
PluralCategory,NumeralSystem,CalendarSystem,DateOrder
New APIs on LocaleUtils #
getLocaleInfo(locale)→LocaleInfogetCountryName(code)→String?— ISO 3166-1 country code to English name (~150 countries)getFullDisplayName(locale)→String— e.g."Arabic (Egypt)"getFullNativeDisplayName(locale)→String— e.g."العربية (مصر)"getPluralCategory(locale, n)→PluralCategory— CLDR plural rules for all major languagesgetNumberFormat(locale)→NumberFormatInfogetNumeralSystem(locale)→NumeralSystemgetFirstDayOfWeek(locale)→int(1=Monday, 6=Saturday, 7=Sunday)getDefaultCalendar(locale)→CalendarSystemgetDateOrder(locale)→DateOrdergetRelatedLocales(locale)→List<Locale>— mutually intelligible language fallbacksisValidLanguageCode(code)→boolisValidCountryCode(code)→boolisValidLocale(locale)→boolnormalizeLocale(string)→Locale— handles case normalization and deprecated code mappinggetWritingSystem(locale)→WritingSystemInfogetTextExpansionFactor(locale)→double— approximate UI text expansion relative to EnglishfindBestMatchgains an optionaluseFallbackChainparameter for intelligent language fallbacks (e.g. Norwegian Bokmål → Norwegian → Danish)
New Extensions on Locale #
All new LocaleUtils methods are also available as extension getters/methods on Locale: countryDisplayName, fullDisplayName, fullNativeDisplayName, pluralCategory(n), numeralSystem, firstDayOfWeek, calendarSystem, dateOrder, writingSystem, textExpansionFactor, isValid
Validation & Normalization (Phase 7) #
- Deprecated ISO 639 code mapping:
iw→he,in→id,jw→jv,ji→yi,mo→ro,sh→sr,tl→fil
Code Organization (Phase 9) #
- Package split into a modular file structure under
lib/src/with separatedata/,models/, and logic files - All existing APIs preserved with identical signatures — no breaking changes
2.0.0 #
- Simplified the package and removed the LocaleProvider widget
1.0.2 #
- Reverted context.currentLocale / context.isLocale() back to LocaleProvider.of(this) — no longer needed for the fix
1.0.1 #
- Added
onBeforeLocaleChangedcallback to allow custom logic before locale changes occur
1.0.0 #
- Initial release of modular_l10n package
- Modular approach to Flutter localization
- RTL support
- Locale utilities
- Cross-project module reuse