base_styled_button.dart 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import 'package:flowy_style/size.dart';
  2. import 'package:flowy_style/text_style.dart';
  3. import 'package:flowy_style/theme.dart';
  4. import 'package:flutter/foundation.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/rendering.dart';
  7. import 'package:provider/provider.dart';
  8. class BaseStyledButton extends StatefulWidget {
  9. final Widget child;
  10. final VoidCallback? onPressed;
  11. final Function(bool)? onFocusChanged;
  12. final Function(bool)? onHighlightChanged;
  13. final Color? bgColor;
  14. final Color? focusColor;
  15. final Color? hoverColor;
  16. final Color? downColor;
  17. final EdgeInsets? contentPadding;
  18. final double? minWidth;
  19. final double? minHeight;
  20. final double? borderRadius;
  21. final bool useBtnText;
  22. final bool autoFocus;
  23. final ShapeBorder? shape;
  24. final Color outlineColor;
  25. const BaseStyledButton({
  26. Key? key,
  27. required this.child,
  28. this.onPressed,
  29. this.onFocusChanged,
  30. this.onHighlightChanged,
  31. this.bgColor,
  32. this.focusColor,
  33. this.contentPadding,
  34. this.minWidth,
  35. this.minHeight,
  36. this.borderRadius,
  37. this.hoverColor,
  38. this.downColor,
  39. this.shape,
  40. this.useBtnText = true,
  41. this.autoFocus = false,
  42. this.outlineColor = Colors.transparent,
  43. }) : super(key: key);
  44. @override
  45. _BaseStyledBtnState createState() => _BaseStyledBtnState();
  46. }
  47. class _BaseStyledBtnState extends State<BaseStyledButton> {
  48. late FocusNode _focusNode;
  49. bool _isFocused = false;
  50. @override
  51. void initState() {
  52. super.initState();
  53. _focusNode = FocusNode(debugLabel: '', canRequestFocus: true);
  54. _focusNode.addListener(() {
  55. if (_focusNode.hasFocus != _isFocused) {
  56. setState(() => _isFocused = _focusNode.hasFocus);
  57. widget.onFocusChanged?.call(_isFocused);
  58. }
  59. });
  60. }
  61. @override
  62. void dispose() {
  63. _focusNode.dispose();
  64. super.dispose();
  65. }
  66. @override
  67. Widget build(BuildContext context) {
  68. final theme = context.watch<AppTheme>();
  69. return Container(
  70. decoration: BoxDecoration(
  71. color: widget.bgColor ?? theme.surface,
  72. borderRadius: BorderRadius.circular(widget.borderRadius ?? Corners.s5),
  73. boxShadow: _isFocused
  74. ? [
  75. BoxShadow(
  76. color: theme.focus.withOpacity(0.25),
  77. offset: Offset.zero,
  78. blurRadius: 8.0,
  79. spreadRadius: 0.0),
  80. BoxShadow(
  81. color: widget.bgColor ?? theme.surface,
  82. offset: Offset.zero,
  83. blurRadius: 8.0,
  84. spreadRadius: -4.0),
  85. ]
  86. : [],
  87. ),
  88. foregroundDecoration: _isFocused
  89. ? ShapeDecoration(
  90. shape: RoundedRectangleBorder(
  91. side: BorderSide(
  92. width: 1.8,
  93. color: theme.focus,
  94. ),
  95. borderRadius:
  96. BorderRadius.circular(widget.borderRadius ?? Corners.s5),
  97. ),
  98. )
  99. : null,
  100. child: RawMaterialButton(
  101. focusNode: _focusNode,
  102. autofocus: widget.autoFocus,
  103. textStyle: widget.useBtnText ? TextStyles.Btn : null,
  104. materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
  105. visualDensity: VisualDensity.compact,
  106. splashColor: Colors.transparent,
  107. mouseCursor: SystemMouseCursors.click,
  108. elevation: 0,
  109. hoverElevation: 0,
  110. highlightElevation: 0,
  111. focusElevation: 0,
  112. fillColor: Colors.transparent,
  113. hoverColor: widget.hoverColor ?? theme.surface,
  114. highlightColor: widget.downColor ?? theme.accent1.withOpacity(.1),
  115. focusColor: widget.focusColor ?? Colors.grey.withOpacity(0.35),
  116. child: Opacity(
  117. child: Padding(
  118. padding: widget.contentPadding ?? EdgeInsets.all(Insets.m),
  119. child: widget.child,
  120. ),
  121. opacity: widget.onPressed != null ? 1 : .7,
  122. ),
  123. constraints: BoxConstraints(
  124. minHeight: widget.minHeight ?? 0, minWidth: widget.minWidth ?? 0),
  125. onPressed: widget.onPressed,
  126. shape: widget.shape ??
  127. RoundedRectangleBorder(
  128. side: BorderSide(color: widget.outlineColor, width: 1.5),
  129. borderRadius:
  130. BorderRadius.circular(widget.borderRadius ?? Corners.s5)),
  131. ),
  132. );
  133. }
  134. }