Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FluentUI Widgets Localization Support #216

Merged
merged 23 commits into from Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@ Date format: DD/MM/YYYY

- Improves `icons.dart` formatting and its generation.
- Fix: [#207](https://github.com/bdlukaa/fluent_ui/pull/207) FilledButton disabled foreground
- NEW: Widgets translated into multiple languages: [#216](https://github.com/bdlukaa/fluent_ui/pull/216)
- Add `useInheritedMediaQuery` property to `FluentApp` [#211](https://github.com/bdlukaa/fluent_ui/pull/211)

## [3.9.1] - Input Update - [25/02/2022]

Expand Down
30 changes: 30 additions & 0 deletions README.md
Expand Up @@ -89,7 +89,9 @@ Unofficial implementation of Fluent UI for [Flutter](flutter.dev). It's written
- [Pill Button Bar](#pill-button-bar)
- [Snackbar](#snackbar)
- [Equivalents with the material library](#equivalents-with-the-material-library)
- [Localization](#Localization)
- [Contribution](#contribution)
-[Contributing new localizations](#contributing-new-localizations)
- [Acknowledgements](#acknowledgements)

## Motivation
Expand Down Expand Up @@ -1681,12 +1683,40 @@ The list of equivalents between this library and `flutter/material.dart`
| - | PillButtonBar |
| ExpansionPanel | Expander |

## Localization

FluentUI widgets currently supports out-of-the-box an wide number of languages, including:

- English
- French
- German
- Hindi
- Portuguese
- Russian
- Simplified Chinese
- Spanish

## Contribution

Feel free to [file an issue](https://github.com/bdlukaa/fluent_ui/issues/new) if you find a problem or [make pull requests](https://github.com/bdlukaa/fluent_ui/pulls).

All contributions are welcome :)

### Contributing new localizations

In [PR#216](https://github.com/bdlukaa/fluent_ui/pull/216) we added support for new localizations in FluentUI Widgets.

If you want to contribute adding new localizations please follow this steps:

- [Fork the repo](https://github.com/bdlukaa/fluent_ui/fork)
- Copy `lib/l10n/intl_en.arb` file into `lib/l10n` folder with a new language code, following [this list of ISO 859-1 codes](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
- Update the contents in the newly created file. Specially, please update the `@locale` value with the corresponding ISO code.
- Then update the `localization.dart:defaultSupportedLocales` list, adding an entry for each new locale
- If your IDE doesn't have any of the `intl` plugins ([Intl plugin for Android Studio/IntelliJ](https://plugins.jetbrains.com/plugin/13666-flutter-intl) / [Flutter Intl for VSCode](https://marketplace.visualstudio.com/items?itemName=localizely.flutter-intl) ) please run your project and code generation will take place.
- When you're done, [make a new pull request](https://github.com/bdlukaa/fluent_ui/pulls)

More about [Localization in the Flutter Official Documentation](https://docs.flutter.dev/development/accessibility-and-localization/internationalization)

### Acknowledgements

Irrespective of order, thanks to all the people below for contributing with the project. It means a lot to me :)
Expand Down
5 changes: 5 additions & 0 deletions example/pubspec.lock
Expand Up @@ -111,6 +111,11 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_localizations:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_native_splash:
dependency: "direct dev"
description:
Expand Down
90 changes: 90 additions & 0 deletions lib/generated/intl/messages_all.dart
@@ -0,0 +1,90 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that looks up messages for specific locales by
// delegating to the appropriate library.

// Ignore issues from commonly used lints in this file.
// ignore_for_file:implementation_imports, file_names, unnecessary_new
// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering
// ignore_for_file:argument_type_not_assignable, invalid_assignment
// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases
// ignore_for_file:comment_references

import 'dart:async';

import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
import 'package:intl/src/intl_helpers.dart';

import 'messages_de.dart' as messages_de;
import 'messages_en.dart' as messages_en;
import 'messages_es.dart' as messages_es;
import 'messages_fr.dart' as messages_fr;
import 'messages_hi.dart' as messages_hi;
import 'messages_pt.dart' as messages_pt;
import 'messages_ru.dart' as messages_ru;
import 'messages_zh.dart' as messages_zh;

typedef Future<dynamic> LibraryLoader();
Map<String, LibraryLoader> _deferredLibraries = {
'de': () => new Future.value(null),
'en': () => new Future.value(null),
'es': () => new Future.value(null),
'fr': () => new Future.value(null),
'hi': () => new Future.value(null),
'pt': () => new Future.value(null),
'ru': () => new Future.value(null),
'zh': () => new Future.value(null),
};

MessageLookupByLibrary? _findExact(String localeName) {
switch (localeName) {
case 'de':
return messages_de.messages;
case 'en':
return messages_en.messages;
case 'es':
return messages_es.messages;
case 'fr':
return messages_fr.messages;
case 'hi':
return messages_hi.messages;
case 'pt':
return messages_pt.messages;
case 'ru':
return messages_ru.messages;
case 'zh':
return messages_zh.messages;
default:
return null;
}
}

/// User programs should call this before using [localeName] for messages.
Future<bool> initializeMessages(String localeName) async {
var availableLocale = Intl.verifiedLocale(
localeName, (locale) => _deferredLibraries[locale] != null,
onFailure: (_) => null);
if (availableLocale == null) {
return new Future.value(false);
}
var lib = _deferredLibraries[availableLocale];
await (lib == null ? new Future.value(false) : lib());
initializeInternalMessageLookup(() => new CompositeMessageLookup());
messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor);
return new Future.value(true);
}

bool _messagesExistFor(String locale) {
try {
return _findExact(locale) != null;
} catch (e) {
return false;
}
}

MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) {
var actualLocale =
Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null);
if (actualLocale == null) return null;
return _findExact(actualLocale);
}
66 changes: 66 additions & 0 deletions lib/generated/intl/messages_de.dart
@@ -0,0 +1,66 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a de locale. All the
// messages from the main program should be duplicated here with the same
// function name.

// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes

import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';

final messages = new MessageLookup();

typedef String MessageIfAbsent(String messageStr, List<dynamic> args);

class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'de';

final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"backButtonTooltip": MessageLookupByLibrary.simpleMessage("Zurück"),
"clickToSearch":
MessageLookupByLibrary.simpleMessage("Zum Suchen klicken"),
"closeButtonLabel": MessageLookupByLibrary.simpleMessage("Schließen"),
"closeNavigationTooltip":
MessageLookupByLibrary.simpleMessage("Navigation schließen"),
"closeTabLabelSuffix":
MessageLookupByLibrary.simpleMessage("Tab schließen"),
"closeWindowTooltip": MessageLookupByLibrary.simpleMessage("Schließen"),
"copyActionLabel": MessageLookupByLibrary.simpleMessage("Kopieren"),
"copyActionTooltip": MessageLookupByLibrary.simpleMessage(
"Ausgewählten Inhalt in die Zwischenablage kopieren"),
"cutActionLabel": MessageLookupByLibrary.simpleMessage("Ausschneiden"),
"cutActionTooltip": MessageLookupByLibrary.simpleMessage(
"Ausgewählten Inhalt entfernen und in die Zwischenablage legen"),
"dialogLabel": MessageLookupByLibrary.simpleMessage("Dialog"),
"minimizeWindowTooltip":
MessageLookupByLibrary.simpleMessage("Minimieren"),
"modalBarrierDismissLabel":
MessageLookupByLibrary.simpleMessage("Schließen"),
"newTabLabel":
MessageLookupByLibrary.simpleMessage("Neuen Tab hinzufügen"),
"noResultsFoundLabel":
MessageLookupByLibrary.simpleMessage("Keine Ergebnisse gefunden"),
"openNavigationTooltip":
MessageLookupByLibrary.simpleMessage("Navigation öffnen"),
"pasteActionLabel": MessageLookupByLibrary.simpleMessage("Einfügen"),
"pasteActionTooltip": MessageLookupByLibrary.simpleMessage(
"Fügt den Inhalt der Zwischenablage an der aktuellen Stelle ein"),
"restoreWindowTooltip":
MessageLookupByLibrary.simpleMessage("Wiederherstellen"),
"scrollTabBackwardLabel": MessageLookupByLibrary.simpleMessage(
"Tab-Liste rückwärts scrollen"),
"scrollTabForwardLabel":
MessageLookupByLibrary.simpleMessage("Tabliste vorwärts scrollen"),
"searchLabel": MessageLookupByLibrary.simpleMessage("Suchen"),
"selectAllActionLabel":
MessageLookupByLibrary.simpleMessage("Alle auswählen"),
"selectAllActionTooltip":
MessageLookupByLibrary.simpleMessage("Alle Inhalte auswählen")
};
}
64 changes: 64 additions & 0 deletions lib/generated/intl/messages_en.dart
@@ -0,0 +1,64 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a en locale. All the
// messages from the main program should be duplicated here with the same
// function name.

// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes

import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';

final messages = new MessageLookup();

typedef String MessageIfAbsent(String messageStr, List<dynamic> args);

class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'en';

final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"backButtonTooltip": MessageLookupByLibrary.simpleMessage("Back"),
"clickToSearch":
MessageLookupByLibrary.simpleMessage("Click to search"),
"closeButtonLabel": MessageLookupByLibrary.simpleMessage("Close"),
"closeNavigationTooltip":
MessageLookupByLibrary.simpleMessage("Close Navigation"),
"closeTabLabelSuffix":
MessageLookupByLibrary.simpleMessage("Close tab"),
"closeWindowTooltip": MessageLookupByLibrary.simpleMessage("Close"),
"copyActionLabel": MessageLookupByLibrary.simpleMessage("Copy"),
"copyActionTooltip": MessageLookupByLibrary.simpleMessage(
"Copy the selected content to the clipboard"),
"cutActionLabel": MessageLookupByLibrary.simpleMessage("Cut"),
"cutActionTooltip": MessageLookupByLibrary.simpleMessage(
"Remove the selected content and put it in the clipboard"),
"dialogLabel": MessageLookupByLibrary.simpleMessage("Dialog"),
"minimizeWindowTooltip":
MessageLookupByLibrary.simpleMessage("Minimize"),
"modalBarrierDismissLabel":
MessageLookupByLibrary.simpleMessage("Dismiss"),
"newTabLabel": MessageLookupByLibrary.simpleMessage("Add new tab"),
"noResultsFoundLabel":
MessageLookupByLibrary.simpleMessage("No results found"),
"openNavigationTooltip":
MessageLookupByLibrary.simpleMessage("Open Navigation"),
"pasteActionLabel": MessageLookupByLibrary.simpleMessage("Paste"),
"pasteActionTooltip": MessageLookupByLibrary.simpleMessage(
"Inserts the contents of the clipboard at the current location"),
"restoreWindowTooltip": MessageLookupByLibrary.simpleMessage("Restore"),
"scrollTabBackwardLabel":
MessageLookupByLibrary.simpleMessage("Scroll tab list backward"),
"scrollTabForwardLabel":
MessageLookupByLibrary.simpleMessage("Scroll tab list forward"),
"searchLabel": MessageLookupByLibrary.simpleMessage("Search"),
"selectAllActionLabel":
MessageLookupByLibrary.simpleMessage("Select all"),
"selectAllActionTooltip":
MessageLookupByLibrary.simpleMessage("Select all content")
};
}
66 changes: 66 additions & 0 deletions lib/generated/intl/messages_es.dart
@@ -0,0 +1,66 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a es locale. All the
// messages from the main program should be duplicated here with the same
// function name.

// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes

import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';

final messages = new MessageLookup();

typedef String MessageIfAbsent(String messageStr, List<dynamic> args);

class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'es';

final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"backButtonTooltip": MessageLookupByLibrary.simpleMessage("Volver"),
"clickToSearch":
MessageLookupByLibrary.simpleMessage("Haz clic para buscar"),
"closeButtonLabel": MessageLookupByLibrary.simpleMessage("Cerrar"),
"closeNavigationTooltip":
MessageLookupByLibrary.simpleMessage("Cerrar Navegador"),
"closeTabLabelSuffix":
MessageLookupByLibrary.simpleMessage("Cerrar pestaña"),
"closeWindowTooltip": MessageLookupByLibrary.simpleMessage("Cerrar"),
"copyActionLabel": MessageLookupByLibrary.simpleMessage("Copiar"),
"copyActionTooltip": MessageLookupByLibrary.simpleMessage(
"Copiar el contenido seleccionado al portapapeles"),
"cutActionLabel": MessageLookupByLibrary.simpleMessage("Cortar"),
"cutActionTooltip": MessageLookupByLibrary.simpleMessage(
"Cortar el contenido seleccionado y ponerlo en el portapapeles"),
"dialogLabel": MessageLookupByLibrary.simpleMessage("Diálogo"),
"minimizeWindowTooltip":
MessageLookupByLibrary.simpleMessage("Minimizar"),
"modalBarrierDismissLabel":
MessageLookupByLibrary.simpleMessage("Cancelar"),
"newTabLabel":
MessageLookupByLibrary.simpleMessage("Añadir nueva pestaña"),
"noResultsFoundLabel": MessageLookupByLibrary.simpleMessage(
"No se encontraron resultados"),
"openNavigationTooltip":
MessageLookupByLibrary.simpleMessage("Abrir Navegador"),
"pasteActionLabel": MessageLookupByLibrary.simpleMessage("Pegar"),
"pasteActionTooltip": MessageLookupByLibrary.simpleMessage(
"Insertar el contenido del portapapeles en la posición actual"),
"restoreWindowTooltip":
MessageLookupByLibrary.simpleMessage("Restaurar"),
"scrollTabBackwardLabel":
MessageLookupByLibrary.simpleMessage("Hacer scroll hacia atrás"),
"scrollTabForwardLabel":
MessageLookupByLibrary.simpleMessage("Hacer scroll hacia delante"),
"searchLabel": MessageLookupByLibrary.simpleMessage("Buscar"),
"selectAllActionLabel":
MessageLookupByLibrary.simpleMessage("Seleccionar todo"),
"selectAllActionTooltip": MessageLookupByLibrary.simpleMessage(
"Seleccionar todo el contenido")
};
}