-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(components): ✨ create new componentes features
introduce button and scaffold components
- Loading branch information
1 parent
8f9afe4
commit 11aff7d
Showing
7 changed files
with
560 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export 'button.widget.dart'; | ||
export 'button_base.widget.dart'; | ||
export 'button_props.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import 'package:flutter_vanilla/flutter_vanilla.dart'; | ||
|
||
/// {@template button} | ||
/// This class define the button. | ||
/// | ||
/// Example: | ||
/// ```dart | ||
/// Button.primary( | ||
/// icon: 'icon', | ||
/// iconPosition: ButtonIconPosition.left, | ||
/// disable: false, | ||
/// ); | ||
/// ``` | ||
/// {@endtemplate} | ||
class Button extends ButtonBase { | ||
/// This is the raw constructor of the [Button]. | ||
/// We recommend using the others constructors, like [Button.primary]. | ||
/// | ||
/// With this constructor you can define the [ButtonState] | ||
/// and the [ButtonIconPosition] directly. | ||
/// | ||
/// Example: | ||
/// ButtonA | ||
/// ```dart | ||
/// Button( | ||
/// props: ButtonProps( | ||
/// actions: actions, | ||
/// | ||
/// state: ButtonState.disabled, | ||
/// iconPosition: ButtonIconPosition.left, | ||
/// ), | ||
/// actions: ButtonActions( | ||
/// onTap: () => print('onTap'), | ||
/// onLongPress: () => print('onLongPress'), | ||
/// ), | ||
/// ); | ||
/// ``` | ||
/// {@macro button} | ||
const Button({ | ||
required super.label, | ||
required super.props, | ||
super.key, | ||
}); | ||
|
||
/// Primary [Button] with the syntax green colors | ||
Button.primary({ | ||
required super.label, | ||
bool disable = false, | ||
IconData? icon, | ||
ButtonIconPosition iconPosition = ButtonIconPosition.left, | ||
ButtonActions actions = const ButtonActions(), | ||
super.key, | ||
}) : super( | ||
props: ButtonProps( | ||
actions: actions, | ||
state: disable ? ButtonState.disabled : ButtonState.idle, | ||
decoration: ButtonDecoration.primary( | ||
icon: icon, | ||
iconPosition: iconPosition, | ||
), | ||
), | ||
); | ||
|
||
/// Neutral (default) [Button] with black and white colors | ||
Button.neutral({ | ||
required super.label, | ||
bool disable = false, | ||
IconData? icon, | ||
ButtonIconPosition iconPosition = ButtonIconPosition.left, | ||
ButtonActions actions = const ButtonActions(), | ||
super.key, | ||
}) : super( | ||
props: ButtonProps( | ||
actions: actions, | ||
state: disable ? ButtonState.disabled : ButtonState.idle, | ||
decoration: ButtonDecoration.neutral( | ||
icon: icon, | ||
iconPosition: iconPosition, | ||
), | ||
), | ||
); | ||
|
||
/// Base [Button] without background and border colors (text only) | ||
Button.base({ | ||
required super.label, | ||
bool disable = false, | ||
IconData? icon, | ||
ButtonIconPosition iconPosition = ButtonIconPosition.left, | ||
ButtonActions actions = const ButtonActions(), | ||
super.key, | ||
}) : super( | ||
props: ButtonProps( | ||
actions: actions, | ||
state: disable ? ButtonState.disabled : ButtonState.idle, | ||
decoration: ButtonDecoration.base( | ||
icon: icon, | ||
iconPosition: iconPosition, | ||
), | ||
), | ||
); | ||
|
||
/// Negative button decoration, with semantics negative (red) colors | ||
Button.negative({ | ||
required super.label, | ||
bool disable = false, | ||
IconData? icon, | ||
ButtonIconPosition iconPosition = ButtonIconPosition.left, | ||
ButtonActions actions = const ButtonActions(), | ||
super.key, | ||
}) : super( | ||
props: ButtonProps( | ||
actions: actions, | ||
state: disable ? ButtonState.disabled : ButtonState.idle, | ||
decoration: ButtonDecoration.negative( | ||
icon: icon, | ||
iconPosition: iconPosition, | ||
), | ||
), | ||
); | ||
|
||
/// Negative button decoration, with dark colors | ||
Button.brand({ | ||
required super.label, | ||
bool disable = false, | ||
IconData? icon, | ||
ButtonIconPosition iconPosition = ButtonIconPosition.left, | ||
ButtonActions actions = const ButtonActions(), | ||
super.key, | ||
}) : super( | ||
props: ButtonProps( | ||
actions: actions, | ||
state: disable ? ButtonState.disabled : ButtonState.idle, | ||
decoration: ButtonDecoration.brand( | ||
icon: icon, | ||
iconPosition: iconPosition, | ||
), | ||
), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import 'package:flutter_vanilla/flutter_vanilla.dart'; | ||
|
||
/// {@template button_base} | ||
/// This class define the base of the button. | ||
/// We do not recommend using this class directly. | ||
/// Instead, use [Button] widget. | ||
/// {@endtemplate} | ||
class ButtonBase extends StatefulWidget { | ||
/// {@macro button_base} | ||
const ButtonBase({ | ||
required this.props, | ||
required this.label, | ||
super.key, | ||
}); | ||
|
||
/// {@macro button_props} | ||
final ButtonProps props; | ||
|
||
/// The label of the button. | ||
final String label; | ||
|
||
@override | ||
State<ButtonBase> createState() => _ButtonBaseState(); | ||
} | ||
|
||
class _ButtonBaseState extends State<ButtonBase> { | ||
late ButtonState _state = widget.props.state; | ||
ButtonState get state => _state; | ||
set state(ButtonState value) => setState(() { | ||
if (!state.isDisabled) _state = value; | ||
}); | ||
|
||
bool _isHover = false; | ||
bool get isHover => _isHover; | ||
set isHover(bool value) => setState(() { | ||
_isHover = value; | ||
state = value ? ButtonState.hover : ButtonState.idle; | ||
}); | ||
|
||
ButtonActions get actions => widget.props.actions; | ||
ButtonDecoration get decoration => widget.props.decoration; | ||
|
||
Color get backgroundColor { | ||
final colors = decoration.backgroundColors; | ||
if (state.isDisabled) { | ||
return colors.disabledColor; | ||
} | ||
|
||
return isHover ? colors.hoverColor : colors.color; | ||
} | ||
|
||
Color get surfaceColor { | ||
final colors = decoration.surfaceColors; | ||
if (state.isDisabled) { | ||
return colors.disabledColor; | ||
} | ||
|
||
return isHover ? colors.hoverColor : colors.color; | ||
} | ||
|
||
Color? get borderColor { | ||
final colors = decoration.borderColors; | ||
if (state.isDisabled) { | ||
return colors?.disabledColor; | ||
} | ||
|
||
return isHover // | ||
? colors?.hoverColor | ||
: colors?.color; | ||
} | ||
|
||
bool get hasLeftIcon => | ||
decoration.icon != null && | ||
decoration.iconPosition == ButtonIconPosition.left; | ||
|
||
bool get hasRightIcon => | ||
decoration.icon != null && | ||
decoration.iconPosition == ButtonIconPosition.right; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final icon = Icon( | ||
decoration.icon, | ||
color: surfaceColor, | ||
size: 16, | ||
); | ||
|
||
return MouseRegion( | ||
onHover: (_) => isHover = true, | ||
onExit: (_) => isHover = false, | ||
child: GestureDetector( | ||
onTap: actions.onTap, | ||
onLongPress: actions.onLongPress, | ||
onDoubleTap: actions.onDoubleTap, | ||
onSecondaryTap: actions.onSecondaryTap, | ||
child: Opacity( | ||
opacity: state.isDisabled ? 0.4 : 1, | ||
child: AnimatedContainer( | ||
duration: const Duration(milliseconds: 200), | ||
alignment: Alignment.center, | ||
padding: const EdgeInsets.all(8), | ||
decoration: BoxDecoration( | ||
color: backgroundColor, | ||
border: Border.all(color: borderColor ?? Colors.transparent), | ||
), | ||
child: Row( | ||
mainAxisSize: MainAxisSize.min, | ||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
children: [ | ||
if (hasLeftIcon) icon, | ||
const SizedBox(width: 8), | ||
Text( | ||
widget.label, | ||
style: VanillaTextStyles.linkDefault.apply( | ||
color: surfaceColor, | ||
), | ||
), | ||
const SizedBox(width: 8), | ||
if (hasRightIcon) icon, | ||
], | ||
), | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} |
Oops, something went wrong.