diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index 8dc0b202639cf..0e93dc6a21636 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -9,8 +9,8 @@ class GridSize { static double get leadingHeaderPadding => 50 * scale; static double get trailHeaderPadding => 140 * scale; static double get headerContainerPadding => 0 * scale; - static double get cellHPadding => 10 * scale; - static double get cellVPadding => 8 * scale; + static double get cellHPadding => 12 * scale; + static double get cellVPadding => 12 * scale; static double get typeOptionItemHeight => 32 * scale; static double get typeOptionSeparatorHeight => 6 * scale; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 4d62dc9eb213d..b3af02a29dddb 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -2,6 +2,12 @@ import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; import 'package:flutter/widgets.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:styled_widget/styled_widget.dart'; import 'checkbox_cell.dart'; import 'date_cell.dart'; import 'number_cell.dart'; @@ -57,3 +63,114 @@ class GridCellRequestFocusNotifier extends ChangeNotifier { } abstract class GridCellStyle {} + +class CellStateNotifier extends ChangeNotifier { + bool _isFocus = false; + bool _onEnter = false; + + set isFocus(bool value) { + if (_isFocus != value) { + _isFocus = value; + notifyListeners(); + } + } + + set onEnter(bool value) { + if (_onEnter != value) { + _onEnter = value; + notifyListeners(); + } + } + + bool get isFocus => _isFocus; + + bool get onEnter => _onEnter; +} + +class CellContainer extends StatelessWidget { + final GridCellWidget child; + final Widget? expander; + final double width; + final RegionStateNotifier rowStateNotifier; + const CellContainer({ + Key? key, + required this.child, + required this.width, + required this.rowStateNotifier, + this.expander, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return ChangeNotifierProxyProvider( + create: (_) => CellStateNotifier(), + update: (_, row, cell) => cell!..onEnter = row.onEnter, + child: Selector( + selector: (context, notifier) => notifier.isFocus, + builder: (context, isFocus, _) { + Widget container = Center(child: child); + child.onFocus.addListener(() { + Provider.of(context, listen: false).isFocus = child.onFocus.value; + }); + + if (expander != null) { + container = _CellEnterRegion(child: container, expander: expander!); + } + + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => child.requestFocus.notify(), + child: Container( + constraints: BoxConstraints(maxWidth: width), + decoration: _makeBoxDecoration(context, isFocus), + padding: GridSize.cellContentInsets, + child: container, + ), + ); + }, + ), + ); + } + + BoxDecoration _makeBoxDecoration(BuildContext context, bool isFocus) { + final theme = context.watch(); + if (isFocus) { + final borderSide = BorderSide(color: theme.main1, width: 1.0); + return BoxDecoration(border: Border.fromBorderSide(borderSide)); + } else { + final borderSide = BorderSide(color: theme.shader5, width: 1.0); + return BoxDecoration(border: Border(right: borderSide, bottom: borderSide)); + } + } +} + +class _CellEnterRegion extends StatelessWidget { + final Widget child; + final Widget expander; + const _CellEnterRegion({required this.child, required this.expander, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Selector( + selector: (context, notifier) => notifier.onEnter, + builder: (context, onEnter, _) { + List children = [child]; + if (onEnter) { + children.add(expander.positioned(right: 0)); + } + + return MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => Provider.of(context, listen: false).onEnter = true, + onExit: (p) => Provider.of(context, listen: false).onEnter = false, + child: Stack( + alignment: AlignmentDirectional.center, + fit: StackFit.expand, + // alignment: AlignmentDirectional.centerEnd, + children: children, + ), + ); + }, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart deleted file mode 100755 index 89f3700a0d230..0000000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ /dev/null @@ -1,115 +0,0 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'cell_builder.dart'; - -class CellStateNotifier extends ChangeNotifier { - bool _isFocus = false; - bool _onEnter = false; - - set isFocus(bool value) { - if (_isFocus != value) { - _isFocus = value; - notifyListeners(); - } - } - - set onEnter(bool value) { - if (_onEnter != value) { - _onEnter = value; - notifyListeners(); - } - } - - bool get isFocus => _isFocus; - - bool get onEnter => _onEnter; -} - -class CellContainer extends StatelessWidget { - final GridCellWidget child; - final Widget? expander; - final double width; - final RegionStateNotifier rowStateNotifier; - const CellContainer({ - Key? key, - required this.child, - required this.width, - required this.rowStateNotifier, - this.expander, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ChangeNotifierProxyProvider( - create: (_) => CellStateNotifier(), - update: (_, row, cell) => cell!..onEnter = row.onEnter, - child: Selector( - selector: (context, notifier) => notifier.isFocus, - builder: (context, isFocus, _) { - Widget container = Center(child: child); - child.onFocus.addListener(() { - Provider.of(context, listen: false).isFocus = child.onFocus.value; - }); - - if (expander != null) { - container = _CellEnterRegion(child: container, expander: expander!); - } - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => child.requestFocus.notify(), - child: Container( - constraints: BoxConstraints(maxWidth: width), - decoration: _makeBoxDecoration(context, isFocus), - padding: GridSize.cellContentInsets, - child: container, - ), - ); - }, - ), - ); - } - - BoxDecoration _makeBoxDecoration(BuildContext context, bool isFocus) { - final theme = context.watch(); - if (isFocus) { - final borderSide = BorderSide(color: theme.main1, width: 1.0); - return BoxDecoration(border: Border.fromBorderSide(borderSide)); - } else { - final borderSide = BorderSide(color: theme.shader4, width: 0.4); - return BoxDecoration(border: Border(right: borderSide, bottom: borderSide)); - } - } -} - -class _CellEnterRegion extends StatelessWidget { - final Widget child; - final Widget expander; - const _CellEnterRegion({required this.child, required this.expander, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Selector( - selector: (context, notifier) => notifier.onEnter, - builder: (context, onEnter, _) { - List children = [Expanded(child: child)]; - if (onEnter) { - children.add(expander); - } - - return MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => Provider.of(context, listen: false).onEnter = true, - onExit: (p) => Provider.of(context, listen: false).onEnter = false, - child: Row( - // alignment: AlignmentDirectional.centerEnd, - children: children, - ), - ); - }, - ); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index 7a69db02f2567..97754e339eb72 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -36,7 +36,7 @@ class _CheckboxCellState extends State { builder: (context, state) { final icon = state.isSelected ? svgWidget('editor/editor_check') : svgWidget('editor/editor_uncheck'); return SizedBox( - height: 42, + height: 20, child: Align( alignment: Alignment.centerLeft, child: FlowyIconButton( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index 9901790fa5c84..b45f964bdc952 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -55,7 +55,7 @@ class _NumberCellState extends State { controller: _controller, focusNode: _focusNode, onEditingComplete: () => _focusNode.unfocus(), - maxLines: 1, + maxLines: null, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), decoration: const InputDecoration( contentPadding: EdgeInsets.zero, 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 index 7fc3b3246fbd3..8f1e13de94dc3 100644 --- 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 @@ -1,5 +1,4 @@ export 'cell_builder.dart'; -export 'cell_container.dart'; export 'text_cell.dart'; export 'number_cell.dart'; export 'date_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart index bdf4d01158ba2..71a86e91b422c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/extension.dart @@ -66,15 +66,25 @@ class SelectOptionTag extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: option.color.make(context), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8.0), - ), - child: Center(child: FlowyText.medium(option.name, fontSize: 12)), - margin: const EdgeInsets.symmetric(horizontal: 3.0), - padding: const EdgeInsets.symmetric(horizontal: 6.0), + return ChoiceChip( + pressElevation: 1, + label: FlowyText.medium(option.name, fontSize: 12), + selectedColor: option.color.make(context), + backgroundColor: option.color.make(context), + labelPadding: const EdgeInsets.symmetric(horizontal: 6), + selected: true, + onSelected: (_) {}, ); + + // return Container( + // decoration: BoxDecoration( + // color: option.color.make(context), + // shape: BoxShape.rectangle, + // borderRadius: BorderRadius.circular(8.0), + // ), + // child: Center(child: FlowyText.medium(option.name, fontSize: 12)), + // margin: const EdgeInsets.symmetric(horizontal: 3.0), + // padding: const EdgeInsets.symmetric(horizontal: 6.0), + // ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 5edb3148d1381..e23af426e6255 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -44,7 +44,6 @@ class _SingleSelectCellState extends State { @override void initState() { - // Log.trace("init widget $hashCode"); final cellContext = _buildCellContext(); _cellBloc = getIt(param1: cellContext)..add(const SelectionCellEvent.initial()); super.initState(); @@ -64,8 +63,7 @@ class _SingleSelectCellState extends State { if (children.isEmpty && widget.cellStyle != null) { children.add(FlowyText.medium(widget.cellStyle!.placeholder, fontSize: 14, color: theme.shader3)); } - return SizedBox( - height: 69, + return SizedBox.expand( child: InkWell( onTap: () { widget.onFocus.value = true; @@ -75,7 +73,7 @@ class _SingleSelectCellState extends State { () => widget.onFocus.value = false, ); }, - child: ClipRRect(child: Row(children: children)), + child: Center(child: Wrap(children: children)), ), ); }, @@ -89,7 +87,6 @@ class _SingleSelectCellState extends State { @override Future dispose() async { - // Log.trace("dispose widget $hashCode"); _cellBloc.close(); super.dispose(); } @@ -148,7 +145,7 @@ class _MultiSelectCellState extends State { () => widget.onFocus.value = false, ); }, - child: ClipRRect(child: Row(children: children)), + child: Wrap(children: children, spacing: 4, runSpacing: 4), ), ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart index e7f4e98851ff0..0bc33fc8d246d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/text_field.dart @@ -94,7 +94,7 @@ class SelectOptionTextField extends StatelessWidget { child: SingleChildScrollView( controller: sc, scrollDirection: Axis.horizontal, - child: Row(children: children), + child: Wrap(children: children, spacing: 4), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index a7b548fda542d..2b3a72525f99b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -68,21 +68,18 @@ class _GridTextCellState extends State { }, buildWhen: (previous, current) => previous.content != current.content, builder: (context, state) { - return SizedBox( - height: 42, - child: TextField( - controller: _controller, - focusNode: _focusNode, - onChanged: (value) => focusChanged(), - onEditingComplete: () => _focusNode.unfocus(), - maxLines: 1, - style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), - decoration: InputDecoration( - contentPadding: EdgeInsets.zero, - border: InputBorder.none, - hintText: widget.cellStyle?.placeholder, - isDense: true, - ), + return TextField( + controller: _controller, + focusNode: _focusNode, + onChanged: (value) => focusChanged(), + onEditingComplete: () => _focusNode.unfocus(), + maxLines: null, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + hintText: widget.cellStyle?.placeholder, + isDense: true, ), ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 195899c2963f5..d4eaa21a90d12 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -206,9 +206,11 @@ class _CellExpander extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyIconButton( - width: 20, + width: 30, + height: 24, onPressed: onExpand, - iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2), + iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), + fillColor: theme.surface, icon: svgWidget("grid/expander", color: theme.main1), ); }