[SYNC] Working on the Buttons

This commit is contained in:
2024-05-18 15:24:48 +03:00
parent 7c0e000c05
commit ced9c294f5
9 changed files with 798 additions and 2 deletions

View File

@@ -16,6 +16,9 @@ Developed, Maintained, and is property of Michael W. Aziz (Micazi)
- Selectors - Selectors
- Radio ☑️ - Radio ☑️
- Chip ☑️ - Chip ☑️
- Toggles
- Checkbox ☑️
- Switcher ☑️
- Custom ☑️
- Buttons - Buttons
- Fields - Fields
- Toggles

View File

@@ -5,8 +5,8 @@ export './src/Spacing/spacing.astromic.dart';
export './src/Widgets/widgets.astromic.dart'; export './src/Widgets/widgets.astromic.dart';
export './src/Selectors/selectors.astromic.dart'; export './src/Selectors/selectors.astromic.dart';
export './src/Toggles/toggles.astromic.dart'; export './src/Toggles/toggles.astromic.dart';
export './src/Buttons/buttons.astromic.dart';
// export './src/2.Buttons/buttons.astromic.dart';
// export './src/5.Fields/fields.astromic.dart'; // export './src/5.Fields/fields.astromic.dart';
// // // //
// export './src/styles/styles.astromic.dart'; // export './src/styles/styles.astromic.dart';

View File

@@ -0,0 +1,118 @@
//s2 Core Packages Imports
import 'package:flutter/material.dart';
//
import 'src/icon_button.dart';
import 'src/link_button.dart';
import 'src/state_button.dart';
//
import 'src/sizing_strategy.enum.dart';
import 'src/style.dart';
//
export 'src/sizing_strategy.enum.dart';
export 'src/style.dart';
class AstromicButtons {
//S1 -- State
static Widget state({
//
void Function(VoidCallback start, VoidCallback stop)? onTap,
Function(VoidCallback start, VoidCallback stop)? onHold,
//
bool? isEnabled,
bool? withFeedback,
bool? withHighlightChange,
//
SizingStrategy? widthSizingStrategy,
SizingStrategy? heightSizingStrategy,
InteractiveInkFeatureFactory? splashFactory,
required AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading) style,
//
Widget? loadingContent,
required Widget Function(bool isEnabled, bool isHighlighted) content,
}) =>
AstromicStateButton(
onTap: onTap,
onHold: onHold,
//
isEnabled: isEnabled,
withFeedback: withFeedback,
withHighlightChange: withHighlightChange,
//
widthSizingStrategy: widthSizingStrategy,
heightSizingStrategy: heightSizingStrategy,
splashFactory: splashFactory,
style: style,
//
loadingContent: loadingContent,
content: content,
);
//S1 -- Icon
static Widget icon({
//
void Function(VoidCallback start, VoidCallback stop)? onTap,
Function(VoidCallback start, VoidCallback stop)? onHold,
//
bool? isEnabled,
bool? withFeedback,
bool? withHighlightChange,
//
bool? isCircular,
InteractiveInkFeatureFactory? splashFactory,
required AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading) style,
//
Widget? loadingContent,
required Widget Function(bool isEnabled, bool isHighlighted) icon,
}) =>
AstromicIconButton(
onTap: onTap,
onHold: onHold,
//
isEnabled: isEnabled,
withFeedback: withFeedback,
withHighlightChange: withHighlightChange,
//
isCircular: isCircular,
splashFactory: splashFactory,
style: style,
//
loadingContent: loadingContent,
icon: icon,
);
//S1 -- Link
static Widget link({
//
VoidCallback? onTap,
VoidCallback? onHold,
//
bool? isEnabled,
TextDirection? textDirection,
//
bool? isUnderlined,
EdgeInsetsGeometry? contentPadding,
required TextStyle Function(bool isEnabled)? style,
//
String? text,
Widget? textWidget,
Widget? prefix,
Widget? suffix,
}) =>
AstromicLinkButton(
onTap: onTap,
onHold: onHold,
//
isEnabled: isEnabled,
textDirection: textDirection,
//
isUnderlined: isUnderlined,
contentPadding: contentPadding,
style: style,
//
text: text,
textWidget: textWidget,
prefix: prefix,
suffix: suffix,
);
}

View File

