Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add icon button #26

Merged
merged 2 commits into from
Feb 21, 2024
Merged
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
5 changes: 4 additions & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: CI - Pull Request
on: pull_request
on:
pull_request_target:
types:
- opened

jobs:
up-to-date:
Expand Down
43 changes: 39 additions & 4 deletions example/lib/pages/components/button_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,21 @@ class _ButtonExampleState extends State<ButtonExample> {
Column(children: buttons(ZetaWidgetBorder.sharp)),
Text('Full Buttons', style: ZetaTextStyles.displayMedium),
Column(children: buttons(ZetaWidgetBorder.full)),
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('Icon Buttons', style: ZetaTextStyles.displayLarge),
Text('Rounded Buttons', style: ZetaTextStyles.displayMedium),
Column(children: inputButtons(ZetaWidgetBorder.rounded)),
Text('Sharp Buttons', style: ZetaTextStyles.displayMedium),
Column(children: inputButtons(ZetaWidgetBorder.sharp)),
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 @@ -136,4 +147,28 @@ class _ButtonExampleState extends State<ButtonExample> {
),
).reversed.divide(const SizedBox.square(dimension: ZetaSpacing.m)).toList();
}

List<Widget> inputButtons(ZetaWidgetBorder borderType) {
return List.generate(
ZetaWidgetSize.values.length + 1,
(index) => SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(
ZetaButtonType.values.length,
(index2) => ZetaIconButton(
onPressed: index == 0 ? null : () {},
type: ZetaButtonType.values[index2],
size: ZetaWidgetSize.values[index == 0 ? 0 : index - 1],
borderType: borderType,
icon: ZetaButtonType.values[index2] == ZetaButtonType.negative
? ZetaIcons.delete_round
: ZetaIcons.more_horizontal_round,
),
).divide(const SizedBox.square(dimension: ZetaSpacing.m)).toList(),
),
),
).reversed.divide(const SizedBox.square(dimension: ZetaSpacing.m)).toList();
}
}
133 changes: 6 additions & 127 deletions lib/src/components/buttons/button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,71 +4,6 @@ import 'package:flutter/material.dart';
import '../../../zeta_flutter.dart';

///Button types
enum ZetaButtonType {
/// Background: Primary color; defaults to blue.
/// Border: None.
primary,

/// Background: Secondary color; defaults to yellow.
/// Border: None.
secondary,

/// Background: Positive color; defaults to green.
/// Border: None.
positive,

/// Background: Negative color; defaults to red.
/// Border: None.
negative,

/// Background: None.
/// Border: Primary color; defaults to blue.
outline,

/// Background: None.
/// Border: Subtle color; defaults to cool grey.
outlineSubtle,

/// Background: None.
/// Border: None.
/// Foreground color: Primary; defaults to blue.
text,
}

extension on ZetaButtonType {
ZetaColorSwatch color(ZetaColors colors) {
switch (this) {
case ZetaButtonType.secondary:
return colors.secondary;
case ZetaButtonType.positive:
return colors.positive;
case ZetaButtonType.negative:
return colors.negative;
case ZetaButtonType.outline:
case ZetaButtonType.primary:
return colors.primary;
case ZetaButtonType.outlineSubtle:
case ZetaButtonType.text:
return colors.cool;
}
}

bool get border => this == ZetaButtonType.outline || this == ZetaButtonType.outlineSubtle;
bool get solid => index < 4;
}

extension on ZetaWidgetBorder {
BorderRadius get radius {
switch (this) {
case ZetaWidgetBorder.sharp:
return ZetaRadius.none;
case ZetaWidgetBorder.rounded:
return ZetaRadius.minimal;
case ZetaWidgetBorder.full:
return ZetaRadius.full;
}
}
}

///Zeta Button
class ZetaButton extends StatelessWidget {
Expand Down Expand Up @@ -184,10 +119,11 @@ class ZetaButton extends StatelessWidget {
Widget build(BuildContext context) {
final colors = Zeta.of(context).colors;
return ConstrainedBox(
constraints: BoxConstraints(minHeight: _minConstraints, minWidth: _minConstraints),
constraints:
BoxConstraints(minHeight: _minConstraints, minWidth: _minConstraints),
child: FilledButton(
onPressed: onPressed,
style: _buttonStyle(colors),
style: buttonStyle(colors, borderType, type, null),
child: SelectionContainer.disabled(
child: label.isEmpty
? const SizedBox()
Expand All @@ -200,66 +136,9 @@ class ZetaButton extends StatelessWidget {
);
}

ButtonStyle _buttonStyle(ZetaColors colors) {
return ButtonStyle(
minimumSize: MaterialStateProperty.all(const Size.square(32)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: borderType.radius)),
backgroundColor: MaterialStateProperty.resolveWith<Color?>(
(states) {
if (states.contains(MaterialState.disabled)) {
return colors.surfaceDisabled;
}
if (states.contains(MaterialState.pressed)) {
return type.solid ? type.color(colors).shade70 : colors.primary.shade10;
}
if (states.contains(MaterialState.hovered)) {
return type.solid ? type.color(colors).shade50 : colors.cool.shade20;
}
return type.solid ? type.color(colors) : Colors.transparent;
},
),
foregroundColor: MaterialStateProperty.resolveWith<Color?>(
(states) {
if (states.contains(MaterialState.disabled)) {
return colors.textDisabled;
}
switch (type) {
case ZetaButtonType.outline:
case ZetaButtonType.text:
return colors.primary;
case ZetaButtonType.outlineSubtle:
return colors.textDefault;
case ZetaButtonType.primary:
case ZetaButtonType.secondary:
case ZetaButtonType.positive:
case ZetaButtonType.negative:
return type.color(colors).onColor;
}
},
),
overlayColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
return null;
}),
side: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (type.border && states.contains(MaterialState.disabled)) {
return BorderSide(color: colors.cool.shade40);
}
// TODO(thelukewalton): This removes a defualt border when focused, rather than adding a second border when focused.
if (states.contains(MaterialState.focused)) {
return BorderSide(color: colors.blue, width: ZetaSpacing.x0_5);
}
if (type.border) {
return BorderSide(color: type == ZetaButtonType.outline ? colors.primary.border : colors.borderDefault);
}

return null;
}),
elevation: const MaterialStatePropertyAll(0),
padding: MaterialStateProperty.all(EdgeInsets.zero),
);
}

