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
This commit is contained in:
Richard Shiue 2023-01-04 19:43:49 +08:00 committed by GitHub
parent 340f27cf87
commit 1a2af1cf49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 24 deletions

View File

@ -1,6 +1,8 @@
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/style_widget/hover.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_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -62,13 +64,13 @@ extension SelectOptionColorExtension on SelectOptionColorPB {
class SelectOptionTag extends StatelessWidget { class SelectOptionTag extends StatelessWidget {
final String name; final String name;
final Color color; final Color color;
final bool isSelected;
final VoidCallback? onSelected; final VoidCallback? onSelected;
final void Function(String)? onRemove;
const SelectOptionTag({ const SelectOptionTag({
required this.name, required this.name,
required this.color, required this.color,
this.onSelected, this.onSelected,
this.isSelected = false, this.onRemove,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -76,25 +78,49 @@ class SelectOptionTag extends StatelessWidget {
required BuildContext context, required BuildContext context,
required SelectOptionPB option, required SelectOptionPB option,
VoidCallback? onSelected, VoidCallback? onSelected,
bool isSelected = false, Function(String)? onRemove,
}) { }) {
return SelectOptionTag( return SelectOptionTag(
name: option.name, name: option.name,
color: option.color.make(context), color: option.color.make(context),
isSelected: isSelected,
onSelected: onSelected, onSelected: onSelected,
onRemove: onRemove,
); );
} }
@override @override
Widget build(BuildContext context) { 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( return Container(
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0), padding: padding,
decoration: BoxDecoration( decoration: BoxDecoration(
color: color, color: color,
borderRadius: Corners.s6Border, 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,
),
),
],
),
); );
} }
} }

View File

@ -159,6 +159,13 @@ class _TextField extends StatelessWidget {
remainder, remainder,
)); ));
}, },
onRemove: (optionName) {
context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.unSelectOption(
optionMap[optionName]!.id,
));
},
), ),
); );
}, },
@ -297,6 +304,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
context context
.read<SelectOptionCellEditorBloc>() .read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.deleteOption(widget.option)); .add(SelectOptionEditorEvent.deleteOption(widget.option));
PopoverContainer.of(popoverContext).close();
}, },
onUpdated: (updatedOption) { onUpdated: (updatedOption) {
context context

View File

@ -22,6 +22,7 @@ class SelectOptionTextField extends StatefulWidget {
final Function(String) onSubmitted; final Function(String) onSubmitted;
final Function(String) newText; final Function(String) newText;
final Function(List<String>, String) onPaste; final Function(List<String>, String) onPaste;
final Function(String) onRemove;
final VoidCallback? onClick; final VoidCallback? onClick;
final int? maxLength; final int? maxLength;
@ -32,6 +33,7 @@ class SelectOptionTextField extends StatefulWidget {
required this.tagController, required this.tagController,
required this.onSubmitted, required this.onSubmitted,
required this.onPaste, required this.onPaste,
required this.onRemove,
required this.newText, required this.newText,
required this.textSeparators, required this.textSeparators,
this.onClick, this.onClick,
@ -163,25 +165,31 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
} }
final children = widget.selectedOptionMap.values final children = widget.selectedOptionMap.values
.map((option) => .map((option) => SelectOptionTag.fromOption(
SelectOptionTag.fromOption(context: context, option: option)) context: context,
option: option,
onRemove: (option) => widget.onRemove(option),
))
.toList(); .toList();
return Padding( return MouseRegion(
padding: const EdgeInsets.all(8.0), cursor: SystemMouseCursors.basic,
child: ScrollConfiguration( child: Padding(
behavior: ScrollConfiguration.of(context).copyWith( padding: const EdgeInsets.all(8.0),
dragDevices: { child: ScrollConfiguration(
PointerDeviceKind.mouse, behavior: ScrollConfiguration.of(context).copyWith(
PointerDeviceKind.touch, dragDevices: {
PointerDeviceKind.trackpad, PointerDeviceKind.mouse,
PointerDeviceKind.stylus, PointerDeviceKind.touch,
PointerDeviceKind.invertedStylus, PointerDeviceKind.trackpad,
}, PointerDeviceKind.stylus,
), PointerDeviceKind.invertedStylus,
child: SingleChildScrollView( },
controller: sc, ),
scrollDirection: Axis.horizontal, child: SingleChildScrollView(
child: Wrap(spacing: 4, children: children), controller: sc,
scrollDirection: Axis.horizontal,
child: Wrap(spacing: 4, children: children),
),
), ),
), ),
); );

View File

@ -28,6 +28,7 @@ void main() {
remainder = remaining; remainder = remaining;
select = options; select = options;
}, },
onRemove: (_) {},
newText: (text) => remainder = text, newText: (text) => remainder = text,
textSeparators: const [','], textSeparators: const [','],
textController: TextEditingController(), textController: TextEditingController(),