@@ -0,0 +1,154 @@
//SECTION - Imports
//
//s1 PACKAGES
//---------------
//s2 CORE
import 'package:flutter/material.dart';
//s2 3RD-PARTY
//
//s1 DEPENDENCIES
//----------------
//s2 SERVICES
//s2 MODELS
import 'style.dart';
//s2 MISC
//!SECTION - Imports
//
//SECTION - Exports
//!SECTION - Exports
//
class AstromicButtonBase extends StatefulWidget {
//SECTION - Widget Arguments
//s1 -- Functionality
final VoidCallback? onTap;
final VoidCallback? onHold;
//s1 -- Configurations
final bool isEnabled;
final bool withFeedback;
final bool withHighlightChange;
final bool isFullWidth;
//s1 -- Style
final InteractiveInkFeatureFactory? splashFactory;
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted) style;
//s1 -- Content
final Widget Function(bool isEnabled, bool isHighlighted) child;
//!SECTION
//
const AstromicButtonBase({
Key? key,
//
this.onTap,
this.onHold,
//
this.isEnabled = true,
this.withFeedback = true,
this.withHighlightChange = true,
this.isFullWidth = false,
//s1 -- Style
this.splashFactory,
required this.style,
//s1 -- Content
required this.child,
}) : super(
key: key,
);
@override
State<AstromicButtonBase> createState() => _AstromicButtonBaseState();
}
class _AstromicButtonBaseState extends State<AstromicButtonBase> {
//
//SECTION - State Variables
//s1 --Controllers
//s1 --Controllers
//
//s1 --State
late bool _isHighlighted;
//s1 --State
//
//s1 --Constants
//s1 --Constants
//!SECTION
@override
void initState() {
super.initState();
//
//SECTION - State Variables initializations & Listeners
//s1 --Controllers & Listeners
//s1 --Controllers & Listeners
//
//s1 --State
_isHighlighted = false;
//s1 --State
//
//s1 --Late & Async Initializers
//s1 --Late & Async Initializers
//!SECTION
}
@override
Widget build(BuildContext context) {
//SECTION - Build Setup
//s1 -Values
//s1 -Values
//
//s1 -Widgets
//s1 -Widgets
//!SECTION
//SECTION - Build Return
return Material(
color: widget.style(widget.isEnabled, _isHighlighted).backgroundGradient != null ? Colors.transparent : widget.style(widget.isEnabled, _isHighlighted).backgroundColor,
shape: OutlineInputBorder(
borderSide: BorderSide(
width: widget.style(widget.isEnabled, _isHighlighted).borderWidth ?? 1,
color: widget.style(widget.isEnabled, _isHighlighted).borderColor ?? Colors.black,
),
borderRadius: widget.style(widget.isEnabled, _isHighlighted).borderRadius?.resolve(null) ?? BorderRadius.circular(0),
),
child: Ink(
decoration: BoxDecoration(
borderRadius: widget.style(widget.isEnabled, _isHighlighted).borderRadius?.resolve(null) ?? BorderRadius.circular(0),
gradient: widget.style(widget.isEnabled, _isHighlighted).backgroundGradient,
),
child: InkWell(
splashFactory: widget.splashFactory,
splashColor: widget.withFeedback ? widget.style(widget.isEnabled, _isHighlighted).splashColor : Colors.transparent,
hoverColor: widget.withFeedback ? widget.style(widget.isEnabled, _isHighlighted).hoverColor : Colors.transparent,
highlightColor: widget.withFeedback ? widget.style(widget.isEnabled, _isHighlighted).highlightColor : Colors.transparent,
//
borderRadius: widget.style(widget.isEnabled, _isHighlighted).borderRadius?.resolve(null) ?? BorderRadius.circular(0),
//
onTap: widget.isEnabled && widget.onTap != null ? widget.onTap : null,
onLongPress: widget.isEnabled && widget.onHold != null ? widget.onHold : null,
onHighlightChanged: widget.withHighlightChange
? (v) {
setState(() {
_isHighlighted = v;
});
}
: null,
//
child: Padding(
padding: widget.style(widget.isEnabled, _isHighlighted).contentPadding ?? EdgeInsets.zero,
child: widget.child(
widget.isEnabled,
_isHighlighted,
),
),
),
),
);
//!SECTION
}
@override
void dispose() {
//SECTION - Disposable variables
//!SECTION
super.dispose();
}
}

View File

