hover.dart 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import 'package:flutter/material.dart';
  2. // ignore: unused_import
  3. import 'package:flowy_infra/time/duration.dart';
  4. typedef HoverBuilder = Widget Function(BuildContext context, bool onHover);
  5. typedef IsOnSelected = bool Function();
  6. class FlowyHover extends StatefulWidget {
  7. final HoverDisplayConfig config;
  8. final HoverBuilder builder;
  9. final IsOnSelected? isOnSelected;
  10. const FlowyHover({
  11. Key? key,
  12. required this.builder,
  13. required this.config,
  14. this.isOnSelected,
  15. }) : super(key: key);
  16. @override
  17. State<FlowyHover> createState() => _FlowyHoverState();
  18. }
  19. class _FlowyHoverState extends State<FlowyHover> {
  20. bool _onHover = false;
  21. @override
  22. Widget build(BuildContext context) {
  23. return MouseRegion(
  24. cursor: SystemMouseCursors.click,
  25. onEnter: (p) => setOnHover(true),
  26. onExit: (p) => setOnHover(false),
  27. child: render(),
  28. );
  29. }
  30. void setOnHover(bool value) => setState(() => _onHover = value);
  31. Widget render() {
  32. var showHover = _onHover;
  33. if (showHover == false && widget.isOnSelected != null) {
  34. showHover = widget.isOnSelected!();
  35. }
  36. if (showHover) {
  37. return FlowyHoverBackground(
  38. config: widget.config,
  39. child: widget.builder(context, _onHover),
  40. );
  41. } else {
  42. return widget.builder(context, _onHover);
  43. }
  44. }
  45. }
  46. class HoverDisplayConfig {
  47. final Color borderColor;
  48. final double borderWidth;
  49. final Color hoverColor;
  50. final BorderRadius borderRadius;
  51. const HoverDisplayConfig(
  52. {this.borderColor = Colors.transparent,
  53. this.borderWidth = 0,
  54. this.borderRadius = const BorderRadius.all(Radius.circular(6)),
  55. required this.hoverColor});
  56. }
  57. class FlowyHoverBackground extends StatelessWidget {
  58. final HoverDisplayConfig config;
  59. final Widget child;
  60. const FlowyHoverBackground({
  61. Key? key,
  62. required this.child,
  63. required this.config,
  64. }) : super(key: key);
  65. @override
  66. Widget build(BuildContext context) {
  67. final hoverBorder = Border.all(
  68. color: config.borderColor,
  69. width: config.borderWidth,
  70. );
  71. return Container(
  72. decoration: BoxDecoration(
  73. border: hoverBorder,
  74. color: config.hoverColor,
  75. borderRadius: config.borderRadius,
  76. ),
  77. child: child,
  78. );
  79. }
  80. }