From b7b558ba482c77cd518f8770823683a52baed834 Mon Sep 17 00:00:00 2001 From: Tayeb Sedraia Date: Mon, 4 Mar 2024 10:11:03 +0100 Subject: [PATCH] 331 module list (#339) * app : add illustration asset * library : update list standard by list_item * app : add l10n keys * app : update list standard by list_item * app : add module lists * app and library : add changelog --- NOTICE.txt | 3 +- app/CHANGELOG.md | 1 + app/assets/il_list_item.png | Bin 0 -> 4931 bytes app/assets/il_lists.png | Bin 0 -> 5143 bytes app/assets/il_lists.svg | 1 - app/lib/l10n/ods_flutter_en.arb | 21 +-- app/lib/ui/about/about_screen.dart | 10 +- app/lib/ui/components/components.dart | 20 +-- .../list_checkbox.dart} | 0 .../list_item/list_customization.dart | 116 +++++++++++++ .../list_item.dart} | 152 +++++++++++++----- .../list_leading_enum.dart} | 14 +- .../list_radio_buttons.dart} | 0 .../list_switches.dart} | 3 +- .../list_trailing_enum.dart} | 14 +- .../components/lists/lists_customization.dart | 140 ---------------- .../sheets_bottom/sheets_bottom.dart | 4 +- .../spacings/guideline_spacings_screen.dart | 4 +- .../lists/module_lists_screen.dart} | 79 +++++---- app/lib/ui/modules/modules.dart | 26 +++ app/lib/ui/modules/modules_entities.dart | 24 +++ app/lib/ui/modules/modules_screen.dart | 48 +++++- app/lib/ui/utilities/navigation_items.dart | 3 +- library/CHANGELOG.md | 1 + .../components/lists/ods_list_checkbox.dart | 5 +- ...selection_item.dart => ods_list_item.dart} | 34 +++- .../lists/ods_list_radio_button.dart | 5 +- .../lists/ods_list_standard_item.dart | 94 ----------- .../lib/components/lists/ods_list_switch.dart | 6 +- 29 files changed, 453 insertions(+), 375 deletions(-) create mode 100644 app/assets/il_list_item.png create mode 100644 app/assets/il_lists.png delete mode 100644 app/assets/il_lists.svg rename app/lib/ui/components/{lists/lists_checkboxes.dart => list_item/list_checkbox.dart} (100%) create mode 100644 app/lib/ui/components/list_item/list_customization.dart rename app/lib/ui/components/{lists/lists_standard.dart => list_item/list_item.dart} (59%) rename app/lib/ui/components/{lists/lists_leading_enum.dart => list_item/list_leading_enum.dart} (77%) rename app/lib/ui/components/{lists/lists_radio_buttons.dart => list_item/list_radio_buttons.dart} (100%) rename app/lib/ui/components/{lists/lists_switches.dart => list_item/list_switches.dart} (97%) rename app/lib/ui/components/{lists/lists_trailing_enum.dart => list_item/list_trailing_enum.dart} (78%) delete mode 100644 app/lib/ui/components/lists/lists_customization.dart rename app/lib/ui/{components/lists/lists_selection.dart => modules/lists/module_lists_screen.dart} (76%) create mode 100644 app/lib/ui/modules/modules.dart create mode 100644 app/lib/ui/modules/modules_entities.dart rename library/lib/components/lists/{ods_list_selection_item.dart => ods_list_item.dart} (79%) delete mode 100644 library/lib/components/lists/ods_list_standard_item.dart diff --git a/NOTICE.txt b/NOTICE.txt index 7752dfc0..466c5a29 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -33,7 +33,7 @@ ods-flutter/app/assets/il_snackbars.svg ods-flutter/app/assets/il_app_bars_top_generic.svg ods-flutter/app/assets/il_chips.png ods-flutter/app/assets/il_floating_action_button.svg -ods-flutter/app/assets/il_lists.svg +ods-flutter/app/assets/il_lists.png ods-flutter/app/assets/il_color.png ods-flutter/app/assets/il_spacing.png ods-flutter/app/assets/il_sheets_bottom.png @@ -47,6 +47,7 @@ ods-flutter/app/assets/il_navigation_rail.png ods-flutter/app/assets/ic_calendar_event_info.png ods-flutter/app/assets/ic_identity_protection.png ods-flutter/app/assets/ic_task_list.png +ods-flutter/app/assets/il_list_item.png ods-flutter/app/assets/1.5x/il_about.png ods-flutter/app/assets/1.5x/il_switches.png diff --git a/app/CHANGELOG.md b/app/CHANGELOG.md index 7aa06848..8f09b171 100644 --- a/app/CHANGELOG.md +++ b/app/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ODS - Component - Navigation Rail ([#25](https://github.com/Orange-OpenSource/ods-flutter/issues/25)) - ODS - Component - Cards: Title First Card ([#9](https://github.com/Orange-OpenSource/ods-flutter/issues/9)) - About - Page ([#332](https://github.com/Orange-OpenSource/ods-flutter/issues/332)) +- Module - List ([#331](https://github.com/Orange-OpenSource/ods-flutter/issues/331)) ## Changed diff --git a/app/assets/il_list_item.png b/app/assets/il_list_item.png new file mode 100644 index 0000000000000000000000000000000000000000..8609094c7b5acca3c751e73a148a28137508c0c5 GIT binary patch literal 4931 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 h@(|*4*&{f_^>V \ No newline at end of file diff --git a/app/lib/l10n/ods_flutter_en.arb b/app/lib/l10n/ods_flutter_en.arb index b640de00..0f4e696a 100644 --- a/app/lib/l10n/ods_flutter_en.arb +++ b/app/lib/l10n/ods_flutter_en.arb @@ -228,19 +228,17 @@ "componentListItemDescription": "A list item is the individual element of data entries like text, icons or images that is used to create a list.", "@_LISTS_VARIANT": {}, - "listVariantSelectionTitle": "List with selection", - "listSelectionTitle": "List selection", - "listVariantSelectionSubtitle": "OdsListSelectionItem", - "listVariantStandardTitle": "Standard Lists", - "listVariantStandardSubtitle": "OdsListStandardItem", + "listVariantItemTitle": "List item demo", + "listSelectionTitle": "List item", + "listVariantItemSubtitle": "OdsListItem", "listCustomizationSubtitle": "Subtitle", - "listLeadingCustomizationTitle": "Leading", + "listLeadingCustomizationTitle": "Leading - Before the list text", "listLeadingEnumNone": "None", "listLeadingEnumIcon": "Icon", "listLeadingEnumCircle": "Circle", "listLeadingEnumWide": "Wide", "listLeadingEnumSquare": "Square", - "listTrailingCustomizationTitle": "Trailing", + "listTrailingCustomizationTitle": "Trailing - After the list text", "listTrailingEnumNone": "None", "listTrailingEnumSwitch": "Switch", "listTrailingEnumCheckbox": "Checkbox", @@ -369,13 +367,8 @@ "componentTextFieldVisualisationIcon": "Visualisation icon", "componentTextFieldErrorMessage": "Error message", - "@_COMPONENTS_MATERIALS": {}, - "componentMaterialsTitle": "Materials", - - "componentMaterialsDescription": "On/off switches toggle the state of a single settings option. The function of the switch should be made clear by the inline label.", - "@_MATERIALS_VARIANT": {}, - "materialsVariantTitle": "Others", - "materialsVariantSubtitle": "Material", + "@_MODULES_SCREEN": {}, + "moduleLists": "Lists", "@_ABOUT_SCREEN": {}, "aboutScreenTitle": "Orange Design System Flutter App", diff --git a/app/lib/ui/about/about_screen.dart b/app/lib/ui/about/about_screen.dart index 01c6ef8f..8a12207a 100644 --- a/app/lib/ui/about/about_screen.dart +++ b/app/lib/ui/about/about_screen.dart @@ -13,7 +13,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; import 'package:get/get.dart'; -import 'package:ods_flutter/components/lists/ods_list_standard_item.dart'; +import 'package:ods_flutter/components/lists/ods_list_item.dart'; import 'package:ods_flutter/guidelines/spacings.dart'; import 'package:ods_flutter_demo/ui/about/detail/about_file_screen.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -75,7 +75,7 @@ class _AboutScreenState extends State { ], ), ), - OdsListStandardItem( + OdsListItem( title: AppLocalizations.of(context)!.aboutMenuChangelog, image: ImageIcon( AssetImage('assets/ic_task_list.png'), @@ -91,7 +91,7 @@ class _AboutScreenState extends State { ); }, ), - OdsListStandardItem( + OdsListItem( title: "Privacy Policy", image: ImageIcon( AssetImage('assets/ic_identity_protection.png'), @@ -107,7 +107,7 @@ class _AboutScreenState extends State { ); }, ), - OdsListStandardItem( + OdsListItem( title: "Terms of services", image: ImageIcon( AssetImage('assets/ic_calendar_event_info.png'), @@ -123,7 +123,7 @@ class _AboutScreenState extends State { ); }, ), - OdsListStandardItem( + OdsListItem( title: "Third party library", image: ImageIcon( AssetImage('assets/ic_task_list.png'), diff --git a/app/lib/ui/components/components.dart b/app/lib/ui/components/components.dart index 966faf66..b9192dd4 100644 --- a/app/lib/ui/components/components.dart +++ b/app/lib/ui/components/components.dart @@ -31,11 +31,10 @@ import 'package:ods_flutter_demo/ui/components/chips/chips_input.dart'; import 'package:ods_flutter_demo/ui/components/component_entities.dart'; import 'package:ods_flutter_demo/ui/components/dialogs/dialogs.dart'; import 'package:ods_flutter_demo/ui/components/floating_action_button/floating_action_button.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_checkboxes.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_radio_buttons.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_selection.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_standard.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_switches.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_checkbox.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_item.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_radio_buttons.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_switches.dart'; import 'package:ods_flutter_demo/ui/components/menus/menu_dropdown.dart'; import 'package:ods_flutter_demo/ui/components/menus/menu_exposed_dropdown.dart'; import 'package:ods_flutter_demo/ui/components/navigation_bar/navigation_bar.dart'; @@ -199,19 +198,14 @@ List components(BuildContext context) { ), Component( AppLocalizations.of(context)!.componentListItem, - 'assets/il_lists.svg', + 'assets/il_list_item.png', AppLocalizations.of(context)!.componentListItemDescription, [ Variant( - AppLocalizations.of(context)!.listVariantSelectionTitle, - AppLocalizations.of(context)!.listVariantSelectionSubtitle, + AppLocalizations.of(context)!.listVariantItemTitle, + AppLocalizations.of(context)!.listVariantItemSubtitle, ComponentListsSelection(), ), - Variant( - AppLocalizations.of(context)!.listVariantStandardTitle, - AppLocalizations.of(context)!.listVariantStandardSubtitle, - ComponentListsStandard(), - ), Variant( AppLocalizations.of(context)!.listCheckboxesTitle, AppLocalizations.of(context)!.listCheckboxesSubtitle, diff --git a/app/lib/ui/components/lists/lists_checkboxes.dart b/app/lib/ui/components/list_item/list_checkbox.dart similarity index 100% rename from app/lib/ui/components/lists/lists_checkboxes.dart rename to app/lib/ui/components/list_item/list_checkbox.dart diff --git a/app/lib/ui/components/list_item/list_customization.dart b/app/lib/ui/components/list_item/list_customization.dart new file mode 100644 index 00000000..0972153b --- /dev/null +++ b/app/lib/ui/components/list_item/list_customization.dart @@ -0,0 +1,116 @@ +/* + * Software Name : Orange Design System + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT licence, + * 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 for Android and iOS + */ + +import 'package:flutter/material.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_leading_enum.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_trailing_enum.dart'; + +class _ListCustomization extends InheritedWidget { + _ListCustomization({ + Key? key, + required Widget child, + required this.data, + }) : super(key: key, child: child); + + final ListCustomizationState data; + + @override + bool updateShouldNotify(_ListCustomization oldWidget) => true; +} + +class ListCustomization extends StatefulWidget { + const ListCustomization({ + super.key, + required this.child, + }); + + final Widget child; + + @override + ListCustomizationState createState() => ListCustomizationState(); + + static ListCustomizationState? of(BuildContext context) { + return (context.dependOnInheritedWidgetOfExactType<_ListCustomization>()) + ?.data; + } +} + +class ListCustomizationState extends State { + bool _hasSubtitle = true; + + ///Leading Enum + List _leadingElements = [ + ListLeadingEnum.none, + ListLeadingEnum.icon, + ListLeadingEnum.circle, + ListLeadingEnum.wide, + ListLeadingEnum.square, + ]; + ListLeadingEnum _selectedLeadingElement = ListLeadingEnum.circle; + + ///Trailing Enum + List _trailingElements = [ + ListTrailingEnum.none, + ListTrailingEnum.trailingSwitch, + ListTrailingEnum.trailingCheckbox, + ListTrailingEnum.trailingText, + ListTrailingEnum.trailingInfoButton, + ]; + ListTrailingEnum _selectedTrailingElement = ListTrailingEnum.none; + + bool get hasSubtitle => _hasSubtitle; + set hasSubtitle(bool value) { + setState(() { + _hasSubtitle = value; + }); + } + + ///Leading Enum + List get leadingElements => _leadingElements; + set leadingElements(List value) { + setState(() { + _leadingElements = value; + }); + } + + ListLeadingEnum get selectedLeadingElement => _selectedLeadingElement; + + set selectedLeadingElement(ListLeadingEnum value) { + setState(() { + _selectedLeadingElement = value; + }); + } + + ///Trailing Enum + List get trailingElements => _trailingElements; + set trailingElements(List value) { + setState(() { + _trailingElements = value; + }); + } + + ListTrailingEnum get selectedTrailingElement => _selectedTrailingElement; + + set selectedTrailingElement(ListTrailingEnum value) { + setState(() { + _selectedTrailingElement = value; + }); + } + + @override + Widget build(BuildContext context) { + return _ListCustomization( + data: this, + child: widget.child, + ); + } +} diff --git a/app/lib/ui/components/lists/lists_standard.dart b/app/lib/ui/components/list_item/list_item.dart similarity index 59% rename from app/lib/ui/components/lists/lists_standard.dart rename to app/lib/ui/components/list_item/list_item.dart index 45d1b181..c569b211 100644 --- a/app/lib/ui/components/lists/lists_standard.dart +++ b/app/lib/ui/components/list_item/list_item.dart @@ -13,25 +13,26 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; import 'package:ods_flutter/components/chips/ods_choice_chips.dart'; -import 'package:ods_flutter/components/lists/ods_list_standard_item.dart'; +import 'package:ods_flutter/components/lists/ods_list_item.dart'; import 'package:ods_flutter/components/lists/ods_list_switch.dart'; import 'package:ods_flutter/components/sheets_bottom/ods_sheets_bottom.dart'; import 'package:ods_flutter/components/utilities/ods_image_shape.dart'; import 'package:ods_flutter/guidelines/spacings.dart'; import 'package:ods_flutter_demo/main.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_customization.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_leading_enum.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_trailing_enum.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_customization.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_leading_enum.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_trailing_enum.dart'; import 'package:ods_flutter_demo/ui/main_app_bar.dart'; -class ComponentListsStandard extends StatefulWidget { - const ComponentListsStandard({super.key}); +class ComponentListsSelection extends StatefulWidget { + const ComponentListsSelection({super.key}); @override - State createState() => _ComponentListsStandardState(); + State createState() => + _ComponentListsSelectionState(); } -class _ComponentListsStandardState extends State { +class _ComponentListsSelectionState extends State { final _scaffoldKey = GlobalKey(); @override @@ -41,15 +42,14 @@ class _ComponentListsStandardState extends State { @override Widget build(BuildContext context) { - return ListsCustomization( + return ListCustomization( child: Scaffold( key: _scaffoldKey, bottomSheet: OdsSheetsBottom( sheetContent: _CustomizationContent(), title: AppLocalizations.of(context)!.componentCustomizeTitle, ), - appBar: - MainAppBar(AppLocalizations.of(context)!.listVariantStandardTitle), + appBar: MainAppBar(AppLocalizations.of(context)!.listSelectionTitle), body: _Body(), ), ); @@ -62,19 +62,24 @@ class _Body extends StatefulWidget { } class _BodyState extends State<_Body> { - List switchValues = List.filled(OdsApplication.recipes.length, true); + List selectionControls = + List.filled(OdsApplication.recipes.length, true); @override Widget build(BuildContext context) { - final ListsCustomizationState? customizationState = - ListsCustomization.of(context); + final ListCustomizationState? customizationState = + ListCustomization.of(context); + var colorScheme = Theme.of(context).colorScheme; + /* return Scaffold( body: ListView.builder( itemCount: OdsApplication.recipes.length - 4, itemBuilder: (context, index) { var recipe = OdsApplication.recipes[index]; + bool isSwitched = switchValues[index]; + var url = ""; switch (customizationState?.selectedLeadingElement ?? "") { case ListsLeadingEnum.icon: @@ -97,28 +102,99 @@ class _BodyState extends State<_Body> { final odsImageShape = OdsImageShape( context, customizationState?.selectedLeadingElement.name, url); - return OdsListStandardItem( + return OdsListSelectionItem( title: recipe.title, subtitle: customizationState?.hasSubtitle == true ? recipe.subtitle : null, image: odsImageShape.buildImage(), - icon: customizationState?.selectedTrailingStandardElement == - ListsTrailingEnum.trailingInfoButton - ? IconButton( - onPressed: () {}, - icon: Icon(Icons.info), - color: colorScheme.secondary) + value: isSwitched, + onChangedSwitch: customizationState?.selectedTrailingElement == + ListsTrailingEnum.trailingSwitch + ? (value) { + setState(() { + switchValues[index] = value ?? false; + }); + } : null, - text: customizationState?.selectedTrailingStandardElement == - ListsTrailingEnum.trailingText - ? AppLocalizations.of(context)!.listTrailingExampleDetails + onChangedCheckBox: customizationState?.selectedTrailingElement == + ListsTrailingEnum.trailingCheckbox + ? (value) { + setState(() { + switchValues[index] = value ?? false; + }); + } : null, - divider: true, ); }, ), ); + + */ + + var recipe = OdsApplication.recipes[0]; + bool isSelectionControl = selectionControls[0]; + var url = ""; + switch (customizationState?.selectedLeadingElement ?? "") { + case ListLeadingEnum.icon: + url = recipe.getIconPath(); + break; + case ListLeadingEnum.circle: + url = recipe.url; + break; + case ListLeadingEnum.square: + url = recipe.url; + break; + case ListLeadingEnum.wide: + url = recipe.url; + break; + case ListLeadingEnum.none: + // TODO: Handle this case. + break; + } + final odsImageShape = OdsImageShape( + context, customizationState?.selectedLeadingElement.name, url); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + OdsListItem( + title: recipe.title, + subtitle: + customizationState?.hasSubtitle == true ? recipe.subtitle : null, + image: odsImageShape.buildImage(), + icon: customizationState?.selectedTrailingElement == + ListTrailingEnum.trailingInfoButton + ? IconButton( + onPressed: () {}, + icon: Icon(Icons.info), + color: colorScheme.secondary) + : null, + text: customizationState?.selectedTrailingElement == + ListTrailingEnum.trailingText + ? AppLocalizations.of(context)!.listTrailingExampleDetails + : null, + value: isSelectionControl, + onChangedSwitch: customizationState?.selectedTrailingElement == + ListTrailingEnum.trailingSwitch + ? (value) { + setState(() { + selectionControls[0] = value ?? false; + }); + } + : null, + onChangedCheckBox: customizationState?.selectedTrailingElement == + ListTrailingEnum.trailingCheckbox + ? (value) { + setState(() { + selectionControls[0] = value ?? false; + }); + } + : null, + onClick: () {}, + ), + ], + ); } } @@ -129,14 +205,14 @@ class _CustomizationContent extends StatefulWidget { class _CustomizationContentState extends State<_CustomizationContent> { int selectedLeadingIndex = 0; - int selectedStandardTrailingIndex = 0; + int selectedTrailingIndex = 0; bool isLeadingFiltered = true; bool isTrailingFiltered = true; @override Widget build(BuildContext context) { - final ListsCustomizationState? customizationState = - ListsCustomization.of(context); + final ListCustomizationState? customizationState = + ListCustomization.of(context); return SafeArea( child: Column( children: [ @@ -164,7 +240,7 @@ class _CustomizationContentState extends State<_CustomizationContent> { child: Row( children: List.generate( customizationState!.leadingElements.length, (int index) { - ListsLeadingEnum currentElement = + ListLeadingEnum currentElement = customizationState.leadingElements[index]; bool isSelected = currentElement == customizationState.selectedLeadingElement; @@ -207,25 +283,23 @@ class _CustomizationContentState extends State<_CustomizationContent> { scrollDirection: Axis.horizontal, child: Row( children: List.generate( - customizationState.trailingStandardElements.length, - (int index) { - ListsTrailingEnum currentElement = - customizationState.trailingStandardElements[index]; + customizationState.trailingElements.length, (int index) { + ListTrailingEnum currentElement = + customizationState.trailingElements[index]; bool isSelected = currentElement == - customizationState.selectedTrailingStandardElement; + customizationState.selectedTrailingElement; return Padding( padding: EdgeInsets.only(right: spacingXs, left: spacingS), child: OdsChoiceChip( - text: customizationState.trailingStandardElements[index] + text: customizationState.trailingElements[index] .stringValue(context), onClick: (selected) { setState( () { - selectedStandardTrailingIndex = index; + selectedTrailingIndex = index; isTrailingFiltered = selected!; - customizationState.selectedTrailingStandardElement = - customizationState - .trailingStandardElements[index]; + customizationState.selectedTrailingElement = + customizationState.trailingElements[index]; }, ); }, diff --git a/app/lib/ui/components/lists/lists_leading_enum.dart b/app/lib/ui/components/list_item/list_leading_enum.dart similarity index 77% rename from app/lib/ui/components/lists/lists_leading_enum.dart rename to app/lib/ui/components/list_item/list_leading_enum.dart index df718840..7f5e26d5 100644 --- a/app/lib/ui/components/lists/lists_leading_enum.dart +++ b/app/lib/ui/components/list_item/list_leading_enum.dart @@ -13,20 +13,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; -enum ListsLeadingEnum { none, icon, circle, wide, square } +enum ListLeadingEnum { none, icon, circle, wide, square } -extension CustomElementExtension on ListsLeadingEnum { +extension CustomElementExtension on ListLeadingEnum { String stringValue(BuildContext context) { switch (this) { - case ListsLeadingEnum.none: + case ListLeadingEnum.none: return AppLocalizations.of(context)!.listLeadingEnumNone; - case ListsLeadingEnum.icon: + case ListLeadingEnum.icon: return AppLocalizations.of(context)!.listLeadingEnumIcon; - case ListsLeadingEnum.circle: + case ListLeadingEnum.circle: return AppLocalizations.of(context)!.listLeadingEnumCircle; - case ListsLeadingEnum.wide: + case ListLeadingEnum.wide: return AppLocalizations.of(context)!.listLeadingEnumWide; - case ListsLeadingEnum.square: + case ListLeadingEnum.square: return AppLocalizations.of(context)!.listLeadingEnumSquare; default: return ""; diff --git a/app/lib/ui/components/lists/lists_radio_buttons.dart b/app/lib/ui/components/list_item/list_radio_buttons.dart similarity index 100% rename from app/lib/ui/components/lists/lists_radio_buttons.dart rename to app/lib/ui/components/list_item/list_radio_buttons.dart diff --git a/app/lib/ui/components/lists/lists_switches.dart b/app/lib/ui/components/list_item/list_switches.dart similarity index 97% rename from app/lib/ui/components/lists/lists_switches.dart rename to app/lib/ui/components/list_item/list_switches.dart index 913ba444..18921362 100644 --- a/app/lib/ui/components/lists/lists_switches.dart +++ b/app/lib/ui/components/list_item/list_switches.dart @@ -42,8 +42,7 @@ class _ComponentSwitchesListState extends State { title: AppLocalizations.of(context)!.componentCustomizeTitle, ), key: _scaffoldKey, - appBar: - MainAppBar(AppLocalizations.of(context)!.listSwitchesSubtitle), + appBar: MainAppBar(AppLocalizations.of(context)!.listSwitchesTitle), body: _Body()), ); } diff --git a/app/lib/ui/components/lists/lists_trailing_enum.dart b/app/lib/ui/components/list_item/list_trailing_enum.dart similarity index 78% rename from app/lib/ui/components/lists/lists_trailing_enum.dart rename to app/lib/ui/components/list_item/list_trailing_enum.dart index 767f532a..c414913c 100644 --- a/app/lib/ui/components/lists/lists_trailing_enum.dart +++ b/app/lib/ui/components/list_item/list_trailing_enum.dart @@ -13,7 +13,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; -enum ListsTrailingEnum { +enum ListTrailingEnum { none, trailingSwitch, trailingCheckbox, @@ -21,18 +21,18 @@ enum ListsTrailingEnum { trailingInfoButton, } -extension CustomElementExtension on ListsTrailingEnum { +extension CustomElementExtension on ListTrailingEnum { String stringValue(BuildContext context) { switch (this) { - case ListsTrailingEnum.none: + case ListTrailingEnum.none: return AppLocalizations.of(context)!.listTrailingEnumNone; - case ListsTrailingEnum.trailingSwitch: + case ListTrailingEnum.trailingSwitch: return AppLocalizations.of(context)!.listTrailingEnumSwitch; - case ListsTrailingEnum.trailingCheckbox: + case ListTrailingEnum.trailingCheckbox: return AppLocalizations.of(context)!.listTrailingEnumCheckbox; - case ListsTrailingEnum.trailingText: + case ListTrailingEnum.trailingText: return AppLocalizations.of(context)!.listTrailingEnumText; - case ListsTrailingEnum.trailingInfoButton: + case ListTrailingEnum.trailingInfoButton: return AppLocalizations.of(context)!.listTrailingEnumInfoButton; default: return ""; diff --git a/app/lib/ui/components/lists/lists_customization.dart b/app/lib/ui/components/lists/lists_customization.dart deleted file mode 100644 index 05206f65..00000000 --- a/app/lib/ui/components/lists/lists_customization.dart +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Software Name : Orange Design System - * SPDX-FileCopyrightText: Copyright (c) Orange SA - * SPDX-License-Identifier: MIT - * - * This software is distributed under the MIT licence, - * 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 for Android and iOS - */ - -import 'package:flutter/material.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_leading_enum.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_trailing_enum.dart'; - -class _ListsCustomization extends InheritedWidget { - _ListsCustomization({ - Key? key, - required Widget child, - required this.data, - }) : super(key: key, child: child); - - final ListsCustomizationState data; - - @override - bool updateShouldNotify(_ListsCustomization oldWidget) => true; -} - -class ListsCustomization extends StatefulWidget { - const ListsCustomization({ - super.key, - required this.child, - }); - - final Widget child; - - @override - ListsCustomizationState createState() => ListsCustomizationState(); - - static ListsCustomizationState? of(BuildContext context) { - return (context.dependOnInheritedWidgetOfExactType<_ListsCustomization>()) - ?.data; - } -} - -class ListsCustomizationState extends State { - bool _hasSubtitle = true; - - ///Leading Enum - List _leadingElements = [ - ListsLeadingEnum.none, - ListsLeadingEnum.icon, - ListsLeadingEnum.circle, - ListsLeadingEnum.wide, - ListsLeadingEnum.square, - ]; - ListsLeadingEnum _selectedLeadingElement = ListsLeadingEnum.circle; - - ///Trailing Enum - List _trailingElements = [ - ListsTrailingEnum.none, - ListsTrailingEnum.trailingSwitch, - ListsTrailingEnum.trailingCheckbox, - ]; - ListsTrailingEnum _selectedTrailingElement = ListsTrailingEnum.none; - - ///Trailing Standard Enum - List _trailingStandardElements = [ - ListsTrailingEnum.none, - ListsTrailingEnum.trailingText, - ListsTrailingEnum.trailingInfoButton, - ]; - ListsTrailingEnum _selectedTrailingStandardElement = ListsTrailingEnum.none; - - bool get hasSubtitle => _hasSubtitle; - set hasSubtitle(bool value) { - setState(() { - _hasSubtitle = value; - }); - } - - ///Leading Enum - List get leadingElements => _leadingElements; - set leadingElements(List value) { - setState(() { - _leadingElements = value; - }); - } - - ListsLeadingEnum get selectedLeadingElement => _selectedLeadingElement; - - set selectedLeadingElement(ListsLeadingEnum value) { - setState(() { - _selectedLeadingElement = value; - }); - } - - ///Trailing Enum - List get trailingElements => _trailingElements; - set trailingElements(List value) { - setState(() { - _trailingElements = value; - }); - } - - ListsTrailingEnum get selectedTrailingElement => _selectedTrailingElement; - - set selectedTrailingElement(ListsTrailingEnum value) { - setState(() { - _selectedTrailingElement = value; - }); - } - - ///Trailing Standard Enum - List get trailingStandardElements => - _trailingStandardElements; - set trailingStandardElements(List value) { - setState(() { - _trailingStandardElements = value; - }); - } - - ListsTrailingEnum get selectedTrailingStandardElement => - _selectedTrailingStandardElement; - - set selectedTrailingStandardElement(ListsTrailingEnum value) { - setState(() { - _selectedTrailingStandardElement = value; - }); - } - - @override - Widget build(BuildContext context) { - return _ListsCustomization( - data: this, - child: widget.child, - ); - } -} diff --git a/app/lib/ui/components/sheets_bottom/sheets_bottom.dart b/app/lib/ui/components/sheets_bottom/sheets_bottom.dart index 35417932..acf4cdb1 100644 --- a/app/lib/ui/components/sheets_bottom/sheets_bottom.dart +++ b/app/lib/ui/components/sheets_bottom/sheets_bottom.dart @@ -14,7 +14,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; import 'package:ods_flutter/components/app_bar/top/ods_top_app_bar.dart'; import 'package:ods_flutter/components/chips/ods_filter_chips.dart'; -import 'package:ods_flutter/components/lists/ods_list_standard_item.dart'; +import 'package:ods_flutter/components/lists/ods_list_item.dart'; import 'package:ods_flutter/components/sheets_bottom/ods_sheets_bottom.dart'; import 'package:ods_flutter/components/utilities/ods_image_shape.dart'; import 'package:ods_flutter/guidelines/spacings.dart'; @@ -140,7 +140,7 @@ class _CustomizationContentState extends State<_CustomizationContent> { final odsImageShape = OdsImageShape( context, OdsImageShapeEnum.icon.name, recipe.getIconPath()); - return OdsListStandardItem( + return OdsListItem( title: recipe.title, image: odsImageShape.buildImage(), ); diff --git a/app/lib/ui/guidelines/spacings/guideline_spacings_screen.dart b/app/lib/ui/guidelines/spacings/guideline_spacings_screen.dart index 6a86173b..0140114c 100644 --- a/app/lib/ui/guidelines/spacings/guideline_spacings_screen.dart +++ b/app/lib/ui/guidelines/spacings/guideline_spacings_screen.dart @@ -12,7 +12,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; -import 'package:ods_flutter/components/lists/ods_list_standard_item.dart'; +import 'package:ods_flutter/components/lists/ods_list_item.dart'; import 'package:ods_flutter/guidelines/spacings.dart'; import 'package:ods_flutter_demo/ui/guidelines/spacings/guideline_spacings_image.dart'; import 'package:ods_flutter_demo/ui/guidelines/spacings/spacing.dart'; @@ -55,7 +55,7 @@ class GuidelineSpacingsScreen extends StatelessWidget { itemBuilder: (context, index) { var spacing = spacingItems[index]; - return OdsListStandardItem( + return OdsListItem( title: spacing.name, subtitle: "${spacing.rawValue.toInt()} px", image: GuidelineSpacingImage( diff --git a/app/lib/ui/components/lists/lists_selection.dart b/app/lib/ui/modules/lists/module_lists_screen.dart similarity index 76% rename from app/lib/ui/components/lists/lists_selection.dart rename to app/lib/ui/modules/lists/module_lists_screen.dart index 87921ed7..91d0962b 100644 --- a/app/lib/ui/components/lists/lists_selection.dart +++ b/app/lib/ui/modules/lists/module_lists_screen.dart @@ -13,26 +13,25 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; import 'package:ods_flutter/components/chips/ods_choice_chips.dart'; -import 'package:ods_flutter/components/lists/ods_list_selection_item.dart'; +import 'package:ods_flutter/components/lists/ods_list_item.dart'; import 'package:ods_flutter/components/lists/ods_list_switch.dart'; import 'package:ods_flutter/components/sheets_bottom/ods_sheets_bottom.dart'; import 'package:ods_flutter/components/utilities/ods_image_shape.dart'; import 'package:ods_flutter/guidelines/spacings.dart'; import 'package:ods_flutter_demo/main.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_customization.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_leading_enum.dart'; -import 'package:ods_flutter_demo/ui/components/lists/lists_trailing_enum.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_customization.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_leading_enum.dart'; +import 'package:ods_flutter_demo/ui/components/list_item/list_trailing_enum.dart'; import 'package:ods_flutter_demo/ui/main_app_bar.dart'; -class ComponentListsSelection extends StatefulWidget { - const ComponentListsSelection({super.key}); +class ModuleListsStandard extends StatefulWidget { + const ModuleListsStandard({super.key}); @override - State createState() => - _ComponentListsSelectionState(); + State createState() => _ModuleListsStandardState(); } -class _ComponentListsSelectionState extends State { +class _ModuleListsStandardState extends State { final _scaffoldKey = GlobalKey(); @override @@ -42,14 +41,14 @@ class _ComponentListsSelectionState extends State { @override Widget build(BuildContext context) { - return ListsCustomization( + return ListCustomization( child: Scaffold( key: _scaffoldKey, bottomSheet: OdsSheetsBottom( sheetContent: _CustomizationContent(), title: AppLocalizations.of(context)!.componentCustomizeTitle, ), - appBar: MainAppBar(AppLocalizations.of(context)!.listSelectionTitle), + appBar: MainAppBar(AppLocalizations.of(context)!.moduleLists), body: _Body(), ), ); @@ -62,13 +61,13 @@ class _Body extends StatefulWidget { } class _BodyState extends State<_Body> { - List switchValues = List.filled(OdsApplication.recipes.length, true); + List selectionControls = + List.filled(OdsApplication.recipes.length, true); @override Widget build(BuildContext context) { - final ListsCustomizationState? customizationState = - ListsCustomization.of(context); - + final ListCustomizationState? customizationState = + ListCustomization.of(context); var colorScheme = Theme.of(context).colorScheme; return Scaffold( @@ -76,23 +75,22 @@ class _BodyState extends State<_Body> { itemCount: OdsApplication.recipes.length - 4, itemBuilder: (context, index) { var recipe = OdsApplication.recipes[index]; - bool isSwitched = switchValues[index]; - + bool isSelectionControl = selectionControls[index]; var url = ""; switch (customizationState?.selectedLeadingElement ?? "") { - case ListsLeadingEnum.icon: + case ListLeadingEnum.icon: url = recipe.getIconPath(); break; - case ListsLeadingEnum.circle: + case ListLeadingEnum.circle: url = recipe.url; break; - case ListsLeadingEnum.square: + case ListLeadingEnum.square: url = recipe.url; break; - case ListsLeadingEnum.wide: + case ListLeadingEnum.wide: url = recipe.url; break; - case ListsLeadingEnum.none: + case ListLeadingEnum.none: // TODO: Handle this case. break; } @@ -100,29 +98,42 @@ class _BodyState extends State<_Body> { final odsImageShape = OdsImageShape( context, customizationState?.selectedLeadingElement.name, url); - return OdsListSelectionItem( + return OdsListItem( title: recipe.title, subtitle: customizationState?.hasSubtitle == true ? recipe.subtitle : null, image: odsImageShape.buildImage(), - value: isSwitched, + icon: customizationState?.selectedTrailingElement == + ListTrailingEnum.trailingInfoButton + ? IconButton( + onPressed: () {}, + icon: Icon(Icons.info), + color: colorScheme.secondary) + : null, + text: customizationState?.selectedTrailingElement == + ListTrailingEnum.trailingText + ? AppLocalizations.of(context)!.listTrailingExampleDetails + : null, + divider: true, + value: isSelectionControl, onChangedSwitch: customizationState?.selectedTrailingElement == - ListsTrailingEnum.trailingSwitch + ListTrailingEnum.trailingSwitch ? (value) { setState(() { - switchValues[index] = value ?? false; + selectionControls[index] = value ?? false; }); } : null, onChangedCheckBox: customizationState?.selectedTrailingElement == - ListsTrailingEnum.trailingCheckbox + ListTrailingEnum.trailingCheckbox ? (value) { setState(() { - switchValues[index] = value ?? false; + selectionControls[index] = value ?? false; }); } : null, + onClick: () {}, ); }, ), @@ -137,14 +148,14 @@ class _CustomizationContent extends StatefulWidget { class _CustomizationContentState extends State<_CustomizationContent> { int selectedLeadingIndex = 0; - int selectedTrailingIndex = 0; + int selectedStandardTrailingIndex = 0; bool isLeadingFiltered = true; bool isTrailingFiltered = true; @override Widget build(BuildContext context) { - final ListsCustomizationState? customizationState = - ListsCustomization.of(context); + final ListCustomizationState? customizationState = + ListCustomization.of(context); return SafeArea( child: Column( children: [ @@ -172,7 +183,7 @@ class _CustomizationContentState extends State<_CustomizationContent> { child: Row( children: List.generate( customizationState!.leadingElements.length, (int index) { - ListsLeadingEnum currentElement = + ListLeadingEnum currentElement = customizationState.leadingElements[index]; bool isSelected = currentElement == customizationState.selectedLeadingElement; @@ -216,7 +227,7 @@ class _CustomizationContentState extends State<_CustomizationContent> { child: Row( children: List.generate( customizationState.trailingElements.length, (int index) { - ListsTrailingEnum currentElement = + ListTrailingEnum currentElement = customizationState.trailingElements[index]; bool isSelected = currentElement == customizationState.selectedTrailingElement; @@ -228,7 +239,7 @@ class _CustomizationContentState extends State<_CustomizationContent> { onClick: (selected) { setState( () { - selectedTrailingIndex = index; + selectedStandardTrailingIndex = index; isTrailingFiltered = selected!; customizationState.selectedTrailingElement = customizationState.trailingElements[index]; diff --git a/app/lib/ui/modules/modules.dart b/app/lib/ui/modules/modules.dart new file mode 100644 index 00000000..f1408942 --- /dev/null +++ b/app/lib/ui/modules/modules.dart @@ -0,0 +1,26 @@ +/* + * Software Name : Orange Design System + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT licence, + * 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 for Android and iOS + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/ods_flutter_app_localizations.dart'; +import 'package:ods_flutter_demo/ui/modules/lists/module_lists_screen.dart'; +import 'package:ods_flutter_demo/ui/modules/modules_entities.dart'; + +List modules(BuildContext context) { + return [ + Module( + AppLocalizations.of(context)!.moduleLists, + 'assets/il_lists.png', + AppLocalizations.of(context)!.cardSmallVariantTitle, + ModuleListsStandard()), + ]; +} diff --git a/app/lib/ui/modules/modules_entities.dart b/app/lib/ui/modules/modules_entities.dart new file mode 100644 index 00000000..8cdcd04f --- /dev/null +++ b/app/lib/ui/modules/modules_entities.dart @@ -0,0 +1,24 @@ +/* + * Software Name : Orange Design System + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT licence, + * 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 for Android and iOS + */ + +import 'dart:core'; + +import 'package:flutter/material.dart'; + +class Module { + String title; + String imageResourceName; + String description; + Widget screen; + + Module(this.title, this.imageResourceName, this.description, this.screen); +} diff --git a/app/lib/ui/modules/modules_screen.dart b/app/lib/ui/modules/modules_screen.dart index 9cc3bb8e..765872d6 100644 --- a/app/lib/ui/modules/modules_screen.dart +++ b/app/lib/ui/modules/modules_screen.dart @@ -11,13 +11,53 @@ */ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ods_flutter/components/card/ods_cards_common.dart'; +import 'package:ods_flutter/components/card/ods_vertical_image_first_card.dart'; +import 'package:ods_flutter/guidelines/spacings.dart'; +import 'package:ods_flutter_demo/ui/modules/modules_entities.dart'; -class ModulesScreen extends StatelessWidget { +class ModulesScreen extends StatefulWidget { + final List odsModules; + + ModulesScreen({required this.odsModules}); + + @override + State createState() => _ModulesScreenState(); +} + +class _ModulesScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold( - // Scaffold is a basic layout structure for an app screen - body: Container(), // Use an empty container to create an empty screen + return SafeArea( + child: ListView.builder( + itemCount: widget.odsModules.length, + itemBuilder: (context, index) { + var module = widget.odsModules[index]; + return Padding( + padding: const EdgeInsets.all(spacingS), + child: Column( + children: [ + OdsVerticalImageFirstCard( + title: module.title, + image: OdsCardImage( + imageProvider: AssetImage(module.imageResourceName), + contentDescription: '', //Optional + alignment: Alignment.center, + contentScale: BoxFit.cover, + ), + onClick: () { + Get.to( + module.screen, + transition: Transition.rightToLeft, + ); + }, + ), + ], + ), + ); + }, + ), ); } } diff --git a/app/lib/ui/utilities/navigation_items.dart b/app/lib/ui/utilities/navigation_items.dart index 7f8ef528..c05ba700 100644 --- a/app/lib/ui/utilities/navigation_items.dart +++ b/app/lib/ui/utilities/navigation_items.dart @@ -19,6 +19,7 @@ import 'package:ods_flutter_demo/ui/components/components.dart'; import 'package:ods_flutter_demo/ui/components/components_screen.dart'; import 'package:ods_flutter_demo/ui/guidelines/guidelines.dart'; import 'package:ods_flutter_demo/ui/guidelines/guidelines_screen.dart'; +import 'package:ods_flutter_demo/ui/modules/modules.dart'; import 'package:ods_flutter_demo/ui/modules/modules_screen.dart'; class NavigationItems { @@ -82,7 +83,7 @@ class NavigationItems { _screens = [ GuidelinesScreen(odsGuidelines: guidelines(context)), ComponentsScreen(odsComponents: components(context)), - ModulesScreen(), + ModulesScreen(odsModules: modules(context)), AboutScreen(), ]; } diff --git a/library/CHANGELOG.md b/library/CHANGELOG.md index 8561dc31..91949040 100644 --- a/library/CHANGELOG.md +++ b/library/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ODS - Component - Navigation Rail ([#25](https://github.com/Orange-OpenSource/ods-flutter/issues/25)) - ODS - Component - Cards: Title First Card ([#9](https://github.com/Orange-OpenSource/ods-flutter/issues/9)) - About - Page ([#332](https://github.com/Orange-OpenSource/ods-flutter/issues/332)) +- Module - List ([#331](https://github.com/Orange-OpenSource/ods-flutter/issues/331)) ### Changed diff --git a/library/lib/components/lists/ods_list_checkbox.dart b/library/lib/components/lists/ods_list_checkbox.dart index fd1ea2fd..ab3aa7ba 100644 --- a/library/lib/components/lists/ods_list_checkbox.dart +++ b/library/lib/components/lists/ods_list_checkbox.dart @@ -63,7 +63,10 @@ class _OdsListCheckboxState extends State { hint: OdsLocalizations.of(context)!.componentCheckboxes, excludeSemantics: true, child: CheckboxListTile( - title: Text(widget.title), + title: Text( + widget.title, + style: Theme.of(context).textTheme.titleMedium, + ), value: widget.checked, onChanged: widget.enabled != false ? widget.onCheckedChange : null, tristate: widget.indeterminate, diff --git a/library/lib/components/lists/ods_list_selection_item.dart b/library/lib/components/lists/ods_list_item.dart similarity index 79% rename from library/lib/components/lists/ods_list_selection_item.dart rename to library/lib/components/lists/ods_list_item.dart index de87500f..a114039a 100644 --- a/library/lib/components/lists/ods_list_selection_item.dart +++ b/library/lib/components/lists/ods_list_item.dart @@ -18,16 +18,20 @@ import 'package:ods_flutter/components/divider/ods_divider.dart'; /// This list contains content and actions about a single subject. /// /// A ripple effect is managed on list tile. -class OdsListSelectionItem extends StatefulWidget { +class OdsListItem extends StatefulWidget { /// Creates an ODS List selection. - const OdsListSelectionItem({ + const OdsListItem({ Key? key, required this.title, this.subtitle, this.image, + this.text, + this.icon, this.value, this.onChangedSwitch, this.onChangedCheckBox, + this.divider, + this.onClick, }) : super(key: key); /// The list's title . @@ -40,6 +44,12 @@ class OdsListSelectionItem extends StatefulWidget { ///TODO For the moment the fit of the image is handled by the provided image. It should be done in the library but we need help to do that! final Widget? image; + /// The text displayed in the list trailing. + final String? text; + + /// The icon displayed in the list trailing. + final Widget? icon; + /// The optional switch or checkbox. final bool? value; @@ -49,11 +59,17 @@ class OdsListSelectionItem extends StatefulWidget { /// The action executed change the checkbox. final Function(bool?)? onChangedCheckBox; + /// The divider displayed in the list. + final bool? divider; + + /// The action to be executed when the item is pressed. + final void Function()? onClick; + @override - State createState() => _OdsListSelectionItemState(); + State createState() => _OdsListItemState(); } -class _OdsListSelectionItemState extends State { +class _OdsListItemState extends State { @override Widget build(BuildContext context) { return Semantics( @@ -107,8 +123,16 @@ class _OdsListSelectionItemState extends State { style: Theme.of(context).textTheme.bodyLarge, ) : null, + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.text != null) Text(widget.text!), + if (widget.icon != null) widget.icon!, // icon-2 + ], + ), + onTap: widget.onClick, ), - const OdsDivider(), + if (widget.divider != null) const OdsDivider(), ], ), ), diff --git a/library/lib/components/lists/ods_list_radio_button.dart b/library/lib/components/lists/ods_list_radio_button.dart index a88ba881..b10ee6d2 100644 --- a/library/lib/components/lists/ods_list_radio_button.dart +++ b/library/lib/components/lists/ods_list_radio_button.dart @@ -65,7 +65,10 @@ class _OdsRadioButtonState extends State> { hint: OdsLocalizations.of(context)!.componentCheckboxes, excludeSemantics: true, child: RadioListTile( - title: Text(widget.title), + title: Text( + widget.title, + style: Theme.of(context).textTheme.titleMedium, + ), value: widget.value, onChanged: widget.enabled != false ? widget.onCheckedChange : null, groupValue: widget.groupValue, diff --git a/library/lib/components/lists/ods_list_standard_item.dart b/library/lib/components/lists/ods_list_standard_item.dart deleted file mode 100644 index d727ecdf..00000000 --- a/library/lib/components/lists/ods_list_standard_item.dart +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Software Name : Orange Design System - * SPDX-FileCopyrightText: Copyright (c) Orange SA - * SPDX-License-Identifier: MIT - * - * This software is distributed under the MIT licence, - * 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 for Android and iOS - */ - -import 'package:flutter/material.dart'; -import 'package:ods_flutter/components/divider/ods_divider.dart'; - -/// ODS List Selection -/// -/// This list contains content and actions about a single subject. -/// -/// A ripple effect is managed on list tile. -class OdsListStandardItem extends StatefulWidget { - /// Creates an ODS List standard. - const OdsListStandardItem( - {Key? key, - required this.title, - this.subtitle, - this.image, - this.text, - this.icon, - this.divider, - this.onClick}) - : super(key: key); - - /// The list's title . - final String title; - - /// The optional list's subtitle displayed below the title. - final String? subtitle; - - /// The image displayed in the list. - ///TODO For the moment the fit of the image is handled by the provided image. It should be done in the library but we need help to do that! - final Widget? image; - - /// The text displayed in the list trailing. - final String? text; - - /// The icon displayed in the list trailing. - final Widget? icon; - - /// The divider displayed in the list. - final bool? divider; - - /// The action to be executed when the button is pressed. - final void Function()? onClick; - - @override - State createState() => _OdsListStandardItemState(); -} - -class _OdsListStandardItemState extends State { - @override - Widget build(BuildContext context) { - return Semantics( - child: MergeSemantics( - child: Column( - children: [ - ListTile( - leading: widget.image, - title: Text( - widget.title, - style: Theme.of(context).textTheme.bodyMedium, - ), - subtitle: widget.subtitle != null - ? Text( - widget.subtitle!, - style: Theme.of(context).textTheme.bodyMedium, - ) - : null, - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (widget.text != null) Text(widget.text!), - if (widget.icon != null) widget.icon!, // icon-2 - ], - ), - onTap: widget.onClick, - ), - if (widget.divider != null) const OdsDivider(), - ], - ), - ), - ); - } -} diff --git a/library/lib/components/lists/ods_list_switch.dart b/library/lib/components/lists/ods_list_switch.dart index df073a19..bdecd313 100644 --- a/library/lib/components/lists/ods_list_switch.dart +++ b/library/lib/components/lists/ods_list_switch.dart @@ -66,8 +66,10 @@ class _OdsListSwitchState extends State { button: true, excludeSemantics: true, child: SwitchListTile( - title: - Text(widget.title, style: Theme.of(context).textTheme.bodyMedium), + title: Text( + widget.title, + style: Theme.of(context).textTheme.titleMedium, + ), value: widget.checked, onChanged: widget.enabled != false ? widget.onCheckedChange : null, thumbIcon: widget.icon == true ? odsSwitchIcon.thumbIcon : null,