浏览代码

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
Richard Shiue 2 年之前
父节点
当前提交
3b3b61e67c

+ 23 - 27
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart

@@ -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),
+      ),
     );
   }
 }

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart

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

+ 54 - 50
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart

@@ -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,

+ 7 - 6
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart

@@ -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:

+ 2 - 6
frontend/app_flowy/lib/plugins/grid/presentation/widgets/common/text_field.dart

@@ -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);

+ 6 - 3
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart

@@ -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,
+              ),
             ),
           ],
         ),

+ 14 - 2
frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart

@@ -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,