Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/lib/l10n/gen/ouds_flutter_app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,18 @@ abstract class AppLocalizations {
/// **'Hidden Password'**
String get app_components_pinCodeInput_hidden_password_label;

/// No description provided for @app_components_navigation_bar_label.
///
/// In en, this message translates to:
/// **'Navigation Bar'**
String get app_components_navigation_bar_label;

/// No description provided for @app_components_navigation_bar_description_text.
///
/// In en, this message translates to:
/// **'The Navigation bar provides access to an app’s primary destinations using 3 to 5 persistent tabs. Each destination is represented by an icon and optionally a text label. Positioned at the bottom of the screen, it supports quick switching between top-level sections, following Material Design navigation patterns.'**
String get app_components_navigation_bar_description_text;

/// No description provided for @app_about_name_label.
///
/// In en, this message translates to:
Expand Down
7 changes: 7 additions & 0 deletions app/lib/l10n/gen/ouds_flutter_app_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,13 @@ class AppLocalizationsAr extends AppLocalizations {
String get app_components_pinCodeInput_hidden_password_label =>
'Hidden Password';

@override
String get app_components_navigation_bar_label => 'Navigation Bar';

@override
String get app_components_navigation_bar_description_text =>
'The Tab bar is a system navigation component positioned at the bottom of the screen. It allows users to switch between the primary sections of an app. Each tab is represented by an icon, optionally paired with a label, and maintains persistent visibility across top-level destinations.';

@override
String get app_about_name_label => 'أداة نظام التصميم';

Expand Down
7 changes: 7 additions & 0 deletions app/lib/l10n/gen/ouds_flutter_app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,13 @@ class AppLocalizationsEn extends AppLocalizations {
String get app_components_pinCodeInput_hidden_password_label =>
'Hidden Password';

@override
String get app_components_navigation_bar_label => 'Navigation Bar';

@override
String get app_components_navigation_bar_description_text =>
'The Navigation bar provides access to an app’s primary destinations using 3 to 5 persistent tabs. Each destination is represented by an icon and optionally a text label. Positioned at the bottom of the screen, it supports quick switching between top-level sections, following Material Design navigation patterns.';

@override
String get app_about_name_label => 'Design System Toolbox';

Expand Down
4 changes: 4 additions & 0 deletions app/lib/l10n/ouds_flutter_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@
"app_components_pinCodeInput_error_label": "يرجى إدخال رمز التحقق.",
"app_components_pinCodeInput_verification_error_label": "فشلت عملية التحقق. يُرجى التحقق وإدخال الرمز الصحيح.",

"@_components_navigation_bar": {},
"app_components_navigation_bar_label": "Navigation Bar",
"app_components_navigation_bar_description_text": "The Tab bar is a system navigation component positioned at the bottom of the screen. It allows users to switch between the primary sections of an app. Each tab is represented by an icon, optionally paired with a label, and maintains persistent visibility across top-level destinations.",

"@_about_screen": {},
"app_about_name_label": "أداة نظام التصميم",
"app_about_privacyPolicy_label": "سياسة الخصوصية",
Expand Down
5 changes: 5 additions & 0 deletions app/lib/l10n/ouds_flutter_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@
"app_components_pinCodeInput_verification_error_label": "Verification failed. Check and enter the correct code.",
"app_components_pinCodeInput_hidden_password_label": "Hidden Password",

"@_components_navigation_bar": {},
"app_components_navigation_bar_label": "Navigation Bar",
"app_components_navigation_bar_description_text": "The Navigation bar provides access to an app’s primary destinations using 3 to 5 persistent tabs. Each destination is represented by an icon and optionally a text label. Positioned at the bottom of the screen, it supports quick switching between top-level sections, following Material Design navigation patterns.",


"@_about_screen": {},
"app_about_name_label": "Design System Toolbox",
"app_about_privacyPolicy_label": "Privacy policy",
Expand Down
13 changes: 13 additions & 0 deletions app/lib/ui/components/components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import 'package:ouds_flutter_demo/ui/components/form_input/password_input/passwo
import 'package:ouds_flutter_demo/ui/components/form_input/phone_number/phone_number_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/form_input/text_input/text_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/link/link_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/navigation/navigation_bar_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/pin_code_input/pin_code_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/radio_button/radio_button_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/radio_button/radio_button_item_demo_screen.dart';
Expand Down Expand Up @@ -181,6 +182,18 @@ List<Component> components(BuildContext context) {
context.l10n.app_components_link_description_text,
LinkDemoScreen(),
),
Component(
context.l10n.app_components_navigation_bar_label,
ComponentContainer(
child: Column(
children: [
/// to be completed
],
),
),
context.l10n.app_components_navigation_bar_description_text,
NavigationBarDemoScreen(),
),
Component(
context.l10n.app_components_passwordInput_label,
ComponentContainer(
Expand Down
216 changes: 216 additions & 0 deletions app/lib/ui/components/navigation/navigation_bar_demo_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
/*
* // Software Name: OUDS Flutter
* // SPDX-FileCopyrightText: Copyright (c) Orange SA
* // SPDX-License-Identifier: MIT
* //
* // This software is distributed under the MIT license,
* // the text of which is available at https://opensource.org/license/MIT/
* // or see the "LICENSE" file for more details.
* //
* // Software description: Flutter library of reusable graphical components
* //
*/

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:ouds_core/components/navigation/ouds_navigation_bar.dart';
import 'package:ouds_flutter_demo/l10n/app_localizations.dart';
import 'package:ouds_flutter_demo/main_app_bar.dart';
import 'package:ouds_flutter_demo/ui/components/switch/switch_customization.dart';
import 'package:ouds_flutter_demo/ui/theme/theme_controller.dart';
import 'package:ouds_flutter_demo/ui/utilities/app_assets.dart';
import 'package:ouds_flutter_demo/ui/utilities/code.dart';
import 'package:ouds_flutter_demo/ui/utilities/customizable/customizable_section.dart';
import 'package:ouds_flutter_demo/ui/utilities/customizable/customizable_switch.dart';
import 'package:ouds_flutter_demo/ui/utilities/detail_screen_header.dart';
import 'package:ouds_flutter_demo/ui/utilities/reference_design_version_component.dart';
import 'package:ouds_flutter_demo/ui/utilities/sheets_bottom/ouds_sheets_bottom.dart';
import 'package:ouds_flutter_demo/ui/utilities/theme_colored_box.dart';
import 'package:ouds_theme_contract/ouds_component_version.dart';
import 'package:ouds_theme_contract/ouds_theme.dart';
import 'package:provider/provider.dart';

/// This screen displays a navigation bar demo and allows customization of NavigationBar properties
class NavigationBarDemoScreen extends StatefulWidget {
final bool indeterminate;

const NavigationBarDemoScreen({super.key, this.indeterminate = false}); // Default value set to false

@override
State<NavigationBarDemoScreen> createState() => _NavigationBarDemoScreenState();
}

class _NavigationBarDemoScreenState extends State<NavigationBarDemoScreen> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
bool _isBottomSheetExpanded = false;

void _onExpansionChanged(bool isExpanded) {
setState(() {
_isBottomSheetExpanded = isExpanded;
});
}

@override
Widget build(BuildContext context) {
return SwitchCustomization(
child: Padding(
padding: EdgeInsets.only(bottom: Platform.isAndroid ? MediaQuery.of(context).viewPadding.bottom : OudsTheme.of(context).spaceScheme(context).paddingBlockNone),
child: Scaffold(
bottomSheet: OudsSheetsBottom(
onExpansionChanged: _onExpansionChanged,
sheetContent: const _CustomizationContent(),
title: context.l10n.app_common_customize_label,
),
key: _scaffoldKey,
appBar: MainAppBar(title: context.l10n.app_components_navigation_bar_label),
body: SafeArea(
child: ExcludeSemantics(
excluding: !_isBottomSheetExpanded,
child: _Body(),
),
),
),
),
);
}
}

class _Body extends StatefulWidget {
@override
State<_Body> createState() => _BodyState();
}

class _BodyState extends State<_Body> {
@override
Widget build(BuildContext context) {
ThemeController? themeController = Provider.of<ThemeController>(context, listen: false);
return DetailScreenDescription(
description: context.l10n.app_components_navigation_bar_description_text,
widget: Column(
children: [
_NavigationBarDemo(),
SizedBox(height: themeController.currentTheme.spaceScheme(context).fixedMedium),
Code(
code: "Exemple",
),
ReferenceDesignVersionComponent(
version: OudsComponentVersion.bar,
)
],
),
);
}
}

/// This widget is now a StatefulWidget for the checkbox demo.
///
/// Component [_NavigationBarDemo] demonstrates the behavior and functionality of a checkbox.
class _NavigationBarDemo extends StatefulWidget {
@override
State<_NavigationBarDemo> createState() => _NavigationBarDemoState();
}

class _NavigationBarDemoState extends State<_NavigationBarDemo> {
ThemeController? themeController;

SwitchCustomizationState? customizationState;
bool _isTabActivated = true;

@override
Widget build(BuildContext context) {
customizationState = SwitchCustomization.of(context);
themeController = Provider.of<ThemeController>(context, listen: true);

return Column(
children: [
ThemeBox(
themeContract: themeController!.currentTheme,
themeMode: themeController!.isInverseDarkTheme ? ThemeMode.light : ThemeMode.dark,
child: OudsNavigationBar(
translucent: false,
items: [
OudsNavigationBarItem(
icon: AppAssets.icons.functionalSocialAndEngagementHeartEmpty(themeController!),
label: 'item',
selected: _isTabActivated,
onPressed: (value) {
print("Value Pressed: ${value}");
},
),
OudsNavigationBarItem(
icon: AppAssets.icons.functionalSocialAndEngagementHeartEmpty(themeController!),
label: 'item',
),
OudsNavigationBarItem(
icon: AppAssets.icons.functionalSocialAndEngagementHeartEmpty(themeController!),
label: 'item',
),
],
),
// ],
),
ThemeBox(
themeContract: themeController!.currentTheme,
themeMode: themeController!.isInverseDarkTheme ? ThemeMode.dark : ThemeMode.light,
child: OudsNavigationBar(
translucent: true,
items: [
OudsNavigationBarItem(
icon: AppAssets.icons.functionalSocialAndEngagementHeartEmpty(themeController!),
label: 'item',
selected: _isTabActivated,
onPressed: (value) {
print("Value Pressed: ${value}");
},
),
OudsNavigationBarItem(
icon: AppAssets.icons.functionalSocialAndEngagementHeartEmpty(themeController!),
label: 'item',
),
OudsNavigationBarItem(
icon: AppAssets.icons.functionalSocialAndEngagementHeartEmpty(themeController!),
label: 'item',
),
],
)),
SizedBox(height: themeController?.currentTheme.spaceScheme(context).fixedSmall),
],
);
}
}

/// This widget represents the customization content section that appears in the bottom sheet
class _CustomizationContent extends StatefulWidget {
const _CustomizationContent();

@override
State<_CustomizationContent> createState() => _CustomizationContentState();
}

/// This state class handles the customization options for the checkbox
class _CustomizationContentState extends State<_CustomizationContent> {
_CustomizationContentState();

@override
Widget build(BuildContext context) {
final SwitchCustomizationState? customizationState = SwitchCustomization.of(context);

return CustomizableSection(
children: [
CustomizableSwitch(
title: context.l10n.app_common_enabled_label,
value: customizationState!.hasEnabled,
onChanged:

/// Specific case: The switch is disabled if there is an error (hasError is true).
customizationState.isEnabledWhenError == true
? null // Disable the switch if there is an error
: (value) {
customizationState.hasEnabled = value;
},
),
],
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* // Software Name: OUDS Flutter
* // SPDX-FileCopyrightText: Copyright (c) Orange SA
* // SPDX-License-Identifier: MIT
* //
* // This software is distributed under the MIT license,
* // the text of which is available at https://opensource.org/license/MIT/
* // or see the "LICENSE" file for more details.
* //
* // Software description: Flutter library of reusable graphical components
* //
*/

import 'package:flutter/material.dart';
import 'package:ouds_core/components/navigation/internal/ouds_navigation_bar_state.dart';
import 'package:ouds_theme_contract/ouds_theme.dart';
import 'package:ouds_theme_contract/theme/utilities/theme_utils.dart';

class OudsNavigationBarStatusModifier {
final BuildContext context;

OudsNavigationBarStatusModifier(this.context);

/// Returns the text a nd icon color based on the link status.
Color getTextItemColor(OudsNavigationBarControlState state, [bool isSelected = false]) {
final barTheme = OudsTheme.of(context).componentsTokens(context).bar;
switch (state) {
case OudsNavigationBarControlState.enabled:
return isSelected
? barTheme.colorContentSelectedEnabled
: ThemeUtils.isDarkTheme(context) == false
? barTheme.colorContentUnselectedEnabledLight
: barTheme.colorContentUnselectedEnabledDark;
case OudsNavigationBarControlState.hovered:
return isSelected ? barTheme.colorContentSelectedHover : barTheme.colorContentUnselectedHover;
case OudsNavigationBarControlState.focused:
return isSelected ? barTheme.colorContentSelectedFocus : barTheme.colorContentUnselectedFocus;
case OudsNavigationBarControlState.pressed:
return isSelected ? barTheme.colorContentSelectedPressed : barTheme.colorContentUnselectedPressed;
}
}
}
Loading
Loading