diff --git a/lib/src/components/accordion/accordion.dart b/lib/src/components/accordion/accordion.dart index 43f7981..cca6a6b 100644 --- a/lib/src/components/accordion/accordion.dart +++ b/lib/src/components/accordion/accordion.dart @@ -3,73 +3,71 @@ import 'package:flutter_dsfr/flutter_dsfr.dart'; import 'package:flutter_dsfr/src/components/accordion/accordion_border.dart'; import 'package:flutter_dsfr/src/components/accordion/accordion_panel.dart'; +/// {@template accordion_data} /// Create an Accordion . /// Must be render inside a Scrollable widget /// /// Specs: https://gouvfr.atlassian.net/wiki/spaces/DB/pages/312082509/Accord+on+-+Accordion +/// {@endtemplate} class DSFRAccordion extends StatefulWidget { + /// {@macro accordion_data} const DSFRAccordion({required this.panels, super.key}); final List panels; @override - State createState() => _DSFRAccordionState(); + State createState() => _DSFRAccordionState(); } class _DSFRAccordionState extends State { - UniqueKey? _accordionValue; - late final _itemsValues = + UniqueKey? accordionValue; + late final itemsValues = List.generate(widget.panels.length, (_) => UniqueKey()); - late final _panels = widget.panels; + late final panels = widget.panels; + bool initialized = false; @override void initState() { super.initState(); - _setDefaultAccordionValue(); + setDefaultAccordionValue(); } - // ! this should only be called once in initState - void _setDefaultAccordionValue() { + void setDefaultAccordionValue() { + if (initialized) return; final lastInitialyExpandedIndex = - _panels.lastIndexWhere((panelData) => panelData.isInitialyExpanded); + panels.lastIndexWhere((panelData) => panelData.isInitialyExpanded); if (lastInitialyExpandedIndex != -1 && - _itemsValues.length == _panels.length) { - _accordionValue = _itemsValues[lastInitialyExpandedIndex]; + itemsValues.length == panels.length) { + accordionValue = itemsValues[lastInitialyExpandedIndex]; } + initialized = true; } - List _renderPanels() { - final children = []; + Iterable renderPanels() sync* { + for (var i = 0; i < panels.length; i++) { + final isLastInGroup = i == panels.length - 1; + final panelData = panels[i]; - for (var i = 0; i < _panels.length; i++) { - final isLastInGroup = i == _panels.length - 1; - final panelData = _panels[i]; - - final child = DSFRAccordionBorder( + yield DSFRAccordionBorder( isLastInGroup: isLastInGroup, child: DSFRAccordionPanel( data: panelData, - accordionValue: _accordionValue, - itemValue: _itemsValues[i], + accordionValue: accordionValue, + itemValue: itemsValues[i], onExpandedChange: (newValue) { - setState(() { - _accordionValue = newValue; - }); + setState(() => accordionValue = newValue); }, ), ); - - children.add(child); } - - return children; } @override Widget build(BuildContext context) { return Column( - children: _renderPanels(), + mainAxisSize: MainAxisSize.min, + children: [...renderPanels()], ); } } diff --git a/lib/src/components/accordion/accordion_panel.dart b/lib/src/components/accordion/accordion_panel.dart index 80b3c91..a2ab160 100644 --- a/lib/src/components/accordion/accordion_panel.dart +++ b/lib/src/components/accordion/accordion_panel.dart @@ -12,52 +12,17 @@ class DSFRAccordionPanel extends StatelessWidget { }); final DSFRAccordionData data; - final void Function(UniqueKey?) onExpandedChange; + final ValueChanged onExpandedChange; final UniqueKey? accordionValue; final UniqueKey itemValue; - bool get _isExpanded => itemValue == accordionValue; - - Widget _getTitle( - BuildContext context, { - required DSFRTypography dsfrTypography, - required DSFRColors dsfrColors, - }) { - if (_isExpanded) { - return Text( - data.title, - style: dsfrTypography.boldText.copyWith( - color: dsfrColors.text, - ), - ); - } - - return Text( - data.title, - style: - DefaultTextStyle.of(context).style.copyWith(color: dsfrColors.text), - ); - } - - Widget _getTrailingIcon({ - required DSFRColors dsfrColors, - required DSFRSizes dsfrSizes, - }) { - final iconData = _isExpanded ? DSFRIcons.substract : DSFRIcons.add; - - return Icon( - iconData, - color: dsfrColors.text, - size: dsfrSizes.w2, - ); - } - @override Widget build(BuildContext context) { final dsfrTheme = DSFRThemeData.of(context); final dsfrTypography = dsfrTheme.typography; final dsfrColors = dsfrTheme.colors; final dsfrSizes = dsfrTheme.sizes; + final isExpanded = itemValue == accordionValue; return Theme( data: Theme.of(context).copyWith( @@ -75,14 +40,19 @@ class DSFRAccordionPanel extends StatelessWidget { onExpandedChange(null); } }, - isExpanded: _isExpanded, - title: _getTitle( - context, - dsfrTypography: dsfrTypography, - dsfrColors: dsfrColors, + isExpanded: isExpanded, + title: DefaultTextStyle( + style: (isExpanded + ? dsfrTypography.boldText + : dsfrTypography.defaultText) + .copyWith(color: dsfrColors.text), + child: Text(data.title), + ), + trailing: Icon( + isExpanded ? DSFRIcons.substract : DSFRIcons.add, + color: dsfrColors.text, + size: dsfrSizes.w2, ), - trailing: - _getTrailingIcon(dsfrColors: dsfrColors, dsfrSizes: dsfrSizes), child: data.content, ), ); diff --git a/test/components/accordion/accordion_robot.dart b/test/components/accordion/accordion_robot.dart index e6bf814..989de15 100644 --- a/test/components/accordion/accordion_robot.dart +++ b/test/components/accordion/accordion_robot.dart @@ -13,23 +13,16 @@ class AccordionRobot { }) async { await tester.pumpWidget( MaterialApp( - home: Material( - child: Theme( - data: ThemeData( - fontFamily: DSFRFonts.marianne, - brightness: Brightness.light, - extensions: const [ - DSFRTypography.medium(), - DSFRColors.light(), - DSFRSizes.regular(), - ], - ), - child: SingleChildScrollView( - child: DSFRAccordion( - panels: panels, - ), - ), - ), + theme: ThemeData( + useMaterial3: false, + fontFamily: DSFRFonts.marianne, + brightness: Brightness.light, + extensions: const [ + DSFRThemeData(colors: DSFRColors.light()), + ], + ), + home: SingleChildScrollView( + child: DSFRAccordion(panels: panels), ), ), ); diff --git a/test/components/accordion/accordion_widget_test.dart b/test/components/accordion/accordion_widget_test.dart index 7b16bd2..04c0f91 100644 --- a/test/components/accordion/accordion_widget_test.dart +++ b/test/components/accordion/accordion_widget_test.dart @@ -38,18 +38,14 @@ void main() { testWidgets( 'it have a radio like logic, only one content can be open at a time', (tester) async { - final panels = [ - const DSFRAccordionData( + const panels = [ + DSFRAccordionData( title: titleText, - content: Text( - contentText1, - ), + content: Text(contentText1), ), - const DSFRAccordionData( + DSFRAccordionData( title: titleText, - content: Text( - contentText2, - ), + content: Text(contentText2), ), ]; diff --git a/test/components/accordion/goldens/ci/accordion_dark.png b/test/components/accordion/goldens/ci/accordion_dark.png index 1547da3..0601695 100644 Binary files a/test/components/accordion/goldens/ci/accordion_dark.png and b/test/components/accordion/goldens/ci/accordion_dark.png differ diff --git a/test/components/accordion/goldens/ci/accordion_light.png b/test/components/accordion/goldens/ci/accordion_light.png index 61003cf..525efb2 100644 Binary files a/test/components/accordion/goldens/ci/accordion_light.png and b/test/components/accordion/goldens/ci/accordion_light.png differ diff --git a/test/components/buttons/goldens/ci/france_connect_button.png b/test/components/buttons/goldens/ci/france_connect_button.png index 9e2ea4c..a2a198f 100644 Binary files a/test/components/buttons/goldens/ci/france_connect_button.png and b/test/components/buttons/goldens/ci/france_connect_button.png differ diff --git a/test/components/buttons/goldens/ci/france_connect_button_dark.png b/test/components/buttons/goldens/ci/france_connect_button_dark.png index e296964..df66017 100644 Binary files a/test/components/buttons/goldens/ci/france_connect_button_dark.png and b/test/components/buttons/goldens/ci/france_connect_button_dark.png differ