فهرست منبع

feat: show the scrollbars again (#1605)

* fix: padding in grid cell editors

* fix: padding in grid header editor

* fix: padding for row details

* fix: shrink number formt list when possible

* chore: simply use column for select option editor

* fix: make sure that popovers are the edges

* fix: delete button padding

* fix: date and time formats padding mistake
Richard Shiue 2 سال پیش
والد
کامیت
70689d3239
16فایلهای تغییر یافته به همراه437 افزوده شده و 343 حذف شده
  1. 0 1
      frontend/app_flowy/lib/plugins/grid/presentation/layout/sizes.dart
  2. 91 68
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart
  3. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart
  4. 108 108
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart
  5. 3 2
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/common/type_option_separator.dart
  6. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart
  7. 5 3
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell_action_sheet.dart
  8. 39 39
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart
  9. 5 2
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart
  10. 42 28
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart
  11. 27 15
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/number.dart
  12. 73 56
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart
  13. 25 20
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option_editor.dart
  14. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart
  15. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart
  16. 15 1
      frontend/app_flowy/lib/workspace/application/appearance.dart

+ 0 - 1
frontend/app_flowy/lib/plugins/grid/presentation/layout/sizes.dart

@@ -14,7 +14,6 @@ class GridSize {
   static double get typeOptionItemHeight => 32 * scale;
   static double get typeOptionItemHeight => 32 * scale;
   static double get typeOptionSeparatorHeight => 4 * scale;
   static double get typeOptionSeparatorHeight => 4 * scale;
 
 
-  //
   static EdgeInsets get headerContentInsets => EdgeInsets.symmetric(
   static EdgeInsets get headerContentInsets => EdgeInsets.symmetric(
         horizontal: GridSize.headerContainerPadding,
         horizontal: GridSize.headerContainerPadding,
         vertical: GridSize.headerContainerPadding,
         vertical: GridSize.headerContainerPadding,

+ 91 - 68
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart

@@ -1,6 +1,7 @@
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
+import 'package:app_flowy/plugins/grid/presentation/widgets/common/type_option_separator.dart';
 import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle.dart';
 import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle.dart';
 import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle_style.dart';
 import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle_style.dart';
 import 'package:appflowy_popover/appflowy_popover.dart';
 import 'package:appflowy_popover/appflowy_popover.dart';
@@ -62,12 +63,9 @@ class _DateCellEditor extends State<DateCellEditor> {
   Widget _buildWidget(AsyncSnapshot<Either<dynamic, FlowyError>> snapshot) {
   Widget _buildWidget(AsyncSnapshot<Either<dynamic, FlowyError>> snapshot) {
     return snapshot.data!.fold(
     return snapshot.data!.fold(
       (dateTypeOptionPB) {
       (dateTypeOptionPB) {
-        return Padding(
-          padding: const EdgeInsets.all(12),
-          child: _CellCalendarWidget(
-            cellContext: widget.cellController,
-            dateTypeOptionPB: dateTypeOptionPB,
-          ),
+        return _CellCalendarWidget(
+          cellContext: widget.cellController,
+          dateTypeOptionPB: dateTypeOptionPB,
         );
         );
       },
       },
       (err) {
       (err) {
@@ -116,26 +114,29 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
         buildWhen: (p, c) => p != c,
         buildWhen: (p, c) => p != c,
         builder: (context, state) {
         builder: (context, state) {
           List<Widget> children = [
           List<Widget> children = [
-            _buildCalendar(context),
-            if (state.dateTypeOptionPB.includeTime)
+            Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 12.0),
+              child: _buildCalendar(context),
+            ),
+            if (state.dateTypeOptionPB.includeTime) ...[
+              const VSpace(12.0),
               _TimeTextField(
               _TimeTextField(
                 bloc: context.read<DateCalBloc>(),
                 bloc: context.read<DateCalBloc>(),
                 popoverMutex: popoverMutex,
                 popoverMutex: popoverMutex,
               ),
               ),
-            Divider(height: 1.0, color: Theme.of(context).dividerColor),
+            ],
+            const TypeOptionSeparator(spacing: 12.0),
             const _IncludeTimeButton(),
             const _IncludeTimeButton(),
-            Divider(height: 1.0, color: Theme.of(context).dividerColor),
+            const TypeOptionSeparator(spacing: 12.0),
             _DateTypeOptionButton(popoverMutex: popoverMutex)
             _DateTypeOptionButton(popoverMutex: popoverMutex)
           ];
           ];
 
 
-          return ListView.separated(
+          return ListView.builder(
             shrinkWrap: true,
             shrinkWrap: true,
             controller: ScrollController(),
             controller: ScrollController(),
-            separatorBuilder: (context, index) => VSpace(GridSize.cellVPadding),
             itemCount: children.length,
             itemCount: children.length,
-            itemBuilder: (BuildContext context, int index) {
-              return children[index];
-            },
+            itemBuilder: (BuildContext context, int index) => children[index],
+            padding: const EdgeInsets.symmetric(vertical: 12.0),
           );
           );
         },
         },
       ),
       ),
@@ -171,10 +172,16 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
             titleTextStyle: textStyle,
             titleTextStyle: textStyle,
             leftChevronMargin: EdgeInsets.zero,
             leftChevronMargin: EdgeInsets.zero,
             leftChevronPadding: EdgeInsets.zero,
             leftChevronPadding: EdgeInsets.zero,
-            leftChevronIcon: svgWidget("home/arrow_left"),
+            leftChevronIcon: svgWidget(
+              "home/arrow_left",
+              color: Theme.of(context).colorScheme.onSurface,
+            ),
             rightChevronPadding: EdgeInsets.zero,
             rightChevronPadding: EdgeInsets.zero,
             rightChevronMargin: EdgeInsets.zero,
             rightChevronMargin: EdgeInsets.zero,
-            rightChevronIcon: svgWidget("home/arrow_right"),
+            rightChevronIcon: svgWidget(
+              "home/arrow_right",
+              color: Theme.of(context).colorScheme.onSurface,
+            ),
             headerMargin: const EdgeInsets.only(bottom: 8.0),
             headerMargin: const EdgeInsets.only(bottom: 8.0),
           ),
           ),
           daysOfWeekStyle: DaysOfWeekStyle(
           daysOfWeekStyle: DaysOfWeekStyle(
@@ -233,28 +240,31 @@ class _IncludeTimeButton extends StatelessWidget {
     return BlocSelector<DateCalBloc, DateCalState, bool>(
     return BlocSelector<DateCalBloc, DateCalState, bool>(
       selector: (state) => state.dateTypeOptionPB.includeTime,
       selector: (state) => state.dateTypeOptionPB.includeTime,
       builder: (context, includeTime) {
       builder: (context, includeTime) {
-        return SizedBox(
-          height: GridSize.typeOptionItemHeight,
-          child: Padding(
-            padding: GridSize.typeOptionContentInsets,
-            child: Row(
-              children: [
-                svgWidget(
-                  "grid/clock",
-                  color: Theme.of(context).colorScheme.onSurface,
-                ),
-                const HSpace(4),
-                FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()),
-                const Spacer(),
-                Toggle(
-                  value: includeTime,
-                  onChanged: (value) => context
-                      .read<DateCalBloc>()
-                      .add(DateCalEvent.setIncludeTime(!value)),
-                  style: ToggleStyle.big,
-                  padding: EdgeInsets.zero,
-                ),
-              ],
+        return Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 12.0),
+          child: SizedBox(
+            height: GridSize.typeOptionItemHeight,
+            child: Padding(
+              padding: GridSize.typeOptionContentInsets,
+              child: Row(
+                children: [
+                  svgWidget(
+                    "grid/clock",
+                    color: Theme.of(context).colorScheme.onSurface,
+                  ),
+                  const HSpace(4),
+                  FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()),
+                  const Spacer(),
+                  Toggle(
+                    value: includeTime,
+                    onChanged: (value) => context
+                        .read<DateCalBloc>()
+                        .add(DateCalEvent.setIncludeTime(!value)),
+                    style: ToggleStyle.big,
+                    padding: EdgeInsets.zero,
+                  ),
+                ],
+              ),
             ),
             ),
           ),
           ),
         );
         );
@@ -313,22 +323,25 @@ class _TimeTextFieldState extends State<_TimeTextField> {
     _controller.selection =
     _controller.selection =
         TextSelection.collapsed(offset: _controller.text.length);
         TextSelection.collapsed(offset: _controller.text.length);
     return Padding(
     return Padding(
-      padding: GridSize.typeOptionContentInsets,
-      child: RoundedInputField(
-        height: GridSize.typeOptionItemHeight,
-        focusNode: _focusNode,
-        autoFocus: true,
-        hintText: widget.bloc.state.timeHintText,
-        controller: _controller,
-        style: Theme.of(context).textTheme.bodyMedium!,
-        normalBorderColor: Theme.of(context).colorScheme.outline,
-        errorBorderColor: Theme.of(context).colorScheme.error,
-        focusBorderColor: Theme.of(context).colorScheme.primary,
-        cursorColor: Theme.of(context).colorScheme.primary,
-        errorText:
-            widget.bloc.state.timeFormatError.fold(() => "", (error) => error),
-        onEditingComplete: (value) =>
-            widget.bloc.add(DateCalEvent.setTime(value)),
+      padding: const EdgeInsets.symmetric(horizontal: 12.0),
+      child: Padding(
+        padding: GridSize.typeOptionContentInsets,
+        child: RoundedInputField(
+          height: GridSize.typeOptionItemHeight,
+          focusNode: _focusNode,
+          autoFocus: true,
+          hintText: widget.bloc.state.timeHintText,
+          controller: _controller,
+          style: Theme.of(context).textTheme.bodyMedium!,
+          normalBorderColor: Theme.of(context).colorScheme.outline,
+          errorBorderColor: Theme.of(context).colorScheme.error,
+          focusBorderColor: Theme.of(context).colorScheme.primary,
+          cursorColor: Theme.of(context).colorScheme.primary,
+          errorText: widget.bloc.state.timeFormatError
+              .fold(() => "", (error) => error),
+          onEditingComplete: (value) =>
+              widget.bloc.add(DateCalEvent.setTime(value)),
+        ),
       ),
       ),
     );
     );
   }
   }
@@ -358,15 +371,19 @@ class _DateTypeOptionButton extends StatelessWidget {
           mutex: popoverMutex,
           mutex: popoverMutex,
           triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
           triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
           offset: const Offset(20, 0),
           offset: const Offset(20, 0),
+          margin: EdgeInsets.zero,
           constraints: BoxConstraints.loose(const Size(140, 100)),
           constraints: BoxConstraints.loose(const Size(140, 100)),
-          child: SizedBox(
-            height: GridSize.typeOptionItemHeight,
-            child: FlowyButton(
-              text: FlowyText.medium(title),
-              margin: GridSize.typeOptionContentInsets,
-              rightIcon: svgWidget(
-                "grid/more",
-                color: Theme.of(context).colorScheme.onSurface,
+          child: Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 12.0),
+            child: SizedBox(
+              height: GridSize.typeOptionItemHeight,
+              child: FlowyButton(
+                text: FlowyText.medium(title),
+                margin: GridSize.typeOptionContentInsets,
+                rightIcon: svgWidget(
+                  "grid/more",
+                  color: Theme.of(context).colorScheme.onSurface,
+                ),
               ),
               ),
             ),
             ),
           ),
           ),
@@ -418,7 +435,10 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
             },
             },
           );
           );
         },
         },
