chore: select option cell & header editor UI + move to theme.of(context).texttheme (#1483)

* chore: improvements for suffix text in textfields

* chore: port more const textstyles to theme provider styles

* chore: select option editor UI improvements
This commit is contained in:
Richard Shiue 2022-11-30 15:02:41 +08:00 committed by GitHub
parent f02e77fcd8
commit 3b3b61e67c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 107 additions and 95 deletions

View File

@ -1,4 +1,5 @@
import 'package:flowy_infra/color_extension.dart'; import 'package:flowy_infra/color_extension.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/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';
@ -87,17 +88,13 @@ class SelectOptionTag extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ChoiceChip( return Container(
pressElevation: 1, padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
label: FlowyText.medium( decoration: BoxDecoration(
name, color: color,
overflow: TextOverflow.clip, borderRadius: Corners.s6Border,
), ),
selectedColor: color, child: FlowyText.medium(name, overflow: TextOverflow.ellipsis),
backgroundColor: color,
labelPadding: const EdgeInsets.symmetric(horizontal: 6),
selected: true,
onSelected: (_) => onSelected?.call(),
); );
} }
} }
@ -115,30 +112,29 @@ class SelectOptionTagCell extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return FlowyHover(
fit: StackFit.expand, child: InkWell(
children: [ child: Row(
FlowyHover( mainAxisAlignment: MainAxisAlignment.spaceBetween,
child: InkWell( children: [
child: Padding( Expanded(
padding: const EdgeInsets.symmetric(horizontal: 3), child: Align(
child: Row( alignment: Alignment.centerLeft,
mainAxisAlignment: MainAxisAlignment.spaceBetween, child: Padding(
children: [ padding: const EdgeInsets.all(5.0),
SelectOptionTag.fromOption( child: SelectOptionTag.fromOption(
context: context, context: context,
option: option, option: option,
onSelected: () => onSelected(option), onSelected: () => onSelected(option),
), ),
const Spacer(), ),
...children,
],
), ),
), ),
onTap: () => onSelected(option), ...children,
), ],
), ),
], onTap: () => onSelected(option),
),
); );
} }
} }

View File

@ -223,7 +223,7 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
).toList(); ).toList();
child = Wrap( child = Wrap(
runSpacing: 2, runSpacing: 4,
children: children, children: children,
); );
} }

View File

