Skip to content

Commit

Permalink
fix(UX-1129): Add didUpdateStates to StatefulWidgets (#138)
Browse files Browse the repository at this point in the history
fix(UX-1129): Accordion, Chip, StepperInput didUpdateState
fix: FAB expanded state
fix: Make Navigation rail and list item stateless
fix: Add min/max values in slider
chore: Refactor existing didUpdateWidgets to best practices - remove setStates and put super call first
test: Accordion, Chip, StepperInput didUpdateState, 
test: Improve existing accordion tests
test: FAB expanded state
test: Min/max values in slider
  • Loading branch information
thelukewalton authored Jul 23, 2024
1 parent d99d40c commit 7905388
Show file tree
Hide file tree
Showing 26 changed files with 528 additions and 113 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
with:
cache: true
- run: dart run build_runner build --delete-conflicting-outputs
- uses: ZebraDevs/[email protected].6
- uses: ZebraDevs/[email protected].7
with:
token: ${{secrets.GITHUB_TOKEN}}

Expand Down
14 changes: 7 additions & 7 deletions example/lib/pages/components/button_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class _ButtonExampleState extends State<ButtonExample> {
scrollController: _scrollController,
label: 'Small Circle Primary',
size: ZetaFabSize.small,
initiallyExpanded: false,
expanded: false,
shape: ZetaWidgetBorder.full,
type: ZetaFabType.primary,
),
ZetaFAB(
scrollController: _scrollController,
initiallyExpanded: false,
expanded: false,
label: 'Small Rounded Primary',
size: ZetaFabSize.small,
shape: ZetaWidgetBorder.rounded,
Expand All @@ -56,7 +56,7 @@ class _ButtonExampleState extends State<ButtonExample> {
label: 'Small Sharp Primary',
size: ZetaFabSize.small,
shape: ZetaWidgetBorder.sharp,
initiallyExpanded: false,
expanded: false,
type: ZetaFabType.inverse,
onPressed: () => setFab(2),
),
Expand All @@ -66,15 +66,15 @@ class _ButtonExampleState extends State<ButtonExample> {
size: ZetaFabSize.large,
shape: ZetaWidgetBorder.full,
type: ZetaFabType.secondary,
initiallyExpanded: false,
expanded: false,
onPressed: () => setFab(3),
),
ZetaFAB(
scrollController: _scrollController,
label: 'Large Rounded Secondary',
size: ZetaFabSize.large,
shape: ZetaWidgetBorder.rounded,
initiallyExpanded: false,
expanded: false,
type: ZetaFabType.inverse,
onPressed: () => setFab(4),
),
Expand All @@ -84,7 +84,7 @@ class _ButtonExampleState extends State<ButtonExample> {
size: ZetaFabSize.large,
shape: ZetaWidgetBorder.sharp,
type: ZetaFabType.primary,
initiallyExpanded: false,
expanded: false,
onPressed: () => setFab(5),
),
];
Expand All @@ -93,7 +93,7 @@ class _ButtonExampleState extends State<ButtonExample> {
return ExampleScaffold(
name: 'Button',
floatingActionButton: ZetaFAB(
initiallyExpanded: true,
expanded: true,
icon: theFab.icon,
label: theFab.label,
scrollController: _scrollController,
Expand Down
2 changes: 1 addition & 1 deletion example/lib/pages/components/stepper_input_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class _StepperInputExampleState extends State<StepperInputExample> {
ZetaStepperInput(
min: 0,
max: 10,
initialValue: 5,
value: 5,
onChange: (_) {},
),
ZetaStepperInput(),
Expand Down
2 changes: 1 addition & 1 deletion example/widgetbook/pages/components/button_widgetbook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class _FabWidgetState extends State<FabWidget> {
itemBuilder: (context, index) => Text("$index"),
),
floatingActionButton: ZetaFAB(
initiallyExpanded: true,
expanded: true,
scrollController: _scrollController,
label: widget.c.knobs.string(label: 'Label', initialValue: 'Floating Action Button'),
onPressed: widget.c.knobs.boolean(label: 'Disabled') ? null : () {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import '../../utils/utils.dart';
Widget stepperInputUseCase(BuildContext context) {
return WidgetbookScaffold(
builder: (context, _) => ZetaStepperInput(
initialValue: context.knobs.int.input(label: 'Initial value'),
value: context.knobs.int.input(label: 'Value'),
min: context.knobs.int.input(label: 'Minimum value', initialValue: 0),
max: context.knobs.int.input(label: 'Maximum value', initialValue: 10),
size: context.knobs.list(
Expand Down
14 changes: 10 additions & 4 deletions lib/src/components/accordion/accordion.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,24 @@ class _ZetaAccordionState extends State<ZetaAccordion> with TickerProviderStateM
parent: _controller,
curve: Curves.fastOutSlowIn,
);
init();
setInitialOpen();
_disabled = widget.child == null;
}

@override
void didUpdateWidget(ZetaAccordion oldWidget) {
init();
super.didUpdateWidget(oldWidget);
if (oldWidget.isOpen != widget.isOpen) {
setInitialOpen();
}
if (oldWidget.child != widget.child) {
_disabled = widget.child == null;
}
}

void init() {
void setInitialOpen() {
_isOpen = widget.isOpen;
_disabled = widget.child == null;
_controller.value = _isOpen ? 1 : 0;
}

@override
Expand Down
8 changes: 3 additions & 5 deletions lib/src/components/breadcrumbs/breadcrumbs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,11 @@ class _ZetaBreadCrumbsState extends State<ZetaBreadCrumbs> {

@override
void didUpdateWidget(ZetaBreadCrumbs oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.children.length != _children.length) {
setState(() {
_selectedIndex = widget.children.length - 1;
_children = [...widget.children];
});
_selectedIndex = widget.children.length - 1;
_children = [...widget.children];
}
super.didUpdateWidget(oldWidget);
}

@override
Expand Down
8 changes: 0 additions & 8 deletions lib/src/components/button_group/button_group.dart
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,6 @@ class _ZetaGroupButtonState extends State<ZetaGroupButton> {
_controller.dispose();
}

@override
void didUpdateWidget(ZetaGroupButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.onPressed != widget.onPressed) {
setState(() {});
}
}

double get _padding => widget.isLarge ? ZetaSpacing.large : ZetaSpacing.medium;

BorderSide _getBorderSide(
Expand Down
8 changes: 8 additions & 0 deletions lib/src/components/chips/chip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ class _ZetaChipState extends State<ZetaChip> {
selected = widget.selected ?? false;
}

@override
void didUpdateWidget(covariant ZetaChip oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.selected != widget.selected) {
selected = widget.selected ?? false;
}
}

Widget _renderLeading(Color foregroundColor) {
if (widget.leading.runtimeType == Icon) {
return IconTheme(data: IconThemeData(color: foregroundColor, size: ZetaSpacing.xl_1), child: widget.leading!);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export 'select_input/select_input.dart';
export 'slider/slider.dart';
export 'snack_bar/snack_bar.dart';
export 'stepper/stepper.dart';
export 'stepper_input/stepper_input.dart';
export 'stepper_input/stepper_input.dart' hide ZetaStepperInputState;
export 'switch/zeta_switch.dart';
export 'tabs/tab.dart';
export 'tabs/tab_bar.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/dropdown/dropdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class ZetaDropDownState<T> extends State<ZetaDropdown<T>> {
void didUpdateWidget(ZetaDropdown<T> oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.value != widget.value) {
setState(_setSelectedItem);
_setSelectedItem();
}
if (oldWidget.size != widget.size) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Expand Down
18 changes: 10 additions & 8 deletions lib/src/components/fabs/fab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ class ZetaFAB extends StatefulWidget {
this.size = ZetaFabSize.small,
this.shape = ZetaWidgetBorder.full,
this.icon = ZetaIcons.add,
this.initiallyExpanded,
bool? expanded,
@Deprecated('Please use expanded instead. ' 'Deprecated in 0.15.0') bool? initiallyExpanded,
this.focusNode,
super.key,
});
}) : expanded = expanded ?? initiallyExpanded ?? label != null;

/// Defines the color of the button.
///
Expand Down Expand Up @@ -80,7 +81,9 @@ class ZetaFAB extends StatefulWidget {
/// Whether the FAB starts as expanded.
///
/// If [scrollController] or [label] are null, this is the permanent state of the FAB.
final bool? initiallyExpanded;
///
/// If the [label] is not null, the FAB will initialize as expanded.
final bool expanded;

/// {@macro flutter.widgets.Focus.focusNode}
final FocusNode? focusNode;
Expand All @@ -99,15 +102,14 @@ class ZetaFAB extends StatefulWidget {
..add(DiagnosticsProperty<ScrollController>('scrollController', scrollController))
..add(StringProperty('label', label))
..add(DiagnosticsProperty<IconData>('icon', icon))
..add(DiagnosticsProperty<bool>('initiallyExpanded', initiallyExpanded))
..add(DiagnosticsProperty<bool>('initiallyExpanded', expanded))
..add(DiagnosticsProperty<FocusNode>('focusNode', focusNode));
}
}

class _ZetaFABState extends State<ZetaFAB> {
@override
Widget build(BuildContext context) {
final bool isExpanded = (widget.initiallyExpanded != null ? widget.initiallyExpanded! : widget.label != null);
final colors = widget.type.colors(context);
final backgroundColor = widget.type == ZetaFabType.inverse ? colors.shade80 : colors.shade60;

Expand All @@ -116,7 +118,7 @@ class _ZetaFABState extends State<ZetaFAB> {
focusNode: widget.focusNode,
style: ButtonStyle(
padding: const WidgetStatePropertyAll(EdgeInsets.zero),
shape: WidgetStatePropertyAll(widget.shape.buttonShape(isExpanded: isExpanded, size: widget.size)),
shape: WidgetStatePropertyAll(widget.shape.buttonShape(isExpanded: widget.expanded, size: widget.size)),
backgroundColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.disabled)) {
return Zeta.of(context).colors.surfaceDisabled;
Expand All @@ -142,14 +144,14 @@ class _ZetaFABState extends State<ZetaFAB> {
child: AnimatedContainer(
duration: ZetaAnimationLength.normal,
child: Padding(
padding: isExpanded
padding: widget.expanded
? const EdgeInsets.symmetric(horizontal: ZetaSpacingBase.x3_5, vertical: ZetaSpacing.medium)
: EdgeInsets.all(widget.size.padding),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
ZetaIcon(widget.icon, size: widget.size.iconSize),
if (isExpanded && widget.label != null)
if (widget.expanded && widget.label != null)
Row(
mainAxisSize: MainAxisSize.min,
children: [Text(widget.label!, style: ZetaTextStyles.labelLarge)],
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/list_item/dropdown_list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ class _ZetaDropdownListItemState extends State<ZetaDropdownListItem> with Single

@override
void didUpdateWidget(covariant ZetaDropdownListItem oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.expanded != widget.expanded) {
_setExpanded(widget.expanded);
}
super.didUpdateWidget(oldWidget);
}

@override
Expand Down
30 changes: 12 additions & 18 deletions lib/src/components/list_item/notification_list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import '../../../zeta_flutter.dart';

/// Notification list items are used in notification lists.
/// {@category Components}
class ZetaNotificationListItem extends ZetaStatefulWidget {
class ZetaNotificationListItem extends ZetaStatelessWidget {
/// Constructor for [ZetaNotificationListItem]
const ZetaNotificationListItem({
super.key,
Expand Down Expand Up @@ -46,9 +46,6 @@ class ZetaNotificationListItem extends ZetaStatefulWidget {
/// {@macro zeta-widget-semantic-label}
final String? semanticLabel;

@override
State<ZetaNotificationListItem> createState() => _ZetaNotificationListItemState();

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
Expand All @@ -59,17 +56,15 @@ class ZetaNotificationListItem extends ZetaStatefulWidget {
..add(DiagnosticsProperty<bool?>('showDivider', showDivider))
..add(StringProperty('semanticLabel', semanticLabel));
}
}

class _ZetaNotificationListItemState extends State<ZetaNotificationListItem> {
@override
Widget build(BuildContext context) {
final colors = Zeta.of(context).colors;
return ZetaRoundedScope(
rounded: context.rounded,
child: Semantics(
explicitChildNodes: true,
label: widget.semanticLabel,
label: semanticLabel,
button: true,
child: DecoratedBox(
decoration: _getStyle(colors),
Expand All @@ -81,7 +76,7 @@ class _ZetaNotificationListItemState extends State<ZetaNotificationListItem> {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.leading,
leading,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expand All @@ -92,23 +87,23 @@ class _ZetaNotificationListItemState extends State<ZetaNotificationListItem> {
MergeSemantics(
child: Row(
children: [
if (!widget.notificationRead)
if (!notificationRead)
ZetaIndicator(
color: colors.blue,
size: ZetaWidgetSize.small,
),
Text(
widget.title,
title,
style: ZetaTextStyles.labelLarge,
),
],
),
),
Row(
children: [
if (widget.notificationTime != null)
if (notificationTime != null)
Text(
widget.notificationTime!,
notificationTime!,
style: ZetaTextStyles.bodySmall.apply(color: colors.textDisabled),
),
Container(
Expand All @@ -125,13 +120,13 @@ class _ZetaNotificationListItemState extends State<ZetaNotificationListItem> {
),
],
),
widget.body,
body,
].gap(ZetaSpacing.minimum),
),
),
].gap(ZetaSpacing.small),
),
Container(alignment: Alignment.centerRight, child: widget.action),
Container(alignment: Alignment.centerRight, child: action),
],
).paddingAll(ZetaSpacing.small),
),
Expand All @@ -141,11 +136,10 @@ class _ZetaNotificationListItemState extends State<ZetaNotificationListItem> {

BoxDecoration _getStyle(ZetaColors colors) {
return BoxDecoration(
color: widget.notificationRead ? colors.surfacePrimary : colors.surfaceSelected,
color: notificationRead ? colors.surfacePrimary : colors.surfaceSelected,
borderRadius: ZetaRadius.rounded,
border: (widget.showDivider ?? false)
? Border(bottom: BorderSide(width: ZetaSpacing.minimum, color: colors.blue))
: null,
border:
(showDivider ?? false) ? Border(bottom: BorderSide(width: ZetaSpacing.minimum, color: colors.blue)) : null,
);
}
}
Expand Down
Loading

0 comments on commit 7905388

Please sign in to comment.