Skip to content

Instantly share code, notes, and snippets.

@mortezanazari-hub
Created January 23, 2025 12:58
Show Gist options
  • Select an option

  • Save mortezanazari-hub/512457adaaa44aea8e3c2cfc494064ac to your computer and use it in GitHub Desktop.

Select an option

Save mortezanazari-hub/512457adaaa44aea8e3c2cfc494064ac to your computer and use it in GitHub Desktop.
/// {@template app_text_button}
/// یک ویجت دکمه متنی سفارشی که با پلتفرم سازگار است.
/// A custom text button widget that adapts to the platform.
/// {@endtemplate}
abstract class AppTextButton extends StatelessWidget {
/// {@macro app_text_button}
const AppTextButton({
super.key,
required this.label,
this.onTap,
this.leading,
this.trailing,
this.appButtonSize = AppButtonSize.medium,
});
/// برچسب دکمه متنی.
/// The label for the text button.
final String label;
/// تابع callback برای دکمه متنی.
/// The callback function for the text button.
final VoidCallback? onTap;
/// آیکون ابتدایی دکمه متنی.
/// The leading icon for the text button.
final IconBuilder? leading;
/// آیکون انتهایی دکمه متنی.
/// The trailing icon for the text button.
final IconBuilder? trailing;
/// اندازه دکمه متنی.
/// The size of the text button.
final AppButtonSize appButtonSize;
/// رنگ پس‌زمینه دکمه متنی.
/// The background color for the text button.
Color backgroundColor(BuildContext context);
/// رنگ فوکوس دکمه متنی.
/// The focus color for the text button.
Color focusColor(BuildContext context);
/// رنگ هاور دکمه متنی.
/// The hover color for the text button.
Color hoverColor(BuildContext context);
/// رنگ غیرفعال دکمه متنی.
/// The disabled color for the text button.
Color disabledColor(BuildContext context);
/// رنگ متن دکمه متنی.
/// The text color for the text button.
Color textColor(BuildContext context);
/// رنگ متن غیرفعال دکمه متنی.
/// The disabled text color for the text button.
Color disabledTextColor(BuildContext context) {
return context.buttonTheme.primaryTextDisabled;
}
/// حاشیه پیش‌فرض دکمه متنی.
/// The default border for the text button.
BorderSide defaultBorder(BuildContext context) => BorderSide.none;
/// حاشیه فوکوس دکمه متنی.
/// The focused border for the text button.
BorderSide focusedBorder(BuildContext context) => BorderSide.none;
/// حاشیه هاور دکمه متنی.
/// The hover border for the text button.
BorderSide hoverBorder(BuildContext context) => BorderSide.none;
/// حاشیه غیرفعال دکمه متنی.
/// The disabled border for the text button.
BorderSide disabledBorder(BuildContext context) => BorderSide.none;
}
@override
Widget build(BuildContext context) {
final betweenSpace = switch (appButtonSize) {
AppButtonSize.small ||
AppButtonSize.xSmall ||
AppButtonSize.medium =>
AppSpacing.xs,
AppButtonSize.large || AppButtonSize.xlarge => AppSpacing.sm,
AppButtonSize.xxLarge => AppSpacing.lg,
};
final inputTextColor = WidgetStateProperty.resolveWith(
(states) {
if (states.contains(WidgetState.disabled)) {
return disabledTextColor(context);
}
return textColor(context);
},
);
return ElevatedButton(
style: ButtonStyle(
elevation: WidgetStateProperty.all(0),
splashFactory: NoSplash.splashFactory,
overlayColor: WidgetStateProperty.resolveWith(
(states) {
if (states.contains(WidgetState.disabled)) {
return disabledColor(context);
}
if (states.contains(WidgetState.hovered)) {
return hoverColor(context);
}
if (states.contains(WidgetState.focused)) {
return focusColor(context);
}
if (states.contains(WidgetState.pressed)) {
return focusColor(context);
}
return backgroundColor(context);
},
),
shape: WidgetStateProperty.resolveWith(
(states) {
const shape = RoundedRectangleBorder(
borderRadius: BorderRadius.all(AppRadius.md),
);
if (states.contains(WidgetState.disabled)) {
return shape.copyWith(side: disabledBorder(context));
}
if (states.contains(WidgetState.focused)) {
return shape.copyWith(side: focusedBorder(context));
}
if (states.contains(WidgetState.hovered)) {
return shape.copyWith(side: hoverBorder(context));
}
if (states.contains(WidgetState.pressed)) {
return shape.copyWith(side: focusedBorder(context));
}
return shape.copyWith(side: defaultBorder(context));
},
),
backgroundColor: WidgetStateProperty.resolveWith(
(states) {
if (states.contains(WidgetState.disabled)) {
return disabledColor(context);
}
if (states.contains(WidgetState.hovered)) {
return hoverColor(context);
}
if (states.contains(WidgetState.focused)) {
return focusColor(context);
}
if (states.contains(WidgetState.pressed)) {
return focusColor(context);
}
return backgroundColor(context);
},
),
foregroundColor: inputTextColor,
fixedSize: WidgetStateProperty.all(
switch (appButtonSize) {
AppButtonSize.small ||
AppButtonSize.xSmall =>
const Size(double.infinity, 36),
AppButtonSize.medium => const Size(double.infinity, 40),
AppButtonSize.large => const Size(double.infinity, 44),
AppButtonSize.xlarge => const Size(double.infinity, 48),
AppButtonSize.xxLarge => const Size(double.infinity, 56),
},
),
padding: WidgetStateProperty.all(
switch (appButtonSize) {
AppButtonSize.small ||
AppButtonSize.xSmall =>
const EdgeInsets.symmetric(horizontal: 12),
AppButtonSize.medium => const EdgeInsets.symmetric(horizontal: 16),
AppButtonSize.large => const EdgeInsets.symmetric(horizontal: 16),
AppButtonSize.xlarge => const EdgeInsets.symmetric(horizontal: 20),
AppButtonSize.xxLarge => const EdgeInsets.symmetric(horizontal: 24),
},
),
),
onPressed: onTap,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
if (leading != null) ...[
leading!(
onTap != null ? textColor(context) : disabledTextColor(context),
),
SizedBox(width: betweenSpace),
],
Padding(
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xxs),
child: Text(
label,
style: switch (appButtonSize) {
AppButtonSize.small ||
AppButtonSize.xSmall =>
context.typography.buttonSmall,
AppButtonSize.medium => context.typography.buttonMedium,
AppButtonSize.large => context.typography.buttonLarge,
AppButtonSize.xlarge => context.typography.buttonXLarge,
AppButtonSize.xxLarge => context.typography.button2XLarge,
},
),
),
if (trailing != null) ...[
SizedBox(width: betweenSpace),
trailing!(
onTap != null ? textColor(context) : disabledTextColor(context),
),
],
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment