Initial commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
|
||||
import '../theme/app_theme.dart';
|
||||
import 'auto_dismiss_menu.dart';
|
||||
|
||||
|
||||
class AppCard extends StatefulWidget {
|
||||
final Widget child;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
|
||||
final List<FItem>? contextMenuItems;
|
||||
|
||||
|
||||
final bool enableLongPressMenu;
|
||||
|
||||
|
||||
final bool filled;
|
||||
final double? radius;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final bool enableHover;
|
||||
|
||||
|
||||
final ValueChanged<bool>? onHoverChanged;
|
||||
|
||||
const AppCard({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.onTap,
|
||||
this.contextMenuItems,
|
||||
this.enableLongPressMenu = true,
|
||||
this.filled = true,
|
||||
this.radius,
|
||||
this.padding,
|
||||
this.enableHover = true,
|
||||
this.onHoverChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AppCard> createState() => _AppCardState();
|
||||
}
|
||||
|
||||
class _AppCardState extends State<AppCard> {
|
||||
bool _hovered = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final tokens = context.appTokens;
|
||||
final radius = widget.radius ?? tokens.radiusCard;
|
||||
final base = theme.colorScheme.onSurface;
|
||||
|
||||
final double alpha;
|
||||
if (widget.filled) {
|
||||
alpha = _hovered ? tokens.cardFillHoverAlpha : tokens.cardFillAlpha;
|
||||
} else {
|
||||
alpha = _hovered ? tokens.cardFillAlpha : 0.0;
|
||||
}
|
||||
|
||||
Widget result = MouseRegion(
|
||||
onEnter: (_) {
|
||||
if (widget.enableHover) setState(() => _hovered = true);
|
||||
widget.onHoverChanged?.call(true);
|
||||
},
|
||||
onExit: (_) {
|
||||
if (widget.enableHover) setState(() => _hovered = false);
|
||||
widget.onHoverChanged?.call(false);
|
||||
},
|
||||
cursor: widget.onTap != null
|
||||
? SystemMouseCursors.click
|
||||
: SystemMouseCursors.basic,
|
||||
child: GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 140),
|
||||
padding: widget.padding,
|
||||
decoration: BoxDecoration(
|
||||
color: base.withValues(alpha: alpha),
|
||||
borderRadius: BorderRadius.circular(radius),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: widget.child,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final items = widget.contextMenuItems;
|
||||
if (items != null && items.isNotEmpty) {
|
||||
result = FContextMenu(
|
||||
menuBuilder: autoDismissMenuBuilder,
|
||||
menu: [FItemGroup(children: items)],
|
||||
longPress: widget.enableLongPressMenu ? null : false,
|
||||
child: result,
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user