mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
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:
parent
f02e77fcd8
commit
3b3b61e67c
@ -1,4 +1,5 @@
|
||||
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/text.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
@ -87,17 +88,13 @@ class SelectOptionTag extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChoiceChip(
|
||||
pressElevation: 1,
|
||||
label: FlowyText.medium(
|
||||
name,
|
||||
overflow: TextOverflow.clip,
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: Corners.s6Border,
|
||||
),
|
||||
selectedColor: color,
|
||||
backgroundColor: color,
|
||||
labelPadding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
selected: true,
|
||||
onSelected: (_) => onSelected?.call(),
|
||||
child: FlowyText.medium(name, overflow: TextOverflow.ellipsis),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -115,30 +112,29 @@ class SelectOptionTagCell extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
FlowyHover(
|
||||
child: InkWell(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SelectOptionTag.fromOption(
|
||||
return FlowyHover(
|
||||
child: InkWell(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: SelectOptionTag.fromOption(
|
||||
context: context,
|
||||
option: option,
|
||||
onSelected: () => onSelected(option),
|
||||
),
|
||||
const Spacer(),
|
||||
...children,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () => onSelected(option),
|
||||
),
|
||||
...children,
|
||||
],
|
||||
),
|
||||
],
|
||||
onTap: () => onSelected(option),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
|
||||
).toList();
|
||||
|
||||
child = Wrap(
|
||||
runSpacing: 2,
|
||||
runSpacing: 4,
|
||||
children: children,
|
||||
);
|
||||
}
|
||||
|
@ -53,21 +53,24 @@ class _SelectOptionCellEditorState extends State<SelectOptionCellEditor> {
|
||||
)..add(const SelectOptionEditorEvent.initial()),
|
||||
child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
|
||||
builder: (context, state) {
|
||||
final List<Widget> children = [
|
||||
_TextField(popoverMutex: popoverMutex),
|
||||
const TypeOptionSeparator(),
|
||||
const _Title(),
|
||||
_OptionList(popoverMutex: popoverMutex),
|
||||
];
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: CustomScrollView(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: _TextField(popoverMutex: popoverMutex),
|
||||
),
|
||||
const SliverToBoxAdapter(child: TypeOptionSeparator()),
|
||||
const SliverToBoxAdapter(child: VSpace(6)),
|
||||
const SliverToBoxAdapter(child: _Title()),
|
||||
SliverToBoxAdapter(
|
||||
child: _OptionList(popoverMutex: popoverMutex),
|
||||
),
|
||||
],
|
||||
itemCount: children.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return children[index];
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return VSpace(GridSize.typeOptionSeparatorHeight);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -143,35 +146,32 @@ class _TextField extends StatelessWidget {
|
||||
key: (option) => option.name,
|
||||
value: (option) => option);
|
||||
|
||||
return SizedBox(
|
||||
height: 52,
|
||||
child: SelectOptionTextField(
|
||||
options: state.options,
|
||||
selectedOptionMap: optionMap,
|
||||
distanceToText: _editorPanelWidth * 0.7,
|
||||
maxLength: 30,
|
||||
tagController: _tagController,
|
||||
textSeparators: const [','],
|
||||
onClick: () => popoverMutex.close(),
|
||||
newText: (text) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.filterOption(text));
|
||||
},
|
||||
onSubmitted: (tagName) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.trySelectOption(tagName));
|
||||
},
|
||||
onPaste: (tagNames, remainder) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.selectMultipleOptions(
|
||||
tagNames,
|
||||
remainder,
|
||||
));
|
||||
},
|
||||
),
|
||||
return SelectOptionTextField(
|
||||
options: state.options,
|
||||
selectedOptionMap: optionMap,
|
||||
distanceToText: _editorPanelWidth * 0.7,
|
||||
maxLength: 30,
|
||||
tagController: _tagController,
|
||||
textSeparators: const [','],
|
||||
onClick: () => popoverMutex.close(),
|
||||
newText: (text) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.filterOption(text));
|
||||
},
|
||||
onSubmitted: (tagName) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.trySelectOption(tagName));
|
||||
},
|
||||
onPaste: (tagNames, remainder) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.selectMultipleOptions(
|
||||
tagNames,
|
||||
remainder,
|
||||
));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -209,12 +209,17 @@ class _CreateOptionCell extends StatelessWidget {
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
const HSpace(10),
|
||||
SelectOptionTag(
|
||||
name: name,
|
||||
color: AFThemeExtension.of(context).lightGreyHover,
|
||||
onSelected: () => context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.newOption(name)),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: SelectOptionTag(
|
||||
name: name,
|
||||
color: AFThemeExtension.of(context).lightGreyHover,
|
||||
onSelected: () => context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.newOption(name)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -271,14 +276,13 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
|
||||
children: [
|
||||
if (widget.isSelected)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 6),
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: svgWidget("grid/checkmark"),
|
||||
),
|
||||
FlowyIconButton(
|
||||
width: 30,
|
||||
onPressed: () => _popoverController.show(),
|
||||
hoverColor: Colors.transparent,
|
||||
iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4),
|
||||
iconPadding: const EdgeInsets.symmetric(horizontal: 6.0),
|
||||
icon: svgWidget(
|
||||
"editor/details",
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'dart:collection';
|
||||
|
||||
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:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -49,7 +48,6 @@ class SelectOptionTextField extends StatefulWidget {
|
||||
class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
|
||||
late FocusNode focusNode;
|
||||
late TextEditingController controller;
|
||||
var textLength = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -64,7 +62,7 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
|
||||
|
||||
String? _suffixText() {
|
||||
if (widget.maxLength != null) {
|
||||
return '${textLength.toString()}/${widget.maxLength.toString()}';
|
||||
return ' ${controller.text.length}/${widget.maxLength}';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -92,7 +90,6 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
|
||||
focusNode: focusNode,
|
||||
onTap: widget.onClick,
|
||||
onChanged: (text) {
|
||||
textLength = text.length;
|
||||
if (onChanged != null) {
|
||||
onChanged(text);
|
||||
}
|
||||
@ -112,11 +109,11 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
|
||||
maxLength: widget.maxLength,
|
||||
maxLengthEnforcement:
|
||||
MaxLengthEnforcement.truncateAfterCompositionEnds,
|
||||
style: TextStyles.body1.size(FontSizes.s14),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
decoration: InputDecoration(
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
width: 1.0,
|
||||
),
|
||||
borderRadius: Corners.s10Border,
|
||||
@ -124,6 +121,10 @@ class _SelectOptionTextFieldState extends State<SelectOptionTextField> {
|
||||
isDense: true,
|
||||
prefixIcon: _renderTags(context, sc),
|
||||
hintText: LocaleKeys.grid_selectOption_searchOption.tr(),
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.textColor(Theme.of(context).hintColor),
|
||||
suffixText: _suffixText(),
|
||||
counterText: "",
|
||||
prefixIconConstraints:
|
||||
|
@ -1,8 +1,6 @@
|
||||
import 'package:flowy_infra/text_style.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
||||
|
||||
class InputTextField extends StatefulWidget {
|
||||
final void Function(String)? onDone;
|
||||
@ -47,15 +45,13 @@ class _InputTextFieldState extends State<InputTextField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final height = widget.maxLength == null ? 36.0 : 56.0;
|
||||
|
||||
return RoundedInputField(
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
autoFocus: true,
|
||||
height: height,
|
||||
height: 36.0,
|
||||
maxLength: widget.maxLength,
|
||||
style: TextStyles.body1.size(13),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
onChanged: (text) {
|
||||
if (widget.onChanged != null) {
|
||||
widget.onChanged!(text);
|
||||
|
@ -193,9 +193,12 @@ class _OptionCellState extends State<_OptionCell> {
|
||||
_popoverController.show();
|
||||
},
|
||||
children: [
|
||||
svgWidget(
|
||||
"grid/details",
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6.0),
|
||||
child: svgWidget(
|
||||
"grid/details",
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -73,6 +73,14 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
String? _suffixText() {
|
||||
if (widget.maxLength != null) {
|
||||
return ' ${widget.controller!.text.length}/${widget.maxLength}';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var borderColor =
|
||||
@ -117,8 +125,12 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
decoration: InputDecoration(
|
||||
contentPadding: widget.contentPadding,
|
||||
hintText: widget.hintText,
|
||||
hintStyle:
|
||||
Theme.of(context).textTheme.bodySmall!.textColor(borderColor),
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.textColor(Theme.of(context).hintColor),
|
||||
suffixText: _suffixText(),
|
||||
counterText: "",
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: borderColor,
|
||||
|
Loading…
Reference in New Issue
Block a user