From 1a2af1cf492be26543b494789cf0e505cc57ebd0 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Wed, 4 Jan 2023 19:43:49 +0800 Subject: [PATCH] chore: add close button in select option tags for select option textfield (#1640) * chore: remove unused isSelected flag * chore: close popover when an option is deleted * chore: allow unselecting an option by clicking on a close button --- .../cell/select_option_cell/extension.dart | 38 +++++++++++++--- .../select_option_editor.dart | 8 ++++ .../cell/select_option_cell/text_field.dart | 44 +++++++++++-------- .../select_option_text_field_test.dart | 1 + 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart index 69b6c8d4a7..4947b03c15 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart @@ -1,6 +1,8 @@ +import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart'; import 'package:flutter/material.dart'; @@ -62,13 +64,13 @@ extension SelectOptionColorExtension on SelectOptionColorPB { class SelectOptionTag extends StatelessWidget { final String name; final Color color; - final bool isSelected; final VoidCallback? onSelected; + final void Function(String)? onRemove; const SelectOptionTag({ required this.name, required this.color, this.onSelected, - this.isSelected = false, + this.onRemove, Key? key, }) : super(key: key); @@ -76,25 +78,49 @@ class SelectOptionTag extends StatelessWidget { required BuildContext context, required SelectOptionPB option, VoidCallback? onSelected, - bool isSelected = false, + Function(String)? onRemove, }) { return SelectOptionTag( name: option.name, color: option.color.make(context), - isSelected: isSelected, onSelected: onSelected, + onRemove: onRemove, ); } @override Widget build(BuildContext context) { + EdgeInsets padding = + const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0); + if (onRemove != null) { + padding = padding.copyWith(right: 2.0); + } + return Container( - padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0), + padding: padding, decoration: BoxDecoration( color: color, borderRadius: Corners.s6Border, ), - child: FlowyText.medium(name, overflow: TextOverflow.ellipsis), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: FlowyText.medium(name, overflow: TextOverflow.ellipsis), + ), + if (onRemove != null) + FlowyIconButton( + width: 18.0, + onPressed: () => onRemove?.call(name), + fillColor: Colors.transparent, + hoverColor: Colors.transparent, + icon: svgWidget( + 'home/close', + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ], + ), ); } } diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart index 3ec747be5e..f6a694d7ad 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart @@ -159,6 +159,13 @@ class _TextField extends StatelessWidget { remainder, )); }, + onRemove: (optionName) { + context + .read() + .add(SelectOptionEditorEvent.unSelectOption( + optionMap[optionName]!.id, + )); + }, ), ); }, @@ -297,6 +304,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { context .read() .add(SelectOptionEditorEvent.deleteOption(widget.option)); + PopoverContainer.of(popoverContext).close(); }, onUpdated: (updatedOption) { context diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart index 0c53944f20..8068ea88a1 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart @@ -22,6 +22,7 @@ class SelectOptionTextField extends StatefulWidget { final Function(String) onSubmitted; final Function(String) newText; final Function(List, String) onPaste; + final Function(String) onRemove; final VoidCallback? onClick; final int? maxLength; @@ -32,6 +33,7 @@ class SelectOptionTextField extends StatefulWidget { required this.tagController, required this.onSubmitted, required this.onPaste, + required this.onRemove, required this.newText, required this.textSeparators, this.onClick, @@ -163,25 +165,31 @@ class _SelectOptionTextFieldState extends State { } final children = widget.selectedOptionMap.values - .map((option) => - SelectOptionTag.fromOption(context: context, option: option)) + .map((option) => SelectOptionTag.fromOption( + context: context, + option: option, + onRemove: (option) => widget.onRemove(option), + )) .toList(); - return Padding( - padding: const EdgeInsets.all(8.0), - child: ScrollConfiguration( - behavior: ScrollConfiguration.of(context).copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.trackpad, - PointerDeviceKind.stylus, - PointerDeviceKind.invertedStylus, - }, - ), - child: SingleChildScrollView( - controller: sc, - scrollDirection: Axis.horizontal, - child: Wrap(spacing: 4, children: children), + return MouseRegion( + cursor: SystemMouseCursors.basic, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith( + dragDevices: { + PointerDeviceKind.mouse, + PointerDeviceKind.touch, + PointerDeviceKind.trackpad, + PointerDeviceKind.stylus, + PointerDeviceKind.invertedStylus, + }, + ), + child: SingleChildScrollView( + controller: sc, + scrollDirection: Axis.horizontal, + child: Wrap(spacing: 4, children: children), + ), ), ), ); diff --git a/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart b/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart index 01e36edd85..7580b30b68 100644 --- a/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart +++ b/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart @@ -28,6 +28,7 @@ void main() { remainder = remaining; select = options; }, + onRemove: (_) {}, newText: (text) => remainder = text, textSeparators: const [','], textController: TextEditingController(),