diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart
new file mode 100644
index 0000000000..7e617069c4
--- /dev/null
+++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart
@@ -0,0 +1,102 @@
+import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
+import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:flowy_sdk/log.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:freezed_annotation/freezed_annotation.dart';
+import 'dart:async';
+import 'cell_service.dart';
+
+part 'selection_editor_bloc.freezed.dart';
+
+class SelectionEditorBloc extends Bloc<SelectionEditorEvent, SelectionEditorState> {
+  final CellService service = CellService();
+  final FieldListener _listener;
+
+  SelectionEditorBloc({
+    required String gridId,
+    required Field field,
+  })  : _listener = FieldListener(fieldId: field.id),
+        super(SelectionEditorState.initial(gridId, field)) {
+    on<SelectionEditorEvent>(
+      (event, emit) async {
+        await event.map(
+          initial: (_Initial value) async {
+            _startListening();
+            _loadOptions();
+          },
+          didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
+            emit(state.copyWith(field: value.field));
+            _loadOptions();
+          },
+          didReceiveOptions: (_DidReceiveOptions value) {
+            emit(state.copyWith(options: value.options));
+          },
+        );
+      },
+    );
+  }
+
+  @override
+  Future<void> close() async {
+    await _listener.stop();
+    return super.close();
+  }
+
+  void _startListening() {
+    _listener.updateFieldNotifier.addPublishListener((result) {
+      result.fold(
+        (field) => add(SelectionEditorEvent.didReceiveFieldUpdate(field)),
+        (err) => Log.error(err),
+      );
+    });
+  }
+
+  void _loadOptions() async {
+    final result = await FieldContextLoaderAdaptor(gridId: state.gridId, field: state.field).load();
+    result.fold(
+      (context) {
+        List<SelectOption> options = [];
+        switch (state.field.fieldType) {
+          case FieldType.MultiSelect:
+            options.addAll(MultiSelectTypeOption.fromBuffer(context.typeOptionData).options);
+            break;
+          case FieldType.SingleSelect:
+            options.addAll(SingleSelectTypeOption.fromBuffer(context.typeOptionData).options);
+            break;
+          default:
+            Log.error("Invalid field type, expect single select or multiple select");
+            break;
+        }
+        add(SelectionEditorEvent.didReceiveOptions(options));
+      },
+      (err) => Log.error(err),
+    );
+  }
+}
+
+@freezed
+class SelectionEditorEvent with _$SelectionEditorEvent {
+  const factory SelectionEditorEvent.initial() = _Initial;
+  const factory SelectionEditorEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate;
+  const factory SelectionEditorEvent.didReceiveOptions(List<SelectOption> options) = _DidReceiveOptions;
+}
+
+@freezed
+class SelectionEditorState with _$SelectionEditorState {
+  const factory SelectionEditorState({
+    required String gridId,
+    required Field field,
+    required List<SelectOption> options,
+  }) = _SelectionEditorState;
+
+  factory SelectionEditorState.initial(String gridId, Field field) {
+    return SelectionEditorState(
+      gridId: gridId,
+      field: field,
+      options: [],
+    );
+  }
+}
diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart
new file mode 100644
index 0000000000..eda5d83e69
--- /dev/null
+++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart
@@ -0,0 +1,51 @@
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
+import 'package:flowy_sdk/rust_stream.dart';
+import 'package:flowy_infra/notifier.dart';
+import 'dart:async';
+import 'dart:typed_data';
+import 'package:app_flowy/core/notification_helper.dart';
+
+typedef UpdateFieldNotifiedValue = Either<Field, FlowyError>;
+
+class FieldListener {
+  final String fieldId;
+  PublishNotifier<UpdateFieldNotifiedValue> updateFieldNotifier = PublishNotifier();
+  StreamSubscription<SubscribeObject>? _subscription;
+  GridNotificationParser? _parser;
+
+  FieldListener({required this.fieldId});
+
+  void start() {
+    _parser = GridNotificationParser(
+      id: fieldId,
+      callback: (ty, result) {
+        _handleObservableType(ty, result);
+      },
+    );
+
+    _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
+  }
+
+  void _handleObservableType(GridNotification ty, Either<Uint8List, FlowyError> result) {
+    switch (ty) {
+      case GridNotification.DidUpdateField:
+        result.fold(
+          (payload) => updateFieldNotifier.value = left(Field.fromBuffer(payload)),
+          (error) => updateFieldNotifier.value = right(error),
+        );
+        break;
+      default:
+        break;
+    }
+  }
+
+  Future<void> stop() async {
+    _parser = null;
+    await _subscription?.cancel();
+    updateFieldNotifier.dispose();
+  }
+}
diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart
index d47dab99d0..61ccad6b81 100644
--- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart
+++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart
@@ -132,16 +132,20 @@ class NewFieldContextLoader extends FieldContextLoader {
 }
 
 class FieldContextLoaderAdaptor extends FieldContextLoader {
-  final GridFieldCellContext data;
+  final String gridId;
+  final Field field;
 
-  FieldContextLoaderAdaptor(this.data);
+  FieldContextLoaderAdaptor({
+    required this.gridId,
+    required this.field,
+  });
 
   @override
   Future<Either<EditFieldContext, FlowyError>> load() {
     final payload = GetEditFieldContextPayload.create()
-      ..gridId = data.gridId
-      ..fieldId = data.field.id
-      ..fieldType = data.field.fieldType;
+      ..gridId = gridId
+      ..fieldId = field.id
+      ..fieldType = field.fieldType;
 
     return GridEventGetEditFieldContext(payload).send();
   }
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart
index 83bce9c7ef..111235841f 100755
--- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart
@@ -10,7 +10,7 @@ import 'package:flutter/material.dart';
 import 'controller/grid_scroll.dart';
 import 'layout/layout.dart';
 import 'layout/sizes.dart';
-import 'widgets/content/grid_row.dart';
+import 'widgets/row/grid_row.dart';
 import 'widgets/footer/grid_footer.dart';
 import 'widgets/header/grid_header.dart';
 import 'widgets/toolbar/grid_toolbar.dart';
@@ -101,7 +101,7 @@ class _FlowyGridState extends State<FlowyGrid> {
                   controller: _scrollController.verticalController,
                   slivers: [
                     _renderToolbar(gridId),
-                    _renderHeader(gridId),
+                    GridHeader(gridId: gridId, fields: List.from(state.fields)),
                     _renderRows(context),
                     const GridFooter(),
                   ],
@@ -144,21 +144,6 @@ class _FlowyGridState extends State<FlowyGrid> {
     );
   }
 
-  Widget _renderHeader(String gridId) {
-    return BlocBuilder<GridBloc, GridState>(
-      buildWhen: (previous, current) => previous.fields.length != current.fields.length,
-      builder: (context, state) {
-        return GridHeader(gridId: gridId, fields: List.from(state.fields));
-
-        // return SliverPersistentHeader(
-        //   delegate: GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)),
-        //   floating: true,
-        //   pinned: true,
-        // );
-      },
-    );
-  }
-
   Widget _renderRows(BuildContext context) {
     return BlocBuilder<GridBloc, GridState>(
       buildWhen: (previous, current) {
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart
similarity index 96%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart
index 856338aea4..8a1b3a63ea 100755
--- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart
@@ -5,7 +5,7 @@ import 'package:flutter/widgets.dart';
 import 'checkbox_cell.dart';
 import 'date_cell.dart';
 import 'number_cell.dart';
-import 'selection_cell.dart';
+import 'selection_cell/selection_cell.dart';
 import 'text_cell.dart';
 
 Widget buildGridCell(String rowId, Field field, FutureCellData cellData) {
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart
similarity index 100%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_decoration.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_decoration.dart
similarity index 100%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_decoration.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_decoration.dart
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart
similarity index 100%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart
similarity index 100%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart
similarity index 100%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart
new file mode 100644
index 0000000000..7fc3b3246f
--- /dev/null
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart
@@ -0,0 +1,7 @@
+export 'cell_builder.dart';
+export 'cell_container.dart';
+export 'text_cell.dart';
+export 'number_cell.dart';
+export 'date_cell.dart';
+export 'checkbox_cell.dart';
+export 'selection_cell/selection_cell.dart';
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart
new file mode 100644
index 0000000000..8f0f3dfc78
--- /dev/null
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart
@@ -0,0 +1,77 @@
+import 'package:flowy_infra/theme.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
+import 'package:flutter/material.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:app_flowy/generated/locale_keys.g.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+class SelectionBadge extends StatelessWidget {
+  final SelectOption option;
+  const SelectionBadge({required this.option, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      decoration: BoxDecoration(
+        color: option.color.make(context),
+        shape: BoxShape.rectangle,
+        borderRadius: BorderRadius.circular(6.0),
+      ),
+      child: FlowyText.medium(option.name, fontSize: 12),
+    );
+  }
+}
+
+extension SelectOptionColorExtension on SelectOptionColor {
+  Color make(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    switch (this) {
+      case SelectOptionColor.Purple:
+        return theme.tint1;
+      case SelectOptionColor.Pink:
+        return theme.tint2;
+      case SelectOptionColor.LightPink:
+        return theme.tint3;
+      case SelectOptionColor.Orange:
+        return theme.tint4;
+      case SelectOptionColor.Yellow:
+        return theme.tint5;
+      case SelectOptionColor.Lime:
+        return theme.tint6;
+      case SelectOptionColor.Green:
+        return theme.tint7;
+      case SelectOptionColor.Aqua:
+        return theme.tint8;
+      case SelectOptionColor.Blue:
+        return theme.tint9;
+      default:
+        throw ArgumentError;
+    }
+  }
+
+  String optionName() {
+    switch (this) {
+      case SelectOptionColor.Purple:
+        return LocaleKeys.grid_selectOption_purpleColor.tr();
+      case SelectOptionColor.Pink:
+        return LocaleKeys.grid_selectOption_pinkColor.tr();
+      case SelectOptionColor.LightPink:
+        return LocaleKeys.grid_selectOption_lightPinkColor.tr();
+      case SelectOptionColor.Orange:
+        return LocaleKeys.grid_selectOption_orangeColor.tr();
+      case SelectOptionColor.Yellow:
+        return LocaleKeys.grid_selectOption_yellowColor.tr();
+      case SelectOptionColor.Lime:
+        return LocaleKeys.grid_selectOption_limeColor.tr();
+      case SelectOptionColor.Green:
+        return LocaleKeys.grid_selectOption_greenColor.tr();
+      case SelectOptionColor.Aqua:
+        return LocaleKeys.grid_selectOption_aquaColor.tr();
+      case SelectOptionColor.Blue:
+        return LocaleKeys.grid_selectOption_blueColor.tr();
+      default:
+        throw ArgumentError;
+    }
+  }
+}
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart
similarity index 100%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart
new file mode 100644
index 0000000000..de25430066
--- /dev/null
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart
@@ -0,0 +1,45 @@
+import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart';
+import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
+import 'package:flowy_infra/theme.dart';
+import 'package:flowy_infra_ui/style_widget/hover.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'selection.dart';
+
+class SelectionEditor extends StatelessWidget {
+  final GridCellData cellData;
+  const SelectionEditor({required this.cellData, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocProvider(
+      create: (context) => SelectionEditorBloc(gridId: cellData.gridId, field: cellData.field),
+      child: BlocBuilder<SelectionEditorBloc, SelectionEditorState>(
+        builder: (context, state) {
+          return Container();
+        },
+      ),
+    );
+  }
+}
+
+class _SelectionCell extends StatelessWidget {
+  final SelectOption option;
+  const _SelectionCell({required this.option, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    return InkWell(
+      onTap: () {},
+      child: FlowyHover(
+        config: HoverDisplayConfig(hoverColor: theme.hover),
+        builder: (_, onHover) {
+          return SelectionBadge(option: option);
+        },
+      ),
+    );
+  }
+}
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart
similarity index 100%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart
index 6a2051318e..89cd0b60ff 100755
--- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart
@@ -49,7 +49,10 @@ class GridFieldCell extends StatelessWidget {
   void _showFieldEditor(BuildContext context) {
     FieldEditor(
       gridId: fieldCellContext.gridId,
-      fieldContextLoader: FieldContextLoaderAdaptor(fieldCellContext),
+      fieldContextLoader: FieldContextLoaderAdaptor(
+        gridId: fieldCellContext.gridId,
+        field: fieldCellContext.field,
+      ),
     ).show(context);
   }
 }
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart
index 4f133090de..a69575a409 100644
--- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart
@@ -1,5 +1,6 @@
 import 'package:app_flowy/workspace/application/grid/field/type_option/edit_option_bloc.dart';
 import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
+import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection.dart';
 import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
@@ -183,56 +184,3 @@ class _SelectOptionColorCell extends StatelessWidget {
     );
   }
 }
-
-extension SelectOptionColorExtension on SelectOptionColor {
-  Color color(BuildContext context) {
-    final theme = context.watch<AppTheme>();
-    switch (this) {
-      case SelectOptionColor.Purple:
-        return theme.tint1;
-      case SelectOptionColor.Pink:
-        return theme.tint2;
-      case SelectOptionColor.LightPink:
-        return theme.tint3;
-      case SelectOptionColor.Orange:
-        return theme.tint4;
-      case SelectOptionColor.Yellow:
-        return theme.tint5;
-      case SelectOptionColor.Lime:
-        return theme.tint6;
-      case SelectOptionColor.Green:
-        return theme.tint7;
-      case SelectOptionColor.Aqua:
-        return theme.tint8;
-      case SelectOptionColor.Blue:
-        return theme.tint9;
-      default:
-        throw ArgumentError;
-    }
-  }
-
-  String optionName() {
-    switch (this) {
-      case SelectOptionColor.Purple:
-        return LocaleKeys.grid_selectOption_purpleColor.tr();
-      case SelectOptionColor.Pink:
-        return LocaleKeys.grid_selectOption_pinkColor.tr();
-      case SelectOptionColor.LightPink:
-        return LocaleKeys.grid_selectOption_lightPinkColor.tr();
-      case SelectOptionColor.Orange:
-        return LocaleKeys.grid_selectOption_orangeColor.tr();
-      case SelectOptionColor.Yellow:
-        return LocaleKeys.grid_selectOption_yellowColor.tr();
-      case SelectOptionColor.Lime:
-        return LocaleKeys.grid_selectOption_limeColor.tr();
-      case SelectOptionColor.Green:
-        return LocaleKeys.grid_selectOption_greenColor.tr();
-      case SelectOptionColor.Aqua:
-        return LocaleKeys.grid_selectOption_aquaColor.tr();
-      case SelectOptionColor.Blue:
-        return LocaleKeys.grid_selectOption_blueColor.tr();
-      default:
-        throw ArgumentError;
-    }
-  }
-}
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart
similarity index 97%
rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart
rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart
index 73594de957..c4c32bda3b 100755
--- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart
@@ -1,14 +1,13 @@
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/grid/prelude.dart';
 import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
+import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:provider/provider.dart';
-import 'cell_builder.dart';
-import 'cell_container.dart';
 
 class GridRowWidget extends StatefulWidget {
   final GridRowData data;
diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart
index 9951e6ba65..a34682d204 100644
--- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart
+++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart
@@ -97,14 +97,9 @@ class _GridPropertyCell extends StatelessWidget {
               hoverColor: theme.hover,
               leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
               onTap: () {
-                final fieldCellContext = GridFieldCellContext(
-                  gridId: gridId,
-                  field: field,
-                );
-
                 FieldEditor(
                   gridId: gridId,
-                  fieldContextLoader: FieldContextLoaderAdaptor(fieldCellContext),
+                  fieldContextLoader: FieldContextLoaderAdaptor(gridId: gridId, field: field),
                 ).show(context, anchorDirection: AnchorDirection.bottomRight);
               },
             ),
diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart
index c000793a5e..634de1b7f2 100644
--- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart
+++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart
@@ -11,17 +11,19 @@ import 'package:protobuf/protobuf.dart' as $pb;
 
 class GridNotification extends $pb.ProtobufEnum {
   static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
-  static const GridNotification GridDidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateBlock');
+  static const GridNotification DidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidCreateBlock');
   static const GridNotification DidUpdateRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow');
   static const GridNotification GridDidUpdateCells = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells');
   static const GridNotification DidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateFields');
+  static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField');
 
   static const $core.List<GridNotification> values = <GridNotification> [
     Unknown,
-    GridDidCreateBlock,
+    DidCreateBlock,
     DidUpdateRow,
     GridDidUpdateCells,
     DidUpdateFields,
+    DidUpdateField,
   ];
 
   static final $core.Map<$core.int, GridNotification> _byValue = $pb.ProtobufEnum.initByValue(values);
diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart
index 5dc1fbc1a5..571fe64399 100644
--- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart
+++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart
@@ -13,12 +13,13 @@ const GridNotification$json = const {
   '1': 'GridNotification',
   '2': const [
     const {'1': 'Unknown', '2': 0},
-    const {'1': 'GridDidCreateBlock', '2': 11},
+    const {'1': 'DidCreateBlock', '2': 11},
     const {'1': 'DidUpdateRow', '2': 20},
     const {'1': 'GridDidUpdateCells', '2': 30},
     const {'1': 'DidUpdateFields', '2': 40},
+    const {'1': 'DidUpdateField', '2': 41},
   ],
 };
 
 /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIQCgxEaWRVcGRhdGVSb3cQFBIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQHhITCg9EaWRVcGRhdGVGaWVsZHMQKA==');
+final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhAKDERpZFVwZGF0ZVJvdxAUEhYKEkdyaWREaWRVcGRhdGVDZWxscxAeEhMKD0RpZFVwZGF0ZUZpZWxkcxAoEhIKDkRpZFVwZGF0ZUZpZWxkECk=');
diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs
index 34c972a9bb..364c42f680 100644
--- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs
+++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs
@@ -5,13 +5,11 @@ const OBSERVABLE_CATEGORY: &str = "Grid";
 #[derive(ProtoBuf_Enum, Debug)]
 pub enum GridNotification {
     Unknown = 0,
-
-    GridDidCreateBlock = 11,
-
+    DidCreateBlock = 11,
     DidUpdateRow = 20,
-
     GridDidUpdateCells = 30,
     DidUpdateFields = 40,
+    DidUpdateField = 41,
 }
 
 impl std::default::Default for GridNotification {
diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs
index 0dd067b3d5..32e697b36e 100644
--- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs
+++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs
@@ -26,10 +26,11 @@
 #[derive(Clone,PartialEq,Eq,Debug,Hash)]
 pub enum GridNotification {
     Unknown = 0,
-    GridDidCreateBlock = 11,
+    DidCreateBlock = 11,
     DidUpdateRow = 20,
     GridDidUpdateCells = 30,
     DidUpdateFields = 40,
+    DidUpdateField = 41,
 }
 
 impl ::protobuf::ProtobufEnum for GridNotification {
@@ -40,10 +41,11 @@ impl ::protobuf::ProtobufEnum for GridNotification {
     fn from_i32(value: i32) -> ::std::option::Option<GridNotification> {
         match value {
             0 => ::std::option::Option::Some(GridNotification::Unknown),
-            11 => ::std::option::Option::Some(GridNotification::GridDidCreateBlock),
+            11 => ::std::option::Option::Some(GridNotification::DidCreateBlock),
             20 => ::std::option::Option::Some(GridNotification::DidUpdateRow),
             30 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells),
             40 => ::std::option::Option::Some(GridNotification::DidUpdateFields),
+            41 => ::std::option::Option::Some(GridNotification::DidUpdateField),
             _ => ::std::option::Option::None
         }
     }
@@ -51,10 +53,11 @@ impl ::protobuf::ProtobufEnum for GridNotification {
     fn values() -> &'static [Self] {
         static values: &'static [GridNotification] = &[
             GridNotification::Unknown,
-            GridNotification::GridDidCreateBlock,
+            GridNotification::DidCreateBlock,
             GridNotification::DidUpdateRow,
             GridNotification::GridDidUpdateCells,
             GridNotification::DidUpdateFields,
+            GridNotification::DidUpdateField,
         ];
         values
     }
@@ -83,10 +86,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x17dart_notification.proto*v\n\x10GridNotification\x12\x0b\n\x07Unkno\
-    wn\x10\0\x12\x16\n\x12GridDidCreateBlock\x10\x0b\x12\x10\n\x0cDidUpdateR\
-    ow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x13\n\x0fDidUpdat\
-    eFields\x10(b\x06proto3\
+    \n\x17dart_notification.proto*\x86\x01\n\x10GridNotification\x12\x0b\n\
+    \x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x10\n\x0cDidUp\
+    dateRow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x13\n\x0fDid\
+    UpdateFields\x10(\x12\x12\n\x0eDidUpdateField\x10)b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto
index da1d193b21..176e0d83a4 100644
--- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto
+++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto
@@ -2,8 +2,9 @@ syntax = "proto3";
 
 enum GridNotification {
     Unknown = 0;
-    GridDidCreateBlock = 11;
+    DidCreateBlock = 11;
     DidUpdateRow = 20;
     GridDidUpdateCells = 30;
     DidUpdateFields = 40;
+    DidUpdateField = 41;
 }
diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
index 95c23f489b..443c1ee2bf 100644
--- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
@@ -97,6 +97,7 @@ impl ClientGridEditor {
     }
 
     pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> {
+        let field_id = params.field_id.clone();
         let deserializer = match self.pad.read().await.get_field(&params.field_id) {
             None => return Err(ErrorCode::FieldDoesNotExist.into()),
             Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()),
@@ -104,6 +105,7 @@ impl ClientGridEditor {
 
         let _ = self.modify(|grid| Ok(grid.update_field(params, deserializer)?)).await?;
         let _ = self.notify_did_update_fields().await?;
+        let _ = self.notify_did_update_field(&field_id).await?;
         Ok(())
     }
 
@@ -133,6 +135,7 @@ impl ClientGridEditor {
             .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?))
             .await?;
         let _ = self.notify_did_update_fields().await?;
+        let _ = self.notify_did_update_field(field_id).await?;
         Ok(())
     }
 
@@ -294,7 +297,19 @@ impl ClientGridEditor {
     }
 
     pub async fn get_field_metas(&self, field_orders: Option<RepeatedFieldOrder>) -> FlowyResult<Vec<FieldMeta>> {
-        let mut field_metas = self.pad.read().await.get_field_metas(field_orders)?;
+        let expected_len = match field_orders.as_ref() {
+            None => 0,
+            Some(field_orders) => field_orders.len(),
+        };
+
+        let field_metas = self.pad.read().await.get_field_metas(field_orders)?;
+        debug_assert!(field_metas.len() == expected_len);
+        if field_metas.len() != expected_len {
+            tracing::error!(
+                "This is a bug. The len of the field_metas should equal to {}",
+                expected_len
+            );
+        }
         // field_metas.retain(|field_meta| field_meta.visibility);
         Ok(field_metas)
     }
@@ -368,6 +383,20 @@ impl ClientGridEditor {
             .send();
         Ok(())
     }
+
+    async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> {
+        let field_orders: RepeatedFieldOrder = vec![FieldOrder::from(field_id)].into();
+        let mut field_metas = self.get_field_metas(Some(field_orders)).await?;
+        debug_assert!(field_metas.len() == 1);
+
+        if let Some(field_meta) = field_metas.pop() {
+            send_dart_notification(&self.grid_id, GridNotification::DidUpdateField)
+                .payload(field_meta)
+                .send();
+        }
+
+        Ok(())
+    }
 }
 
 #[cfg(feature = "flowy_unit_test")]
diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs
index b60aafedae..1dd2220f13 100644
--- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs
+++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs
@@ -100,6 +100,12 @@ impl std::convert::From<&FieldMeta> for FieldOrder {
     }
 }
 
+impl std::convert::From<&str> for FieldOrder {
+    fn from(s: &str) -> Self {
+        FieldOrder { field_id: s.to_owned() }
+    }
+}
+
 #[derive(Debug, Default, ProtoBuf)]
 pub struct GetEditFieldContextPayload {
     #[pb(index = 1)]
@@ -193,6 +199,12 @@ impl std::ops::Deref for RepeatedFieldOrder {
     }
 }
 
+impl std::convert::From<Vec<FieldOrder>> for RepeatedFieldOrder {
+    fn from(field_orders: Vec<FieldOrder>) -> Self {
+        RepeatedFieldOrder { items: field_orders }
+    }
+}
+
 #[derive(Debug, Default, Clone, ProtoBuf)]
 pub struct RowOrder {
     #[pb(index = 1)]