Files
2026-06-05 17:54:46 +08:00

114 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 colors = ShadTheme.of(context).colorScheme;
final variant = switch (kind) {
AppButtonKind.primary => ShadButtonVariant.primary,
AppButtonKind.dark => ShadButtonVariant.primary,
AppButtonKind.accent => ShadButtonVariant.secondary,
AppButtonKind.ghost => ShadButtonVariant.outline,
};
final palette = switch (kind) {
AppButtonKind.primary => (null, null, null),
AppButtonKind.dark => (
colors.foreground,
colors.background,
colors.foreground.withValues(alpha: 0.9),
),
AppButtonKind.accent => (
colors.brandSoft,
colors.primaryForeground,
colors.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: palette.$1,
foregroundColor: palette.$2,
hoverBackgroundColor: palette.$3,
leading: icon == null ? null : Icon(icon, size: compact ? 15 : 16),
gap: compact ? 5 : 7,
textStyle: (compact ? YantingText.badge : YantingText.body).copyWith(
color: palette.$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);
final colors = ShadTheme.of(context).colorScheme;
return switch (kind) {
AppButtonKind.primary => ShadIconButton(
onPressed: onPressed,
icon: iconWidget,
),
AppButtonKind.dark => ShadIconButton(
onPressed: onPressed,
backgroundColor: colors.foreground,
foregroundColor: colors.background,
hoverBackgroundColor: colors.foreground.withValues(alpha: 0.9),
icon: iconWidget,
),
AppButtonKind.accent => ShadIconButton.secondary(
onPressed: onPressed,
backgroundColor: colors.brandSoft,
foregroundColor: colors.primaryForeground,
hoverBackgroundColor: colors.brandSoftBorder,
icon: iconWidget,
),
AppButtonKind.ghost => ShadIconButton.outline(
onPressed: onPressed,
icon: iconWidget,
),
};
}
}
enum AppButtonKind { primary, dark, accent, ghost }