Files
yanting/lib/widgets/app_buttons.dart
T
2026-06-05 16:05:32 +08:00

112 lines
3.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../theme/yanting_text.dart';
import '../theme/yanting_tokens.dart';
class AppButton extends StatelessWidget {
const AppButton({
required this.label,
required this.onPressed,
this.icon,
this.kind = AppButtonKind.primary,
this.expand = false,
this.compact = false,
super.key,
});
final String label;
final VoidCallback? onPressed;
final IconData? icon;
final AppButtonKind kind;
final bool expand;
final bool compact;
@override
Widget build(BuildContext context) {
final variant = switch (kind) {
AppButtonKind.primary => ShadButtonVariant.primary,
AppButtonKind.dark => ShadButtonVariant.primary,
AppButtonKind.accent => ShadButtonVariant.secondary,
AppButtonKind.ghost => ShadButtonVariant.outline,
};
final colors = switch (kind) {
AppButtonKind.primary => (null, null, null),
AppButtonKind.dark => (
YantingColors.foreground,
YantingColors.background,
YantingColors.foreground.withValues(alpha: 0.9),
),
AppButtonKind.accent => (
YantingColors.brandSoft,
YantingColors.primaryForeground,
YantingColors.brandSoftBorder,
),
AppButtonKind.ghost => (null, null, null),
};
final button = ShadButton.raw(
variant: variant,
enabled: onPressed != null,
onPressed: onPressed,
width: expand ? double.infinity : null,
height: compact ? 36 : 44,
padding: EdgeInsets.symmetric(horizontal: compact ? 16 : 20),
backgroundColor: colors.$1,
foregroundColor: colors.$2,
hoverBackgroundColor: colors.$3,
leading: icon == null ? null : Icon(icon, size: compact ? 15 : 16),
gap: compact ? 5 : 7,
textStyle: (compact ? YantingText.badge : YantingText.body).copyWith(
color: colors.$2,
fontWeight: FontWeight.w600,
),
child: Text(label),
);
return expand ? SizedBox(width: double.infinity, child: button) : button;
}
}
class AppIconButton extends StatelessWidget {
const AppIconButton({
required this.icon,
required this.onPressed,
this.kind = AppButtonKind.ghost,
super.key,
});
final IconData icon;
final VoidCallback? onPressed;
final AppButtonKind kind;
@override
Widget build(BuildContext context) {
final iconWidget = Icon(icon, size: 16);
return switch (kind) {
AppButtonKind.primary => ShadIconButton(
onPressed: onPressed,
icon: iconWidget,
),
AppButtonKind.dark => ShadIconButton(
onPressed: onPressed,
backgroundColor: YantingColors.foreground,
foregroundColor: YantingColors.background,
hoverBackgroundColor: YantingColors.foreground.withValues(alpha: 0.9),
icon: iconWidget,
),
AppButtonKind.accent => ShadIconButton.secondary(
onPressed: onPressed,
backgroundColor: YantingColors.brandSoft,
foregroundColor: YantingColors.primaryForeground,
hoverBackgroundColor: YantingColors.brandSoftBorder,
icon: iconWidget,
),
AppButtonKind.ghost => ShadIconButton.outline(
onPressed: onPressed,
icon: iconWidget,
),
};
}
}
enum AppButtonKind { primary, dark, accent, ghost }