@@ -0,0 +1,156 @@
//SECTION - Imports
//
//s1 PACKAGES
//---------------
//s2 CORE
import 'package:flutter/material.dart';
import 'base.dart';
import 'style.dart';
//s2 3RD-PARTY
//
//s1 DEPENDENCIES
//---------------
//s2 SERVICES
//s2 MODELS
//s2 MISC
//!SECTION - Imports
//
//SECTION - Exports
//!SECTION - Exports
//
class AstromicIconButton extends StatefulWidget {
//SECTION - Widget Arguments
//s1 -- Functionality
final void Function(VoidCallback start, VoidCallback stop)? onTap;
final Function(VoidCallback start, VoidCallback stop)? onHold;
//s1 -- Configurations
final bool? isEnabled;
final bool? withFeedback;
final bool? withHighlightChange;
//s1 -- Style
final InteractiveInkFeatureFactory? splashFactory;
final bool? isCircular;
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading)? style;
//s1 -- Content
final Widget? loadingContent;
final Widget Function(bool isEnabled, bool isHighlighted) icon;
//!SECTION
//
const AstromicIconButton({
super.key,
//
this.onTap,
this.onHold,
//
this.isEnabled = true,
this.withFeedback = true,
this.withHighlightChange = true,
//s1 -- Style
this.splashFactory,
this.isCircular = true,
this.style,
//s1 -- Content
this.loadingContent,
required this.icon,
});
@override
State<AstromicIconButton> createState() => _AstromicIconButtonState();
}
class _AstromicIconButtonState extends State<AstromicIconButton> {
//
//SECTION - State Variables
//s1 --Controllers
//s1 --Controllers
//
//s1 --State
late bool isLoading;
late bool isHighlighted;
//s1 --State
//
//s1 --Constants
//s1 --Constants
//!SECTION
@override
void initState() {
super.initState();
//
//SECTION - State Variables initializations & Listeners
//s1 --Controllers & Listeners
//s1 --Controllers & Listeners
//
//s1 --State
isLoading = false;
isHighlighted = false;
//s1 --State
//
//s1 --Late & Async Initializers
//s1 --Late & Async Initializers
//!SECTION
}
@override
Widget build(BuildContext context) {
//SECTION - Build Setup
//s1 -Values
//s1 -Values
//
//s1 -Widgets
//-----
Widget baseChild = AstromicButtonBase(
isEnabled: widget.isEnabled!,
withFeedback: widget.withFeedback!,
withHighlightChange: widget.withHighlightChange!,
isFullWidth: false,
//
onTap: !isLoading && context.mounted && widget.onTap != null
? () {
widget.onTap!(() {
setState(() {
isLoading = true;
});
}, () {
setState(() {
isLoading = false;
});
});
}
: null,
onHold: !isLoading && context.mounted && widget.onHold != null
? () {
widget.onHold!(() {
setState(() {
isLoading = true;
});
}, () {
setState(() {
isLoading = false;
});
});
}
: null,
splashFactory: widget.splashFactory,
style: (enabled, highlighted) => widget.style!(enabled, highlighted, isLoading).copyWith(
borderRadius: widget.isCircular! ? BorderRadiusDirectional.circular(100000000000) : null,
),
child: (enabled, highlighted) => isLoading && widget.loadingContent != null ? widget.loadingContent! : widget.icon(enabled, highlighted),
);
//s1 -Widgets
//!SECTION
//SECTION - Build Return
return baseChild;
//!SECTION
}
@override
void dispose() {
//SECTION - Disposable variables
//!SECTION
super.dispose();
}
}

View File

@@ -0,0 +1,119 @@
//SECTION - Imports
//
//s1 PACKAGES
//---------------
//s2 CORE
import 'package:flutter/widgets.dart';
//s2 3RD-PARTY
//
//s1 DEPENDENCIES
//---------------
//s2 SERVICES
//s2 MODELS
//s2 MISC
import 'base.dart';
import 'style.dart';
//!SECTION - Imports
//
//SECTION - Exports
//!SECTION - Exports
//
class AstromicLinkButton extends StatelessWidget {
//SECTION - Widget Arguments
//s1 -- Functionality
final VoidCallback? onTap;
final VoidCallback? onHold;
//s1 -- Configurations
final bool? isEnabled;
final TextDirection? textDirection;
//s1 -- Style
final bool? isUnderlined;
final EdgeInsetsGeometry? contentPadding;
final TextStyle Function(bool isEnabled)? style;
//
//s1 -- Content
final String? text;
final Widget? textWidget;
final Widget? prefix;
final Widget? suffix;
//!SECTION
//
const AstromicLinkButton({
Key? key,
//s1 -- Functionality
this.onTap,
this.onHold,
//s1 -- Configurations
this.isEnabled = true,
this.textDirection,
//s1 -- Style
this.isUnderlined = true,
this.contentPadding,
this.style,
//s1 -- Content
this.text,
this.textWidget,
this.prefix,
this.suffix,
}) : assert(text != null || textWidget != null, 'You need to provide either a text or text widget.'),
super(
key: key,
);
@override
Widget build(BuildContext context) {
//SECTION - Build Setup
//s1 -Values
//s1 -Values
//
//s1 -Widgets
//s1 -Widgets
//!SECTION
//SECTION - Build Return
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
textDirection: textDirection,
children: [
AstromicButtonBase(
onTap: onTap,
onHold: onHold,
//
isEnabled: isEnabled!,
withFeedback: false,
withHighlightChange: false,
isFullWidth: false,
//
style: (isEnabled, isHighlighted) => AstromicButtonStyle(
contentPadding: contentPadding,
),
//
child: (isEnabled, isHighlighted) => Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (prefix != null) prefix!,
textWidget != null
? textWidget!
: Text(
text!,
style: style != null
? style!(isEnabled).copyWith(
decoration: isUnderlined! ? TextDecoration.underline : TextDecoration.none,
)
: TextStyle(
decoration: isUnderlined! ? TextDecoration.underline : TextDecoration.none,
),
),
if (suffix != null) suffix!,
],
),
)
],
);
//!SECTION
}
}

View File

@@ -0,0 +1,5 @@
enum SizingStrategy {
hug,
fill,
fixed,
}

View File

@@ -0,0 +1,180 @@
//SECTION - Imports
//
//s1 PACKAGES
//---------------
//s2 CORE
import 'package:flutter/material.dart';
import 'base.dart';
//s2 3RD-PARTY
//
//s1 DEPENDENCIES
//---------------
//s2 SERVICES
//s2 MODELS
import 'sizing_strategy.enum.dart';
import 'style.dart';
//s2 MISC
//!SECTION - Imports
//
//SECTION - Exports
//!SECTION - Exports
//
class AstromicStateButton extends StatefulWidget {
//SECTION - Widget Arguments
//s1 -- Functionality
final void Function(VoidCallback start, VoidCallback stop)? onTap;
final Function(VoidCallback start, VoidCallback stop)? onHold;
//s1 -- Configurations
final bool? isEnabled;
final bool? withFeedback;
final bool? withHighlightChange;
//s1 -- Style
final SizingStrategy? widthSizingStrategy;
final SizingStrategy? heightSizingStrategy;
final InteractiveInkFeatureFactory? splashFactory;
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading)? style;
//s1 -- Content
final Widget? loadingContent;
final Widget Function(bool isEnabled, bool isHighlighted) content;
//!SECTION
//
const AstromicStateButton({
super.key,
//
this.onTap,
this.onHold,
//
this.isEnabled = true,
this.withFeedback = true,
this.withHighlightChange = true,
//s1 -- Style
this.widthSizingStrategy = SizingStrategy.hug,
this.heightSizingStrategy = SizingStrategy.hug,
this.splashFactory,
this.style,
//s1 -- Content
this.loadingContent,
required this.content,
});
@override
State<AstromicStateButton> createState() => _AstromicStateButtonState();
}
class _AstromicStateButtonState extends State<AstromicStateButton> {
//
//SECTION - State Variables
//s1 --Controllers
//s1 --Controllers
//
//s1 --State
late bool isLoading;
late bool isHighlighted;
//s1 --State
//
//s1 --Constants
//s1 --Constants
//!SECTION
@override
void initState() {
super.initState();
//
//SECTION - State Variables initializations & Listeners
//s1 --Controllers & Listeners
//s1 --Controllers & Listeners
//
//s1 --State
isLoading = false;
isHighlighted = false;
//s1 --State
//
//s1 --Late & Async Initializers
//s1 --Late & Async Initializers
//!SECTION
}
@override
Widget build(BuildContext context) {
//SECTION - Build Setup
//s1 -Values
//s1 -Values
//
//s1 -Widgets
//-----
Widget baseChild = AstromicButtonBase(
isEnabled: widget.isEnabled!,
withFeedback: widget.withFeedback!,
withHighlightChange: widget.withHighlightChange!,
isFullWidth: false,
//
onTap: !isLoading && context.mounted && widget.onTap != null
? () {
widget.onTap!(() {
setState(() {
isLoading = true;
});
}, () {
setState(() {
isLoading = false;
});
});
}
: null,
onHold: !isLoading && context.mounted && widget.onHold != null
? () {
widget.onHold!(() {
setState(() {
isLoading = true;
});
}, () {
setState(() {
isLoading = false;
});
});
}
: null,
splashFactory: widget.splashFactory,
style: (enabled, highlighted) => widget.style!(enabled, highlighted, isLoading).copyWith(
contentPadding: widget.heightSizingStrategy == SizingStrategy.fixed && widget.widthSizingStrategy == SizingStrategy.fixed
? EdgeInsets.zero
: widget.heightSizingStrategy == SizingStrategy.fixed && widget.widthSizingStrategy != SizingStrategy.fixed
? EdgeInsets.symmetric(
horizontal: widget.style!(enabled, highlighted, isLoading).contentPadding?.horizontal ?? 0,
vertical: 0,
)
: widget.widthSizingStrategy == SizingStrategy.fixed && widget.heightSizingStrategy != SizingStrategy.fixed
? EdgeInsets.symmetric(
vertical: widget.style!(enabled, highlighted, isLoading).contentPadding?.vertical ?? 0,
horizontal: 0,
)
: null,
),
child: (enabled, highlighted) => isLoading && widget.loadingContent != null ? widget.loadingContent! : widget.content(enabled, highlighted),
);
//s1 -Widgets
//!SECTION
//SECTION - Build Return
return SizedBox(
width: widget.widthSizingStrategy == SizingStrategy.fixed && widget.style != null ? widget.style!(widget.isEnabled!, isHighlighted, isLoading).fixedWidth : null,
height: widget.heightSizingStrategy == SizingStrategy.fixed && widget.style != null ? widget.style!(widget.isEnabled!, isHighlighted, isLoading).fixedHeight : null,
child: Row(
mainAxisSize: widget.widthSizingStrategy == SizingStrategy.hug ? MainAxisSize.min : MainAxisSize.max,
children: [
baseChild,
],
),
);
//!SECTION
}
@override
void dispose() {
//SECTION - Disposable variables
//!SECTION
super.dispose();
}
}

View File

@@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
class AstromicButtonStyle {
//s1 -- Colors
final Color? backgroundColor;
final Gradient? backgroundGradient;
final Color? hoverColor;
final Color? splashColor;
final Color? highlightColor;
final Color? borderColor;
//
//s1 -- Spacing & Insets
final double? fixedHeight;
final double? fixedWidth;
final EdgeInsetsGeometry? contentPadding;
final BorderRadiusGeometry? borderRadius;
final double? borderWidth;
const AstromicButtonStyle({
this.backgroundColor = Colors.transparent,
this.backgroundGradient,
this.hoverColor,
this.splashColor,
this.highlightColor,
this.borderColor,
//
this.fixedHeight,
this.fixedWidth,
this.contentPadding,
this.borderRadius,
this.borderWidth,
//
});
AstromicButtonStyle copyWith({
Color? backgroundColor,
Gradient? backgroundGradient,
Color? hoverColor,
Color? splashColor,
Color? highlightColor,
Color? borderColor,
double? fixedHeight,
double? fixedWidth,
EdgeInsetsGeometry? contentPadding,
BorderRadiusGeometry? borderRadius,
double? borderWidth,
}) {
return AstromicButtonStyle(
backgroundGradient: backgroundGradient ?? this.backgroundGradient,
backgroundColor: backgroundColor ?? this.backgroundColor,
hoverColor: hoverColor ?? this.hoverColor,
splashColor: splashColor ?? this.splashColor,
highlightColor: highlightColor ?? this.highlightColor,
borderColor: borderColor ?? this.borderColor,
fixedHeight: fixedHeight == -1 ? null : fixedHeight ?? this.fixedHeight,
fixedWidth: fixedWidth == -1 ? null : fixedWidth ?? this.fixedWidth,
contentPadding: contentPadding ?? this.contentPadding,
borderRadius: borderRadius ?? this.borderRadius,
borderWidth: borderWidth ?? this.borderWidth,
);
}
}