Skip to content

Commit

Permalink
feat(components): ✨ create new componentes features
Browse files Browse the repository at this point in the history
introduce button and scaffold components
  • Loading branch information
HenriqueNas committed Feb 4, 2024
1 parent 8f9afe4 commit 11aff7d
Show file tree
Hide file tree
Showing 7 changed files with 560 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/src/components/button/button.dart
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';
139 changes: 139 additions & 0 deletions lib/src/components/button/button.widget.dart
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,
),
),
);
}
127 changes: 127 additions & 0 deletions lib/src/components/button/button_base.widget.dart
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,
],
),
),
),
),
);
}
}
Loading

0 comments on commit 11aff7d

Please sign in to comment.