Skip to content
Merged
2 changes: 2 additions & 0 deletions app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased](https://github.com/Orange-OpenSource/ouds-flutter/compare/1.1.2...develop)
### Added
- [Library] Manage Helvetica Neue Arabic font ([#404](https://github.com/Orange-OpenSource/ouds-flutter/issues/404))

### Changed
- [DemoApp][Library] Remove OudsTagConfig and add rounded corner into `Tag` ([#598](https://github.com/Orange-OpenSource/ouds-flutter/issues/598))
- [DemoApp][Library] Update uses icons of status in `badge` and `tag` ([#597](https://github.com/Orange-OpenSource/ouds-flutter/issues/597))

### Fixed
- [DemoApp] `About` Text Overflow Issue in Arabic language ([#640](https://github.com/Orange-OpenSource/ouds-flutter/issues/640))
- [Library] `Checkbox` Incorrect accessibility label ([#514](https://github.com/Orange-OpenSource/ouds-flutter/issues/514))
- [Library] `Input Tag` The whole component should have the role button ([#481](https://github.com/Orange-OpenSource/ouds-flutter/issues/481))

Expand Down
2 changes: 2 additions & 0 deletions app/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />

<application
android:label="@string/app_name"
android:name="${applicationName}"
Expand Down
18 changes: 9 additions & 9 deletions app/lib/l10n/gen/ouds_flutter_app_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ class AppLocalizationsAr extends AppLocalizations {

@override
String get app_components_textInput_error_label =>
'لا يمكن أن يكون هذا الحقل فارغًا.';
'This field can’t be empty.';

@override
String get app_components_textInput_trailingAction_a11y =>
Expand All @@ -432,7 +432,7 @@ class AppLocalizationsAr extends AppLocalizations {
String get app_components_textInput_helperLink_label => 'Helper link';

@override
String get app_components_textInputHelperText_label => 'نص المساعدة.';
String get app_components_textInputHelperText_label => 'Helper Text';

@override
String get app_components_phoneNumberInput_label => 'Phone number input';
Expand All @@ -450,7 +450,7 @@ class AppLocalizationsAr extends AppLocalizations {

@override
String get app_components_phoneNumberInput_error_label =>
'لا يمكن أن يكون رقم الهاتف فارغًا.';
'The phone number can\'t be empty.';

@override
String get app_components_link_label => 'Link';
Expand All @@ -474,7 +474,7 @@ class AppLocalizationsAr extends AppLocalizations {

@override
String get app_components_passwordInput_error_label =>
'يرجى إدخال كلمة المرور الخاصة بك.';
'Please enter your password.';

@override
String get app_components_pinCodeInput_label => 'Pin code input';
Expand All @@ -488,23 +488,23 @@ class AppLocalizationsAr extends AppLocalizations {

@override
String get app_components_pinCodeInput_helperText_description_text_4 =>
'أدخل الرقم السري المكوَّن من 4 أرقام المُرسَل إلى هاتفك.';
'Enter the 4-digit code sent to your phone.';

@override
String get app_components_pinCodeInput_helperText_description_text_6 =>
'أدخل الرقم السري المكوَّن من 6 أرقام المُرسَل إلى هاتفك.';
'Enter the 6-digit code sent to your phone.';

@override
String get app_components_pinCodeInput_helperText_description_text_8 =>
'أدخل الرقم السري المكوَّن من 8 أرقام المُرسَل إلى هاتفك.';
'Enter the 8-digit code sent to your phone.';

@override
String get app_components_pinCodeInput_error_label =>
'يرجى إدخال رمز التحقق.';
'Please enter the verification code.';

@override
String get app_components_pinCodeInput_verification_error_label =>
'فشلت عملية التحقق. يُرجى التحقق وإدخال الرمز الصحيح.';
'Verification failed. Check and enter the correct code.';

@override
String get app_components_pinCodeInput_hidden_password_label =>
Expand Down
10 changes: 0 additions & 10 deletions app/lib/l10n/ouds_flutter_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,19 @@

"@_components_textInput": {},
"app_components_textInput_description_text": "Text Input هو أحد مكونات واجهة المستخدم، ويُتيح للمستخدمين إدخال بيانات نصية أحادية السطر أو تحريرها أو تحديدها. وهو أحد أهم عناصر النموذج المستخدمة لتسجيل بيانات المستخدم، مثل الأسماء ورسائل البريد الإلكتروني وكلمات المرور واستعلامات البحث",
"app_components_textInput_error_label": "لا يمكن أن يكون هذا الحقل فارغًا.",
"app_components_textInput_trailingAction_a11y": "وصف محتوى أيقونة النهاية",
"app_components_textInputHelperText_label": "نص المساعدة.",

"@_components_phone_number_input": {},
"app_components_phoneNumberInput_description_text": "Phone Number هو حقل نموذج مصمم خصيصًا لالتقاط أرقام الهواتف والتحقق منها، وغالبًا ما يكون بتنسيق دولي. عادةً ما يتضمن محددًا للدولة، مما يسمح للمستخدمين باختيار بلدهم وتطبيق رمز الاتصال المقابل تلقائيًا (مثل 33 لفرنسا).",
"app_components_phoneNumberInput_error_label": "لا يمكن أن يكون رقم الهاتف فارغًا.",

"@_components_link": {},
"app_components_link_description_text": "تُستخدم links لتوجيه المستخدمين إلى موارد أو أقسام إضافية، سواء كانت داخلية (ضمن نفس التطبيق) أو خارجية (مثل موقع إلكتروني أو مستند).",

"@_components_password_input": {},
"app_components_passwordInput_description_text": "Password Input هو حقل نموذج مصمم خصيصًا لالتقاط كلمة مرور المستخدم بسرية. يقوم بإخفاء الأحرف أثناء الكتابة، عادةً باستبدالها بنقاط، لحماية الإدخال من قراءته من قبل الآخرين القريبين. بينما الهدف الأساسي هو تعزيز الخصوصية والأمان، قد يتضمن الحقل أيضًا ميزات سهولة الاستخدام مثل تبديل إظهار/إخفاء كلمة المرور ونص المساعدة لتوجيه إنشاء كلمة المرور.",
"app_components_passwordInput_error_label": "يرجى إدخال كلمة المرور الخاصة بك.",


"@_components_pin_code_input": {},
"app_components_pinCodeInput_description_text": "PIN Code Input هو حقل مخصص لإدخال رموز رقمية قصيرة وثابتة الطول، يُستخدم عادةً للمصادقة أو لتأكيد العمليات، مثل الرقم السري الشخصي المكوَّن من 4 أو 6 أو 8 أرقام.",
"app_components_pinCodeInput_helperText_description_text_4": "أدخل الرقم السري المكوَّن من 4 أرقام المُرسَل إلى هاتفك.",
"app_components_pinCodeInput_helperText_description_text_6": "أدخل الرقم السري المكوَّن من 6 أرقام المُرسَل إلى هاتفك.",
"app_components_pinCodeInput_helperText_description_text_8": "أدخل الرقم السري المكوَّن من 8 أرقام المُرسَل إلى هاتفك.",
"app_components_pinCodeInput_error_label": "يرجى إدخال رمز التحقق.",
"app_components_pinCodeInput_verification_error_label": "فشلت عملية التحقق. يُرجى التحقق وإدخال الرمز الصحيح.",

"@_components_navigation_bar": {},
"app_components_navigationBar_label": "Bottom Bar",
Expand Down
10 changes: 6 additions & 4 deletions app/lib/ui/about/about_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,13 @@ class _AboutScreenState extends State<AboutScreen> {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
text,
style: currentTheme.typographyTokens.typeBodyDefaultMedium(context),
Expanded(
child: Text(
text,
style: currentTheme.typographyTokens.typeBodyDefaultMedium(context),
),
),
Spacer(),
SizedBox(width: currentTheme.spaceScheme(context).rowGapSmall),
OudsTag.text(label: version, status: Info(), appearance: OudsTagAppearance.muted, size: OudsTagSize.small)
],
),
Expand Down
1 change: 1 addition & 0 deletions ouds_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/Orange-OpenSource/ouds-flutter/compare/1.1.2...develop)
### Added
- [Library] Manage Helvetica Neue Arabic font ([#404](https://github.com/Orange-OpenSource/ouds-flutter/issues/404))

### Changed
- [Library] Remove OudsTagConfig and add rounded corner into `Tag` ([#598](https://github.com/Orange-OpenSource/ouds-flutter/issues/598))
Expand Down
15 changes: 14 additions & 1 deletion ouds_core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,10 @@ For production apps, bundle fonts locally:
app/fonts/
├── helvetica_neue_latin_roman.ttf
├── helvetica_neue_latin_medium.ttf
└── helvetica_neue_latin_bold.ttf
├── helvetica_neue_latin_bold.ttf
├── helvetica_neue_arabic_roman.ttf
├── helvetica_neue_arabic_light.ttf
└── helvetica_neue_arabic_bold.ttf
```

2. Configure in `pubspec.yaml`:
Expand All @@ -232,6 +235,16 @@ For production apps, bundle fonts locally:
- family: HelveticaNeue-Bold
fonts:
- asset: fonts/helvetica_neue_latin_bold.ttf
- family: HelveticaNeue-Arabic
fonts:
- asset: fonts/helvetica_neue_arabic_roman.ttf
- family: HelveticaNeue-Arabic-Light
fonts:
- asset: fonts/helvetica_neue_arabic_light.ttf
- family: HelveticaNeue-Arabic-Bold
fonts:
- asset: fonts/helvetica_neue_arabic_bold.ttf

```

3. Load fonts at startup:
Expand Down
54 changes: 34 additions & 20 deletions ouds_core/lib/components/navigation/ouds_tab_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
library;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:ouds_core/components/control/internal/interaction/ouds_inherited_interaction_model.dart';
import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_background_modifier.dart';
import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_border_modifier.dart';
import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_state.dart';
import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_status_modifier.dart';
import 'package:ouds_core/components/navigation/ouds_navigation_bar_item.dart';
import 'package:ouds_theme_contract/ouds_theme.dart';

/// [OUDS Tab Bar design guidelines](https://r.orange.fr/r/S-ouds-doc-ios-tab-bar)
///
Expand Down Expand Up @@ -156,28 +158,40 @@ class _OudsTabBarState extends State<OudsTabBar> {

final safeIndex = _selectedIndex.clamp(0, widget.items.length - 1);

return ClipRect(
child: BackdropFilter(
filter: navigationBarBorderModifier.getBlurNavigationBar(),
child: CupertinoTabBar(
currentIndex: safeIndex,
activeColor: navigationBarModifier.getTextIconItemColor(barControlState, true),
inactiveColor: navigationBarModifier.getTextIconItemColor(barControlState, false),
border: navigationBarBorderModifier.getBorderNavigationBar(),
backgroundColor: navigationBarBgModifier.getBackgroundColor(widget.translucent),
items: List.generate(
widget.items.length,
(index) => widget.items[index].toBottomNavigationBarItem(
context,
barControlState,
isSelected: index == safeIndex,
// Get the existing Cupertino theme to avoid overwriting other styles.
final existingCupertinoTheme = CupertinoTheme.of(context);

return CupertinoTheme(
data: existingCupertinoTheme.copyWith(
textTheme: existingCupertinoTheme.textTheme.copyWith(
tabLabelTextStyle: OudsTheme.of(context).typographyTokens.typeBodyModerateMedium(context).copyWith(
fontSize: 10
), // Apply the custom text style.
),
),
child: ClipRect(
child: BackdropFilter(
filter: navigationBarBorderModifier.getBlurNavigationBar(),
child: CupertinoTabBar(
currentIndex: safeIndex,
activeColor: navigationBarModifier.getTextIconItemColor(barControlState, true),
inactiveColor: navigationBarModifier.getTextIconItemColor(barControlState, false),
border: navigationBarBorderModifier.getBorderNavigationBar(),
backgroundColor: navigationBarBgModifier.getBackgroundColor(widget.translucent),
items: List.generate(
widget.items.length,
(index) => widget.items[index].toBottomNavigationBarItem(
context,
barControlState,
isSelected: index == safeIndex,
),
),
onTap: (index) {
if (index == safeIndex) return;
setState(() => _selectedIndex = index);
widget.onTap?.call(index);
},
),
onTap: (index) {
if (index == safeIndex) return;
setState(() => _selectedIndex = index);
widget.onTap?.call(index);
},
),
),
);
Expand Down
1 change: 1 addition & 0 deletions ouds_theme_orange/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/Orange-OpenSource/ouds-flutter/compare/1.1.2...develop)
### Added
- [Library] Manage Helvetica Neue Arabic font ([#404](https://github.com/Orange-OpenSource/ouds-flutter/issues/404))

### Changed

Expand Down
6 changes: 3 additions & 3 deletions ouds_theme_orange/lib/orange_font_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* //
*/

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

/// Helper class for selecting the correct Helvetica Neue font family based on weight.
Expand Down Expand Up @@ -95,9 +96,8 @@ class OrangeFontHelper {
extension OrangeFontStyleExtension on TextStyle {
/// Returns a copy of this TextStyle with the correct Helvetica Neue font family
/// based on the current font weight and locale.
///
/// [isArabic] - Whether the text is in Arabic (default: false)
TextStyle withOrangeFont({bool isArabic = false}) {
TextStyle withOrangeFont() {
final isArabic = PlatformDispatcher.instance.locale.languageCode == 'ar';
final weight = fontWeight ?? FontWeight.w400;
return copyWith(
fontFamily: OrangeFontHelper.getFontFamily(
Expand Down
10 changes: 5 additions & 5 deletions ouds_theme_orange/lib/orange_font_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ class OrangeFontProvider {
/// - Arabic locale (`ar`): Helvetica Neue Arabic (Light, Regular, Bold)
/// - Other locales: Helvetica Neue Latin (Regular, Medium, Bold)
///
/// Returns the font family name or fallback font if loading fails.
static Future<String> loadFromCdn() async {
final isArabic = PlatformDispatcher.instance.locale.languageCode == 'ar';
final variants = isArabic ? _OrangeFontVariant.arabicVariants : _OrangeFontVariant.latinVariants;
/// Returns the fonts family name or fallback font if loading fails.
static Future<List<String>> loadFromCdn() async {
String arabicFont = await _loadFromCdn(_OrangeFontVariant.arabicVariants);
String latinFont = await _loadFromCdn(_OrangeFontVariant.latinVariants);

return await _loadFromCdn(variants);
return [arabicFont,latinFont];
}

/// Loads Orange fonts from user-specified assets.
Expand Down
32 changes: 24 additions & 8 deletions ouds_theme_orange/lib/orange_font_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,34 @@ class OrangeFontService {

OrangeFontService._();

String? _loadedFontFamily;
List<String?>? _loadedFontsFamily;

bool _isLoading = false;
final List<VoidCallback> _listeners = [];

/// Gets the currently loaded font family name, or null if not yet loaded.
String? get fontFamily => _loadedFontFamily;
String? get fontFamily {
final isArabic = PlatformDispatcher.instance.locale.languageCode == 'ar';

try {
if (isArabic) {
return _loadedFontsFamily?.firstWhere(
(font) => font != null && font.toLowerCase().contains('arabic'),
);
}

return _loadedFontsFamily?.firstWhere(
(font) => font != null && !font.toLowerCase().contains('arabic'),
);
} on StateError {
return null; // Return null if no font is found
}
}
/// Returns true if fonts are currently being loaded.
bool get isLoading => _isLoading;

/// Returns true if fonts have been successfully loaded.
bool get isLoaded => _loadedFontFamily != null;
bool get isLoaded => _loadedFontsFamily != null;

/// Adds a listener that will be called when fonts finish loading.
void addListener(VoidCallback listener) {
Expand All @@ -94,11 +110,11 @@ class OrangeFontService {

/// Loads fonts from CDN in background (non-blocking).
void loadFromCdn() {
if (_isLoading || _loadedFontFamily != null) return;
if (_isLoading || _loadedFontsFamily != null) return;

_isLoading = true;
OrangeFontProvider.loadFromCdn().then((fontFamily) {
_loadedFontFamily = fontFamily;
_loadedFontsFamily = fontFamily;
_isLoading = false;
_notifyListeners();
if (kDebugMode) {
Expand All @@ -114,11 +130,11 @@ class OrangeFontService {

/// Loads fonts from assets in background (non-blocking).
void loadFromAssets(OrangeFontFamily fontFamily) {
if (_isLoading || _loadedFontFamily != null) return;
if (_isLoading || _loadedFontsFamily != null) return;

_isLoading = true;
OrangeFontProvider.loadFromAssets(fontFamily).then((loadedFontFamily) {
_loadedFontFamily = loadedFontFamily;
_loadedFontsFamily = [loadedFontFamily];
_isLoading = false;
_notifyListeners();
/*if (kDebugMode) {
Expand All @@ -134,7 +150,7 @@ class OrangeFontService {

/// Resets the service (useful for testing or hot reload).
void reset() {
_loadedFontFamily = null;
_loadedFontsFamily = null;
_isLoading = false;
_listeners.clear();
}
Expand Down
4 changes: 2 additions & 2 deletions ouds_theme_orange_compact/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [1.1.1](https://github.com/Orange-OpenSource/ouds-flutter/compare/0.0.0...1.1.1) - 2026-03-06
### Added
- [DemoApp][Library] Management of Helvetica Neue 75 font for Orange themes ([#370](https://github.com/Orange-OpenSource/ouds-flutter/issues/370))
- [DemoApp][Library] Add Orange Compact theme ([#504](https://github.com/Orange-OpenSource/ouds-flutter/issues/504))
- [Library] Management of Helvetica Neue 75 font for Orange themes ([#370](https://github.com/Orange-OpenSource/ouds-flutter/issues/370))
- [Library] Add Orange Compact theme ([#504](https://github.com/Orange-OpenSource/ouds-flutter/issues/504))

### Changed
- [Library] Update tokens 1.9.0 - Input tag tokens ([#594](https://github.com/Orange-OpenSource/ouds-flutter/issues/594))
Expand Down
Loading