The-Agency/lib/ui/widgets/common/button.dart

235 lines
6.2 KiB
Dart

import "package:shadcn_flutter/shadcn_flutter.dart";
class AgcGhostButton extends StatefulWidget {
final Widget child;
final VoidCallback? onPressed;
final BorderRadius? borderRadius;
AgcGhostButton({
required this.child,
this.onPressed,
this.borderRadius,
});
@override
State<AgcGhostButton> createState() => _GhostButtonState();
}
class _GhostButtonState extends State<AgcGhostButton> {
bool _hovering = false;
bool _pressing = false;
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final radius = widget.borderRadius ?? BorderRadius.circular(
Theme.of(context).radiusSm - 4
);
Color bg = Colors.transparent;
if (_pressing) {
bg = colorScheme.accent.withOpacity(0.8);
} else if (_hovering) {
bg = colorScheme.accent.withOpacity(0.5);
}
final active = widget.onPressed != null;
return MouseRegion(
cursor: active ? SystemMouseCursors.click : MouseCursor.defer,
onEnter: (_) { if (active) setState(() => _hovering = true); },
onExit: (_) => setState(() {
_hovering = false;
_pressing = false;
}),
child: GestureDetector(
onTapDown: active ? (_) => setState(() => _pressing = true) : null,
onTapUp: active ? (_) {
setState(() => _pressing = false);
widget.onPressed!();
} : null,
onTapCancel: active ? () => setState(() => _pressing = false) : null,
child: AnimatedContainer(
duration: Duration(milliseconds: 80),
decoration: BoxDecoration(
color: bg,
borderRadius: radius,
),
padding: EdgeInsets.all(4),
child: widget.child,
),
),
);
}
}
class AgcSecondaryButton extends StatefulWidget {
final Widget child;
final VoidCallback? onPressed;
final BorderRadius? borderRadius;
final bool enabled;
AgcSecondaryButton({
required this.child,
this.onPressed,
this.borderRadius,
this.enabled = true,
});
@override
State<AgcSecondaryButton> createState() => _SecondaryButtonState();
}
class _SecondaryButtonState extends State<AgcSecondaryButton> {
bool _hovering = false;
bool _pressing = false;
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final radius = widget.borderRadius ?? BorderRadius.circular(
Theme.of(context).radiusSm
);
final bool active = widget.enabled && widget.onPressed != null;
Color bg = colorScheme.secondary;
if (!active) {
bg = colorScheme.secondary.withOpacity(0.4);
} else if (_pressing) {
bg = colorScheme.secondary.withOpacity(0.75);
} else if (_hovering) {
bg = colorScheme.secondary.withOpacity(0.85);
}
return MouseRegion(
cursor: active ? SystemMouseCursors.click : MouseCursor.defer,
onEnter: (_) { if (active) setState(() => _hovering = true); },
onExit: (_) => setState(() {
_hovering = false;
_pressing = false;
}),
child: GestureDetector(
onTapDown: active ? (_) => setState(() => _pressing = true) : null,
onTapUp: active ? (_) {
setState(() => _pressing = false);
widget.onPressed!();
} : null,
onTapCancel: active ? () => setState(() => _pressing = false) : null,
child: AnimatedContainer(
duration: Duration(milliseconds: 80),
decoration: BoxDecoration(
color: bg,
borderRadius: radius,
),
padding: EdgeInsets.all(4),
child: DefaultTextStyle.merge(
style: TextStyle(color: colorScheme.secondaryForeground),
child: IconTheme.merge(
data: IconThemeData(color: colorScheme.secondaryForeground),
child: widget.child,
),
),
),
),
);
}
}
class AgcOutlinedButton extends StatefulWidget {
final Widget child;
final VoidCallback? onPressed;
final BorderRadius? borderRadius;
final bool enabled;
AgcOutlinedButton({
required this.child,
this.onPressed,
this.borderRadius,
this.enabled = true,
});
@override
State<AgcOutlinedButton> createState() => _OutlinedButtonState();
}
class _OutlinedButtonState extends State<AgcOutlinedButton> {
bool _hovering = false;
bool _pressing = false;
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final radius = widget.borderRadius ?? BorderRadius.circular(
Theme.of(context).radiusSm
);
final bool active = widget.enabled && widget.onPressed != null;
Color bg = Colors.transparent;
if (_pressing && active) {
bg = colorScheme.accent.withOpacity(0.6);
} else if (_hovering && active) {
bg = colorScheme.accent.withOpacity(0.35);
}
final borderColor = active
? colorScheme.border
: colorScheme.border.withOpacity(0.4);
return MouseRegion(
cursor: active ? SystemMouseCursors.click : MouseCursor.defer,
onEnter: (_) { if (active) setState(() => _hovering = true); },
onExit: (_) => setState(() {
_hovering = false;
_pressing = false;
}),
child: GestureDetector(
onTapDown: active ? (_) => setState(() => _pressing = true) : null,
onTapUp: active ? (_) {
setState(() => _pressing = false);
widget.onPressed!();
} : null,
onTapCancel: active ? () => setState(() => _pressing = false) : null,
child: AnimatedContainer(
duration: Duration(milliseconds: 80),
decoration: BoxDecoration(
color: bg,
borderRadius: radius,
border: Border.all(color: borderColor),
),
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: DefaultTextStyle.merge(
style: TextStyle(
color: active ? colorScheme.foreground : colorScheme.mutedForeground,
),
child: IconTheme.merge(
data: IconThemeData(
color: active ? colorScheme.foreground : colorScheme.mutedForeground,
),
child: widget.child,
),
),
),
),
);
}
}