@ -53,21 +53,24 @@ class _SelectOptionCellEditorState extends State<SelectOptionCellEditor> {
)..add(const SelectOptionEditorEvent.initial()), )..add(const SelectOptionEditorEvent.initial()),
child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>( child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
builder: (context, state) { builder: (context, state) {
final List<Widget> children = [
_TextField(popoverMutex: popoverMutex),
const TypeOptionSeparator(),
const _Title(),
_OptionList(popoverMutex: popoverMutex),
];
return Padding( return Padding(
padding: const EdgeInsets.all(6.0), padding: const EdgeInsets.all(6.0),
child: CustomScrollView( child: ListView.separated(
shrinkWrap: true, shrinkWrap: true,
slivers: [ itemCount: children.length,
SliverToBoxAdapter( itemBuilder: (BuildContext context, int index) {
child: _TextField(popoverMutex: popoverMutex), return children[index];
), },
const SliverToBoxAdapter(child: TypeOptionSeparator()), separatorBuilder: (BuildContext context, int index) {
const SliverToBoxAdapter(child: VSpace(6)), return VSpace(GridSize.typeOptionSeparatorHeight);
const SliverToBoxAdapter(child: _Title()), },
SliverToBoxAdapter(
child: _OptionList(popoverMutex: popoverMutex),
),
],
), ),
); );
}, },
@ -143,35 +146,32 @@ class _TextField extends StatelessWidget {
key: (option) => option.name, key: (option) => option.name,
value: (option) => option); value: (option) => option);
return SizedBox( return SelectOptionTextField(
height: 52, options: state.options,
child: SelectOptionTextField( selectedOptionMap: optionMap,
options: state.options, distanceToText: _editorPanelWidth * 0.7,
selectedOptionMap: optionMap, maxLength: 30,
distanceToText: _editorPanelWidth * 0.7, tagController: _tagController,
maxLength: 30, textSeparators: const [','],
tagController: _tagController, onClick: () => popoverMutex.close(),
textSeparators: const [','], newText: (text) {
onClick: () => popoverMutex.close(), context
newText: (text) { .read<SelectOptionCellEditorBloc>()
context .add(SelectOptionEditorEvent.filterOption(text));
.read<SelectOptionCellEditorBloc>() },
.add(SelectOptionEditorEvent.filterOption(text)); onSubmitted: (tagName) {
}, context
onSubmitted: (tagName) { .read<SelectOptionCellEditorBloc>()
context .add(SelectOptionEditorEvent.trySelectOption(tagName));
.read<SelectOptionCellEditorBloc>() },
.add(SelectOptionEditorEvent.trySelectOption(tagName)); onPaste: (tagNames, remainder) {
}, context
onPaste: (tagNames, remainder) { .read<SelectOptionCellEditorBloc>()
context .add(SelectOptionEditorEvent.selectMultipleOptions(
.read<SelectOptionCellEditorBloc>() tagNames,
.add(SelectOptionEditorEvent.selectMultipleOptions( remainder,
tagNames, ));
remainder, },
));
},
),
); );
}, },
); );
@ -209,12 +209,17 @@ class _CreateOptionCell extends StatelessWidget {
color: Theme.of(context).hintColor, color: Theme.of(context).hintColor,
), ),
const HSpace(10), const HSpace(10),
SelectOptionTag( Expanded(
name: name, child: Align(
color: AFThemeExtension.of(context).lightGreyHover, alignment: Alignment.centerLeft,
onSelected: () => context child: SelectOptionTag(
.read<SelectOptionCellEditorBloc>() name: name,
.add(SelectOptionEditorEvent.newOption(name)), color: AFThemeExtension.of(context).lightGreyHover,
onSelected: () => context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.newOption(name)),
),
),
), ),
], ],
); );
@ -271,14 +276,13 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
children: [ children: [
if (widget.isSelected) if (widget.isSelected)
Padding( Padding(
padding: const EdgeInsets.only(right: 6), padding: const EdgeInsets.only(left: 6),
child: svgWidget("grid/checkmark"), child: svgWidget("grid/checkmark"),
), ),
FlowyIconButton( FlowyIconButton(
width: 30,
onPressed: () => _popoverController.show(), onPressed: () => _popoverController.show(),
hoverColor: Colors.transparent, hoverColor: Colors.transparent,
iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), iconPadding: const EdgeInsets.symmetric(horizontal: 6.0),
icon: svgWidget( icon: svgWidget(
"editor/details", "editor/details",
color: Theme.of(context).colorScheme.onSurface, color: Theme.of(context).colorScheme.onSurface,

View File

@ -1,7 +1,6 @@
import 'dart:collection'; import 'dart:collection';
import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/text_style.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/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -49,7 +48,6 @@ class SelectOptionTextField extends StatefulWidget {
class _SelectOptionTextFieldState extends State<SelectOptionTextField> { class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
late FocusNode focusNode; late FocusNode focusNode;
late TextEditingController controller; late TextEditingController controller;
var textLength = 0;
@override @override
void initState() { void initState() {
@ -64,7 +62,7 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
String? _suffixText() { String? _suffixText() {
if (widget.maxLength != null) { if (widget.maxLength != null) {
return '${textLength.toString()}/${widget.maxLength.toString()}'; return ' ${controller.text.length}/${widget.maxLength}';
} else { } else {
return null; return null;
} }
@ -92,7 +90,6 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
focusNode: focusNode, focusNode: focusNode,
onTap: widget.onClick, onTap: widget.onClick,
onChanged: (text) { onChanged: (text) {
textLength = text.length;
if (onChanged != null) { if (onChanged != null) {
onChanged(text); onChanged(text);
} }
@ -112,11 +109,11 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
maxLength: widget.maxLength, maxLength: widget.maxLength,
maxLengthEnforcement: maxLengthEnforcement:
MaxLengthEnforcement.truncateAfterCompositionEnds, MaxLengthEnforcement.truncateAfterCompositionEnds,
style: TextStyles.body1.size(FontSizes.s14), style: Theme.of(context).textTheme.bodyMedium,
decoration: InputDecoration( decoration: InputDecoration(
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.outline,
width: 1.0, width: 1.0,
), ),
borderRadius: Corners.s10Border, borderRadius: Corners.s10Border,
@ -124,6 +121,10 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
isDense: true, isDense: true,
prefixIcon: _renderTags(context, sc), prefixIcon: _renderTags(context, sc),
hintText: LocaleKeys.grid_selectOption_searchOption.tr(), hintText: LocaleKeys.grid_selectOption_searchOption.tr(),
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.textColor(Theme.of(context).hintColor),
suffixText: _suffixText(), suffixText: _suffixText(),
counterText: "", counterText: "",
prefixIconConstraints: prefixIconConstraints:

View File

@ -1,8 +1,6 @@
import 'package:flowy_infra/text_style.dart';
import 'package:flowy_infra_ui/widget/rounded_input_field.dart'; import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:textstyle_extensions/textstyle_extensions.dart';
class InputTextField extends StatefulWidget { class InputTextField extends StatefulWidget {
final void Function(String)? onDone; final void Function(String)? onDone;
@ -47,15 +45,13 @@ class _InputTextFieldState extends State<InputTextField> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final height = widget.maxLength == null ? 36.0 : 56.0;
return RoundedInputField( return RoundedInputField(
controller: _controller, controller: _controller,
focusNode: _focusNode, focusNode: _focusNode,
autoFocus: true, autoFocus: true,
height: height, height: 36.0,
maxLength: widget.maxLength, maxLength: widget.maxLength,
style: TextStyles.body1.size(13), style: Theme.of(context).textTheme.bodyMedium,
onChanged: (text) { onChanged: (text) {
if (widget.onChanged != null) { if (widget.onChanged != null) {
widget.onChanged!(text); widget.onChanged!(text);

View File

@ -193,9 +193,12 @@ class _OptionCellState extends State<_OptionCell> {
_popoverController.show(); _popoverController.show();
}, },
children: [ children: [
svgWidget( Padding(
"grid/details", padding: const EdgeInsets.symmetric(horizontal: 6.0),
color: Theme.of(context).colorScheme.onSurface, child: svgWidget(
"grid/details",
color: Theme.of(context).colorScheme.onSurface,
),
), ),
], ],
), ),

View File

@ -73,6 +73,14 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
super.initState(); super.initState();
} }
String? _suffixText() {
if (widget.maxLength != null) {
return ' ${widget.controller!.text.length}/${widget.maxLength}';
} else {
return null;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var borderColor = var borderColor =
@ -117,8 +125,12 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
decoration: InputDecoration( decoration: InputDecoration(
contentPadding: widget.contentPadding, contentPadding: widget.contentPadding,
hintText: widget.hintText, hintText: widget.hintText,
hintStyle: hintStyle: Theme.of(context)
Theme.of(context).textTheme.bodySmall!.textColor(borderColor), .textTheme
.bodySmall!
.textColor(Theme.of(context).hintColor),
suffixText: _suffixText(),
counterText: "",
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: borderColor, color: borderColor,