fix: hover color highlight with custom widget

This commit is contained in:
appflowy 2021-07-27 11:54:59 +08:00
parent 5d520d7217
commit 56ced4a76f
8 changed files with 150 additions and 90 deletions

View file

@ -1,7 +1,6 @@
import 'package:app_flowy/workspace/presentation/view/view_widget.dart';
import 'package:flowy_infra/flowy_logger.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flowy_infra_ui/style_widget/styled_hover.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:dartz/dartz.dart';
@ -17,22 +16,18 @@ class ViewList extends StatelessWidget {
() => const SizedBox(),
(views) {
return Column(
children: _renderViewWidgets(views),
children: _renderViews(views),
);
},
);
}
List<Widget> _renderViewWidgets(List<View> views) {
List<Widget> _renderViews(List<View> views) {
var targetViews = views.map((view) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: StyledHover(
color: Colors.red,
borderRadius: BorderRadius.circular(8),
child: ViewWidget(
view: view,
),
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
child: ViewWidget(
view: view,
),
);
}).toList(growable: false);

View file

@ -5,6 +5,8 @@ import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter/material.dart';
import 'package:flowy_infra_ui/style_widget/styled_more.dart';
import 'package:flowy_infra_ui/style_widget/styled_hover.dart';
class ViewWidget extends StatelessWidget {
final View view;
@ -12,32 +14,56 @@ class ViewWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final contentPadding = EdgeInsets.only(
left: AppWidgetSize.expandedPadding, top: 5, bottom: 5, right: 5);
return InkWell(
onTap: _openView(context),
child: Padding(
padding: contentPadding,
child: buildContent(),
child: StyledHover(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(8),
builder: (context, onHover) => _render(context, onHover),
),
);
}
Row buildContent() {
return Row(
children: [
Image(
fit: BoxFit.cover,
width: 20,
height: 20,
image: assetImageForViewType(view.viewType)),
const HSpace(6),
Text(
view.name,
textAlign: TextAlign.start,
style: const TextStyle(fontSize: 15),
)
],
Widget _render(BuildContext context, bool onHover) {
const double width = 20;
List<Widget> children = [
Image(
fit: BoxFit.cover,
width: width,
height: width,
image: assetImageForViewType(view.viewType)),
const HSpace(6),
Text(
view.name,
textAlign: TextAlign.start,
style: const TextStyle(fontSize: 15),
),
];
if (onHover) {
children.add(const Spacer());
children.add(Align(
alignment: Alignment.center,
child: StyledMore(
width: width,
onPressed: () {},
),
));
}
final padding = EdgeInsets.only(
left: AppWidgetSize.expandedPadding,
top: 5,
bottom: 5,
right: 5,
);
return Padding(
padding: padding,
child: Flexible(
child: Row(children: children),
),
);
}

View file

@ -5,6 +5,8 @@ import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pbenum.dart';
import 'package:flutter/material.dart';
import 'package:flowy_infra_ui/style_widget/styled_more.dart';
import 'package:flowy_infra_ui/style_widget/styled_text.dart';
class HomeTopBar extends StatelessWidget {
final HomeStackView view;
@ -50,14 +52,9 @@ class HomeTopBar extends StatelessWidget {
}
Widget _renderMoreButton() {
return SizedBox(
return StyledMore(
width: 24,
child: IconButton(
icon: const Icon(Icons.more_vert),
iconSize: 12,
alignment: Alignment.center,
onPressed: () {},
),
onPressed: () {},
);
}
}
@ -83,12 +80,7 @@ class HomeTitle extends StatelessWidget {
height: 15,
image: assetImageForViewType(type)),
const HSpace(6),
Text(
title,
overflow: TextOverflow.fade,
softWrap: false,
style: const TextStyle(fontSize: 16),
),
StyledText(title, fontSize: 16),
],
),
);

View file

@ -5,6 +5,7 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flowy_infra_ui/style_widget/styled_text.dart';
class MenuUser extends MenuItem {
final UserDetail user;
@ -44,12 +45,7 @@ class MenuUser extends MenuItem {
name = context.read<MenuUserBloc>().state.user.email;
}
return Flexible(
child: Text(
name,
overflow: TextOverflow.fade,
softWrap: false,
style: const TextStyle(fontSize: 18),
),
child: StyledText(name, fontSize: 18),
);
}

View file

@ -1,59 +1,58 @@
import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart';
import 'package:flutter/material.dart';
import 'package:flowy_infra/time/duration.dart';
class StyledHover extends StatelessWidget {
typedef HoverBuilder = Widget Function(BuildContext context, bool onHover);
class StyledHover extends StatefulWidget {
final Color color;
final Color borderColor;
final double borderWidth;
final Widget child;
final BorderRadius borderRadius;
final HoverBuilder builder;
const StyledHover({
Key? key,
required this.color,
required this.child,
this.borderColor = Colors.transparent,
this.borderWidth = 0,
this.borderRadius = BorderRadius.zero,
required this.builder,
}) : super(key: key);
@override
State<StyledHover> createState() => _StyledHoverState();
}
class _StyledHoverState extends State<StyledHover> {
bool _onHover = false;
@override
Widget build(BuildContext context) {
return MouseHoverBuilder(
builder: (_, isHovered) => AnimatedContainer(
final hoverColor =
_onHover ? widget.color : Theme.of(context).colorScheme.background;
final hoverBorder = Border.all(
color: widget.borderColor,
width: widget.borderWidth,
);
final animatedDuration = .1.seconds;
return MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (p) => setOnHover(true),
onExit: (p) => setOnHover(false),
child: AnimatedContainer(
decoration: BoxDecoration(
border: Border.all(color: borderColor, width: borderWidth),
color: isHovered ? color : Colors.transparent,
borderRadius: borderRadius,
border: hoverBorder,
color: hoverColor,
borderRadius: widget.borderRadius,
),
duration: .1.seconds,
child: child,
duration: animatedDuration,
child: widget.builder(context, _onHover),
),
);
}
void setOnHover(bool value) => setState(() => _onHover = value);
}
// @override
// Widget build(BuildContext context) {
// return GestureDetector(
// behavior: HitTestBehavior.translucent,
// onTap: () {
// context
// .read<HomeBloc>()
// .add(HomeEvent.setEditPannel(CellEditPannelContext()));
// },
// child: MouseHoverBuilder(
// builder: (_, isHovered) => Container(
// width: width,
// decoration: CellDecoration.box(
// color: isHovered ? Colors.red.withOpacity(.1) : Colors.transparent,
// ),
// padding: EdgeInsets.symmetric(
// vertical: GridInsets.vertical, horizontal: GridInsets.horizontal),
// child: child,
// ),
// ),
// );
// }

View file

@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
class StyledMore extends StatelessWidget {
final double width;
final double? height;
final VoidCallback? onPressed;
const StyledMore({
Key? key,
required this.width,
this.height,
this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
height: height ?? width,
child: IconButton(
icon: const Icon(Icons.more_vert),
padding: EdgeInsets.zero,
iconSize: width / 2,
alignment: Alignment.center,
onPressed: onPressed,
),
);
}
}

View file

@ -0,0 +1,23 @@
import 'package:flutter/widgets.dart';
class StyledText extends StatelessWidget {
final String title;
final TextOverflow overflow;
final double fontSize;
const StyledText(
this.title, {
Key? key,
this.overflow = TextOverflow.fade,
this.fontSize = 16,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
title,
overflow: overflow,
softWrap: false,
style: TextStyle(fontSize: fontSize),
);
}
}

View file

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
typedef HoverBuilder = Widget Function(BuildContext context, bool isHovering);
typedef HoverBuilder = Widget Function(BuildContext context, bool onHover);
class MouseHoverBuilder extends StatefulWidget {
final bool isClickable;
@ -17,7 +17,7 @@ class MouseHoverBuilder extends StatefulWidget {
}
class _MouseHoverBuilderState extends State<MouseHoverBuilder> {
bool isOver = false;
bool _onHover = false;
@override
Widget build(BuildContext context) {
@ -25,11 +25,11 @@ class _MouseHoverBuilderState extends State<MouseHoverBuilder> {
cursor: widget.isClickable
? SystemMouseCursors.click
: SystemMouseCursors.basic,
onEnter: (p) => setOver(true),
onExit: (p) => setOver(false),
child: widget.builder(context, isOver),
onEnter: (p) => setOnHover(true),
onExit: (p) => setOnHover(false),
child: widget.builder(context, _onHover),
);
}
void setOver(bool value) => setState(() => isOver = value);
void setOnHover(bool value) => setState(() => _onHover = value);
}