| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 | import 'package:flowy_infra/theme.dart';import 'package:flowy_infra_ui/style_widget/hover.dart';import 'package:flutter/material.dart';import 'package:provider/provider.dart';import 'package:styled_widget/styled_widget.dart';class BoardCardContainer extends StatelessWidget {  final Widget child;  final CardAccessoryBuilder? accessoryBuilder;  final bool Function()? buildAccessoryWhen;  final void Function(BuildContext) onTap;  const BoardCardContainer({    required this.child,    required this.onTap,    this.accessoryBuilder,    this.buildAccessoryWhen,    Key? key,  }) : super(key: key);  @override  Widget build(BuildContext context) {    return ChangeNotifierProvider(      create: (_) => _CardContainerNotifier(),      child: Consumer<_CardContainerNotifier>(        builder: (context, notifier, _) {          Widget container = Center(child: child);          bool shouldBuildAccessory = true;          if (buildAccessoryWhen != null) {            shouldBuildAccessory = buildAccessoryWhen!.call();          }          if (accessoryBuilder != null && shouldBuildAccessory) {            final accessories = accessoryBuilder!(context);            if (accessories.isNotEmpty) {              container = _CardEnterRegion(                accessories: accessories,                child: container,              );            }          }          return GestureDetector(            onTap: () => onTap(context),            child: Padding(              padding: const EdgeInsets.all(8),              child: ConstrainedBox(                constraints: const BoxConstraints(minHeight: 30),                child: container,              ),            ),          );        },      ),    );  }}abstract class CardAccessory implements Widget {  void onTap(BuildContext context);}typedef CardAccessoryBuilder = List<CardAccessory> Function(  BuildContext buildContext,);class CardAccessoryContainer extends StatelessWidget {  final List<CardAccessory> accessories;  const CardAccessoryContainer({required this.accessories, Key? key})      : super(key: key);  @override  Widget build(BuildContext context) {    final theme = context.read<AppTheme>();    final children = accessories.map((accessory) {      final hover = FlowyHover(        style: HoverStyle(          hoverColor: theme.hover,          backgroundColor: theme.surface,          borderRadius: BorderRadius.zero,        ),        builder: (_, onHover) => SizedBox(          width: 24,          height: 24,          child: accessory,        ),      );      return GestureDetector(        behavior: HitTestBehavior.opaque,        onTap: () => accessory.onTap(context),        child: hover,      );    }).toList();    return Container(      clipBehavior: Clip.hardEdge,      decoration: _makeBoxDecoration(context),      child: Row(children: children),    );  }}BoxDecoration _makeBoxDecoration(BuildContext context) {  final theme = context.read<AppTheme>();  final borderSide = BorderSide(color: theme.shader6, width: 1.0);  return BoxDecoration(    color: Colors.transparent,    border: Border.fromBorderSide(borderSide),    // boxShadow: const [    //   BoxShadow(    //     color: Colors.transparent,    //     spreadRadius: 0,    //     blurRadius: 5,    //     offset: Offset.zero,    //   )    // ],    borderRadius: const BorderRadius.all(Radius.circular(4)),  );}class _CardEnterRegion extends StatelessWidget {  final Widget child;  final List<CardAccessory> accessories;  const _CardEnterRegion(      {required this.child, required this.accessories, Key? key})      : super(key: key);  @override  Widget build(BuildContext context) {    return Selector<_CardContainerNotifier, bool>(      selector: (context, notifier) => notifier.onEnter,      builder: (context, onEnter, _) {        List<Widget> children = [child];        if (onEnter) {          children.add(CardAccessoryContainer(            accessories: accessories,          ).positioned(right: 0));        }        return MouseRegion(          cursor: SystemMouseCursors.click,          onEnter: (p) =>              Provider.of<_CardContainerNotifier>(context, listen: false)                  .onEnter = true,          onExit: (p) =>              Provider.of<_CardContainerNotifier>(context, listen: false)                  .onEnter = false,          child: IntrinsicHeight(              child: Stack(            alignment: AlignmentDirectional.topEnd,            fit: StackFit.expand,            children: children,          )),        );      },    );  }}class _CardContainerNotifier extends ChangeNotifier {  bool _onEnter = false;  _CardContainerNotifier();  set onEnter(bool value) {    if (_onEnter != value) {      _onEnter = value;      notifyListeners();    }  }  bool get onEnter => _onEnter;}
 |