-        child: const DateFormatButton(),
+        child: const Padding(
+          padding: EdgeInsets.symmetric(horizontal: 6.0),
+          child: DateFormatButton(),
+        ),
       ),
       ),
       AppFlowyPopover(
       AppFlowyPopover(
         mutex: timeSettingPopoverMutex,
         mutex: timeSettingPopoverMutex,
@@ -432,7 +452,11 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
                 timeSettingPopoverMutex.close();
                 timeSettingPopoverMutex.close();
               });
               });
         },
         },
-        child: TimeFormatButton(timeFormat: widget.dateTypeOptionPB.timeFormat),
+        child: Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 6.0),
+          child:
+              TimeFormatButton(timeFormat: widget.dateTypeOptionPB.timeFormat),
+        ),
       ),
       ),
     ];
     ];
 
 
@@ -444,9 +468,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
         separatorBuilder: (context, index) =>
         separatorBuilder: (context, index) =>
             VSpace(GridSize.typeOptionSeparatorHeight),
             VSpace(GridSize.typeOptionSeparatorHeight),
         itemCount: children.length,
         itemCount: children.length,
-        itemBuilder: (BuildContext context, int index) {
-          return children[index];
-        },
+        itemBuilder: (BuildContext context, int index) => children[index],
+        padding: const EdgeInsets.symmetric(vertical: 6.0),
       ),
       ),
     );
     );
   }
   }

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

