diff --git a/frontend/appflowy_flutter/integration_test/board/board_add_row_test.dart b/frontend/appflowy_flutter/integration_test/board/board_add_row_test.dart index fe58e3836b..7304ae9f37 100644 --- a/frontend/appflowy_flutter/integration_test/board/board_add_row_test.dart +++ b/frontend/appflowy_flutter/integration_test/board/board_add_row_test.dart @@ -1,5 +1,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/plugins/database_view/board/presentation/widgets/board_column_header.dart'; +import 'package:appflowy/plugins/database_view/widgets/card/container/card_container.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; import 'package:appflowy_board/appflowy_board.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; @@ -15,8 +16,8 @@ const defaultLastCardName = 'Card 3'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group('board add row test', () { - testWidgets('Add card from header', (tester) async { + group('board add row test:', () { + testWidgets('from header', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); @@ -45,7 +46,7 @@ void main() { const newCardName = 'Card 4'; await tester.enterText( find.descendant( - of: find.byType(IntrinsicHeight), + of: find.byType(RowCardContainer), matching: find.byType(TextField), ), newCardName, @@ -59,7 +60,7 @@ void main() { expect(firstCardText.text, newCardName); }); - testWidgets('Add card from footer', (tester) async { + testWidgets('from footer', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); @@ -87,7 +88,7 @@ void main() { const newCardName = 'Card 4'; await tester.enterText( find.descendant( - of: find.byType(IntrinsicHeight), + of: find.byType(RowCardContainer), matching: find.byType(TextField), ), newCardName, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart index 9c6ac62fc7..b5e8dd1d04 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart @@ -17,6 +17,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart'; import 'package:appflowy_board/appflowy_board.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flutter/material.dart' hide Card; @@ -159,10 +160,12 @@ class _BoardContentState extends State { boardScrollController: scrollManager, scrollController: scrollController, controller: context.read().boardController, - groupConstraints: const BoxConstraints.tightFor(width: 300), + groupConstraints: const BoxConstraints.tightFor(width: 256), config: const AppFlowyBoardConfig( groupPadding: EdgeInsets.symmetric(horizontal: 4), groupItemPadding: EdgeInsets.symmetric(horizontal: 4), + footerPadding: EdgeInsets.fromLTRB(4, 14, 4, 4), + stretchGroupHeight: false, ), leading: HiddenGroupsColumn(margin: config.headerPadding), trailing: showCreateGroupButton @@ -200,20 +203,15 @@ class _BoardContentState extends State { Widget _buildFooter(BuildContext context, AppFlowyGroupData columnData) { return AppFlowyGroupFooter( - height: 50, + height: 36, margin: config.footerPadding, - icon: SizedBox( - height: 20, - width: 20, - child: FlowySvg( - FlowySvgs.add_s, - color: Theme.of(context).hintColor, - ), + icon: FlowySvg( + FlowySvgs.add_s, + color: Theme.of(context).hintColor, ), title: FlowyText.medium( LocaleKeys.board_column_createNewCard.tr(), color: Theme.of(context).hintColor, - fontSize: 14, ), onAddButtonClick: () => context .read() @@ -266,6 +264,14 @@ class _BoardContentState extends State { rowMeta: rowMeta, rowCache: rowCache, ), + styleConfiguration: RowCardStyleConfiguration( + hoverStyle: HoverStyle( + hoverColor: Theme.of(context).brightness == Brightness.light + ? const Color(0x0F1F2329) + : const Color(0x0FEFF4FB), + foregroundColorOnHover: Theme.of(context).colorScheme.onBackground, + ), + ), onStartEditing: () => boardBloc .add(BoardEvent.startEditingRow(groupData.group, groupItem.row)), onEndEditing: () => @@ -280,8 +286,10 @@ class _BoardContentState extends State { borderRadius: const BorderRadius.all(Radius.circular(6)), border: Border.fromBorderSide( BorderSide( - color: Theme.of(context).dividerColor, - width: 1.4, + color: Theme.of(context).brightness == Brightness.light + ? const Color(0xFF1F2329).withOpacity(0.12) + : const Color(0xFF59647A), + width: 1.0, ), ), boxShadow: [ diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/widgets/board_column_header.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/widgets/board_column_header.dart index 67c01a51a3..70db26df3d 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/widgets/board_column_header.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/widgets/board_column_header.dart @@ -3,7 +3,6 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database_view/board/application/board_bloc.dart'; import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart'; -import 'package:appflowy/plugins/database_view/widgets/card/define.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/group.pb.dart'; import 'package:appflowy_board/appflowy_board.dart'; @@ -158,10 +157,8 @@ class _BoardColumnHeaderState extends State { filled: true, fillColor: Theme.of(context).colorScheme.surface, hoverColor: Colors.transparent, - contentPadding: EdgeInsets.symmetric( - vertical: CardSizes.cardCellVPadding + 4, - horizontal: 8, - ), + contentPadding: + const EdgeInsets.symmetric(vertical: 12, horizontal: 8), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Theme.of(context).colorScheme.primary, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart index 260d9b89c5..e83e7bbbcf 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart @@ -73,9 +73,9 @@ class RowCard extends StatefulWidget { } class _RowCardState extends State> { + final popoverController = PopoverController(); late final CardBloc _cardBloc; late final EditableRowNotifier rowNotifier; - late final PopoverController popoverController; AccessoryType? accessoryType; @override @@ -100,8 +100,6 @@ class _RowCardState extends State> { widget.onEndEditing(); } }); - - popoverController = PopoverController(); } @override @@ -111,26 +109,21 @@ class _RowCardState extends State> { child: BlocBuilder( buildWhen: (previous, current) { // Rebuild when: - // 1.If the length of the cells is not the same - // 2.isEditing changed + // 1. If the length of the cells is not the same or isEditing changed if (previous.cells.length != current.cells.length || previous.isEditing != current.isEditing) { return true; } - // 3.Compare the content of the cells. The cells consists of - // list of [BoardCellEquatable] that extends the [Equatable]. + // 2. the content of the cells changed return !listEquals(previous.cells, current.cells); }, builder: (context, state) { - // mobile if (PlatformExtension.isMobile) { // TODO(yijing): refactor it in mobile to display card in database view return RowCardContainer( buildAccessoryWhen: () => state.isEditing == false, - accessoryBuilder: (context) { - return []; - }, + accessories: const [], openAccessory: (p0) {}, openCard: (context) => widget.openCard(context), child: _CardContent( @@ -143,29 +136,27 @@ class _RowCardState extends State> { ), ); } - // desktop + return AppFlowyPopover( controller: popoverController, triggerActions: PopoverTriggerFlags.none, constraints: BoxConstraints.loose(const Size(140, 200)), - margin: const EdgeInsets.all(6), direction: PopoverDirection.rightWithCenterAligned, - popupBuilder: (popoverContext) => _handlePopoverBuilder( - context, - popoverContext, - ), + popupBuilder: (popoverContext) { + return RowActions( + viewId: _cardBloc.viewId, + rowId: _cardBloc.rowMeta.id, + groupId: widget.groupId, + ); + }, child: RowCardContainer( buildAccessoryWhen: () => state.isEditing == false, - accessoryBuilder: (context) { - if (widget.styleConfiguration.showAccessory == false) { - return []; - } else { - return [ - _CardEditOption(rowNotifier: rowNotifier), - CardMoreOption(), - ]; - } - }, + accessories: [ + if (widget.styleConfiguration.showAccessory) ...[ + _CardEditOption(rowNotifier: rowNotifier), + const CardMoreOption(), + ], + ], openAccessory: _handleOpenAccessory, openCard: (context) => widget.openCard(context), child: _CardContent( @@ -194,22 +185,6 @@ class _RowCardState extends State> { } } - Widget _handlePopoverBuilder( - BuildContext context, - BuildContext popoverContext, - ) { - switch (accessoryType!) { - case AccessoryType.edit: - throw UnimplementedError(); - case AccessoryType.more: - return RowActions( - viewId: context.read().viewId, - rowId: context.read().rowMeta.id, - groupId: widget.groupId, - ); - } - } - @override Future dispose() async { rowNotifier.dispose(); @@ -241,6 +216,7 @@ class _CardContent extends StatelessWidget { if (styleConfiguration.hoverStyle != null) { return FlowyHover( style: styleConfiguration.hoverStyle, + buildWhenOnHover: () => !rowNotifier.isEditing.value, child: Padding( padding: styleConfiguration.cardPadding, child: Column( @@ -296,21 +272,21 @@ class _CardContent extends StatelessWidget { } class CardMoreOption extends StatelessWidget with CardAccessory { - CardMoreOption({Key? key}) : super(key: key); + const CardMoreOption({super.key}); + + @override + AccessoryType get type => AccessoryType.more; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(3.0), child: FlowySvg( - FlowySvgs.details_s, - color: Theme.of(context).iconTheme.color, + FlowySvgs.three_dots_s, + color: Theme.of(context).hintColor, ), ); } - - @override - AccessoryType get type => AccessoryType.more; } class _CardEditOption extends StatelessWidget with CardAccessory { @@ -326,7 +302,7 @@ class _CardEditOption extends StatelessWidget with CardAccessory { padding: const EdgeInsets.all(3.0), child: FlowySvg( FlowySvgs.edit_s, - color: Theme.of(context).iconTheme.color, + color: Theme.of(context).hintColor, ), ); } @@ -346,7 +322,7 @@ class RowCardStyleConfiguration { const RowCardStyleConfiguration({ this.showAccessory = true, - this.cellPadding = const EdgeInsets.only(left: 4, right: 4), + this.cellPadding = EdgeInsets.zero, this.cardPadding = const EdgeInsets.all(8), this.hoverStyle, }); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checkbox_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checkbox_card_cell.dart index b39ed584e5..6b54ab88e2 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checkbox_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checkbox_card_cell.dart @@ -5,6 +5,7 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import '../define.dart'; import 'card_cell.dart'; class CheckboxCardCell extends CardCell { @@ -24,11 +25,11 @@ class _CheckboxCellState extends State { @override void initState() { + super.initState(); final cellController = widget.cellControllerBuilder.build() as CheckboxCellController; - _cellBloc = CheckboxCellBloc(cellController: cellController); - _cellBloc.add(const CheckboxCellEvent.initial()); - super.initState(); + _cellBloc = CheckboxCellBloc(cellController: cellController) + ..add(const CheckboxCellEvent.initial()); } @override @@ -47,7 +48,7 @@ class _CheckboxCellState extends State { return Align( alignment: Alignment.centerLeft, child: Padding( - padding: const EdgeInsets.symmetric(vertical: 2), + padding: CardSizes.cardCellPadding, child: FlowyIconButton( iconPadding: EdgeInsets.zero, icon: icon, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checklist_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checklist_card_cell.dart index 4e3e50c237..523f3593d6 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checklist_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/checklist_card_cell.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../row/cells/checklist_cell/checklist_cell_bloc.dart'; +import '../define.dart'; import 'card_cell.dart'; class ChecklistCardCell extends CardCell { @@ -37,7 +38,7 @@ class _ChecklistCellState extends State { return const SizedBox.shrink(); } return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), + padding: CardSizes.cardCellPadding, child: ChecklistProgressBar( tasks: state.tasks, percent: state.percent, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/date_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/date_card_cell.dart index 130113e400..afbc6b4a8c 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/date_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/date_card_cell.dart @@ -42,31 +42,28 @@ class _DateCellState extends State { buildWhen: (previous, current) => previous.dateStr != current.dateStr, builder: (context, state) { if (state.dateStr.isEmpty) { - return const SizedBox(); - } else { - final Widget? custom = widget.renderHook?.call( - state.data, - widget.cardData, - context, - ); - if (custom != null) { - return custom; - } - - return Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.symmetric( - vertical: CardSizes.cardCellVPadding, - ), - child: FlowyText.regular( - state.dateStr, - fontSize: 13, - color: Theme.of(context).hintColor, - ), - ), - ); + return const SizedBox.shrink(); } + final Widget? custom = widget.renderHook?.call( + state.data, + widget.cardData, + context, + ); + if (custom != null) { + return custom; + } + + return Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: CardSizes.cardCellPadding, + child: FlowyText.regular( + state.dateStr, + fontSize: 11, + color: Theme.of(context).hintColor, + ), + ), + ); }, ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/number_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/number_card_cell.dart index 547fdc4086..a0bb41718b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/number_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/number_card_cell.dart @@ -52,30 +52,28 @@ class _NumberCellState extends State { previous.cellContent != current.cellContent, builder: (context, state) { if (state.cellContent.isEmpty) { - return const SizedBox(); - } else { - final Widget? custom = widget.renderHook?.call( - state.cellContent, - widget.cardData, - context, - ); - if (custom != null) { - return custom; - } - - return Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.symmetric( - vertical: CardSizes.cardCellVPadding, - ), - child: FlowyText.medium( - state.cellContent, - fontSize: widget.style?.fontSize ?? 14, - ), - ), - ); + return const SizedBox.shrink(); } + final Widget? custom = widget.renderHook?.call( + state.cellContent, + widget.cardData, + context, + ); + if (custom != null) { + return custom; + } + + return Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: CardSizes.cardCellPadding, + child: FlowyText.regular( + state.cellContent, + fontSize: widget.style?.fontSize ?? 11, + color: Theme.of(context).hintColor, + ), + ), + ); }, ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/select_option_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/select_option_card_cell.dart index bf199f5b7d..997559cce3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/select_option_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/select_option_card_cell.dart @@ -5,6 +5,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart' import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import '../define.dart'; import 'card_cell.dart'; class SelectOptionCardCellStyle extends CardCellStyle {} @@ -69,12 +70,11 @@ class _SelectOptionCellState extends State { ) .toList(); - return IntrinsicHeight( + return Align( + alignment: AlignmentDirectional.topStart, child: Padding( - padding: const EdgeInsets.symmetric(vertical: 6), - child: SizedBox.expand( - child: Wrap(spacing: 4, runSpacing: 2, children: children), - ), + padding: CardSizes.cardCellPadding, + child: Wrap(spacing: 4, runSpacing: 2, children: children), ), ); }, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart index 7f23f0e374..8e01c4165e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart @@ -1,10 +1,13 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart'; import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; + import '../../row/cell_builder.dart'; import '../define.dart'; import 'card_cell.dart'; @@ -120,24 +123,30 @@ class _TextCellState extends State { return custom; } + final isTitle = + context.read().cellController.fieldInfo.isPrimary; if (state.content.isEmpty && state.enableEdit == false && - focusWhenInit == false) { - return const SizedBox(); + focusWhenInit == false && + !isTitle) { + return const SizedBox.shrink(); } final child = state.enableEdit || focusWhenInit ? _buildTextField() - : _buildText(state); + : _buildText(state, isTitle); - return Row( - children: [ - if (widget.showNotes) ...[ - const FlowySvg(FlowySvgs.notes_s), - const HSpace(4), + return Padding( + padding: CardSizes.cardCellPadding, + child: Row( + children: [ + if (widget.showNotes) ...[ + const FlowySvg(FlowySvgs.notes_s), + const HSpace(4), + ], + Expanded(child: child), ], - Expanded(child: child), - ], + ), ); }, ), @@ -157,47 +166,46 @@ class _TextCellState extends State { super.dispose(); } - double _fontSize() { - if (widget.style != null) { - return widget.style!.fontSize; - } - - return 14; - } - - Widget _buildText(TextCellState state) { - return Padding( - padding: EdgeInsets.symmetric( - vertical: CardSizes.cardCellVPadding, - ), - child: FlowyText.medium( - state.content, - fontSize: _fontSize(), - maxLines: null, // Enable multiple lines - ), + Widget _buildText(TextCellState state, bool isTitle) { + final text = state.content.isEmpty + ? LocaleKeys.grid_row_titlePlaceholder.tr() + : state.content; + final color = state.content.isEmpty ? Theme.of(context).hintColor : null; + return FlowyText( + text, + fontSize: _fontSize(isTitle), + fontWeight: _fontWeight(isTitle), + color: color, + maxLines: null, // Enable multiple lines ); } + double _fontSize(bool isTitle) { + return widget.style?.fontSize ?? (isTitle ? 12 : 11); + } + + FontWeight _fontWeight(bool isTitle) { + return isTitle ? FontWeight.w500 : FontWeight.w400; + } + Widget _buildTextField() { - return IntrinsicHeight( - child: TextField( - controller: _controller, - focusNode: focusNode, - onChanged: (value) => focusChanged(), - onEditingComplete: () => focusNode.unfocus(), - maxLines: null, - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(fontSize: _fontSize()), - decoration: InputDecoration( - // Magic number 4 makes the textField take up the same space as FlowyText - contentPadding: EdgeInsets.symmetric( - vertical: CardSizes.cardCellVPadding + 4, - ), - border: InputBorder.none, - isDense: true, - ), + return TextField( + controller: _controller, + focusNode: focusNode, + onChanged: (value) => focusChanged(), + onEditingComplete: () => focusNode.unfocus(), + maxLines: null, + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(fontSize: _fontSize(true)), + decoration: InputDecoration( + contentPadding: + EdgeInsets.symmetric(vertical: CardSizes.cardCellPadding.top), + border: InputBorder.none, + isDense: true, + isCollapsed: true, + hintText: LocaleKeys.grid_row_titlePlaceholder.tr(), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/timestamp_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/timestamp_card_cell.dart index 1155940dee..3b3f03ad85 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/timestamp_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/timestamp_card_cell.dart @@ -56,12 +56,10 @@ class _TimestampCellState extends State { return Align( alignment: Alignment.centerLeft, child: Padding( - padding: EdgeInsets.symmetric( - vertical: CardSizes.cardCellVPadding, - ), + padding: CardSizes.cardCellPadding, child: FlowyText.regular( state.dateStr, - fontSize: 13, + fontSize: 11, color: Theme.of(context).hintColor, ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/url_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/url_card_cell.dart index 84eec23367..befd071cb4 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/url_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/url_card_cell.dart @@ -1,6 +1,5 @@ import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart'; import 'package:appflowy/plugins/database_view/widgets/row/cells/url_cell/url_cell_bloc.dart'; -import 'package:flowy_infra/size.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -48,27 +47,24 @@ class _URLCellState extends State { builder: (context, state) { if (state.content.isEmpty) { return const SizedBox(); - } else { - return Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.symmetric( - vertical: CardSizes.cardCellVPadding, - ), - child: RichText( - textAlign: TextAlign.left, - text: TextSpan( - text: state.content, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: widget.style?.fontSize ?? FontSizes.s14, - color: Theme.of(context).colorScheme.primary, - decoration: TextDecoration.underline, - ), - ), + } + return Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: CardSizes.cardCellPadding, + child: RichText( + textAlign: TextAlign.left, + text: TextSpan( + text: state.content, + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontSize: widget.style?.fontSize ?? 11, + color: Theme.of(context).colorScheme.primary, + decoration: TextDecoration.underline, + ), ), ), - ); - } + ), + ); }, ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/accessory.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/accessory.dart index 5480e24687..76236014e8 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/accessory.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/accessory.dart @@ -26,7 +26,7 @@ class CardAccessoryContainer extends StatelessWidget { @override Widget build(BuildContext context) { - final children = accessories.map((accessory) { + final children = accessories.map((accessory) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { @@ -36,32 +36,62 @@ class CardAccessoryContainer extends StatelessWidget { child: _wrapHover(context, accessory), ); }).toList(); - return _wrapDecoration(context, Row(children: children)); + + children.insert( + 1, + VerticalDivider( + width: 1, + thickness: 1, + color: Theme.of(context).brightness == Brightness.light + ? const Color(0xFF1F2329).withOpacity(0.12) + : const Color(0xff59647a), + ), + ); + + return _wrapDecoration( + context, + IntrinsicHeight(child: Row(children: children)), + ); } - FlowyHover _wrapHover(BuildContext context, CardAccessory accessory) { - return FlowyHover( - style: HoverStyle( - backgroundColor: Theme.of(context).colorScheme.surface, - borderRadius: BorderRadius.zero, - ), - builder: (_, onHover) => SizedBox( - width: 24, - height: 24, + Widget _wrapHover(BuildContext context, CardAccessory accessory) { + return SizedBox( + width: 24, + height: 22, + child: FlowyHover( + style: HoverStyle( + backgroundColor: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.zero, + ), child: accessory, ), ); } Widget _wrapDecoration(BuildContext context, Widget child) { - final borderSide = BorderSide( - color: Theme.of(context).dividerColor, - width: 1.0, - ); final decoration = BoxDecoration( - color: Colors.transparent, - border: Border.fromBorderSide(borderSide), + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(4)), + border: Border.fromBorderSide( + BorderSide( + color: Theme.of(context).brightness == Brightness.light + ? const Color(0xFF1F2329).withOpacity(0.12) + : const Color(0xff59647a), + width: 1.0, + ), + ), + boxShadow: [ + BoxShadow( + blurRadius: 4, + spreadRadius: 0, + color: const Color(0xFF1F2329).withOpacity(0.02), + ), + BoxShadow( + blurRadius: 4, + spreadRadius: -2, + color: const Color(0xFF1F2329).withOpacity(0.02), + ), + ], ); return Container( clipBehavior: Clip.hardEdge, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart index 5de39625e9..99e0698a4b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart @@ -5,7 +5,7 @@ import 'accessory.dart'; class RowCardContainer extends StatelessWidget { final Widget child; - final CardAccessoryBuilder? accessoryBuilder; + final List accessories; final bool Function()? buildAccessoryWhen; final void Function(BuildContext) openCard; final void Function(AccessoryType) openAccessory; @@ -13,7 +13,7 @@ class RowCardContainer extends StatelessWidget { required this.child, required this.openCard, required this.openAccessory, - this.accessoryBuilder, + required this.accessories, this.buildAccessoryWhen, Key? key, }) : super(key: key); @@ -30,15 +30,12 @@ class RowCardContainer extends StatelessWidget { shouldBuildAccessory = buildAccessoryWhen!.call(); } - if (accessoryBuilder != null && shouldBuildAccessory) { - final accessories = accessoryBuilder!(context); - if (accessories.isNotEmpty) { - container = _CardEnterRegion( - accessories: accessories, - onTapAccessory: openAccessory, - child: container, - ); - } + if (shouldBuildAccessory && accessories.isNotEmpty) { + container = _CardEnterRegion( + accessories: accessories, + onTapAccessory: openAccessory, + child: container, + ); } return GestureDetector( @@ -75,8 +72,8 @@ class _CardEnterRegion extends StatelessWidget { if (onEnter) { children.add( Positioned( - top: 8.0, - right: 8.0, + top: 10.0, + right: 10.0, child: CardAccessoryContainer( accessories: accessories, onTapAccessory: onTapAccessory, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/define.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/define.dart index f07f867e7e..d96ea48418 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/define.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/define.dart @@ -1,3 +1,5 @@ +import 'package:flutter/widgets.dart'; + class CardSizes { - static double get cardCellVPadding => 6; + static EdgeInsets get cardCellPadding => const EdgeInsets.all(4); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell.dart index 5296737e56..0de6876f73 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell.dart @@ -113,7 +113,7 @@ class GridChecklistCellState extends GridCellState { : LocaleKeys.grid_checklist_hideComplete.tr(), width: 32, iconColorOnHover: - Theme.of(context).colorScheme.onPrimary, + Theme.of(context).colorScheme.onSurface, icon: FlowySvg( showIncompleteOnly ? FlowySvgs.show_m diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart index 19955b9342..d5322337e3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart @@ -106,7 +106,7 @@ class SelectOptionTag extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Flexible( - child: FlowyText.medium( + child: FlowyText.regular( name, fontSize: FontSizes.s11, overflow: TextOverflow.ellipsis, @@ -135,11 +135,11 @@ class SelectOptionTagCell extends StatelessWidget { final void Function(SelectOptionPB) onSelected; final SelectOptionPB option; const SelectOptionTagCell({ + super.key, required this.option, required this.onSelected, this.children = const [], - Key? key, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart index 7c830775c8..cb147e2782 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart @@ -17,5 +17,6 @@ export 'style_widget/button.dart'; export 'style_widget/icon_button.dart'; export 'style_widget/scrolling/styled_scroll_bar.dart'; export '/widget/spacing.dart'; +export '/widget/separated_flex.dart'; export 'style_widget/scrolling/styled_list.dart'; export 'style_widget/color_picker.dart'; diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/separated_flex.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/separated_flex.dart new file mode 100644 index 0000000000..9b2cac25e4 --- /dev/null +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/separated_flex.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; + +typedef SeparatorBuilder = Widget Function(); + +class SeparatedColumn extends Column { + SeparatedColumn({ + super.key, + super.mainAxisAlignment, + super.crossAxisAlignment, + super.mainAxisSize, + super.textBaseline, + super.textDirection, + super.verticalDirection, + required SeparatorBuilder separatorBuilder, + required List children, + }) : super(children: _insertSeparators(children, separatorBuilder)); +} + +class SeparatedRow extends Row { + SeparatedRow({ + super.key, + super.mainAxisAlignment, + super.crossAxisAlignment, + super.mainAxisSize, + super.textBaseline, + super.textDirection, + super.verticalDirection, + required SeparatorBuilder separatorBuilder, + required List children, + }) : super(children: _insertSeparators(children, separatorBuilder)); +} + +List _insertSeparators( + List children, + SeparatorBuilder separatorBuilder, +) { + if (children.length < 2) { + return children; + } + + List newChildren = []; + for (int i = 0; i < children.length - 1; i++) { + newChildren.add(children[i]); + newChildren.add(separatorBuilder()); + } + return newChildren..add(children.last); +} diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/seperated_column.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/seperated_column.dart deleted file mode 100644 index 7362f989e5..0000000000 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/seperated_column.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -typedef SeparatorBuilder = Widget Function(); - -class SeparatedColumn extends StatelessWidget { - final List children; - final SeparatorBuilder? separatorBuilder; - final MainAxisAlignment mainAxisAlignment; - final CrossAxisAlignment crossAxisAlignment; - final MainAxisSize mainAxisSize; - final TextBaseline? textBaseline; - final TextDirection? textDirection; - final VerticalDirection verticalDirection; - - const SeparatedColumn({ - Key? key, - required this.children, - this.separatorBuilder, - this.mainAxisAlignment = MainAxisAlignment.start, - this.crossAxisAlignment = CrossAxisAlignment.center, - this.mainAxisSize = MainAxisSize.max, - this.verticalDirection = VerticalDirection.down, - this.textBaseline, - this.textDirection, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var c = children.toList(); - for (var i = c.length; i-- > 0;) { - if (i > 0 && separatorBuilder != null) c.insert(i, separatorBuilder!()); - } - return Column( - mainAxisAlignment: mainAxisAlignment, - crossAxisAlignment: crossAxisAlignment, - mainAxisSize: mainAxisSize, - textBaseline: textBaseline, - textDirection: textDirection, - verticalDirection: verticalDirection, - children: c, - ); - } -}