TextStyle get _textStyle => size == ZetaWidgetSize.small ? ZetaTextStyles.labelMedium : ZetaTextStyles.labelLarge;
TextStyle get _textStyle => size == ZetaWidgetSize.small
? ZetaTextStyles.labelMedium
: ZetaTextStyles.labelLarge;

double get _minConstraints {
switch (size) {
Expand Down
155 changes: 155 additions & 0 deletions lib/src/components/buttons/button_style.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import 'package:flutter/material.dart';

import '../../../zeta_flutter.dart';

/// Shared enum for type of buttons.
enum ZetaButtonType {
/// Background: Primary color; defaults to blue.
/// Border: None.
primary,

/// Background: Secondary color; defaults to yellow.
/// Border: None.
secondary,

/// Background: Positive color; defaults to green.
/// Border: None.
positive,

/// Background: Negative color; defaults to red.
/// Border: None.
negative,

/// Background: None.
/// Border: Primary color; defaults to blue.
outline,

/// Background: None.
/// Border: Subtle color; defaults to cool grey.
outlineSubtle,

/// Background: None.
/// Border: None.
/// Foreground color: Primary; defaults to blue.
text,
}

/// Button utility functions for styling
extension ButtonFunctions on ZetaButtonType {
/// Returns color based on [ZetaButtonType]
ZetaColorSwatch color(ZetaColors colors) {
switch (this) {
case ZetaButtonType.secondary:
return colors.secondary;
case ZetaButtonType.positive:
return colors.positive;
case ZetaButtonType.negative:
return colors.negative;
case ZetaButtonType.outline:
case ZetaButtonType.primary:
return colors.primary;
case ZetaButtonType.outlineSubtle:
case ZetaButtonType.text:
return colors.cool;
}
}

/// Returns if button has border
bool get border =>
this == ZetaButtonType.outline || this == ZetaButtonType.outlineSubtle;

///Returns if button is solid
bool get solid => index < 4;
}

extension on ZetaColors {}

///Border utility functions
extension BorderFunctions on ZetaWidgetBorder {
///Returns radius based on [ZetaWidgetBorder]
BorderRadius get radius {
switch (this) {
case ZetaWidgetBorder.sharp:
return ZetaRadius.none;
case ZetaWidgetBorder.rounded:
return ZetaRadius.minimal;
case ZetaWidgetBorder.full:
return ZetaRadius.full;
}
}
}

/// Shared buttonStyle for buttons and icon buttons
ButtonStyle buttonStyle(ZetaColors colors, ZetaWidgetBorder borderType,
ZetaButtonType type, Color? backgroundColor) {
final ZetaColorSwatch color = backgroundColor != null
? ZetaColorSwatch.fromColor(backgroundColor)
: type.color(colors);

final bool isSolid = type.solid || backgroundColor != null;

return ButtonStyle(
minimumSize: MaterialStateProperty.all(const Size.square(32)),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(borderRadius: borderType.radius),
),
backgroundColor: MaterialStateProperty.resolveWith<Color?>(
(states) {
if (states.contains(MaterialState.disabled)) {
return colors.surfaceDisabled;
}
if (states.contains(MaterialState.pressed)) {
return isSolid ? color.shade70 : colors.primary.shade10;
}
if (states.contains(MaterialState.hovered)) {
return isSolid ? color.shade50 : colors.cool.shade20;
}
if (backgroundColor != null) return backgroundColor;
return isSolid ? color : Colors.transparent;
},
),
foregroundColor: MaterialStateProperty.resolveWith<Color?>(
(states) {
if (states.contains(MaterialState.disabled)) {
return colors.textDisabled;
}
switch (type) {
case ZetaButtonType.outline:
case ZetaButtonType.text:
return colors.primary;
case ZetaButtonType.outlineSubtle:
return colors.textDefault;
case ZetaButtonType.primary:
case ZetaButtonType.secondary:
case ZetaButtonType.positive:
case ZetaButtonType.negative:
return color.onColor;
}
},
),
overlayColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
return null;
}),
side: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (type.border && states.contains(MaterialState.disabled)) {
return BorderSide(color: colors.cool.shade40);
}
// TODO(thelukewalton): This removes a defualt border when focused, rather than adding a second border when focused.
if (states.contains(MaterialState.focused)) {
return BorderSide(color: colors.blue, width: ZetaSpacing.x0_5);
}
if (type.border) {
return BorderSide(
color: type == ZetaButtonType.outline
? colors.primary.border
: colors.borderDefault,
);
}

return null;
}),
elevation: const MaterialStatePropertyAll(0),
padding: MaterialStateProperty.all(EdgeInsets.zero),
);
}
Loading