@@ -182,6 +182,7 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
     return AppFlowyPopover(
     return AppFlowyPopover(
       controller: _popover,
       controller: _popover,
       constraints: constraints,
       constraints: constraints,
+      margin: EdgeInsets.zero,
       direction: PopoverDirection.bottomWithLeftAligned,
       direction: PopoverDirection.bottomWithLeftAligned,
       popupBuilder: (BuildContext context) {
       popupBuilder: (BuildContext context) {
         WidgetsBinding.instance.addPostFrameCallback((_) {
         WidgetsBinding.instance.addPostFrameCallback((_) {

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

@@ -1,6 +1,7 @@
 import 'dart:collection';
 import 'dart:collection';
 import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
 import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
 import 'package:app_flowy/plugins/grid/application/cell/select_option_editor_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/cell/select_option_editor_bloc.dart';
+import 'package:app_flowy/plugins/grid/presentation/widgets/common/type_option_separator.dart';
 import 'package:appflowy_popover/appflowy_popover.dart';
 import 'package:appflowy_popover/appflowy_popover.dart';
 import 'package:flowy_infra/theme_extension.dart';
 import 'package:flowy_infra/theme_extension.dart';
 
 
@@ -17,12 +18,12 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:textfield_tags/textfield_tags.dart';
 import 'package:textfield_tags/textfield_tags.dart';
 
 
 import '../../../layout/sizes.dart';
 import '../../../layout/sizes.dart';
-import '../../common/type_option_separator.dart';
 import '../../header/type_option/select_option_editor.dart';
 import '../../header/type_option/select_option_editor.dart';
 import 'extension.dart';
 import 'extension.dart';
 import 'text_field.dart';
 import 'text_field.dart';
 
 
 const double _editorPanelWidth = 300;
 const double _editorPanelWidth = 300;
+const double _padding = 12.0;
 
 
 class SelectOptionCellEditor extends StatefulWidget {
 class SelectOptionCellEditor extends StatefulWidget {
   final GridSelectOptionCellController cellController;
   final GridSelectOptionCellController cellController;
@@ -52,25 +53,13 @@ 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(
-            padding: const EdgeInsets.all(6.0),
-            child: ListView.separated(
-              shrinkWrap: true,
-              itemCount: children.length,
-              itemBuilder: (BuildContext context, int index) {
-                return children[index];
-              },
-              separatorBuilder: (BuildContext context, int index) {
-                return VSpace(GridSize.typeOptionSeparatorHeight);
-              },
-            ),
+          return Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              _TextField(popoverMutex: popoverMutex),
+              const TypeOptionSeparator(spacing: 0.0),
+              Flexible(child: _OptionList(popoverMutex: popoverMutex)),
+            ],
           );
           );
         },
         },
       ),
       ),
@@ -90,6 +79,7 @@ class _OptionList extends StatelessWidget {
     return BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
     return BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
       builder: (context, state) {
       builder: (context, state) {
         List<Widget> cells = [];
         List<Widget> cells = [];
+        cells.add(const _Title());
         cells.addAll(state.options.map((option) {
         cells.addAll(state.options.map((option) {
           return _SelectOptionCell(
           return _SelectOptionCell(
             option: option,
             option: option,
@@ -113,15 +103,11 @@ class _OptionList extends StatelessWidget {
             return VSpace(GridSize.typeOptionSeparatorHeight);
             return VSpace(GridSize.typeOptionSeparatorHeight);
           },
           },
           physics: StyledScrollPhysics(),
           physics: StyledScrollPhysics(),
-          itemBuilder: (BuildContext context, int index) {
-            return cells[index];
-          },
+          itemBuilder: (BuildContext context, int index) => cells[index],
+          padding: const EdgeInsets.only(top: 6.0, bottom: 12.0),
         );
         );
 
 
-        return Padding(
-          padding: const EdgeInsets.all(3.0),
-          child: list,
-        );
+        return list;
       },
       },
     );
     );
   }
   }
@@ -145,32 +131,35 @@ class _TextField extends StatelessWidget {
             key: (option) => option.name,
             key: (option) => option.name,
             value: (option) => option);
             value: (option) => option);
 
 
-        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,
-                ));
-          },
+        return Padding(
+          padding: const EdgeInsets.all(_padding),
+          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,
+                  ));
+            },
+          ),
         );
         );
       },
       },
     );
     );
@@ -182,10 +171,10 @@ class _Title extends StatelessWidget {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    return SizedBox(
-      height: GridSize.typeOptionItemHeight,
-      child: Padding(
-        padding: const EdgeInsets.symmetric(horizontal: 6),
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 12.0),
+      child: SizedBox(
+        height: GridSize.typeOptionItemHeight,
         child: FlowyText.medium(
         child: FlowyText.medium(
           LocaleKeys.grid_selectOption_panelTitle.tr(),
           LocaleKeys.grid_selectOption_panelTitle.tr(),
           color: Theme.of(context).hintColor,
           color: Theme.of(context).hintColor,
@@ -201,26 +190,32 @@ class _CreateOptionCell extends StatelessWidget {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    return Row(
-      children: [
-        FlowyText.medium(
-          LocaleKeys.grid_selectOption_create.tr(),
-          color: Theme.of(context).hintColor,
-        ),
-        const HSpace(10),
-        Expanded(
-          child: Align(
-            alignment: Alignment.centerLeft,
-            child: SelectOptionTag(
-              name: name,
-              color: AFThemeExtension.of(context).lightGreyHover,
-              onSelected: () => context
-                  .read<SelectOptionCellEditorBloc>()
-                  .add(SelectOptionEditorEvent.newOption(name)),
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 12.0),
+      child: SizedBox(
+        height: GridSize.typeOptionItemHeight,
+        child: Row(
+          children: [
+            FlowyText.medium(
+              LocaleKeys.grid_selectOption_create.tr(),
+              color: Theme.of(context).hintColor,
             ),
             ),
-          ),
+            const HSpace(10),
+            Expanded(
+              child: Align(
+                alignment: Alignment.centerLeft,
+                child: SelectOptionTag(
+                  name: name,
+                  color: AFThemeExtension.of(context).lightGreyHover,
+                  onSelected: () => context
+                      .read<SelectOptionCellEditorBloc>()
+                      .add(SelectOptionEditorEvent.newOption(name)),
+                ),
+              ),
+            ),
+          ],
         ),
         ),
-      ],
+      ),
     );
     );
   }
   }
 }
 }
