Skip to content

Commit

Permalink
Update group button
Browse files Browse the repository at this point in the history
  • Loading branch information
thelukewalton committed Mar 8, 2024
1 parent 549f168 commit 48bb26b
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 86 deletions.
57 changes: 25 additions & 32 deletions example/lib/pages/components/button_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,10 @@ class _ButtonExampleState extends State<ButtonExample> {
Column(
children: groupButtons(ZetaWidgetBorder.rounded),
),
Text('Floating Action Buttons',
style: ZetaTextStyles.displayMedium),
Text('Tap buttons to change current FAB: ',
style: ZetaTextStyles.bodyMedium),
Wrap(
children:
fabs.divide(SizedBox.square(dimension: 10)).toList()),
]
.divide(const SizedBox.square(dimension: ZetaSpacing.m))
.toList(),
Text('Floating Action Buttons', style: ZetaTextStyles.displayMedium),
Text('Tap buttons to change current FAB: ', style: ZetaTextStyles.bodyMedium),
Wrap(children: fabs.divide(SizedBox.square(dimension: 10)).toList()),
].divide(const SizedBox.square(dimension: ZetaSpacing.m)).toList(),
),
),
Expanded(child: const SizedBox()),
Expand Down Expand Up @@ -178,63 +172,62 @@ class _ButtonExampleState extends State<ButtonExample> {

List<Widget> groupButtons(ZetaWidgetBorder) {
return [
ZetaButtonGroup(
isLarge: true,
rounded: true,
buttons: [
GroupButton(
ZetaButtonGroup(isLarge: true, rounded: true, buttons: [
ZetaGroupButton(
onPressed: () {},
label: "Label",
),
GroupButton(
ZetaGroupButton(
onPressed: () {},
label: "Label",
),
]),
ZetaButtonGroup(
isLarge: true,
rounded: true,
buttons: [
GroupButton(
ZetaButtonGroup(isLarge: true, rounded: true, buttons: [
ZetaGroupButton(
onPressed: () {},
label: "Label",
),
GroupButton.dropdown(
ZetaGroupButton.dropdown(
onPressed: () {},
label: "Label",
dropdown: SizedBox(height: 100, width: 100),
),
]),
ZetaButtonGroup(
isLarge: true,
rounded: true,
isLarge: true,
rounded: true,
buttons: [
GroupButton.icon(
ZetaGroupButton.icon(
icon: ZetaIcons.star_round,
onPressed: () {},
label: "Label",
),
GroupButton.dropdown(
ZetaGroupButton.dropdown(
onPressed: () {},
label: "Label",
dropdown: SizedBox(height: 100, width: 100),
),
GroupButton.icon(

ZetaGroupButton.icon(
icon: ZetaIcons.star_round,
label: "Label",
),
],
),
ZetaButtonGroup(
isLarge: true,
rounded: true,
rounded: true,
buttons: [
GroupButton.icon(
ZetaGroupButton.icon(
icon: ZetaIcons.star_round,
label: "Label",
onPressed: () {},
),
GroupButton.icon(
ZetaGroupButton.icon(
icon: ZetaIcons.star_round,
label: "Label",
onPressed: () {},
),
GroupButton.icon(
ZetaGroupButton.icon(
icon: ZetaIcons.star_round,
label: "Label",
onPressed: () {},
Expand Down
18 changes: 12 additions & 6 deletions example/widgetbook/pages/components/button_widgetbook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,31 @@ Widget iconButtonUseCase(BuildContext context) {
Widget buttonGroupUseCase(BuildContext context) {
final bool rounded = roundedKnob(context);

final onPressed = context.knobs.boolean(label: 'Disabled', initialValue: false) ? null : () {};

return WidgetbookTestWidget(
widget: ZetaButtonGroup(
isLarge: context.knobs.boolean(label: 'Large'),
rounded: rounded,
isInverse: context.knobs.boolean(label: 'Inverse'),
buttons: [
GroupButton(
ZetaGroupButton(
label: context.knobs.string(label: 'Button 1 Title', initialValue: 'Button'),
onPressed: context.knobs.boolean(label: 'Button 1 Dropdown') ? () {} : null,
onPressed: onPressed,
icon: iconKnob(context, name: 'Button 1 Icon', nullable: true, initial: null, rounded: rounded),
dropdown: context.knobs.boolean(label: 'Button 1 Dropdown') ? Container() : null,
),
GroupButton(
ZetaGroupButton(
label: context.knobs.string(label: 'Button 2 Title'),
onPressed: context.knobs.boolean(label: 'Button 2 Dropdown', initialValue: true) ? () {} : null,
onPressed: onPressed,
icon: iconKnob(context, name: 'Button 2 Icon', nullable: true, initial: null, rounded: rounded),
dropdown: context.knobs.boolean(label: 'Button 2 Dropdown') ? Container() : null,
),
GroupButton(
ZetaGroupButton(
label: context.knobs.string(label: 'Button 3 Title'),
onPressed: context.knobs.boolean(label: 'Button 3 Dropdown') ? () {} : null,
onPressed: onPressed,
icon: iconKnob(context, name: 'Button 3 Icon', nullable: true, initial: null, rounded: rounded),
dropdown: context.knobs.boolean(label: 'Button 3 Dropdown') ? Container() : null,
)
],
));
Expand Down
110 changes: 62 additions & 48 deletions lib/src/components/buttons/button_group.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,26 @@ import '../../../zeta_flutter.dart';

/// Zeta Button Group
class ZetaButtonGroup extends StatelessWidget {
/// Constructs [ZetaButtonGroup] from a list of [GroupButton]s
/// Constructs [ZetaButtonGroup] from a list of [ZetaGroupButton]s
const ZetaButtonGroup({
super.key,
required this.buttons,
required this.rounded,
required this.isLarge,
this.isInverse = false,
});

/// Determines size of [GroupButton]
/// Determines size of [ZetaGroupButton].
final bool isLarge;

/// Determinses border radius of [GroupButton]
/// {@macro zeta-component-rounded}
final bool rounded;

/// [GroupButton]s to be rendered in list
final List<GroupButton> buttons;
/// [ZetaGroupButton]s to be rendered in list.
final List<ZetaGroupButton> buttons;

/// If widget should be rendered in inverted colors.
final bool isInverse;

@override
Widget build(BuildContext context) {
Expand All @@ -30,13 +34,14 @@ class ZetaButtonGroup extends StatelessWidget {
);
}

/// Returns [GroupButton]s with there appropriate styling.
List<GroupButton> getButtons() {
/// Returns [ZetaGroupButton]s with there appropriate styling.
List<ZetaGroupButton> getButtons() {
for (final element in buttons) {
element
.._isInitial = element._isFinal = false
.._isLarge = isLarge
.._rounded = rounded;
.._rounded = rounded
.._isInverse = isInverse;
}

buttons.first._isInitial = true;
Expand All @@ -50,64 +55,75 @@ class ZetaButtonGroup extends StatelessWidget {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty<bool>('isLarge', isLarge))
..add(DiagnosticsProperty<bool>('rounded', rounded));
..add(DiagnosticsProperty<bool>('rounded', rounded))
..add(DiagnosticsProperty<bool>('isInverse', isInverse));
}
}

// TODO(UX-854): Create country variant.

/// Group Button item
// ignore: must_be_immutable
class GroupButton extends StatefulWidget {
/// Constructs [GroupButton]
GroupButton({
class ZetaGroupButton extends StatefulWidget {
/// Constructs [ZetaGroupButton]
ZetaGroupButton({
super.key,
this.label,
this.icon,
this.onPressed,
this.dropdown,
});

/// Constructs dropdown group button
GroupButton.dropdown({
ZetaGroupButton.dropdown({
super.key,
required this.onPressed,
required this.dropdown,
this.icon,
this.label,
});

///Constructs group button with icon
GroupButton.icon({
ZetaGroupButton.icon({
super.key,
required this.icon,
this.dropdown,
this.onPressed,
this.label,
});

/// Label for [GroupButton]
/// Label for [ZetaGroupButton].
final String? label;

/// Optional icon for [GroupButton]
/// Optional icon for [ZetaGroupButton].
final IconData? icon;

/// Function for when [GroupButton] is clicked.
/// Function for when [ZetaGroupButton] is clicked.
final VoidCallback? onPressed;

///If [GroupButton] is large
/// Content of dropdown.
final Widget? dropdown;

///If [ZetaGroupButton] is large.
bool _isLarge = false;

///If [GroupButton] is rounded
///If [ZetaGroupButton] is rounded.
bool _rounded = false;

/// If [GroupButton] is the first button in its list.
/// If [ZetaGroupButton] is the first button in its list.
bool _isInitial = false;

/// If [GroupButton] is the final button in its list.
/// If [ZetaGroupButton] is the final button in its list.
bool _isFinal = false;

bool _isInverse = false;

@override
State<GroupButton> createState() => _GroupButtonState();
State<ZetaGroupButton> createState() => _ZetaGroupButtonState();

/// Returns copy of [GroupButton] with fields.
GroupButton copyWith({bool? isFinal, bool? isInitial}) {
return GroupButton(
/// Returns copy of [ZetaGroupButton] with fields.
ZetaGroupButton copyWith({bool? isFinal, bool? isInitial}) {
return ZetaGroupButton(
key: key,
label: label,
icon: icon,
Expand All @@ -125,21 +141,18 @@ class GroupButton extends StatefulWidget {
}
}

class _GroupButtonState extends State<GroupButton> {
late bool selected;
class _ZetaGroupButtonState extends State<ZetaGroupButton> {
late MaterialStatesController controller;

@override
void initState() {
super.initState();
selected = false;
controller = MaterialStatesController();
}

void onPressed() {
widget.onPressed?.call();
setState(() {
selected = !selected;
controller.addListener(() {
if (!controller.value.contains(MaterialState.disabled) && context.mounted && mounted) {
// TODO(UX-1005): setState causing exception when going from disabled to enabled.
setState(() {});
}
});
}

Expand All @@ -157,22 +170,27 @@ class _GroupButtonState extends State<GroupButton> {
top: borderSide,
left: borderSide,
bottom: borderSide,
right: (widget._isFinal) ? borderSide : BorderSide.none,
right: controller.value.contains(MaterialState.focused)
? BorderSide(color: colors.blue.shade50, width: 2)
: (widget._isFinal)
? borderSide
: BorderSide.none,
),
borderRadius: _getRadius(borderType),
),
padding: EdgeInsets.zero,
child: FilledButton(
statesController: controller,
onPressed: onPressed,
onPressed: widget.onPressed, // TODO(UX-1006): Dropdown
style: getStyle(borderType, colors),
child: SelectionContainer.disabled(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (widget.icon != null) Icon(widget.icon),
Text(widget.label!),
if (widget.onPressed != null) const Icon(ZetaIcons.expand_more_round),
if (widget.dropdown != null) // TODO(UX-1006): Dropdown
Icon(widget._rounded ? ZetaIcons.expand_more_round : ZetaIcons.expand_more_sharp, size: 20),
],
).paddingAll(_padding),
),
Expand All @@ -187,13 +205,13 @@ class _GroupButtonState extends State<GroupButton> {
ZetaColors colors,
bool finalButton,
) {
if (selected) return BorderSide(color: colors.black);
if (states.contains(MaterialState.focused)) {
return BorderSide(color: colors.blue.shade50, width: ZetaSpacing.x0_5);
}
if (widget._isInverse) return BorderSide(color: colors.black);
if (states.contains(MaterialState.disabled)) {
return BorderSide(color: colors.cool.shade40);
}
if (states.contains(MaterialState.focused)) {
return BorderSide(color: colors.blue, width: ZetaSpacing.x0_5);
}
return BorderSide(
color: finalButton ? colors.borderDefault : colors.borderSubtle,
);
Expand Down Expand Up @@ -223,7 +241,7 @@ class _GroupButtonState extends State<GroupButton> {
),
),
backgroundColor: MaterialStateProperty.resolveWith<Color?>((states) {
if (selected) return colors.cool.shade100;
if (widget._isInverse) return colors.cool.shade100;

if (states.contains(MaterialState.disabled)) {
return colors.surfaceDisabled;
Expand All @@ -240,7 +258,7 @@ class _GroupButtonState extends State<GroupButton> {
if (states.contains(MaterialState.disabled)) {
return colors.textDisabled;
}
if (selected) return colors.cool.shade100.onColor;
if (widget._isInverse) return colors.cool.shade100.onColor;
return colors.textDefault;
}),
elevation: const MaterialStatePropertyAll(0),
Expand All @@ -251,10 +269,6 @@ class _GroupButtonState extends State<GroupButton> {
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty<bool>('selected', selected))
..add(
DiagnosticsProperty<MaterialStatesController>('controller', controller),
);
properties.add(DiagnosticsProperty<MaterialStatesController>('controller', controller));
}
}

0 comments on commit 48bb26b

Please sign in to comment.