@@ -251,44 +246,49 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
+    final child = SizedBox(
+      height: GridSize.typeOptionItemHeight,
+      child: SelectOptionTagCell(
+        option: widget.option,
+        onSelected: (option) {
+          if (widget.isSelected) {
+            context
+                .read<SelectOptionCellEditorBloc>()
+                .add(SelectOptionEditorEvent.unSelectOption(option.id));
+          } else {
+            context
+                .read<SelectOptionCellEditorBloc>()
+                .add(SelectOptionEditorEvent.selectOption(option.id));
+          }
+        },
+        children: [
+          if (widget.isSelected)
+            Padding(
+              padding: const EdgeInsets.only(left: 6),
+              child: svgWidget("grid/checkmark"),
+            ),
+          FlowyIconButton(
+            onPressed: () => _popoverController.show(),
+            hoverColor: Colors.transparent,
+            iconPadding: const EdgeInsets.symmetric(horizontal: 6.0),
+            icon: svgWidget(
+              "editor/details",
+              color: Theme.of(context).colorScheme.onSurface,
+            ),
+          ),
+        ],
+      ),
+    );
     return AppFlowyPopover(
     return AppFlowyPopover(
       controller: _popoverController,
       controller: _popoverController,
       offset: const Offset(20, 0),
       offset: const Offset(20, 0),
+      margin: EdgeInsets.zero,
       asBarrier: true,
       asBarrier: true,
-      constraints: BoxConstraints.loose(const Size(200, 300)),
+      constraints: BoxConstraints.loose(const Size(200, 460)),
       mutex: widget.popoverMutex,
       mutex: widget.popoverMutex,
-      child: SizedBox(
-        height: GridSize.typeOptionItemHeight,
-        child: SelectOptionTagCell(
-          option: widget.option,
-          onSelected: (option) {
-            if (widget.isSelected) {
-              context
-                  .read<SelectOptionCellEditorBloc>()
-                  .add(SelectOptionEditorEvent.unSelectOption(option.id));
-            } else {
-              context
-                  .read<SelectOptionCellEditorBloc>()
-                  .add(SelectOptionEditorEvent.selectOption(option.id));
-            }
-          },
-          children: [
-            if (widget.isSelected)
-              Padding(
-                padding: const EdgeInsets.only(left: 6),
-                child: svgWidget("grid/checkmark"),
-              ),
-            FlowyIconButton(
-              onPressed: () => _popoverController.show(),
-              hoverColor: Colors.transparent,
-              iconPadding: const EdgeInsets.symmetric(horizontal: 6.0),
-              icon: svgWidget(
-                "editor/details",
-                color: Theme.of(context).colorScheme.onSurface,
-              ),
-            ),
-          ],
-        ),
+      child: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 12.0),
+        child: child,
       ),
       ),
       popupBuilder: (BuildContext popoverContext) {
       popupBuilder: (BuildContext popoverContext) {
         return SelectOptionTypeOptionEditor(
         return SelectOptionTypeOptionEditor(

+ 3 - 2
frontend/app_flowy/lib/plugins/grid/presentation/widgets/common/type_option_separator.dart

@@ -1,12 +1,13 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 
 
 class TypeOptionSeparator extends StatelessWidget {
 class TypeOptionSeparator extends StatelessWidget {
-  const TypeOptionSeparator({Key? key}) : super(key: key);
+  final double spacing;
+  const TypeOptionSeparator({this.spacing = 6.0, Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     return Padding(
     return Padding(
-      padding: const EdgeInsets.symmetric(vertical: 6),
+      padding: EdgeInsets.symmetric(vertical: spacing),
       child: Container(
       child: Container(
         color: Theme.of(context).dividerColor,
         color: Theme.of(context).dividerColor,
         height: 1.0,
         height: 1.0,

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart

@@ -45,6 +45,7 @@ class _GridFieldCellState extends State<GridFieldCell> {
           final button = AppFlowyPopover(
           final button = AppFlowyPopover(
             triggerActions: PopoverTriggerFlags.none,
             triggerActions: PopoverTriggerFlags.none,
             constraints: BoxConstraints.loose(const Size(240, 440)),
             constraints: BoxConstraints.loose(const Size(240, 440)),
+            margin: EdgeInsets.zero,
             direction: PopoverDirection.bottomWithLeftAligned,
             direction: PopoverDirection.bottomWithLeftAligned,
             controller: popoverController,
             controller: popoverController,
             popupBuilder: (BuildContext context) {
             popupBuilder: (BuildContext context) {

+ 5 - 3
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell_action_sheet.dart

@@ -44,6 +44,7 @@ class _GridFieldCellActionSheetState extends State<GridFieldCellActionSheet> {
       create: (context) =>
       create: (context) =>
           getIt<FieldActionSheetBloc>(param1: widget.cellContext),
           getIt<FieldActionSheetBloc>(param1: widget.cellContext),
       child: SingleChildScrollView(
       child: SingleChildScrollView(
+        padding: const EdgeInsets.all(12.0),
         child: Column(
         child: Column(
           children: [
           children: [
             _EditFieldButton(
             _EditFieldButton(
@@ -54,7 +55,7 @@ class _GridFieldCellActionSheetState extends State<GridFieldCellActionSheet> {
                 });
                 });
               },
               },
             ),
             ),
-            const VSpace(6),
+            VSpace(GridSize.typeOptionSeparatorHeight),
             _FieldOperationList(widget.cellContext, () {}),
             _FieldOperationList(widget.cellContext, () {}),
           ],
           ],
         ),
         ),
@@ -98,10 +99,11 @@ class _FieldOperationList extends StatelessWidget {
     return GridView(
     return GridView(
       // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html
       // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html
       shrinkWrap: true,
       shrinkWrap: true,
-      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
         crossAxisCount: 2,
         crossAxisCount: 2,
         childAspectRatio: 4.0,
         childAspectRatio: 4.0,
-        mainAxisSpacing: 8,
+        mainAxisSpacing: GridSize.typeOptionSeparatorHeight,
+        crossAxisSpacing: GridSize.typeOptionSeparatorHeight,
       ),
       ),
       children: buildCells(),
       children: buildCells(),
     );
     );

+ 39 - 39
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart

@@ -51,6 +51,12 @@ class _FieldEditorState extends State<FieldEditor> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
+    List<Widget> children = [
+      _FieldNameTextField(popoverMutex: popoverMutex),
+      const VSpace(10),
+      if (widget.onDeleted != null) _addDeleteFieldButton(),
+      _FieldTypeOptionCell(popoverMutex: popoverMutex),
+    ];
     return BlocProvider(
     return BlocProvider(
       create: (context) => FieldEditorBloc(
       create: (context) => FieldEditorBloc(
         gridId: widget.gridId,
         gridId: widget.gridId,
@@ -58,33 +64,21 @@ class _FieldEditorState extends State<FieldEditor> {
         isGroupField: widget.isGroupField,
         isGroupField: widget.isGroupField,
         loader: widget.typeOptionLoader,
         loader: widget.typeOptionLoader,
       )..add(const FieldEditorEvent.initial()),
       )..add(const FieldEditorEvent.initial()),
-      child: Padding(
-        padding: GridSize.typeOptionContentInsets,
-        child: ListView(
-          shrinkWrap: true,
-          children: [
-            FlowyText.medium(
-              LocaleKeys.grid_field_editProperty.tr(),
-            ),
-            const VSpace(10),
-            _FieldNameTextField(popoverMutex: popoverMutex),
-            const VSpace(10),
-            ..._addDeleteFieldButton(),
-            _FieldTypeOptionCell(popoverMutex: popoverMutex),
-          ],
-        ),
+      child: ListView.builder(
+        shrinkWrap: true,
+        itemCount: children.length,
+        itemBuilder: (context, index) => children[index],
+        padding: const EdgeInsets.symmetric(vertical: 12.0),
       ),
       ),
     );
     );
   }
   }
 
 
-  List<Widget> _addDeleteFieldButton() {
-    if (widget.onDeleted == null) {
-      return [];
-    }
-    return [
-      BlocBuilder<FieldEditorBloc, FieldEditorState>(
-        builder: (context, state) {
-          return _DeleteFieldButton(
+  Widget _addDeleteFieldButton() {
+    return BlocBuilder<FieldEditorBloc, FieldEditorState>(
+      builder: (context, state) {
+        return Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 12.0),
+          child: _DeleteFieldButton(
             popoverMutex: popoverMutex,
             popoverMutex: popoverMutex,
             onDeleted: () {
             onDeleted: () {
               state.field.fold(
               state.field.fold(
@@ -92,10 +86,10 @@ class _FieldEditorState extends State<FieldEditor> {
                 (field) => widget.onDeleted?.call(field.id),
                 (field) => widget.onDeleted?.call(field.id),
               );
               );
             },
             },
-          );
-        },
-      ),
-    ];
+          ),
+        );
+      },
+    );
   }
   }
 }
 }
 
 
@@ -182,17 +176,20 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> {
         buildWhen: (previous, current) =>
         buildWhen: (previous, current) =>
             previous.errorText != current.errorText,
             previous.errorText != current.errorText,
         builder: (context, state) {
         builder: (context, state) {
-          return RoundedInputField(
-            height: 36,
-            focusNode: focusNode,
-            style: Theme.of(context).textTheme.bodyMedium,
-            controller: controller,
-            errorText: context.read<FieldEditorBloc>().state.errorText,
-            onChanged: (newName) {
-              context
-                  .read<FieldEditorBloc>()
-                  .add(FieldEditorEvent.updateName(newName));
-            },
+          return Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 12.0),
+            child: RoundedInputField(
+              height: 36,
+              focusNode: focusNode,
+              style: Theme.of(context).textTheme.bodyMedium,
+              controller: controller,
+              errorText: context.read<FieldEditorBloc>().state.errorText,
+              onChanged: (newName) {
+                context
+                    .read<FieldEditorBloc>()
+                    .add(FieldEditorEvent.updateName(newName));
+              },
+            ),
           );
           );
         },
         },
       ),
       ),
@@ -224,7 +221,10 @@ class _DeleteFieldButton extends StatelessWidget {
           onTap: () => onDeleted?.call(),
           onTap: () => onDeleted?.call(),
           onHover: (_) => popoverMutex.close(),
           onHover: (_) => popoverMutex.close(),
         );
         );
-        return SizedBox(height: 36, child: button);
+        return Padding(
+          padding: const EdgeInsets.only(bottom: 4.0),
+          child: SizedBox(height: GridSize.typeOptionItemHeight, child: button),
+        );
       },
       },
     );
     );
   }
   }

+ 5 - 2
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart

@@ -96,7 +96,10 @@ class _SwitchFieldButton extends StatelessWidget {
               .add(FieldTypeOptionEditEvent.switchToField(newFieldType));
               .add(FieldTypeOptionEditEvent.switchToField(newFieldType));
         });
         });
       },
       },
-      child: _buildMoreButton(context),
+      child: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 12.0),
+        child: _buildMoreButton(context),
+      ),
     );
     );
 
 
     return SizedBox(
     return SizedBox(
@@ -111,7 +114,7 @@ class _SwitchFieldButton extends StatelessWidget {
       text: FlowyText.medium(
       text: FlowyText.medium(
         bloc.state.field.fieldType.title(),
         bloc.state.field.fieldType.title(),
       ),
       ),
-      margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
+      margin: GridSize.typeOptionContentInsets,
       leftIcon: svgWidget(
       leftIcon: svgWidget(
         bloc.state.field.fieldType.iconName(),
         bloc.state.field.fieldType.iconName(),
         color: Theme.of(context).colorScheme.onSurface,
         color: Theme.of(context).colorScheme.onSurface,

+ 42 - 28
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart

@@ -62,12 +62,15 @@ class DateTypeOptionWidget extends TypeOptionWidget {
           return ListView.separated(
           return ListView.separated(
             shrinkWrap: true,
             shrinkWrap: true,
             controller: ScrollController(),
             controller: ScrollController(),
-            separatorBuilder: (context, index) =>
-                VSpace(GridSize.typeOptionSeparatorHeight),
-            itemCount: children.length,
-            itemBuilder: (BuildContext context, int index) {
-              return children[index];
+            separatorBuilder: (context, index) {
+              if (index == 0) {
+                return const SizedBox();
+              } else {
+                return VSpace(GridSize.typeOptionSeparatorHeight);
+              }
             },
             },
+            itemCount: children.length,
+            itemBuilder: (BuildContext context, int index) => children[index],
           );
           );
         },
         },
       ),
       ),
@@ -92,7 +95,12 @@ class DateTypeOptionWidget extends TypeOptionWidget {
           },
           },
         );
         );
       },
       },
-      child: DateFormatButton(buttonMargins: GridSize.typeOptionContentInsets),
+      child: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 12.0),
+        child: DateFormatButton(
+          buttonMargins: GridSize.typeOptionContentInsets,
+        ),
+      ),
     );
     );
   }
   }
 
 
@@ -114,9 +122,12 @@ class DateTypeOptionWidget extends TypeOptionWidget {
           },
           },
         );
         );
       },
       },
-      child: TimeFormatButton(
-        timeFormat: timeFormat,
-        buttonMargins: GridSize.typeOptionContentInsets,
+      child: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 12.0),
+        child: TimeFormatButton(
+          timeFormat: timeFormat,
+          buttonMargins: GridSize.typeOptionContentInsets,
+        ),
       ),
       ),
     );
     );
   }
   }
@@ -190,25 +201,28 @@ class _IncludeTimeButton extends StatelessWidget {
     return BlocSelector<DateTypeOptionBloc, DateTypeOptionState, bool>(
     return BlocSelector<DateTypeOptionBloc, DateTypeOptionState, bool>(
       selector: (state) => state.typeOption.includeTime,
       selector: (state) => state.typeOption.includeTime,
       builder: (context, includeTime) {
       builder: (context, includeTime) {
-        return SizedBox(
-          height: GridSize.typeOptionItemHeight,
-          child: Padding(
-            padding: GridSize.typeOptionContentInsets,
-            child: Row(
-              children: [
-                FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()),
-                const Spacer(),
-                Toggle(
-                  value: includeTime,
-                  onChanged: (value) {
-                    context
-                        .read<DateTypeOptionBloc>()
-                        .add(DateTypeOptionEvent.includeTime(!value));
-                  },
-                  style: ToggleStyle.big,
-                  padding: EdgeInsets.zero,
-                ),
-              ],
+        return Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 12.0),
+          child: SizedBox(
+            height: GridSize.typeOptionItemHeight,
+            child: Padding(
+              padding: GridSize.typeOptionContentInsets,
+              child: Row(
+                children: [
+                  FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()),
+                  const Spacer(),
+                  Toggle(
+                    value: includeTime,
+                    onChanged: (value) {
+                      context
+                          .read<DateTypeOptionBloc>()
+                          .add(DateTypeOptionEvent.includeTime(!value));
+                    },
+                    style: ToggleStyle.big,
+                    padding: EdgeInsets.zero,
+                  ),
+                ],
+              ),
             ),
             ),
           ),
           ),
         );
         );

+ 27 - 15
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/number.dart

@@ -31,7 +31,7 @@ class NumberTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
   @override
   @override
   Widget? build(BuildContext context) {
   Widget? build(BuildContext context) {
     return Column(children: [
     return Column(children: [
-      const TypeOptionSeparator(),
+      VSpace(GridSize.typeOptionSeparatorHeight),
       _widget,
       _widget,
     ]);
     ]);
   }
   }
@@ -57,12 +57,8 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
           listener: (context, state) =>
           listener: (context, state) =>
               typeOptionContext.typeOption = state.typeOption,
               typeOptionContext.typeOption = state.typeOption,
           builder: (context, state) {
           builder: (context, state) {
-            return AppFlowyPopover(
-              mutex: popoverMutex,
-              triggerActions:
-                  PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
-              offset: const Offset(20, 0),
-              constraints: BoxConstraints.loose(const Size(460, 440)),
+            final button = SizedBox(
+              height: GridSize.typeOptionItemHeight,
               child: FlowyButton(
               child: FlowyButton(
                 margin: GridSize.typeOptionContentInsets,
                 margin: GridSize.typeOptionContentInsets,
                 rightIcon: svgWidget(
                 rightIcon: svgWidget(
@@ -72,12 +68,24 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
                 text: Row(
                 text: Row(
                   children: [
                   children: [
                     FlowyText.medium(LocaleKeys.grid_field_numberFormat.tr()),
                     FlowyText.medium(LocaleKeys.grid_field_numberFormat.tr()),
-                    // const HSpace(6),
                     const Spacer(),
                     const Spacer(),
                     FlowyText.regular(state.typeOption.format.title()),
                     FlowyText.regular(state.typeOption.format.title()),
                   ],
                   ],
                 ),
                 ),
               ),
               ),
+            );
+
+            return AppFlowyPopover(
+              mutex: popoverMutex,
+              triggerActions:
+                  PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
+              offset: const Offset(20, 0),
+              constraints: BoxConstraints.loose(const Size(460, 440)),
+              margin: EdgeInsets.zero,
+              child: Padding(
+                padding: const EdgeInsets.symmetric(horizontal: 12.0),
+                child: button,
+              ),
               popupBuilder: (BuildContext popoverContext) {
               popupBuilder: (BuildContext popoverContext) {
                 return NumberFormatList(
                 return NumberFormatList(
                   onSelected: (format) {
                   onSelected: (format) {
@@ -113,10 +121,10 @@ class NumberFormatList extends StatelessWidget {
       child: SizedBox(
       child: SizedBox(
         width: 180,
         width: 180,
         child: Column(
         child: Column(
-          crossAxisAlignment: CrossAxisAlignment.start,
+          mainAxisSize: MainAxisSize.min,
           children: [
           children: [
             const _FilterTextField(),
             const _FilterTextField(),
-            const VSpace(10),
+            const TypeOptionSeparator(spacing: 0.0),
             BlocBuilder<NumberFormatBloc, NumberFormatState>(
             BlocBuilder<NumberFormatBloc, NumberFormatState>(
               builder: (context, state) {
               builder: (context, state) {
                 final cells = state.formats.map((format) {
                 final cells = state.formats.map((format) {
@@ -138,8 +146,9 @@ class NumberFormatList extends StatelessWidget {
                   itemBuilder: (BuildContext context, int index) {
                   itemBuilder: (BuildContext context, int index) {
                     return cells[index];
                     return cells[index];
                   },
                   },
+                  padding: const EdgeInsets.all(6.0),
                 );
                 );
-                return Expanded(child: list);
+                return Flexible(child: list);
               },
               },
             ),
             ),
           ],
           ],
@@ -182,10 +191,13 @@ class _FilterTextField extends StatelessWidget {
   const _FilterTextField({Key? key}) : super(key: key);
   const _FilterTextField({Key? key}) : super(key: key);
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    return FlowyTextField(
-      onChanged: (text) => context
-          .read<NumberFormatBloc>()
-          .add(NumberFormatEvent.setFilter(text)),
+    return Padding(
+      padding: const EdgeInsets.all(6.0),
+      child: FlowyTextField(
+        onChanged: (text) => context
+            .read<NumberFormatBloc>()
+            .add(NumberFormatEvent.setFilter(text)),
+      ),
     );
     );
   }
   }
 }
 }

+ 73 - 56
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart

@@ -43,18 +43,21 @@ class SelectOptionTypeOptionWidget extends StatelessWidget {
             const TypeOptionSeparator(),
             const TypeOptionSeparator(),
             const OptionTitle(),
             const OptionTitle(),
             if (state.isEditingOption)
             if (state.isEditingOption)
-              Padding(
-                padding: const EdgeInsets.only(bottom: 10),
-                child: _CreateOptionTextField(
-                  popoverMutex: popoverMutex,
-                ),
-              ),
+              _CreateOptionTextField(popoverMutex: popoverMutex),
+            if (state.options.isNotEmpty && state.isEditingOption)
+              const VSpace(10),
             if (state.options.isEmpty && !state.isEditingOption)
             if (state.options.isEmpty && !state.isEditingOption)
               const _AddOptionButton(),
               const _AddOptionButton(),
             _OptionList(popoverMutex: popoverMutex)
             _OptionList(popoverMutex: popoverMutex)
           ];
           ];
 
 
-          return Column(children: children);
+          return ListView.builder(
+            shrinkWrap: true,
+            itemCount: children.length,
+            itemBuilder: (context, index) {
+              return children[index];
+            },
+          );
         },
         },
       ),
       ),
     );
     );
@@ -79,9 +82,12 @@ class OptionTitle extends StatelessWidget {
           children.add(const _OptionTitleButton());
           children.add(const _OptionTitleButton());
         }
         }
 
 
-        return SizedBox(
-          height: GridSize.typeOptionItemHeight,
-          child: Row(children: children),
+        return Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 12.0),
+          child: SizedBox(
+            height: GridSize.typeOptionItemHeight,
+            child: Row(children: children),
+          ),
         );
         );
       },
       },
     );
     );
@@ -178,29 +184,34 @@ class _OptionCellState extends State<_OptionCell> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
+    final child = SizedBox(
+      height: GridSize.typeOptionItemHeight,
+      child: SelectOptionTagCell(
+        option: widget.option,
+        onSelected: (SelectOptionPB pb) {
+          _popoverController.show();
+        },
+        children: [
+          Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 6.0),
+            child: svgWidget(
+              "grid/details",
+              color: Theme.of(context).colorScheme.onSurface,
+            ),
+          ),
+        ],
+      ),
+    );
     return AppFlowyPopover(
     return AppFlowyPopover(
       controller: _popoverController,
       controller: _popoverController,
       mutex: widget.popoverMutex,
       mutex: widget.popoverMutex,
       offset: const Offset(20, 0),
       offset: const Offset(20, 0),
+      margin: EdgeInsets.zero,
       asBarrier: true,
       asBarrier: true,
-      constraints: BoxConstraints.loose(const Size(460, 440)),
-      child: SizedBox(
-        height: GridSize.typeOptionItemHeight,
-        child: SelectOptionTagCell(
-          option: widget.option,
-          onSelected: (SelectOptionPB pb) {
-            _popoverController.show();
-          },
-          children: [
-            Padding(
-              padding: const EdgeInsets.symmetric(horizontal: 6.0),
-              child: svgWidget(
-                "grid/details",
-                color: Theme.of(context).colorScheme.onSurface,
-              ),
-            ),
-          ],
-        ),
+      constraints: BoxConstraints.loose(const Size(460, 460)),
+      child: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 12.0),
+        child: child,
       ),
       ),
       popupBuilder: (BuildContext popoverContext) {
       popupBuilder: (BuildContext popoverContext) {
         return SelectOptionTypeOptionEditor(
         return SelectOptionTypeOptionEditor(
@@ -229,18 +240,21 @@ class _AddOptionButton extends StatelessWidget {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    return SizedBox(
-      height: GridSize.typeOptionItemHeight,
-      child: FlowyButton(
-        text: FlowyText.medium(LocaleKeys.grid_field_addSelectOption.tr()),
-        onTap: () {
-          context
-              .read<SelectOptionTypeOptionBloc>()
-              .add(const SelectOptionTypeOptionEvent.addingOption());
-        },
-        leftIcon: svgWidget(
-          "home/add",
-          color: Theme.of(context).colorScheme.onSurface,
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 12.0),
+      child: SizedBox(
+        height: GridSize.typeOptionItemHeight,
+        child: FlowyButton(
+          text: FlowyText.medium(LocaleKeys.grid_field_addSelectOption.tr()),
+          onTap: () {
+            context
+                .read<SelectOptionTypeOptionBloc>()
+                .add(const SelectOptionTypeOptionEvent.addingOption());
+          },
+          leftIcon: svgWidget(
+            "home/add",
+            color: Theme.of(context).colorScheme.onSurface,
+          ),
         ),
         ),
       ),
       ),
     );
     );
@@ -282,22 +296,25 @@ class _CreateOptionTextFieldState extends State<_CreateOptionTextField> {
     return BlocBuilder<SelectOptionTypeOptionBloc, SelectOptionTypeOptionState>(
     return BlocBuilder<SelectOptionTypeOptionBloc, SelectOptionTypeOptionState>(
       builder: (context, state) {
       builder: (context, state) {
         final text = state.newOptionName.foldRight("", (a, previous) => a);
         final text = state.newOptionName.foldRight("", (a, previous) => a);
-        return FlowyTextField(
-          autoClearWhenDone: true,
-          maxLength: 30,
-          text: text,
-          focusNode: _focusNode,
-          onCanceled: () {
-            context
-                .read<SelectOptionTypeOptionBloc>()
-                .add(const SelectOptionTypeOptionEvent.endAddingOption());
-          },
-          onEditingComplete: () {},
-          onSubmitted: (optionName) {
-            context
-                .read<SelectOptionTypeOptionBloc>()
-                .add(SelectOptionTypeOptionEvent.createOption(optionName));
-          },
+        return Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 12.0),
+          child: FlowyTextField(
+            autoClearWhenDone: true,
+            maxLength: 30,
+            text: text,
+            focusNode: _focusNode,
+            onCanceled: () {
+              context
+                  .read<SelectOptionTypeOptionBloc>()
+                  .add(const SelectOptionTypeOptionEvent.endAddingOption());
+            },
+            onEditingComplete: () {},
+            onSubmitted: (optionName) {
+              context
+                  .read<SelectOptionTypeOptionBloc>()
+                  .add(SelectOptionTypeOptionEvent.createOption(optionName));
+            },
+          ),
         );
         );
       },
       },
     );
     );

+ 25 - 20
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option_editor.dart

@@ -53,34 +53,39 @@ class SelectOptionTypeOptionEditor extends StatelessWidget {
         ],
         ],
         child: BlocBuilder<EditSelectOptionBloc, EditSelectOptionState>(
         child: BlocBuilder<EditSelectOptionBloc, EditSelectOptionState>(
           builder: (context, state) {
           builder: (context, state) {
-            List<Widget> slivers = [
-              SliverToBoxAdapter(
-                  child: _OptionNameTextField(
+            List<Widget> cells = [
+              _OptionNameTextField(
                 name: state.option.name,
                 name: state.option.name,
                 autoFocus: autoFocus,
                 autoFocus: autoFocus,
-              )),
-              const SliverToBoxAdapter(child: VSpace(10)),
-              const SliverToBoxAdapter(child: _DeleteTag()),
+              ),
+              const VSpace(10),
+              const _DeleteTag(),
             ];
             ];
 
 
             if (showOptions) {
             if (showOptions) {
-              slivers
-                  .add(const SliverToBoxAdapter(child: TypeOptionSeparator()));
-              slivers.add(SliverToBoxAdapter(
-                  child: SelectOptionColorList(
-                      selectedColor: state.option.color)));
+              cells.add(const TypeOptionSeparator());
+              cells.add(
+                  SelectOptionColorList(selectedColor: state.option.color));
             }
             }
 
 
             return SizedBox(
             return SizedBox(
-              width: 160,
-              child: Padding(
-                padding: const EdgeInsets.all(6.0),
-                child: CustomScrollView(
-                  slivers: slivers,
-                  shrinkWrap: true,
-                  controller: ScrollController(),
-                  physics: StyledScrollPhysics(),
-                ),
+              width: 180,
+              child: ListView.builder(
+                shrinkWrap: true,
+                controller: ScrollController(),
+                physics: StyledScrollPhysics(),
+                itemCount: cells.length,
+                itemBuilder: (context, index) {
+                  if (cells[index] is TypeOptionSeparator) {
+                    return cells[index];
+                  } else {
+                    return Padding(
+                      padding: const EdgeInsets.symmetric(horizontal: 6.0),
+                      child: cells[index],
+                    );
+                  }
+                },
+                padding: const EdgeInsets.symmetric(vertical: 6.0),
               ),
               ),
             );
             );
           },
           },

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart

@@ -274,6 +274,7 @@ class _RowDetailCellState extends State<_RowDetailCell> {
             AppFlowyPopover(
             AppFlowyPopover(
               controller: popover,
               controller: popover,
               constraints: BoxConstraints.loose(const Size(240, 600)),
               constraints: BoxConstraints.loose(const Size(240, 600)),
+              margin: EdgeInsets.zero,
               triggerActions: PopoverTriggerFlags.none,
               triggerActions: PopoverTriggerFlags.none,
               popupBuilder: (popoverContext) => buildFieldEditor(),
               popupBuilder: (popoverContext) => buildFieldEditor(),
               child: SizedBox(
               child: SizedBox(

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart

@@ -117,6 +117,7 @@ class _GridPropertyCell extends StatelessWidget {
       offset: const Offset(20, 0),
       offset: const Offset(20, 0),
       direction: PopoverDirection.leftWithTopAligned,
       direction: PopoverDirection.leftWithTopAligned,
       constraints: BoxConstraints.loose(const Size(240, 400)),
       constraints: BoxConstraints.loose(const Size(240, 400)),
+      margin: EdgeInsets.zero,
       child: FlowyButton(
       child: FlowyButton(
         text: FlowyText.medium(fieldInfo.name),
         text: FlowyText.medium(fieldInfo.name),
         leftIcon: svgWidget(
         leftIcon: svgWidget(

+ 15 - 1
frontend/app_flowy/lib/workspace/application/appearance.dart

@@ -201,7 +201,21 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
       primaryIconTheme: IconThemeData(color: theme.hover),
       primaryIconTheme: IconThemeData(color: theme.hover),
       iconTheme: IconThemeData(color: theme.shader1),
       iconTheme: IconThemeData(color: theme.shader1),
       scrollbarTheme: ScrollbarThemeData(
       scrollbarTheme: ScrollbarThemeData(
-        thumbColor: MaterialStateProperty.all(Colors.transparent),
+        thumbColor: MaterialStateProperty.all(theme.shader3),
+        thickness: MaterialStateProperty.resolveWith((states) {
+          const Set<MaterialState> interactiveStates = <MaterialState>{
+            MaterialState.pressed,
+            MaterialState.hovered,
+            MaterialState.dragged,
+          };
+          if (states.any(interactiveStates.contains)) {
+            return 5.0;
+          }
+          return 3.0;
+        }),
+        crossAxisMargin: 0.0,
+        mainAxisMargin: 0.0,
+        radius: Corners.s10Radius,
       ),
       ),
       materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
       materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
       canvasColor: theme.shader6,
       canvasColor: theme.shader6,